summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2016-04-09 21:45:54 +1000
committer Vas Crabb <vas@vastheman.com>2016-04-09 21:52:08 +1000
commite925c494fe30adafb615c075f5eb692dd2b2effa (patch)
treeeed0b7ccadb049ed2dc8a72282c0235c4e94b6ae /3rdparty/lzma
parentb13e02f9751424dfc9ce6070676e2e318087a991 (diff)
Update LZMA SDK to 15.14
Diffstat (limited to '3rdparty/lzma')
-rw-r--r--3rdparty/lzma/7zr.exebin335360 -> 0 bytes
-rw-r--r--3rdparty/lzma/Asm/x86/7zAsm.asm28
-rw-r--r--3rdparty/lzma/Asm/x86/XzCrc64Opt.asm205
-rw-r--r--3rdparty/lzma/C/7z.h205
-rw-r--r--3rdparty/lzma/C/7zAlloc.c16
-rw-r--r--3rdparty/lzma/C/7zAlloc.h10
-rw-r--r--3rdparty/lzma/C/7zArcIn.c1770
-rw-r--r--3rdparty/lzma/C/7zBuf.c6
-rw-r--r--3rdparty/lzma/C/7zBuf.h12
-rw-r--r--3rdparty/lzma/C/7zBuf2.c12
-rw-r--r--3rdparty/lzma/C/7zCrc.c72
-rw-r--r--3rdparty/lzma/C/7zCrc.h4
-rw-r--r--3rdparty/lzma/C/7zCrcOpt.c87
-rw-r--r--3rdparty/lzma/C/7zDec.c351
-rw-r--r--3rdparty/lzma/C/7zFile.c2
-rw-r--r--3rdparty/lzma/C/7zFile.h4
-rw-r--r--3rdparty/lzma/C/7zIn.c1402
-rw-r--r--3rdparty/lzma/C/7zStream.c6
-rw-r--r--3rdparty/lzma/C/7zTypes.h (renamed from 3rdparty/lzma/C/Types.h)22
-rw-r--r--3rdparty/lzma/C/7zVersion.h27
-rw-r--r--3rdparty/lzma/C/Aes.c295
-rw-r--r--3rdparty/lzma/C/Aes.h38
-rw-r--r--3rdparty/lzma/C/AesOpt.c184
-rw-r--r--3rdparty/lzma/C/Alloc.c19
-rw-r--r--3rdparty/lzma/C/Alloc.h17
-rw-r--r--3rdparty/lzma/C/Bcj2.c330
-rw-r--r--3rdparty/lzma/C/Bcj2.h158
-rw-r--r--3rdparty/lzma/C/Bcj2Enc.c312
-rw-r--r--3rdparty/lzma/C/Bra.c2
-rw-r--r--3rdparty/lzma/C/Bra.h12
-rw-r--r--3rdparty/lzma/C/Bra86.c99
-rw-r--r--3rdparty/lzma/C/BraIA64.c4
-rw-r--r--3rdparty/lzma/C/Compiler.h32
-rw-r--r--3rdparty/lzma/C/CpuArch.c75
-rw-r--r--3rdparty/lzma/C/CpuArch.h156
-rw-r--r--3rdparty/lzma/C/Delta.c2
-rw-r--r--3rdparty/lzma/C/Delta.h12
-rw-r--r--3rdparty/lzma/C/LzFind.c499
-rw-r--r--3rdparty/lzma/C/LzFind.h38
-rw-r--r--3rdparty/lzma/C/LzFindMt.c190
-rw-r--r--3rdparty/lzma/C/LzFindMt.h12
-rw-r--r--3rdparty/lzma/C/LzHash.h43
-rw-r--r--3rdparty/lzma/C/Lzma2Dec.c50
-rw-r--r--3rdparty/lzma/C/Lzma2Dec.h12
-rw-r--r--3rdparty/lzma/C/Lzma2Enc.c73
-rw-r--r--3rdparty/lzma/C/Lzma2Enc.h10
-rw-r--r--3rdparty/lzma/C/Lzma86.h4
-rw-r--r--3rdparty/lzma/C/Lzma86Dec.c8
-rw-r--r--3rdparty/lzma/C/Lzma86Enc.c10
-rw-r--r--3rdparty/lzma/C/LzmaDec.c250
-rw-r--r--3rdparty/lzma/C/LzmaDec.h17
-rw-r--r--3rdparty/lzma/C/LzmaEnc.c348
-rw-r--r--3rdparty/lzma/C/LzmaEnc.h6
-rw-r--r--3rdparty/lzma/C/LzmaLib.c16
-rw-r--r--3rdparty/lzma/C/LzmaLib.h12
-rw-r--r--3rdparty/lzma/C/MtCoder.c6
-rw-r--r--3rdparty/lzma/C/Ppmd.h3
-rw-r--r--3rdparty/lzma/C/Ppmd7.c8
-rw-r--r--3rdparty/lzma/C/Ppmd7Dec.c2
-rw-r--r--3rdparty/lzma/C/Ppmd7Enc.c6
-rw-r--r--3rdparty/lzma/C/Precomp.h10
-rw-r--r--3rdparty/lzma/C/RotateDefs.h12
-rw-r--r--3rdparty/lzma/C/Sha256.c170
-rw-r--r--3rdparty/lzma/C/Sha256.h4
-rw-r--r--3rdparty/lzma/C/Sort.c141
-rw-r--r--3rdparty/lzma/C/Sort.h18
-rw-r--r--3rdparty/lzma/C/Threads.c29
-rw-r--r--3rdparty/lzma/C/Threads.h26
-rw-r--r--3rdparty/lzma/C/Util/7z/7z.dsp45
-rw-r--r--3rdparty/lzma/C/Util/7z/7zMain.c315
-rw-r--r--3rdparty/lzma/C/Util/7z/Precomp.c4
-rw-r--r--3rdparty/lzma/C/Util/7z/Precomp.h10
-rw-r--r--3rdparty/lzma/C/Util/7z/makefile13
-rw-r--r--3rdparty/lzma/C/Util/7z/makefile.gcc19
-rw-r--r--3rdparty/lzma/C/Util/Lzma/LzmaUtil.c12
-rw-r--r--3rdparty/lzma/C/Util/Lzma/LzmaUtil.dsp4
-rw-r--r--3rdparty/lzma/C/Util/Lzma/makefile2
-rw-r--r--3rdparty/lzma/C/Util/LzmaLib/LzmaLib.dsp8
-rw-r--r--3rdparty/lzma/C/Util/LzmaLib/LzmaLibExports.c10
-rw-r--r--3rdparty/lzma/C/Util/SfxSetup/Precomp.c4
-rw-r--r--3rdparty/lzma/C/Util/SfxSetup/Precomp.h10
-rw-r--r--3rdparty/lzma/C/Util/SfxSetup/SfxSetup.c109
-rw-r--r--3rdparty/lzma/C/Util/SfxSetup/SfxSetup.dsp35
-rw-r--r--3rdparty/lzma/C/Util/SfxSetup/makefile6
-rw-r--r--3rdparty/lzma/C/Util/SfxSetup/makefile_con7
-rw-r--r--3rdparty/lzma/C/Xz.c12
-rw-r--r--3rdparty/lzma/C/Xz.h49
-rw-r--r--3rdparty/lzma/C/XzCrc64.c85
-rw-r--r--3rdparty/lzma/C/XzCrc64.h4
-rw-r--r--3rdparty/lzma/C/XzCrc64Opt.c69
-rw-r--r--3rdparty/lzma/C/XzDec.c102
-rw-r--r--3rdparty/lzma/C/XzEnc.c94
-rw-r--r--3rdparty/lzma/C/XzIn.c74
-rw-r--r--3rdparty/lzma/CPP/7zip/7zip.mak240
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h43
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp569
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h58
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp622
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h69
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp484
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp135
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h41
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.cpp149
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.h58
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp735
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h57
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp561
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp5
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h57
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp1571
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h363
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h239
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp504
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h209
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp108
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp21
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp10
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h10
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp2072
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h71
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h3
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Archive.def8
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Archive2.def12
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp80
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp1065
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h465
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp240
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.h81
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.cpp15
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.h37
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp19
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h7
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp60
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h16
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp32
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp37
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h7
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp49
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h11
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h1
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h3
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp82
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/IArchive.h466
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp382
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp345
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/StdAfx.h3
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp668
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/XzHandler.h65
-rw-r--r--3rdparty/lzma/CPP/7zip/Asm.mak2
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp285
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h3
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/Alone7z/makefile111
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h3
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile49
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h3
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/Format7zR/makefile52
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp633
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp16
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/StdAfx.h2
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile38
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile.gcc49
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/resource.rc3
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/LzmaSpec/LzmaSpec.cpp715
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXCon/7z.icobin0 -> 1078 bytes
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SFXCon.dsp869
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SFXCon.dsw29
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SfxCon.cpp459
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXCon/StdAfx.cpp3
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXCon/StdAfx.h8
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXCon/makefile127
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXCon/resource.rc5
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp246
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h86
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp138
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h11
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp760
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw29
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp356
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp3
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/StdAfx.h13
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/makefile109
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/resource.h6
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/resource.rc16
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/setup.icobin0 -> 1078 bytes
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXWin/7z.icobin0 -> 1078 bytes
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SFXWin.dsp953
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SFXWin.dsw29
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SfxWin.cpp235
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXWin/StdAfx.cpp3
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXWin/StdAfx.h14
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXWin/makefile146
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXWin/resource.h1
-rw-r--r--3rdparty/lzma/CPP/7zip/Bundles/SFXWin/resource.rc50
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp46
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/CWrappers.h33
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp428
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/CreateCoder.h152
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp50
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h2
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp209
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/FileStreams.h50
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp433
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/FilterCoder.h184
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp122
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/InBuffer.h99
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp28
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h8
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp280
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h142
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/LockedStream.cpp20
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/LockedStream.h36
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/MethodId.h2
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp184
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/MethodProps.h26
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp12
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/OffsetStream.h7
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp57
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/OutBuffer.h35
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp35
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h7
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/PropId.cpp108
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/RegisterArc.h80
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h85
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/StdAfx.h3
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp52
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/StreamBinder.h32
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp110
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/StreamObjects.h50
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp8
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/StreamUtils.h12
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/UniqBlocks.cpp57
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/UniqBlocks.h26
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.cpp836
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.h144
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/Bcj2Register.cpp10
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/BcjCoder.cpp12
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/BcjCoder.h19
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/BcjRegister.cpp15
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/BranchCoder.cpp19
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/BranchCoder.h44
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/BranchMisc.cpp43
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/BranchMisc.h28
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/BranchRegister.cpp36
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/ByteSwap.cpp62
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/CodecExports.cpp324
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp82
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/CopyCoder.h18
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/CopyRegister.cpp7
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/DeltaFilter.cpp58
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.cpp169
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.h43
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.cpp23
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/Lzma2Register.cpp13
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.cpp32
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.h9
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.cpp32
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.h2
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/LzmaRegister.cpp13
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.cpp6
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp6
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/PpmdRegister.cpp14
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/RangeCoder.h205
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/RangeCoderBit.h114
-rw-r--r--3rdparty/lzma/CPP/7zip/Compress/StdAfx.h2
-rw-r--r--3rdparty/lzma/CPP/7zip/Crc.mak2
-rw-r--r--3rdparty/lzma/CPP/7zip/Crc64.mak8
-rw-r--r--3rdparty/lzma/CPP/7zip/Crypto/7zAes.cpp280
-rw-r--r--3rdparty/lzma/CPP/7zip/Crypto/7zAes.h116
-rw-r--r--3rdparty/lzma/CPP/7zip/Crypto/7zAesRegister.cpp12
-rw-r--r--3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp112
-rw-r--r--3rdparty/lzma/CPP/7zip/Crypto/MyAes.h55
-rw-r--r--3rdparty/lzma/CPP/7zip/Crypto/MyAesReg.cpp12
-rw-r--r--3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp124
-rw-r--r--3rdparty/lzma/CPP/7zip/Crypto/RandGen.h21
-rw-r--r--3rdparty/lzma/CPP/7zip/Crypto/StdAfx.h8
-rw-r--r--3rdparty/lzma/CPP/7zip/GuiCommon.rc81
-rw-r--r--3rdparty/lzma/CPP/7zip/Guid.txt62
-rw-r--r--3rdparty/lzma/CPP/7zip/ICoder.h215
-rw-r--r--3rdparty/lzma/CPP/7zip/IDecl.h19
-rw-r--r--3rdparty/lzma/CPP/7zip/IPassword.h3
-rw-r--r--3rdparty/lzma/CPP/7zip/IProgress.h18
-rw-r--r--3rdparty/lzma/CPP/7zip/IStream.h95
-rw-r--r--3rdparty/lzma/CPP/7zip/MyVersion.h8
-rw-r--r--3rdparty/lzma/CPP/7zip/PropID.h69
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.cpp245
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.dsp21
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Client7z/StdAfx.h3
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Client7z/makefile25
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Client7z/resource.rc3
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp1227
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h110
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp1478
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h259
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.cpp68
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.h11
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp72
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h55
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp2236
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/Bench.h12
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.cpp16
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.h6
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/DirItem.h114
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp809
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.h20
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/Extract.cpp416
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/Extract.h54
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/ExtractMode.h41
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp275
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h16
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.cpp351
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.h107
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h106
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp1008
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.h334
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp3448
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.h415
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp582
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.h14
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.cpp25
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.cpp19
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.h8
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/StdAfx.h5
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.cpp8
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.h2
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp1272
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/Update.h163
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.cpp10
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.h23
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp664
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.h112
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp204
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.h4
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp30
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.h26
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.cpp21
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.h8
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/ZipRegistry.h26
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp5
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h2
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/Console.mak36
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp29
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h19
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp766
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h155
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/HashCon.cpp367
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/HashCon.h48
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/List.cpp1425
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/List.h15
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp1174
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp113
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp83
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h55
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp205
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h70
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h3
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp615
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h120
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp71
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h6
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/makefile87
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.cpp37
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.h16
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.cpp1024
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.h21
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialogRes.h9
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.cpp64
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.h28
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialogRes.h4
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/DialogSize.h16
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.cpp1035
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.h328
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.cpp28
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.h14
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/LangUtils.h40
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/MyWindowsNew.h76
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.cpp119
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.h69
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.rc91
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialogRes.h17
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.cpp58
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.h28
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.rc14
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialogRes.h5
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.cpp196
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.h170
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.rc12
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.cpp1319
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.h313
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.rc40
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2Res.h48
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2a.rc80
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialogRes.h3
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.cpp23
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.h10
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyNameRes.h95
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.cpp255
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.h62
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/resource.h175
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/FileManager/resourceGui.h15
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/GUI/Extract.rc59
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.cpp418
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.h113
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.rc98
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialogRes.h24
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.cpp272
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.h38
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/GUI/ExtractRes.h51
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/GUI/HashGUI.h16
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/GUI/resource2.h2
-rw-r--r--3rdparty/lzma/CPP/Build.mak39
-rw-r--r--3rdparty/lzma/CPP/Common/Buffer.h77
-rw-r--r--3rdparty/lzma/CPP/Common/C_FileIO.h4
-rw-r--r--3rdparty/lzma/CPP/Common/CommandLineParser.cpp270
-rw-r--r--3rdparty/lzma/CPP/Common/CommandLineParser.h49
-rw-r--r--3rdparty/lzma/CPP/Common/Common.h13
-rw-r--r--3rdparty/lzma/CPP/Common/CrcReg.cpp98
-rw-r--r--3rdparty/lzma/CPP/Common/Defs.h15
-rw-r--r--3rdparty/lzma/CPP/Common/DynamicBuffer.h76
-rw-r--r--3rdparty/lzma/CPP/Common/IntToString.cpp149
-rw-r--r--3rdparty/lzma/CPP/Common/IntToString.h23
-rw-r--r--3rdparty/lzma/CPP/Common/Lang.h23
-rw-r--r--3rdparty/lzma/CPP/Common/ListFileUtils.cpp117
-rw-r--r--3rdparty/lzma/CPP/Common/ListFileUtils.h5
-rw-r--r--3rdparty/lzma/CPP/Common/MyBuffer.h244
-rw-r--r--3rdparty/lzma/CPP/Common/MyCom.h93
-rw-r--r--3rdparty/lzma/CPP/Common/MyGuidDef.h2
-rw-r--r--3rdparty/lzma/CPP/Common/MyInitGuid.h23
-rw-r--r--3rdparty/lzma/CPP/Common/MyLinux.h42
-rw-r--r--3rdparty/lzma/CPP/Common/MyString.cpp1460
-rw-r--r--3rdparty/lzma/CPP/Common/MyString.h1075
-rw-r--r--3rdparty/lzma/CPP/Common/MyTypes.h35
-rw-r--r--3rdparty/lzma/CPP/Common/MyUnknown.h4
-rw-r--r--3rdparty/lzma/CPP/Common/MyVector.cpp84
-rw-r--r--3rdparty/lzma/CPP/Common/MyVector.h584
-rw-r--r--3rdparty/lzma/CPP/Common/MyWindows.cpp109
-rw-r--r--3rdparty/lzma/CPP/Common/MyWindows.h15
-rw-r--r--3rdparty/lzma/CPP/Common/NewHandler.cpp67
-rw-r--r--3rdparty/lzma/CPP/Common/NewHandler.h57
-rw-r--r--3rdparty/lzma/CPP/Common/Sha256Reg.cpp40
-rw-r--r--3rdparty/lzma/CPP/Common/StdAfx.h3
-rw-r--r--3rdparty/lzma/CPP/Common/StdInStream.cpp25
-rw-r--r--3rdparty/lzma/CPP/Common/StdInStream.h21
-rw-r--r--3rdparty/lzma/CPP/Common/StdOutStream.cpp86
-rw-r--r--3rdparty/lzma/CPP/Common/StdOutStream.h61
-rw-r--r--3rdparty/lzma/CPP/Common/StringConvert.cpp330
-rw-r--r--3rdparty/lzma/CPP/Common/StringConvert.h10
-rw-r--r--3rdparty/lzma/CPP/Common/StringToInt.cpp157
-rw-r--r--3rdparty/lzma/CPP/Common/StringToInt.h19
-rw-r--r--3rdparty/lzma/CPP/Common/TextConfig.cpp124
-rw-r--r--3rdparty/lzma/CPP/Common/TextConfig.h19
-rw-r--r--3rdparty/lzma/CPP/Common/Types.h11
-rw-r--r--3rdparty/lzma/CPP/Common/UTFConvert.cpp293
-rw-r--r--3rdparty/lzma/CPP/Common/UTFConvert.h7
-rw-r--r--3rdparty/lzma/CPP/Common/Wildcard.cpp468
-rw-r--r--3rdparty/lzma/CPP/Common/Wildcard.h95
-rw-r--r--3rdparty/lzma/CPP/Common/XzCrc64Reg.cpp42
-rw-r--r--3rdparty/lzma/CPP/Windows/COM.h70
-rw-r--r--3rdparty/lzma/CPP/Windows/CommonDialog.cpp185
-rw-r--r--3rdparty/lzma/CPP/Windows/CommonDialog.h23
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/ComboBox.cpp66
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/ComboBox.h65
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/CommandBar.h52
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/Dialog.cpp250
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/Dialog.h167
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/Edit.h19
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/ImageList.cpp10
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/ImageList.h87
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/ListView.cpp155
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/ListView.h146
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/ProgressBar.h35
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/PropertyPage.cpp143
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/PropertyPage.h50
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/ReBar.h34
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/Static.h28
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/StatusBar.h42
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/StdAfx.h8
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/ToolBar.h43
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/Trackbar.h27
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/Window2.cpp200
-rw-r--r--3rdparty/lzma/CPP/Windows/Control/Window2.h51
-rw-r--r--3rdparty/lzma/CPP/Windows/DLL.cpp15
-rw-r--r--3rdparty/lzma/CPP/Windows/DLL.h16
-rw-r--r--3rdparty/lzma/CPP/Windows/Error.h15
-rw-r--r--3rdparty/lzma/CPP/Windows/ErrorMsg.cpp (renamed from 3rdparty/lzma/CPP/Windows/Error.cpp)30
-rw-r--r--3rdparty/lzma/CPP/Windows/ErrorMsg.h15
-rw-r--r--3rdparty/lzma/CPP/Windows/FileDir.cpp501
-rw-r--r--3rdparty/lzma/CPP/Windows/FileDir.h60
-rw-r--r--3rdparty/lzma/CPP/Windows/FileFind.cpp546
-rw-r--r--3rdparty/lzma/CPP/Windows/FileFind.h67
-rw-r--r--3rdparty/lzma/CPP/Windows/FileIO.cpp337
-rw-r--r--3rdparty/lzma/CPP/Windows/FileIO.h184
-rw-r--r--3rdparty/lzma/CPP/Windows/FileLink.cpp436
-rw-r--r--3rdparty/lzma/CPP/Windows/FileMapping.cpp2
-rw-r--r--3rdparty/lzma/CPP/Windows/FileMapping.h8
-rw-r--r--3rdparty/lzma/CPP/Windows/FileName.cpp810
-rw-r--r--3rdparty/lzma/CPP/Windows/FileName.h98
-rw-r--r--3rdparty/lzma/CPP/Windows/FileSystem.cpp131
-rw-r--r--3rdparty/lzma/CPP/Windows/FileSystem.h27
-rw-r--r--3rdparty/lzma/CPP/Windows/MemoryLock.cpp100
-rw-r--r--3rdparty/lzma/CPP/Windows/MemoryLock.h29
-rw-r--r--3rdparty/lzma/CPP/Windows/NtCheck.h2
-rw-r--r--3rdparty/lzma/CPP/Windows/PropVariant.cpp164
-rw-r--r--3rdparty/lzma/CPP/Windows/PropVariant.h104
-rw-r--r--3rdparty/lzma/CPP/Windows/PropVariantConv.cpp109
-rw-r--r--3rdparty/lzma/CPP/Windows/PropVariantConv.h30
-rw-r--r--3rdparty/lzma/CPP/Windows/PropVariantConversions.cpp105
-rw-r--r--3rdparty/lzma/CPP/Windows/PropVariantConversions.h14
-rw-r--r--3rdparty/lzma/CPP/Windows/Registry.cpp165
-rw-r--r--3rdparty/lzma/CPP/Windows/Registry.h39
-rw-r--r--3rdparty/lzma/CPP/Windows/ResourceString.cpp103
-rw-r--r--3rdparty/lzma/CPP/Windows/ResourceString.h16
-rw-r--r--3rdparty/lzma/CPP/Windows/SecurityUtils.cpp181
-rw-r--r--3rdparty/lzma/CPP/Windows/SecurityUtils.h167
-rw-r--r--3rdparty/lzma/CPP/Windows/Shell.cpp340
-rw-r--r--3rdparty/lzma/CPP/Windows/Shell.h94
-rw-r--r--3rdparty/lzma/CPP/Windows/StdAfx.h3
-rw-r--r--3rdparty/lzma/CPP/Windows/System.cpp74
-rw-r--r--3rdparty/lzma/CPP/Windows/System.h5
-rw-r--r--3rdparty/lzma/CPP/Windows/Time.h23
-rw-r--r--3rdparty/lzma/CPP/Windows/TimeUtils.cpp (renamed from 3rdparty/lzma/CPP/Windows/Time.cpp)50
-rw-r--r--3rdparty/lzma/CPP/Windows/TimeUtils.h24
-rw-r--r--3rdparty/lzma/CPP/Windows/Window.cpp179
-rw-r--r--3rdparty/lzma/CPP/Windows/Window.h284
-rw-r--r--3rdparty/lzma/DOC/7zC.txt (renamed from 3rdparty/lzma/7zC.txt)19
-rw-r--r--3rdparty/lzma/DOC/7zFormat.txt (renamed from 3rdparty/lzma/7zFormat.txt)84
-rw-r--r--3rdparty/lzma/DOC/Methods.txt158
-rw-r--r--3rdparty/lzma/DOC/installer.txt166
-rw-r--r--3rdparty/lzma/DOC/lzma-history.txt (renamed from 3rdparty/lzma/history.txt)56
-rw-r--r--3rdparty/lzma/DOC/lzma-sdk.txt357
-rw-r--r--3rdparty/lzma/DOC/lzma-specification.txt1176
-rw-r--r--3rdparty/lzma/DOC/lzma.txt328
-rw-r--r--3rdparty/lzma/Methods.txt152
-rw-r--r--3rdparty/lzma/lzma.exebin87552 -> 0 bytes
-rw-r--r--3rdparty/lzma/lzma.txt604
534 files changed, 65266 insertions, 17440 deletions
diff --git a/3rdparty/lzma/7zr.exe b/3rdparty/lzma/7zr.exe
deleted file mode 100644
index 1a3a84347dc..00000000000
--- a/3rdparty/lzma/7zr.exe
+++ /dev/null
Binary files differ
diff --git a/3rdparty/lzma/Asm/x86/7zAsm.asm b/3rdparty/lzma/Asm/x86/7zAsm.asm
index 3e42ab454ce..3707e90c566 100644
--- a/3rdparty/lzma/Asm/x86/7zAsm.asm
+++ b/3rdparty/lzma/Asm/x86/7zAsm.asm
@@ -1,5 +1,5 @@
; 7zAsm.asm -- ASM macros
-; 2009-12-12 : Igor Pavlov : Public domain
+; 2012-12-30 : Igor Pavlov : Public domain
MY_ASM_START macro
ifdef x64
@@ -13,30 +13,34 @@ endm
MY_PROC macro name:req, numParams:req
align 16
- proc_numParams equ numParams
+ proc_numParams = numParams
ifdef x64
proc_name equ name
- name PROC
else
- proc_fastcall_name equ @CatStr(@,name,@, %numParams * 4)
- public proc_fastcall_name
- proc_fastcall_name:
+ proc_name equ @CatStr(@,name,@, %numParams * 4)
endif
+ proc_name PROC
endm
MY_ENDP macro
ifdef x64
ret
- proc_name ENDP
else
- ret (proc_numParams - 2) * 4
+ if proc_numParams LT 3
+ ret
+ else
+ ret (proc_numParams - 2) * 4
+ endif
endif
+ proc_name ENDP
endm
ifdef x64
REG_SIZE equ 8
+ REG_LOGAR_SIZE equ 3
else
REG_SIZE equ 4
+ REG_LOGAR_SIZE equ 2
endif
x0 equ EAX
@@ -67,6 +71,14 @@ ifdef x64
r5 equ RBP
r6 equ RSI
r7 equ RDI
+ x8 equ r8d
+ x9 equ r9d
+ x10 equ r10d
+ x11 equ r11d
+ x12 equ r12d
+ x13 equ r13d
+ x14 equ r14d
+ x15 equ r15d
else
r0 equ x0
r1 equ x1
diff --git a/3rdparty/lzma/Asm/x86/XzCrc64Opt.asm b/3rdparty/lzma/Asm/x86/XzCrc64Opt.asm
new file mode 100644
index 00000000000..734ca5c45f4
--- /dev/null
+++ b/3rdparty/lzma/Asm/x86/XzCrc64Opt.asm
@@ -0,0 +1,205 @@
+; XzCrc64Opt.asm -- CRC64 calculation : optimized version
+; 2011-06-28 : Igor Pavlov : Public domain
+
+include 7zAsm.asm
+
+MY_ASM_START
+
+ifdef x64
+
+ rD equ r9
+ rN equ r10
+
+ num_VAR equ r8
+ table_VAR equ r9
+
+ SRCDAT equ rN + rD
+
+CRC_XOR macro dest:req, src:req, t:req
+ xor dest, QWORD PTR [r5 + src * 8 + 0800h * t]
+endm
+
+CRC1b macro
+ movzx x6, BYTE PTR [rD]
+ inc rD
+ movzx x3, x0_L
+ xor x6, x3
+ shr r0, 8
+ CRC_XOR r0, r6, 0
+ dec rN
+endm
+
+MY_PROLOG macro crc_end:req
+ MY_PUSH_4_REGS
+
+ mov r0, r1
+ mov rN, num_VAR
+ mov r5, table_VAR
+ mov rD, r2
+ test rN, rN
+ jz crc_end
+ @@:
+ test rD, 3
+ jz @F
+ CRC1b
+ jnz @B
+ @@:
+ cmp rN, 8
+ jb crc_end
+ add rN, rD
+ mov num_VAR, rN
+ sub rN, 4
+ and rN, NOT 3
+ sub rD, rN
+ mov x1, [SRCDAT]
+ xor r0, r1
+ add rN, 4
+endm
+
+MY_EPILOG macro crc_end:req
+ sub rN, 4
+ mov x1, [SRCDAT]
+ xor r0, r1
+ mov rD, rN
+ mov rN, num_VAR
+ sub rN, rD
+ crc_end:
+ test rN, rN
+ jz @F
+ CRC1b
+ jmp crc_end
+ @@:
+ MY_POP_4_REGS
+endm
+
+MY_PROC XzCrc64UpdateT4, 4
+ MY_PROLOG crc_end_4
+ align 16
+ main_loop_4:
+ mov x1, [SRCDAT]
+ movzx x2, x0_L
+ movzx x3, x0_H
+ shr r0, 16
+ movzx x6, x0_L
+ movzx x7, x0_H
+ shr r0, 16
+ CRC_XOR r1, r2, 3
+ CRC_XOR r0, r3, 2
+ CRC_XOR r1, r6, 1
+ CRC_XOR r0, r7, 0
+ xor r0, r1
+
+ add rD, 4
+ jnz main_loop_4
+
+ MY_EPILOG crc_end_4
+MY_ENDP
+
+else
+
+ rD equ r1
+ rN equ r7
+
+ crc_val equ (REG_SIZE * 5)
+ crc_table equ (8 + crc_val)
+ table_VAR equ [r4 + crc_table]
+ num_VAR equ table_VAR
+
+
+ SRCDAT equ rN + rD
+
+CRC macro op0:req, op1:req, dest0:req, dest1:req, src:req, t:req
+ op0 dest0, DWORD PTR [r5 + src * 8 + 0800h * t]
+ op1 dest1, DWORD PTR [r5 + src * 8 + 0800h * t + 4]
+endm
+
+CRC_XOR macro dest0:req, dest1:req, src:req, t:req
+ CRC xor, xor, dest0, dest1, src, t
+endm
+
+
+CRC1b macro
+ movzx x6, BYTE PTR [rD]
+ inc rD
+ movzx x3, x0_L
+ xor x6, x3
+ shrd r0, r2, 8
+ shr r2, 8
+ CRC_XOR r0, r2, r6, 0
+ dec rN
+endm
+
+MY_PROLOG macro crc_end:req
+ MY_PUSH_4_REGS
+
+ mov rN, r2
+
+ mov x0, [r4 + crc_val]
+ mov x2, [r4 + crc_val + 4]
+ mov r5, table_VAR
+ test rN, rN
+ jz crc_end
+ @@:
+ test rD, 3
+ jz @F
+ CRC1b
+ jnz @B
+ @@:
+ cmp rN, 8
+ jb crc_end
+ add rN, rD
+
+ mov num_VAR, rN
+
+ sub rN, 4
+ and rN, NOT 3
+ sub rD, rN
+ xor r0, [SRCDAT]
+ add rN, 4
+endm
+
+MY_EPILOG macro crc_end:req
+ sub rN, 4
+ xor r0, [SRCDAT]
+
+ mov rD, rN
+ mov rN, num_VAR
+ sub rN, rD
+ crc_end:
+ test rN, rN
+ jz @F
+ CRC1b
+ jmp crc_end
+ @@:
+ MY_POP_4_REGS
+endm
+
+MY_PROC XzCrc64UpdateT4, 5
+ MY_PROLOG crc_end_4
+ movzx x6, x0_L
+ align 16
+ main_loop_4:
+ mov r3, [SRCDAT]
+ xor r3, r2
+
+ CRC xor, mov, r3, r2, r6, 3
+ movzx x6, x0_H
+ shr r0, 16
+ CRC_XOR r3, r2, r6, 2
+
+ movzx x6, x0_L
+ movzx x0, x0_H
+ CRC_XOR r3, r2, r6, 1
+ CRC_XOR r3, r2, r0, 0
+ movzx x6, x3_L
+ mov r0, r3
+
+ add rD, 4
+ jnz main_loop_4
+
+ MY_EPILOG crc_end_4
+MY_ENDP
+
+endif
+
+end
diff --git a/3rdparty/lzma/C/7z.h b/3rdparty/lzma/C/7z.h
index 01c4cac6a7b..4768151948d 100644
--- a/3rdparty/lzma/C/7z.h
+++ b/3rdparty/lzma/C/7z.h
@@ -1,89 +1,57 @@
/* 7z.h -- 7z interface
-2010-03-11 : Igor Pavlov : Public domain */
+2015-11-18 : Igor Pavlov : Public domain */
#ifndef __7Z_H
#define __7Z_H
-#include "7zBuf.h"
+#include "7zTypes.h"
EXTERN_C_BEGIN
#define k7zStartHeaderSize 0x20
#define k7zSignatureSize 6
-extern Byte k7zSignature[k7zSignatureSize];
-#define k7zMajorVersion 0
-enum EIdEnum
+extern const Byte k7zSignature[k7zSignatureSize];
+
+typedef struct
{
- k7zIdEnd,
- k7zIdHeader,
- k7zIdArchiveProperties,
- k7zIdAdditionalStreamsInfo,
- k7zIdMainStreamsInfo,
- k7zIdFilesInfo,
- k7zIdPackInfo,
- k7zIdUnpackInfo,
- k7zIdSubStreamsInfo,
- k7zIdSize,
- k7zIdCRC,
- k7zIdFolder,
- k7zIdCodersUnpackSize,
- k7zIdNumUnpackStream,
- k7zIdEmptyStream,
- k7zIdEmptyFile,
- k7zIdAnti,
- k7zIdName,
- k7zIdCTime,
- k7zIdATime,
- k7zIdMTime,
- k7zIdWinAttributes,
- k7zIdComment,
- k7zIdEncodedHeader,
- k7zIdStartPos,
- k7zIdDummy
-};
+ const Byte *Data;
+ size_t Size;
+} CSzData;
+
+/* CSzCoderInfo & CSzFolder support only default methods */
typedef struct
{
- UInt32 NumInStreams;
- UInt32 NumOutStreams;
- UInt64 MethodID;
- CBuf Props;
+ size_t PropsOffset;
+ UInt32 MethodID;
+ Byte NumStreams;
+ Byte PropsSize;
} CSzCoderInfo;
-void SzCoderInfo_Init(CSzCoderInfo *p);
-void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
-
typedef struct
{
UInt32 InIndex;
UInt32 OutIndex;
-} CSzBindPair;
+} CSzBond;
+
+#define SZ_NUM_CODERS_IN_FOLDER_MAX 4
+#define SZ_NUM_BONDS_IN_FOLDER_MAX 3
+#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4
typedef struct
{
- CSzCoderInfo *Coders;
- CSzBindPair *BindPairs;
- UInt32 *PackStreams;
- UInt64 *UnpackSizes;
UInt32 NumCoders;
- UInt32 NumBindPairs;
+ UInt32 NumBonds;
UInt32 NumPackStreams;
- int UnpackCRCDefined;
- UInt32 UnpackCRC;
-
- UInt32 NumUnpackStreams;
+ UInt32 UnpackStream;
+ UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
+ CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
+ CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
} CSzFolder;
-void SzFolder_Init(CSzFolder *p);
-UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
-int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
-UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
-UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
-SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
- ILookInStream *stream, UInt64 startPos,
- Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
+SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);
typedef struct
{
@@ -93,72 +61,75 @@ typedef struct
typedef struct
{
- CNtfsFileTime MTime;
- UInt64 Size;
- UInt32 Crc;
- UInt32 Attrib;
- Byte HasStream;
- Byte IsDir;
- Byte IsAnti;
- Byte CrcDefined;
- Byte MTimeDefined;
- Byte AttribDefined;
-} CSzFileItem;
-
-void SzFile_Init(CSzFileItem *p);
+ Byte *Defs; /* MSB 0 bit numbering */
+ UInt32 *Vals;
+} CSzBitUi32s;
+
+typedef struct
+{
+ Byte *Defs; /* MSB 0 bit numbering */
+ // UInt64 *Vals;
+ CNtfsFileTime *Vals;
+} CSzBitUi64s;
+
+#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
+
+#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
typedef struct
{
- UInt64 *PackSizes;
- Byte *PackCRCsDefined;
- UInt32 *PackCRCs;
- CSzFolder *Folders;
- CSzFileItem *Files;
UInt32 NumPackStreams;
UInt32 NumFolders;
- UInt32 NumFiles;
-} CSzAr;
-void SzAr_Init(CSzAr *p);
-void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
+ UInt64 *PackPositions; // NumPackStreams + 1
+ CSzBitUi32s FolderCRCs; // NumFolders
+ size_t *FoCodersOffsets; // NumFolders + 1
+ UInt32 *FoStartPackStreamIndex; // NumFolders + 1
+ UInt32 *FoToCoderUnpackSizes; // NumFolders + 1
+ Byte *FoToMainUnpackSizeIndex; // NumFolders
+ UInt64 *CoderUnpackSizes; // for all coders in all folders
-/*
- SzExtract extracts file from archive
+ Byte *CodersData;
+} CSzAr;
- *outBuffer must be 0 before first call for each new archive.
+UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
- Extracting cache:
- If you need to decompress more than one file, you can send
- these values from previous call:
- *blockIndex,
- *outBuffer,
- *outBufferSize
- You can consider "*outBuffer" as cache of solid block. If your archive is solid,
- it will increase decompression speed.
-
- If you use external function, you can declare these 3 cache variables
- (blockIndex, outBuffer, outBufferSize) as static in that external function.
-
- Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
-*/
+SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
+ ILookInStream *stream, UInt64 startPos,
+ Byte *outBuffer, size_t outSize,
+ ISzAlloc *allocMain);
typedef struct
{
CSzAr db;
-
+
UInt64 startPosAfterHeader;
UInt64 dataPos;
+
+ UInt32 NumFiles;
- UInt32 *FolderStartPackStreamIndex;
- UInt64 *PackStreamStartPositions;
- UInt32 *FolderStartFileIndex;
- UInt32 *FileIndexToFolderIndexMap;
+ UInt64 *UnpackPositions; // NumFiles + 1
+ // Byte *IsEmptyFiles;
+ Byte *IsDirs;
+ CSzBitUi32s CRCs;
+
+ CSzBitUi32s Attribs;
+ // CSzBitUi32s Parents;
+ CSzBitUi64s MTime;
+ CSzBitUi64s CTime;
+
+ UInt32 *FolderToFile; // NumFolders + 1
+ UInt32 *FileToFolder; // NumFiles
size_t *FileNameOffsets; /* in 2-byte steps */
- CBuf FileNames; /* UTF-16-LE */
+ Byte *FileNames; /* UTF-16-LE */
} CSzArEx;
+#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i))
+
+#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
+
void SzArEx_Init(CSzArEx *p);
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
@@ -172,6 +143,33 @@ if dest != NULL, the return value specifies the number of 16-bit characters that
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
+/*
+size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
+UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
+*/
+
+
+
+/*
+ SzArEx_Extract extracts file from archive
+
+ *outBuffer must be 0 before first call for each new archive.
+
+ Extracting cache:
+ If you need to decompress more than one file, you can send
+ these values from previous call:
+ *blockIndex,
+ *outBuffer,
+ *outBufferSize
+ You can consider "*outBuffer" as cache of solid block. If your archive is solid,
+ it will increase decompression speed.
+
+ If you use external function, you can declare these 3 cache variables
+ (blockIndex, outBuffer, outBufferSize) as static in that external function.
+
+ Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
+*/
+
SRes SzArEx_Extract(
const CSzArEx *db,
ILookInStream *inStream,
@@ -196,7 +194,8 @@ SZ_ERROR_INPUT_EOF
SZ_ERROR_FAIL
*/
-SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
+ ISzAlloc *allocMain, ISzAlloc *allocTemp);
EXTERN_C_END
diff --git a/3rdparty/lzma/C/7zAlloc.c b/3rdparty/lzma/C/7zAlloc.c
index 964b28db38e..3e848c9800d 100644
--- a/3rdparty/lzma/C/7zAlloc.c
+++ b/3rdparty/lzma/C/7zAlloc.c
@@ -1,5 +1,7 @@
/* 7zAlloc.c -- Allocation functions
-2010-10-29 : Igor Pavlov : Public domain */
+2015-11-09 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "7zAlloc.h"
@@ -20,11 +22,11 @@ int g_allocCountTemp = 0;
void *SzAlloc(void *p, size_t size)
{
- p = p;
+ UNUSED_VAR(p);
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
- fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
+ fprintf(stderr, "\nAlloc %10u bytes; count = %10d", (unsigned)size, g_allocCount);
g_allocCount++;
#endif
return malloc(size);
@@ -32,7 +34,7 @@ void *SzAlloc(void *p, size_t size)
void SzFree(void *p, void *address)
{
- p = p;
+ UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
@@ -45,11 +47,11 @@ void SzFree(void *p, void *address)
void *SzAllocTemp(void *p, size_t size)
{
- p = p;
+ UNUSED_VAR(p);
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
- fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
+ fprintf(stderr, "\nAlloc_temp %10u bytes; count = %10d", (unsigned)size, g_allocCountTemp);
g_allocCountTemp++;
#ifdef _WIN32
return HeapAlloc(GetProcessHeap(), 0, size);
@@ -60,7 +62,7 @@ void *SzAllocTemp(void *p, size_t size)
void SzFreeTemp(void *p, void *address)
{
- p = p;
+ UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
diff --git a/3rdparty/lzma/C/7zAlloc.h b/3rdparty/lzma/C/7zAlloc.h
index 3344e9373f7..2fd5bdbc800 100644
--- a/3rdparty/lzma/C/7zAlloc.h
+++ b/3rdparty/lzma/C/7zAlloc.h
@@ -1,15 +1,23 @@
/* 7zAlloc.h -- Allocation functions
-2010-10-29 : Igor Pavlov : Public domain */
+2013-03-25 : Igor Pavlov : Public domain */
#ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H
#include <stdlib.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void *SzAlloc(void *p, size_t size);
void SzFree(void *p, void *address);
void *SzAllocTemp(void *p, size_t size);
void SzFreeTemp(void *p, void *address);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/3rdparty/lzma/C/7zArcIn.c b/3rdparty/lzma/C/7zArcIn.c
new file mode 100644
index 00000000000..06e35de0d4f
--- /dev/null
+++ b/3rdparty/lzma/C/7zArcIn.c
@@ -0,0 +1,1770 @@
+/* 7zArcIn.c -- 7z Input functions
+2015-11-18 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include <string.h>
+
+#include "7z.h"
+#include "7zBuf.h"
+#include "7zCrc.h"
+#include "CpuArch.h"
+
+#define MY_ALLOC(T, p, size, alloc) { \
+ if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }
+
+#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) }
+
+#define MY_ALLOC_AND_CPY(to, size, from, alloc) \
+ { MY_ALLOC(Byte, to, size, alloc); memcpy(to, from, size); }
+
+#define MY_ALLOC_ZE_AND_CPY(to, size, from, alloc) \
+ { if ((size) == 0) p = NULL; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } }
+
+#define k7zMajorVersion 0
+
+enum EIdEnum
+{
+ k7zIdEnd,
+ k7zIdHeader,
+ k7zIdArchiveProperties,
+ k7zIdAdditionalStreamsInfo,
+ k7zIdMainStreamsInfo,
+ k7zIdFilesInfo,
+ k7zIdPackInfo,
+ k7zIdUnpackInfo,
+ k7zIdSubStreamsInfo,
+ k7zIdSize,
+ k7zIdCRC,
+ k7zIdFolder,
+ k7zIdCodersUnpackSize,
+ k7zIdNumUnpackStream,
+ k7zIdEmptyStream,
+ k7zIdEmptyFile,
+ k7zIdAnti,
+ k7zIdName,
+ k7zIdCTime,
+ k7zIdATime,
+ k7zIdMTime,
+ k7zIdWinAttrib,
+ k7zIdComment,
+ k7zIdEncodedHeader,
+ k7zIdStartPos,
+ k7zIdDummy
+ // k7zNtSecure,
+ // k7zParent,
+ // k7zIsReal
+};
+
+const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
+
+#define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
+
+static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
+{
+ if (num == 0)
+ {
+ p->Defs = NULL;
+ p->Vals = NULL;
+ }
+ else
+ {
+ MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc);
+ MY_ALLOC(UInt32, p->Vals, num, alloc);
+ }
+ return SZ_OK;
+}
+
+void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc)
+{
+ IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
+ IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
+}
+
+#define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
+
+void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc)
+{
+ IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
+ IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
+}
+
+
+static void SzAr_Init(CSzAr *p)
+{
+ p->NumPackStreams = 0;
+ p->NumFolders = 0;
+
+ p->PackPositions = NULL;
+ SzBitUi32s_Init(&p->FolderCRCs);
+
+ p->FoCodersOffsets = NULL;
+ p->FoStartPackStreamIndex = NULL;
+ p->FoToCoderUnpackSizes = NULL;
+ p->FoToMainUnpackSizeIndex = NULL;
+ p->CoderUnpackSizes = NULL;
+
+ p->CodersData = NULL;
+}
+
+static void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
+{
+ IAlloc_Free(alloc, p->PackPositions);
+ SzBitUi32s_Free(&p->FolderCRCs, alloc);
+
+ IAlloc_Free(alloc, p->FoCodersOffsets);
+ IAlloc_Free(alloc, p->FoStartPackStreamIndex);
+ IAlloc_Free(alloc, p->FoToCoderUnpackSizes);
+ IAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);
+ IAlloc_Free(alloc, p->CoderUnpackSizes);
+
+ IAlloc_Free(alloc, p->CodersData);
+
+ SzAr_Init(p);
+}
+
+
+void SzArEx_Init(CSzArEx *p)
+{
+ SzAr_Init(&p->db);
+
+ p->NumFiles = 0;
+ p->dataPos = 0;
+
+ p->UnpackPositions = NULL;
+ p->IsDirs = NULL;
+
+ p->FolderToFile = NULL;
+ p->FileToFolder = NULL;
+
+ p->FileNameOffsets = NULL;
+ p->FileNames = NULL;
+
+ SzBitUi32s_Init(&p->CRCs);
+ SzBitUi32s_Init(&p->Attribs);
+ // SzBitUi32s_Init(&p->Parents);
+ SzBitUi64s_Init(&p->MTime);
+ SzBitUi64s_Init(&p->CTime);
+}
+
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
+{
+ IAlloc_Free(alloc, p->UnpackPositions);
+ IAlloc_Free(alloc, p->IsDirs);
+
+ IAlloc_Free(alloc, p->FolderToFile);
+ IAlloc_Free(alloc, p->FileToFolder);
+
+ IAlloc_Free(alloc, p->FileNameOffsets);
+ IAlloc_Free(alloc, p->FileNames);
+
+ SzBitUi32s_Free(&p->CRCs, alloc);
+ SzBitUi32s_Free(&p->Attribs, alloc);
+ // SzBitUi32s_Free(&p->Parents, alloc);
+ SzBitUi64s_Free(&p->MTime, alloc);
+ SzBitUi64s_Free(&p->CTime, alloc);
+
+ SzAr_Free(&p->db, alloc);
+ SzArEx_Init(p);
+}
+
+
+static int TestSignatureCandidate(const Byte *testBytes)
+{
+ unsigned i;
+ for (i = 0; i < k7zSignatureSize; i++)
+ if (testBytes[i] != k7zSignature[i])
+ return 0;
+ return 1;
+}
+
+#define SzData_Clear(p) { (p)->Data = NULL; (p)->Size = 0; }
+
+#define SZ_READ_BYTE_SD(_sd_, dest) if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; (_sd_)->Size--; dest = *(_sd_)->Data++;
+#define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest)
+#define SZ_READ_BYTE_2(dest) if (sd.Size == 0) return SZ_ERROR_ARCHIVE; sd.Size--; dest = *sd.Data++;
+
+#define SKIP_DATA(sd, size) { sd->Size -= (size_t)(size); sd->Data += (size_t)(size); }
+#define SKIP_DATA2(sd, size) { sd.Size -= (size_t)(size); sd.Data += (size_t)(size); }
+
+#define SZ_READ_32(dest) if (sd.Size < 4) return SZ_ERROR_ARCHIVE; \
+ dest = GetUi32(sd.Data); SKIP_DATA2(sd, 4);
+
+static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)
+{
+ Byte firstByte, mask;
+ unsigned i;
+ UInt32 v;
+
+ SZ_READ_BYTE(firstByte);
+ if ((firstByte & 0x80) == 0)
+ {
+ *value = firstByte;
+ return SZ_OK;
+ }
+ SZ_READ_BYTE(v);
+ if ((firstByte & 0x40) == 0)
+ {
+ *value = (((UInt32)firstByte & 0x3F) << 8) | v;
+ return SZ_OK;
+ }
+ SZ_READ_BYTE(mask);
+ *value = v | ((UInt32)mask << 8);
+ mask = 0x20;
+ for (i = 2; i < 8; i++)
+ {
+ Byte b;
+ if ((firstByte & mask) == 0)
+ {
+ UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1);
+ *value |= (highPart << (8 * i));
+ return SZ_OK;
+ }
+ SZ_READ_BYTE(b);
+ *value |= ((UInt64)b << (8 * i));
+ mask >>= 1;
+ }
+ return SZ_OK;
+}
+
+
+static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value)
+{
+ Byte firstByte;
+ UInt64 value64;
+ if (sd->Size == 0)
+ return SZ_ERROR_ARCHIVE;
+ firstByte = *sd->Data;
+ if ((firstByte & 0x80) == 0)
+ {
+ *value = firstByte;
+ sd->Data++;
+ sd->Size--;
+ return SZ_OK;
+ }
+ RINOK(ReadNumber(sd, &value64));
+ if (value64 >= (UInt32)0x80000000 - 1)
+ return SZ_ERROR_UNSUPPORTED;
+ if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 4)))
+ return SZ_ERROR_UNSUPPORTED;
+ *value = (UInt32)value64;
+ return SZ_OK;
+}
+
+#define ReadID(sd, value) ReadNumber(sd, value)
+
+static SRes SkipData(CSzData *sd)
+{
+ UInt64 size;
+ RINOK(ReadNumber(sd, &size));
+ if (size > sd->Size)
+ return SZ_ERROR_ARCHIVE;
+ SKIP_DATA(sd, size);
+ return SZ_OK;
+}
+
+static SRes WaitId(CSzData *sd, UInt32 id)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(ReadID(sd, &type));
+ if (type == id)
+ return SZ_OK;
+ if (type == k7zIdEnd)
+ return SZ_ERROR_ARCHIVE;
+ RINOK(SkipData(sd));
+ }
+}
+
+static SRes RememberBitVector(CSzData *sd, UInt32 numItems, const Byte **v)
+{
+ UInt32 numBytes = (numItems + 7) >> 3;
+ if (numBytes > sd->Size)
+ return SZ_ERROR_ARCHIVE;
+ *v = sd->Data;
+ SKIP_DATA(sd, numBytes);
+ return SZ_OK;
+}
+
+static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems)
+{
+ Byte b = 0;
+ unsigned m = 0;
+ UInt32 sum = 0;
+ for (; numItems != 0; numItems--)
+ {
+ if (m == 0)
+ {
+ b = *bits++;
+ m = 8;
+ }
+ m--;
+ sum += ((b >> m) & 1);
+ }
+ return sum;
+}
+
+static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc)
+{
+ Byte allAreDefined;
+ Byte *v2;
+ UInt32 numBytes = (numItems + 7) >> 3;
+ *v = NULL;
+ SZ_READ_BYTE(allAreDefined);
+ if (numBytes == 0)
+ return SZ_OK;
+ if (allAreDefined == 0)
+ {
+ if (numBytes > sd->Size)
+ return SZ_ERROR_ARCHIVE;
+ MY_ALLOC_AND_CPY(*v, numBytes, sd->Data, alloc);
+ SKIP_DATA(sd, numBytes);
+ return SZ_OK;
+ }
+ MY_ALLOC(Byte, *v, numBytes, alloc);
+ v2 = *v;
+ memset(v2, 0xFF, (size_t)numBytes);
+ {
+ unsigned numBits = (unsigned)numItems & 7;
+ if (numBits != 0)
+ v2[numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits));
+ }
+ return SZ_OK;
+}
+
+static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)
+{
+ UInt32 i;
+ CSzData sd;
+ UInt32 *vals;
+ const Byte *defs;
+ MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc);
+ sd = *sd2;
+ defs = crcs->Defs;
+ vals = crcs->Vals;
+ for (i = 0; i < numItems; i++)
+ if (SzBitArray_Check(defs, i))
+ {
+ SZ_READ_32(vals[i]);
+ }
+ else
+ vals[i] = 0;
+ *sd2 = sd;
+ return SZ_OK;
+}
+
+static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)
+{
+ SzBitUi32s_Free(crcs, alloc);
+ RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc));
+ return ReadUi32s(sd, numItems, crcs, alloc);
+}
+
+static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)
+{
+ Byte allAreDefined;
+ UInt32 numDefined = numItems;
+ SZ_READ_BYTE(allAreDefined);
+ if (!allAreDefined)
+ {
+ size_t numBytes = (numItems + 7) >> 3;
+ if (numBytes > sd->Size)
+ return SZ_ERROR_ARCHIVE;
+ numDefined = CountDefinedBits(sd->Data, numItems);
+ SKIP_DATA(sd, numBytes);
+ }
+ if (numDefined > (sd->Size >> 2))
+ return SZ_ERROR_ARCHIVE;
+ SKIP_DATA(sd, (size_t)numDefined * 4);
+ return SZ_OK;
+}
+
+static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAlloc *alloc)
+{
+ RINOK(SzReadNumber32(sd, &p->NumPackStreams));
+
+ RINOK(WaitId(sd, k7zIdSize));
+ MY_ALLOC(UInt64, p->PackPositions, (size_t)p->NumPackStreams + 1, alloc);
+ {
+ UInt64 sum = 0;
+ UInt32 i;
+ UInt32 numPackStreams = p->NumPackStreams;
+ for (i = 0; i < numPackStreams; i++)
+ {
+ UInt64 packSize;
+ p->PackPositions[i] = sum;
+ RINOK(ReadNumber(sd, &packSize));
+ sum += packSize;
+ if (sum < packSize)
+ return SZ_ERROR_ARCHIVE;
+ }
+ p->PackPositions[i] = sum;
+ }
+
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(ReadID(sd, &type));
+ if (type == k7zIdEnd)
+ return SZ_OK;
+ if (type == k7zIdCRC)
+ {
+ /* CRC of packed streams is unused now */
+ RINOK(SkipBitUi32s(sd, p->NumPackStreams));
+ continue;
+ }
+ RINOK(SkipData(sd));
+ }
+}
+
+/*
+static SRes SzReadSwitch(CSzData *sd)
+{
+ Byte external;
+ RINOK(SzReadByte(sd, &external));
+ return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
+}
+*/
+
+#define k_NumCodersStreams_in_Folder_MAX (SZ_NUM_BONDS_IN_FOLDER_MAX + SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
+
+SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd)
+{
+ UInt32 numCoders, i;
+ UInt32 numInStreams = 0;
+ const Byte *dataStart = sd->Data;
+
+ f->NumCoders = 0;
+ f->NumBonds = 0;
+ f->NumPackStreams = 0;
+ f->UnpackStream = 0;
+
+ RINOK(SzReadNumber32(sd, &numCoders));
+ if (numCoders == 0 || numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+
+ for (i = 0; i < numCoders; i++)
+ {
+ Byte mainByte;
+ CSzCoderInfo *coder = f->Coders + i;
+ unsigned idSize, j;
+ UInt64 id;
+
+ SZ_READ_BYTE(mainByte);
+ if ((mainByte & 0xC0) != 0)
+ return SZ_ERROR_UNSUPPORTED;
+
+ idSize = (unsigned)(mainByte & 0xF);
+ if (idSize > sizeof(id))
+ return SZ_ERROR_UNSUPPORTED;
+ if (idSize > sd->Size)
+ return SZ_ERROR_ARCHIVE;
+ id = 0;
+ for (j = 0; j < idSize; j++)
+ {
+ id = ((id << 8) | *sd->Data);
+ sd->Data++;
+ sd->Size--;
+ }
+ if (id > (UInt32)0xFFFFFFFF)
+ return SZ_ERROR_UNSUPPORTED;
+ coder->MethodID = (UInt32)id;
+
+ coder->NumStreams = 1;
+ coder->PropsOffset = 0;
+ coder->PropsSize = 0;
+
+ if ((mainByte & 0x10) != 0)
+ {
+ UInt32 numStreams;
+
+ RINOK(SzReadNumber32(sd, &numStreams));
+ if (numStreams > k_NumCodersStreams_in_Folder_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+ coder->NumStreams = (Byte)numStreams;
+
+ RINOK(SzReadNumber32(sd, &numStreams));
+ if (numStreams != 1)
+ return SZ_ERROR_UNSUPPORTED;
+ }
+
+ numInStreams += coder->NumStreams;
+
+ if (numInStreams > k_NumCodersStreams_in_Folder_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+
+ if ((mainByte & 0x20) != 0)
+ {
+ UInt32 propsSize = 0;
+ RINOK(SzReadNumber32(sd, &propsSize));
+ if (propsSize > sd->Size)
+ return SZ_ERROR_ARCHIVE;
+ if (propsSize >= 0x80)
+ return SZ_ERROR_UNSUPPORTED;
+ coder->PropsOffset = sd->Data - dataStart;
+ coder->PropsSize = (Byte)propsSize;
+ sd->Data += (size_t)propsSize;
+ sd->Size -= (size_t)propsSize;
+ }
+ }
+
+ /*
+ if (numInStreams == 1 && numCoders == 1)
+ {
+ f->NumPackStreams = 1;
+ f->PackStreams[0] = 0;
+ }
+ else
+ */
+ {
+ Byte streamUsed[k_NumCodersStreams_in_Folder_MAX];
+ UInt32 numBonds, numPackStreams;
+
+ numBonds = numCoders - 1;
+ if (numInStreams < numBonds)
+ return SZ_ERROR_ARCHIVE;
+ if (numBonds > SZ_NUM_BONDS_IN_FOLDER_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+ f->NumBonds = numBonds;
+
+ numPackStreams = numInStreams - numBonds;
+ if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+ f->NumPackStreams = numPackStreams;
+
+ for (i = 0; i < numInStreams; i++)
+ streamUsed[i] = False;
+
+ if (numBonds != 0)
+ {
+ Byte coderUsed[SZ_NUM_CODERS_IN_FOLDER_MAX];
+
+ for (i = 0; i < numCoders; i++)
+ coderUsed[i] = False;
+
+ for (i = 0; i < numBonds; i++)
+ {
+ CSzBond *bp = f->Bonds + i;
+
+ RINOK(SzReadNumber32(sd, &bp->InIndex));
+ if (bp->InIndex >= numInStreams || streamUsed[bp->InIndex])
+ return SZ_ERROR_ARCHIVE;
+ streamUsed[bp->InIndex] = True;
+
+ RINOK(SzReadNumber32(sd, &bp->OutIndex));
+ if (bp->OutIndex >= numCoders || coderUsed[bp->OutIndex])
+ return SZ_ERROR_ARCHIVE;
+ coderUsed[bp->OutIndex] = True;
+ }
+
+ for (i = 0; i < numCoders; i++)
+ if (!coderUsed[i])
+ {
+ f->UnpackStream = i;
+ break;
+ }
+
+ if (i == numCoders)
+ return SZ_ERROR_ARCHIVE;
+ }
+
+ if (numPackStreams == 1)
+ {
+ for (i = 0; i < numInStreams; i++)
+ if (!streamUsed[i])
+ break;
+ if (i == numInStreams)
+ return SZ_ERROR_ARCHIVE;
+ f->PackStreams[0] = i;
+ }
+ else
+ for (i = 0; i < numPackStreams; i++)
+ {
+ UInt32 index;
+ RINOK(SzReadNumber32(sd, &index));
+ if (index >= numInStreams || streamUsed[index])
+ return SZ_ERROR_ARCHIVE;
+ streamUsed[index] = True;
+ f->PackStreams[i] = index;
+ }
+ }
+
+ f->NumCoders = numCoders;
+
+ return SZ_OK;
+}
+
+
+static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)
+{
+ CSzData sd;
+ sd = *sd2;
+ for (; num != 0; num--)
+ {
+ Byte firstByte, mask;
+ unsigned i;
+ SZ_READ_BYTE_2(firstByte);
+ if ((firstByte & 0x80) == 0)
+ continue;
+ if ((firstByte & 0x40) == 0)
+ {
+ if (sd.Size == 0)
+ return SZ_ERROR_ARCHIVE;
+ sd.Size--;
+ sd.Data++;
+ continue;
+ }
+ mask = 0x20;
+ for (i = 2; i < 8 && (firstByte & mask) != 0; i++)
+ mask >>= 1;
+ if (i > sd.Size)
+ return SZ_ERROR_ARCHIVE;
+ SKIP_DATA2(sd, i);
+ }
+ *sd2 = sd;
+ return SZ_OK;
+}
+
+
+#define k_Scan_NumCoders_MAX 64
+#define k_Scan_NumCodersStreams_in_Folder_MAX 64
+
+
+static SRes ReadUnpackInfo(CSzAr *p,
+ CSzData *sd2,
+ UInt32 numFoldersMax,
+ const CBuf *tempBufs, UInt32 numTempBufs,
+ ISzAlloc *alloc)
+{
+ CSzData sd;
+
+ UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex;
+ const Byte *startBufPtr;
+ Byte external;
+
+ RINOK(WaitId(sd2, k7zIdFolder));
+
+ RINOK(SzReadNumber32(sd2, &numFolders));
+ if (numFolders > numFoldersMax)
+ return SZ_ERROR_UNSUPPORTED;
+ p->NumFolders = numFolders;
+
+ SZ_READ_BYTE_SD(sd2, external);
+ if (external == 0)
+ sd = *sd2;
+ else
+ {
+ UInt32 index;
+ RINOK(SzReadNumber32(sd2, &index));
+ if (index >= numTempBufs)
+ return SZ_ERROR_ARCHIVE;
+ sd.Data = tempBufs[index].data;
+ sd.Size = tempBufs[index].size;
+ }
+
+ MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc);
+ MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc);
+ MY_ALLOC(UInt32, p->FoToCoderUnpackSizes, (size_t)numFolders + 1, alloc);
+ MY_ALLOC(Byte, p->FoToMainUnpackSizeIndex, (size_t)numFolders, alloc);
+
+ startBufPtr = sd.Data;
+
+ packStreamIndex = 0;
+ numCodersOutStreams = 0;
+
+ for (fo = 0; fo < numFolders; fo++)
+ {
+ UInt32 numCoders, ci, numInStreams = 0;
+
+ p->FoCodersOffsets[fo] = sd.Data - startBufPtr;
+
+ RINOK(SzReadNumber32(&sd, &numCoders));
+ if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+
+ for (ci = 0; ci < numCoders; ci++)
+ {
+ Byte mainByte;
+ unsigned idSize;
+ UInt32 coderInStreams;
+
+ SZ_READ_BYTE_2(mainByte);
+ if ((mainByte & 0xC0) != 0)
+ return SZ_ERROR_UNSUPPORTED;
+ idSize = (mainByte & 0xF);
+ if (idSize > 8)
+ return SZ_ERROR_UNSUPPORTED;
+ if (idSize > sd.Size)
+ return SZ_ERROR_ARCHIVE;
+ SKIP_DATA2(sd, idSize);
+
+ coderInStreams = 1;
+
+ if ((mainByte & 0x10) != 0)
+ {
+ UInt32 coderOutStreams;
+ RINOK(SzReadNumber32(&sd, &coderInStreams));
+ RINOK(SzReadNumber32(&sd, &coderOutStreams));
+ if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX || coderOutStreams != 1)
+ return SZ_ERROR_UNSUPPORTED;
+ }
+
+ numInStreams += coderInStreams;
+
+ if ((mainByte & 0x20) != 0)
+ {
+ UInt32 propsSize;
+ RINOK(SzReadNumber32(&sd, &propsSize));
+ if (propsSize > sd.Size)
+ return SZ_ERROR_ARCHIVE;
+ SKIP_DATA2(sd, propsSize);
+ }
+ }
+
+ {
+ UInt32 indexOfMainStream = 0;
+ UInt32 numPackStreams = 1;
+
+ if (numCoders != 1 || numInStreams != 1)
+ {
+ Byte streamUsed[k_Scan_NumCodersStreams_in_Folder_MAX];
+ Byte coderUsed[k_Scan_NumCoders_MAX];
+
+ UInt32 i;
+ UInt32 numBonds = numCoders - 1;
+ if (numInStreams < numBonds)
+ return SZ_ERROR_ARCHIVE;
+
+ if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+
+ for (i = 0; i < numInStreams; i++)
+ streamUsed[i] = False;
+ for (i = 0; i < numCoders; i++)
+ coderUsed[i] = False;
+
+ for (i = 0; i < numBonds; i++)
+ {
+ UInt32 index;
+
+ RINOK(SzReadNumber32(&sd, &index));
+ if (index >= numInStreams || streamUsed[index])
+ return SZ_ERROR_ARCHIVE;
+ streamUsed[index] = True;
+
+ RINOK(SzReadNumber32(&sd, &index));
+ if (index >= numCoders || coderUsed[index])
+ return SZ_ERROR_ARCHIVE;
+ coderUsed[index] = True;
+ }
+
+ numPackStreams = numInStreams - numBonds;
+
+ if (numPackStreams != 1)
+ for (i = 0; i < numPackStreams; i++)
+ {
+ UInt32 index;
+ RINOK(SzReadNumber32(&sd, &index));
+ if (index >= numInStreams || streamUsed[index])
+ return SZ_ERROR_ARCHIVE;
+ streamUsed[index] = True;
+ }
+
+ for (i = 0; i < numCoders; i++)
+ if (!coderUsed[i])
+ {
+ indexOfMainStream = i;
+ break;
+ }
+
+ if (i == numCoders)
+ return SZ_ERROR_ARCHIVE;
+ }
+
+ p->FoStartPackStreamIndex[fo] = packStreamIndex;
+ p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;
+ p->FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
+ numCodersOutStreams += numCoders;
+ if (numCodersOutStreams < numCoders)
+ return SZ_ERROR_UNSUPPORTED;
+
+ packStreamIndex += numPackStreams;
+ if (packStreamIndex < numPackStreams)
+ return SZ_ERROR_UNSUPPORTED;
+
+ if (packStreamIndex > p->NumPackStreams)
+ return SZ_ERROR_ARCHIVE;
+ }
+ }
+
+ p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;
+
+ {
+ size_t dataSize = sd.Data - startBufPtr;
+ p->FoStartPackStreamIndex[fo] = packStreamIndex;
+ p->FoCodersOffsets[fo] = dataSize;
+ MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc);
+ }
+
+ if (external != 0)
+ {
+ if (sd.Size != 0)
+ return SZ_ERROR_ARCHIVE;
+ sd = *sd2;
+ }
+
+ RINOK(WaitId(&sd, k7zIdCodersUnpackSize));
+
+ MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc);
+ {
+ UInt32 i;
+ for (i = 0; i < numCodersOutStreams; i++)
+ {
+ RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i));
+ }
+ }
+
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(ReadID(&sd, &type));
+ if (type == k7zIdEnd)
+ {
+ *sd2 = sd;
+ return SZ_OK;
+ }
+ if (type == k7zIdCRC)
+ {
+ RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc));
+ continue;
+ }
+ RINOK(SkipData(&sd));
+ }
+}
+
+
+UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex)
+{
+ return p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex] + p->FoToMainUnpackSizeIndex[folderIndex]];
+}
+
+
+typedef struct
+{
+ UInt32 NumTotalSubStreams;
+ UInt32 NumSubDigests;
+ CSzData sdNumSubStreams;
+ CSzData sdSizes;
+ CSzData sdCRCs;
+} CSubStreamInfo;
+
+
+static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
+{
+ UInt64 type = 0;
+ UInt32 numSubDigests = 0;
+ UInt32 numFolders = p->NumFolders;
+ UInt32 numUnpackStreams = numFolders;
+ UInt32 numUnpackSizesInData = 0;
+
+ for (;;)
+ {
+ RINOK(ReadID(sd, &type));
+ if (type == k7zIdNumUnpackStream)
+ {
+ UInt32 i;
+ ssi->sdNumSubStreams.Data = sd->Data;
+ numUnpackStreams = 0;
+ numSubDigests = 0;
+ for (i = 0; i < numFolders; i++)
+ {
+ UInt32 numStreams;
+ RINOK(SzReadNumber32(sd, &numStreams));
+ if (numUnpackStreams > numUnpackStreams + numStreams)
+ return SZ_ERROR_UNSUPPORTED;
+ numUnpackStreams += numStreams;
+ if (numStreams != 0)
+ numUnpackSizesInData += (numStreams - 1);
+ if (numStreams != 1 || !SzBitWithVals_Check(&p->FolderCRCs, i))
+ numSubDigests += numStreams;
+ }
+ ssi->sdNumSubStreams.Size = sd->Data - ssi->sdNumSubStreams.Data;
+ continue;
+ }
+ if (type == k7zIdCRC || type == k7zIdSize || type == k7zIdEnd)
+ break;
+ RINOK(SkipData(sd));
+ }
+
+ if (!ssi->sdNumSubStreams.Data)
+ {
+ numSubDigests = numFolders;
+ if (p->FolderCRCs.Defs)
+ numSubDigests = numFolders - CountDefinedBits(p->FolderCRCs.Defs, numFolders);
+ }
+
+ ssi->NumTotalSubStreams = numUnpackStreams;
+ ssi->NumSubDigests = numSubDigests;
+
+ if (type == k7zIdSize)
+ {
+ ssi->sdSizes.Data = sd->Data;
+ RINOK(SkipNumbers(sd, numUnpackSizesInData));
+ ssi->sdSizes.Size = sd->Data - ssi->sdSizes.Data;
+ RINOK(ReadID(sd, &type));
+ }
+
+ for (;;)
+ {
+ if (type == k7zIdEnd)
+ return SZ_OK;
+ if (type == k7zIdCRC)
+ {
+ ssi->sdCRCs.Data = sd->Data;
+ RINOK(SkipBitUi32s(sd, numSubDigests));
+ ssi->sdCRCs.Size = sd->Data - ssi->sdCRCs.Data;
+ }
+ else
+ {
+ RINOK(SkipData(sd));
+ }
+ RINOK(ReadID(sd, &type));
+ }
+}
+
+static SRes SzReadStreamsInfo(CSzAr *p,
+ CSzData *sd,
+ UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,
+ UInt64 *dataOffset,
+ CSubStreamInfo *ssi,
+ ISzAlloc *alloc)
+{
+ UInt64 type;
+
+ SzData_Clear(&ssi->sdSizes);
+ SzData_Clear(&ssi->sdCRCs);
+ SzData_Clear(&ssi->sdNumSubStreams);
+
+ *dataOffset = 0;
+ RINOK(ReadID(sd, &type));
+ if (type == k7zIdPackInfo)
+ {
+ RINOK(ReadNumber(sd, dataOffset));
+ RINOK(ReadPackInfo(p, sd, alloc));
+ RINOK(ReadID(sd, &type));
+ }
+ if (type == k7zIdUnpackInfo)
+ {
+ RINOK(ReadUnpackInfo(p, sd, numFoldersMax, tempBufs, numTempBufs, alloc));
+ RINOK(ReadID(sd, &type));
+ }
+ if (type == k7zIdSubStreamsInfo)
+ {
+ RINOK(ReadSubStreamsInfo(p, sd, ssi));
+ RINOK(ReadID(sd, &type));
+ }
+ else
+ {
+ ssi->NumTotalSubStreams = p->NumFolders;
+ // ssi->NumSubDigests = 0;
+ }
+
+ return (type == k7zIdEnd ? SZ_OK : SZ_ERROR_UNSUPPORTED);
+}
+
+static SRes SzReadAndDecodePackedStreams(
+ ILookInStream *inStream,
+ CSzData *sd,
+ CBuf *tempBufs,
+ UInt32 numFoldersMax,
+ UInt64 baseOffset,
+ CSzAr *p,
+ ISzAlloc *allocTemp)
+{
+ UInt64 dataStartPos;
+ UInt32 fo;
+ CSubStreamInfo ssi;
+
+ RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp));
+
+ dataStartPos += baseOffset;
+ if (p->NumFolders == 0)
+ return SZ_ERROR_ARCHIVE;
+
+ for (fo = 0; fo < p->NumFolders; fo++)
+ Buf_Init(tempBufs + fo);
+
+ for (fo = 0; fo < p->NumFolders; fo++)
+ {
+ CBuf *tempBuf = tempBufs + fo;
+ UInt64 unpackSize = SzAr_GetFolderUnpackSize(p, fo);
+ if ((size_t)unpackSize != unpackSize)
+ return SZ_ERROR_MEM;
+ if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp))
+ return SZ_ERROR_MEM;
+ }
+
+ for (fo = 0; fo < p->NumFolders; fo++)
+ {
+ const CBuf *tempBuf = tempBufs + fo;
+ RINOK(LookInStream_SeekTo(inStream, dataStartPos));
+ RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp));
+ }
+
+ return SZ_OK;
+}
+
+static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size_t *offsets)
+{
+ size_t pos = 0;
+ *offsets++ = 0;
+ if (numFiles == 0)
+ return (size == 0) ? SZ_OK : SZ_ERROR_ARCHIVE;
+ if (size < 2)
+ return SZ_ERROR_ARCHIVE;
+ if (data[size - 2] != 0 || data[size - 1] != 0)
+ return SZ_ERROR_ARCHIVE;
+ do
+ {
+ const Byte *p;
+ if (pos == size)
+ return SZ_ERROR_ARCHIVE;
+ for (p = data + pos;
+ #ifdef _WIN32
+ *(const UInt16 *)p != 0
+ #else
+ p[0] != 0 || p[1] != 0
+ #endif
+ ; p += 2);
+ pos = p - data + 2;
+ *offsets++ = (pos >> 1);
+ }
+ while (--numFiles);
+ return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
+}
+
+static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
+ CSzData *sd2,
+ const CBuf *tempBufs, UInt32 numTempBufs,
+ ISzAlloc *alloc)
+{
+ CSzData sd;
+ UInt32 i;
+ CNtfsFileTime *vals;
+ Byte *defs;
+ Byte external;
+
+ RINOK(ReadBitVector(sd2, num, &p->Defs, alloc));
+
+ SZ_READ_BYTE_SD(sd2, external);
+ if (external == 0)
+ sd = *sd2;
+ else
+ {
+ UInt32 index;
+ RINOK(SzReadNumber32(sd2, &index));
+ if (index >= numTempBufs)
+ return SZ_ERROR_ARCHIVE;
+ sd.Data = tempBufs[index].data;
+ sd.Size = tempBufs[index].size;
+ }
+
+ MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc);
+ vals = p->Vals;
+ defs = p->Defs;
+ for (i = 0; i < num; i++)
+ if (SzBitArray_Check(defs, i))
+ {
+ if (sd.Size < 8)
+ return SZ_ERROR_ARCHIVE;
+ vals[i].Low = GetUi32(sd.Data);
+ vals[i].High = GetUi32(sd.Data + 4);
+ SKIP_DATA2(sd, 8);
+ }
+ else
+ vals[i].High = vals[i].Low = 0;
+
+ if (external == 0)
+ *sd2 = sd;
+
+ return SZ_OK;
+}
+
+
+#define NUM_ADDITIONAL_STREAMS_MAX 8
+
+
+static SRes SzReadHeader2(
+ CSzArEx *p, /* allocMain */
+ CSzData *sd,
+ ILookInStream *inStream,
+ CBuf *tempBufs, UInt32 *numTempBufs,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp
+ )
+{
+ UInt64 type;
+ UInt32 numFiles = 0;
+ UInt32 numEmptyStreams = 0;
+ CSubStreamInfo ssi;
+ const Byte *emptyStreams = NULL;
+ const Byte *emptyFiles = NULL;
+
+ SzData_Clear(&ssi.sdSizes);
+ SzData_Clear(&ssi.sdCRCs);
+ SzData_Clear(&ssi.sdNumSubStreams);
+
+ ssi.NumSubDigests = 0;
+ ssi.NumTotalSubStreams = 0;
+
+ RINOK(ReadID(sd, &type));
+
+ if (type == k7zIdArchiveProperties)
+ {
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(ReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ RINOK(SkipData(sd));
+ }
+ RINOK(ReadID(sd, &type));
+ }
+
+ if (type == k7zIdAdditionalStreamsInfo)
+ {
+ CSzAr tempAr;
+ SRes res;
+
+ SzAr_Init(&tempAr);
+ res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX,
+ p->startPosAfterHeader, &tempAr, allocTemp);
+ *numTempBufs = tempAr.NumFolders;
+ SzAr_Free(&tempAr, allocTemp);
+
+ if (res != SZ_OK)
+ return res;
+ RINOK(ReadID(sd, &type));
+ }
+
+ if (type == k7zIdMainStreamsInfo)
+ {
+ RINOK(SzReadStreamsInfo(&p->db, sd, (UInt32)1 << 30, tempBufs, *numTempBufs,
+ &p->dataPos, &ssi, allocMain));
+ p->dataPos += p->startPosAfterHeader;
+ RINOK(ReadID(sd, &type));
+ }
+
+ if (type == k7zIdEnd)
+ {
+ return SZ_OK;
+ }
+
+ if (type != k7zIdFilesInfo)
+ return SZ_ERROR_ARCHIVE;
+
+ RINOK(SzReadNumber32(sd, &numFiles));
+ p->NumFiles = numFiles;
+
+ for (;;)
+ {
+ UInt64 type;
+ UInt64 size;
+ RINOK(ReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ RINOK(ReadNumber(sd, &size));
+ if (size > sd->Size)
+ return SZ_ERROR_ARCHIVE;
+
+ if (type >= ((UInt32)1 << 8))
+ {
+ SKIP_DATA(sd, size);
+ }
+ else switch ((unsigned)type)
+ {
+ case k7zIdName:
+ {
+ size_t namesSize;
+ const Byte *namesData;
+ Byte external;
+
+ SZ_READ_BYTE(external);
+ if (external == 0)
+ {
+ namesSize = (size_t)size - 1;
+ namesData = sd->Data;
+ }
+ else
+ {
+ UInt32 index;
+ RINOK(SzReadNumber32(sd, &index));
+ if (index >= *numTempBufs)
+ return SZ_ERROR_ARCHIVE;
+ namesData = (tempBufs)[index].data;
+ namesSize = (tempBufs)[index].size;
+ }
+
+ if ((namesSize & 1) != 0)
+ return SZ_ERROR_ARCHIVE;
+ MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
+ MY_ALLOC_ZE_AND_CPY(p->FileNames, namesSize, namesData, allocMain);
+ RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets))
+ if (external == 0)
+ {
+ SKIP_DATA(sd, namesSize);
+ }
+ break;
+ }
+ case k7zIdEmptyStream:
+ {
+ RINOK(RememberBitVector(sd, numFiles, &emptyStreams));
+ numEmptyStreams = CountDefinedBits(emptyStreams, numFiles);
+ emptyFiles = NULL;
+ break;
+ }
+ case k7zIdEmptyFile:
+ {
+ RINOK(RememberBitVector(sd, numEmptyStreams, &emptyFiles));
+ break;
+ }
+ case k7zIdWinAttrib:
+ {
+ Byte external;
+ CSzData sdSwitch;
+ CSzData *sdPtr;
+ SzBitUi32s_Free(&p->Attribs, allocMain);
+ RINOK(ReadBitVector(sd, numFiles, &p->Attribs.Defs, allocMain));
+
+ SZ_READ_BYTE(external);
+ if (external == 0)
+ sdPtr = sd;
+ else
+ {
+ UInt32 index;
+ RINOK(SzReadNumber32(sd, &index));
+ if (index >= *numTempBufs)
+ return SZ_ERROR_ARCHIVE;
+ sdSwitch.Data = (tempBufs)[index].data;
+ sdSwitch.Size = (tempBufs)[index].size;
+ sdPtr = &sdSwitch;
+ }
+ RINOK(ReadUi32s(sdPtr, numFiles, &p->Attribs, allocMain));
+ break;
+ }
+ /*
+ case k7zParent:
+ {
+ SzBitUi32s_Free(&p->Parents, allocMain);
+ RINOK(ReadBitVector(sd, numFiles, &p->Parents.Defs, allocMain));
+ RINOK(SzReadSwitch(sd));
+ RINOK(ReadUi32s(sd, numFiles, &p->Parents, allocMain));
+ break;
+ }
+ */
+ case k7zIdMTime: RINOK(ReadTime(&p->MTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break;
+ case k7zIdCTime: RINOK(ReadTime(&p->CTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break;
+ default:
+ {
+ SKIP_DATA(sd, size);
+ }
+ }
+ }
+
+ if (numFiles - numEmptyStreams != ssi.NumTotalSubStreams)
+ return SZ_ERROR_ARCHIVE;
+
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(ReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ RINOK(SkipData(sd));
+ }
+
+ {
+ UInt32 i;
+ UInt32 emptyFileIndex = 0;
+ UInt32 folderIndex = 0;
+ UInt32 remSubStreams = 0;
+ UInt32 numSubStreams = 0;
+ UInt64 unpackPos = 0;
+ const Byte *digestsDefs = NULL;
+ const Byte *digestsVals = NULL;
+ UInt32 digestsValsIndex = 0;
+ UInt32 digestIndex;
+ Byte allDigestsDefined = 0;
+ Byte isDirMask = 0;
+ Byte crcMask = 0;
+ Byte mask = 0x80;
+
+ MY_ALLOC(UInt32, p->FolderToFile, p->db.NumFolders + 1, allocMain);
+ MY_ALLOC_ZE(UInt32, p->FileToFolder, p->NumFiles, allocMain);
+ MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain);
+ MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain);
+
+ RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain));
+
+ if (ssi.sdCRCs.Size != 0)
+ {
+ SZ_READ_BYTE_SD(&ssi.sdCRCs, allDigestsDefined);
+ if (allDigestsDefined)
+ digestsVals = ssi.sdCRCs.Data;
+ else
+ {
+ size_t numBytes = (ssi.NumSubDigests + 7) >> 3;
+ digestsDefs = ssi.sdCRCs.Data;
+ digestsVals = digestsDefs + numBytes;
+ }
+ }
+
+ digestIndex = 0;
+
+ for (i = 0; i < numFiles; i++, mask >>= 1)
+ {
+ if (mask == 0)
+ {
+ UInt32 byteIndex = (i - 1) >> 3;
+ p->IsDirs[byteIndex] = isDirMask;
+ p->CRCs.Defs[byteIndex] = crcMask;
+ isDirMask = 0;
+ crcMask = 0;
+ mask = 0x80;
+ }
+
+ p->UnpackPositions[i] = unpackPos;
+ p->CRCs.Vals[i] = 0;
+
+ if (emptyStreams && SzBitArray_Check(emptyStreams, i))
+ {
+ if (emptyFiles)
+ {
+ if (!SzBitArray_Check(emptyFiles, emptyFileIndex))
+ isDirMask |= mask;
+ emptyFileIndex++;
+ }
+ else
+ isDirMask |= mask;
+ if (remSubStreams == 0)
+ {
+ p->FileToFolder[i] = (UInt32)-1;
+ continue;
+ }
+ }
+
+ if (remSubStreams == 0)
+ {
+ for (;;)
+ {
+ if (folderIndex >= p->db.NumFolders)
+ return SZ_ERROR_ARCHIVE;
+ p->FolderToFile[folderIndex] = i;
+ numSubStreams = 1;
+ if (ssi.sdNumSubStreams.Data)
+ {
+ RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams));
+ }
+ remSubStreams = numSubStreams;
+ if (numSubStreams != 0)
+ break;
+ {
+ UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
+ unpackPos += folderUnpackSize;
+ if (unpackPos < folderUnpackSize)
+ return SZ_ERROR_ARCHIVE;
+ }
+
+ folderIndex++;
+ }
+ }
+
+ p->FileToFolder[i] = folderIndex;
+
+ if (emptyStreams && SzBitArray_Check(emptyStreams, i))
+ continue;
+
+ if (--remSubStreams == 0)
+ {
+ UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
+ UInt64 startFolderUnpackPos = p->UnpackPositions[p->FolderToFile[folderIndex]];
+ if (folderUnpackSize < unpackPos - startFolderUnpackPos)
+ return SZ_ERROR_ARCHIVE;
+ unpackPos = startFolderUnpackPos + folderUnpackSize;
+ if (unpackPos < folderUnpackSize)
+ return SZ_ERROR_ARCHIVE;
+
+ if (numSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i))
+ {
+ p->CRCs.Vals[i] = p->db.FolderCRCs.Vals[folderIndex];
+ crcMask |= mask;
+ }
+ else if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex)))
+ {
+ p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4);
+ digestsValsIndex++;
+ crcMask |= mask;
+ }
+
+ folderIndex++;
+ }
+ else
+ {
+ UInt64 v;
+ RINOK(ReadNumber(&ssi.sdSizes, &v));
+ unpackPos += v;
+ if (unpackPos < v)
+ return SZ_ERROR_ARCHIVE;
+ if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex)))
+ {
+ p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4);
+ digestsValsIndex++;
+ crcMask |= mask;
+ }
+ }
+ }
+
+ if (mask != 0x80)
+ {
+ UInt32 byteIndex = (i - 1) >> 3;
+ p->IsDirs[byteIndex] = isDirMask;
+ p->CRCs.Defs[byteIndex] = crcMask;
+ }
+
+ p->UnpackPositions[i] = unpackPos;
+
+ if (remSubStreams != 0)
+ return SZ_ERROR_ARCHIVE;
+
+ for (;;)
+ {
+ p->FolderToFile[folderIndex] = i;
+ if (folderIndex >= p->db.NumFolders)
+ break;
+ if (!ssi.sdNumSubStreams.Data)
+ return SZ_ERROR_ARCHIVE;
+ RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams));
+ if (numSubStreams != 0)
+ return SZ_ERROR_ARCHIVE;
+ /*
+ {
+ UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
+ unpackPos += folderUnpackSize;
+ if (unpackPos < folderUnpackSize)
+ return SZ_ERROR_ARCHIVE;
+ }
+ */
+ folderIndex++;
+ }
+
+ if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0)
+ return SZ_ERROR_ARCHIVE;
+ }
+
+ return SZ_OK;
+}
+
+
+static SRes SzReadHeader(
+ CSzArEx *p,
+ CSzData *sd,
+ ILookInStream *inStream,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ UInt32 i;
+ UInt32 numTempBufs = 0;
+ SRes res;
+ CBuf tempBufs[NUM_ADDITIONAL_STREAMS_MAX];
+
+ for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
+ Buf_Init(tempBufs + i);
+
+ res = SzReadHeader2(p, sd, inStream,
+ tempBufs, &numTempBufs,
+ allocMain, allocTemp);
+
+ for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
+ Buf_Free(tempBufs + i, allocTemp);
+
+ RINOK(res);
+
+ if (sd->Size != 0)
+ return SZ_ERROR_FAIL;
+
+ return res;
+}
+
+static SRes SzArEx_Open2(
+ CSzArEx *p,
+ ILookInStream *inStream,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ Byte header[k7zStartHeaderSize];
+ Int64 startArcPos;
+ UInt64 nextHeaderOffset, nextHeaderSize;
+ size_t nextHeaderSizeT;
+ UInt32 nextHeaderCRC;
+ CBuf buf;
+ SRes res;
+
+ startArcPos = 0;
+ RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
+
+ RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
+
+ if (!TestSignatureCandidate(header))
+ return SZ_ERROR_NO_ARCHIVE;
+ if (header[6] != k7zMajorVersion)
+ return SZ_ERROR_UNSUPPORTED;
+
+ nextHeaderOffset = GetUi64(header + 12);
+ nextHeaderSize = GetUi64(header + 20);
+ nextHeaderCRC = GetUi32(header + 28);
+
+ p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;
+
+ if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
+ return SZ_ERROR_CRC;
+
+ nextHeaderSizeT = (size_t)nextHeaderSize;
+ if (nextHeaderSizeT != nextHeaderSize)
+ return SZ_ERROR_MEM;
+ if (nextHeaderSizeT == 0)
+ return SZ_OK;
+ if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
+ nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
+ return SZ_ERROR_NO_ARCHIVE;
+
+ {
+ Int64 pos = 0;
+ RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
+ if ((UInt64)pos < startArcPos + nextHeaderOffset ||
+ (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
+ (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
+ return SZ_ERROR_INPUT_EOF;
+ }
+
+ RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));
+
+ if (!Buf_Create(&buf, nextHeaderSizeT, allocTemp))
+ return SZ_ERROR_MEM;
+
+ res = LookInStream_Read(inStream, buf.data, nextHeaderSizeT);
+
+ if (res == SZ_OK)
+ {
+ res = SZ_ERROR_ARCHIVE;
+ if (CrcCalc(buf.data, nextHeaderSizeT) == nextHeaderCRC)
+ {
+ CSzData sd;
+ UInt64 type;
+ sd.Data = buf.data;
+ sd.Size = buf.size;
+
+ res = ReadID(&sd, &type);
+
+ if (res == SZ_OK && type == k7zIdEncodedHeader)
+ {
+ CSzAr tempAr;
+ CBuf tempBuf;
+ Buf_Init(&tempBuf);
+
+ SzAr_Init(&tempAr);
+ res = SzReadAndDecodePackedStreams(inStream, &sd, &tempBuf, 1, p->startPosAfterHeader, &tempAr, allocTemp);
+ SzAr_Free(&tempAr, allocTemp);
+
+ if (res != SZ_OK)
+ {
+ Buf_Free(&tempBuf, allocTemp);
+ }
+ else
+ {
+ Buf_Free(&buf, allocTemp);
+ buf.data = tempBuf.data;
+ buf.size = tempBuf.size;
+ sd.Data = buf.data;
+ sd.Size = buf.size;
+ res = ReadID(&sd, &type);
+ }
+ }
+
+ if (res == SZ_OK)
+ {
+ if (type == k7zIdHeader)
+ {
+ /*
+ CSzData sd2;
+ unsigned ttt;
+ for (ttt = 0; ttt < 40000; ttt++)
+ {
+ SzArEx_Free(p, allocMain);
+ sd2 = sd;
+ res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp);
+ if (res != SZ_OK)
+ break;
+ }
+ */
+ res = SzReadHeader(p, &sd, inStream, allocMain, allocTemp);
+ }
+ else
+ res = SZ_ERROR_UNSUPPORTED;
+ }
+ }
+ }
+
+ Buf_Free(&buf, allocTemp);
+ return res;
+}
+
+
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
+ ISzAlloc *allocMain, ISzAlloc *allocTemp)
+{
+ SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
+ if (res != SZ_OK)
+ SzArEx_Free(p, allocMain);
+ return res;
+}
+
+
+SRes SzArEx_Extract(
+ const CSzArEx *p,
+ ILookInStream *inStream,
+ UInt32 fileIndex,
+ UInt32 *blockIndex,
+ Byte **tempBuf,
+ size_t *outBufferSize,
+ size_t *offset,
+ size_t *outSizeProcessed,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ UInt32 folderIndex = p->FileToFolder[fileIndex];
+ SRes res = SZ_OK;
+
+ *offset = 0;
+ *outSizeProcessed = 0;
+
+ if (folderIndex == (UInt32)-1)
+ {
+ IAlloc_Free(allocMain, *tempBuf);
+ *blockIndex = folderIndex;
+ *tempBuf = NULL;
+ *outBufferSize = 0;
+ return SZ_OK;
+ }
+
+ if (*tempBuf == NULL || *blockIndex != folderIndex)
+ {
+ UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
+ /*
+ UInt64 unpackSizeSpec =
+ p->UnpackPositions[p->FolderToFile[folderIndex + 1]] -
+ p->UnpackPositions[p->FolderToFile[folderIndex]];
+ */
+ size_t unpackSize = (size_t)unpackSizeSpec;
+
+ if (unpackSize != unpackSizeSpec)
+ return SZ_ERROR_MEM;
+ *blockIndex = folderIndex;
+ IAlloc_Free(allocMain, *tempBuf);
+ *tempBuf = NULL;
+
+ if (res == SZ_OK)
+ {
+ *outBufferSize = unpackSize;
+ if (unpackSize != 0)
+ {
+ *tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
+ if (*tempBuf == NULL)
+ res = SZ_ERROR_MEM;
+ }
+
+ if (res == SZ_OK)
+ {
+ res = SzAr_DecodeFolder(&p->db, folderIndex,
+ inStream, p->dataPos, *tempBuf, unpackSize, allocTemp);
+ }
+ }
+ }
+
+ if (res == SZ_OK)
+ {
+ UInt64 unpackPos = p->UnpackPositions[fileIndex];
+ *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]);
+ *outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos);
+ if (*offset + *outSizeProcessed > *outBufferSize)
+ return SZ_ERROR_FAIL;
+ if (SzBitWithVals_Check(&p->CRCs, fileIndex))
+ if (CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex])
+ res = SZ_ERROR_CRC;
+ }
+
+ return res;
+}
+
+
+size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
+{
+ size_t offs = p->FileNameOffsets[fileIndex];
+ size_t len = p->FileNameOffsets[fileIndex + 1] - offs;
+ if (dest != 0)
+ {
+ size_t i;
+ const Byte *src = p->FileNames + offs * 2;
+ for (i = 0; i < len; i++)
+ dest[i] = GetUi16(src + i * 2);
+ }
+ return len;
+}
+
+/*
+size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex)
+{
+ size_t len;
+ if (!p->FileNameOffsets)
+ return 1;
+ len = 0;
+ for (;;)
+ {
+ UInt32 parent = (UInt32)(Int32)-1;
+ len += p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
+ if SzBitWithVals_Check(&p->Parents, fileIndex)
+ parent = p->Parents.Vals[fileIndex];
+ if (parent == (UInt32)(Int32)-1)
+ return len;
+ fileIndex = parent;
+ }
+}
+
+UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
+{
+ Bool needSlash;
+ if (!p->FileNameOffsets)
+ {
+ *(--dest) = 0;
+ return dest;
+ }
+ needSlash = False;
+ for (;;)
+ {
+ UInt32 parent = (UInt32)(Int32)-1;
+ size_t curLen = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
+ SzArEx_GetFileNameUtf16(p, fileIndex, dest - curLen);
+ if (needSlash)
+ *(dest - 1) = '/';
+ needSlash = True;
+ dest -= curLen;
+
+ if SzBitWithVals_Check(&p->Parents, fileIndex)
+ parent = p->Parents.Vals[fileIndex];
+ if (parent == (UInt32)(Int32)-1)
+ return dest;
+ fileIndex = parent;
+ }
+}
+*/
diff --git a/3rdparty/lzma/C/7zBuf.c b/3rdparty/lzma/C/7zBuf.c
index 14e7f4e2b92..089a5c4f21f 100644
--- a/3rdparty/lzma/C/7zBuf.c
+++ b/3rdparty/lzma/C/7zBuf.c
@@ -1,7 +1,7 @@
/* 7zBuf.c -- Byte Buffer
-2008-03-28
-Igor Pavlov
-Public domain */
+2013-01-21 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "7zBuf.h"
diff --git a/3rdparty/lzma/C/7zBuf.h b/3rdparty/lzma/C/7zBuf.h
index e9f2f316d0d..65f1d7a716e 100644
--- a/3rdparty/lzma/C/7zBuf.h
+++ b/3rdparty/lzma/C/7zBuf.h
@@ -1,14 +1,12 @@
/* 7zBuf.h -- Byte Buffer
-2009-02-07 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __7Z_BUF_H
#define __7Z_BUF_H
-#include "Types.h"
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
typedef struct
{
@@ -32,8 +30,6 @@ void DynBuf_SeekToBeg(CDynBuf *p);
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/7zBuf2.c b/3rdparty/lzma/C/7zBuf2.c
index 8d17e0dcf80..430f76bf830 100644
--- a/3rdparty/lzma/C/7zBuf2.c
+++ b/3rdparty/lzma/C/7zBuf2.c
@@ -1,7 +1,10 @@
/* 7zBuf2.c -- Byte Buffer
-2008-10-04 : Igor Pavlov : Public domain */
+2014-08-22 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <string.h>
+
#include "7zBuf.h"
void DynBuf_Construct(CDynBuf *p)
@@ -31,8 +34,11 @@ int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)
alloc->Free(alloc, p->data);
p->data = data;
}
- memcpy(p->data + p->pos, buf, size);
- p->pos += size;
+ if (size != 0)
+ {
+ memcpy(p->data + p->pos, buf, size);
+ p->pos += size;
+ }
return 1;
}
diff --git a/3rdparty/lzma/C/7zCrc.c b/3rdparty/lzma/C/7zCrc.c
index a73b1379bad..dc6d6abdc0a 100644
--- a/3rdparty/lzma/C/7zCrc.c
+++ b/3rdparty/lzma/C/7zCrc.c
@@ -1,26 +1,35 @@
/* 7zCrc.c -- CRC32 init
-2010-12-01 : Igor Pavlov : Public domain */
+2015-03-10 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "7zCrc.h"
#include "CpuArch.h"
#define kCrcPoly 0xEDB88320
-#if defined(MY_CPU_LE)
- #define CRC_NUM_TABLES 4
+#ifdef MY_CPU_LE
+ #define CRC_NUM_TABLES 8
#else
- #define CRC_NUM_TABLES 5
+ #define CRC_NUM_TABLES 9
+
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
+
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
+ UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
#ifndef MY_CPU_BE
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
+ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
-static CRC_FUNC g_CrcUpdate;
+CRC_FUNC g_CrcUpdateT4;
+CRC_FUNC g_CrcUpdateT8;
+CRC_FUNC g_CrcUpdate;
+
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
@@ -33,6 +42,17 @@ UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
}
+#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+
+UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
+{
+ const Byte *p = (const Byte *)data;
+ const Byte *pEnd = p + size;
+ for (; p != pEnd; p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ return v;
+}
+
void MY_FAST_CALL CrcGenerateTable()
{
UInt32 i;
@@ -49,22 +69,43 @@ void MY_FAST_CALL CrcGenerateTable()
UInt32 r = g_CrcTable[i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
+
+ #if CRC_NUM_TABLES < 4
+ g_CrcUpdate = CrcUpdateT1;
+
+ #else
+
#ifdef MY_CPU_LE
- g_CrcUpdate = CrcUpdateT4;
+ g_CrcUpdateT4 = CrcUpdateT4;
+ g_CrcUpdate = CrcUpdateT4;
+
+ #if CRC_NUM_TABLES >= 8
+ g_CrcUpdateT8 = CrcUpdateT8;
- #if CRC_NUM_TABLES == 8
- if (!CPU_Is_InOrder())
- g_CrcUpdate = CrcUpdateT8;
- #endif
+ #ifdef MY_CPU_X86_OR_AMD64
+ if (!CPU_Is_InOrder())
+ g_CrcUpdate = CrcUpdateT8;
+ #endif
+ #endif
#else
{
#ifndef MY_CPU_BE
- UInt32 k = 1;
- if (*(const Byte *)&k == 1)
+ UInt32 k = 0x01020304;
+ const Byte *p = (const Byte *)&k;
+ if (p[0] == 4 && p[1] == 3)
+ {
+ g_CrcUpdateT4 = CrcUpdateT4;
g_CrcUpdate = CrcUpdateT4;
+ #if CRC_NUM_TABLES >= 8
+ g_CrcUpdateT8 = CrcUpdateT8;
+ // g_CrcUpdate = CrcUpdateT8;
+ #endif
+ }
+ else if (p[0] != 1 || p[1] != 2)
+ g_CrcUpdate = CrcUpdateT1;
else
#endif
{
@@ -73,8 +114,15 @@ void MY_FAST_CALL CrcGenerateTable()
UInt32 x = g_CrcTable[i - 256];
g_CrcTable[i] = CRC_UINT32_SWAP(x);
}
+ g_CrcUpdateT4 = CrcUpdateT1_BeT4;
g_CrcUpdate = CrcUpdateT1_BeT4;
+ #if CRC_NUM_TABLES >= 8
+ g_CrcUpdateT8 = CrcUpdateT1_BeT8;
+ // g_CrcUpdate = CrcUpdateT1_BeT8;
+ #endif
}
}
#endif
+
+ #endif
}
diff --git a/3rdparty/lzma/C/7zCrc.h b/3rdparty/lzma/C/7zCrc.h
index 38e3e5fbc06..8fd57958715 100644
--- a/3rdparty/lzma/C/7zCrc.h
+++ b/3rdparty/lzma/C/7zCrc.h
@@ -1,10 +1,10 @@
/* 7zCrc.h -- CRC32 calculation
-2009-11-21 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __7Z_CRC_H
#define __7Z_CRC_H
-#include "Types.h"
+#include "7zTypes.h"
EXTERN_C_BEGIN
diff --git a/3rdparty/lzma/C/7zCrcOpt.c b/3rdparty/lzma/C/7zCrcOpt.c
index a8d42a80074..d1e1cd7bae1 100644
--- a/3rdparty/lzma/C/7zCrcOpt.c
+++ b/3rdparty/lzma/C/7zCrcOpt.c
@@ -1,12 +1,14 @@
/* 7zCrcOpt.c -- CRC32 calculation
-2010-12-01 : Igor Pavlov : Public domain */
+2015-03-01 : Igor Pavlov : Public domain */
-#include "CpuArch.h"
+#include "Precomp.h"
-#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+#include "CpuArch.h"
#ifndef MY_CPU_BE
+#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
@@ -16,10 +18,10 @@ UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const U
{
v ^= *(const UInt32 *)p;
v =
- table[0x300 + (v & 0xFF)] ^
- table[0x200 + ((v >> 8) & 0xFF)] ^
- table[0x100 + ((v >> 16) & 0xFF)] ^
- table[0x000 + ((v >> 24))];
+ table[0x300 + ((v ) & 0xFF)]
+ ^ table[0x200 + ((v >> 8) & 0xFF)]
+ ^ table[0x100 + ((v >> 16) & 0xFF)]
+ ^ table[0x000 + ((v >> 24))];
}
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
@@ -28,7 +30,28 @@ UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const U
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
- return CrcUpdateT4(v, data, size, table);
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ for (; size >= 8; size -= 8, p += 8)
+ {
+ UInt32 d;
+ v ^= *(const UInt32 *)p;
+ v =
+ table[0x700 + ((v ) & 0xFF)]
+ ^ table[0x600 + ((v >> 8) & 0xFF)]
+ ^ table[0x500 + ((v >> 16) & 0xFF)]
+ ^ table[0x400 + ((v >> 24))];
+ d = *((const UInt32 *)p + 1);
+ v ^=
+ table[0x300 + ((d ) & 0xFF)]
+ ^ table[0x200 + ((d >> 8) & 0xFF)]
+ ^ table[0x100 + ((d >> 16) & 0xFF)]
+ ^ table[0x000 + ((d >> 24))];
+ }
+ for (; size > 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ return v;
}
#endif
@@ -38,27 +61,55 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
+#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(((crc) >> 24) ^ (b))] ^ ((crc) << 8))
+
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
- for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
- v = CRC_UPDATE_BYTE_2(v, *p);
- v = CRC_UINT32_SWAP(v);
table += 0x100;
+ v = CRC_UINT32_SWAP(v);
+ for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2_BE(v, *p);
for (; size >= 4; size -= 4, p += 4)
{
v ^= *(const UInt32 *)p;
v =
- table[0x000 + (v & 0xFF)] ^
- table[0x100 + ((v >> 8) & 0xFF)] ^
- table[0x200 + ((v >> 16) & 0xFF)] ^
- table[0x300 + ((v >> 24))];
+ table[0x000 + ((v ) & 0xFF)]
+ ^ table[0x100 + ((v >> 8) & 0xFF)]
+ ^ table[0x200 + ((v >> 16) & 0xFF)]
+ ^ table[0x300 + ((v >> 24))];
}
- table -= 0x100;
+ for (; size > 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2_BE(v, *p);
+ return CRC_UINT32_SWAP(v);
+}
+
+UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
+{
+ const Byte *p = (const Byte *)data;
+ table += 0x100;
v = CRC_UINT32_SWAP(v);
+ for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2_BE(v, *p);
+ for (; size >= 8; size -= 8, p += 8)
+ {
+ UInt32 d;
+ v ^= *(const UInt32 *)p;
+ v =
+ table[0x400 + ((v ) & 0xFF)]
+ ^ table[0x500 + ((v >> 8) & 0xFF)]
+ ^ table[0x600 + ((v >> 16) & 0xFF)]
+ ^ table[0x700 + ((v >> 24))];
+ d = *((const UInt32 *)p + 1);
+ v ^=
+ table[0x000 + ((d ) & 0xFF)]
+ ^ table[0x100 + ((d >> 8) & 0xFF)]
+ ^ table[0x200 + ((d >> 16) & 0xFF)]
+ ^ table[0x300 + ((d >> 24))];
+ }
for (; size > 0; size--, p++)
- v = CRC_UPDATE_BYTE_2(v, *p);
- return v;
+ v = CRC_UPDATE_BYTE_2_BE(v, *p);
+ return CRC_UINT32_SWAP(v);
}
#endif
diff --git a/3rdparty/lzma/C/7zDec.c b/3rdparty/lzma/C/7zDec.c
index b6d809956cd..c45d6bf8d4b 100644
--- a/3rdparty/lzma/C/7zDec.c
+++ b/3rdparty/lzma/C/7zDec.c
@@ -1,15 +1,19 @@
/* 7zDec.c -- Decoding from 7z folder
-2010-11-02 : Igor Pavlov : Public domain */
+2015-11-18 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <string.h>
/* #define _7ZIP_PPMD_SUPPPORT */
#include "7z.h"
+#include "7zCrc.h"
#include "Bcj2.h"
#include "Bra.h"
#include "CpuArch.h"
+#include "Delta.h"
#include "LzmaDec.h"
#include "Lzma2Dec.h"
#ifdef _7ZIP_PPMD_SUPPPORT
@@ -17,14 +21,17 @@
#endif
#define k_Copy 0
+#define k_Delta 3
#define k_LZMA2 0x21
#define k_LZMA 0x30101
-#define k_BCJ 0x03030103
-#define k_PPC 0x03030205
-#define k_ARM 0x03030501
-#define k_ARMT 0x03030701
-#define k_SPARC 0x03030805
-#define k_BCJ2 0x0303011B
+#define k_BCJ 0x3030103
+#define k_BCJ2 0x303011B
+#define k_PPC 0x3030205
+#define k_IA64 0x3030401
+#define k_ARM 0x3030501
+#define k_ARMT 0x3030701
+#define k_SPARC 0x3030805
+
#ifdef _7ZIP_PPMD_SUPPPORT
@@ -63,7 +70,7 @@ static Byte ReadByte(void *pp)
return 0;
}
-static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
+static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{
CPpmd7 ppmd;
@@ -77,12 +84,12 @@ static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
s.res = SZ_OK;
s.processed = 0;
- if (coder->Props.size != 5)
+ if (propsSize != 5)
return SZ_ERROR_UNSUPPORTED;
{
- unsigned order = coder->Props.data[0];
- UInt32 memSize = GetUi32(coder->Props.data + 1);
+ unsigned order = props[0];
+ UInt32 memSize = GetUi32(props + 1);
if (order < PPMD7_MIN_ORDER ||
order > PPMD7_MAX_ORDER ||
memSize < PPMD7_MIN_MEM_SIZE ||
@@ -124,25 +131,25 @@ static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
#endif
-static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
+static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{
CLzmaDec state;
SRes res = SZ_OK;
LzmaDec_Construct(&state);
- RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
+ RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain));
state.dic = outBuffer;
state.dicBufSize = outSize;
LzmaDec_Init(&state);
for (;;)
{
- Byte *inBuf = NULL;
+ const void *inBuf = NULL;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
- res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
+ res = inStream->Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK)
break;
@@ -154,14 +161,23 @@ static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
inSize -= inProcessed;
if (res != SZ_OK)
break;
- if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
+
+ if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{
- if (state.dicBufSize != outSize || lookahead != 0 ||
- (status != LZMA_STATUS_FINISHED_WITH_MARK &&
- status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
+ if (outSize != state.dicPos || inSize != 0)
res = SZ_ERROR_DATA;
break;
}
+
+ if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
+ break;
+
+ if (inProcessed == 0 && dicPos == state.dicPos)
+ {
+ res = SZ_ERROR_DATA;
+ break;
+ }
+
res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK)
break;
@@ -172,27 +188,30 @@ static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
return res;
}
-static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
+
+#ifndef _7Z_NO_METHOD_LZMA2
+
+static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{
CLzma2Dec state;
SRes res = SZ_OK;
Lzma2Dec_Construct(&state);
- if (coder->Props.size != 1)
+ if (propsSize != 1)
return SZ_ERROR_DATA;
- RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));
+ RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain));
state.decoder.dic = outBuffer;
state.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&state);
for (;;)
{
- Byte *inBuf = NULL;
+ const void *inBuf = NULL;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
- res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
+ res = inStream->Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK)
break;
@@ -204,13 +223,20 @@ static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inS
inSize -= inProcessed;
if (res != SZ_OK)
break;
- if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
+
+ if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{
- if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
- (status != LZMA_STATUS_FINISHED_WITH_MARK))
+ if (outSize != state.decoder.dicPos || inSize != 0)
res = SZ_ERROR_DATA;
break;
}
+
+ if (inProcessed == 0 && dicPos == state.decoder.dicPos)
+ {
+ res = SZ_ERROR_DATA;
+ break;
+ }
+
res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK)
break;
@@ -221,15 +247,18 @@ static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inS
return res;
}
+#endif
+
+
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
{
while (inSize > 0)
{
- void *inBuf;
+ const void *inBuf;
size_t curSize = (1 << 18);
if (curSize > inSize)
curSize = (size_t)inSize;
- RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
+ RINOK(inStream->Look(inStream, &inBuf, &curSize));
if (curSize == 0)
return SZ_ERROR_INPUT_EOF;
memcpy(outBuffer, inBuf, curSize);
@@ -242,11 +271,13 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
static Bool IS_MAIN_METHOD(UInt32 m)
{
- switch(m)
+ switch (m)
{
case k_Copy:
case k_LZMA:
+ #ifndef _7Z_NO_METHOD_LZMA2
case k_LZMA2:
+ #endif
#ifdef _7ZIP_PPMD_SUPPPORT
case k_PPMD:
#endif
@@ -258,13 +289,12 @@ static Bool IS_MAIN_METHOD(UInt32 m)
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
{
return
- c->NumInStreams == 1 &&
- c->NumOutStreams == 1 &&
- c->MethodID <= (UInt32)0xFFFFFFFF &&
- IS_MAIN_METHOD((UInt32)c->MethodID);
+ c->NumStreams == 1
+ /* && c->MethodID <= (UInt32)0xFFFFFFFF */
+ && IS_MAIN_METHOD((UInt32)c->MethodID);
}
-#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
+#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4)
static SRes CheckSupportedFolder(const CSzFolder *f)
{
@@ -274,65 +304,73 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
return SZ_ERROR_UNSUPPORTED;
if (f->NumCoders == 1)
{
- if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
+ if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
}
+
+
+ #ifndef _7Z_NO_METHODS_FILTERS
+
if (f->NumCoders == 2)
{
- CSzCoderInfo *c = &f->Coders[1];
- if (c->MethodID > (UInt32)0xFFFFFFFF ||
- c->NumInStreams != 1 ||
- c->NumOutStreams != 1 ||
- f->NumPackStreams != 1 ||
- f->PackStreams[0] != 0 ||
- f->NumBindPairs != 1 ||
- f->BindPairs[0].InIndex != 1 ||
- f->BindPairs[0].OutIndex != 0)
+ const CSzCoderInfo *c = &f->Coders[1];
+ if (
+ /* c->MethodID > (UInt32)0xFFFFFFFF || */
+ c->NumStreams != 1
+ || f->NumPackStreams != 1
+ || f->PackStreams[0] != 0
+ || f->NumBonds != 1
+ || f->Bonds[0].InIndex != 1
+ || f->Bonds[0].OutIndex != 0)
return SZ_ERROR_UNSUPPORTED;
switch ((UInt32)c->MethodID)
{
+ case k_Delta:
case k_BCJ:
+ case k_PPC:
+ case k_IA64:
+ case k_SPARC:
case k_ARM:
+ case k_ARMT:
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
return SZ_OK;
}
+
+ #endif
+
+
if (f->NumCoders == 4)
{
- if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
- !IS_SUPPORTED_CODER(&f->Coders[2]) ||
- !IS_BCJ2(&f->Coders[3]))
+ if (!IS_SUPPORTED_CODER(&f->Coders[1])
+ || !IS_SUPPORTED_CODER(&f->Coders[2])
+ || !IS_BCJ2(&f->Coders[3]))
return SZ_ERROR_UNSUPPORTED;
- if (f->NumPackStreams != 4 ||
- f->PackStreams[0] != 2 ||
- f->PackStreams[1] != 6 ||
- f->PackStreams[2] != 1 ||
- f->PackStreams[3] != 0 ||
- f->NumBindPairs != 3 ||
- f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
- f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
- f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
+ if (f->NumPackStreams != 4
+ || f->PackStreams[0] != 2
+ || f->PackStreams[1] != 6
+ || f->PackStreams[2] != 1
+ || f->PackStreams[3] != 0
+ || f->NumBonds != 3
+ || f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
+ || f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
+ || f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
}
+
return SZ_ERROR_UNSUPPORTED;
}
-static UInt64 GetSum(const UInt64 *values, UInt32 index)
-{
- UInt64 sum = 0;
- UInt32 i;
- for (i = 0; i < index; i++)
- sum += values[i];
- return sum;
-}
-
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
-static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
+static SRes SzFolder_Decode2(const CSzFolder *folder,
+ const Byte *propsData,
+ const UInt64 *unpackSizes,
+ const UInt64 *packPositions,
ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
Byte *tempBuf[])
@@ -346,7 +384,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
for (ci = 0; ci < folder->NumCoders; ci++)
{
- CSzCoderInfo *coder = &folder->Coders[ci];
+ const CSzCoderInfo *coder = &folder->Coders[ci];
if (IS_MAIN_METHOD((UInt32)coder->MethodID))
{
@@ -358,7 +396,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
if (folder->NumCoders == 4)
{
UInt32 indices[] = { 3, 2, 0 };
- UInt64 unpackSize = folder->UnpackSizes[ci];
+ UInt64 unpackSize = unpackSizes[ci];
si = indices[ci];
if (ci < 2)
{
@@ -367,7 +405,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
if (outSizeCur != unpackSize)
return SZ_ERROR_MEM;
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
- if (temp == 0 && outSizeCur != 0)
+ if (!temp && outSizeCur != 0)
return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp;
tempSizes[1 - ci] = outSizeCur;
@@ -382,8 +420,8 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
else
return SZ_ERROR_UNSUPPORTED;
}
- offset = GetSum(packSizes, si);
- inSize = packSizes[si];
+ offset = packPositions[si];
+ inSize = packPositions[si + 1] - offset;
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
if (coder->MethodID == k_Copy)
@@ -394,77 +432,160 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
}
else if (coder->MethodID == k_LZMA)
{
- RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
+ RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
}
+ #ifndef _7Z_NO_METHOD_LZMA2
else if (coder->MethodID == k_LZMA2)
{
- RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
+ RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
}
- else
+ #endif
+ #ifdef _7ZIP_PPMD_SUPPPORT
+ else if (coder->MethodID == k_PPMD)
{
- #ifdef _7ZIP_PPMD_SUPPPORT
- RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
- #else
- return SZ_ERROR_UNSUPPORTED;
- #endif
+ RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
}
+ #endif
+ else
+ return SZ_ERROR_UNSUPPORTED;
}
else if (coder->MethodID == k_BCJ2)
{
- UInt64 offset = GetSum(packSizes, 1);
- UInt64 s3Size = packSizes[1];
- SRes res;
+ UInt64 offset = packPositions[1];
+ UInt64 s3Size = packPositions[2] - offset;
+
if (ci != 3)
return SZ_ERROR_UNSUPPORTED;
- RINOK(LookInStream_SeekTo(inStream, startPos + offset));
+
tempSizes[2] = (SizeT)s3Size;
if (tempSizes[2] != s3Size)
return SZ_ERROR_MEM;
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
- if (tempBuf[2] == 0 && tempSizes[2] != 0)
+ if (!tempBuf[2] && tempSizes[2] != 0)
return SZ_ERROR_MEM;
- res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
- RINOK(res)
-
- res = Bcj2_Decode(
- tempBuf3, tempSize3,
- tempBuf[0], tempSizes[0],
- tempBuf[1], tempSizes[1],
- tempBuf[2], tempSizes[2],
- outBuffer, outSize);
- RINOK(res)
+
+ RINOK(LookInStream_SeekTo(inStream, startPos + offset));
+ RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]));
+
+ if ((tempSizes[0] & 3) != 0 ||
+ (tempSizes[1] & 3) != 0 ||
+ tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
+ return SZ_ERROR_DATA;
+
+ {
+ CBcj2Dec p;
+
+ p.bufs[0] = tempBuf3; p.lims[0] = tempBuf3 + tempSize3;
+ p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0];
+ p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1];
+ p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2];
+
+ p.dest = outBuffer;
+ p.destLim = outBuffer + outSize;
+
+ Bcj2Dec_Init(&p);
+ RINOK(Bcj2Dec_Decode(&p));
+
+ {
+ unsigned i;
+ for (i = 0; i < 4; i++)
+ if (p.bufs[i] != p.lims[i])
+ return SZ_ERROR_DATA;
+
+ if (!Bcj2Dec_IsFinished(&p))
+ return SZ_ERROR_DATA;
+
+ if (p.dest != p.destLim
+ || p.state != BCJ2_STREAM_MAIN)
+ return SZ_ERROR_DATA;
+ }
+ }
}
- else
+ #ifndef _7Z_NO_METHODS_FILTERS
+ else if (ci == 1)
{
- if (ci != 1)
- return SZ_ERROR_UNSUPPORTED;
- switch(coder->MethodID)
+ if (coder->MethodID == k_Delta)
{
- case k_BCJ:
+ if (coder->PropsSize != 1)
+ return SZ_ERROR_UNSUPPORTED;
{
- UInt32 state;
- x86_Convert_Init(state);
- x86_Convert(outBuffer, outSize, 0, &state, 0);
- break;
+ Byte state[DELTA_STATE_SIZE];
+ Delta_Init(state);
+ Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
}
- CASE_BRA_CONV(ARM)
- default:
+ }
+ else
+ {
+ if (coder->PropsSize != 0)
return SZ_ERROR_UNSUPPORTED;
+ switch (coder->MethodID)
+ {
+ case k_BCJ:
+ {
+ UInt32 state;
+ x86_Convert_Init(state);
+ x86_Convert(outBuffer, outSize, 0, &state, 0);
+ break;
+ }
+ CASE_BRA_CONV(PPC)
+ CASE_BRA_CONV(IA64)
+ CASE_BRA_CONV(SPARC)
+ CASE_BRA_CONV(ARM)
+ CASE_BRA_CONV(ARMT)
+ default:
+ return SZ_ERROR_UNSUPPORTED;
+ }
}
}
+ #endif
+ else
+ return SZ_ERROR_UNSUPPORTED;
}
+
return SZ_OK;
}
-SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
+
+SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *inStream, UInt64 startPos,
- Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
+ Byte *outBuffer, size_t outSize,
+ ISzAlloc *allocMain)
{
- Byte *tempBuf[3] = { 0, 0, 0};
- int i;
- SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
- outBuffer, (SizeT)outSize, allocMain, tempBuf);
- for (i = 0; i < 3; i++)
- IAlloc_Free(allocMain, tempBuf[i]);
- return res;
+ SRes res;
+ CSzFolder folder;
+ CSzData sd;
+
+ const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
+ sd.Data = data;
+ sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];
+
+ res = SzGetNextFolderItem(&folder, &sd);
+
+ if (res != SZ_OK)
+ return res;
+
+ if (sd.Size != 0
+ || folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
+ || outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
+ return SZ_ERROR_FAIL;
+ {
+ unsigned i;
+ Byte *tempBuf[3] = { 0, 0, 0};
+
+ res = SzFolder_Decode2(&folder, data,
+ &p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
+ p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
+ inStream, startPos,
+ outBuffer, (SizeT)outSize, allocMain, tempBuf);
+
+ for (i = 0; i < 3; i++)
+ IAlloc_Free(allocMain, tempBuf[i]);
+
+ if (res == SZ_OK)
+ if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
+ if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
+ res = SZ_ERROR_CRC;
+
+ return res;
+ }
}
diff --git a/3rdparty/lzma/C/7zFile.c b/3rdparty/lzma/C/7zFile.c
index a66c9e9d08e..041e5b15465 100644
--- a/3rdparty/lzma/C/7zFile.c
+++ b/3rdparty/lzma/C/7zFile.c
@@ -1,6 +1,8 @@
/* 7zFile.c -- File IO
2009-11-24 : Igor Pavlov : Public domain */
+#include "Precomp.h"
+
#include "7zFile.h"
#ifndef USE_WINDOWS_FILE
diff --git a/3rdparty/lzma/C/7zFile.h b/3rdparty/lzma/C/7zFile.h
index 84538c03fd2..658987ed51a 100644
--- a/3rdparty/lzma/C/7zFile.h
+++ b/3rdparty/lzma/C/7zFile.h
@@ -1,5 +1,5 @@
/* 7zFile.h -- File IO
-2009-11-24 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __7Z_FILE_H
#define __7Z_FILE_H
@@ -14,7 +14,7 @@
#include <stdio.h>
#endif
-#include "Types.h"
+#include "7zTypes.h"
EXTERN_C_BEGIN
diff --git a/3rdparty/lzma/C/7zIn.c b/3rdparty/lzma/C/7zIn.c
deleted file mode 100644
index ec93a43ffec..00000000000
--- a/3rdparty/lzma/C/7zIn.c
+++ /dev/null
@@ -1,1402 +0,0 @@
-/* 7zIn.c -- 7z Input functions
-2010-10-29 : Igor Pavlov : Public domain */
-
-#include <string.h>
-
-#include "7z.h"
-#include "7zCrc.h"
-#include "CpuArch.h"
-
-Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
-
-#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
-
-#define NUM_FOLDER_CODERS_MAX 32
-#define NUM_CODER_STREAMS_MAX 32
-
-void SzCoderInfo_Init(CSzCoderInfo *p)
-{
- Buf_Init(&p->Props);
-}
-
-void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
-{
- Buf_Free(&p->Props, alloc);
- SzCoderInfo_Init(p);
-}
-
-void SzFolder_Init(CSzFolder *p)
-{
- p->Coders = 0;
- p->BindPairs = 0;
- p->PackStreams = 0;
- p->UnpackSizes = 0;
- p->NumCoders = 0;
- p->NumBindPairs = 0;
- p->NumPackStreams = 0;
- p->UnpackCRCDefined = 0;
- p->UnpackCRC = 0;
- p->NumUnpackStreams = 0;
-}
-
-void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
-{
- UInt32 i;
- if (p->Coders)
- for (i = 0; i < p->NumCoders; i++)
- SzCoderInfo_Free(&p->Coders[i], alloc);
- IAlloc_Free(alloc, p->Coders);
- IAlloc_Free(alloc, p->BindPairs);
- IAlloc_Free(alloc, p->PackStreams);
- IAlloc_Free(alloc, p->UnpackSizes);
- SzFolder_Init(p);
-}
-
-UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
-{
- UInt32 result = 0;
- UInt32 i;
- for (i = 0; i < p->NumCoders; i++)
- result += p->Coders[i].NumOutStreams;
- return result;
-}
-
-int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
-{
- UInt32 i;
- for (i = 0; i < p->NumBindPairs; i++)
- if (p->BindPairs[i].InIndex == inStreamIndex)
- return i;
- return -1;
-}
-
-
-int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
-{
- UInt32 i;
- for (i = 0; i < p->NumBindPairs; i++)
- if (p->BindPairs[i].OutIndex == outStreamIndex)
- return i;
- return -1;
-}
-
-UInt64 SzFolder_GetUnpackSize(CSzFolder *p)
-{
- int i = (int)SzFolder_GetNumOutStreams(p);
- if (i == 0)
- return 0;
- for (i--; i >= 0; i--)
- if (SzFolder_FindBindPairForOutStream(p, i) < 0)
- return p->UnpackSizes[i];
- /* throw 1; */
- return 0;
-}
-
-void SzFile_Init(CSzFileItem *p)
-{
- p->HasStream = 1;
- p->IsDir = 0;
- p->IsAnti = 0;
- p->CrcDefined = 0;
- p->MTimeDefined = 0;
-}
-
-void SzAr_Init(CSzAr *p)
-{
- p->PackSizes = 0;
- p->PackCRCsDefined = 0;
- p->PackCRCs = 0;
- p->Folders = 0;
- p->Files = 0;
- p->NumPackStreams = 0;
- p->NumFolders = 0;
- p->NumFiles = 0;
-}
-
-void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
-{
- UInt32 i;
- if (p->Folders)
- for (i = 0; i < p->NumFolders; i++)
- SzFolder_Free(&p->Folders[i], alloc);
-
- IAlloc_Free(alloc, p->PackSizes);
- IAlloc_Free(alloc, p->PackCRCsDefined);
- IAlloc_Free(alloc, p->PackCRCs);
- IAlloc_Free(alloc, p->Folders);
- IAlloc_Free(alloc, p->Files);
- SzAr_Init(p);
-}
-
-
-void SzArEx_Init(CSzArEx *p)
-{
- SzAr_Init(&p->db);
- p->FolderStartPackStreamIndex = 0;
- p->PackStreamStartPositions = 0;
- p->FolderStartFileIndex = 0;
- p->FileIndexToFolderIndexMap = 0;
- p->FileNameOffsets = 0;
- Buf_Init(&p->FileNames);
-}
-
-void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
-{
- IAlloc_Free(alloc, p->FolderStartPackStreamIndex);
- IAlloc_Free(alloc, p->PackStreamStartPositions);
- IAlloc_Free(alloc, p->FolderStartFileIndex);
- IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
-
- IAlloc_Free(alloc, p->FileNameOffsets);
- Buf_Free(&p->FileNames, alloc);
-
- SzAr_Free(&p->db, alloc);
- SzArEx_Init(p);
-}
-
-/*
-UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
-{
- return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
-}
-
-UInt64 GetFilePackSize(int fileIndex) const
-{
- int folderIndex = FileIndexToFolderIndexMap[fileIndex];
- if (folderIndex >= 0)
- {
- const CSzFolder &folderInfo = Folders[folderIndex];
- if (FolderStartFileIndex[folderIndex] == fileIndex)
- return GetFolderFullPackSize(folderIndex);
- }
- return 0;
-}
-*/
-
-#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \
- if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }
-
-static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
-{
- UInt32 startPos = 0;
- UInt64 startPosSize = 0;
- UInt32 i;
- UInt32 folderIndex = 0;
- UInt32 indexInFolder = 0;
- MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc);
- for (i = 0; i < p->db.NumFolders; i++)
- {
- p->FolderStartPackStreamIndex[i] = startPos;
- startPos += p->db.Folders[i].NumPackStreams;
- }
-
- MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc);
-
- for (i = 0; i < p->db.NumPackStreams; i++)
- {
- p->PackStreamStartPositions[i] = startPosSize;
- startPosSize += p->db.PackSizes[i];
- }
-
- MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc);
- MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc);
-
- for (i = 0; i < p->db.NumFiles; i++)
- {
- CSzFileItem *file = p->db.Files + i;
- int emptyStream = !file->HasStream;
- if (emptyStream && indexInFolder == 0)
- {
- p->FileIndexToFolderIndexMap[i] = (UInt32)-1;
- continue;
- }
- if (indexInFolder == 0)
- {
- /*
- v3.13 incorrectly worked with empty folders
- v4.07: Loop for skipping empty folders
- */
- for (;;)
- {
- if (folderIndex >= p->db.NumFolders)
- return SZ_ERROR_ARCHIVE;
- p->FolderStartFileIndex[folderIndex] = i;
- if (p->db.Folders[folderIndex].NumUnpackStreams != 0)
- break;
- folderIndex++;
- }
- }
- p->FileIndexToFolderIndexMap[i] = folderIndex;
- if (emptyStream)
- continue;
- indexInFolder++;
- if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams)
- {
- folderIndex++;
- indexInFolder = 0;
- }
- }
- return SZ_OK;
-}
-
-
-UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)
-{
- return p->dataPos +
- p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
-}
-
-int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize)
-{
- UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex];
- CSzFolder *folder = p->db.Folders + folderIndex;
- UInt64 size = 0;
- UInt32 i;
- for (i = 0; i < folder->NumPackStreams; i++)
- {
- UInt64 t = size + p->db.PackSizes[packStreamIndex + i];
- if (t < size) /* check it */
- return SZ_ERROR_FAIL;
- size = t;
- }
- *resSize = size;
- return SZ_OK;
-}
-
-
-/*
-SRes SzReadTime(const CObjectVector<CBuf> &dataVector,
- CObjectVector<CSzFileItem> &files, UInt64 type)
-{
- CBoolVector boolVector;
- RINOK(ReadBoolVector2(files.Size(), boolVector))
-
- CStreamSwitch streamSwitch;
- RINOK(streamSwitch.Set(this, &dataVector));
-
- for (int i = 0; i < files.Size(); i++)
- {
- CSzFileItem &file = files[i];
- CArchiveFileTime fileTime;
- bool defined = boolVector[i];
- if (defined)
- {
- UInt32 low, high;
- RINOK(SzReadUInt32(low));
- RINOK(SzReadUInt32(high));
- fileTime.dwLowDateTime = low;
- fileTime.dwHighDateTime = high;
- }
- switch(type)
- {
- case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break;
- case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break;
- case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break;
- }
- }
- return SZ_OK;
-}
-*/
-
-static int TestSignatureCandidate(Byte *testBytes)
-{
- size_t i;
- for (i = 0; i < k7zSignatureSize; i++)
- if (testBytes[i] != k7zSignature[i])
- return 0;
- return 1;
-}
-
-typedef struct _CSzState
-{
- Byte *Data;
- size_t Size;
-}CSzData;
-
-static SRes SzReadByte(CSzData *sd, Byte *b)
-{
- if (sd->Size == 0)
- return SZ_ERROR_ARCHIVE;
- sd->Size--;
- *b = *sd->Data++;
- return SZ_OK;
-}
-
-static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size)
-{
- size_t i;
- for (i = 0; i < size; i++)
- {
- RINOK(SzReadByte(sd, data + i));
- }
- return SZ_OK;
-}
-
-static SRes SzReadUInt32(CSzData *sd, UInt32 *value)
-{
- int i;
- *value = 0;
- for (i = 0; i < 4; i++)
- {
- Byte b;
- RINOK(SzReadByte(sd, &b));
- *value |= ((UInt32)(b) << (8 * i));
- }
- return SZ_OK;
-}
-
-static SRes SzReadNumber(CSzData *sd, UInt64 *value)
-{
- Byte firstByte;
- Byte mask = 0x80;
- int i;
- RINOK(SzReadByte(sd, &firstByte));
- *value = 0;
- for (i = 0; i < 8; i++)
- {
- Byte b;
- if ((firstByte & mask) == 0)
- {
- UInt64 highPart = firstByte & (mask - 1);
- *value += (highPart << (8 * i));
- return SZ_OK;
- }
- RINOK(SzReadByte(sd, &b));
- *value |= ((UInt64)b << (8 * i));
- mask >>= 1;
- }
- return SZ_OK;
-}
-
-static SRes SzReadNumber32(CSzData *sd, UInt32 *value)
-{
- UInt64 value64;
- RINOK(SzReadNumber(sd, &value64));
- if (value64 >= 0x80000000)
- return SZ_ERROR_UNSUPPORTED;
- if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
- return SZ_ERROR_UNSUPPORTED;
- *value = (UInt32)value64;
- return SZ_OK;
-}
-
-static SRes SzReadID(CSzData *sd, UInt64 *value)
-{
- return SzReadNumber(sd, value);
-}
-
-static SRes SzSkeepDataSize(CSzData *sd, UInt64 size)
-{
- if (size > sd->Size)
- return SZ_ERROR_ARCHIVE;
- sd->Size -= (size_t)size;
- sd->Data += (size_t)size;
- return SZ_OK;
-}
-
-static SRes SzSkeepData(CSzData *sd)
-{
- UInt64 size;
- RINOK(SzReadNumber(sd, &size));
- return SzSkeepDataSize(sd, size);
-}
-
-static SRes SzReadArchiveProperties(CSzData *sd)
-{
- for (;;)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- break;
- SzSkeepData(sd);
- }
- return SZ_OK;
-}
-
-static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute)
-{
- for (;;)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == attribute)
- return SZ_OK;
- if (type == k7zIdEnd)
- return SZ_ERROR_ARCHIVE;
- RINOK(SzSkeepData(sd));
- }
-}
-
-static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
-{
- Byte b = 0;
- Byte mask = 0;
- size_t i;
- MY_ALLOC(Byte, *v, numItems, alloc);
- for (i = 0; i < numItems; i++)
- {
- if (mask == 0)
- {
- RINOK(SzReadByte(sd, &b));
- mask = 0x80;
- }
- (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
- mask >>= 1;
- }
- return SZ_OK;
-}
-
-static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
-{
- Byte allAreDefined;
- size_t i;
- RINOK(SzReadByte(sd, &allAreDefined));
- if (allAreDefined == 0)
- return SzReadBoolVector(sd, numItems, v, alloc);
- MY_ALLOC(Byte, *v, numItems, alloc);
- for (i = 0; i < numItems; i++)
- (*v)[i] = 1;
- return SZ_OK;
-}
-
-static SRes SzReadHashDigests(
- CSzData *sd,
- size_t numItems,
- Byte **digestsDefined,
- UInt32 **digests,
- ISzAlloc *alloc)
-{
- size_t i;
- RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc));
- MY_ALLOC(UInt32, *digests, numItems, alloc);
- for (i = 0; i < numItems; i++)
- if ((*digestsDefined)[i])
- {
- RINOK(SzReadUInt32(sd, (*digests) + i));
- }
- return SZ_OK;
-}
-
-static SRes SzReadPackInfo(
- CSzData *sd,
- UInt64 *dataOffset,
- UInt32 *numPackStreams,
- UInt64 **packSizes,
- Byte **packCRCsDefined,
- UInt32 **packCRCs,
- ISzAlloc *alloc)
-{
- UInt32 i;
- RINOK(SzReadNumber(sd, dataOffset));
- RINOK(SzReadNumber32(sd, numPackStreams));
-
- RINOK(SzWaitAttribute(sd, k7zIdSize));
-
- MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc);
-
- for (i = 0; i < *numPackStreams; i++)
- {
- RINOK(SzReadNumber(sd, (*packSizes) + i));
- }
-
- for (;;)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- break;
- if (type == k7zIdCRC)
- {
- RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));
- continue;
- }
- RINOK(SzSkeepData(sd));
- }
- if (*packCRCsDefined == 0)
- {
- MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc);
- MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc);
- for (i = 0; i < *numPackStreams; i++)
- {
- (*packCRCsDefined)[i] = 0;
- (*packCRCs)[i] = 0;
- }
- }
- return SZ_OK;
-}
-
-static SRes SzReadSwitch(CSzData *sd)
-{
- Byte external;
- RINOK(SzReadByte(sd, &external));
- return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
-}
-
-static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
-{
- UInt32 numCoders, numBindPairs, numPackStreams, i;
- UInt32 numInStreams = 0, numOutStreams = 0;
-
- RINOK(SzReadNumber32(sd, &numCoders));
- if (numCoders > NUM_FOLDER_CODERS_MAX)
- return SZ_ERROR_UNSUPPORTED;
- folder->NumCoders = numCoders;
-
- MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc);
-
- for (i = 0; i < numCoders; i++)
- SzCoderInfo_Init(folder->Coders + i);
-
- for (i = 0; i < numCoders; i++)
- {
- Byte mainByte;
- CSzCoderInfo *coder = folder->Coders + i;
- {
- unsigned idSize, j;
- Byte longID[15];
- RINOK(SzReadByte(sd, &mainByte));
- idSize = (unsigned)(mainByte & 0xF);
- RINOK(SzReadBytes(sd, longID, idSize));
- if (idSize > sizeof(coder->MethodID))
- return SZ_ERROR_UNSUPPORTED;
- coder->MethodID = 0;
- for (j = 0; j < idSize; j++)
- coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j);
-
- if ((mainByte & 0x10) != 0)
- {
- RINOK(SzReadNumber32(sd, &coder->NumInStreams));
- RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
- if (coder->NumInStreams > NUM_CODER_STREAMS_MAX ||
- coder->NumOutStreams > NUM_CODER_STREAMS_MAX)
- return SZ_ERROR_UNSUPPORTED;
- }
- else
- {
- coder->NumInStreams = 1;
- coder->NumOutStreams = 1;
- }
- if ((mainByte & 0x20) != 0)
- {
- UInt64 propertiesSize = 0;
- RINOK(SzReadNumber(sd, &propertiesSize));
- if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc))
- return SZ_ERROR_MEM;
- RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize));
- }
- }
- while ((mainByte & 0x80) != 0)
- {
- RINOK(SzReadByte(sd, &mainByte));
- RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
- if ((mainByte & 0x10) != 0)
- {
- UInt32 n;
- RINOK(SzReadNumber32(sd, &n));
- RINOK(SzReadNumber32(sd, &n));
- }
- if ((mainByte & 0x20) != 0)
- {
- UInt64 propertiesSize = 0;
- RINOK(SzReadNumber(sd, &propertiesSize));
- RINOK(SzSkeepDataSize(sd, propertiesSize));
- }
- }
- numInStreams += coder->NumInStreams;
- numOutStreams += coder->NumOutStreams;
- }
-
- if (numOutStreams == 0)
- return SZ_ERROR_UNSUPPORTED;
-
- folder->NumBindPairs = numBindPairs = numOutStreams - 1;
- MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);
-
- for (i = 0; i < numBindPairs; i++)
- {
- CSzBindPair *bp = folder->BindPairs + i;
- RINOK(SzReadNumber32(sd, &bp->InIndex));
- RINOK(SzReadNumber32(sd, &bp->OutIndex));
- }
-
- if (numInStreams < numBindPairs)
- return SZ_ERROR_UNSUPPORTED;
-
- folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
- MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc);
-
- if (numPackStreams == 1)
- {
- for (i = 0; i < numInStreams ; i++)
- if (SzFolder_FindBindPairForInStream(folder, i) < 0)
- break;
- if (i == numInStreams)
- return SZ_ERROR_UNSUPPORTED;
- folder->PackStreams[0] = i;
- }
- else
- for (i = 0; i < numPackStreams; i++)
- {
- RINOK(SzReadNumber32(sd, folder->PackStreams + i));
- }
- return SZ_OK;
-}
-
-static SRes SzReadUnpackInfo(
- CSzData *sd,
- UInt32 *numFolders,
- CSzFolder **folders, /* for alloc */
- ISzAlloc *alloc,
- ISzAlloc *allocTemp)
-{
- UInt32 i;
- RINOK(SzWaitAttribute(sd, k7zIdFolder));
- RINOK(SzReadNumber32(sd, numFolders));
- {
- RINOK(SzReadSwitch(sd));
-
- MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc);
-
- for (i = 0; i < *numFolders; i++)
- SzFolder_Init((*folders) + i);
-
- for (i = 0; i < *numFolders; i++)
- {
- RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc));
- }
- }
-
- RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));
-
- for (i = 0; i < *numFolders; i++)
- {
- UInt32 j;
- CSzFolder *folder = (*folders) + i;
- UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);
-
- MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc);
-
- for (j = 0; j < numOutStreams; j++)
- {
- RINOK(SzReadNumber(sd, folder->UnpackSizes + j));
- }
- }
-
- for (;;)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- return SZ_OK;
- if (type == k7zIdCRC)
- {
- SRes res;
- Byte *crcsDefined = 0;
- UInt32 *crcs = 0;
- res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);
- if (res == SZ_OK)
- {
- for (i = 0; i < *numFolders; i++)
- {
- CSzFolder *folder = (*folders) + i;
- folder->UnpackCRCDefined = crcsDefined[i];
- folder->UnpackCRC = crcs[i];
- }
- }
- IAlloc_Free(allocTemp, crcs);
- IAlloc_Free(allocTemp, crcsDefined);
- RINOK(res);
- continue;
- }
- RINOK(SzSkeepData(sd));
- }
-}
-
-static SRes SzReadSubStreamsInfo(
- CSzData *sd,
- UInt32 numFolders,
- CSzFolder *folders,
- UInt32 *numUnpackStreams,
- UInt64 **unpackSizes,
- Byte **digestsDefined,
- UInt32 **digests,
- ISzAlloc *allocTemp)
-{
- UInt64 type = 0;
- UInt32 i;
- UInt32 si = 0;
- UInt32 numDigests = 0;
-
- for (i = 0; i < numFolders; i++)
- folders[i].NumUnpackStreams = 1;
- *numUnpackStreams = numFolders;
-
- for (;;)
- {
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdNumUnpackStream)
- {
- *numUnpackStreams = 0;
- for (i = 0; i < numFolders; i++)
- {
- UInt32 numStreams;
- RINOK(SzReadNumber32(sd, &numStreams));
- folders[i].NumUnpackStreams = numStreams;
- *numUnpackStreams += numStreams;
- }
- continue;
- }
- if (type == k7zIdCRC || type == k7zIdSize)
- break;
- if (type == k7zIdEnd)
- break;
- RINOK(SzSkeepData(sd));
- }
-
- if (*numUnpackStreams == 0)
- {
- *unpackSizes = 0;
- *digestsDefined = 0;
- *digests = 0;
- }
- else
- {
- *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64));
- RINOM(*unpackSizes);
- *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte));
- RINOM(*digestsDefined);
- *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32));
- RINOM(*digests);
- }
-
- for (i = 0; i < numFolders; i++)
- {
- /*
- v3.13 incorrectly worked with empty folders
- v4.07: we check that folder is empty
- */
- UInt64 sum = 0;
- UInt32 j;
- UInt32 numSubstreams = folders[i].NumUnpackStreams;
- if (numSubstreams == 0)
- continue;
- if (type == k7zIdSize)
- for (j = 1; j < numSubstreams; j++)
- {
- UInt64 size;
- RINOK(SzReadNumber(sd, &size));
- (*unpackSizes)[si++] = size;
- sum += size;
- }
- (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
- }
- if (type == k7zIdSize)
- {
- RINOK(SzReadID(sd, &type));
- }
-
- for (i = 0; i < *numUnpackStreams; i++)
- {
- (*digestsDefined)[i] = 0;
- (*digests)[i] = 0;
- }
-
-
- for (i = 0; i < numFolders; i++)
- {
- UInt32 numSubstreams = folders[i].NumUnpackStreams;
- if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
- numDigests += numSubstreams;
- }
-
-
- si = 0;
- for (;;)
- {
- if (type == k7zIdCRC)
- {
- int digestIndex = 0;
- Byte *digestsDefined2 = 0;
- UInt32 *digests2 = 0;
- SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);
- if (res == SZ_OK)
- {
- for (i = 0; i < numFolders; i++)
- {
- CSzFolder *folder = folders + i;
- UInt32 numSubstreams = folder->NumUnpackStreams;
- if (numSubstreams == 1 && folder->UnpackCRCDefined)
- {
- (*digestsDefined)[si] = 1;
- (*digests)[si] = folder->UnpackCRC;
- si++;
- }
- else
- {
- UInt32 j;
- for (j = 0; j < numSubstreams; j++, digestIndex++)
- {
- (*digestsDefined)[si] = digestsDefined2[digestIndex];
- (*digests)[si] = digests2[digestIndex];
- si++;
- }
- }
- }
- }
- IAlloc_Free(allocTemp, digestsDefined2);
- IAlloc_Free(allocTemp, digests2);
- RINOK(res);
- }
- else if (type == k7zIdEnd)
- return SZ_OK;
- else
- {
- RINOK(SzSkeepData(sd));
- }
- RINOK(SzReadID(sd, &type));
- }
-}
-
-
-static SRes SzReadStreamsInfo(
- CSzData *sd,
- UInt64 *dataOffset,
- CSzAr *p,
- UInt32 *numUnpackStreams,
- UInt64 **unpackSizes, /* allocTemp */
- Byte **digestsDefined, /* allocTemp */
- UInt32 **digests, /* allocTemp */
- ISzAlloc *alloc,
- ISzAlloc *allocTemp)
-{
- for (;;)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if ((UInt64)(int)type != type)
- return SZ_ERROR_UNSUPPORTED;
- switch((int)type)
- {
- case k7zIdEnd:
- return SZ_OK;
- case k7zIdPackInfo:
- {
- RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams,
- &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc));
- break;
- }
- case k7zIdUnpackInfo:
- {
- RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp));
- break;
- }
- case k7zIdSubStreamsInfo:
- {
- RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,
- numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp));
- break;
- }
- default:
- return SZ_ERROR_UNSUPPORTED;
- }
- }
-}
-
-size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
-{
- size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
- if (dest != 0)
- {
- size_t i;
- const Byte *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2);
- for (i = 0; i < len; i++)
- dest[i] = GetUi16(src + i * 2);
- }
- return len;
-}
-
-static SRes SzReadFileNames(const Byte *p, size_t size, UInt32 numFiles, size_t *sizes)
-{
- UInt32 i;
- size_t pos = 0;
- for (i = 0; i < numFiles; i++)
- {
- sizes[i] = pos;
- for (;;)
- {
- if (pos >= size)
- return SZ_ERROR_ARCHIVE;
- if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0)
- break;
- pos++;
- }
- pos++;
- }
- sizes[i] = pos;
- return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
-}
-
-static SRes SzReadHeader2(
- CSzArEx *p, /* allocMain */
- CSzData *sd,
- UInt64 **unpackSizes, /* allocTemp */
- Byte **digestsDefined, /* allocTemp */
- UInt32 **digests, /* allocTemp */
- Byte **emptyStreamVector, /* allocTemp */
- Byte **emptyFileVector, /* allocTemp */
- Byte **lwtVector, /* allocTemp */
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- UInt64 type;
- UInt32 numUnpackStreams = 0;
- UInt32 numFiles = 0;
- CSzFileItem *files = 0;
- UInt32 numEmptyStreams = 0;
- UInt32 i;
-
- RINOK(SzReadID(sd, &type));
-
- if (type == k7zIdArchiveProperties)
- {
- RINOK(SzReadArchiveProperties(sd));
- RINOK(SzReadID(sd, &type));
- }
-
-
- if (type == k7zIdMainStreamsInfo)
- {
- RINOK(SzReadStreamsInfo(sd,
- &p->dataPos,
- &p->db,
- &numUnpackStreams,
- unpackSizes,
- digestsDefined,
- digests, allocMain, allocTemp));
- p->dataPos += p->startPosAfterHeader;
- RINOK(SzReadID(sd, &type));
- }
-
- if (type == k7zIdEnd)
- return SZ_OK;
- if (type != k7zIdFilesInfo)
- return SZ_ERROR_ARCHIVE;
-
- RINOK(SzReadNumber32(sd, &numFiles));
- p->db.NumFiles = numFiles;
-
- MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain);
-
- p->db.Files = files;
- for (i = 0; i < numFiles; i++)
- SzFile_Init(files + i);
-
- for (;;)
- {
- UInt64 type;
- UInt64 size;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- break;
- RINOK(SzReadNumber(sd, &size));
- if (size > sd->Size)
- return SZ_ERROR_ARCHIVE;
- if ((UInt64)(int)type != type)
- {
- RINOK(SzSkeepDataSize(sd, size));
- }
- else
- switch((int)type)
- {
- case k7zIdName:
- {
- size_t namesSize;
- RINOK(SzReadSwitch(sd));
- namesSize = (size_t)size - 1;
- if ((namesSize & 1) != 0)
- return SZ_ERROR_ARCHIVE;
- if (!Buf_Create(&p->FileNames, namesSize, allocMain))
- return SZ_ERROR_MEM;
- MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
- memcpy(p->FileNames.data, sd->Data, namesSize);
- RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets))
- RINOK(SzSkeepDataSize(sd, namesSize));
- break;
- }
- case k7zIdEmptyStream:
- {
- RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp));
- numEmptyStreams = 0;
- for (i = 0; i < numFiles; i++)
- if ((*emptyStreamVector)[i])
- numEmptyStreams++;
- break;
- }
- case k7zIdEmptyFile:
- {
- RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
- break;
- }
- case k7zIdWinAttributes:
- {
- RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
- RINOK(SzReadSwitch(sd));
- for (i = 0; i < numFiles; i++)
- {
- CSzFileItem *f = &files[i];
- Byte defined = (*lwtVector)[i];
- f->AttribDefined = defined;
- f->Attrib = 0;
- if (defined)
- {
- RINOK(SzReadUInt32(sd, &f->Attrib));
- }
- }
- IAlloc_Free(allocTemp, *lwtVector);
- *lwtVector = NULL;
- break;
- }
- case k7zIdMTime:
- {
- RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
- RINOK(SzReadSwitch(sd));
- for (i = 0; i < numFiles; i++)
- {
- CSzFileItem *f = &files[i];
- Byte defined = (*lwtVector)[i];
- f->MTimeDefined = defined;
- f->MTime.Low = f->MTime.High = 0;
- if (defined)
- {
- RINOK(SzReadUInt32(sd, &f->MTime.Low));
- RINOK(SzReadUInt32(sd, &f->MTime.High));
- }
- }
- IAlloc_Free(allocTemp, *lwtVector);
- *lwtVector = NULL;
- break;
- }
- default:
- {
- RINOK(SzSkeepDataSize(sd, size));
- }
- }
- }
-
- {
- UInt32 emptyFileIndex = 0;
- UInt32 sizeIndex = 0;
- for (i = 0; i < numFiles; i++)
- {
- CSzFileItem *file = files + i;
- file->IsAnti = 0;
- if (*emptyStreamVector == 0)
- file->HasStream = 1;
- else
- file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
- if (file->HasStream)
- {
- file->IsDir = 0;
- file->Size = (*unpackSizes)[sizeIndex];
- file->Crc = (*digests)[sizeIndex];
- file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex];
- sizeIndex++;
- }
- else
- {
- if (*emptyFileVector == 0)
- file->IsDir = 1;
- else
- file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
- emptyFileIndex++;
- file->Size = 0;
- file->Crc = 0;
- file->CrcDefined = 0;
- }
- }
- }
- return SzArEx_Fill(p, allocMain);
-}
-
-static SRes SzReadHeader(
- CSzArEx *p,
- CSzData *sd,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- UInt64 *unpackSizes = 0;
- Byte *digestsDefined = 0;
- UInt32 *digests = 0;
- Byte *emptyStreamVector = 0;
- Byte *emptyFileVector = 0;
- Byte *lwtVector = 0;
- SRes res = SzReadHeader2(p, sd,
- &unpackSizes, &digestsDefined, &digests,
- &emptyStreamVector, &emptyFileVector, &lwtVector,
- allocMain, allocTemp);
- IAlloc_Free(allocTemp, unpackSizes);
- IAlloc_Free(allocTemp, digestsDefined);
- IAlloc_Free(allocTemp, digests);
- IAlloc_Free(allocTemp, emptyStreamVector);
- IAlloc_Free(allocTemp, emptyFileVector);
- IAlloc_Free(allocTemp, lwtVector);
- return res;
-}
-
-static SRes SzReadAndDecodePackedStreams2(
- ILookInStream *inStream,
- CSzData *sd,
- CBuf *outBuffer,
- UInt64 baseOffset,
- CSzAr *p,
- UInt64 **unpackSizes,
- Byte **digestsDefined,
- UInt32 **digests,
- ISzAlloc *allocTemp)
-{
-
- UInt32 numUnpackStreams = 0;
- UInt64 dataStartPos;
- CSzFolder *folder;
- UInt64 unpackSize;
- SRes res;
-
- RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
- &numUnpackStreams, unpackSizes, digestsDefined, digests,
- allocTemp, allocTemp));
-
- dataStartPos += baseOffset;
- if (p->NumFolders != 1)
- return SZ_ERROR_ARCHIVE;
-
- folder = p->Folders;
- unpackSize = SzFolder_GetUnpackSize(folder);
-
- RINOK(LookInStream_SeekTo(inStream, dataStartPos));
-
- if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
- return SZ_ERROR_MEM;
-
- res = SzFolder_Decode(folder, p->PackSizes,
- inStream, dataStartPos,
- outBuffer->data, (size_t)unpackSize, allocTemp);
- RINOK(res);
- if (folder->UnpackCRCDefined)
- if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC)
- return SZ_ERROR_CRC;
- return SZ_OK;
-}
-
-static SRes SzReadAndDecodePackedStreams(
- ILookInStream *inStream,
- CSzData *sd,
- CBuf *outBuffer,
- UInt64 baseOffset,
- ISzAlloc *allocTemp)
-{
- CSzAr p;
- UInt64 *unpackSizes = 0;
- Byte *digestsDefined = 0;
- UInt32 *digests = 0;
- SRes res;
- SzAr_Init(&p);
- res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
- &p, &unpackSizes, &digestsDefined, &digests,
- allocTemp);
- SzAr_Free(&p, allocTemp);
- IAlloc_Free(allocTemp, unpackSizes);
- IAlloc_Free(allocTemp, digestsDefined);
- IAlloc_Free(allocTemp, digests);
- return res;
-}
-
-static SRes SzArEx_Open2(
- CSzArEx *p,
- ILookInStream *inStream,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- Byte header[k7zStartHeaderSize];
- Int64 startArcPos;
- UInt64 nextHeaderOffset, nextHeaderSize;
- size_t nextHeaderSizeT;
- UInt32 nextHeaderCRC;
- CBuf buffer;
- SRes res;
-
- startArcPos = 0;
- RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
-
- RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
-
- if (!TestSignatureCandidate(header))
- return SZ_ERROR_NO_ARCHIVE;
- if (header[6] != k7zMajorVersion)
- return SZ_ERROR_UNSUPPORTED;
-
- nextHeaderOffset = GetUi64(header + 12);
- nextHeaderSize = GetUi64(header + 20);
- nextHeaderCRC = GetUi32(header + 28);
-
- p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;
-
- if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
- return SZ_ERROR_CRC;
-
- nextHeaderSizeT = (size_t)nextHeaderSize;
- if (nextHeaderSizeT != nextHeaderSize)
- return SZ_ERROR_MEM;
- if (nextHeaderSizeT == 0)
- return SZ_OK;
- if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
- nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
- return SZ_ERROR_NO_ARCHIVE;
-
- {
- Int64 pos = 0;
- RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
- if ((UInt64)pos < startArcPos + nextHeaderOffset ||
- (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
- (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
- return SZ_ERROR_INPUT_EOF;
- }
-
- RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));
-
- if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
- return SZ_ERROR_MEM;
-
- res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT);
- if (res == SZ_OK)
- {
- res = SZ_ERROR_ARCHIVE;
- if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)
- {
- CSzData sd;
- UInt64 type;
- sd.Data = buffer.data;
- sd.Size = buffer.size;
- res = SzReadID(&sd, &type);
- if (res == SZ_OK)
- {
- if (type == k7zIdEncodedHeader)
- {
- CBuf outBuffer;
- Buf_Init(&outBuffer);
- res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp);
- if (res != SZ_OK)
- Buf_Free(&outBuffer, allocTemp);
- else
- {
- Buf_Free(&buffer, allocTemp);
- buffer.data = outBuffer.data;
- buffer.size = outBuffer.size;
- sd.Data = buffer.data;
- sd.Size = buffer.size;
- res = SzReadID(&sd, &type);
- }
- }
- }
- if (res == SZ_OK)
- {
- if (type == k7zIdHeader)
- res = SzReadHeader(p, &sd, allocMain, allocTemp);
- else
- res = SZ_ERROR_UNSUPPORTED;
- }
- }
- }
- Buf_Free(&buffer, allocTemp);
- return res;
-}
-
-SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp)
-{
- SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
- if (res != SZ_OK)
- SzArEx_Free(p, allocMain);
- return res;
-}
-
-SRes SzArEx_Extract(
- const CSzArEx *p,
- ILookInStream *inStream,
- UInt32 fileIndex,
- UInt32 *blockIndex,
- Byte **outBuffer,
- size_t *outBufferSize,
- size_t *offset,
- size_t *outSizeProcessed,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
- SRes res = SZ_OK;
- *offset = 0;
- *outSizeProcessed = 0;
- if (folderIndex == (UInt32)-1)
- {
- IAlloc_Free(allocMain, *outBuffer);
- *blockIndex = folderIndex;
- *outBuffer = 0;
- *outBufferSize = 0;
- return SZ_OK;
- }
-
- if (*outBuffer == 0 || *blockIndex != folderIndex)
- {
- CSzFolder *folder = p->db.Folders + folderIndex;
- UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
- size_t unpackSize = (size_t)unpackSizeSpec;
- UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
-
- if (unpackSize != unpackSizeSpec)
- return SZ_ERROR_MEM;
- *blockIndex = folderIndex;
- IAlloc_Free(allocMain, *outBuffer);
- *outBuffer = 0;
-
- RINOK(LookInStream_SeekTo(inStream, startOffset));
-
- if (res == SZ_OK)
- {
- *outBufferSize = unpackSize;
- if (unpackSize != 0)
- {
- *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
- if (*outBuffer == 0)
- res = SZ_ERROR_MEM;
- }
- if (res == SZ_OK)
- {
- res = SzFolder_Decode(folder,
- p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex],
- inStream, startOffset,
- *outBuffer, unpackSize, allocTemp);
- if (res == SZ_OK)
- {
- if (folder->UnpackCRCDefined)
- {
- if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
- res = SZ_ERROR_CRC;
- }
- }
- }
- }
- }
- if (res == SZ_OK)
- {
- UInt32 i;
- CSzFileItem *fileItem = p->db.Files + fileIndex;
- *offset = 0;
- for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
- *offset += (UInt32)p->db.Files[i].Size;
- *outSizeProcessed = (size_t)fileItem->Size;
- if (*offset + *outSizeProcessed > *outBufferSize)
- return SZ_ERROR_FAIL;
- if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc)
- res = SZ_ERROR_CRC;
- }
- return res;
-}
diff --git a/3rdparty/lzma/C/7zStream.c b/3rdparty/lzma/C/7zStream.c
index 0ebb7b5f93c..88f9c42b1dd 100644
--- a/3rdparty/lzma/C/7zStream.c
+++ b/3rdparty/lzma/C/7zStream.c
@@ -1,9 +1,11 @@
/* 7zStream.c -- 7z Stream functions
-2010-03-11 : Igor Pavlov : Public domain */
+2013-11-12 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <string.h>
-#include "Types.h"
+#include "7zTypes.h"
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
{
diff --git a/3rdparty/lzma/C/Types.h b/3rdparty/lzma/C/7zTypes.h
index 1dfea2fbea4..778413ef424 100644
--- a/3rdparty/lzma/C/Types.h
+++ b/3rdparty/lzma/C/7zTypes.h
@@ -1,15 +1,15 @@
-/* Types.h -- Basic types
-2010-10-09 : Igor Pavlov : Public domain */
+/* 7zTypes.h -- Basic types
+2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
-#include <stddef.h>
-
-#ifdef _WIN32_7Z
-#include <windows.h>
+#ifdef _WIN32
+/* #include <windows.h> */
#endif
+#include <stddef.h>
+
#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
@@ -42,8 +42,9 @@ EXTERN_C_BEGIN
typedef int SRes;
-#ifdef _WIN32_7Z
-typedef DWORD WRes;
+#ifdef _WIN32
+/* typedef DWORD WRes; */
+typedef unsigned WRes;
#else
typedef int WRes;
#endif
@@ -97,7 +98,7 @@ typedef int Bool;
#define False 0
-#ifdef _WIN32_7Z
+#ifdef _WIN32
#define MY_STD_CALL __stdcall
#else
#define MY_STD_CALL
@@ -116,6 +117,7 @@ typedef int Bool;
#else
+#define MY_NO_INLINE
#define MY_CDECL
#define MY_FAST_CALL
@@ -233,7 +235,7 @@ typedef struct
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
-#ifdef _WIN32_7Z
+#ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\'
#define WCHAR_PATH_SEPARATOR L'\\'
diff --git a/3rdparty/lzma/C/7zVersion.h b/3rdparty/lzma/C/7zVersion.h
index 5a83e5f74ef..c4f5c8e940c 100644
--- a/3rdparty/lzma/C/7zVersion.h
+++ b/3rdparty/lzma/C/7zVersion.h
@@ -1,8 +1,19 @@
-#define MY_VER_MAJOR 9
-#define MY_VER_MINOR 22
-#define MY_VER_BUILD 00
-#define MY_VERSION "9.22 beta"
-#define MY_7ZIP_VERSION "9.22 beta"
-#define MY_DATE "2011-04-18"
-#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
-#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
+#define MY_VER_MAJOR 15
+#define MY_VER_MINOR 14
+#define MY_VER_BUILD 0
+#define MY_VERSION_NUMBERS "15.14"
+#define MY_VERSION "15.14"
+#define MY_DATE "2015-12-31"
+#undef MY_COPYRIGHT
+#undef MY_VERSION_COPYRIGHT_DATE
+#define MY_AUTHOR_NAME "Igor Pavlov"
+#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
+#define MY_COPYRIGHT_CR "Copyright (c) 1999-2015 Igor Pavlov"
+
+#ifdef USE_COPYRIGHT_CR
+ #define MY_COPYRIGHT MY_COPYRIGHT_CR
+#else
+ #define MY_COPYRIGHT MY_COPYRIGHT_PD
+#endif
+
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE
diff --git a/3rdparty/lzma/C/Aes.c b/3rdparty/lzma/C/Aes.c
new file mode 100644
index 00000000000..7c100c55db8
--- /dev/null
+++ b/3rdparty/lzma/C/Aes.c
@@ -0,0 +1,295 @@
+/* Aes.c -- AES encryption / decryption
+2015-02-23 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "Aes.h"
+#include "CpuArch.h"
+
+static UInt32 T[256 * 4];
+static const Byte Sbox[256] = {
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
+
+void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks);
+
+void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
+
+AES_CODE_FUNC g_AesCbc_Encode;
+AES_CODE_FUNC g_AesCbc_Decode;
+AES_CODE_FUNC g_AesCtr_Code;
+
+static UInt32 D[256 * 4];
+static Byte InvS[256];
+
+static const Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
+
+#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF)
+
+#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24))
+
+#define gb0(x) ( (x) & 0xFF)
+#define gb1(x) (((x) >> ( 8)) & 0xFF)
+#define gb2(x) (((x) >> (16)) & 0xFF)
+#define gb3(x) (((x) >> (24)) & 0xFF)
+
+void AesGenTables(void)
+{
+ unsigned i;
+ for (i = 0; i < 256; i++)
+ InvS[Sbox[i]] = (Byte)i;
+
+ for (i = 0; i < 256; i++)
+ {
+ {
+ UInt32 a1 = Sbox[i];
+ UInt32 a2 = xtime(a1);
+ UInt32 a3 = a2 ^ a1;
+ T[ i] = Ui32(a2, a1, a1, a3);
+ T[0x100 + i] = Ui32(a3, a2, a1, a1);
+ T[0x200 + i] = Ui32(a1, a3, a2, a1);
+ T[0x300 + i] = Ui32(a1, a1, a3, a2);
+ }
+ {
+ UInt32 a1 = InvS[i];
+ UInt32 a2 = xtime(a1);
+ UInt32 a4 = xtime(a2);
+ UInt32 a8 = xtime(a4);
+ UInt32 a9 = a8 ^ a1;
+ UInt32 aB = a8 ^ a2 ^ a1;
+ UInt32 aD = a8 ^ a4 ^ a1;
+ UInt32 aE = a8 ^ a4 ^ a2;
+ D[ i] = Ui32(aE, a9, aD, aB);
+ D[0x100 + i] = Ui32(aB, aE, a9, aD);
+ D[0x200 + i] = Ui32(aD, aB, aE, a9);
+ D[0x300 + i] = Ui32(a9, aD, aB, aE);
+ }
+ }
+
+ g_AesCbc_Encode = AesCbc_Encode;
+ g_AesCbc_Decode = AesCbc_Decode;
+ g_AesCtr_Code = AesCtr_Code;
+
+ #ifdef MY_CPU_X86_OR_AMD64
+ if (CPU_Is_Aes_Supported())
+ {
+ g_AesCbc_Encode = AesCbc_Encode_Intel;
+ g_AesCbc_Decode = AesCbc_Decode_Intel;
+ g_AesCtr_Code = AesCtr_Code_Intel;
+ }
+ #endif
+}
+
+
+#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])]
+
+#define HT4(m, i, s, p) m[i] = \
+ HT(i, 0, s) ^ \
+ HT(i, 1, s) ^ \
+ HT(i, 2, s) ^ \
+ HT(i, 3, s) ^ w[p + i]
+
+#define HT16(m, s, p) \
+ HT4(m, 0, s, p); \
+ HT4(m, 1, s, p); \
+ HT4(m, 2, s, p); \
+ HT4(m, 3, s, p); \
+
+#define FT(i, x) Sbox[gb ## x(m[(i + x) & 3])]
+#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i];
+
+
+#define HD(i, x, s) (D + (x << 8))[gb ## x(s[(i - x) & 3])]
+
+#define HD4(m, i, s, p) m[i] = \
+ HD(i, 0, s) ^ \
+ HD(i, 1, s) ^ \
+ HD(i, 2, s) ^ \
+ HD(i, 3, s) ^ w[p + i];
+
+#define HD16(m, s, p) \
+ HD4(m, 0, s, p); \
+ HD4(m, 1, s, p); \
+ HD4(m, 2, s, p); \
+ HD4(m, 3, s, p); \
+
+#define FD(i, x) InvS[gb ## x(m[(i - x) & 3])]
+#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i];
+
+void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize)
+{
+ unsigned i, wSize;
+ wSize = keySize + 28;
+ keySize /= 4;
+ w[0] = ((UInt32)keySize / 2) + 3;
+ w += 4;
+
+ for (i = 0; i < keySize; i++, key += 4)
+ w[i] = GetUi32(key);
+
+ for (; i < wSize; i++)
+ {
+ UInt32 t = w[i - 1];
+ unsigned rem = i % keySize;
+ if (rem == 0)
+ t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]);
+ else if (keySize > 6 && rem == 4)
+ t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]);
+ w[i] = w[i - keySize] ^ t;
+ }
+}
+
+void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize)
+{
+ unsigned i, num;
+ Aes_SetKey_Enc(w, key, keySize);
+ num = keySize + 20;
+ w += 8;
+ for (i = 0; i < num; i++)
+ {
+ UInt32 r = w[i];
+ w[i] =
+ D[ Sbox[gb0(r)]] ^
+ D[0x100 + Sbox[gb1(r)]] ^
+ D[0x200 + Sbox[gb2(r)]] ^
+ D[0x300 + Sbox[gb3(r)]];
+ }
+}
+
+/* Aes_Encode and Aes_Decode functions work with little-endian words.
+ src and dest are pointers to 4 UInt32 words.
+ src and dest can point to same block */
+
+static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src)
+{
+ UInt32 s[4];
+ UInt32 m[4];
+ UInt32 numRounds2 = w[0];
+ w += 4;
+ s[0] = src[0] ^ w[0];
+ s[1] = src[1] ^ w[1];
+ s[2] = src[2] ^ w[2];
+ s[3] = src[3] ^ w[3];
+ w += 4;
+ for (;;)
+ {
+ HT16(m, s, 0);
+ if (--numRounds2 == 0)
+ break;
+ HT16(s, m, 4);
+ w += 8;
+ }
+ w += 4;
+ FT4(0); FT4(1); FT4(2); FT4(3);
+}
+
+static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src)
+{
+ UInt32 s[4];
+ UInt32 m[4];
+ UInt32 numRounds2 = w[0];
+ w += 4 + numRounds2 * 8;
+ s[0] = src[0] ^ w[0];
+ s[1] = src[1] ^ w[1];
+ s[2] = src[2] ^ w[2];
+ s[3] = src[3] ^ w[3];
+ for (;;)
+ {
+ w -= 8;
+ HD16(m, s, 4);
+ if (--numRounds2 == 0)
+ break;
+ HD16(s, m, 0);
+ }
+ FD4(0); FD4(1); FD4(2); FD4(3);
+}
+
+void AesCbc_Init(UInt32 *p, const Byte *iv)
+{
+ unsigned i;
+ for (i = 0; i < 4; i++)
+ p[i] = GetUi32(iv + i * 4);
+}
+
+void MY_FAST_CALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks)
+{
+ for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE)
+ {
+ p[0] ^= GetUi32(data);
+ p[1] ^= GetUi32(data + 4);
+ p[2] ^= GetUi32(data + 8);
+ p[3] ^= GetUi32(data + 12);
+
+ Aes_Encode(p + 4, p, p);
+
+ SetUi32(data, p[0]);
+ SetUi32(data + 4, p[1]);
+ SetUi32(data + 8, p[2]);
+ SetUi32(data + 12, p[3]);
+ }
+}
+
+void MY_FAST_CALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks)
+{
+ UInt32 in[4], out[4];
+ for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE)
+ {
+ in[0] = GetUi32(data);
+ in[1] = GetUi32(data + 4);
+ in[2] = GetUi32(data + 8);
+ in[3] = GetUi32(data + 12);
+
+ Aes_Decode(p + 4, out, in);
+
+ SetUi32(data, p[0] ^ out[0]);
+ SetUi32(data + 4, p[1] ^ out[1]);
+ SetUi32(data + 8, p[2] ^ out[2]);
+ SetUi32(data + 12, p[3] ^ out[3]);
+
+ p[0] = in[0];
+ p[1] = in[1];
+ p[2] = in[2];
+ p[3] = in[3];
+ }
+}
+
+void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks)
+{
+ for (; numBlocks != 0; numBlocks--)
+ {
+ UInt32 temp[4];
+ Byte buf[16];
+ int i;
+
+ if (++p[0] == 0)
+ p[1]++;
+
+ Aes_Encode(p + 4, temp, p);
+
+ SetUi32(buf, temp[0]);
+ SetUi32(buf + 4, temp[1]);
+ SetUi32(buf + 8, temp[2]);
+ SetUi32(buf + 12, temp[3]);
+
+ for (i = 0; i < 16; i++)
+ *data++ ^= buf[i];
+ }
+}
diff --git a/3rdparty/lzma/C/Aes.h b/3rdparty/lzma/C/Aes.h
new file mode 100644
index 00000000000..64979b5bcbf
--- /dev/null
+++ b/3rdparty/lzma/C/Aes.h
@@ -0,0 +1,38 @@
+/* Aes.h -- AES encryption / decryption
+2013-01-18 : Igor Pavlov : Public domain */
+
+#ifndef __AES_H
+#define __AES_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+#define AES_BLOCK_SIZE 16
+
+/* Call AesGenTables one time before other AES functions */
+void AesGenTables(void);
+
+/* UInt32 pointers must be 16-byte aligned */
+
+/* 16-byte (4 * 32-bit words) blocks: 1 (IV) + 1 (keyMode) + 15 (AES-256 roundKeys) */
+#define AES_NUM_IVMRK_WORDS ((1 + 1 + 15) * 4)
+
+/* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */
+/* keySize = 16 or 24 or 32 (bytes) */
+typedef void (MY_FAST_CALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize);
+void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize);
+void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize);
+
+/* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */
+void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */
+/* data - 16-byte aligned pointer to data */
+/* numBlocks - the number of 16-byte blocks in data array */
+typedef void (MY_FAST_CALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks);
+extern AES_CODE_FUNC g_AesCbc_Encode;
+extern AES_CODE_FUNC g_AesCbc_Decode;
+extern AES_CODE_FUNC g_AesCtr_Code;
+
+EXTERN_C_END
+
+#endif
diff --git a/3rdparty/lzma/C/AesOpt.c b/3rdparty/lzma/C/AesOpt.c
new file mode 100644
index 00000000000..10a8fb25c51
--- /dev/null
+++ b/3rdparty/lzma/C/AesOpt.c
@@ -0,0 +1,184 @@
+/* AesOpt.c -- Intel's AES
+2013-11-12 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "CpuArch.h"
+
+#ifdef MY_CPU_X86_OR_AMD64
+#if _MSC_VER >= 1500
+#define USE_INTEL_AES
+#endif
+#endif
+
+#ifdef USE_INTEL_AES
+
+#include <wmmintrin.h>
+
+void MY_FAST_CALL AesCbc_Encode_Intel(__m128i *p, __m128i *data, size_t numBlocks)
+{
+ __m128i m = *p;
+ for (; numBlocks != 0; numBlocks--, data++)
+ {
+ UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
+ const __m128i *w = p + 3;
+ m = _mm_xor_si128(m, *data);
+ m = _mm_xor_si128(m, p[2]);
+ do
+ {
+ m = _mm_aesenc_si128(m, w[0]);
+ m = _mm_aesenc_si128(m, w[1]);
+ w += 2;
+ }
+ while (--numRounds2 != 0);
+ m = _mm_aesenc_si128(m, w[0]);
+ m = _mm_aesenclast_si128(m, w[1]);
+ *data = m;
+ }
+ *p = m;
+}
+
+#define NUM_WAYS 3
+
+#define AES_OP_W(op, n) { \
+ const __m128i t = w[n]; \
+ m0 = op(m0, t); \
+ m1 = op(m1, t); \
+ m2 = op(m2, t); \
+ }
+
+#define AES_DEC(n) AES_OP_W(_mm_aesdec_si128, n)
+#define AES_DEC_LAST(n) AES_OP_W(_mm_aesdeclast_si128, n)
+#define AES_ENC(n) AES_OP_W(_mm_aesenc_si128, n)
+#define AES_ENC_LAST(n) AES_OP_W(_mm_aesenclast_si128, n)
+
+void MY_FAST_CALL AesCbc_Decode_Intel(__m128i *p, __m128i *data, size_t numBlocks)
+{
+ __m128i iv = *p;
+ for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS)
+ {
+ UInt32 numRounds2 = *(const UInt32 *)(p + 1);
+ const __m128i *w = p + numRounds2 * 2;
+ __m128i m0, m1, m2;
+ {
+ const __m128i t = w[2];
+ m0 = _mm_xor_si128(t, data[0]);
+ m1 = _mm_xor_si128(t, data[1]);
+ m2 = _mm_xor_si128(t, data[2]);
+ }
+ numRounds2--;
+ do
+ {
+ AES_DEC(1)
+ AES_DEC(0)
+ w -= 2;
+ }
+ while (--numRounds2 != 0);
+ AES_DEC(1)
+ AES_DEC_LAST(0)
+
+ {
+ __m128i t;
+ t = _mm_xor_si128(m0, iv); iv = data[0]; data[0] = t;
+ t = _mm_xor_si128(m1, iv); iv = data[1]; data[1] = t;
+ t = _mm_xor_si128(m2, iv); iv = data[2]; data[2] = t;
+ }
+ }
+ for (; numBlocks != 0; numBlocks--, data++)
+ {
+ UInt32 numRounds2 = *(const UInt32 *)(p + 1);
+ const __m128i *w = p + numRounds2 * 2;
+ __m128i m = _mm_xor_si128(w[2], *data);
+ numRounds2--;
+ do
+ {
+ m = _mm_aesdec_si128(m, w[1]);
+ m = _mm_aesdec_si128(m, w[0]);
+ w -= 2;
+ }
+ while (--numRounds2 != 0);
+ m = _mm_aesdec_si128(m, w[1]);
+ m = _mm_aesdeclast_si128(m, w[0]);
+
+ m = _mm_xor_si128(m, iv);
+ iv = *data;
+ *data = m;
+ }
+ *p = iv;
+}
+
+void MY_FAST_CALL AesCtr_Code_Intel(__m128i *p, __m128i *data, size_t numBlocks)
+{
+ __m128i ctr = *p;
+ __m128i one;
+ one.m128i_u64[0] = 1;
+ one.m128i_u64[1] = 0;
+ for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS)
+ {
+ UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
+ const __m128i *w = p;
+ __m128i m0, m1, m2;
+ {
+ const __m128i t = w[2];
+ ctr = _mm_add_epi64(ctr, one); m0 = _mm_xor_si128(ctr, t);
+ ctr = _mm_add_epi64(ctr, one); m1 = _mm_xor_si128(ctr, t);
+ ctr = _mm_add_epi64(ctr, one); m2 = _mm_xor_si128(ctr, t);
+ }
+ w += 3;
+ do
+ {
+ AES_ENC(0)
+ AES_ENC(1)
+ w += 2;
+ }
+ while (--numRounds2 != 0);
+ AES_ENC(0)
+ AES_ENC_LAST(1)
+ data[0] = _mm_xor_si128(data[0], m0);
+ data[1] = _mm_xor_si128(data[1], m1);
+ data[2] = _mm_xor_si128(data[2], m2);
+ }
+ for (; numBlocks != 0; numBlocks--, data++)
+ {
+ UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
+ const __m128i *w = p;
+ __m128i m;
+ ctr = _mm_add_epi64(ctr, one);
+ m = _mm_xor_si128(ctr, p[2]);
+ w += 3;
+ do
+ {
+ m = _mm_aesenc_si128(m, w[0]);
+ m = _mm_aesenc_si128(m, w[1]);
+ w += 2;
+ }
+ while (--numRounds2 != 0);
+ m = _mm_aesenc_si128(m, w[0]);
+ m = _mm_aesenclast_si128(m, w[1]);
+ *data = _mm_xor_si128(*data, m);
+ }
+ *p = ctr;
+}
+
+#else
+
+void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks);
+
+void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *p, Byte *data, size_t numBlocks)
+{
+ AesCbc_Encode(p, data, numBlocks);
+}
+
+void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *p, Byte *data, size_t numBlocks)
+{
+ AesCbc_Decode(p, data, numBlocks);
+}
+
+void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *p, Byte *data, size_t numBlocks)
+{
+ AesCtr_Code(p, data, numBlocks);
+}
+
+#endif
diff --git a/3rdparty/lzma/C/Alloc.c b/3rdparty/lzma/C/Alloc.c
index df7412afe79..3f6ac41918e 100644
--- a/3rdparty/lzma/C/Alloc.c
+++ b/3rdparty/lzma/C/Alloc.c
@@ -1,9 +1,9 @@
/* Alloc.c -- Memory allocation functions
-2008-09-24
-Igor Pavlov
-Public domain */
+2015-02-21 : Igor Pavlov : Public domain */
-#ifdef _WIN32_7Z
+#include "Precomp.h"
+
+#ifdef _WIN32
#include <windows.h>
#endif
#include <stdlib.h>
@@ -44,7 +44,7 @@ void MyFree(void *address)
free(address);
}
-#ifdef _WIN32_7Z
+#ifdef _WIN32
void *MidAlloc(size_t size)
{
@@ -125,3 +125,12 @@ void BigFree(void *address)
}
#endif
+
+
+static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
+static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
+ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+static void *SzBigAlloc(void *p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
+static void SzBigFree(void *p, void *address) { UNUSED_VAR(p); BigFree(address); }
+ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
diff --git a/3rdparty/lzma/C/Alloc.h b/3rdparty/lzma/C/Alloc.h
index 4b73481f4c6..bac0d87e2a0 100644
--- a/3rdparty/lzma/C/Alloc.h
+++ b/3rdparty/lzma/C/Alloc.h
@@ -1,19 +1,17 @@
/* Alloc.h -- Memory allocation functions
-2009-02-07 : Igor Pavlov : Public domain */
+2015-02-21 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H
-#include <stddef.h>
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
void *MyAlloc(size_t size);
void MyFree(void *address);
-#ifdef _WIN32_7Z
+#ifdef _WIN32
void SetLargePageSize();
@@ -31,8 +29,9 @@ void BigFree(void *address);
#endif
-#ifdef __cplusplus
-}
-#endif
+extern ISzAlloc g_Alloc;
+extern ISzAlloc g_BigAlloc;
+
+EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/Bcj2.c b/3rdparty/lzma/C/Bcj2.c
index 20199ce5659..3c88e44fc1f 100644
--- a/3rdparty/lzma/C/Bcj2.c
+++ b/3rdparty/lzma/C/Bcj2.c
@@ -1,132 +1,256 @@
-/* Bcj2.c -- Converter for x86 code (BCJ2)
-2008-10-04 : Igor Pavlov : Public domain */
+/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
+2015-08-01 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "Bcj2.h"
+#include "CpuArch.h"
-#ifdef _LZMA_PROB32
-#define CProb UInt32
-#else
#define CProb UInt16
-#endif
-
-#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
-#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
-
-#define kNumTopBits 24
-#define kTopValue ((UInt32)1 << kNumTopBits)
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kTopValue ((UInt32)1 << 24)
+#define kNumModelBits 11
+#define kBitModelTotal (1 << kNumModelBits)
#define kNumMoveBits 5
-#define RC_READ_BYTE (*buffer++)
-#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
-#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
- { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
+#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
+#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
-#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
-
-#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
-#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
-#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
-
-int Bcj2_Decode(
- const Byte *buf0, SizeT size0,
- const Byte *buf1, SizeT size1,
- const Byte *buf2, SizeT size2,
- const Byte *buf3, SizeT size3,
- Byte *outBuf, SizeT outSize)
+void Bcj2Dec_Init(CBcj2Dec *p)
{
- CProb p[256 + 2];
- SizeT inPos = 0, outPos = 0;
-
- const Byte *buffer, *bufferLim;
- UInt32 range, code;
- Byte prevByte = 0;
+ unsigned i;
- unsigned int i;
- for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
- p[i] = kBitModelTotal >> 1;
-
- buffer = buf3;
- bufferLim = buffer + size3;
- RC_INIT2
+ p->state = BCJ2_DEC_STATE_OK;
+ p->ip = 0;
+ p->temp[3] = 0;
+ p->range = 0;
+ p->code = 0;
+ for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
+ p->probs[i] = kBitModelTotal >> 1;
+}
- if (outSize == 0)
- return SZ_OK;
+SRes Bcj2Dec_Decode(CBcj2Dec *p)
+{
+ if (p->range <= 5)
+ {
+ p->state = BCJ2_DEC_STATE_OK;
+ for (; p->range != 5; p->range++)
+ {
+ if (p->range == 1 && p->code != 0)
+ return SZ_ERROR_DATA;
+
+ if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
+ {
+ p->state = BCJ2_STREAM_RC;
+ return SZ_OK;
+ }
- for (;;)
+ p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
+ }
+
+ if (p->code == 0xFFFFFFFF)
+ return SZ_ERROR_DATA;
+
+ p->range = 0xFFFFFFFF;
+ }
+ else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
{
- Byte b;
- CProb *prob;
- UInt32 bound;
- UInt32 ttt;
-
- SizeT limit = size0 - inPos;
- if (outSize - outPos < limit)
- limit = outSize - outPos;
- while (limit != 0)
+ while (p->state <= BCJ2_DEC_STATE_ORIG_3)
{
- Byte b = buf0[inPos];
- outBuf[outPos++] = b;
- if (IsJ(prevByte, b))
- break;
- inPos++;
- prevByte = b;
- limit--;
+ Byte *dest = p->dest;
+ if (dest == p->destLim)
+ return SZ_OK;
+ *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0];
+ p->dest = dest + 1;
}
+ }
- if (limit == 0 || outPos == outSize)
- break;
-
- b = buf0[inPos++];
-
- if (b == 0xE8)
- prob = p + prevByte;
- else if (b == 0xE9)
- prob = p + 256;
- else
- prob = p + 257;
-
- IF_BIT_0(prob)
+ /*
+ if (BCJ2_IS_32BIT_STREAM(p->state))
+ {
+ const Byte *cur = p->bufs[p->state];
+ if (cur == p->lims[p->state])
+ return SZ_OK;
+ p->bufs[p->state] = cur + 4;
+
{
- UPDATE_0(prob)
- prevByte = b;
+ UInt32 val;
+ Byte *dest;
+ SizeT rem;
+
+ p->ip += 4;
+ val = GetBe32(cur) - p->ip;
+ dest = p->dest;
+ rem = p->destLim - dest;
+ if (rem < 4)
+ {
+ SizeT i;
+ SetUi32(p->temp, val);
+ for (i = 0; i < rem; i++)
+ dest[i] = p->temp[i];
+ p->dest = dest + rem;
+ p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
+ return SZ_OK;
+ }
+ SetUi32(dest, val);
+ p->temp[3] = (Byte)(val >> 24);
+ p->dest = dest + 4;
+ p->state = BCJ2_DEC_STATE_OK;
}
+ }
+ */
+
+ for (;;)
+ {
+ if (BCJ2_IS_32BIT_STREAM(p->state))
+ p->state = BCJ2_DEC_STATE_OK;
else
{
- UInt32 dest;
- const Byte *v;
- UPDATE_1(prob)
- if (b == 0xE8)
+ if (p->range < kTopValue)
{
- v = buf1;
- if (size1 < 4)
- return SZ_ERROR_DATA;
- buf1 += 4;
- size1 -= 4;
+ if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
+ {
+ p->state = BCJ2_STREAM_RC;
+ return SZ_OK;
+ }
+ p->range <<= 8;
+ p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
}
- else
+
{
- v = buf2;
- if (size2 < 4)
- return SZ_ERROR_DATA;
- buf2 += 4;
- size2 -= 4;
+ const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
+ const Byte *srcLim;
+ Byte *dest;
+ SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
+
+ if (num == 0)
+ {
+ p->state = BCJ2_STREAM_MAIN;
+ return SZ_OK;
+ }
+
+ dest = p->dest;
+ if (num > (SizeT)(p->destLim - dest))
+ {
+ num = p->destLim - dest;
+ if (num == 0)
+ {
+ p->state = BCJ2_DEC_STATE_ORIG;
+ return SZ_OK;
+ }
+ }
+
+ srcLim = src + num;
+
+ if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
+ *dest = src[0];
+ else for (;;)
+ {
+ Byte b = *src;
+ *dest = b;
+ if (b != 0x0F)
+ {
+ if ((b & 0xFE) == 0xE8)
+ break;
+ dest++;
+ if (++src != srcLim)
+ continue;
+ break;
+ }
+ dest++;
+ if (++src == srcLim)
+ break;
+ if ((*src & 0xF0) != 0x80)
+ continue;
+ *dest = *src;
+ break;
+ }
+
+ num = src - p->bufs[BCJ2_STREAM_MAIN];
+
+ if (src == srcLim)
+ {
+ p->temp[3] = src[-1];
+ p->bufs[BCJ2_STREAM_MAIN] = src;
+ p->ip += (UInt32)num;
+ p->dest += num;
+ p->state =
+ p->bufs[BCJ2_STREAM_MAIN] ==
+ p->lims[BCJ2_STREAM_MAIN] ?
+ (unsigned)BCJ2_STREAM_MAIN :
+ (unsigned)BCJ2_DEC_STATE_ORIG;
+ return SZ_OK;
+ }
+
+ {
+ UInt32 bound, ttt;
+ CProb *prob;
+ Byte b = src[0];
+ Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
+
+ p->temp[3] = b;
+ p->bufs[BCJ2_STREAM_MAIN] = src + 1;
+ num++;
+ p->ip += (UInt32)num;
+ p->dest += num;
+
+ prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
+
+ _IF_BIT_0
+ {
+ _UPDATE_0
+ continue;
+ }
+ _UPDATE_1
+
+ }
}
- dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
- ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
- outBuf[outPos++] = (Byte)dest;
- if (outPos == outSize)
- break;
- outBuf[outPos++] = (Byte)(dest >> 8);
- if (outPos == outSize)
+ }
+
+ {
+ UInt32 val;
+ unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
+ const Byte *cur = p->bufs[cj];
+ Byte *dest;
+ SizeT rem;
+
+ if (cur == p->lims[cj])
+ {
+ p->state = cj;
break;
- outBuf[outPos++] = (Byte)(dest >> 16);
- if (outPos == outSize)
+ }
+
+ val = GetBe32(cur);
+ p->bufs[cj] = cur + 4;
+
+ p->ip += 4;
+ val -= p->ip;
+ dest = p->dest;
+ rem = p->destLim - dest;
+
+ if (rem < 4)
+ {
+ SizeT i;
+ SetUi32(p->temp, val);
+ for (i = 0; i < rem; i++)
+ dest[i] = p->temp[i];
+ p->dest = dest + rem;
+ p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
break;
- outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
+ }
+
+ SetUi32(dest, val);
+ p->temp[3] = (Byte)(val >> 24);
+ p->dest = dest + 4;
}
}
- return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
+
+ if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])
+ {
+ p->range <<= 8;
+ p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
+ }
+
+ return SZ_OK;
}
diff --git a/3rdparty/lzma/C/Bcj2.h b/3rdparty/lzma/C/Bcj2.h
index dbc054148d2..8824080acfb 100644
--- a/3rdparty/lzma/C/Bcj2.h
+++ b/3rdparty/lzma/C/Bcj2.h
@@ -1,38 +1,146 @@
-/* Bcj2.h -- Converter for x86 code (BCJ2)
-2009-02-07 : Igor Pavlov : Public domain */
+/* Bcj2.h -- BCJ2 Converter for x86 code
+2014-11-10 : Igor Pavlov : Public domain */
#ifndef __BCJ2_H
#define __BCJ2_H
-#include "Types.h"
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
-/*
-Conditions:
- outSize <= FullOutputSize,
- where FullOutputSize is full size of output stream of x86_2 filter.
+#define BCJ2_NUM_STREAMS 4
+
+enum
+{
+ BCJ2_STREAM_MAIN,
+ BCJ2_STREAM_CALL,
+ BCJ2_STREAM_JUMP,
+ BCJ2_STREAM_RC
+};
+
+enum
+{
+ BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS,
+ BCJ2_DEC_STATE_ORIG_1,
+ BCJ2_DEC_STATE_ORIG_2,
+ BCJ2_DEC_STATE_ORIG_3,
+
+ BCJ2_DEC_STATE_ORIG,
+ BCJ2_DEC_STATE_OK
+};
-If buf0 overlaps outBuf, there are two required conditions:
- 1) (buf0 >= outBuf)
- 2) (buf0 + size0 >= outBuf + FullOutputSize).
+enum
+{
+ BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS,
+ BCJ2_ENC_STATE_OK
+};
+
+
+#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP)
+
+/*
+CBcj2Dec / CBcj2Enc
+bufs sizes:
+ BUF_SIZE(n) = lims[n] - bufs[n]
+bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4:
+ (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0
+ (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0
+*/
-Returns:
- SZ_OK
- SZ_ERROR_DATA - Data error
+/*
+CBcj2Dec:
+dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions:
+ bufs[BCJ2_STREAM_MAIN] >= dest &&
+ bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv +
+ BUF_SIZE(BCJ2_STREAM_CALL) +
+ BUF_SIZE(BCJ2_STREAM_JUMP)
+ tempReserv = 0 : for first call of Bcj2Dec_Decode
+ tempReserv = 4 : for any other calls of Bcj2Dec_Decode
+ overlap with offset = 1 is not allowed
*/
-int Bcj2_Decode(
- const Byte *buf0, SizeT size0,
- const Byte *buf1, SizeT size1,
- const Byte *buf2, SizeT size2,
- const Byte *buf3, SizeT size3,
- Byte *outBuf, SizeT outSize);
+typedef struct
+{
+ const Byte *bufs[BCJ2_NUM_STREAMS];
+ const Byte *lims[BCJ2_NUM_STREAMS];
+ Byte *dest;
+ const Byte *destLim;
-#ifdef __cplusplus
-}
-#endif
+ unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */
+
+ UInt32 ip;
+ Byte temp[4];
+ UInt32 range;
+ UInt32 code;
+ UInt16 probs[2 + 256];
+} CBcj2Dec;
+
+void Bcj2Dec_Init(CBcj2Dec *p);
+
+/* Returns: SZ_OK or SZ_ERROR_DATA */
+SRes Bcj2Dec_Decode(CBcj2Dec *p);
+
+#define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0)
+
+
+
+typedef enum
+{
+ BCJ2_ENC_FINISH_MODE_CONTINUE,
+ BCJ2_ENC_FINISH_MODE_END_BLOCK,
+ BCJ2_ENC_FINISH_MODE_END_STREAM
+} EBcj2Enc_FinishMode;
+
+typedef struct
+{
+ Byte *bufs[BCJ2_NUM_STREAMS];
+ const Byte *lims[BCJ2_NUM_STREAMS];
+ const Byte *src;
+ const Byte *srcLim;
+
+ unsigned state;
+ EBcj2Enc_FinishMode finishMode;
+
+ Byte prevByte;
+
+ Byte cache;
+ UInt32 range;
+ UInt64 low;
+ UInt64 cacheSize;
+
+ UInt32 ip;
+
+ /* 32-bit ralative offset in JUMP/CALL commands is
+ - (mod 4 GB) in 32-bit mode
+ - signed Int32 in 64-bit mode
+ We use (mod 4 GB) check for fileSize.
+ Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */
+ UInt32 fileIp;
+ UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */
+ UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */
+
+ UInt32 tempTarget;
+ unsigned tempPos;
+ Byte temp[4 * 2];
+
+ unsigned flushPos;
+
+ UInt16 probs[2 + 256];
+} CBcj2Enc;
+
+void Bcj2Enc_Init(CBcj2Enc *p);
+void Bcj2Enc_Encode(CBcj2Enc *p);
+
+#define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos)
+#define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5)
+
+
+#define BCJ2_RELAT_LIMIT_NUM_BITS 26
+#define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS)
+
+/* limit for CBcj2Enc::fileSize variable */
+#define BCJ2_FileSize_MAX ((UInt32)1 << 31)
+
+EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/Bcj2Enc.c b/3rdparty/lzma/C/Bcj2Enc.c
new file mode 100644
index 00000000000..0ea36462cbe
--- /dev/null
+++ b/3rdparty/lzma/C/Bcj2Enc.c
@@ -0,0 +1,312 @@
+/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code)
+2014-11-10 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+/* #define SHOW_STAT */
+
+#ifdef SHOW_STAT
+#include <stdio.h>
+#define PRF(x) x
+#else
+#define PRF(x)
+#endif
+
+#include <windows.h>
+#include <string.h>
+
+#include "Bcj2.h"
+#include "CpuArch.h"
+
+#define CProb UInt16
+
+#define kTopValue ((UInt32)1 << 24)
+#define kNumModelBits 11
+#define kBitModelTotal (1 << kNumModelBits)
+#define kNumMoveBits 5
+
+void Bcj2Enc_Init(CBcj2Enc *p)
+{
+ unsigned i;
+
+ p->state = BCJ2_ENC_STATE_OK;
+ p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE;
+
+ p->prevByte = 0;
+
+ p->cache = 0;
+ p->range = 0xFFFFFFFF;
+ p->low = 0;
+ p->cacheSize = 1;
+
+ p->ip = 0;
+
+ p->fileIp = 0;
+ p->fileSize = 0;
+ p->relatLimit = BCJ2_RELAT_LIMIT;
+
+ p->tempPos = 0;
+
+ p->flushPos = 0;
+
+ for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
+ p->probs[i] = kBitModelTotal >> 1;
+}
+
+static Bool MY_FAST_CALL RangeEnc_ShiftLow(CBcj2Enc *p)
+{
+ if ((UInt32)p->low < (UInt32)0xFF000000 || (UInt32)(p->low >> 32) != 0)
+ {
+ Byte *buf = p->bufs[BCJ2_STREAM_RC];
+ do
+ {
+ if (buf == p->lims[BCJ2_STREAM_RC])
+ {
+ p->state = BCJ2_STREAM_RC;
+ p->bufs[BCJ2_STREAM_RC] = buf;
+ return True;
+ }
+ *buf++ = (Byte)(p->cache + (Byte)(p->low >> 32));
+ p->cache = 0xFF;
+ }
+ while (--p->cacheSize);
+ p->bufs[BCJ2_STREAM_RC] = buf;
+ p->cache = (Byte)((UInt32)p->low >> 24);
+ }
+ p->cacheSize++;
+ p->low = (UInt32)p->low << 8;
+ return False;
+}
+
+static void Bcj2Enc_Encode_2(CBcj2Enc *p)
+{
+ if (BCJ2_IS_32BIT_STREAM(p->state))
+ {
+ Byte *cur = p->bufs[p->state];
+ if (cur == p->lims[p->state])
+ return;
+ SetBe32(cur, p->tempTarget);
+ p->bufs[p->state] = cur + 4;
+ }
+
+ p->state = BCJ2_ENC_STATE_ORIG;
+
+ for (;;)
+ {
+ if (p->range < kTopValue)
+ {
+ if (RangeEnc_ShiftLow(p))
+ return;
+ p->range <<= 8;
+ }
+
+ {
+ {
+ const Byte *src = p->src;
+ const Byte *srcLim;
+ Byte *dest;
+ SizeT num = p->srcLim - src;
+
+ if (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE)
+ {
+ if (num <= 4)
+ return;
+ num -= 4;
+ }
+ else if (num == 0)
+ break;
+
+ dest = p->bufs[BCJ2_STREAM_MAIN];
+ if (num > (SizeT)(p->lims[BCJ2_STREAM_MAIN] - dest))
+ {
+ num = p->lims[BCJ2_STREAM_MAIN] - dest;
+ if (num == 0)
+ {
+ p->state = BCJ2_STREAM_MAIN;
+ return;
+ }
+ }
+
+ srcLim = src + num;
+
+ if (p->prevByte == 0x0F && (src[0] & 0xF0) == 0x80)
+ *dest = src[0];
+ else for (;;)
+ {
+ Byte b = *src;
+ *dest = b;
+ if (b != 0x0F)
+ {
+ if ((b & 0xFE) == 0xE8)
+ break;
+ dest++;
+ if (++src != srcLim)
+ continue;
+ break;
+ }
+ dest++;
+ if (++src == srcLim)
+ break;
+ if ((*src & 0xF0) != 0x80)
+ continue;
+ *dest = *src;
+ break;
+ }
+
+ num = src - p->src;
+
+ if (src == srcLim)
+ {
+ p->prevByte = src[-1];
+ p->bufs[BCJ2_STREAM_MAIN] = dest;
+ p->src = src;
+ p->ip += (UInt32)num;
+ continue;
+ }
+
+ {
+ Byte context = (Byte)(num == 0 ? p->prevByte : src[-1]);
+ Bool needConvert;
+
+ p->bufs[BCJ2_STREAM_MAIN] = dest + 1;
+ p->ip += (UInt32)num + 1;
+ src++;
+
+ needConvert = False;
+
+ if ((SizeT)(p->srcLim - src) >= 4)
+ {
+ UInt32 relatVal = GetUi32(src);
+ if ((p->fileSize == 0 || (UInt32)(p->ip + 4 + relatVal - p->fileIp) < p->fileSize)
+ && ((relatVal + p->relatLimit) >> 1) < p->relatLimit)
+ needConvert = True;
+ }
+
+ {
+ UInt32 bound;
+ unsigned ttt;
+ Byte b = src[-1];
+ CProb *prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)context : (b == 0xE9 ? 1 : 0));
+
+ ttt = *prob;
+ bound = (p->range >> kNumModelBits) * ttt;
+
+ if (!needConvert)
+ {
+ p->range = bound;
+ *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+ p->src = src;
+ p->prevByte = b;
+ continue;
+ }
+
+ p->low += bound;
+ p->range -= bound;
+ *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
+
+ {
+ UInt32 relatVal = GetUi32(src);
+ UInt32 absVal;
+ p->ip += 4;
+ absVal = p->ip + relatVal;
+ p->prevByte = src[3];
+ src += 4;
+ p->src = src;
+ {
+ unsigned cj = (b == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
+ Byte *cur = p->bufs[cj];
+ if (cur == p->lims[cj])
+ {
+ p->state = cj;
+ p->tempTarget = absVal;
+ return;
+ }
+ SetBe32(cur, absVal);
+ p->bufs[cj] = cur + 4;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM)
+ return;
+
+ for (; p->flushPos < 5; p->flushPos++)
+ if (RangeEnc_ShiftLow(p))
+ return;
+ p->state = BCJ2_ENC_STATE_OK;
+}
+
+
+void Bcj2Enc_Encode(CBcj2Enc *p)
+{
+ PRF(printf("\n"));
+ PRF(printf("---- ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src));
+
+ if (p->tempPos != 0)
+ {
+ unsigned extra = 0;
+
+ for (;;)
+ {
+ const Byte *src = p->src;
+ const Byte *srcLim = p->srcLim;
+ unsigned finishMode = p->finishMode;
+
+ p->src = p->temp;
+ p->srcLim = p->temp + p->tempPos;
+ if (src != srcLim)
+ p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE;
+
+ PRF(printf(" ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src));
+
+ Bcj2Enc_Encode_2(p);
+
+ {
+ unsigned num = (unsigned)(p->src - p->temp);
+ unsigned tempPos = p->tempPos - num;
+ unsigned i;
+ p->tempPos = tempPos;
+ for (i = 0; i < tempPos; i++)
+ p->temp[i] = p->temp[i + num];
+
+ p->src = src;
+ p->srcLim = srcLim;
+ p->finishMode = finishMode;
+
+ if (p->state != BCJ2_ENC_STATE_ORIG || src == srcLim)
+ return;
+
+ if (extra >= tempPos)
+ {
+ p->src = src - tempPos;
+ p->tempPos = 0;
+ break;
+ }
+
+ p->temp[tempPos] = src[0];
+ p->tempPos = tempPos + 1;
+ p->src = src + 1;
+ extra++;
+ }
+ }
+ }
+
+ PRF(printf("++++ ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src));
+
+ Bcj2Enc_Encode_2(p);
+
+ if (p->state == BCJ2_ENC_STATE_ORIG)
+ {
+ const Byte *src = p->src;
+ unsigned rem = (unsigned)(p->srcLim - src);
+ unsigned i;
+ for (i = 0; i < rem; i++)
+ p->temp[i] = src[i];
+ p->tempPos = rem;
+ p->src = src + rem;
+ }
+}
diff --git a/3rdparty/lzma/C/Bra.c b/3rdparty/lzma/C/Bra.c
index 2e47b1413c1..cdb94569202 100644
--- a/3rdparty/lzma/C/Bra.c
+++ b/3rdparty/lzma/C/Bra.c
@@ -1,6 +1,8 @@
/* Bra.c -- Converters for RISC code
2010-04-16 : Igor Pavlov : Public domain */
+#include "Precomp.h"
+
#include "Bra.h"
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
diff --git a/3rdparty/lzma/C/Bra.h b/3rdparty/lzma/C/Bra.h
index 5748c1c051d..855e37a6b50 100644
--- a/3rdparty/lzma/C/Bra.h
+++ b/3rdparty/lzma/C/Bra.h
@@ -1,14 +1,12 @@
/* Bra.h -- Branch converters for executables
-2009-02-07 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __BRA_H
#define __BRA_H
-#include "Types.h"
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
/*
These functions convert relative addresses to absolute addresses
@@ -61,8 +59,6 @@ SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/Bra86.c b/3rdparty/lzma/C/Bra86.c
index 1ee0e709b88..6db15e7ecd3 100644
--- a/3rdparty/lzma/C/Bra86.c
+++ b/3rdparty/lzma/C/Bra86.c
@@ -1,85 +1,82 @@
/* Bra86.c -- Converter for x86 code (BCJ)
-2008-10-04 : Igor Pavlov : Public domain */
+2013-11-12 : Igor Pavlov : Public domain */
-#include "Bra.h"
+#include "Precomp.h"
-#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+#include "Bra.h"
-const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
-const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
{
- SizeT bufferPos = 0, prevPosT;
- UInt32 prevMask = *state & 0x7;
+ SizeT pos = 0;
+ UInt32 mask = *state & 7;
if (size < 5)
return 0;
+ size -= 4;
ip += 5;
- prevPosT = (SizeT)0 - 1;
for (;;)
{
- Byte *p = data + bufferPos;
- Byte *limit = data + size - 4;
+ Byte *p = data + pos;
+ const Byte *limit = data + size;
for (; p < limit; p++)
if ((*p & 0xFE) == 0xE8)
break;
- bufferPos = (SizeT)(p - data);
- if (p >= limit)
- break;
- prevPosT = bufferPos - prevPosT;
- if (prevPosT > 3)
- prevMask = 0;
- else
+
{
- prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
- if (prevMask != 0)
+ SizeT d = (SizeT)(p - data - pos);
+ pos = (SizeT)(p - data);
+ if (p >= limit)
{
- Byte b = p[4 - kMaskToBitNumber[prevMask]];
- if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
+ *state = (d > 2 ? 0 : mask >> (unsigned)d);
+ return pos;
+ }
+ if (d > 2)
+ mask = 0;
+ else
+ {
+ mask >>= (unsigned)d;
+ if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1])))
{
- prevPosT = bufferPos;
- prevMask = ((prevMask << 1) & 0x7) | 1;
- bufferPos++;
+ mask = (mask >> 1) | 4;
+ pos++;
continue;
}
}
}
- prevPosT = bufferPos;
if (Test86MSByte(p[4]))
{
- UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
- UInt32 dest;
- for (;;)
+ UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
+ UInt32 cur = ip + (UInt32)pos;
+ pos += 5;
+ if (encoding)
+ v += cur;
+ else
+ v -= cur;
+ if (mask != 0)
{
- Byte b;
- int index;
- if (encoding)
- dest = (ip + (UInt32)bufferPos) + src;
- else
- dest = src - (ip + (UInt32)bufferPos);
- if (prevMask == 0)
- break;
- index = kMaskToBitNumber[prevMask] * 8;
- b = (Byte)(dest >> (24 - index));
- if (!Test86MSByte(b))
- break;
- src = dest ^ ((1 << (32 - index)) - 1);
+ unsigned sh = (mask & 6) << 2;
+ if (Test86MSByte((Byte)(v >> sh)))
+ {
+ v ^= (((UInt32)0x100 << sh) - 1);
+ if (encoding)
+ v += cur;
+ else
+ v -= cur;
+ }
+ mask = 0;
}
- p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
- p[3] = (Byte)(dest >> 16);
- p[2] = (Byte)(dest >> 8);
- p[1] = (Byte)dest;
- bufferPos += 5;
+ p[1] = (Byte)v;
+ p[2] = (Byte)(v >> 8);
+ p[3] = (Byte)(v >> 16);
+ p[4] = (Byte)(0 - ((v >> 24) & 1));
}
else
{
- prevMask = ((prevMask << 1) & 0x7) | 1;
- bufferPos++;
+ mask = (mask >> 1) | 4;
+ pos++;
}
}
- prevPosT = bufferPos - prevPosT;
- *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
- return bufferPos;
}
diff --git a/3rdparty/lzma/C/BraIA64.c b/3rdparty/lzma/C/BraIA64.c
index 0b4ee85bc76..fa60356b288 100644
--- a/3rdparty/lzma/C/BraIA64.c
+++ b/3rdparty/lzma/C/BraIA64.c
@@ -1,5 +1,7 @@
/* BraIA64.c -- Converter for IA-64 code
-2008-10-04 : Igor Pavlov : Public domain */
+2013-11-12 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "Bra.h"
diff --git a/3rdparty/lzma/C/Compiler.h b/3rdparty/lzma/C/Compiler.h
new file mode 100644
index 00000000000..5bba7ee5618
--- /dev/null
+++ b/3rdparty/lzma/C/Compiler.h
@@ -0,0 +1,32 @@
+/* Compiler.h
+2015-08-02 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_COMPILER_H
+#define __7Z_COMPILER_H
+
+#ifdef _MSC_VER
+
+ #ifdef UNDER_CE
+ #define RPC_NO_WINDOWS_H
+ /* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */
+ #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
+ #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
+ #endif
+
+ #if _MSC_VER >= 1300
+ #pragma warning(disable : 4996) // This function or variable may be unsafe
+ #else
+ #pragma warning(disable : 4511) // copy constructor could not be generated
+ #pragma warning(disable : 4512) // assignment operator could not be generated
+ #pragma warning(disable : 4514) // unreferenced inline function has been removed
+ #pragma warning(disable : 4702) // unreachable code
+ #pragma warning(disable : 4710) // not inlined
+ #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
+ #endif
+
+#endif
+
+#define UNUSED_VAR(x) (void)x;
+/* #define UNUSED_VAR(x) x=x; */
+
+#endif
diff --git a/3rdparty/lzma/C/CpuArch.c b/3rdparty/lzma/C/CpuArch.c
index caf21643cef..36fc5bb4972 100644
--- a/3rdparty/lzma/C/CpuArch.c
+++ b/3rdparty/lzma/C/CpuArch.c
@@ -1,5 +1,7 @@
/* CpuArch.c -- CPU specific code
-2010-10-26: Igor Pavlov : Public domain */
+2015-03-25: Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "CpuArch.h"
@@ -9,6 +11,10 @@
#define USE_ASM
#endif
+#if !defined(USE_ASM) && _MSC_VER >= 1500
+#include <intrin.h>
+#endif
+
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
static UInt32 CheckFlag(UInt32 flag)
{
@@ -48,7 +54,7 @@ static UInt32 CheckFlag(UInt32 flag)
#define CHECK_CPUID_IS_SUPPORTED
#endif
-static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
+void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
{
#ifdef USE_ASM
@@ -72,28 +78,24 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#else
- #ifdef __PIC__
- __asm__ __volatile__ (
- "mov %%ebx, %%edi;"
- "cpuid;"
- "xchgl %%ebx, %%edi;"
- : "=a" (*a) ,
- "=D" (*b) , /* edi */
- "=c" (*c) ,
- "=d" (*d)
- : "0" (function)) ;
- #else // __PIC__
- __asm__ __volatile__ (
- "cpuid"
- : "=a" (*a) ,
- "=b" (*b) ,
- "=c" (*c) ,
- "=d" (*d)
- : "0" (function)) ;
- #endif // __PIC__
-
- #endif
+ __asm__ __volatile__ (
+ #if defined(MY_CPU_X86) && defined(__PIC__)
+ "mov %%ebx, %%edi;"
+ "cpuid;"
+ "xchgl %%ebx, %%edi;"
+ : "=a" (*a) ,
+ "=D" (*b) ,
+ #else
+ "cpuid"
+ : "=a" (*a) ,
+ "=b" (*b) ,
+ #endif
+ "=c" (*c) ,
+ "=d" (*d)
+ : "0" (function)) ;
+ #endif
+
#else
int CPUInfo[4];
@@ -114,7 +116,7 @@ Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
return True;
}
-static UInt32 kVendors[][3] =
+static const UInt32 kVendors[][3] =
{
{ 0x756E6547, 0x49656E69, 0x6C65746E},
{ 0x68747541, 0x69746E65, 0x444D4163},
@@ -135,27 +137,38 @@ int x86cpuid_GetFirm(const Cx86cpuid *p)
return -1;
}
-Bool CPU_Is_InOrder(void)
+Bool CPU_Is_InOrder()
{
Cx86cpuid p;
int firm;
UInt32 family, model;
if (!x86cpuid_CheckAndRead(&p))
return True;
- family = x86cpuid_GetFamily(&p);
- model = x86cpuid_GetModel(&p);
+
+ family = x86cpuid_GetFamily(p.ver);
+ model = x86cpuid_GetModel(p.ver);
+
firm = x86cpuid_GetFirm(&p);
+
switch (firm)
{
- case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
+ case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
+ /* In-Order Atom CPU */
+ model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
+ || model == 0x26 /* 45 nm, Z6xx */
+ || model == 0x27 /* 32 nm, Z2460 */
+ || model == 0x35 /* 32 nm, Z2760 */
+ || model == 0x36 /* 32 nm, N2xxx, D2xxx */
+ )));
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
}
return True;
}
-#if !defined(MY_CPU_AMD64) && defined(_WIN32_7Z)
-static Bool CPU_Sys_Is_SSE_Supported(void)
+#if !defined(MY_CPU_AMD64) && defined(_WIN32)
+#include <windows.h>
+static Bool CPU_Sys_Is_SSE_Supported()
{
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
@@ -168,7 +181,7 @@ static Bool CPU_Sys_Is_SSE_Supported(void)
#define CHECK_SYS_SSE_SUPPORT
#endif
-Bool CPU_Is_Aes_Supported(void)
+Bool CPU_Is_Aes_Supported()
{
Cx86cpuid p;
CHECK_SYS_SSE_SUPPORT
diff --git a/3rdparty/lzma/C/CpuArch.h b/3rdparty/lzma/C/CpuArch.h
index 50a7467f639..f6a28ba7e67 100644
--- a/3rdparty/lzma/C/CpuArch.h
+++ b/3rdparty/lzma/C/CpuArch.h
@@ -1,27 +1,34 @@
/* CpuArch.h -- CPU specific code
-2010-12-01: Igor Pavlov : Public domain */
+2015-12-01: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
-#include "Types.h"
+#include "7zTypes.h"
EXTERN_C_BEGIN
/*
MY_CPU_LE means that CPU is LITTLE ENDIAN.
-If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).
+MY_CPU_BE means that CPU is BIG ENDIAN.
+If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
-If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
*/
-#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
-#define MY_CPU_AMD64
+#if defined(_M_X64) \
+ || defined(_M_AMD64) \
+ || defined(__x86_64__) \
+ || defined(__AMD64__) \
+ || defined(__amd64__)
+ #define MY_CPU_AMD64
#endif
-#ifdef PTR64
-#define MY_CPU_64BIT
+#if defined(MY_CPU_AMD64) \
+ || defined(_M_IA64) \
+ || defined(__AARCH64EL__) \
+ || defined(__AARCH64EB__)
+ #define MY_CPU_64BIT
#endif
#if defined(_M_IX86) || defined(__i386__)
@@ -32,46 +39,80 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_X86_OR_AMD64
#endif
-#if defined(MY_CPU_X86) || defined(_M_ARM)
-#define MY_CPU_32BIT
+#if defined(MY_CPU_X86) \
+ || defined(_M_ARM) \
+ || defined(__ARMEL__) \
+ || defined(__THUMBEL__) \
+ || defined(__ARMEB__) \
+ || defined(__THUMBEB__)
+ #define MY_CPU_32BIT
#endif
-#if defined(_WIN32_7Z) && defined(_M_ARM)
+#if defined(_WIN32) && defined(_M_ARM)
#define MY_CPU_ARM_LE
#endif
-#if defined(_WIN32_7Z) && defined(_M_IA64)
+#if defined(_WIN32) && defined(_M_IA64)
#define MY_CPU_IA64_LE
#endif
-#if defined(MY_CPU_X86_OR_AMD64)
-#define MY_CPU_LE_UNALIGN
+#if defined(MY_CPU_X86_OR_AMD64) \
+ || defined(MY_CPU_ARM_LE) \
+ || defined(MY_CPU_IA64_LE) \
+ || defined(__LITTLE_ENDIAN__) \
+ || defined(__ARMEL__) \
+ || defined(__THUMBEL__) \
+ || defined(__AARCH64EL__) \
+ || defined(__MIPSEL__) \
+ || defined(__MIPSEL) \
+ || defined(_MIPSEL) \
+ || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
+ #define MY_CPU_LE
#endif
-#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
-#define MY_CPU_LE
-#endif
-
-#ifdef BIGENDIAN
-#define MY_CPU_BE
+#if defined(__BIG_ENDIAN__) \
+ || defined(__ARMEB__) \
+ || defined(__THUMBEB__) \
+ || defined(__AARCH64EB__) \
+ || defined(__MIPSEB__) \
+ || defined(__MIPSEB) \
+ || defined(_MIPSEB) \
+ || defined(__m68k__) \
+ || defined(__s390__) \
+ || defined(__s390x__) \
+ || defined(__zarch__) \
+ || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
+ #define MY_CPU_BE
#endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
Stop_Compiling_Bad_Endian
#endif
+
+#ifdef MY_CPU_LE
+ #if defined(MY_CPU_X86_OR_AMD64) \
+ /* || defined(__AARCH64EL__) */
+ #define MY_CPU_LE_UNALIGN
+ #endif
+#endif
+
+
#ifdef MY_CPU_LE_UNALIGN
-#define GetUi16(p) (*(const UInt16 *)(p))
-#define GetUi32(p) (*(const UInt32 *)(p))
-#define GetUi64(p) (*(const UInt64 *)(p))
-#define SetUi16(p, d) *(UInt16 *)(p) = (d);
-#define SetUi32(p, d) *(UInt32 *)(p) = (d);
-#define SetUi64(p, d) *(UInt64 *)(p) = (d);
+#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
+#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
+#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
+
+#define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
+#define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
+#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
#else
-#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
+#define GetUi16(p) ( (UInt16) ( \
+ ((const Byte *)(p))[0] | \
+ ((UInt16)((const Byte *)(p))[1] << 8) ))
#define GetUi32(p) ( \
((const Byte *)(p))[0] | \
@@ -81,23 +122,27 @@ Stop_Compiling_Bad_Endian
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
-#define SetUi16(p, d) { UInt32 _x_ = (d); \
- ((Byte *)(p))[0] = (Byte)_x_; \
- ((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
+#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+ _ppp_[0] = (Byte)_vvv_; \
+ _ppp_[1] = (Byte)(_vvv_ >> 8); }
-#define SetUi32(p, d) { UInt32 _x_ = (d); \
- ((Byte *)(p))[0] = (Byte)_x_; \
- ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
- ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
- ((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
+#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+ _ppp_[0] = (Byte)_vvv_; \
+ _ppp_[1] = (Byte)(_vvv_ >> 8); \
+ _ppp_[2] = (Byte)(_vvv_ >> 16); \
+ _ppp_[3] = (Byte)(_vvv_ >> 24); }
-#define SetUi64(p, d) { UInt64 _x64_ = (d); \
- SetUi32(p, (UInt32)_x64_); \
- SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
+#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
+ SetUi32(_ppp2_ , (UInt32)_vvv2_); \
+ SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
#endif
-#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (defined(_MSC_VER) && (_MSC_VER >= 1300))
+
+#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
+
+/* Note: we use bswap instruction, that is unsupported in 386 cpu */
+
#include <stdlib.h>
#pragma intrinsic(_byteswap_ulong)
@@ -105,6 +150,15 @@ Stop_Compiling_Bad_Endian
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
+#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
+
+#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+
+#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
+#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
+
+#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
+
#else
#define GetBe32(p) ( \
@@ -115,9 +169,19 @@ Stop_Compiling_Bad_Endian
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
+#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+ _ppp_[0] = (Byte)(_vvv_ >> 24); \
+ _ppp_[1] = (Byte)(_vvv_ >> 16); \
+ _ppp_[2] = (Byte)(_vvv_ >> 8); \
+ _ppp_[3] = (Byte)_vvv_; }
+
#endif
-#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
+
+#define GetBe16(p) ( (UInt16) ( \
+ ((UInt16)((const Byte *)(p))[0] << 8) | \
+ ((const Byte *)(p))[1] ))
+
#ifdef MY_CPU_X86_OR_AMD64
@@ -139,15 +203,17 @@ enum
CPU_FIRM_VIA
};
+void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
+
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
int x86cpuid_GetFirm(const Cx86cpuid *p);
-#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
-#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
-#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
+#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
+#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
+#define x86cpuid_GetStepping(ver) (ver & 0xF)
-Bool CPU_Is_InOrder(void);
-Bool CPU_Is_Aes_Supported(void);
+Bool CPU_Is_InOrder();
+Bool CPU_Is_Aes_Supported();
#endif
diff --git a/3rdparty/lzma/C/Delta.c b/3rdparty/lzma/C/Delta.c
index 2b327f15f37..e3edd21edbb 100644
--- a/3rdparty/lzma/C/Delta.c
+++ b/3rdparty/lzma/C/Delta.c
@@ -1,6 +1,8 @@
/* Delta.c -- Delta converter
2009-05-26 : Igor Pavlov : Public domain */
+#include "Precomp.h"
+
#include "Delta.h"
void Delta_Init(Byte *state)
diff --git a/3rdparty/lzma/C/Delta.h b/3rdparty/lzma/C/Delta.h
index 0d4cd62746c..2fa54ad67b3 100644
--- a/3rdparty/lzma/C/Delta.h
+++ b/3rdparty/lzma/C/Delta.h
@@ -1,14 +1,12 @@
/* Delta.h -- Delta converter
-2009-04-15 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __DELTA_H
#define __DELTA_H
-#include "Types.h"
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
#define DELTA_STATE_SIZE 256
@@ -16,8 +14,6 @@ void Delta_Init(Byte *state);
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size);
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/LzFind.c b/3rdparty/lzma/C/LzFind.c
index e3ecb05420e..2d05fa39534 100644
--- a/3rdparty/lzma/C/LzFind.c
+++ b/3rdparty/lzma/C/LzFind.c
@@ -1,5 +1,7 @@
/* LzFind.c -- Match finder for LZ algorithms
-2009-04-22 : Igor Pavlov : Public domain */
+2015-10-15 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <string.h>
@@ -9,8 +11,8 @@
#define kEmptyHashValue 0
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
-#define kNormalizeMask (~(kNormalizeStepMin - 1))
-#define kMaxHistorySize ((UInt32)3 << 30)
+#define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1))
+#define kMaxHistorySize ((UInt32)7 << 29)
#define kStartMaxLen 3
@@ -19,7 +21,7 @@ static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
if (!p->directInput)
{
alloc->Free(alloc, p->bufferBase);
- p->bufferBase = 0;
+ p->bufferBase = NULL;
}
}
@@ -33,17 +35,16 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a
p->blockSize = blockSize;
return 1;
}
- if (p->bufferBase == 0 || p->blockSize != blockSize)
+ if (!p->bufferBase || p->blockSize != blockSize)
{
LzInWindow_Free(p, alloc);
p->blockSize = blockSize;
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
}
- return (p->bufferBase != 0);
+ return (p->bufferBase != NULL);
}
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
-Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
@@ -58,9 +59,12 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
{
if (p->streamEndWasReached || p->result != SZ_OK)
return;
+
+ /* We use (p->streamPos - p->pos) value. (p->streamPos < p->pos) is allowed. */
+
if (p->directInput)
{
- UInt32 curSize = 0xFFFFFFFF - p->streamPos;
+ UInt32 curSize = 0xFFFFFFFF - (p->streamPos - p->pos);
if (curSize > p->directInputRem)
curSize = (UInt32)p->directInputRem;
p->directInputRem -= curSize;
@@ -69,12 +73,14 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
p->streamEndWasReached = 1;
return;
}
+
for (;;)
{
Byte *dest = p->buffer + (p->streamPos - p->pos);
size_t size = (p->bufferBase + p->blockSize - dest);
if (size == 0)
return;
+
p->result = p->stream->Read(p->stream, dest, &size);
if (p->result != SZ_OK)
return;
@@ -92,8 +98,8 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
void MatchFinder_MoveBlock(CMatchFinder *p)
{
memmove(p->bufferBase,
- p->buffer - p->keepSizeBefore,
- (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
+ p->buffer - p->keepSizeBefore,
+ (size_t)(p->streamPos - p->pos) + p->keepSizeBefore);
p->buffer = p->bufferBase + p->keepSizeBefore;
}
@@ -133,15 +139,15 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
void MatchFinder_Construct(CMatchFinder *p)
{
UInt32 i;
- p->bufferBase = 0;
+ p->bufferBase = NULL;
p->directInput = 0;
- p->hash = 0;
+ p->hash = NULL;
MatchFinder_SetDefaultSettings(p);
for (i = 0; i < 256; i++)
{
UInt32 r = i;
- int j;
+ unsigned j;
for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
p->crc[i] = r;
@@ -151,7 +157,7 @@ void MatchFinder_Construct(CMatchFinder *p)
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->hash);
- p->hash = 0;
+ p->hash = NULL;
}
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
@@ -160,11 +166,11 @@ void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
LzInWindow_Free(p, alloc);
}
-static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
+static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc)
{
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
if (sizeInBytes / sizeof(CLzRef) != num)
- return 0;
+ return NULL;
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
}
@@ -173,19 +179,24 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
ISzAlloc *alloc)
{
UInt32 sizeReserv;
+
if (historySize > kMaxHistorySize)
{
MatchFinder_Free(p, alloc);
return 0;
}
+
sizeReserv = historySize >> 1;
- if (historySize > ((UInt32)2 << 30))
- sizeReserv = historySize >> 2;
+ if (historySize >= ((UInt32)3 << 30)) sizeReserv = historySize >> 3;
+ else if (historySize >= ((UInt32)2 << 30)) sizeReserv = historySize >> 2;
+
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
+
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
+
if (LzInWindow_Create(p, sizeReserv, alloc))
{
UInt32 newCyclicBufferSize = historySize + 1;
@@ -210,6 +221,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
hs = (1 << 24) - 1;
else
hs >>= 1;
+ /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */
}
}
p->hashMask = hs;
@@ -221,24 +233,32 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
}
{
- UInt32 prevSize = p->hashSizeSum + p->numSons;
- UInt32 newSize;
+ size_t newSize;
+ size_t numSons;
p->historySize = historySize;
p->hashSizeSum = hs;
p->cyclicBufferSize = newCyclicBufferSize;
- p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
- newSize = p->hashSizeSum + p->numSons;
- if (p->hash != 0 && prevSize == newSize)
+
+ numSons = newCyclicBufferSize;
+ if (p->btMode)
+ numSons <<= 1;
+ newSize = hs + numSons;
+
+ if (p->hash && p->numRefs == newSize)
return 1;
+
MatchFinder_FreeThisClassMemory(p, alloc);
+ p->numRefs = newSize;
p->hash = AllocRefs(newSize, alloc);
- if (p->hash != 0)
+
+ if (p->hash)
{
p->son = p->hash + p->hashSizeSum;
return 1;
}
}
}
+
MatchFinder_Free(p, alloc);
return 0;
}
@@ -247,9 +267,11 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
{
UInt32 limit = kMaxValForNormalize - p->pos;
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
+
if (limit2 < limit)
limit = limit2;
limit2 = p->streamPos - p->pos;
+
if (limit2 <= p->keepSizeAfter)
{
if (limit2 > 0)
@@ -257,8 +279,10 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
}
else
limit2 -= p->keepSizeAfter;
+
if (limit2 < limit)
limit = limit2;
+
{
UInt32 lenLimit = p->streamPos - p->pos;
if (lenLimit > p->matchMaxLen)
@@ -268,28 +292,39 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
p->posLimit = p->pos + limit;
}
-void MatchFinder_Init(CMatchFinder *p)
+void MatchFinder_Init_2(CMatchFinder *p, int readData)
{
UInt32 i;
- for (i = 0; i < p->hashSizeSum; i++)
- p->hash[i] = kEmptyHashValue;
+ UInt32 *hash = p->hash;
+ UInt32 num = p->hashSizeSum;
+ for (i = 0; i < num; i++)
+ hash[i] = kEmptyHashValue;
+
p->cyclicBufferPos = 0;
p->buffer = p->bufferBase;
p->pos = p->streamPos = p->cyclicBufferSize;
p->result = SZ_OK;
p->streamEndWasReached = 0;
- MatchFinder_ReadBlock(p);
+
+ if (readData)
+ MatchFinder_ReadBlock(p);
+
MatchFinder_SetLimits(p);
}
+void MatchFinder_Init(CMatchFinder *p)
+{
+ MatchFinder_Init_2(p, True);
+}
+
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
{
return (p->pos - p->historySize - 1) & kNormalizeMask;
}
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems)
{
- UInt32 i;
+ size_t i;
for (i = 0; i < numItems; i++)
{
UInt32 value = items[i];
@@ -304,7 +339,7 @@ void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
static void MatchFinder_Normalize(CMatchFinder *p)
{
UInt32 subValue = MatchFinder_GetSubValue(p);
- MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
+ MatchFinder_Normalize3(subValue, p->hash, p->numRefs);
MatchFinder_ReduceOffsets(p, subValue);
}
@@ -465,7 +500,7 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
#define GET_MATCHES_HEADER2(minLen, ret_op) \
- UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
+ UInt32 lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
cur = p->buffer;
@@ -481,13 +516,20 @@ static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
#define SKIP_FOOTER \
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
+#define UPDATE_maxLen { \
+ ptrdiff_t diff = (ptrdiff_t)0 - d2; \
+ const Byte *c = cur + maxLen; \
+ const Byte *lim = cur + lenLimit; \
+ for (; c != lim; c++) if (*(c + diff) != *c) break; \
+ maxLen = (UInt32)(c - cur); }
+
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 offset;
GET_MATCHES_HEADER(2)
HASH2_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
offset = 0;
GET_MATCHES_FOOTER(offset, 1)
}
@@ -497,35 +539,38 @@ UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
UInt32 offset;
GET_MATCHES_HEADER(3)
HASH_ZIP_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
offset = 0;
GET_MATCHES_FOOTER(offset, 2)
}
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
- UInt32 hash2Value, delta2, maxLen, offset;
+ UInt32 h2, d2, maxLen, offset, pos;
+ UInt32 *hash;
GET_MATCHES_HEADER(3)
HASH3_CALC;
- delta2 = p->pos - p->hash[hash2Value];
- curMatch = p->hash[kFix3HashSize + hashValue];
-
- p->hash[hash2Value] =
- p->hash[kFix3HashSize + hashValue] = p->pos;
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash[h2];
+ curMatch = hash[kFix3HashSize + hv];
+
+ hash[h2] = pos;
+ hash[kFix3HashSize + hv] = pos;
maxLen = 2;
offset = 0;
- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
- for (; maxLen != lenLimit; maxLen++)
- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
- break;
+ UPDATE_maxLen
distances[0] = maxLen;
- distances[1] = delta2 - 1;
+ distances[1] = d2 - 1;
offset = 2;
if (maxLen == lenLimit)
{
@@ -533,44 +578,51 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
MOVE_POS_RET;
}
}
+
GET_MATCHES_FOOTER(offset, maxLen)
}
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
- UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+ UInt32 h2, h3, d2, d3, maxLen, offset, pos;
+ UInt32 *hash;
GET_MATCHES_HEADER(4)
HASH4_CALC;
- delta2 = p->pos - p->hash[ hash2Value];
- delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
- curMatch = p->hash[kFix4HashSize + hashValue];
-
- p->hash[ hash2Value] =
- p->hash[kFix3HashSize + hash3Value] =
- p->hash[kFix4HashSize + hashValue] = p->pos;
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash[ h2];
+ d3 = pos - hash[kFix3HashSize + h3];
+
+ curMatch = hash[kFix4HashSize + hv];
+
+ hash[ h2] = pos;
+ hash[kFix3HashSize + h3] = pos;
+ hash[kFix4HashSize + hv] = pos;
- maxLen = 1;
+ maxLen = 0;
offset = 0;
- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
distances[0] = maxLen = 2;
- distances[1] = delta2 - 1;
+ distances[1] = d2 - 1;
offset = 2;
}
- if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+
+ if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
maxLen = 3;
- distances[offset + 1] = delta3 - 1;
+ distances[offset + 1] = d3 - 1;
offset += 2;
- delta2 = delta3;
+ d2 = d3;
}
+
if (offset != 0)
{
- for (; maxLen != lenLimit; maxLen++)
- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
- break;
+ UPDATE_maxLen
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
@@ -578,46 +630,131 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
MOVE_POS_RET;
}
}
+
if (maxLen < 3)
maxLen = 3;
+
GET_MATCHES_FOOTER(offset, maxLen)
}
+/*
+static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos;
+ UInt32 *hash;
+ GET_MATCHES_HEADER(5)
+
+ HASH5_CALC;
+
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash[ h2];
+ d3 = pos - hash[kFix3HashSize + h3];
+ d4 = pos - hash[kFix4HashSize + h4];
+
+ curMatch = hash[kFix5HashSize + hv];
+
+ hash[ h2] = pos;
+ hash[kFix3HashSize + h3] = pos;
+ hash[kFix4HashSize + h4] = pos;
+ hash[kFix5HashSize + hv] = pos;
+
+ maxLen = 0;
+ offset = 0;
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
+ {
+ distances[0] = maxLen = 2;
+ distances[1] = d2 - 1;
+ offset = 2;
+ if (*(cur - d2 + 2) == cur[2])
+ distances[0] = maxLen = 3;
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ distances[2] = maxLen = 3;
+ distances[3] = d3 - 1;
+ offset = 4;
+ d2 = d3;
+ }
+ }
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ distances[0] = maxLen = 3;
+ distances[1] = d3 - 1;
+ offset = 2;
+ d2 = d3;
+ }
+
+ if (d2 != d4 && d4 < p->cyclicBufferSize
+ && *(cur - d4) == *cur
+ && *(cur - d4 + 3) == *(cur + 3))
+ {
+ maxLen = 4;
+ distances[offset + 1] = d4 - 1;
+ offset += 2;
+ d2 = d4;
+ }
+
+ if (offset != 0)
+ {
+ UPDATE_maxLen
+ distances[offset - 2] = maxLen;
+ if (maxLen == lenLimit)
+ {
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+ MOVE_POS_RET;
+ }
+ }
+
+ if (maxLen < 4)
+ maxLen = 4;
+
+ GET_MATCHES_FOOTER(offset, maxLen)
+}
+*/
+
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
- UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+ UInt32 h2, h3, d2, d3, maxLen, offset, pos;
+ UInt32 *hash;
GET_MATCHES_HEADER(4)
HASH4_CALC;
- delta2 = p->pos - p->hash[ hash2Value];
- delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
- curMatch = p->hash[kFix4HashSize + hashValue];
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash[ h2];
+ d3 = pos - hash[kFix3HashSize + h3];
+
+ curMatch = hash[kFix4HashSize + hv];
- p->hash[ hash2Value] =
- p->hash[kFix3HashSize + hash3Value] =
- p->hash[kFix4HashSize + hashValue] = p->pos;
+ hash[ h2] = pos;
+ hash[kFix3HashSize + h3] = pos;
+ hash[kFix4HashSize + hv] = pos;
- maxLen = 1;
+ maxLen = 0;
offset = 0;
- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
distances[0] = maxLen = 2;
- distances[1] = delta2 - 1;
+ distances[1] = d2 - 1;
offset = 2;
}
- if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+
+ if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
maxLen = 3;
- distances[offset + 1] = delta3 - 1;
+ distances[offset + 1] = d3 - 1;
offset += 2;
- delta2 = delta3;
+ d2 = d3;
}
+
if (offset != 0)
{
- for (; maxLen != lenLimit; maxLen++)
- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
- break;
+ UPDATE_maxLen
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
@@ -625,22 +762,103 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
MOVE_POS_RET;
}
}
+
if (maxLen < 3)
maxLen = 3;
+
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
- distances + offset, maxLen) - (distances));
+ distances + offset, maxLen) - (distances));
MOVE_POS_RET
}
+/*
+static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos
+ UInt32 *hash;
+ GET_MATCHES_HEADER(5)
+
+ HASH5_CALC;
+
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash[ h2];
+ d3 = pos - hash[kFix3HashSize + h3];
+ d4 = pos - hash[kFix4HashSize + h4];
+
+ curMatch = hash[kFix5HashSize + hv];
+
+ hash[ h2] = pos;
+ hash[kFix3HashSize + h3] = pos;
+ hash[kFix4HashSize + h4] = pos;
+ hash[kFix5HashSize + hv] = pos;
+
+ maxLen = 0;
+ offset = 0;
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
+ {
+ distances[0] = maxLen = 2;
+ distances[1] = d2 - 1;
+ offset = 2;
+ if (*(cur - d2 + 2) == cur[2])
+ distances[0] = maxLen = 3;
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ distances[2] = maxLen = 3;
+ distances[3] = d3 - 1;
+ offset = 4;
+ d2 = d3;
+ }
+ }
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ distances[0] = maxLen = 3;
+ distances[1] = d3 - 1;
+ offset = 2;
+ d2 = d3;
+ }
+
+ if (d2 != d4 && d4 < p->cyclicBufferSize
+ && *(cur - d4) == *cur
+ && *(cur - d4 + 3) == *(cur + 3))
+ {
+ maxLen = 4;
+ distances[offset + 1] = d4 - 1;
+ offset += 2;
+ d2 = d4;
+ }
+
+ if (offset != 0)
+ {
+ UPDATE_maxLen
+ distances[offset - 2] = maxLen;
+ if (maxLen == lenLimit)
+ {
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS_RET;
+ }
+ }
+
+ if (maxLen < 4)
+ maxLen = 4;
+
+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+ distances + offset, maxLen) - (distances));
+ MOVE_POS_RET
+}
+*/
+
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 offset;
GET_MATCHES_HEADER(3)
HASH_ZIP_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
- distances, 2) - (distances));
+ distances, 2) - (distances));
MOVE_POS_RET
}
@@ -650,8 +868,8 @@ static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
SKIP_HEADER(2)
HASH2_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
@@ -663,8 +881,8 @@ void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
SKIP_HEADER(3)
HASH_ZIP_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
@@ -674,12 +892,14 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
- UInt32 hash2Value;
+ UInt32 h2;
+ UInt32 *hash;
SKIP_HEADER(3)
HASH3_CALC;
- curMatch = p->hash[kFix3HashSize + hashValue];
- p->hash[hash2Value] =
- p->hash[kFix3HashSize + hashValue] = p->pos;
+ hash = p->hash;
+ curMatch = hash[kFix3HashSize + hv];
+ hash[h2] =
+ hash[kFix3HashSize + hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
@@ -689,43 +909,90 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
- UInt32 hash2Value, hash3Value;
+ UInt32 h2, h3;
+ UInt32 *hash;
SKIP_HEADER(4)
HASH4_CALC;
- curMatch = p->hash[kFix4HashSize + hashValue];
- p->hash[ hash2Value] =
- p->hash[kFix3HashSize + hash3Value] = p->pos;
- p->hash[kFix4HashSize + hashValue] = p->pos;
+ hash = p->hash;
+ curMatch = hash[kFix4HashSize + hv];
+ hash[ h2] =
+ hash[kFix3HashSize + h3] =
+ hash[kFix4HashSize + hv] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+/*
+static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 h2, h3, h4;
+ UInt32 *hash;
+ SKIP_HEADER(5)
+ HASH5_CALC;
+ hash = p->hash;
+ curMatch = hash[kFix5HashSize + hv];
+ hash[ h2] =
+ hash[kFix3HashSize + h3] =
+ hash[kFix4HashSize + h4] =
+ hash[kFix5HashSize + hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
+*/
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
- UInt32 hash2Value, hash3Value;
+ UInt32 h2, h3;
+ UInt32 *hash;
SKIP_HEADER(4)
HASH4_CALC;
- curMatch = p->hash[kFix4HashSize + hashValue];
- p->hash[ hash2Value] =
- p->hash[kFix3HashSize + hash3Value] =
- p->hash[kFix4HashSize + hashValue] = p->pos;
+ hash = p->hash;
+ curMatch = hash[kFix4HashSize + hv];
+ hash[ h2] =
+ hash[kFix3HashSize + h3] =
+ hash[kFix4HashSize + hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
while (--num != 0);
}
+/*
+static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 h2, h3, h4;
+ UInt32 *hash;
+ SKIP_HEADER(5)
+ HASH5_CALC;
+ hash = p->hash;
+ curMatch = p->hash[kFix5HashSize + hv];
+ hash[ h2] =
+ hash[kFix3HashSize + h3] =
+ hash[kFix4HashSize + h4] =
+ hash[kFix5HashSize + hv] = p->pos;
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS
+ }
+ while (--num != 0);
+}
+*/
+
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
SKIP_HEADER(3)
HASH_ZIP_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
@@ -735,13 +1002,22 @@ void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
{
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
- vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
if (!p->btMode)
{
- vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
- vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
+ /* if (p->numHashBytes <= 4) */
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
+ }
+ /*
+ else
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Hc5_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Hc5_MatchFinder_Skip;
+ }
+ */
}
else if (p->numHashBytes == 2)
{
@@ -753,9 +1029,16 @@ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
}
- else
+ else /* if (p->numHashBytes == 4) */
{
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
}
+ /*
+ else
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt5_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt5_MatchFinder_Skip;
+ }
+ */
}
diff --git a/3rdparty/lzma/C/LzFind.h b/3rdparty/lzma/C/LzFind.h
index 010c4b92ba3..d119944f445 100644
--- a/3rdparty/lzma/C/LzFind.h
+++ b/3rdparty/lzma/C/LzFind.h
@@ -1,14 +1,12 @@
/* LzFind.h -- Match finder for LZ algorithms
-2009-04-22 : Igor Pavlov : Public domain */
+2015-10-15 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H
#define __LZ_FIND_H
-#include "Types.h"
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
typedef UInt32 CLzRef;
@@ -23,6 +21,11 @@ typedef struct _CMatchFinder
UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
+ Byte streamEndWasReached;
+ Byte btMode;
+ Byte bigHash;
+ Byte directInput;
+
UInt32 matchMaxLen;
CLzRef *hash;
CLzRef *son;
@@ -31,30 +34,30 @@ typedef struct _CMatchFinder
Byte *bufferBase;
ISeqInStream *stream;
- int streamEndWasReached;
-
+
UInt32 blockSize;
UInt32 keepSizeBefore;
UInt32 keepSizeAfter;
UInt32 numHashBytes;
- int directInput;
size_t directInputRem;
- int btMode;
- int bigHash;
UInt32 historySize;
UInt32 fixedHashSize;
UInt32 hashSizeSum;
- UInt32 numSons;
SRes result;
UInt32 crc[256];
+ size_t numRefs;
} CMatchFinder;
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
-#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
+#define Inline_MatchFinder_IsFinishedOK(p) \
+ ((p)->streamEndWasReached \
+ && (p)->streamPos == (p)->pos \
+ && (!(p)->directInput || (p)->directInputRem == 0))
+
int MatchFinder_NeedMove(CMatchFinder *p);
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
void MatchFinder_MoveBlock(CMatchFinder *p);
@@ -70,7 +73,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
@@ -84,7 +87,6 @@ Conditions:
*/
typedef void (*Mf_Init_Func)(void *object);
-typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
@@ -93,7 +95,6 @@ typedef void (*Mf_Skip_Func)(void *object, UInt32);
typedef struct _IMatchFinder
{
Mf_Init_Func Init;
- Mf_GetIndexByte_Func GetIndexByte;
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
Mf_GetMatches_Func GetMatches;
@@ -102,14 +103,15 @@ typedef struct _IMatchFinder
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
+void MatchFinder_Init_2(CMatchFinder *p, int readData);
void MatchFinder_Init(CMatchFinder *p);
+
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/LzFindMt.c b/3rdparty/lzma/C/LzFindMt.c
index aa41ed98a57..a4ffa5ef9c8 100644
--- a/3rdparty/lzma/C/LzFindMt.c
+++ b/3rdparty/lzma/C/LzFindMt.c
@@ -1,11 +1,13 @@
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
-2009-09-20 : Igor Pavlov : Public domain */
+2015-10-15 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "LzHash.h"
#include "LzFindMt.h"
-void MtSync_Construct(CMtSync *p)
+static void MtSync_Construct(CMtSync *p)
{
p->wasCreated = False;
p->csWasInitialized = False;
@@ -18,7 +20,7 @@ void MtSync_Construct(CMtSync *p)
Semaphore_Construct(&p->filledSemaphore);
}
-void MtSync_GetNextBlock(CMtSync *p)
+static void MtSync_GetNextBlock(CMtSync *p)
{
if (p->needStart)
{
@@ -46,7 +48,7 @@ void MtSync_GetNextBlock(CMtSync *p)
/* MtSync_StopWriting must be called if Writing was started */
-void MtSync_StopWriting(CMtSync *p)
+static void MtSync_StopWriting(CMtSync *p)
{
UInt32 myNumBlocks = p->numProcessedBlocks;
if (!Thread_WasCreated(&p->thread) || p->needStart)
@@ -69,7 +71,7 @@ void MtSync_StopWriting(CMtSync *p)
p->needStart = True;
}
-void MtSync_Destruct(CMtSync *p)
+static void MtSync_Destruct(CMtSync *p)
{
if (Thread_WasCreated(&p->thread))
{
@@ -97,7 +99,7 @@ void MtSync_Destruct(CMtSync *p)
#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
-static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
+static SRes MtSync_Create2(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks)
{
if (p->wasCreated)
return SZ_OK;
@@ -119,7 +121,7 @@ static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void
return SZ_OK;
}
-static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
+static SRes MtSync_Create(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks)
{
SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
if (res != SZ_OK)
@@ -132,20 +134,20 @@ void MtSync_Init(CMtSync *p) { p->needStart = True; }
#define kMtMaxValForNormalize 0xFFFFFFFF
#define DEF_GetHeads2(name, v, action) \
-static void GetHeads ## name(const Byte *p, UInt32 pos, \
-UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
-{ action; for (; numHeads != 0; numHeads--) { \
-const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
+ static void GetHeads ## name(const Byte *p, UInt32 pos, \
+ UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
+ { action; for (; numHeads != 0; numHeads--) { \
+ const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)
-DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; )
+DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), UNUSED_VAR(hashMask); UNUSED_VAR(crc); )
DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
/* DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */
-void HashThreadFunc(CMatchFinderMt *mt)
+static void HashThreadFunc(CMatchFinderMt *mt)
{
CMtSync *p = &mt->hashSync;
for (;;)
@@ -171,12 +173,12 @@ void HashThreadFunc(CMatchFinderMt *mt)
CriticalSection_Enter(&mt->btSync.cs);
CriticalSection_Enter(&mt->hashSync.cs);
{
- const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);
- const Byte *afterPtr;
+ const Byte *beforePtr = Inline_MatchFinder_GetPointerToCurrentPos(mf);
+ ptrdiff_t offset;
MatchFinder_MoveBlock(mf);
- afterPtr = MatchFinder_GetPointerToCurrentPos(mf);
- mt->pointerToCurPos -= beforePtr - afterPtr;
- mt->buffer -= beforePtr - afterPtr;
+ offset = beforePtr - Inline_MatchFinder_GetPointerToCurrentPos(mf);
+ mt->pointerToCurPos -= offset;
+ mt->buffer -= offset;
}
CriticalSection_Leave(&mt->btSync.cs);
CriticalSection_Leave(&mt->hashSync.cs);
@@ -190,7 +192,7 @@ void HashThreadFunc(CMatchFinderMt *mt)
{
UInt32 subValue = (mf->pos - mf->historySize - 1);
MatchFinder_ReduceOffsets(mf, subValue);
- MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1);
+ MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, (size_t)mf->hashMask + 1);
}
{
UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize;
@@ -215,7 +217,7 @@ void HashThreadFunc(CMatchFinderMt *mt)
}
}
-void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
+static void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
{
MtSync_GetNextBlock(&p->hashSync);
p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
@@ -231,7 +233,7 @@ void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
#define NO_INLINE MY_FAST_CALL
-Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
+static Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
{
@@ -308,12 +310,14 @@ Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CL
#endif
-void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
+static void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
{
UInt32 numProcessed = 0;
UInt32 curPos = 2;
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
+
distances[1] = p->hashNumAvail;
+
while (curPos < limit)
{
if (p->hashBufPos == p->hashBufPosLimit)
@@ -322,9 +326,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
distances[1] = numProcessed + p->hashNumAvail;
if (p->hashNumAvail >= p->numHashBytes)
continue;
+ distances[0] = curPos + p->hashNumAvail;
+ distances += curPos;
for (; p->hashNumAvail != 0; p->hashNumAvail--)
- distances[curPos++] = 0;
- break;
+ *distances++ = 0;
+ return;
}
{
UInt32 size = p->hashBufPosLimit - p->hashBufPos;
@@ -341,13 +347,14 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
if (size2 < size)
size = size2;
}
+
#ifndef MFMT_GM_INLINE
while (curPos < limit && size-- != 0)
{
UInt32 *startDistances = distances + curPos;
UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
- pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
- startDistances + 1, p->numHashBytes - 1) - startDistances);
+ pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
+ startDistances + 1, p->numHashBytes - 1) - startDistances);
*startDistances = num - 1;
curPos += num;
cyclicBufferPos++;
@@ -358,7 +365,7 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
{
UInt32 posRes;
curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
- distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes);
+ distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos), size, &posRes);
p->hashBufPos += posRes - pos;
cyclicBufferPos += posRes - pos;
p->buffer += posRes - pos;
@@ -374,10 +381,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
p->cyclicBufferPos = cyclicBufferPos;
}
}
+
distances[0] = curPos;
}
-void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
+static void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
{
CMtSync *sync = &p->hashSync;
if (!sync->needStart)
@@ -391,7 +399,7 @@ void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
{
UInt32 subValue = p->pos - p->cyclicBufferSize;
- MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2);
+ MatchFinder_Normalize3(subValue, p->son, (size_t)p->cyclicBufferSize * 2);
p->pos -= subValue;
}
@@ -430,15 +438,15 @@ void BtThreadFunc(CMatchFinderMt *mt)
void MatchFinderMt_Construct(CMatchFinderMt *p)
{
- p->hashBuf = 0;
+ p->hashBuf = NULL;
MtSync_Construct(&p->hashSync);
MtSync_Construct(&p->btSync);
}
-void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
+static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->hashBuf);
- p->hashBuf = 0;
+ p->hashBuf = NULL;
}
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
@@ -451,14 +459,15 @@ void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
-static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
-static unsigned MY_STD_CALL BtThreadFunc2(void *p)
+static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
+static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
{
Byte allocaDummy[0x180];
- int i = 0;
+ unsigned i = 0;
for (i = 0; i < 16; i++)
- allocaDummy[i] = (Byte)i;
- BtThreadFunc((CMatchFinderMt *)p);
+ allocaDummy[i] = (Byte)0;
+ if (allocaDummy[0] == 0)
+ BtThreadFunc((CMatchFinderMt *)p);
return 0;
}
@@ -469,10 +478,10 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
p->historySize = historySize;
if (kMtBtBlockSize <= matchMaxLen * 4)
return SZ_ERROR_PARAM;
- if (p->hashBuf == 0)
+ if (!p->hashBuf)
{
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
- if (p->hashBuf == 0)
+ if (!p->hashBuf)
return SZ_ERROR_MEM;
p->btBuf = p->hashBuf + kHashBufferSize;
}
@@ -492,8 +501,11 @@ void MatchFinderMt_Init(CMatchFinderMt *p)
CMatchFinder *mf = p->MatchFinder;
p->btBufPos = p->btBufPosLimit = 0;
p->hashBufPos = p->hashBufPosLimit = 0;
- MatchFinder_Init(mf);
- p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf);
+
+ /* Init without data reading. We don't want to read data in this thread */
+ MatchFinder_Init_2(mf, False);
+
+ p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
p->btNumAvailBytes = 0;
p->lzPos = p->historySize + 1;
@@ -518,13 +530,13 @@ void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
/* p->MatchFinder->ReleaseStream(); */
}
-void MatchFinderMt_Normalize(CMatchFinderMt *p)
+static void MatchFinderMt_Normalize(CMatchFinderMt *p)
{
MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
p->lzPos = p->historySize + 1;
}
-void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
+static void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
{
UInt32 blockIndex;
MtSync_GetNextBlock(&p->btSync);
@@ -536,34 +548,29 @@ void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
MatchFinderMt_Normalize(p);
}
-const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
+static const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
{
return p->pointerToCurPos;
}
#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
-UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
+static UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
{
GET_NEXT_BLOCK_IF_REQUIRED;
return p->btNumAvailBytes;
}
-Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
+static UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
{
- return p->pointerToCurPos[index];
-}
-
-UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
-{
- UInt32 hash2Value, curMatch2;
+ UInt32 h2, curMatch2;
UInt32 *hash = p->hash;
const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos;
MT_HASH2_CALC
- curMatch2 = hash[hash2Value];
- hash[hash2Value] = lzPos;
+ curMatch2 = hash[h2];
+ hash[h2] = lzPos;
if (curMatch2 >= matchMinPos)
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
@@ -571,23 +578,23 @@ UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
*distances++ = 2;
*distances++ = lzPos - curMatch2 - 1;
}
+
return distances;
}
-UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
{
- UInt32 hash2Value, hash3Value, curMatch2, curMatch3;
+ UInt32 h2, h3, curMatch2, curMatch3;
UInt32 *hash = p->hash;
const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos;
MT_HASH3_CALC
- curMatch2 = hash[ hash2Value];
- curMatch3 = hash[kFix3HashSize + hash3Value];
+ curMatch2 = hash[ h2];
+ curMatch3 = hash[kFix3HashSize + h3];
- hash[ hash2Value] =
- hash[kFix3HashSize + hash3Value] =
- lzPos;
+ hash[ h2] = lzPos;
+ hash[kFix3HashSize + h3] = lzPos;
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
{
@@ -600,43 +607,45 @@ UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
distances[0] = 2;
distances += 2;
}
+
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
{
*distances++ = 3;
*distances++ = lzPos - curMatch3 - 1;
}
+
return distances;
}
/*
-UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
{
- UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4;
+ UInt32 h2, h3, h4, curMatch2, curMatch3, curMatch4;
UInt32 *hash = p->hash;
const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos;
MT_HASH4_CALC
- curMatch2 = hash[ hash2Value];
- curMatch3 = hash[kFix3HashSize + hash3Value];
- curMatch4 = hash[kFix4HashSize + hash4Value];
+ curMatch2 = hash[ h2];
+ curMatch3 = hash[kFix3HashSize + h3];
+ curMatch4 = hash[kFix4HashSize + h4];
- hash[ hash2Value] =
- hash[kFix3HashSize + hash3Value] =
- hash[kFix4HashSize + hash4Value] =
- lzPos;
+ hash[ h2] = lzPos;
+ hash[kFix3HashSize + h3] = lzPos;
+ hash[kFix4HashSize + h4] = lzPos;
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
{
distances[1] = lzPos - curMatch2 - 1;
if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
{
- distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
+ distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
return distances + 2;
}
distances[0] = 2;
distances += 2;
}
+
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
{
distances[1] = lzPos - curMatch3 - 1;
@@ -658,13 +667,14 @@ UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
*distances++ = 4;
*distances++ = lzPos - curMatch4 - 1;
}
+
return distances;
}
*/
#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
-UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
+static UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
{
const UInt32 *btBuf = p->btBuf + p->btBufPos;
UInt32 len = *btBuf++;
@@ -682,7 +692,7 @@ UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
return len;
}
-UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
+static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
{
const UInt32 *btBuf = p->btBuf + p->btBufPos;
UInt32 len = *btBuf++;
@@ -690,6 +700,7 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
if (len == 0)
{
+ /* change for bt5 ! */
if (p->btNumAvailBytes-- >= 4)
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
}
@@ -705,7 +716,7 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
*distances2++ = *btBuf++;
}
while ((len -= 2) != 0);
- len = (UInt32)(distances2 - (distances));
+ len = (UInt32)(distances2 - (distances));
}
INCREASE_LZ_POS
return len;
@@ -715,41 +726,41 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);
-void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
+static void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
{
SKIP_HEADER2_MT { p->btNumAvailBytes--;
SKIP_FOOTER_MT
}
-void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
+static void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
{
SKIP_HEADER_MT(2)
- UInt32 hash2Value;
+ UInt32 h2;
MT_HASH2_CALC
- hash[hash2Value] = p->lzPos;
+ hash[h2] = p->lzPos;
SKIP_FOOTER_MT
}
-void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
+static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
{
SKIP_HEADER_MT(3)
- UInt32 hash2Value, hash3Value;
+ UInt32 h2, h3;
MT_HASH3_CALC
- hash[kFix3HashSize + hash3Value] =
- hash[ hash2Value] =
+ hash[kFix3HashSize + h3] =
+ hash[ h2] =
p->lzPos;
SKIP_FOOTER_MT
}
/*
-void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
+static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
{
SKIP_HEADER_MT(4)
- UInt32 hash2Value, hash3Value, hash4Value;
+ UInt32 h2, h3, h4;
MT_HASH4_CALC
- hash[kFix4HashSize + hash4Value] =
- hash[kFix3HashSize + hash3Value] =
- hash[ hash2Value] =
+ hash[kFix4HashSize + h4] =
+ hash[kFix3HashSize + h3] =
+ hash[ h2] =
p->lzPos;
SKIP_FOOTER_MT
}
@@ -758,11 +769,11 @@ void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
{
vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
- vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
- switch(p->MatchFinder->numHashBytes)
+
+ switch (p->MatchFinder->numHashBytes)
{
case 2:
p->GetHeadsFunc = GetHeads2;
@@ -778,7 +789,6 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
default:
/* case 4: */
p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
- /* p->GetHeadsFunc = GetHeads4; */
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
break;
diff --git a/3rdparty/lzma/C/LzFindMt.h b/3rdparty/lzma/C/LzFindMt.h
index b985af5fee2..89b91fefd6e 100644
--- a/3rdparty/lzma/C/LzFindMt.h
+++ b/3rdparty/lzma/C/LzFindMt.h
@@ -1,5 +1,5 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
-2009-02-07 : Igor Pavlov : Public domain */
+2015-05-03 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_MT_H
#define __LZ_FIND_MT_H
@@ -7,9 +7,7 @@
#include "LzFind.h"
#include "Threads.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
#define kMtHashBlockSize (1 << 13)
#define kMtHashNumBlocks (1 << 3)
@@ -77,7 +75,7 @@ typedef struct _CMatchFinderMt
UInt32 matchMaxLen;
UInt32 numHashBytes;
UInt32 pos;
- Byte *buffer;
+ const Byte *buffer;
UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be historySize + 1 */
UInt32 cutValue;
@@ -98,8 +96,6 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/LzHash.h b/3rdparty/lzma/C/LzHash.h
index f3e89966cc7..e7c942303dd 100644
--- a/3rdparty/lzma/C/LzHash.h
+++ b/3rdparty/lzma/C/LzHash.h
@@ -1,5 +1,5 @@
/* LzHash.h -- HASH functions for LZ algorithms
-2009-02-07 : Igor Pavlov : Public domain */
+2015-04-12 : Igor Pavlov : Public domain */
#ifndef __LZ_HASH_H
#define __LZ_HASH_H
@@ -12,43 +12,46 @@
#define kFix4HashSize (kHash2Size + kHash3Size)
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
-#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
+#define HASH2_CALC hv = cur[0] | ((UInt32)cur[1] << 8);
#define HASH3_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
+ h2 = temp & (kHash2Size - 1); \
+ hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
#define HASH4_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
- hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
+ h2 = temp & (kHash2Size - 1); \
+ temp ^= ((UInt32)cur[2] << 8); \
+ h3 = temp & (kHash3Size - 1); \
+ hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
#define HASH5_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
- hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
- hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
- hash4Value &= (kHash4Size - 1); }
+ h2 = temp & (kHash2Size - 1); \
+ temp ^= ((UInt32)cur[2] << 8); \
+ h3 = temp & (kHash3Size - 1); \
+ temp ^= (p->crc[cur[3]] << 5); \
+ h4 = temp & (kHash4Size - 1); \
+ hv = (temp ^ (p->crc[cur[4]] << 3)) & p->hashMask; }
-/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
-#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
+/* #define HASH_ZIP_CALC hv = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
+#define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
#define MT_HASH2_CALC \
- hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
+ h2 = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
#define MT_HASH3_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
+ h2 = temp & (kHash2Size - 1); \
+ h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
#define MT_HASH4_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
- hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
+ h2 = temp & (kHash2Size - 1); \
+ temp ^= ((UInt32)cur[2] << 8); \
+ h3 = temp & (kHash3Size - 1); \
+ h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
#endif
diff --git a/3rdparty/lzma/C/Lzma2Dec.c b/3rdparty/lzma/C/Lzma2Dec.c
index f3a6b821daf..b84f88a4813 100644
--- a/3rdparty/lzma/C/Lzma2Dec.c
+++ b/3rdparty/lzma/C/Lzma2Dec.c
@@ -1,8 +1,10 @@
/* Lzma2Dec.c -- LZMA2 Decoder
-2010-12-15 : Igor Pavlov : Public domain */
+2015-11-09 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
+#include "Precomp.h"
+
#ifdef SHOW_DEBUG_INFO
#include <stdio.h>
#endif
@@ -97,12 +99,12 @@ void Lzma2Dec_Init(CLzma2Dec *p)
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
{
- switch(p->state)
+ switch (p->state)
{
case LZMA2_STATE_CONTROL:
p->control = b;
- PRF(printf("\n %4X ", p->decoder.dicPos));
- PRF(printf(" %2X", b));
+ PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
+ PRF(printf(" %2X", (unsigned)b));
if (p->control == 0)
return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
@@ -122,7 +124,7 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b;
p->unpackSize++;
- PRF(printf(" %8d", p->unpackSize));
+ PRF(printf(" %8u", (unsigned)p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0:
@@ -132,13 +134,13 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b;
p->packSize++;
- PRF(printf(" %8d", p->packSize));
+ PRF(printf(" %8u", (unsigned)p->packSize));
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
case LZMA2_STATE_PROP:
{
- int lc, lp;
+ unsigned lc, lp;
if (b >= (9 * 5 * 5))
return LZMA2_STATE_ERROR;
lc = b % 9;
@@ -177,13 +179,16 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
while (p->state != LZMA2_STATE_FINISHED)
{
SizeT dicPos = p->decoder.dicPos;
+
if (p->state == LZMA2_STATE_ERROR)
return SZ_ERROR_DATA;
+
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK;
}
+
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{
if (*srcLen == inSize)
@@ -193,8 +198,15 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
}
(*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++);
+
+ if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
+ {
+ p->state = LZMA2_STATE_ERROR;
+ return SZ_ERROR_DATA;
+ }
continue;
}
+
{
SizeT destSizeCur = dicLimit - dicPos;
SizeT srcSizeCur = inSize - *srcLen;
@@ -220,7 +232,10 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (initDic)
p->needInitProp = p->needInitState = True;
else if (p->needInitDic)
+ {
+ p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
+ }
p->needInitDic = False;
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
}
@@ -229,7 +244,10 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
srcSizeCur = destSizeCur;
if (srcSizeCur == 0)
+ {
+ p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
+ }
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
@@ -245,17 +263,21 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (p->state == LZMA2_STATE_DATA)
{
- int mode = LZMA2_GET_LZMA_MODE(p);
+ unsigned mode = LZMA2_GET_LZMA_MODE(p);
Bool initDic = (mode == 3);
- Bool initState = (mode > 0);
+ Bool initState = (mode != 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
+ {
+ p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
+ }
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->needInitDic = False;
p->needInitState = False;
p->state = LZMA2_STATE_DATA_CONT;
}
+
if (srcSizeCur > p->packSize)
srcSizeCur = (SizeT)p->packSize;
@@ -274,16 +296,22 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (srcSizeCur == 0 && outSizeProcessed == 0)
{
- if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
- p->unpackSize != 0 || p->packSize != 0)
+ if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+ || p->unpackSize != 0
+ || p->packSize != 0)
+ {
+ p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
+ }
p->state = LZMA2_STATE_CONTROL;
}
+
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
*status = LZMA_STATUS_NOT_FINISHED;
}
}
}
+
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK;
}
diff --git a/3rdparty/lzma/C/Lzma2Dec.h b/3rdparty/lzma/C/Lzma2Dec.h
index 6bc07bbc185..e6a0f6ed6db 100644
--- a/3rdparty/lzma/C/Lzma2Dec.h
+++ b/3rdparty/lzma/C/Lzma2Dec.h
@@ -1,14 +1,12 @@
/* Lzma2Dec.h -- LZMA2 Decoder
-2009-05-03 : Igor Pavlov : Public domain */
+2015-05-13 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H
#include "LzmaDec.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
/* ---------- State Interface ---------- */
@@ -17,7 +15,7 @@ typedef struct
CLzmaDec decoder;
UInt32 packSize;
UInt32 unpackSize;
- int state;
+ unsigned state;
Byte control;
Bool needInitDic;
Bool needInitState;
@@ -77,8 +75,6 @@ Returns:
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/Lzma2Enc.c b/3rdparty/lzma/C/Lzma2Enc.c
index e97597f63d5..1b77a2bbc1c 100644
--- a/3rdparty/lzma/C/Lzma2Enc.c
+++ b/3rdparty/lzma/C/Lzma2Enc.c
@@ -1,5 +1,7 @@
/* Lzma2Enc.c -- LZMA2 Encoder
-2010-09-24 : Igor Pavlov : Public domain */
+2015-10-04 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
/* #include <stdio.h> */
#include <string.h>
@@ -107,6 +109,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
{
size_t destPos = 0;
PRF(printf("################# COPY "));
+
while (unpackSize > 0)
{
UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE;
@@ -119,6 +122,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
unpackSize -= u;
destPos += u;
p->srcPos += u;
+
if (outStream)
{
*packSizeRes += destPos;
@@ -130,9 +134,11 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
*packSizeRes = destPos;
/* needInitState = True; */
}
+
LzmaEnc_RestoreState(p->enc);
return SZ_OK;
}
+
{
size_t destPos = 0;
UInt32 u = unpackSize - 1;
@@ -158,11 +164,13 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
if (outStream)
if (outStream->Write(outStream, outBuf, destPos) != destPos)
return SZ_ERROR_WRITE;
+
*packSizeRes = destPos;
return SZ_OK;
}
}
+
/* ---------- Lzma2 Props ---------- */
void Lzma2EncProps_Init(CLzma2EncProps *p)
@@ -216,10 +224,11 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
t3 = t1n * t2;
p->lzmaProps.numThreads = t1;
- p->numBlockThreads = t2;
- p->numTotalThreads = t3;
+
LzmaEncProps_Normalize(&p->lzmaProps);
+ t1 = p->lzmaProps.numThreads;
+
if (p->blockSize == 0)
{
UInt32 dictSize = p->lzmaProps.dictSize;
@@ -231,13 +240,34 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
if (blockSize < dictSize) blockSize = dictSize;
p->blockSize = (size_t)blockSize;
}
+
+ if (t2 > 1 && p->lzmaProps.reduceSize != (UInt64)(Int64)-1)
+ {
+ UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1;
+ if (temp > p->lzmaProps.reduceSize)
+ {
+ UInt64 numBlocks = temp / p->blockSize;
+ if (numBlocks < (unsigned)t2)
+ {
+ t2 = (unsigned)numBlocks;
+ if (t2 == 0)
+ t2 = 1;
+ t3 = t1 * t2;
+ }
+ }
+ }
+
+ p->numBlockThreads = t2;
+ p->numTotalThreads = t3;
}
+
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
{
return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
}
+
/* ---------- Lzma2 ---------- */
typedef struct
@@ -267,15 +297,17 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
UInt64 packTotal = 0;
SRes res = SZ_OK;
- if (mainEncoder->outBuf == 0)
+ if (!mainEncoder->outBuf)
{
mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
- if (mainEncoder->outBuf == 0)
+ if (!mainEncoder->outBuf)
return SZ_ERROR_MEM;
}
+
RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE,
mainEncoder->alloc, mainEncoder->allocBig));
+
for (;;)
{
size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
@@ -289,16 +321,20 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
if (packSize == 0)
break;
}
+
LzmaEnc_Finish(p->enc);
+
if (res == SZ_OK)
{
Byte b = 0;
if (outStream->Write(outStream, &b, 1) != 1)
return SZ_ERROR_WRITE;
}
+
return res;
}
+
#ifndef _7ZIP_ST
typedef struct
@@ -346,10 +382,12 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des
break;
}
}
+
LzmaEnc_Finish(p->enc);
if (res != SZ_OK)
return res;
}
+
if (finished)
{
if (*destSize == destLim)
@@ -362,12 +400,13 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des
#endif
+
/* ---------- Lzma2Enc ---------- */
CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
{
CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc));
- if (p == 0)
+ if (!p)
return NULL;
Lzma2EncProps_Init(&p->props);
Lzma2EncProps_Normalize(&p->props);
@@ -379,6 +418,7 @@ CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
p->coders[i].enc = 0;
}
+
#ifndef _7ZIP_ST
MtCoder_Construct(&p->mtCoder);
#endif
@@ -439,22 +479,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
for (i = 0; i < p->props.numBlockThreads; i++)
{
- CLzma2EncInt *t = &p->coders[i];
- if (t->enc == NULL)
+ CLzma2EncInt *t = &p->coders[(unsigned)i];
+ if (!t->enc)
{
t->enc = LzmaEnc_Create(p->alloc);
- if (t->enc == NULL)
+ if (!t->enc)
return SZ_ERROR_MEM;
}
}
#ifndef _7ZIP_ST
- if (p->props.numBlockThreads <= 1)
- #endif
- return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
-
- #ifndef _7ZIP_ST
-
+ if (p->props.numBlockThreads > 1)
{
CMtCallbackImp mtCallback;
@@ -469,9 +504,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
p->mtCoder.blockSize = p->props.blockSize;
p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16;
+ if (p->mtCoder.destBlockSize < p->props.blockSize)
+ {
+ p->mtCoder.destBlockSize = (size_t)0 - 1;
+ if (p->mtCoder.destBlockSize < p->props.blockSize)
+ return SZ_ERROR_FAIL;
+ }
p->mtCoder.numThreads = p->props.numBlockThreads;
return MtCoder_Code(&p->mtCoder);
}
#endif
+
+ return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
}
diff --git a/3rdparty/lzma/C/Lzma2Enc.h b/3rdparty/lzma/C/Lzma2Enc.h
index 283525581e9..f409f184cc3 100644
--- a/3rdparty/lzma/C/Lzma2Enc.h
+++ b/3rdparty/lzma/C/Lzma2Enc.h
@@ -1,14 +1,12 @@
/* Lzma2Enc.h -- LZMA2 Encoder
-2009-02-07 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA2_ENC_H
#define __LZMA2_ENC_H
#include "LzmaEnc.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
typedef struct
{
@@ -59,8 +57,6 @@ SRes Lzma2Encode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
*/
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/Lzma86.h b/3rdparty/lzma/C/Lzma86.h
index 6acbd888a04..bebed5cb76a 100644
--- a/3rdparty/lzma/C/Lzma86.h
+++ b/3rdparty/lzma/C/Lzma86.h
@@ -1,10 +1,10 @@
/* Lzma86.h -- LZMA + x86 (BCJ) Filter
-2009-08-14 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA86_H
#define __LZMA86_H
-#include "Types.h"
+#include "7zTypes.h"
EXTERN_C_BEGIN
diff --git a/3rdparty/lzma/C/Lzma86Dec.c b/3rdparty/lzma/C/Lzma86Dec.c
index fe7726097d0..7d89b2fcdec 100644
--- a/3rdparty/lzma/C/Lzma86Dec.c
+++ b/3rdparty/lzma/C/Lzma86Dec.c
@@ -1,5 +1,7 @@
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
-2009-08-14 : Igor Pavlov : Public domain */
+2015-11-08 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "Lzma86.h"
@@ -7,8 +9,8 @@
#include "Bra.h"
#include "LzmaDec.h"
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
+static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
+static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
{
diff --git a/3rdparty/lzma/C/Lzma86Enc.c b/3rdparty/lzma/C/Lzma86Enc.c
index 2ea4ac2da45..bfb7727d50e 100644
--- a/3rdparty/lzma/C/Lzma86Enc.c
+++ b/3rdparty/lzma/C/Lzma86Enc.c
@@ -1,5 +1,7 @@
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
-2009-08-14 : Igor Pavlov : Public domain */
+2015-11-08 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <string.h>
@@ -11,8 +13,8 @@
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
+static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
+static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
int level, UInt32 dictSize, int filterMode)
@@ -99,7 +101,7 @@ int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
}
}
}
- dest[0] = (bestIsFiltered ? 1 : 0);
+ dest[0] = (Byte)(bestIsFiltered ? 1 : 0);
*destLen = LZMA86_HEADER_SIZE + minSize;
}
if (useFilter)
diff --git a/3rdparty/lzma/C/LzmaDec.c b/3rdparty/lzma/C/LzmaDec.c
index f7f79bb063d..27efbaba904 100644
--- a/3rdparty/lzma/C/LzmaDec.c
+++ b/3rdparty/lzma/C/LzmaDec.c
@@ -1,5 +1,7 @@
/* LzmaDec.c -- LZMA Decoder
-2010-12-15 : Igor Pavlov : Public domain */
+2015-06-23 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "LzmaDec.h"
@@ -44,6 +46,13 @@
i -= 0x40; }
#endif
+#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol)
+#define MATCHED_LITER_DEC \
+ matchByte <<= 1; \
+ bit = (matchByte & offs); \
+ probLit = prob + offs + bit + symbol; \
+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
+
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
@@ -105,14 +114,14 @@
#define Literal (RepLenCoder + kNumLenProbs)
#define LZMA_BASE_SIZE 1846
-#define LZMA_LIT_SIZE 768
-
-#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+#define LZMA_LIT_SIZE 0x300
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
+#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+
#define LZMA_DIC_MIN (1 << 12)
/* First LZMA-symbol is always decoded.
@@ -124,8 +133,8 @@ Out:
p->remainLen:
< kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished
- = kMatchSpecLenStart + 1 : Flush marker
- = kMatchSpecLenStart + 2 : State Init Marker
+ = kMatchSpecLenStart + 1 : Flush marker (unused now)
+ = kMatchSpecLenStart + 2 : State Init Marker (unused now)
*/
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
@@ -163,38 +172,62 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
unsigned symbol;
UPDATE_0(prob);
prob = probs + Literal;
- if (checkDicSize != 0 || processedPos != 0)
- prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
- (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+ if (processedPos != 0 || checkDicSize != 0)
+ prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+ processedPos++;
if (state < kNumLitStates)
{
state -= (state < 4) ? state : 3;
symbol = 1;
- do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
+ #ifdef _LZMA_SIZE_OPT
+ do { NORMAL_LITER_DEC } while (symbol < 0x100);
+ #else
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ #endif
}
else
{
- unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
unsigned offs = 0x100;
state -= (state < 10) ? 3 : 6;
symbol = 1;
+ #ifdef _LZMA_SIZE_OPT
do
{
unsigned bit;
CLzmaProb *probLit;
- matchByte <<= 1;
- bit = (matchByte & offs);
- probLit = prob + offs + bit + symbol;
- GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
+ MATCHED_LITER_DEC
}
while (symbol < 0x100);
+ #else
+ {
+ unsigned bit;
+ CLzmaProb *probLit;
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ }
+ #endif
}
+
dic[dicPos++] = (Byte)symbol;
- processedPos++;
continue;
}
- else
+
{
UPDATE_1(prob);
prob = probs + IsRep + state;
@@ -217,7 +250,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(prob)
{
UPDATE_0(prob);
- dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
dicPos++;
processedPos++;
state = state < kNumLitStates ? 9 : 11;
@@ -258,6 +291,8 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
state = state < kNumLitStates ? 8 : 11;
prob = probs + RepLenCoder;
}
+
+ #ifdef _LZMA_SIZE_OPT
{
unsigned limit, offset;
CLzmaProb *probLen = prob + LenChoice;
@@ -290,6 +325,42 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
TREE_DECODE(probLen, limit, len);
len += offset;
}
+ #else
+ {
+ CLzmaProb *probLen = prob + LenChoice;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ len = 1;
+ TREE_GET_BIT(probLen, len);
+ TREE_GET_BIT(probLen, len);
+ TREE_GET_BIT(probLen, len);
+ len -= 8;
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenChoice2;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ len = 1;
+ TREE_GET_BIT(probLen, len);
+ TREE_GET_BIT(probLen, len);
+ TREE_GET_BIT(probLen, len);
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenHigh;
+ TREE_DECODE(probLen, (1 << kLenNumHighBits), len);
+ len += kLenNumLowSymbols + kLenNumMidSymbols;
+ }
+ }
+ }
+ #endif
if (state >= kNumStates)
{
@@ -300,7 +371,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (distance >= kStartPosModelIndex)
{
unsigned posSlot = (unsigned)distance;
- int numDirectBits = (int)(((distance >> 1) - 1));
+ unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));
distance = (2 | (distance & 1));
if (posSlot < kEndPosModelIndex)
{
@@ -359,6 +430,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
}
}
+
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
@@ -366,26 +438,39 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (checkDicSize == 0)
{
if (distance >= processedPos)
+ {
+ p->dicPos = dicPos;
return SZ_ERROR_DATA;
+ }
}
else if (distance >= checkDicSize)
+ {
+ p->dicPos = dicPos;
return SZ_ERROR_DATA;
+ }
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
}
len += kMatchMinLen;
- if (limit == dicPos)
- return SZ_ERROR_DATA;
{
- SizeT rem = limit - dicPos;
- unsigned curLen = ((rem < len) ? (unsigned)rem : len);
- SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
+ SizeT rem;
+ unsigned curLen;
+ SizeT pos;
+
+ if ((rem = limit - dicPos) == 0)
+ {
+ p->dicPos = dicPos;
+ return SZ_ERROR_DATA;
+ }
+
+ curLen = ((rem < len) ? (unsigned)rem : len);
+ pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
processedPos += curLen;
len -= curLen;
- if (pos + curLen <= dicBufSize)
+ if (curLen <= dicBufSize - pos)
{
Byte *dest = dic + dicPos;
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
@@ -409,7 +494,9 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
}
while (dicPos < limit && buf < bufLimit);
+
NORMALIZE;
+
p->buf = buf;
p->range = range;
p->code = code;
@@ -433,9 +520,10 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
SizeT dicPos = p->dicPos;
SizeT dicBufSize = p->dicBufSize;
unsigned len = p->remainLen;
- UInt32 rep0 = p->reps[0];
- if (limit - dicPos < len)
- len = (unsigned)(limit - dicPos);
+ SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
+ SizeT rem = limit - dicPos;
+ if (rem < len)
+ len = (unsigned)(rem);
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
p->checkDicSize = p->prop.dicSize;
@@ -445,7 +533,7 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
while (len != 0)
{
len--;
- dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
dicPos++;
}
p->dicPos = dicPos;
@@ -463,17 +551,19 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
if (limit - p->dicPos > rem)
limit2 = p->dicPos + rem;
}
+
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
- if (p->processedPos >= p->prop.dicSize)
+
+ if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
p->checkDicSize = p->prop.dicSize;
+
LzmaDec_WriteRem(p, limit);
}
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
if (p->remainLen > kMatchSpecLenStart)
- {
p->remainLen = kMatchSpecLenStart;
- }
+
return 0;
}
@@ -490,12 +580,12 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
UInt32 range = p->range;
UInt32 code = p->code;
const Byte *bufLimit = buf + inSize;
- CLzmaProb *probs = p->probs;
+ const CLzmaProb *probs = p->probs;
unsigned state = p->state;
ELzmaDummy res;
{
- CLzmaProb *prob;
+ const CLzmaProb *prob;
UInt32 bound;
unsigned ttt;
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
@@ -509,9 +599,9 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
prob = probs + Literal;
if (p->checkDicSize != 0 || p->processedPos != 0)
- prob += (LZMA_LIT_SIZE *
- ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
- (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
+ prob += ((UInt32)LZMA_LIT_SIZE *
+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
if (state < kNumLitStates)
{
@@ -521,13 +611,13 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
else
{
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
- ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
+ (p->dicPos < p->reps[0] ? p->dicBufSize : 0)];
unsigned offs = 0x100;
unsigned symbol = 1;
do
{
unsigned bit;
- CLzmaProb *probLit;
+ const CLzmaProb *probLit;
matchByte <<= 1;
bit = (matchByte & offs);
probLit = prob + offs + bit + symbol;
@@ -597,7 +687,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
}
{
unsigned limit, offset;
- CLzmaProb *probLen = prob + LenChoice;
+ const CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0_CHECK(probLen)
{
UPDATE_0_CHECK;
@@ -637,7 +727,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
- int numDirectBits = ((posSlot >> 1) - 1);
+ unsigned numDirectBits = ((posSlot >> 1) - 1);
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
@@ -676,13 +766,6 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
}
-static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
-{
- p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
- p->range = 0xFFFFFFFF;
- p->needFlush = 0;
-}
-
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
{
p->needFlush = 1;
@@ -707,8 +790,8 @@ void LzmaDec_Init(CLzmaDec *p)
static void LzmaDec_InitStateReal(CLzmaDec *p)
{
- UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
- UInt32 i;
+ SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
+ SizeT i;
CLzmaProb *probs = p->probs;
for (i = 0; i < numProbs; i++)
probs[i] = kBitModelTotal >> 1;
@@ -730,7 +813,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
{
int checkEndMarkNow;
- if (p->needFlush != 0)
+ if (p->needFlush)
{
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++;
@@ -741,8 +824,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
}
if (p->tempBuf[0] != 0)
return SZ_ERROR_DATA;
-
- LzmaDec_InitRc(p, p->tempBuf);
+ p->code =
+ ((UInt32)p->tempBuf[1] << 24)
+ | ((UInt32)p->tempBuf[2] << 16)
+ | ((UInt32)p->tempBuf[3] << 8)
+ | ((UInt32)p->tempBuf[4]);
+ p->range = 0xFFFFFFFF;
+ p->needFlush = 0;
p->tempBufSize = 0;
}
@@ -826,7 +914,16 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
p->buf = p->tempBuf;
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
return SZ_ERROR_DATA;
- lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
+
+ {
+ unsigned kkk = (unsigned)(p->buf - p->tempBuf);
+ if (rem < kkk)
+ return SZ_ERROR_FAIL; /* some internal error */
+ rem -= kkk;
+ if (lookAhead < rem)
+ return SZ_ERROR_FAIL; /* some internal error */
+ lookAhead -= rem;
+ }
(*srcLen) += lookAhead;
src += lookAhead;
inSize -= lookAhead;
@@ -881,13 +978,13 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->probs);
- p->probs = 0;
+ p->probs = NULL;
}
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->dic);
- p->dic = 0;
+ p->dic = NULL;
}
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
@@ -925,12 +1022,12 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
{
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
- if (p->probs == 0 || numProbs != p->numProbs)
+ if (!p->probs || numProbs != p->numProbs)
{
LzmaDec_FreeProbs(p, alloc);
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs;
- if (p->probs == 0)
+ if (!p->probs)
return SZ_ERROR_MEM;
}
return SZ_OK;
@@ -951,12 +1048,22 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
SizeT dicBufSize;
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
- dicBufSize = propNew.dicSize;
- if (p->dic == 0 || dicBufSize != p->dicBufSize)
+
+ {
+ UInt32 dictSize = propNew.dicSize;
+ SizeT mask = ((UInt32)1 << 12) - 1;
+ if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1;
+ else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;;
+ dicBufSize = ((SizeT)dictSize + mask) & ~mask;
+ if (dicBufSize < dictSize)
+ dicBufSize = dictSize;
+ }
+
+ if (!p->dic || dicBufSize != p->dicBufSize)
{
LzmaDec_FreeDict(p, alloc);
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
- if (p->dic == 0)
+ if (!p->dic)
{
LzmaDec_FreeProbs(p, alloc);
return SZ_ERROR_MEM;
@@ -967,27 +1074,6 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
return SZ_OK;
}
-// why isn't there an interface to pass in the properties directly????
-SRes LzmaDec_Allocate_MAME(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
-{
- SizeT dicBufSize;
- RINOK(LzmaDec_AllocateProbs2(p, propNew, alloc));
- dicBufSize = propNew->dicSize;
- if (p->dic == 0 || dicBufSize != p->dicBufSize)
- {
- LzmaDec_FreeDict(p, alloc);
- p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
- if (p->dic == 0)
- {
- LzmaDec_FreeProbs(p, alloc);
- return SZ_ERROR_MEM;
- }
- }
- p->dicBufSize = dicBufSize;
- p->prop = *propNew;
- return SZ_OK;
-}
-
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc)
diff --git a/3rdparty/lzma/C/LzmaDec.h b/3rdparty/lzma/C/LzmaDec.h
index e84a01e282e..cc44daef214 100644
--- a/3rdparty/lzma/C/LzmaDec.h
+++ b/3rdparty/lzma/C/LzmaDec.h
@@ -1,14 +1,12 @@
/* LzmaDec.h -- LZMA Decoder
-2009-02-07 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H
#define __LZMA_DEC_H
-#include "Types.h"
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
/* #define _LZMA_PROB32 */
/* _LZMA_PROB32 can increase the speed on some CPUs,
@@ -224,13 +222,6 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc);
-/*
- * Why isn't there an interface to pass in the properties directly????
- */
-SRes LzmaDec_Allocate_MAME(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc);
-
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/LzmaEnc.c b/3rdparty/lzma/C/LzmaEnc.c
index e1e170b1977..9c164e6f041 100644
--- a/3rdparty/lzma/C/LzmaEnc.c
+++ b/3rdparty/lzma/C/LzmaEnc.c
@@ -1,5 +1,7 @@
/* LzmaEnc.c -- LZMA Encoder
-2011-01-27 : Igor Pavlov : Public domain */
+2015-11-08 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <string.h>
@@ -18,9 +20,12 @@
#endif
#ifdef SHOW_STAT
-static int ttt = 0;
+static unsigned g_STAT_OFFSET = 0;
#endif
+#define kMaxHistorySize ((UInt32)3 << 29)
+/* #define kMaxHistorySize ((UInt32)7 << 29) */
+
#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
#define kBlockSize (9 << 10)
@@ -46,7 +51,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p)
{
p->level = 5;
p->dictSize = p->mc = 0;
- p->reduceSize = (UInt32)(Int32)-1;
+ p->reduceSize = (UInt64)(Int64)-1;
p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
p->writeEndMark = 0;
}
@@ -56,24 +61,28 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
int level = p->level;
if (level < 0) level = 5;
p->level = level;
+
if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
if (p->dictSize > p->reduceSize)
{
unsigned i;
- for (i = 15; i <= 30; i++)
+ for (i = 11; i <= 30; i++)
{
- if (p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
- if (p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
+ if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
+ if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
}
}
+
if (p->lc < 0) p->lc = 3;
if (p->lp < 0) p->lp = 0;
if (p->pb < 0) p->pb = 2;
+
if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
if (p->numHashBytes < 0) p->numHashBytes = 4;
- if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
+
if (p->numThreads < 0)
p->numThreads =
#ifndef _7ZIP_ST
@@ -90,17 +99,18 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
return props.dictSize;
}
+#if (_MSC_VER >= 1400)
+/* BSR code is fast for some new CPUs */
/* #define LZMA_LOG_BSR */
-/* Define it for Intel's CPU */
-
+#endif
#ifdef LZMA_LOG_BSR
-#define kDicLogSizeMaxCompress 30
+#define kDicLogSizeMaxCompress 32
#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
-UInt32 GetPosSlot1(UInt32 pos)
+static UInt32 GetPosSlot1(UInt32 pos)
{
UInt32 res;
BSR2_RET(pos, res);
@@ -111,27 +121,44 @@ UInt32 GetPosSlot1(UInt32 pos)
#else
-#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
+#define kNumLogBits (9 + sizeof(size_t) / 2)
+/* #define kNumLogBits (11 + sizeof(size_t) / 8 * 3) */
+
#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
-void LzmaEnc_FastPosInit(Byte *g_FastPos)
+static void LzmaEnc_FastPosInit(Byte *g_FastPos)
{
- int c = 2, slotFast;
+ unsigned slot;
g_FastPos[0] = 0;
g_FastPos[1] = 1;
+ g_FastPos += 2;
- for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
+ for (slot = 2; slot < kNumLogBits * 2; slot++)
{
- UInt32 k = (1 << ((slotFast >> 1) - 1));
- UInt32 j;
- for (j = 0; j < k; j++, c++)
- g_FastPos[c] = (Byte)slotFast;
+ size_t k = ((size_t)1 << ((slot >> 1) - 1));
+ size_t j;
+ for (j = 0; j < k; j++)
+ g_FastPos[j] = (Byte)slot;
+ g_FastPos += k;
}
}
+/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
+/*
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
res = p->g_FastPos[pos >> i] + (i * 2); }
+*/
+
+/*
+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
+ (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
+ res = p->g_FastPos[pos >> i] + (i * 2); }
+*/
+
+#define BSR2_RET(pos, res) { UInt32 i = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
+ res = p->g_FastPos[pos >> i] + (i * 2); }
+
/*
#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
p->g_FastPos[pos >> 6] + 12 : \
@@ -211,6 +238,7 @@ typedef struct
#define kNumStates 12
+
typedef struct
{
CLzmaProb choice;
@@ -220,14 +248,16 @@ typedef struct
CLzmaProb high[kLenNumHighSymbols];
} CLenEnc;
+
typedef struct
{
CLenEnc p;
- UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
UInt32 tableSize;
+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
UInt32 counters[LZMA_NUM_PB_STATES_MAX];
} CLenPriceEnc;
+
typedef struct
{
UInt32 range;
@@ -242,10 +272,14 @@ typedef struct
SRes res;
} CRangeEnc;
+
typedef struct
{
CLzmaProb *litProbs;
+ UInt32 state;
+ UInt32 reps[LZMA_NUM_REPS];
+
CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
CLzmaProb isRep[kNumStates];
CLzmaProb isRepG0[kNumStates];
@@ -259,15 +293,49 @@ typedef struct
CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc;
-
- UInt32 reps[LZMA_NUM_REPS];
- UInt32 state;
} CSaveState;
+
typedef struct
{
- IMatchFinder matchFinder;
void *matchFinderObj;
+ IMatchFinder matchFinder;
+
+ UInt32 optimumEndIndex;
+ UInt32 optimumCurrentIndex;
+
+ UInt32 longestMatchLength;
+ UInt32 numPairs;
+ UInt32 numAvail;
+
+ UInt32 numFastBytes;
+ UInt32 additionalOffset;
+ UInt32 reps[LZMA_NUM_REPS];
+ UInt32 state;
+
+ unsigned lc, lp, pb;
+ unsigned lpMask, pbMask;
+ unsigned lclp;
+
+ CLzmaProb *litProbs;
+
+ Bool fastMode;
+ Bool writeEndMark;
+ Bool finished;
+ Bool multiThread;
+ Bool needInit;
+
+ UInt64 nowPos64;
+
+ UInt32 matchPriceCount;
+ UInt32 alignPriceCount;
+
+ UInt32 distTableSize;
+
+ UInt32 dictSize;
+ SRes result;
+
+ CRangeEnc rc;
#ifndef _7ZIP_ST
Bool mtMode;
@@ -280,12 +348,6 @@ typedef struct
Byte pad[128];
#endif
- UInt32 optimumEndIndex;
- UInt32 optimumCurrentIndex;
-
- UInt32 longestMatchLength;
- UInt32 numPairs;
- UInt32 numAvail;
COptimal opt[kNumOpts];
#ifndef LZMA_LOG_BSR
@@ -294,22 +356,10 @@ typedef struct
UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
- UInt32 numFastBytes;
- UInt32 additionalOffset;
- UInt32 reps[LZMA_NUM_REPS];
- UInt32 state;
UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
UInt32 alignPrices[kAlignTableSize];
- UInt32 alignPriceCount;
-
- UInt32 distTableSize;
-
- unsigned lc, lp, pb;
- unsigned lpMask, pbMask;
-
- CLzmaProb *litProbs;
CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
CLzmaProb isRep[kNumStates];
@@ -325,26 +375,14 @@ typedef struct
CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc;
- unsigned lclp;
-
- Bool fastMode;
-
- CRangeEnc rc;
-
- Bool writeEndMark;
- UInt64 nowPos64;
- UInt32 matchPriceCount;
- Bool finished;
- Bool multiThread;
-
- SRes result;
- UInt32 dictSize;
-
- int needInit;
-
CSaveState saveState;
+
+ #ifndef _7ZIP_ST
+ Byte pad2[128];
+ #endif
} CLzmaEnc;
+
void LzmaEnc_SaveState(CLzmaEncHandle pp)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -368,7 +406,7 @@ void LzmaEnc_SaveState(CLzmaEncHandle pp)
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
memcpy(dest->reps, p->reps, sizeof(p->reps));
- memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
+ memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb));
}
void LzmaEnc_RestoreState(CLzmaEncHandle pp)
@@ -394,7 +432,7 @@ void LzmaEnc_RestoreState(CLzmaEncHandle pp)
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
memcpy(dest->reps, p->reps, sizeof(p->reps));
- memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
+ memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb));
}
SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
@@ -403,9 +441,13 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
CLzmaEncProps props = *props2;
LzmaEncProps_Normalize(&props);
- if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
- props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30))
+ if (props.lc > LZMA_LC_MAX
+ || props.lp > LZMA_LP_MAX
+ || props.pb > LZMA_PB_MAX
+ || props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
+ || props.dictSize > kMaxHistorySize)
return SZ_ERROR_PARAM;
+
p->dictSize = props.dictSize;
{
unsigned fb = props.fb;
@@ -419,7 +461,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
p->lp = props.lp;
p->pb = props.pb;
p->fastMode = (props.algo == 0);
- p->matchFinderBase.btMode = props.btMode;
+ p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0);
{
UInt32 numHashBytes = 4;
if (props.btMode)
@@ -463,8 +505,8 @@ static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11,
static void RangeEnc_Construct(CRangeEnc *p)
{
- p->outStream = 0;
- p->bufBase = 0;
+ p->outStream = NULL;
+ p->bufBase = NULL;
}
#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
@@ -472,10 +514,10 @@ static void RangeEnc_Construct(CRangeEnc *p)
#define RC_BUF_SIZE (1 << 16)
static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
{
- if (p->bufBase == 0)
+ if (!p->bufBase)
{
p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
- if (p->bufBase == 0)
+ if (!p->bufBase)
return 0;
p->bufLim = p->bufBase + RC_BUF_SIZE;
}
@@ -516,7 +558,7 @@ static void RangeEnc_FlushStream(CRangeEnc *p)
static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
{
- if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
+ if ((UInt32)p->low < (UInt32)0xFF000000 || (unsigned)(p->low >> 32) != 0)
{
Byte temp = p->cache;
do
@@ -542,7 +584,7 @@ static void RangeEnc_FlushData(CRangeEnc *p)
RangeEnc_ShiftLow(p);
}
-static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, unsigned numBits)
{
do
{
@@ -605,7 +647,7 @@ static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol,
while (symbol < 0x10000);
}
-void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
+static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
{
UInt32 i;
for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
@@ -641,7 +683,7 @@ void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, const UInt32 *ProbPrices)
{
UInt32 price = 0;
symbol |= 0x100;
@@ -654,7 +696,7 @@ static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *Pro
return price;
}
-static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, const UInt32 *ProbPrices)
{
UInt32 price = 0;
UInt32 offs = 0x100;
@@ -698,7 +740,7 @@ static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLeve
}
}
-static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)
{
UInt32 price = 0;
symbol |= (1 << numBitLevels);
@@ -710,7 +752,7 @@ static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 s
return price;
}
-static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)
{
UInt32 price = 0;
UInt32 m = 1;
@@ -761,7 +803,7 @@ static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posSt
}
}
-static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, const UInt32 *ProbPrices)
{
UInt32 a0 = GET_PRICE_0a(p->choice);
UInt32 a1 = GET_PRICE_1a(p->choice);
@@ -784,20 +826,20 @@ static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UIn
prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
}
-static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, const UInt32 *ProbPrices)
{
LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
p->counters[posState] = p->tableSize;
}
-static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, const UInt32 *ProbPrices)
{
UInt32 posState;
for (posState = 0; posState < numPosStates; posState++)
LenPriceEnc_UpdateTable(p, posState, ProbPrices);
}
-static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, const UInt32 *ProbPrices)
{
LenEnc_Encode(&p->p, rc, symbol, posState);
if (updatePrice)
@@ -811,9 +853,10 @@ static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32
static void MovePos(CLzmaEnc *p, UInt32 num)
{
#ifdef SHOW_STAT
- ttt += num;
- printf("\n MovePos %d", num);
+ g_STAT_OFFSET += num;
+ printf("\n MovePos %u", num);
#endif
+
if (num != 0)
{
p->additionalOffset += num;
@@ -826,28 +869,32 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
UInt32 lenRes = 0, numPairs;
p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
+
#ifdef SHOW_STAT
- printf("\n i = %d numPairs = %d ", ttt, numPairs / 2);
- ttt++;
+ printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2);
+ g_STAT_OFFSET++;
{
UInt32 i;
for (i = 0; i < numPairs; i += 2)
- printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
+ printf("%2u %6u | ", p->matches[i], p->matches[i + 1]);
}
#endif
+
if (numPairs > 0)
{
lenRes = p->matches[numPairs - 2];
if (lenRes == p->numFastBytes)
{
- const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
- UInt32 distance = p->matches[numPairs - 1] + 1;
UInt32 numAvail = p->numAvail;
if (numAvail > LZMA_MATCH_LEN_MAX)
numAvail = LZMA_MATCH_LEN_MAX;
{
- const Byte *pby2 = pby - distance;
- for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
+ const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ const Byte *pby = pbyCur + lenRes;
+ ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1];
+ const Byte *pbyLim = pbyCur + numAvail;
+ for (; pby != pbyLim && *pby == pby[dif]; pby++);
+ lenRes = (UInt32)(pby - pbyCur);
}
}
}
@@ -932,7 +979,7 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
return p->optimumCurrentIndex;
}
-#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * (UInt32)0x300)
static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
{
@@ -976,7 +1023,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 lenTest;
const Byte *data2;
reps[i] = p->reps[i];
- data2 = data - (reps[i] + 1);
+ data2 = data - reps[i] - 1;
if (data[0] != data2[0] || data[1] != data2[1])
{
repLens[i] = 0;
@@ -1120,12 +1167,12 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
cur = 0;
#ifdef SHOW_STAT2
- if (position >= 0)
+ /* if (position >= 0) */
{
unsigned i;
printf("\n pos = %4X", position);
for (i = cur; i <= lenEnd; i++)
- printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
+ printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price);
}
#endif
@@ -1277,7 +1324,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
/* try Literal + rep0 */
UInt32 temp;
UInt32 lenTest2;
- const Byte *data2 = data - (reps[0] + 1);
+ const Byte *data2 = data - reps[0] - 1;
UInt32 limit = p->numFastBytes + 1;
if (limit > numAvailFull)
limit = numAvailFull;
@@ -1320,7 +1367,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 lenTest;
UInt32 lenTestTemp;
UInt32 price;
- const Byte *data2 = data - (reps[repIndex] + 1);
+ const Byte *data2 = data - reps[repIndex] - 1;
if (data[0] != data2[0] || data[1] != data2[1])
continue;
for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
@@ -1350,13 +1397,13 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
{
UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes;
- UInt32 nextRepMatchPrice;
if (limit > numAvailFull)
limit = numAvailFull;
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
lenTest2 -= lenTest + 1;
if (lenTest2 >= 2)
{
+ UInt32 nextRepMatchPrice;
UInt32 state2 = kRepNextStates[state];
UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice =
@@ -1437,16 +1484,16 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
if (/*_maxMode && */lenTest == matches[offs])
{
/* Try Match + Literal + Rep0 */
- const Byte *data2 = data - (curBack + 1);
+ const Byte *data2 = data - curBack - 1;
UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes;
- UInt32 nextRepMatchPrice;
if (limit > numAvailFull)
limit = numAvailFull;
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
lenTest2 -= lenTest + 1;
if (lenTest2 >= 2)
{
+ UInt32 nextRepMatchPrice;
UInt32 state2 = kMatchNextStates[state];
UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice = curAndLenPrice +
@@ -1520,7 +1567,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
for (i = 0; i < LZMA_NUM_REPS; i++)
{
UInt32 len;
- const Byte *data2 = data - (p->reps[i] + 1);
+ const Byte *data2 = data - p->reps[i] - 1;
if (data[0] != data2[0] || data[1] != data2[1])
continue;
for (len = 2; len < numAvail && data[len] == data2[len]; len++);
@@ -1589,7 +1636,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
for (i = 0; i < LZMA_NUM_REPS; i++)
{
UInt32 len, limit;
- const Byte *data2 = data - (p->reps[i] + 1);
+ const Byte *data2 = data - p->reps[i] - 1;
if (data[0] != data2[0] || data[1] != data2[1])
continue;
limit = mainLen - 1;
@@ -1685,6 +1732,7 @@ void LzmaEnc_Construct(CLzmaEnc *p)
{
RangeEnc_Construct(&p->rc);
MatchFinder_Construct(&p->matchFinderBase);
+
#ifndef _7ZIP_ST
MatchFinderMt_Construct(&p->matchFinderMt);
p->matchFinderMt.MatchFinder = &p->matchFinderBase;
@@ -1701,15 +1749,15 @@ void LzmaEnc_Construct(CLzmaEnc *p)
#endif
LzmaEnc_InitPriceTables(p->ProbPrices);
- p->litProbs = 0;
- p->saveState.litProbs = 0;
+ p->litProbs = NULL;
+ p->saveState.litProbs = NULL;
}
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
{
void *p;
p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
- if (p != 0)
+ if (p)
LzmaEnc_Construct((CLzmaEnc *)p);
return p;
}
@@ -1718,8 +1766,8 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->litProbs);
alloc->Free(alloc, p->saveState.litProbs);
- p->litProbs = 0;
- p->saveState.litProbs = 0;
+ p->litProbs = NULL;
+ p->saveState.litProbs = NULL;
}
void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
@@ -1727,6 +1775,7 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
#ifndef _7ZIP_ST
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
#endif
+
MatchFinder_Free(&p->matchFinderBase, allocBig);
LzmaEnc_FreeLits(p, alloc);
RangeEnc_Free(&p->rc, alloc);
@@ -1763,7 +1812,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
ReadMatchDistances(p, &numPairs);
RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
p->state = kLiteralNextStates[p->state];
- curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
+ curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset);
LitEnc_Encode(&p->rc, p->litProbs, curByte);
p->additionalOffset--;
nowPos32++;
@@ -1780,7 +1829,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
len = GetOptimum(p, nowPos32, &pos);
#ifdef SHOW_STAT2
- printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos);
+ printf("\n pos = %4X, len = %u pos = %u", nowPos32, len, pos);
#endif
posState = nowPos32 & p->pbMask;
@@ -1889,7 +1938,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
break;
}
- else if (processed >= (1 << 15))
+ else if (processed >= (1 << 17))
{
p->nowPos64 += nowPos32 - startPos32;
return CheckErrors(p);
@@ -1905,24 +1954,21 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
{
UInt32 beforeSize = kNumOpts;
- #ifndef _7ZIP_ST
- Bool btMode;
- #endif
if (!RangeEnc_Alloc(&p->rc, alloc))
- return SZ_ERROR_MEM;
+ return SZ_ERROR_MEM;
+
#ifndef _7ZIP_ST
- btMode = (p->matchFinderBase.btMode != 0);
- p->mtMode = (p->multiThread && !p->fastMode && btMode);
+ p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0));
#endif
{
unsigned lclp = p->lc + p->lp;
- if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
+ if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
{
LzmaEnc_FreeLits(p, alloc);
- p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
- p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
- if (p->litProbs == 0 || p->saveState.litProbs == 0)
+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
+ if (!p->litProbs || !p->saveState.litProbs)
{
LzmaEnc_FreeLits(p, alloc);
return SZ_ERROR_MEM;
@@ -1931,7 +1977,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
}
}
- p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
+ p->matchFinderBase.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0);
if (beforeSize + p->dictSize < keepWindowSize)
beforeSize = keepWindowSize - p->dictSize;
@@ -1951,6 +1997,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
p->matchFinderObj = &p->matchFinderBase;
MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
}
+
return SZ_OK;
}
@@ -1979,9 +2026,10 @@ void LzmaEnc_Init(CLzmaEnc *p)
}
{
- UInt32 num = 0x300 << (p->lp + p->lc);
+ UInt32 num = (UInt32)0x300 << (p->lp + p->lc);
+ CLzmaProb *probs = p->litProbs;
for (i = 0; i < num; i++)
- p->litProbs[i] = kProbInitValue;
+ probs[i] = kProbInitValue;
}
{
@@ -2087,9 +2135,12 @@ void LzmaEnc_Finish(CLzmaEncHandle pp)
CLzmaEnc *p = (CLzmaEnc *)pp;
if (p->mtMode)
MatchFinderMt_ReleaseStream(&p->matchFinderMt);
+ #else
+ UNUSED_VAR(pp);
#endif
}
+
typedef struct
{
ISeqOutStream funcTable;
@@ -2119,12 +2170,14 @@ UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
}
+
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
{
const CLzmaEnc *p = (CLzmaEnc *)pp;
return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
}
+
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
{
@@ -2159,23 +2212,23 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
return res;
}
+
static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
{
SRes res = SZ_OK;
#ifndef _7ZIP_ST
Byte allocaDummy[0x300];
- int i = 0;
- for (i = 0; i < 16; i++)
- allocaDummy[i] = (Byte)i;
+ allocaDummy[0] = 0;
+ allocaDummy[1] = allocaDummy[0];
#endif
for (;;)
{
res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
- if (res != SZ_OK || p->finished != 0)
+ if (res != SZ_OK || p->finished)
break;
- if (progress != 0)
+ if (progress)
{
res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
if (res != SZ_OK)
@@ -2185,10 +2238,19 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
}
}
}
+
LzmaEnc_Finish(p);
+
+ /*
+ if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
+ res = SZ_ERROR_FAIL;
+ }
+ */
+
return res;
}
+
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
ISzAlloc *alloc, ISzAlloc *allocBig)
{
@@ -2196,28 +2258,27 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
}
+
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
- int i;
+ unsigned i;
UInt32 dictSize = p->dictSize;
if (*size < LZMA_PROPS_SIZE)
return SZ_ERROR_PARAM;
*size = LZMA_PROPS_SIZE;
props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
- for (i = 11; i <= 30; i++)
+ if (dictSize >= ((UInt32)1 << 22))
{
- if (dictSize <= ((UInt32)2 << i))
- {
- dictSize = (2 << i);
- break;
- }
- if (dictSize <= ((UInt32)3 << i))
- {
- dictSize = (3 << i);
- break;
- }
+ UInt32 kDictMask = ((UInt32)1 << 20) - 1;
+ if (dictSize < (UInt32)0xFFFFFFFF - kDictMask)
+ dictSize = (dictSize + kDictMask) & ~kDictMask;
+ }
+ else for (i = 11; i <= 30; i++)
+ {
+ if (dictSize <= ((UInt32)2 << i)) { dictSize = (2 << i); break; }
+ if (dictSize <= ((UInt32)3 << i)) { dictSize = (3 << i); break; }
}
for (i = 0; i < 4; i++)
@@ -2225,6 +2286,7 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
return SZ_OK;
}
+
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
{
@@ -2233,19 +2295,22 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
CSeqOutStreamBuf outStream;
- LzmaEnc_SetInputBuf(p, src, srcLen);
-
outStream.funcTable.Write = MyWrite;
outStream.data = dest;
outStream.rem = *destLen;
outStream.overflow = False;
p->writeEndMark = writeEndMark;
-
p->rc.outStream = &outStream.funcTable;
+
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
+
if (res == SZ_OK)
+ {
res = LzmaEnc_Encode2(p, progress);
+ if (res == SZ_OK && p->nowPos64 != srcLen)
+ res = SZ_ERROR_FAIL;
+ }
*destLen -= outStream.rem;
if (outStream.overflow)
@@ -2253,13 +2318,14 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
return res;
}
+
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
SRes res;
- if (p == 0)
+ if (!p)
return SZ_ERROR_MEM;
res = LzmaEnc_SetProps(p, props);
diff --git a/3rdparty/lzma/C/LzmaEnc.h b/3rdparty/lzma/C/LzmaEnc.h
index b8d9ce77230..cffe220bbf6 100644
--- a/3rdparty/lzma/C/LzmaEnc.h
+++ b/3rdparty/lzma/C/LzmaEnc.h
@@ -1,10 +1,10 @@
/* LzmaEnc.h -- LZMA Encoder
-2011-01-27 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA_ENC_H
#define __LZMA_ENC_H
-#include "Types.h"
+#include "7zTypes.h"
EXTERN_C_BEGIN
@@ -16,7 +16,7 @@ typedef struct _CLzmaEncProps
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
default = (1 << 24) */
- UInt32 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF.
+ UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF.
Encoder uses this value to reduce dictionary size */
int lc; /* 0 <= lc <= 8, default = 3 */
int lp; /* 0 <= lp <= 4, default = 0 */
diff --git a/3rdparty/lzma/C/LzmaLib.c b/3rdparty/lzma/C/LzmaLib.c
index 02a511857c9..706e9e58cd6 100644
--- a/3rdparty/lzma/C/LzmaLib.c
+++ b/3rdparty/lzma/C/LzmaLib.c
@@ -1,18 +1,12 @@
/* LzmaLib.c -- LZMA library wrapper
-2008-08-05
-Igor Pavlov
-Public domain */
+2015-06-13 : Igor Pavlov : Public domain */
-#include "LzmaEnc.h"
-#include "LzmaDec.h"
#include "Alloc.h"
+#include "LzmaDec.h"
+#include "LzmaEnc.h"
#include "LzmaLib.h"
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
-MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
+MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize,
int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
@@ -38,7 +32,7 @@ MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned cha
}
-MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
+MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
const unsigned char *props, size_t propsSize)
{
ELzmaStatus status;
diff --git a/3rdparty/lzma/C/LzmaLib.h b/3rdparty/lzma/C/LzmaLib.h
index 76c99ce758d..88fa87d350c 100644
--- a/3rdparty/lzma/C/LzmaLib.h
+++ b/3rdparty/lzma/C/LzmaLib.h
@@ -1,14 +1,12 @@
/* LzmaLib.h -- LZMA library interface
-2009-04-07 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA_LIB_H
#define __LZMA_LIB_H
-#include "Types.h"
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
#define MY_STDAPI int MY_STD_CALL
@@ -128,8 +126,6 @@ Returns:
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
const unsigned char *props, size_t propsSize);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/MtCoder.c b/3rdparty/lzma/C/MtCoder.c
index 946fbbc7076..8d9731d0a28 100644
--- a/3rdparty/lzma/C/MtCoder.c
+++ b/3rdparty/lzma/C/MtCoder.c
@@ -1,7 +1,7 @@
/* MtCoder.c -- Multi-thread Coder
-2010-09-24 : Igor Pavlov : Public domain */
+2015-10-13 : Igor Pavlov : Public domain */
-#include <stdio.h>
+#include "Precomp.h"
#include "MtCoder.h"
@@ -118,7 +118,7 @@ void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder)
LoopThread_Construct(&p->thread);
}
-#define RINOK_THREAD(x) { if((x) != 0) return SZ_ERROR_THREAD; }
+#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
static void CMtThread_CloseEvents(CMtThread *p)
{
diff --git a/3rdparty/lzma/C/Ppmd.h b/3rdparty/lzma/C/Ppmd.h
index 9cbc46647b8..4356dd1d871 100644
--- a/3rdparty/lzma/C/Ppmd.h
+++ b/3rdparty/lzma/C/Ppmd.h
@@ -1,11 +1,10 @@
/* Ppmd.h -- PPMD codec common code
-2011-01-27 : Igor Pavlov : Public domain
+2013-01-18 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H
#define __PPMD_H
-#include "Types.h"
#include "CpuArch.h"
EXTERN_C_BEGIN
diff --git a/3rdparty/lzma/C/Ppmd7.c b/3rdparty/lzma/C/Ppmd7.c
index bba4d06f0ab..7ef84d47b3b 100644
--- a/3rdparty/lzma/C/Ppmd7.c
+++ b/3rdparty/lzma/C/Ppmd7.c
@@ -1,7 +1,9 @@
/* Ppmd7.c -- PPMdH codec
-2010-03-12 : Igor Pavlov : Public domain
+2015-09-28 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
+#include "Precomp.h"
+
#include <string.h>
#include "Ppmd7.h"
@@ -64,7 +66,7 @@ void Ppmd7_Construct(CPpmd7 *p)
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
{
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
- do { p->Units2Indx[k++] = (Byte)i; } while(--step);
+ do { p->Units2Indx[k++] = (Byte)i; } while (--step);
p->Indx2Units[i] = (Byte)k;
}
@@ -255,7 +257,7 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx)
#define MyMem12Cpy(dest, src, num) \
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
- do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
+ do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); }
static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
{
diff --git a/3rdparty/lzma/C/Ppmd7Dec.c b/3rdparty/lzma/C/Ppmd7Dec.c
index 68438d5ce4e..04b4b09e330 100644
--- a/3rdparty/lzma/C/Ppmd7Dec.c
+++ b/3rdparty/lzma/C/Ppmd7Dec.c
@@ -2,6 +2,8 @@
2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
+#include "Precomp.h"
+
#include "Ppmd7.h"
#define kTopValue (1 << 24)
diff --git a/3rdparty/lzma/C/Ppmd7Enc.c b/3rdparty/lzma/C/Ppmd7Enc.c
index 8247757d09d..e6dd3d2fc29 100644
--- a/3rdparty/lzma/C/Ppmd7Enc.c
+++ b/3rdparty/lzma/C/Ppmd7Enc.c
@@ -1,7 +1,9 @@
/* Ppmd7Enc.c -- PPMdH Encoder
-2010-03-12 : Igor Pavlov : Public domain
+2015-09-28 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
+#include "Precomp.h"
+
#include "Ppmd7.h"
#define kTopValue (1 << 24)
@@ -24,7 +26,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
temp = 0xFF;
}
- while(--p->CacheSize != 0);
+ while (--p->CacheSize != 0);
p->Cache = (Byte)((UInt32)p->Low >> 24);
}
p->CacheSize++;
diff --git a/3rdparty/lzma/C/Precomp.h b/3rdparty/lzma/C/Precomp.h
new file mode 100644
index 00000000000..e8ff8b40e81
--- /dev/null
+++ b/3rdparty/lzma/C/Precomp.h
@@ -0,0 +1,10 @@
+/* Precomp.h -- StdAfx
+2013-11-12 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_PRECOMP_H
+#define __7Z_PRECOMP_H
+
+#include "Compiler.h"
+/* #include "7zTypes.h" */
+
+#endif
diff --git a/3rdparty/lzma/C/RotateDefs.h b/3rdparty/lzma/C/RotateDefs.h
index c3a1385ce5a..8f01d1a6c59 100644
--- a/3rdparty/lzma/C/RotateDefs.h
+++ b/3rdparty/lzma/C/RotateDefs.h
@@ -1,5 +1,5 @@
/* RotateDefs.h -- Rotate functions
-2009-02-07 : Igor Pavlov : Public domain */
+2015-03-25 : Igor Pavlov : Public domain */
#ifndef __ROTATE_DEFS_H
#define __ROTATE_DEFS_H
@@ -7,11 +7,21 @@
#ifdef _MSC_VER
#include <stdlib.h>
+
+/* don't use _rotl with MINGW. It can insert slow call to function. */
+
+/* #if (_MSC_VER >= 1200) */
+#pragma intrinsic(_rotl)
+#pragma intrinsic(_rotr)
+/* #endif */
+
#define rotlFixed(x, n) _rotl((x), (n))
#define rotrFixed(x, n) _rotr((x), (n))
#else
+/* new compilers can translate these macros to fast commands. */
+
#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
diff --git a/3rdparty/lzma/C/Sha256.c b/3rdparty/lzma/C/Sha256.c
index eb4fc61fc9d..b5bc19b9602 100644
--- a/3rdparty/lzma/C/Sha256.c
+++ b/3rdparty/lzma/C/Sha256.c
@@ -1,12 +1,21 @@
/* Crypto/Sha256.c -- SHA-256 Hash
-2010-06-11 : Igor Pavlov : Public domain
+2015-11-14 : Igor Pavlov : Public domain
This code is based on public domain code from Wei Dai's Crypto++ library. */
+#include "Precomp.h"
+
+#include <string.h>
+
+#include "CpuArch.h"
#include "RotateDefs.h"
#include "Sha256.h"
/* define it for speed optimization */
-/* #define _SHA256_UNROLL */
+#ifndef _SFX
+#define _SHA256_UNROLL
+#define _SHA256_UNROLL2
+#endif
+
/* #define _SHA256_UNROLL2 */
void Sha256_Init(CSha256 *p)
@@ -27,26 +36,18 @@ void Sha256_Init(CSha256 *p)
#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
-#define blk0(i) (W[i] = data[i])
-#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15]))
+#define blk0(i) (W[i])
+#define blk2(i) (W[i] += s1(W[((i)-2)&15]) + W[((i)-7)&15] + s0(W[((i)-15)&15]))
#define Ch(x,y,z) (z^(x&(y^z)))
#define Maj(x,y,z) ((x&y)|(z&(x|y)))
-#define a(i) T[(0-(i))&7]
-#define b(i) T[(1-(i))&7]
-#define c(i) T[(2-(i))&7]
-#define d(i) T[(3-(i))&7]
-#define e(i) T[(4-(i))&7]
-#define f(i) T[(5-(i))&7]
-#define g(i) T[(6-(i))&7]
-#define h(i) T[(7-(i))&7]
-
-
#ifdef _SHA256_UNROLL2
-#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\
- d += h; h += S0(a) + Maj(a, b, c)
+#define R(a,b,c,d,e,f,g,h, i) \
+ h += S1(e) + Ch(e,f,g) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \
+ d += h; \
+ h += S0(a) + Maj(a, b, c)
#define RX_8(i) \
R(a,b,c,d,e,f,g,h, i); \
@@ -58,14 +59,32 @@ void Sha256_Init(CSha256 *p)
R(c,d,e,f,g,h,a,b, i+6); \
R(b,c,d,e,f,g,h,a, i+7)
+#define RX_16 RX_8(0); RX_8(8);
+
#else
-#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\
- d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
+#define a(i) T[(0-(i))&7]
+#define b(i) T[(1-(i))&7]
+#define c(i) T[(2-(i))&7]
+#define d(i) T[(3-(i))&7]
+#define e(i) T[(4-(i))&7]
+#define f(i) T[(5-(i))&7]
+#define g(i) T[(6-(i))&7]
+#define h(i) T[(7-(i))&7]
+
+#define R(i) \
+ h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \
+ d(i) += h(i); \
+ h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \
#ifdef _SHA256_UNROLL
-#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
+#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
+#define RX_16 RX_8(0); RX_8(8);
+
+#else
+
+#define RX_16 unsigned i; for (i = 0; i < 16; i++) { R(i); }
#endif
@@ -90,12 +109,30 @@ static const UInt32 K[64] = {
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
-static void Sha256_Transform(UInt32 *state, const UInt32 *data)
+static void Sha256_WriteByteBlock(CSha256 *p)
{
UInt32 W[16];
unsigned j;
+ UInt32 *state;
+
#ifdef _SHA256_UNROLL2
UInt32 a,b,c,d,e,f,g,h;
+ #else
+ UInt32 T[8];
+ #endif
+
+ for (j = 0; j < 16; j += 4)
+ {
+ const Byte *ccc = p->buffer + j * 4;
+ W[j ] = GetBe32(ccc);
+ W[j + 1] = GetBe32(ccc + 4);
+ W[j + 2] = GetBe32(ccc + 8);
+ W[j + 3] = GetBe32(ccc + 12);
+ }
+
+ state = p->state;
+
+ #ifdef _SHA256_UNROLL2
a = state[0];
b = state[1];
c = state[2];
@@ -105,19 +142,13 @@ static void Sha256_Transform(UInt32 *state, const UInt32 *data)
g = state[6];
h = state[7];
#else
- UInt32 T[8];
for (j = 0; j < 8; j++)
T[j] = state[j];
#endif
for (j = 0; j < 64; j += 16)
{
- #if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2)
- RX_8(0); RX_8(8);
- #else
- unsigned i;
- for (i = 0; i < 16; i++) { R(i); }
- #endif
+ RX_16
}
#ifdef _SHA256_UNROLL2
@@ -144,61 +175,74 @@ static void Sha256_Transform(UInt32 *state, const UInt32 *data)
#undef s0
#undef s1
-static void Sha256_WriteByteBlock(CSha256 *p)
-{
- UInt32 data32[16];
- unsigned i;
- for (i = 0; i < 16; i++)
- data32[i] =
- ((UInt32)(p->buffer[i * 4 ]) << 24) +
- ((UInt32)(p->buffer[i * 4 + 1]) << 16) +
- ((UInt32)(p->buffer[i * 4 + 2]) << 8) +
- ((UInt32)(p->buffer[i * 4 + 3]));
- Sha256_Transform(p->state, data32);
-}
-
void Sha256_Update(CSha256 *p, const Byte *data, size_t size)
{
- UInt32 curBufferPos = (UInt32)p->count & 0x3F;
- while (size > 0)
+ if (size == 0)
+ return;
+
{
- p->buffer[curBufferPos++] = *data++;
- p->count++;
- size--;
- if (curBufferPos == 64)
+ unsigned pos = (unsigned)p->count & 0x3F;
+ unsigned num;
+
+ p->count += size;
+
+ num = 64 - pos;
+ if (num > size)
{
- curBufferPos = 0;
- Sha256_WriteByteBlock(p);
+ memcpy(p->buffer + pos, data, size);
+ return;
}
+
+ size -= num;
+ memcpy(p->buffer + pos, data, num);
+ data += num;
+ }
+
+ for (;;)
+ {
+ Sha256_WriteByteBlock(p);
+ if (size < 64)
+ break;
+ size -= 64;
+ memcpy(p->buffer, data, 64);
+ data += 64;
}
+
+ if (size != 0)
+ memcpy(p->buffer, data, size);
}
void Sha256_Final(CSha256 *p, Byte *digest)
{
- UInt64 lenInBits = (p->count << 3);
- UInt32 curBufferPos = (UInt32)p->count & 0x3F;
+ unsigned pos = (unsigned)p->count & 0x3F;
unsigned i;
- p->buffer[curBufferPos++] = 0x80;
- while (curBufferPos != (64 - 8))
+
+ p->buffer[pos++] = 0x80;
+
+ while (pos != (64 - 8))
{
- curBufferPos &= 0x3F;
- if (curBufferPos == 0)
+ pos &= 0x3F;
+ if (pos == 0)
Sha256_WriteByteBlock(p);
- p->buffer[curBufferPos++] = 0;
+ p->buffer[pos++] = 0;
}
- for (i = 0; i < 8; i++)
+
{
- p->buffer[curBufferPos++] = (Byte)(lenInBits >> 56);
- lenInBits <<= 8;
+ UInt64 numBits = (p->count << 3);
+ SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32));
+ SetBe32(p->buffer + 64 - 4, (UInt32)(numBits));
}
+
Sha256_WriteByteBlock(p);
- for (i = 0; i < 8; i++)
+ for (i = 0; i < 8; i += 2)
{
- *digest++ = (Byte)(p->state[i] >> 24);
- *digest++ = (Byte)(p->state[i] >> 16);
- *digest++ = (Byte)(p->state[i] >> 8);
- *digest++ = (Byte)(p->state[i]);
+ UInt32 v0 = p->state[i];
+ UInt32 v1 = p->state[i + 1];
+ SetBe32(digest , v0);
+ SetBe32(digest + 4, v1);
+ digest += 8;
}
+
Sha256_Init(p);
}
diff --git a/3rdparty/lzma/C/Sha256.h b/3rdparty/lzma/C/Sha256.h
index 530f513ec68..3f455dbc0d8 100644
--- a/3rdparty/lzma/C/Sha256.h
+++ b/3rdparty/lzma/C/Sha256.h
@@ -1,10 +1,10 @@
/* Sha256.h -- SHA-256 Hash
-2010-06-11 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __CRYPTO_SHA256_H
#define __CRYPTO_SHA256_H
-#include "Types.h"
+#include "7zTypes.h"
EXTERN_C_BEGIN
diff --git a/3rdparty/lzma/C/Sort.c b/3rdparty/lzma/C/Sort.c
new file mode 100644
index 00000000000..e1097e38068
--- /dev/null
+++ b/3rdparty/lzma/C/Sort.c
@@ -0,0 +1,141 @@
+/* Sort.c -- Sort functions
+2014-04-05 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "Sort.h"
+
+#define HeapSortDown(p, k, size, temp) \
+ { for (;;) { \
+ size_t s = (k << 1); \
+ if (s > size) break; \
+ if (s < size && p[s + 1] > p[s]) s++; \
+ if (temp >= p[s]) break; \
+ p[k] = p[s]; k = s; \
+ } p[k] = temp; }
+
+void HeapSort(UInt32 *p, size_t size)
+{
+ if (size <= 1)
+ return;
+ p--;
+ {
+ size_t i = size / 2;
+ do
+ {
+ UInt32 temp = p[i];
+ size_t k = i;
+ HeapSortDown(p, k, size, temp)
+ }
+ while (--i != 0);
+ }
+ /*
+ do
+ {
+ size_t k = 1;
+ UInt32 temp = p[size];
+ p[size--] = p[1];
+ HeapSortDown(p, k, size, temp)
+ }
+ while (size > 1);
+ */
+ while (size > 3)
+ {
+ UInt32 temp = p[size];
+ size_t k = (p[3] > p[2]) ? 3 : 2;
+ p[size--] = p[1];
+ p[1] = p[k];
+ HeapSortDown(p, k, size, temp)
+ }
+ {
+ UInt32 temp = p[size];
+ p[size] = p[1];
+ if (size > 2 && p[2] < temp)
+ {
+ p[1] = p[2];
+ p[2] = temp;
+ }
+ else
+ p[1] = temp;
+ }
+}
+
+void HeapSort64(UInt64 *p, size_t size)
+{
+ if (size <= 1)
+ return;
+ p--;
+ {
+ size_t i = size / 2;
+ do
+ {
+ UInt64 temp = p[i];
+ size_t k = i;
+ HeapSortDown(p, k, size, temp)
+ }
+ while (--i != 0);
+ }
+ /*
+ do
+ {
+ size_t k = 1;
+ UInt64 temp = p[size];
+ p[size--] = p[1];
+ HeapSortDown(p, k, size, temp)
+ }
+ while (size > 1);
+ */
+ while (size > 3)
+ {
+ UInt64 temp = p[size];
+ size_t k = (p[3] > p[2]) ? 3 : 2;
+ p[size--] = p[1];
+ p[1] = p[k];
+ HeapSortDown(p, k, size, temp)
+ }
+ {
+ UInt64 temp = p[size];
+ p[size] = p[1];
+ if (size > 2 && p[2] < temp)
+ {
+ p[1] = p[2];
+ p[2] = temp;
+ }
+ else
+ p[1] = temp;
+ }
+}
+
+/*
+#define HeapSortRefDown(p, vals, n, size, temp) \
+ { size_t k = n; UInt32 val = vals[temp]; for (;;) { \
+ size_t s = (k << 1); \
+ if (s > size) break; \
+ if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \
+ if (val >= vals[p[s]]) break; \
+ p[k] = p[s]; k = s; \
+ } p[k] = temp; }
+
+void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size)
+{
+ if (size <= 1)
+ return;
+ p--;
+ {
+ size_t i = size / 2;
+ do
+ {
+ UInt32 temp = p[i];
+ HeapSortRefDown(p, vals, i, size, temp);
+ }
+ while (--i != 0);
+ }
+ do
+ {
+ UInt32 temp = p[size];
+ p[size--] = p[1];
+ HeapSortRefDown(p, vals, 1, size, temp);
+ }
+ while (size > 1);
+}
+*/
diff --git a/3rdparty/lzma/C/Sort.h b/3rdparty/lzma/C/Sort.h
new file mode 100644
index 00000000000..2e2963a23da
--- /dev/null
+++ b/3rdparty/lzma/C/Sort.h
@@ -0,0 +1,18 @@
+/* Sort.h -- Sort functions
+2014-04-05 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_SORT_H
+#define __7Z_SORT_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+void HeapSort(UInt32 *p, size_t size);
+void HeapSort64(UInt64 *p, size_t size);
+
+/* void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size); */
+
+EXTERN_C_END
+
+#endif
diff --git a/3rdparty/lzma/C/Threads.c b/3rdparty/lzma/C/Threads.c
index 68561067fe6..d3d0912da42 100644
--- a/3rdparty/lzma/C/Threads.c
+++ b/3rdparty/lzma/C/Threads.c
@@ -1,7 +1,9 @@
/* Threads.c -- multithreading library
-2009-09-20 : Igor Pavlov : Public domain */
+2014-09-21 : Igor Pavlov : Public domain */
-#ifndef _WIN32_7Z_WCE
+#include "Precomp.h"
+
+#ifndef UNDER_CE
#include <process.h>
#endif
@@ -29,14 +31,21 @@ WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE)
WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
{
- unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
- *p =
- #ifdef UNDER_CE
- CreateThread(0, 0, func, param, 0, &threadId);
- #else
- (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);
- #endif
- /* maybe we must use errno here, but probably GetLastError() is also OK. */
+ /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
+
+ #ifdef UNDER_CE
+
+ DWORD threadId;
+ *p = CreateThread(0, 0, func, param, 0, &threadId);
+
+ #else
+
+ unsigned threadId;
+ *p = (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);
+
+ #endif
+
+ /* maybe we must use errno here, but probably GetLastError() is also OK. */
return HandleToWRes(*p);
}
diff --git a/3rdparty/lzma/C/Threads.h b/3rdparty/lzma/C/Threads.h
index d0ddd80e227..9b3e1c556d2 100644
--- a/3rdparty/lzma/C/Threads.h
+++ b/3rdparty/lzma/C/Threads.h
@@ -1,15 +1,17 @@
/* Threads.h -- multithreading library
-2009-03-27 : Igor Pavlov : Public domain */
+2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_THREADS_H
#define __7Z_THREADS_H
-#include "Types.h"
-
-#ifdef __cplusplus
-extern "C" {
+#ifdef _WIN32
+#include <windows.h>
#endif
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
WRes HandlePtr_Close(HANDLE *h);
WRes Handle_WaitObject(HANDLE h);
@@ -18,7 +20,15 @@ typedef HANDLE CThread;
#define Thread_WasCreated(p) (*(p) != NULL)
#define Thread_Close(p) HandlePtr_Close(p)
#define Thread_Wait(p) Handle_WaitObject(*(p))
-typedef unsigned THREAD_FUNC_RET_TYPE;
+
+typedef
+#ifdef UNDER_CE
+ DWORD
+#else
+ unsigned
+#endif
+ THREAD_FUNC_RET_TYPE;
+
#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);
@@ -52,8 +62,6 @@ WRes CriticalSection_Init(CCriticalSection *p);
#define CriticalSection_Enter(p) EnterCriticalSection(p)
#define CriticalSection_Leave(p) LeaveCriticalSection(p)
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/Util/7z/7z.dsp b/3rdparty/lzma/C/Util/7z/7z.dsp
index 21dd5995f05..be0f0a74376 100644
--- a/3rdparty/lzma/C/Util/7z/7z.dsp
+++ b/3rdparty/lzma/C/Util/7z/7z.dsp
@@ -42,7 +42,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 /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAs /YX /FD /c
+# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAcs /Yu"Precomp.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -50,7 +50,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe" /opt:NOWIN98
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\util\7zDec.exe" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "7z - Win32 Debug"
@@ -67,7 +67,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 /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c
+# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Yu"Precomp.h" /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
@@ -75,7 +75,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zDec.exe" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\util\7zDec.exe" /pdbtype:sept
!ENDIF
@@ -100,6 +100,10 @@ SOURCE=..\..\7zAlloc.h
# End Source File
# Begin Source File
+SOURCE=..\..\7zArcIn.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\7zBuf.c
# End Source File
# Begin Source File
@@ -133,11 +137,11 @@ SOURCE=..\..\7zFile.h
# End Source File
# Begin Source File
-SOURCE=..\..\7zIn.c
+SOURCE=..\..\7zStream.c
# End Source File
# Begin Source File
-SOURCE=..\..\7zStream.c
+SOURCE=..\..\7zTypes.h
# End Source File
# Begin Source File
@@ -161,6 +165,10 @@ SOURCE=..\..\Bra86.c
# End Source File
# Begin Source File
+SOURCE=..\..\BraIA64.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\CpuArch.c
# End Source File
# Begin Source File
@@ -169,6 +177,14 @@ SOURCE=..\..\CpuArch.h
# End Source File
# Begin Source File
+SOURCE=..\..\Delta.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Delta.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Lzma2Dec.c
# End Source File
# Begin Source File
@@ -190,7 +206,6 @@ SOURCE=..\..\Ppmd.h
# Begin Source File
SOURCE=..\..\Ppmd7.c
-# SUBTRACT CPP /YX
# End Source File
# Begin Source File
@@ -199,11 +214,23 @@ SOURCE=..\..\Ppmd7.h
# Begin Source File
SOURCE=..\..\Ppmd7Dec.c
-# SUBTRACT CPP /YX
+# End Source File
+# End Group
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compiler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Precomp.c
+# ADD CPP /Yc"Precomp.h"
# End Source File
# Begin Source File
-SOURCE=..\..\Types.h
+SOURCE=.\Precomp.h
# End Source File
# End Group
# Begin Source File
diff --git a/3rdparty/lzma/C/Util/7z/7zMain.c b/3rdparty/lzma/C/Util/7z/7zMain.c
index 9496dc07d4c..ed6bab2a5a4 100644
--- a/3rdparty/lzma/C/Util/7z/7zMain.c
+++ b/3rdparty/lzma/C/Util/7z/7zMain.c
@@ -1,11 +1,14 @@
/* 7zMain.c - Test application for 7z Decoder
-2010-10-28 : Igor Pavlov : Public domain */
+2015-08-02 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <stdio.h>
#include <string.h>
#include "../../7z.h"
#include "../../7zAlloc.h"
+#include "../../7zBuf.h"
#include "../../7zCrc.h"
#include "../../7zFile.h"
#include "../../7zVersion.h"
@@ -31,106 +34,158 @@ static int Buf_EnsureSize(CBuf *dest, size_t size)
}
#ifndef _WIN32
+#define _USE_UTF8
+#endif
+
+/* #define _USE_UTF8 */
+
+#ifdef _USE_UTF8
+
+#define _UTF8_START(n) (0x100 - (1 << (7 - (n))))
-static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+#define _UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6))
-static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen)
+#define _UTF8_HEAD(n, val) ((Byte)(_UTF8_START(n) + (val >> (6 * (n)))))
+#define _UTF8_CHAR(n, val) ((Byte)(0x80 + (((val) >> (6 * (n))) & 0x3F)))
+
+static size_t Utf16_To_Utf8_Calc(const UInt16 *src, const UInt16 *srcLim)
{
- size_t destPos = 0, srcPos = 0;
+ size_t size = 0;
for (;;)
{
- unsigned numAdds;
- UInt32 value;
- if (srcPos == srcLen)
+ UInt32 val;
+ if (src == srcLim)
+ return size;
+
+ size++;
+ val = *src++;
+
+ if (val < 0x80)
+ continue;
+
+ if (val < _UTF8_RANGE(1))
{
- *destLen = destPos;
- return True;
+ size++;
+ continue;
}
- value = src[srcPos++];
- if (value < 0x80)
+
+ if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
{
- if (dest)
- dest[destPos] = (char)value;
- destPos++;
+ UInt32 c2 = *src;
+ if (c2 >= 0xDC00 && c2 < 0xE000)
+ {
+ src++;
+ size += 3;
+ continue;
+ }
+ }
+
+ size += 2;
+ }
+}
+
+static Byte *Utf16_To_Utf8(Byte *dest, const UInt16 *src, const UInt16 *srcLim)
+{
+ for (;;)
+ {
+ UInt32 val;
+ if (src == srcLim)
+ return dest;
+
+ val = *src++;
+
+ if (val < 0x80)
+ {
+ *dest++ = (char)val;
continue;
}
- if (value >= 0xD800 && value < 0xE000)
+
+ if (val < _UTF8_RANGE(1))
{
- UInt32 c2;
- if (value >= 0xDC00 || srcPos == srcLen)
- break;
- c2 = src[srcPos++];
- if (c2 < 0xDC00 || c2 >= 0xE000)
- break;
- value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
+ dest[0] = _UTF8_HEAD(1, val);
+ dest[1] = _UTF8_CHAR(0, val);
+ dest += 2;
+ continue;
}
- for (numAdds = 1; numAdds < 5; numAdds++)
- if (value < (((UInt32)1) << (numAdds * 5 + 6)))
- break;
- if (dest)
- dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
- destPos++;
- do
+
+ if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
{
- numAdds--;
- if (dest)
- dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
- destPos++;
+ UInt32 c2 = *src;
+ if (c2 >= 0xDC00 && c2 < 0xE000)
+ {
+ src++;
+ val = (((val - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
+ dest[0] = _UTF8_HEAD(3, val);
+ dest[1] = _UTF8_CHAR(2, val);
+ dest[2] = _UTF8_CHAR(1, val);
+ dest[3] = _UTF8_CHAR(0, val);
+ dest += 4;
+ continue;
+ }
}
- while (numAdds != 0);
+
+ dest[0] = _UTF8_HEAD(2, val);
+ dest[1] = _UTF8_CHAR(1, val);
+ dest[2] = _UTF8_CHAR(0, val);
+ dest += 3;
}
- *destLen = destPos;
- return False;
}
static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
{
- size_t destLen = 0;
- Bool res;
- Utf16_To_Utf8(NULL, &destLen, src, srcLen);
+ size_t destLen = Utf16_To_Utf8_Calc(src, src + srcLen);
destLen += 1;
if (!Buf_EnsureSize(dest, destLen))
return SZ_ERROR_MEM;
- res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen);
- dest->data[destLen] = 0;
- return res ? SZ_OK : SZ_ERROR_FAIL;
+ *Utf16_To_Utf8(dest->data, src, src + srcLen) = 0;
+ return SZ_OK;
}
+
#endif
-static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)
+static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
+ #ifndef _USE_UTF8
+ , UINT codePage
+ #endif
+ )
{
- int len = 0;
- for (len = 0; s[len] != '\0'; len++);
+ unsigned len = 0;
+ for (len = 0; s[len] != 0; len++);
- #ifdef _WIN32
+ #ifndef _USE_UTF8
{
- int size = len * 3 + 100;
+ unsigned size = len * 3 + 100;
if (!Buf_EnsureSize(buf, size))
return SZ_ERROR_MEM;
{
- char defaultChar = '_';
- BOOL defUsed;
- int numChars = WideCharToMultiByte(fileMode ?
- (
- #ifdef UNDER_CE
- CP_ACP
- #else
- AreFileApisANSI() ? CP_ACP : CP_OEMCP
- #endif
- ) : CP_OEMCP,
- 0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);
- if (numChars == 0 || numChars >= size)
- return SZ_ERROR_FAIL;
- buf->data[numChars] = 0;
+ buf->data[0] = 0;
+ if (len != 0)
+ {
+ char defaultChar = '_';
+ BOOL defUsed;
+ unsigned numChars = 0;
+ numChars = WideCharToMultiByte(codePage, 0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);
+ if (numChars == 0 || numChars >= size)
+ return SZ_ERROR_FAIL;
+ buf->data[numChars] = 0;
+ }
return SZ_OK;
}
}
#else
- fileMode = fileMode;
return Utf16_To_Utf8Buf(buf, s, len);
#endif
}
+#ifdef _WIN32
+ #ifndef USE_WINDOWS_FILE
+ static UINT g_FileCodePage = CP_ACP;
+ #endif
+ #define MY_FILE_CODE_PAGE_PARAM ,g_FileCodePage
+#else
+ #define MY_FILE_CODE_PAGE_PARAM
+#endif
+
static WRes MyCreateDir(const UInt16 *name)
{
#ifdef USE_WINDOWS_FILE
@@ -142,7 +197,7 @@ static WRes MyCreateDir(const UInt16 *name)
CBuf buf;
WRes res;
Buf_Init(&buf);
- RINOK(Utf16_To_Char(&buf, name, 1));
+ RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM));
res =
#ifdef _WIN32
@@ -165,7 +220,7 @@ static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
CBuf buf;
WRes res;
Buf_Init(&buf);
- RINOK(Utf16_To_Char(&buf, name, 1));
+ RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM));
res = OutFile_Open(p, (const char *)buf.data);
Buf_Free(&buf, &g_Alloc);
return res;
@@ -177,7 +232,11 @@ static SRes PrintString(const UInt16 *s)
CBuf buf;
SRes res;
Buf_Init(&buf);
- res = Utf16_To_Char(&buf, s, 0);
+ res = Utf16_To_Char(&buf, s
+ #ifndef _USE_UTF8
+ , CP_OEMCP
+ #endif
+ );
if (res == SZ_OK)
fputs((const char *)buf.data, stdout);
Buf_Free(&buf, &g_Alloc);
@@ -216,17 +275,24 @@ static char *UIntToStr(char *s, unsigned value, int numDigits)
return s;
}
+static void UIntToStr_2(char *s, unsigned value)
+{
+ s[0] = (char)('0' + (value / 10));
+ s[1] = (char)('0' + (value % 10));
+}
+
#define PERIOD_4 (4 * 365 + 1)
#define PERIOD_100 (PERIOD_4 * 25 - 1)
#define PERIOD_400 (PERIOD_100 * 4 + 1)
-static void ConvertFileTimeToString(const CNtfsFileTime *ft, char *s)
+static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
{
- unsigned year, mon, day, hour, min, sec;
- UInt64 v64 = (ft->Low | ((UInt64)ft->High << 32)) / 10000000;
+ unsigned year, mon, hour, min, sec;
Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
unsigned t;
UInt32 v;
+ UInt64 v64 = nt->Low | ((UInt64)nt->High << 32);
+ v64 /= 10000000;
sec = (unsigned)(v64 % 60); v64 /= 60;
min = (unsigned)(v64 % 60); v64 /= 60;
hour = (unsigned)(v64 % 24); v64 /= 24;
@@ -242,20 +308,19 @@ static void ConvertFileTimeToString(const CNtfsFileTime *ft, char *s)
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
ms[1] = 29;
- for (mon = 1; mon <= 12; mon++)
+ for (mon = 0;; mon++)
{
- unsigned s = ms[mon - 1];
+ unsigned s = ms[mon];
if (v < s)
break;
v -= s;
}
- day = (unsigned)v + 1;
s = UIntToStr(s, year, 4); *s++ = '-';
- s = UIntToStr(s, mon, 2); *s++ = '-';
- s = UIntToStr(s, day, 2); *s++ = ' ';
- s = UIntToStr(s, hour, 2); *s++ = ':';
- s = UIntToStr(s, min, 2); *s++ = ':';
- s = UIntToStr(s, sec, 2);
+ UIntToStr_2(s, mon + 1); s[2] = '-'; s += 3;
+ UIntToStr_2(s, (unsigned)v + 1); s[2] = ' '; s += 3;
+ UIntToStr_2(s, hour); s[2] = ':'; s += 3;
+ UIntToStr_2(s, min); s[2] = ':'; s += 3;
+ UIntToStr_2(s, sec); s[2] = 0;
}
void PrintError(char *sz)
@@ -263,23 +328,22 @@ void PrintError(char *sz)
printf("\nERROR: %s\n", sz);
}
-#ifdef USE_WINDOWS_FILE
-#define kEmptyAttribChar '.'
static void GetAttribString(UInt32 wa, Bool isDir, char *s)
{
- s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : kEmptyAttribChar);
- s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar);
- s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar);
- s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar);
- s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar);
- s[5] = '\0';
-}
-#else
-static void GetAttribString(UInt32, Bool, char *s)
-{
- s[0] = '\0';
+ #ifdef USE_WINDOWS_FILE
+ s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : '.');
+ s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY ) != 0) ? 'R': '.');
+ s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN ) != 0) ? 'H': '.');
+ s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM ) != 0) ? 'S': '.');
+ s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE ) != 0) ? 'A': '.');
+ s[5] = 0;
+ #else
+ s[0] = (char)(((wa & (1 << 4)) != 0 || isDir) ? 'D' : '.');
+ s[1] = 0;
+ #endif
}
-#endif
+
+// #define NUM_PARENTS_MAX 128
int MY_CDECL main(int numargs, char *args[])
{
@@ -291,8 +355,10 @@ int MY_CDECL main(int numargs, char *args[])
ISzAlloc allocTempImp;
UInt16 *temp = NULL;
size_t tempSize = 0;
+ // UInt32 parents[NUM_PARENTS_MAX];
printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");
+
if (numargs == 1)
{
printf(
@@ -304,19 +370,28 @@ int MY_CDECL main(int numargs, char *args[])
" x: eXtract files with full paths\n");
return 0;
}
+
if (numargs < 3)
{
PrintError("incorrect command");
return 1;
}
+ #if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE)
+ g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ #endif
+
allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree;
allocTempImp.Alloc = SzAllocTemp;
allocTempImp.Free = SzFreeTemp;
+ #ifdef UNDER_CE
+ if (InFile_OpenW(&archiveStream.file, L"\test.7z"))
+ #else
if (InFile_Open(&archiveStream.file, args[2]))
+ #endif
{
PrintError("can not open input file");
return 1;
@@ -331,15 +406,18 @@ int MY_CDECL main(int numargs, char *args[])
CrcGenerateTable();
SzArEx_Init(&db);
+
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
+
if (res == SZ_OK)
{
char *command = args[1];
- int listCommand = 0, testCommand = 0, extractCommand = 0, fullPaths = 0;
+ int listCommand = 0, testCommand = 0, fullPaths = 0;
+
if (strcmp(command, "l") == 0) listCommand = 1;
else if (strcmp(command, "t") == 0) testCommand = 1;
- else if (strcmp(command, "e") == 0) extractCommand = 1;
- else if (strcmp(command, "x") == 0) { extractCommand = 1; fullPaths = 1; }
+ else if (strcmp(command, "e") == 0) { }
+ else if (strcmp(command, "x") == 0) { fullPaths = 1; }
else
{
PrintError("incorrect command");
@@ -358,22 +436,24 @@ int MY_CDECL main(int numargs, char *args[])
Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
- for (i = 0; i < db.db.NumFiles; i++)
+ for (i = 0; i < db.NumFiles; i++)
{
size_t offset = 0;
size_t outSizeProcessed = 0;
- const CSzFileItem *f = db.db.Files + i;
+ // const CSzFileItem *f = db.Files + i;
size_t len;
- if (listCommand == 0 && f->IsDir && !fullPaths)
+ unsigned isDir = SzArEx_IsDir(&db, i);
+ if (listCommand == 0 && isDir && !fullPaths)
continue;
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
+ // len = SzArEx_GetFullNameLen(&db, i);
if (len > tempSize)
{
SzFree(NULL, temp);
tempSize = len;
temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
- if (temp == 0)
+ if (!temp)
{
res = SZ_ERROR_MEM;
break;
@@ -381,15 +461,26 @@ int MY_CDECL main(int numargs, char *args[])
}
SzArEx_GetFileNameUtf16(&db, i, temp);
+ /*
+ if (SzArEx_GetFullNameUtf16_Back(&db, i, temp + len) != temp)
+ {
+ res = SZ_ERROR_FAIL;
+ break;
+ }
+ */
+
if (listCommand)
{
char attr[8], s[32], t[32];
+ UInt64 fileSize;
- GetAttribString(f->AttribDefined ? f->Attrib : 0, f->IsDir, attr);
+ GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr);
- UInt64ToStr(f->Size, s);
- if (f->MTimeDefined)
- ConvertFileTimeToString(&f->MTime, t);
+ fileSize = SzArEx_GetFileSize(&db, i);
+ UInt64ToStr(fileSize, s);
+
+ if (SzBitWithVals_Check(&db.MTime, i))
+ ConvertFileTimeToString(&db.MTime.Vals[i], t);
else
{
size_t j;
@@ -402,11 +493,12 @@ int MY_CDECL main(int numargs, char *args[])
res = PrintString(temp);
if (res != SZ_OK)
break;
- if (f->IsDir)
+ if (isDir)
printf("/");
printf("\n");
continue;
}
+
fputs(testCommand ?
"Testing ":
"Extracting ",
@@ -414,7 +506,8 @@ int MY_CDECL main(int numargs, char *args[])
res = PrintString(temp);
if (res != SZ_OK)
break;
- if (f->IsDir)
+
+ if (isDir)
printf("/");
else
{
@@ -425,6 +518,7 @@ int MY_CDECL main(int numargs, char *args[])
if (res != SZ_OK)
break;
}
+
if (!testCommand)
{
CSzFile outFile;
@@ -432,6 +526,7 @@ int MY_CDECL main(int numargs, char *args[])
size_t j;
UInt16 *name = (UInt16 *)temp;
const UInt16 *destPath = (const UInt16 *)name;
+
for (j = 0; name[j] != 0; j++)
if (name[j] == '/')
{
@@ -445,7 +540,7 @@ int MY_CDECL main(int numargs, char *args[])
destPath = name + j + 1;
}
- if (f->IsDir)
+ if (isDir)
{
MyCreateDir(destPath);
printf("\n");
@@ -457,22 +552,26 @@ int MY_CDECL main(int numargs, char *args[])
res = SZ_ERROR_FAIL;
break;
}
+
processedSize = outSizeProcessed;
+
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
{
PrintError("can not write output file");
res = SZ_ERROR_FAIL;
break;
}
+
if (File_Close(&outFile))
{
PrintError("can not close output file");
res = SZ_ERROR_FAIL;
break;
}
+
#ifdef USE_WINDOWS_FILE
- if (f->AttribDefined)
- SetFileAttributesW(destPath, f->Attrib);
+ if (SzBitWithVals_Check(&db.Attribs, i))
+ SetFileAttributesW(destPath, db.Attribs.Vals[i]);
#endif
}
printf("\n");
@@ -480,15 +579,18 @@ int MY_CDECL main(int numargs, char *args[])
IAlloc_Free(&allocImp, outBuffer);
}
}
+
SzArEx_Free(&db, &allocImp);
SzFree(NULL, temp);
File_Close(&archiveStream.file);
+
if (res == SZ_OK)
{
printf("\nEverything is Ok\n");
return 0;
}
+
if (res == SZ_ERROR_UNSUPPORTED)
PrintError("decoder doesn't support this archive");
else if (res == SZ_ERROR_MEM)
@@ -497,5 +599,6 @@ int MY_CDECL main(int numargs, char *args[])
PrintError("CRC error");
else
printf("\nERROR #%d\n", res);
+
return 1;
}
diff --git a/3rdparty/lzma/C/Util/7z/Precomp.c b/3rdparty/lzma/C/Util/7z/Precomp.c
new file mode 100644
index 00000000000..01605e3c261
--- /dev/null
+++ b/3rdparty/lzma/C/Util/7z/Precomp.c
@@ -0,0 +1,4 @@
+/* Precomp.c -- StdAfx
+2013-01-21 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
diff --git a/3rdparty/lzma/C/Util/7z/Precomp.h b/3rdparty/lzma/C/Util/7z/Precomp.h
new file mode 100644
index 00000000000..588a66f7eb8
--- /dev/null
+++ b/3rdparty/lzma/C/Util/7z/Precomp.h
@@ -0,0 +1,10 @@
+/* Precomp.h -- StdAfx
+2013-06-16 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_PRECOMP_H
+#define __7Z_PRECOMP_H
+
+#include "../../Compiler.h"
+#include "../../7zTypes.h"
+
+#endif
diff --git a/3rdparty/lzma/C/Util/7z/makefile b/3rdparty/lzma/C/Util/7z/makefile
index 96edda42039..9a49fd515a6 100644
--- a/3rdparty/lzma/C/Util/7z/makefile
+++ b/3rdparty/lzma/C/Util/7z/makefile
@@ -1,4 +1,3 @@
-MY_STATIC_LINK=1
CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT
PROG = 7zDec.exe
@@ -6,17 +5,18 @@ PROG = 7zDec.exe
C_OBJS = \
$O\7zAlloc.obj \
$O\7zBuf.obj \
- $O\7zBuf2.obj \
$O\7zCrc.obj \
$O\7zCrcOpt.obj \
$O\7zFile.obj \
$O\7zDec.obj \
- $O\7zIn.obj \
+ $O\7zArcIn.obj \
$O\7zStream.obj \
$O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
+ $O\BraIA64.obj \
$O\CpuArch.obj \
+ $O\Delta.obj \
$O\Lzma2Dec.obj \
$O\LzmaDec.obj \
$O\Ppmd7.obj \
@@ -26,12 +26,15 @@ C_OBJS = \
$O\7zMain.obj \
OBJS = \
+ $O\Precomp.obj \
$(7Z_OBJS) \
$(C_OBJS) \
!include "../../../CPP/Build.mak"
$(7Z_OBJS): $(*B).c
- $(COMPL_O1)
+ $(CCOMPL_USE)
$(C_OBJS): ../../$(*B).c
- $(COMPL_O2)
+ $(CCOMPL_USE)
+$O\Precomp.obj: Precomp.c
+ $(CCOMPL_PCH)
diff --git a/3rdparty/lzma/C/Util/7z/makefile.gcc b/3rdparty/lzma/C/Util/7z/makefile.gcc
index 364c6474a1c..51053bad65c 100644
--- a/3rdparty/lzma/C/Util/7z/makefile.gcc
+++ b/3rdparty/lzma/C/Util/7z/makefile.gcc
@@ -1,10 +1,10 @@
PROG = 7zDec
-CXX = g++
+CXX = gcc
LIB =
RM = rm -f
CFLAGS = -c -O2 -Wall
-OBJS = 7zMain.o 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o 7zIn.o CpuArch.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
+OBJS = 7zMain.o 7zAlloc.o 7zArcIn.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o CpuArch.o Delta.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o BraIA64.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
all: $(PROG)
@@ -14,9 +14,12 @@ $(PROG): $(OBJS)
7zMain.o: 7zMain.c
$(CXX) $(CFLAGS) 7zMain.c
-7zAlloc.o: 7zAlloc.c
+7zAlloc.o: ../../7zAlloc.c
$(CXX) $(CFLAGS) ../../7zAlloc.c
+7zArcIn.o: ../../7zArcIn.c
+ $(CXX) $(CFLAGS) ../../7zArcIn.c
+
7zBuf.o: ../../7zBuf.c
$(CXX) $(CFLAGS) ../../7zBuf.c
@@ -32,12 +35,12 @@ $(PROG): $(OBJS)
7zDec.o: ../../7zDec.c
$(CXX) $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT ../../7zDec.c
-7zIn.o: ../../7zIn.c
- $(CXX) $(CFLAGS) ../../7zIn.c
-
CpuArch.o: ../../CpuArch.c
$(CXX) $(CFLAGS) ../../CpuArch.c
+Delta.o: ../../Delta.c
+ $(CXX) $(CFLAGS) ../../Delta.c
+
LzmaDec.o: ../../LzmaDec.c
$(CXX) $(CFLAGS) ../../LzmaDec.c
@@ -50,6 +53,9 @@ Bra.o: ../../Bra.c
Bra86.o: ../../Bra86.c
$(CXX) $(CFLAGS) ../../Bra86.c
+BraIA64.o: ../../BraIA64.c
+ $(CXX) $(CFLAGS) ../../BraIA64.c
+
Bcj2.o: ../../Bcj2.c
$(CXX) $(CFLAGS) ../../Bcj2.c
@@ -67,4 +73,3 @@ Ppmd7Dec.o: ../../Ppmd7Dec.c
clean:
-$(RM) $(PROG) $(OBJS)
-
diff --git a/3rdparty/lzma/C/Util/Lzma/LzmaUtil.c b/3rdparty/lzma/C/Util/Lzma/LzmaUtil.c
index 09a749afad7..e5857ceff09 100644
--- a/3rdparty/lzma/C/Util/Lzma/LzmaUtil.c
+++ b/3rdparty/lzma/C/Util/Lzma/LzmaUtil.c
@@ -1,7 +1,7 @@
/* LzmaUtil.c -- Test application for LZMA compression
-2010-09-20 : Igor Pavlov : Public domain */
+2015-11-08 : Igor Pavlov : Public domain */
-#define _CRT_SECURE_NO_WARNINGS
+#include "../../Precomp.h"
#include <stdio.h>
#include <stdlib.h>
@@ -18,10 +18,6 @@ const char *kCantWriteMessage = "Can not write output file";
const char *kCantAllocateMessage = "Can not allocate memory";
const char *kDataErrorMessage = "Data error";
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
void PrintHelp(char *buffer)
{
strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"
@@ -92,7 +88,7 @@ static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inS
outPos = 0;
- if (res != SZ_OK || thereIsSize && unpackSize == 0)
+ if (res != SZ_OK || (thereIsSize && unpackSize == 0))
return res;
if (inProcessed == 0 && outProcessed == 0)
@@ -137,7 +133,7 @@ static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 file
SRes res;
CLzmaEncProps props;
- rs = rs;
+ UNUSED_VAR(rs);
enc = LzmaEnc_Create(&g_Alloc);
if (enc == 0)
diff --git a/3rdparty/lzma/C/Util/Lzma/LzmaUtil.dsp b/3rdparty/lzma/C/Util/Lzma/LzmaUtil.dsp
index d10af8b41d3..43b8e176b22 100644
--- a/3rdparty/lzma/C/Util/Lzma/LzmaUtil.dsp
+++ b/3rdparty/lzma/C/Util/Lzma/LzmaUtil.dsp
@@ -42,7 +42,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 /MT /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
+# ADD CPP /nologo /MT /W4 /WX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
@@ -67,7 +67,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 /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c
+# ADD CPP /nologo /MTd /W4 /WX /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
diff --git a/3rdparty/lzma/C/Util/Lzma/makefile b/3rdparty/lzma/C/Util/Lzma/makefile
index afac07161bf..4795322786b 100644
--- a/3rdparty/lzma/C/Util/Lzma/makefile
+++ b/3rdparty/lzma/C/Util/Lzma/makefile
@@ -1,4 +1,4 @@
-MY_STATIC_LINK=1
+# MY_STATIC_LINK=1
PROG = LZMAc.exe
CFLAGS = $(CFLAGS) \
diff --git a/3rdparty/lzma/C/Util/LzmaLib/LzmaLib.dsp b/3rdparty/lzma/C/Util/LzmaLib/LzmaLib.dsp
index 7d8d386fcad..3421de83a1d 100644
--- a/3rdparty/lzma/C/Util/LzmaLib/LzmaLib.dsp
+++ b/3rdparty/lzma/C/Util/LzmaLib/LzmaLib.dsp
@@ -104,6 +104,10 @@ SOURCE=.\LzmaLibExports.c
# End Group
# Begin Source File
+SOURCE=..\..\7zTypes.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Alloc.c
# End Source File
# Begin Source File
@@ -170,9 +174,5 @@ SOURCE=..\..\Threads.c
SOURCE=..\..\Threads.h
# End Source File
-# Begin Source File
-
-SOURCE=..\..\Types.h
-# End Source File
# End Target
# End Project
diff --git a/3rdparty/lzma/C/Util/LzmaLib/LzmaLibExports.c b/3rdparty/lzma/C/Util/LzmaLib/LzmaLibExports.c
index 845545db9a9..4a28a9a6b34 100644
--- a/3rdparty/lzma/C/Util/LzmaLib/LzmaLibExports.c
+++ b/3rdparty/lzma/C/Util/LzmaLib/LzmaLibExports.c
@@ -1,12 +1,14 @@
/* LzmaLibExports.c -- LZMA library DLL Entry point
-2008-10-04 : Igor Pavlov : Public domain */
+2015-11-08 : Igor Pavlov : Public domain */
+
+#include "../../Precomp.h"
#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
- hInstance = hInstance;
- dwReason = dwReason;
- lpReserved = lpReserved;
+ UNUSED_VAR(hInstance);
+ UNUSED_VAR(dwReason);
+ UNUSED_VAR(lpReserved);
return TRUE;
}
diff --git a/3rdparty/lzma/C/Util/SfxSetup/Precomp.c b/3rdparty/lzma/C/Util/SfxSetup/Precomp.c
new file mode 100644
index 00000000000..01605e3c261
--- /dev/null
+++ b/3rdparty/lzma/C/Util/SfxSetup/Precomp.c
@@ -0,0 +1,4 @@
+/* Precomp.c -- StdAfx
+2013-01-21 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
diff --git a/3rdparty/lzma/C/Util/SfxSetup/Precomp.h b/3rdparty/lzma/C/Util/SfxSetup/Precomp.h
new file mode 100644
index 00000000000..588a66f7eb8
--- /dev/null
+++ b/3rdparty/lzma/C/Util/SfxSetup/Precomp.h
@@ -0,0 +1,10 @@
+/* Precomp.h -- StdAfx
+2013-06-16 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_PRECOMP_H
+#define __7Z_PRECOMP_H
+
+#include "../../Compiler.h"
+#include "../../7zTypes.h"
+
+#endif
diff --git a/3rdparty/lzma/C/Util/SfxSetup/SfxSetup.c b/3rdparty/lzma/C/Util/SfxSetup/SfxSetup.c
index c3c56b1e7f2..0e5152e5907 100644
--- a/3rdparty/lzma/C/Util/SfxSetup/SfxSetup.c
+++ b/3rdparty/lzma/C/Util/SfxSetup/SfxSetup.c
@@ -1,5 +1,7 @@
/* SfxSetup.c - 7z SFX Setup
-2010-12-13 : Igor Pavlov : Public domain */
+2015-11-08 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#ifndef UNICODE
#define UNICODE
@@ -19,28 +21,28 @@
#include "../../7zFile.h"
#include "../../CpuArch.h"
-#define k_EXE_ExtIndex 1
+#define k_EXE_ExtIndex 2
-static const char *kExts[] =
+static const char * const kExts[] =
{
- "bat",
- "cmd",
- "exe",
- "inf",
- "msi",
+ "bat"
+ , "cmd"
+ , "exe"
+ , "inf"
+ , "msi"
#ifdef UNDER_CE
- "cab",
+ , "cab"
#endif
- "html",
- "htm"
+ , "html"
+ , "htm"
};
-static const char *kNames[] =
+static const char * const kNames[] =
{
- "setup",
- "install",
- "run",
- "start"
+ "setup"
+ , "install"
+ , "run"
+ , "start"
};
static unsigned FindExt(const wchar_t *s, unsigned *extLen)
@@ -61,7 +63,7 @@ static unsigned FindExt(const wchar_t *s, unsigned *extLen)
#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c)))
-static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, unsigned len)
+static unsigned FindItem(const char * const *items, unsigned num, const wchar_t *s, unsigned len)
{
unsigned i;
for (i = 0; i < num; i++)
@@ -73,7 +75,7 @@ static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, uns
continue;
for (j = 0; j < len; j++)
{
- unsigned c = item[j];
+ unsigned c = (Byte)item[j];
if (c != s[j] && MAKE_CHAR_UPPER(c) != s[j])
break;
}
@@ -86,7 +88,7 @@ static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, uns
#ifdef _CONSOLE
static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
{
- ctrlType = ctrlType;
+ UNUSED_VAR(ctrlType);
return TRUE;
}
#endif
@@ -142,7 +144,7 @@ static Bool FindSignature(CSzFile *stream, UInt64 *resPos)
processed -= k7zStartHeaderSize;
for (pos = 0; pos <= processed; pos++)
{
- for (; buf[pos] != '7' && pos <= processed; pos++);
+ for (; pos <= processed && buf[pos] != '7'; pos++);
if (pos > processed)
break;
if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
@@ -180,6 +182,7 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
path[len] = L'\0';
if (handle == INVALID_HANDLE_VALUE)
return GetLastError();
+
for (;;)
{
if (wcscmp(fd.cFileName, L".") != 0 &&
@@ -188,7 +191,7 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
wcscpy(path + len, fd.cFileName);
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
{
- wcscat(path, L"\\");
+ wcscat(path, WSTRING_PATH_SEPARATOR);
res = RemoveDirWithSubItems(path);
}
else
@@ -197,9 +200,11 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
if (DeleteFileW(path) == 0)
res = GetLastError();
}
+
if (res != 0)
break;
}
+
if (!FindNextFileW(handle, &fd))
{
res = GetLastError();
@@ -208,6 +213,7 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
break;
}
}
+
path[len] = L'\0';
FindClose(handle);
if (res == 0)
@@ -238,19 +244,23 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
ISzAlloc allocTempImp;
WCHAR sfxPath[MAX_PATH + 2];
WCHAR path[MAX_PATH * 3 + 2];
+ #ifndef UNDER_CE
+ WCHAR workCurDir[MAX_PATH + 32];
+ #endif
size_t pathLen;
DWORD winRes;
const wchar_t *cmdLineParams;
const char *errorMessage = NULL;
Bool useShellExecute = True;
+ DWORD exitCode = 0;
#ifdef _CONSOLE
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
#else
- hInstance = hInstance;
- hPrevInstance = hPrevInstance;
- lpCmdLine = lpCmdLine;
- nCmdShow = nCmdShow;
+ UNUSED_VAR(hInstance);
+ UNUSED_VAR(hPrevInstance);
+ UNUSED_VAR(lpCmdLine);
+ UNUSED_VAR(nCmdShow);
#endif
CrcGenerateTable();
@@ -292,6 +302,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
return 1;
pathLen = wcslen(path);
d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
+
for (i = 0;; i++, d += GetTickCount())
{
if (i >= 100)
@@ -309,7 +320,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
{
unsigned t = value & 0xF;
value >>= 4;
- s[7 - k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
s[k] = '\0';
}
@@ -318,7 +329,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
continue;
if (CreateDirectoryW(path, NULL))
{
- wcscat(path, L"\\");
+ wcscat(path, WSTRING_PATH_SEPARATOR);
pathLen = wcslen(path);
break;
}
@@ -328,6 +339,10 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
break;
}
}
+
+ #ifndef UNDER_CE
+ wcscpy(workCurDir, path);
+ #endif
if (res != SZ_OK)
errorMessage = "Can't create temp folder";
}
@@ -367,6 +382,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
{
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
}
+
if (res == SZ_OK)
{
UInt32 executeFileIndex = (UInt32)(Int32)-1;
@@ -376,11 +392,10 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
- for (i = 0; i < db.db.NumFiles; i++)
+ for (i = 0; i < db.NumFiles; i++)
{
size_t offset = 0;
size_t outSizeProcessed = 0;
- const CSzFileItem *f = db.db.Files + i;
size_t len;
WCHAR *temp;
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
@@ -418,7 +433,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
}
}
- if (f->IsDir)
+ if (SzArEx_IsDir(&db, i))
{
MyCreateDir(path);
continue;
@@ -453,6 +468,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
break;
}
}
+
processedSize = outSizeProcessed;
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
{
@@ -461,11 +477,12 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
}
#ifdef USE_WINDOWS_FILE
- if (f->MTimeDefined)
+ if (SzBitWithVals_Check(&db.MTime, i))
{
+ const CNtfsFileTime *t = db.MTime.Vals + i;
FILETIME mTime;
- mTime.dwLowDateTime = f->MTime.Low;
- mTime.dwHighDateTime = f->MTime.High;
+ mTime.dwLowDateTime = t->Low;
+ mTime.dwHighDateTime = t->High;
SetFileTime(outFile.handle, NULL, NULL, &mTime);
}
#endif
@@ -481,8 +498,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
}
}
#ifdef USE_WINDOWS_FILE
- if (f->AttribDefined)
- SetFileAttributesW(path, f->Attrib);
+ if (SzBitWithVals_Check(&db.Attribs, i))
+ SetFileAttributesW(path, db.Attribs.Vals[i]);
#endif
}
}
@@ -513,6 +530,18 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
if (res == SZ_OK)
{
HANDLE hProcess = 0;
+
+ #ifndef UNDER_CE
+ WCHAR oldCurDir[MAX_PATH + 2];
+ oldCurDir[0] = 0;
+ {
+ DWORD needLen = GetCurrentDirectory(MAX_PATH + 1, oldCurDir);
+ if (needLen == 0 || needLen > MAX_PATH)
+ oldCurDir[0] = 0;
+ SetCurrentDirectory(workCurDir);
+ }
+ #endif
+
if (useShellExecute)
{
SHELLEXECUTEINFO ei;
@@ -556,18 +585,25 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
hProcess = pi.hProcess;
}
}
+
if (hProcess != 0)
{
WaitForSingleObject(hProcess, INFINITE);
+ if (!GetExitCodeProcess(hProcess, &exitCode))
+ exitCode = 1;
CloseHandle(hProcess);
}
+
+ #ifndef UNDER_CE
+ SetCurrentDirectory(oldCurDir);
+ #endif
}
path[pathLen] = L'\0';
RemoveDirWithSubItems(path);
if (res == SZ_OK)
- return 0;
+ return (int)exitCode;
{
if (res == SZ_ERROR_UNSUPPORTED)
@@ -581,6 +617,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
if (!errorMessage)
errorMessage = "ERROR";
}
+
if (errorMessage)
PrintErrorMessage(errorMessage);
}
diff --git a/3rdparty/lzma/C/Util/SfxSetup/SfxSetup.dsp b/3rdparty/lzma/C/Util/SfxSetup/SfxSetup.dsp
index 39f876d4e23..50e012f03ac 100644
--- a/3rdparty/lzma/C/Util/SfxSetup/SfxSetup.dsp
+++ b/3rdparty/lzma/C/Util/SfxSetup/SfxSetup.dsp
@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /YX /FD /c
+# ADD CPP /nologo /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /Yu"Precomp.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
@@ -68,7 +68,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 "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c
+# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /Yu"Precomp.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG"
@@ -103,6 +103,10 @@ SOURCE=..\..\7zAlloc.h
# End Source File
# Begin Source File
+SOURCE=..\..\7zArcIn.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\7zBuf.c
# End Source File
# Begin Source File
@@ -135,11 +139,11 @@ SOURCE=..\..\7zFile.h
# End Source File
# Begin Source File
-SOURCE=..\..\7zIn.c
+SOURCE=..\..\7zStream.c
# End Source File
# Begin Source File
-SOURCE=..\..\7zStream.c
+SOURCE=..\..\7zTypes.h
# End Source File
# Begin Source File
@@ -163,6 +167,10 @@ SOURCE=..\..\Bra86.c
# End Source File
# Begin Source File
+SOURCE=..\..\BraIA64.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\CpuArch.c
# End Source File
# Begin Source File
@@ -171,6 +179,14 @@ SOURCE=..\..\CpuArch.h
# End Source File
# Begin Source File
+SOURCE=..\..\Delta.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Delta.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Lzma2Dec.c
# End Source File
# Begin Source File
@@ -185,9 +201,18 @@ SOURCE=..\..\LzmaDec.c
SOURCE=..\..\LzmaDec.h
# End Source File
+# End Group
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Precomp.c
+# ADD CPP /Yc"Precomp.h"
+# End Source File
# Begin Source File
-SOURCE=..\..\Types.h
+SOURCE=.\Precomp.h
# End Source File
# End Group
# Begin Source File
diff --git a/3rdparty/lzma/C/Util/SfxSetup/makefile b/3rdparty/lzma/C/Util/SfxSetup/makefile
index ce1fbc9d639..b294479305b 100644
--- a/3rdparty/lzma/C/Util/SfxSetup/makefile
+++ b/3rdparty/lzma/C/Util/SfxSetup/makefile
@@ -1,21 +1,21 @@
PROG = 7zS2.sfx
-LIBS = $(LIBS)
-CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_WARNINGS
C_OBJS = \
$O\7zAlloc.obj \
+ $O\7zArcIn.obj \
$O\7zBuf.obj \
$O\7zBuf2.obj \
$O\7zCrc.obj \
$O\7zCrcOpt.obj \
$O\7zFile.obj \
$O\7zDec.obj \
- $O\7zIn.obj \
$O\7zStream.obj \
$O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
+ $O\BraIA64.obj \
$O\CpuArch.obj \
+ $O\Delta.obj \
$O\Lzma2Dec.obj \
$O\LzmaDec.obj \
diff --git a/3rdparty/lzma/C/Util/SfxSetup/makefile_con b/3rdparty/lzma/C/Util/SfxSetup/makefile_con
index 8e1a050d8af..7a96fd36a7c 100644
--- a/3rdparty/lzma/C/Util/SfxSetup/makefile_con
+++ b/3rdparty/lzma/C/Util/SfxSetup/makefile_con
@@ -1,21 +1,22 @@
PROG = 7zS2con.sfx
-LIBS = $(LIBS)
-CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE -D_CONSOLE
+CFLAGS = $(CFLAGS) -D_CONSOLE
C_OBJS = \
$O\7zAlloc.obj \
+ $O\7zArcIn.obj \
$O\7zBuf.obj \
$O\7zBuf2.obj \
$O\7zCrc.obj \
$O\7zCrcOpt.obj \
$O\7zFile.obj \
$O\7zDec.obj \
- $O\7zIn.obj \
$O\7zStream.obj \
$O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
+ $O\BraIA64.obj \
$O\CpuArch.obj \
+ $O\Delta.obj \
$O\Lzma2Dec.obj \
$O\LzmaDec.obj \
diff --git a/3rdparty/lzma/C/Xz.c b/3rdparty/lzma/C/Xz.c
index 18caba2c15b..1ef6878252c 100644
--- a/3rdparty/lzma/C/Xz.c
+++ b/3rdparty/lzma/C/Xz.c
@@ -1,13 +1,15 @@
/* Xz.c - Xz
-2009-04-15 : Igor Pavlov : Public domain */
+2015-05-01 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "7zCrc.h"
#include "CpuArch.h"
#include "Xz.h"
#include "XzCrc64.h"
-Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 };
-Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' };
+const Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 };
+const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' };
unsigned Xz_WriteVarInt(Byte *buf, UInt64 v)
{
@@ -38,11 +40,11 @@ void Xz_Free(CXzStream *p, ISzAlloc *alloc)
unsigned XzFlags_GetCheckSize(CXzStreamFlags f)
{
- int t = XzFlags_GetCheckType(f);
+ unsigned t = XzFlags_GetCheckType(f);
return (t == 0) ? 0 : (4 << ((t - 1) / 3));
}
-void XzCheck_Init(CXzCheck *p, int mode)
+void XzCheck_Init(CXzCheck *p, unsigned mode)
{
p->mode = mode;
switch (mode)
diff --git a/3rdparty/lzma/C/Xz.h b/3rdparty/lzma/C/Xz.h
index 0f7a822c37e..be3a1c36220 100644
--- a/3rdparty/lzma/C/Xz.h
+++ b/3rdparty/lzma/C/Xz.h
@@ -1,5 +1,5 @@
/* Xz.h - Xz interface
-2011-01-09 : Igor Pavlov : Public domain */
+2015-05-01 : Igor Pavlov : Public domain */
#ifndef __XZ_H
#define __XZ_H
@@ -59,8 +59,8 @@ SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt
#define XZ_SIG_SIZE 6
#define XZ_FOOTER_SIG_SIZE 2
-extern Byte XZ_SIG[XZ_SIG_SIZE];
-extern Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
+extern const Byte XZ_SIG[XZ_SIG_SIZE];
+extern const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
#define XZ_STREAM_FLAGS_SIZE 2
#define XZ_STREAM_CRC_SIZE 4
@@ -76,13 +76,13 @@ extern Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
typedef struct
{
- int mode;
+ unsigned mode;
UInt32 crc;
UInt64 crc64;
CSha256 sha;
} CXzCheck;
-void XzCheck_Init(CXzCheck *p, int mode);
+void XzCheck_Init(CXzCheck *p, unsigned mode);
void XzCheck_Update(CXzCheck *p, const void *data, size_t size);
int XzCheck_Final(CXzCheck *p, Byte *digest);
@@ -163,7 +163,7 @@ typedef struct
{
ISzAlloc *alloc;
Byte *buf;
- int numCoders;
+ unsigned numCoders;
int finished[MIXCODER_NUM_FILTERS_MAX - 1];
size_t pos[MIXCODER_NUM_FILTERS_MAX - 1];
size_t size[MIXCODER_NUM_FILTERS_MAX - 1];
@@ -174,7 +174,7 @@ typedef struct
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc);
void MixCoder_Free(CMixCoder *p);
void MixCoder_Init(CMixCoder *p);
-SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId);
+SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId);
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, int srcWasFinished,
ECoderFinishMode finishMode, ECoderStatus *status);
@@ -209,7 +209,9 @@ typedef struct
UInt64 indexPos;
UInt64 padSize;
- UInt64 numStreams;
+ UInt64 numStartedStreams;
+ UInt64 numFinishedStreams;
+ UInt64 numTotalBlocks;
UInt32 crc;
CMixCoder decoder;
@@ -227,8 +229,8 @@ void XzUnpacker_Free(CXzUnpacker *p);
/*
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
- LZMA_FINISH_ANY - use smallest number of input bytes
- LZMA_FINISH_END - read EndOfStream marker after decoding
+ CODER_FINISH_ANY - use smallest number of input bytes
+ CODER_FINISH_END - read EndOfStream marker after decoding
Returns:
SZ_OK
@@ -236,19 +238,38 @@ Returns:
CODER_STATUS_NOT_FINISHED,
CODER_STATUS_NEEDS_MORE_INPUT - maybe there are more xz streams,
call XzUnpacker_IsStreamWasFinished to check that current stream was finished
- SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_UNSUPPORTED - Unsupported properties
- SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+ SZ_ERROR_DATA - Data error
+ SZ_ERROR_UNSUPPORTED - Unsupported method or method properties
+ SZ_ERROR_CRC - CRC error
+ // SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+
+ SZ_ERROR_NO_ARCHIVE - the error with xz Stream Header with one of the following reasons:
+ - xz Stream Signature failure
+ - CRC32 of xz Stream Header is failed
+ - The size of Stream padding is not multiple of four bytes.
+ It's possible to get that error, if xz stream was finished and the stream
+ contains some another data. In that case you can call XzUnpacker_GetExtraSize()
+ function to get real size of xz stream.
*/
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
- const Byte *src, SizeT *srcLen, /* int srcWasFinished, */ int finishMode,
+ const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode,
ECoderStatus *status);
Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p);
+/*
+Call XzUnpacker_GetExtraSize after XzUnpacker_Code function to detect real size of
+xz stream in two cases:
+XzUnpacker_Code() returns:
+ res == SZ_OK && status == CODER_STATUS_NEEDS_MORE_INPUT
+ res == SZ_ERROR_NO_ARCHIVE
+*/
+
+UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p);
+
EXTERN_C_END
#endif
diff --git a/3rdparty/lzma/C/XzCrc64.c b/3rdparty/lzma/C/XzCrc64.c
index 0369554b736..e2da63b6ebe 100644
--- a/3rdparty/lzma/C/XzCrc64.c
+++ b/3rdparty/lzma/C/XzCrc64.c
@@ -1,33 +1,86 @@
/* XzCrc64.c -- CRC64 calculation
-2010-04-16 : Igor Pavlov : Public domain */
+2015-03-01 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "XzCrc64.h"
+#include "CpuArch.h"
#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42)
-UInt64 g_Crc64Table[256];
-void MY_FAST_CALL Crc64GenerateTable(void)
+#ifdef MY_CPU_LE
+ #define CRC_NUM_TABLES 4
+#else
+ #define CRC_NUM_TABLES 5
+ #define CRC_UINT64_SWAP(v) \
+ ((v >> 56) \
+ | ((v >> 40) & ((UInt64)0xFF << 8)) \
+ | ((v >> 24) & ((UInt64)0xFF << 16)) \
+ | ((v >> 8) & ((UInt64)0xFF << 24)) \
+ | ((v << 8) & ((UInt64)0xFF << 32)) \
+ | ((v << 24) & ((UInt64)0xFF << 40)) \
+ | ((v << 40) & ((UInt64)0xFF << 48)) \
+ | ((v << 56)))
+
+ UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
+#endif
+
+#ifndef MY_CPU_BE
+ UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
+#endif
+
+typedef UInt64 (MY_FAST_CALL *CRC_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table);
+
+static CRC_FUNC g_Crc64Update;
+UInt64 g_Crc64Table[256 * CRC_NUM_TABLES];
+
+UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size)
+{
+ return g_Crc64Update(v, data, size, g_Crc64Table);
+}
+
+UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size)
+{
+ return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL;
+}
+
+void MY_FAST_CALL Crc64GenerateTable()
{
UInt32 i;
for (i = 0; i < 256; i++)
{
UInt64 r = i;
- int j;
+ unsigned j;
for (j = 0; j < 8; j++)
- r = (r >> 1) ^ ((UInt64)kCrc64Poly & ~((r & 1) - 1));
+ r = (r >> 1) ^ (kCrc64Poly & ~((r & 1) - 1));
g_Crc64Table[i] = r;
}
-}
+ for (; i < 256 * CRC_NUM_TABLES; i++)
+ {
+ UInt64 r = g_Crc64Table[i - 256];
+ g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8);
+ }
+
+ #ifdef MY_CPU_LE
-UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size)
-{
- const Byte *p = (const Byte *)data;
- for (; size > 0 ; size--, p++)
- v = CRC64_UPDATE_BYTE(v, *p);
- return v;
-}
+ g_Crc64Update = XzCrc64UpdateT4;
-UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size)
-{
- return CRC64_GET_DIGEST(Crc64Update(CRC64_INIT_VAL, data, size));
+ #else
+ {
+ #ifndef MY_CPU_BE
+ UInt32 k = 1;
+ if (*(const Byte *)&k == 1)
+ g_Crc64Update = XzCrc64UpdateT4;
+ else
+ #endif
+ {
+ for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
+ {
+ UInt64 x = g_Crc64Table[i - 256];
+ g_Crc64Table[i] = CRC_UINT64_SWAP(x);
+ }
+ g_Crc64Update = XzCrc64UpdateT1_BeT4;
+ }
+ }
+ #endif
}
diff --git a/3rdparty/lzma/C/XzCrc64.h b/3rdparty/lzma/C/XzCrc64.h
index 0e8efd7ea67..08dbc330c27 100644
--- a/3rdparty/lzma/C/XzCrc64.h
+++ b/3rdparty/lzma/C/XzCrc64.h
@@ -1,12 +1,12 @@
/* XzCrc64.h -- CRC64 calculation
-2010-04-16 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __XZ_CRC64_H
#define __XZ_CRC64_H
#include <stddef.h>
-#include "Types.h"
+#include "7zTypes.h"
EXTERN_C_BEGIN
diff --git a/3rdparty/lzma/C/XzCrc64Opt.c b/3rdparty/lzma/C/XzCrc64Opt.c
new file mode 100644
index 00000000000..c4fde65a10b
--- /dev/null
+++ b/3rdparty/lzma/C/XzCrc64Opt.c
@@ -0,0 +1,69 @@
+/* XzCrc64Opt.c -- CRC64 calculation
+2015-03-01 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "CpuArch.h"
+
+#ifndef MY_CPU_BE
+
+#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+
+UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
+{
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ for (; size >= 4; size -= 4, p += 4)
+ {
+ UInt32 d = (UInt32)v ^ *(const UInt32 *)p;
+ v = (v >> 32)
+ ^ table[0x300 + ((d ) & 0xFF)]
+ ^ table[0x200 + ((d >> 8) & 0xFF)]
+ ^ table[0x100 + ((d >> 16) & 0xFF)]
+ ^ table[0x000 + ((d >> 24))];
+ }
+ for (; size > 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ return v;
+}
+
+#endif
+
+
+#ifndef MY_CPU_LE
+
+#define CRC_UINT64_SWAP(v) \
+ ((v >> 56) \
+ | ((v >> 40) & ((UInt64)0xFF << 8)) \
+ | ((v >> 24) & ((UInt64)0xFF << 16)) \
+ | ((v >> 8) & ((UInt64)0xFF << 24)) \
+ | ((v << 8) & ((UInt64)0xFF << 32)) \
+ | ((v << 24) & ((UInt64)0xFF << 40)) \
+ | ((v << 40) & ((UInt64)0xFF << 48)) \
+ | ((v << 56)))
+
+#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(Byte)((crc) >> 56) ^ (b)] ^ ((crc) << 8))
+
+UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
+{
+ const Byte *p = (const Byte *)data;
+ table += 0x100;
+ v = CRC_UINT64_SWAP(v);
+ for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2_BE(v, *p);
+ for (; size >= 4; size -= 4, p += 4)
+ {
+ UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)p;
+ v = (v << 32)
+ ^ table[0x000 + ((d ) & 0xFF)]
+ ^ table[0x100 + ((d >> 8) & 0xFF)]
+ ^ table[0x200 + ((d >> 16) & 0xFF)]
+ ^ table[0x300 + ((d >> 24))];
+ }
+ for (; size > 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2_BE(v, *p);
+ return CRC_UINT64_SWAP(v);
+}
+
+#endif
diff --git a/3rdparty/lzma/C/XzDec.c b/3rdparty/lzma/C/XzDec.c
index 113e2cdf0f0..1edc0245637 100644
--- a/3rdparty/lzma/C/XzDec.c
+++ b/3rdparty/lzma/C/XzDec.c
@@ -1,5 +1,7 @@
/* XzDec.c -- Xz Decode
-2011-02-07 : Igor Pavlov : Public domain */
+2015-11-09 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
/* #define XZ_DUMP */
@@ -30,9 +32,9 @@
unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
{
- int i, limit;
+ unsigned i, limit;
*value = 0;
- limit = (maxSize > 9) ? 9 : (int)maxSize;
+ limit = (maxSize > 9) ? 9 : (unsigned)maxSize;
for (i = 0; i < limit;)
{
@@ -64,15 +66,15 @@ typedef struct
Byte buf[BRA_BUF_SIZE];
} CBraState;
-void BraState_Free(void *pp, ISzAlloc *alloc)
+static void BraState_Free(void *pp, ISzAlloc *alloc)
{
alloc->Free(alloc, pp);
}
-SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
+static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
{
CBraState *p = ((CBraState *)pp);
- alloc = alloc;
+ UNUSED_VAR(alloc);
p->ip = 0;
if (p->methodId == XZ_ID_Delta)
{
@@ -85,7 +87,7 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a
if (propSize == 4)
{
UInt32 v = GetUi32(props);
- switch(p->methodId)
+ switch (p->methodId)
{
case XZ_ID_PPC:
case XZ_ID_ARM:
@@ -110,7 +112,7 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a
return SZ_OK;
}
-void BraState_Init(void *pp)
+static void BraState_Init(void *pp)
{
CBraState *p = ((CBraState *)pp);
p->bufPos = p->bufConv = p->bufTotal = 0;
@@ -127,9 +129,9 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
CBraState *p = ((CBraState *)pp);
SizeT destLenOrig = *destLen;
SizeT srcLenOrig = *srcLen;
+ UNUSED_VAR(finishMode);
*destLen = 0;
*srcLen = 0;
- finishMode = finishMode;
*wasFinished = 0;
while (destLenOrig > 0)
{
@@ -161,7 +163,7 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
}
if (p->bufTotal == 0)
break;
- switch(p->methodId)
+ switch (p->methodId)
{
case XZ_ID_Delta:
if (p->encodeMode)
@@ -207,7 +209,7 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc
id != XZ_ID_SPARC)
return SZ_ERROR_UNSUPPORTED;
p->p = 0;
- decoder = alloc->Alloc(alloc, sizeof(CBraState));
+ decoder = (CBraState *)alloc->Alloc(alloc, sizeof(CBraState));
if (decoder == 0)
return SZ_ERROR_MEM;
decoder->methodId = (UInt32)id;
@@ -233,9 +235,9 @@ static void SbState_Free(void *pp, ISzAlloc *alloc)
static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
{
- pp = pp;
- props = props;
- alloc = alloc;
+ UNUSED_VAR(pp);
+ UNUSED_VAR(props);
+ UNUSED_VAR(alloc);
return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
}
@@ -249,7 +251,7 @@ static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
{
CSbDec *p = (CSbDec *)pp;
SRes res;
- srcWasFinished = srcWasFinished;
+ UNUSED_VAR(srcWasFinished);
p->dest = dest;
p->destLen = *destLen;
p->src = src;
@@ -305,15 +307,15 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr
{
ELzmaStatus status;
/* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */
- SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, finishMode, &status);
- srcWasFinished = srcWasFinished;
+ SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status);
+ UNUSED_VAR(srcWasFinished);
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
return res;
}
static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
{
- CLzma2Dec *decoder = alloc->Alloc(alloc, sizeof(CLzma2Dec));
+ CLzma2Dec *decoder = (CLzma2Dec *)alloc->Alloc(alloc, sizeof(CLzma2Dec));
p->p = decoder;
if (decoder == 0)
return SZ_ERROR_MEM;
@@ -328,9 +330,9 @@ static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
{
- int i;
+ unsigned i;
p->alloc = alloc;
- p->buf = 0;
+ p->buf = NULL;
p->numCoders = 0;
for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++)
p->coders[i].p = NULL;
@@ -338,7 +340,7 @@ void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
void MixCoder_Free(CMixCoder *p)
{
- int i;
+ unsigned i;
for (i = 0; i < p->numCoders; i++)
{
IStateCoder *sc = &p->coders[i];
@@ -347,13 +349,16 @@ void MixCoder_Free(CMixCoder *p)
}
p->numCoders = 0;
if (p->buf)
+ {
p->alloc->Free(p->alloc, p->buf);
+ p->buf = NULL; /* 9.31: the BUG was fixed */
+ }
}
void MixCoder_Init(CMixCoder *p)
{
- int i;
- for (i = 0; i < p->numCoders - 1; i++)
+ unsigned i;
+ for (i = 0; i < MIXCODER_NUM_FILTERS_MAX - 1; i++)
{
p->size[i] = 0;
p->pos[i] = 0;
@@ -366,11 +371,11 @@ void MixCoder_Init(CMixCoder *p)
}
}
-SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)
+SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId)
{
IStateCoder *sc = &p->coders[coderIndex];
p->ids[coderIndex] = methodId;
- switch(methodId)
+ switch (methodId)
{
case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, p->alloc);
#ifdef USE_SUBBLOCK
@@ -393,10 +398,10 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
*srcLen = 0;
*status = CODER_STATUS_NOT_FINISHED;
- if (p->buf == 0)
+ if (!p->buf)
{
- p->buf = p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
- if (p->buf == 0)
+ p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
+ if (!p->buf)
return SZ_ERROR_MEM;
}
@@ -406,7 +411,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
for (;;)
{
Bool processed = False;
- int i;
+ unsigned i;
/*
if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)
break;
@@ -515,8 +520,8 @@ static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *b
SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
{
unsigned pos;
- int numFilters, i;
- UInt32 headerSize = (UInt32)header[0] << 2;
+ unsigned numFilters, i;
+ unsigned headerSize = (unsigned)header[0] << 2;
if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))
return SZ_ERROR_ARCHIVE;
@@ -550,9 +555,9 @@ SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
pos += (unsigned)size;
#ifdef XZ_DUMP
- printf("\nf[%d] = %2X: ", i, filter->id);
+ printf("\nf[%u] = %2X: ", i, (unsigned)filter->id);
{
- int i;
+ unsigned i;
for (i = 0; i < size; i++)
printf(" %2X", filter->props[i]);
}
@@ -567,9 +572,10 @@ SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
{
- int i;
+ unsigned i;
Bool needReInit = True;
- int numFilters = XzBlock_GetNumFilters(block);
+ unsigned numFilters = XzBlock_GetNumFilters(block);
+
if (numFilters == p->numCoders)
{
for (i = 0; i < numFilters; i++)
@@ -577,6 +583,7 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
break;
needReInit = (i != numFilters);
}
+
if (needReInit)
{
MixCoder_Free(p);
@@ -587,12 +594,14 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
RINOK(MixCoder_SetFromMethod(p, i, f->id));
}
}
+
for (i = 0; i < numFilters; i++)
{
const CXzFilter *f = &block->filters[numFilters - 1 - i];
IStateCoder *sc = &p->coders[i];
RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc));
}
+
MixCoder_Init(p);
return SZ_OK;
}
@@ -601,7 +610,10 @@ void XzUnpacker_Init(CXzUnpacker *p)
{
p->state = XZ_STATE_STREAM_HEADER;
p->pos = 0;
- p->numStreams = 0;
+ p->numStartedStreams = 0;
+ p->numFinishedStreams = 0;
+ p->numTotalBlocks = 0;
+ p->padSize = 0;
}
void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc)
@@ -616,7 +628,7 @@ void XzUnpacker_Free(CXzUnpacker *p)
}
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
- const Byte *src, SizeT *srcLen, int finishMode, ECoderStatus *status)
+ const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, ECoderStatus *status)
{
SizeT destLenOrig = *destLen;
SizeT srcLenOrig = *srcLen;
@@ -676,7 +688,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
return SZ_OK;
}
- switch(p->state)
+ switch (p->state)
{
case XZ_STATE_STREAM_HEADER:
{
@@ -690,6 +702,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
else
{
RINOK(Xz_ParseHeader(&p->streamFlags, p->buf));
+ p->numStartedStreams++;
p->state = XZ_STATE_BLOCK_HEADER;
Sha256_Init(&p->sha);
p->indexSize = 0;
@@ -730,6 +743,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
else
{
RINOK(XzBlock_Parse(&p->block, p->buf));
+ p->numTotalBlocks++;
p->state = XZ_STATE_BLOCK;
p->packSize = 0;
p->unpackSize = 0;
@@ -847,7 +861,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
if (p->pos == XZ_STREAM_FOOTER_SIZE)
{
p->state = XZ_STATE_STREAM_PADDING;
- p->numStreams++;
+ p->numFinishedStreams++;
p->padSize = 0;
if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf))
return SZ_ERROR_CRC;
@@ -887,3 +901,13 @@ Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p)
{
return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0);
}
+
+UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p)
+{
+ UInt64 num = 0;
+ if (p->state == XZ_STATE_STREAM_PADDING)
+ num += p->padSize;
+ else if (p->state == XZ_STATE_STREAM_HEADER)
+ num += p->padSize + p->pos;
+ return num;
+}
diff --git a/3rdparty/lzma/C/XzEnc.c b/3rdparty/lzma/C/XzEnc.c
index 56cfd579c69..ccac7a8ed4b 100644
--- a/3rdparty/lzma/C/XzEnc.c
+++ b/3rdparty/lzma/C/XzEnc.c
@@ -1,5 +1,7 @@
/* XzEnc.c -- Xz Encode
-2011-02-07 : Igor Pavlov : Public domain */
+2015-09-16 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <stdlib.h>
#include <string.h>
@@ -8,6 +10,7 @@
#include "Alloc.h"
#include "Bra.h"
#include "CpuArch.h"
+
#ifdef USE_SUBBLOCK
#include "Bcj3Enc.c"
#include "SbFind.c"
@@ -16,14 +19,6 @@
#include "XzEnc.h"
-static void *SzBigAlloc(void *p, size_t size) { p = p; return BigAlloc(size); }
-static void SzBigFree(void *p, void *address) { p = p; BigFree(address); }
-static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
-
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
#define XzBlock_ClearFlags(p) (p)->flags = 0;
#define XzBlock_SetNumFilters(p, n) (p)->flags |= ((n) - 1);
#define XzBlock_SetHasPackSize(p) (p)->flags |= XZ_BF_PACK_SIZE;
@@ -40,7 +35,7 @@ static SRes WriteBytesAndCrc(ISeqOutStream *s, const void *buf, UInt32 size, UIn
return WriteBytes(s, buf, size);
}
-SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
+static SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
{
UInt32 crc;
Byte header[XZ_STREAM_HEADER_SIZE];
@@ -52,17 +47,19 @@ SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE);
}
-SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
+
+static SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
{
Byte header[XZ_BLOCK_HEADER_SIZE_MAX];
unsigned pos = 1;
- int numFilters, i;
+ unsigned numFilters, i;
header[pos++] = p->flags;
if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize);
if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize);
numFilters = XzBlock_GetNumFilters(p);
+
for (i = 0; i < numFilters; i++)
{
const CXzFilter *f = &p->filters[i];
@@ -71,14 +68,17 @@ SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
memcpy(header + pos, f->props, f->propsSize);
pos += f->propsSize;
}
- while((pos & 3) != 0)
+
+ while ((pos & 3) != 0)
header[pos++] = 0;
+
header[0] = (Byte)(pos >> 2);
SetUi32(header + pos, CrcCalc(header, pos));
return WriteBytes(s, header, pos + 4);
}
-SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
+
+static SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
{
Byte buf[32];
UInt64 globalPos;
@@ -90,6 +90,7 @@ SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
globalPos = pos;
buf[0] = 0;
RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
+
for (i = 0; i < p->numBlocks; i++)
{
const CXzBlockSizes *block = &p->blocks[i];
@@ -98,7 +99,9 @@ SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
globalPos += pos;
RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
}
+
pos = ((unsigned)globalPos & 3);
+
if (pos != 0)
{
buf[0] = buf[1] = buf[2] = 0;
@@ -123,34 +126,36 @@ SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
}
}
-SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc)
+
+static SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc)
{
- if (p->blocks == 0 || p->numBlocksAllocated == p->numBlocks)
+ if (!p->blocks || p->numBlocksAllocated == p->numBlocks)
{
- size_t num = (p->numBlocks + 1) * 2;
+ size_t num = p->numBlocks * 2 + 1;
size_t newSize = sizeof(CXzBlockSizes) * num;
CXzBlockSizes *blocks;
if (newSize / sizeof(CXzBlockSizes) != num)
return SZ_ERROR_MEM;
- blocks = alloc->Alloc(alloc, newSize);
- if (blocks == 0)
+ blocks = (CXzBlockSizes *)alloc->Alloc(alloc, newSize);
+ if (!blocks)
return SZ_ERROR_MEM;
if (p->numBlocks != 0)
{
memcpy(blocks, p->blocks, p->numBlocks * sizeof(CXzBlockSizes));
- Xz_Free(p, alloc);
+ alloc->Free(alloc, p->blocks);
}
p->blocks = blocks;
p->numBlocksAllocated = num;
}
{
CXzBlockSizes *block = &p->blocks[p->numBlocks++];
- block->totalSize = totalSize;
block->unpackSize = unpackSize;
+ block->totalSize = totalSize;
}
return SZ_OK;
}
+
/* ---------- CSeqCheckInStream ---------- */
typedef struct
@@ -161,13 +166,13 @@ typedef struct
CXzCheck check;
} CSeqCheckInStream;
-void SeqCheckInStream_Init(CSeqCheckInStream *p, int mode)
+static void SeqCheckInStream_Init(CSeqCheckInStream *p, unsigned mode)
{
p->processed = 0;
XzCheck_Init(&p->check, mode);
}
-void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest)
+static void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest)
{
XzCheck_Final(&p->check, digest);
}
@@ -181,6 +186,7 @@ static SRes SeqCheckInStream_Read(void *pp, void *data, size_t *size)
return res;
}
+
/* ---------- CSeqSizeOutStream ---------- */
typedef struct
@@ -198,6 +204,7 @@ static size_t MyWrite(void *pp, const void *data, size_t size)
return size;
}
+
/* ---------- CSeqInFilter ---------- */
#define FILTER_BUF_SIZE (1 << 20)
@@ -218,8 +225,9 @@ static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)
CSeqInFilter *p = (CSeqInFilter *)pp;
size_t sizeOriginal = *size;
if (sizeOriginal == 0)
- return S_OK;
+ return SZ_OK;
*size = 0;
+
for (;;)
{
if (!p->srcWasFinished && p->curPos == p->endPos)
@@ -274,9 +282,10 @@ static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props)
RINOK(BraState_SetFromMethod(&p->StateCoder, props->id, 1, &g_Alloc));
RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, &g_Alloc));
p->StateCoder.Init(p->StateCoder.p);
- return S_OK;
+ return SZ_OK;
}
+
/* ---------- CSbEncInStream ---------- */
#ifdef USE_SUBBLOCK
@@ -294,6 +303,7 @@ static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
size_t sizeOriginal = *size;
if (sizeOriginal == 0)
return S_OK;
+
for (;;)
{
if (p->enc.needRead && !p->enc.readWasFinished)
@@ -308,6 +318,7 @@ static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
}
p->enc.needRead = False;
}
+
*size = sizeOriginal;
RINOK(SbEnc_Read(&p->enc, data, size));
if (*size != 0 || !p->enc.needRead)
@@ -360,7 +371,7 @@ static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, IS
static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
{
p->lzma2 = Lzma2Enc_Create(p->alloc, p->bigAlloc);
- if (p->lzma2 == 0)
+ if (!p->lzma2)
return SZ_ERROR_MEM;
return SZ_OK;
}
@@ -378,10 +389,11 @@ static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
}
}
+
void XzProps_Init(CXzProps *p)
{
- p->lzma2Props = 0;
- p->filterProps = 0;
+ p->lzma2Props = NULL;
+ p->filterProps = NULL;
p->checkId = XZ_CHECK_CRC32;
}
@@ -389,10 +401,11 @@ void XzFilterProps_Init(CXzFilterProps *p)
{
p->id = 0;
p->delta = 0;
- p->ip= 0;
+ p->ip = 0;
p->ipDefined = False;
}
+
static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
ISeqOutStream *outStream, ISeqInStream *inStream,
const CXzProps *props, ICompressProgress *progress)
@@ -406,7 +419,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
CSeqCheckInStream checkInStream;
CSeqSizeOutStream seqSizeOutStream;
CXzBlock block;
- int filterIndex = 0;
+ unsigned filterIndex = 0;
CXzFilter *filter = NULL;
const CXzFilterProps *fp = props->filterProps;
@@ -418,6 +431,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
filter = &block.filters[filterIndex++];
filter->id = fp->id;
filter->propsSize = 0;
+
if (fp->id == XZ_ID_Delta)
{
filter->props[0] = (Byte)(fp->delta - 1);
@@ -465,14 +479,16 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
{
UInt64 packPos = seqSizeOutStream.processed;
+
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
- fp ?
- #ifdef USE_SUBBLOCK
- (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
- #endif
- &lzmaf->filter.p:
- &checkInStream.p,
- progress);
+ fp ?
+ #ifdef USE_SUBBLOCK
+ (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
+ #endif
+ &lzmaf->filter.p:
+ &checkInStream.p,
+ progress);
+
RINOK(res);
block.unpackSize = checkInStream.processed;
block.packSize = seqSizeOutStream.processed - packPos;
@@ -481,7 +497,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
{
unsigned padSize = 0;
Byte buf[128];
- while((((unsigned)block.packSize + padSize) & 3) != 0)
+ while ((((unsigned)block.packSize + padSize) & 3) != 0)
buf[padSize++] = 0;
SeqCheckInStream_GetDigest(&checkInStream, buf + padSize);
RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags)));
@@ -491,6 +507,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
return Xz_WriteFooter(xz, outStream);
}
+
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
const CXzProps *props, ICompressProgress *progress)
{
@@ -507,6 +524,7 @@ SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
return res;
}
+
SRes Xz_EncodeEmpty(ISeqOutStream *outStream)
{
SRes res;
diff --git a/3rdparty/lzma/C/XzIn.c b/3rdparty/lzma/C/XzIn.c
index 4ba87a2cfc6..07b1cc39516 100644
--- a/3rdparty/lzma/C/XzIn.c
+++ b/3rdparty/lzma/C/XzIn.c
@@ -1,5 +1,7 @@
/* XzIn.c - Xz input
-2011-02-01 : Igor Pavlov : Public domain */
+2015-11-08 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <string.h>
@@ -70,7 +72,7 @@ SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream)
static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc)
{
- size_t i, numBlocks, crcStartPos, pos = 1;
+ size_t numBlocks, pos = 1;
UInt32 crc;
if (size < 5 || buf[0] != 0)
@@ -89,10 +91,10 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *
return SZ_ERROR_ARCHIVE;
}
- crcStartPos = pos;
Xz_Free(p, alloc);
if (numBlocks != 0)
{
+ size_t i;
p->numBlocks = numBlocks;
p->numBlocksAllocated = numBlocks;
p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);
@@ -133,55 +135,58 @@ static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize,
return res;
}
-static SRes SeekFromCur(ILookInStream *inStream, Int64 *res)
+static SRes LookInStream_SeekRead_ForArc(ILookInStream *stream, UInt64 offset, void *buf, size_t size)
{
- return inStream->Seek(inStream, res, SZ_SEEK_CUR);
+ RINOK(LookInStream_SeekTo(stream, offset));
+ return LookInStream_Read(stream, buf, size);
+ /* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */
}
static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc)
{
UInt64 indexSize;
Byte buf[XZ_STREAM_FOOTER_SIZE];
+ UInt64 pos = *startOffset;
- if ((*startOffset & 3) != 0 || *startOffset < XZ_STREAM_FOOTER_SIZE)
+ if ((pos & 3) != 0 || pos < XZ_STREAM_FOOTER_SIZE)
return SZ_ERROR_NO_ARCHIVE;
- *startOffset = -XZ_STREAM_FOOTER_SIZE;
- RINOK(SeekFromCur(stream, startOffset));
- RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
+ pos -= XZ_STREAM_FOOTER_SIZE;
+ RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
{
UInt32 total = 0;
- *startOffset += XZ_STREAM_FOOTER_SIZE;
+ pos += XZ_STREAM_FOOTER_SIZE;
+
for (;;)
{
size_t i;
#define TEMP_BUF_SIZE (1 << 10)
- Byte tempBuf[TEMP_BUF_SIZE];
- if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
- return SZ_ERROR_NO_ARCHIVE;
- i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
+ Byte temp[TEMP_BUF_SIZE];
+
+ i = (pos > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)pos;
+ pos -= i;
+ RINOK(LookInStream_SeekRead_ForArc(stream, pos, temp, i));
total += (UInt32)i;
- *startOffset = -(Int64)i;
- RINOK(SeekFromCur(stream, startOffset));
- RINOK(LookInStream_Read2(stream, tempBuf, i, SZ_ERROR_NO_ARCHIVE));
for (; i != 0; i--)
- if (tempBuf[i - 1] != 0)
+ if (temp[i - 1] != 0)
break;
if (i != 0)
{
if ((i & 3) != 0)
return SZ_ERROR_NO_ARCHIVE;
- *startOffset += i;
+ pos += i;
break;
}
+ if (pos < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
+ return SZ_ERROR_NO_ARCHIVE;
}
- if (*startOffset < XZ_STREAM_FOOTER_SIZE)
+
+ if (pos < XZ_STREAM_FOOTER_SIZE)
return SZ_ERROR_NO_ARCHIVE;
- *startOffset -= XZ_STREAM_FOOTER_SIZE;
- RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
- RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
+ pos -= XZ_STREAM_FOOTER_SIZE;
+ RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
return SZ_ERROR_NO_ARCHIVE;
}
@@ -196,20 +201,22 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2;
- *startOffset = -(Int64)(indexSize + XZ_STREAM_FOOTER_SIZE);
- RINOK(SeekFromCur(stream, startOffset));
+ if (pos < indexSize)
+ return SZ_ERROR_ARCHIVE;
+ pos -= indexSize;
+ RINOK(LookInStream_SeekTo(stream, pos));
RINOK(Xz_ReadIndex(p, stream, indexSize, alloc));
{
UInt64 totalSize = Xz_GetPackSize(p);
- UInt64 sum = XZ_STREAM_HEADER_SIZE + totalSize + indexSize;
- if (totalSize == XZ_SIZE_OVERFLOW ||
- sum >= ((UInt64)1 << 63) ||
- totalSize >= ((UInt64)1 << 63))
+ if (totalSize == XZ_SIZE_OVERFLOW
+ || totalSize >= ((UInt64)1 << 63)
+ || pos < totalSize + XZ_STREAM_HEADER_SIZE)
return SZ_ERROR_ARCHIVE;
- *startOffset = -(Int64)sum;
- RINOK(SeekFromCur(stream, startOffset));
+ pos -= (totalSize + XZ_STREAM_HEADER_SIZE);
+ RINOK(LookInStream_SeekTo(stream, pos));
+ *startOffset = pos;
}
{
CXzStreamFlags headerFlags;
@@ -290,14 +297,15 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompr
if (data == 0)
return SZ_ERROR_MEM;
p->numAllocated = newNum;
- memcpy(data, p->streams, p->num * sizeof(CXzStream));
+ if (p->num != 0)
+ memcpy(data, p->streams, p->num * sizeof(CXzStream));
alloc->Free(alloc, p->streams);
p->streams = (CXzStream *)data;
}
p->streams[p->num++] = st;
if (*startOffset == 0)
break;
- RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
+ RINOK(LookInStream_SeekTo(stream, *startOffset));
if (progress && progress->Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK)
return SZ_ERROR_PROGRESS;
}
diff --git a/3rdparty/lzma/CPP/7zip/7zip.mak b/3rdparty/lzma/CPP/7zip/7zip.mak
new file mode 100644
index 00000000000..7fbe2ada738
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/7zip.mak
@@ -0,0 +1,240 @@
+OBJS = \
+ $O\StdAfx.obj \
+ $(CURRENT_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(WIN_CTRL_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $(AGENT_OBJS) \
+ $(CONSOLE_OBJS) \
+ $(EXPLORER_OBJS) \
+ $(FM_OBJS) \
+ $(GUI_OBJS) \
+ $(7Z_OBJS) \
+ $(CAB_OBJS) \
+ $(CHM_OBJS) \
+ $(COM_OBJS) \
+ $(ISO_OBJS) \
+ $(NSIS_OBJS) \
+ $(RAR_OBJS) \
+ $(TAR_OBJS) \
+ $(UDF_OBJS) \
+ $(WIM_OBJS) \
+ $(ZIP_OBJS) \
+ $(COMPRESS_OBJS) \
+ $(CRYPTO_OBJS) \
+ $(C_OBJS) \
+ $(ASM_OBJS) \
+ $O\resource.res \
+
+!include "../../../Build.mak"
+
+# MAK_SINGLE_FILE = 1
+
+!IFDEF MAK_SINGLE_FILE
+
+!IFDEF CURRENT_OBJS
+$(CURRENT_OBJS): ./$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+
+!IFDEF COMMON_OBJS
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF WIN_OBJS
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF WIN_CTRL_OBJS
+$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF 7ZIP_COMMON_OBJS
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF AR_OBJS
+$(AR_OBJS): ../../Archive/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF AR_COMMON_OBJS
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF 7Z_OBJS
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF CAB_OBJS
+$(CAB_OBJS): ../../Archive/Cab/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF CHM_OBJS
+$(CHM_OBJS): ../../Archive/Chm/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF COM_OBJS
+$(COM_OBJS): ../../Archive/Com/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF ISO_OBJS
+$(ISO_OBJS): ../../Archive/Iso/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF NSIS_OBJS
+$(NSIS_OBJS): ../../Archive/Nsis/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF RAR_OBJS
+$(RAR_OBJS): ../../Archive/Rar/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF TAR_OBJS
+$(TAR_OBJS): ../../Archive/Tar/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF UDF_OBJS
+$(UDF_OBJS): ../../Archive/Udf/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF WIM_OBJS
+$(WIM_OBJS): ../../Archive/Wim/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF ZIP_OBJS
+$(ZIP_OBJS): ../../Archive/Zip/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF COMPRESS_OBJS
+$(COMPRESS_OBJS): ../../Compress/$(*B).cpp
+ $(COMPL_O2)
+!ENDIF
+
+!IFDEF CRYPTO_OBJS
+$(CRYPTO_OBJS): ../../Crypto/$(*B).cpp
+ $(COMPL_O2)
+!ENDIF
+
+!IFDEF UI_COMMON_OBJS
+$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF AGENT_OBJS
+$(AGENT_OBJS): ../../UI/Agent/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF CONSOLE_OBJS
+$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF EXPLORER_OBJS
+$(EXPLORER_OBJS): ../../UI/Explorer/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF FM_OBJS
+$(FM_OBJS): ../../UI/FileManager/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF GUI_OBJS
+$(GUI_OBJS): ../../UI/GUI/$(*B).cpp
+ $(COMPL)
+!ENDIF
+
+!IFDEF C_OBJS
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+!ENDIF
+
+
+!ELSE
+
+{.}.cpp{$O}.obj::
+ $(COMPLB)
+{../../../Common}.cpp{$O}.obj::
+ $(COMPLB)
+{../../../Windows}.cpp{$O}.obj::
+ $(COMPLB)
+{../../../Windows/Control}.cpp{$O}.obj::
+ $(COMPLB)
+{../../Common}.cpp{$O}.obj::
+ $(COMPLB)
+
+{../../UI/Common}.cpp{$O}.obj::
+ $(COMPLB)
+{../../UI/Agent}.cpp{$O}.obj::
+ $(COMPLB)
+{../../UI/Console}.cpp{$O}.obj::
+ $(COMPLB)
+{../../UI/Explorer}.cpp{$O}.obj::
+ $(COMPLB)
+{../../UI/FileManager}.cpp{$O}.obj::
+ $(COMPLB)
+{../../UI/GUI}.cpp{$O}.obj::
+ $(COMPLB)
+
+
+{../../Archive}.cpp{$O}.obj::
+ $(COMPLB)
+{../../Archive/Common}.cpp{$O}.obj::
+ $(COMPLB)
+
+{../../Archive/7z}.cpp{$O}.obj::
+ $(COMPLB)
+{../../Archive/Cab}.cpp{$O}.obj::
+ $(COMPLB)
+{../../Archive/Chm}.cpp{$O}.obj::
+ $(COMPLB)
+{../../Archive/Com}.cpp{$O}.obj::
+ $(COMPLB)
+{../../Archive/Iso}.cpp{$O}.obj::
+ $(COMPLB)
+{../../Archive/Nsis}.cpp{$O}.obj::
+ $(COMPLB)
+{../../Archive/Rar}.cpp{$O}.obj::
+ $(COMPLB)
+{../../Archive/Tar}.cpp{$O}.obj::
+ $(COMPLB)
+{../../Archive/Udf}.cpp{$O}.obj::
+ $(COMPLB)
+{../../Archive/Wim}.cpp{$O}.obj::
+ $(COMPLB)
+{../../Archive/Zip}.cpp{$O}.obj::
+ $(COMPLB)
+
+{../../Compress}.cpp{$O}.obj::
+ $(COMPLB_O2)
+{../../Crypto}.cpp{$O}.obj::
+ $(COMPLB_O2)
+{../../../../C}.c{$O}.obj::
+ $(CCOMPLB)
+
+!ENDIF
+
+!include "Asm.mak"
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h
index 5cde97c38ba..8105ff0413d 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h
@@ -9,37 +9,62 @@
namespace NArchive {
namespace N7z {
-struct CMethodFull: public CProps
+struct CMethodFull: public CMethodProps
{
CMethodId Id;
- UInt32 NumInStreams;
- UInt32 NumOutStreams;
+ UInt32 NumStreams;
- bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
+ bool IsSimpleCoder() const { return NumStreams == 1; }
};
-struct CBind
+struct CBond2
{
- UInt32 InCoder;
- UInt32 InStream;
UInt32 OutCoder;
UInt32 OutStream;
+ UInt32 InCoder;
};
struct CCompressionMethodMode
{
+ /*
+ if (Bonds.Empty()), then default bonds must be created
+ if (Filter_was_Inserted)
+ {
+ Methods[0] is filter method
+ Bonds don't contain bonds for filter (these bonds must be created)
+ }
+ */
+
CObjectVector<CMethodFull> Methods;
- CRecordVector<CBind> Binds;
+ CRecordVector<CBond2> Bonds;
+
+ bool IsThereBond_to_Coder(unsigned coderIndex) const
+ {
+ FOR_VECTOR(i, Bonds)
+ if (Bonds[i].InCoder == coderIndex)
+ return true;
+ return false;
+ }
+
+ bool DefaultMethod_was_Inserted;
+ bool Filter_was_Inserted;
+
#ifndef _7ZIP_ST
UInt32 NumThreads;
+ bool MultiThreadMixer;
#endif
+
bool PasswordIsDefined;
UString Password;
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
- CCompressionMethodMode(): PasswordIsDefined(false)
+ CCompressionMethodMode():
+ DefaultMethod_was_Inserted(false),
+ Filter_was_Inserted(false),
+ PasswordIsDefined(false)
#ifndef _7ZIP_ST
, NumThreads(1)
+ , MultiThreadMixer(true)
#endif
{}
};
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp
index 425a341577d..bfe1b24e923 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp
@@ -3,7 +3,6 @@
#include "StdAfx.h"
#include "../../Common/LimitedStreams.h"
-#include "../../Common/LockedStream.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/StreamObjects.h"
@@ -12,230 +11,364 @@
namespace NArchive {
namespace N7z {
-static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
- CBindInfoEx &bindInfo)
+class CDecProgress:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
{
- bindInfo.Clear();
- int i;
- for (i = 0; i < folder.BindPairs.Size(); i++)
+ CMyComPtr<ICompressProgressInfo> _progress;
+public:
+ CDecProgress(ICompressProgressInfo *progress): _progress(progress) {}
+
+ MY_UNKNOWN_IMP1(ICompressProgressInfo)
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+STDMETHODIMP CDecProgress::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 *outSize)
+{
+ return _progress->SetRatioInfo(NULL, outSize);
+}
+
+static void Convert_FolderInfo_to_BindInfo(const CFolderEx &folder, CBindInfoEx &bi)
+{
+ bi.Clear();
+
+ bi.Bonds.ClearAndSetSize(folder.Bonds.Size());
+ unsigned i;
+ for (i = 0; i < folder.Bonds.Size(); i++)
{
- NCoderMixer::CBindPair bindPair;
- bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;
- bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;
- bindInfo.BindPairs.Add(bindPair);
+ NCoderMixer2::CBond &bond = bi.Bonds[i];
+ const N7z::CBond &folderBond = folder.Bonds[i];
+ bond.PackIndex = folderBond.PackIndex;
+ bond.UnpackIndex = folderBond.UnpackIndex;
}
- UInt32 outStreamIndex = 0;
+
+ bi.Coders.ClearAndSetSize(folder.Coders.Size());
+ bi.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size());
for (i = 0; i < folder.Coders.Size(); i++)
{
- NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
const CCoderInfo &coderInfo = folder.Coders[i];
- coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams;
- coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams;
- bindInfo.Coders.Add(coderStreamsInfo);
- bindInfo.CoderMethodIDs.Add(coderInfo.MethodID);
- for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)
- if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
- bindInfo.OutStreams.Add(outStreamIndex);
+ bi.Coders[i].NumStreams = coderInfo.NumStreams;
+ bi.CoderMethodIDs[i] = coderInfo.MethodID;
}
+
+ /*
+ if (!bi.SetUnpackCoder())
+ throw 1112;
+ */
+ bi.UnpackCoder = folder.UnpackCoder;
+ bi.PackStreams.ClearAndSetSize(folder.PackStreams.Size());
for (i = 0; i < folder.PackStreams.Size(); i++)
- bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);
+ bi.PackStreams[i] = folder.PackStreams[i];
}
-static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1,
- const NCoderMixer::CCoderStreamsInfo &a2)
+static inline bool AreCodersEqual(
+ const NCoderMixer2::CCoderStreamsInfo &a1,
+ const NCoderMixer2::CCoderStreamsInfo &a2)
{
- return (a1.NumInStreams == a2.NumInStreams) &&
- (a1.NumOutStreams == a2.NumOutStreams);
+ return (a1.NumStreams == a2.NumStreams);
}
-static bool AreBindPairsEqual(const NCoderMixer::CBindPair &a1, const NCoderMixer::CBindPair &a2)
+static inline bool AreBondsEqual(
+ const NCoderMixer2::CBond &a1,
+ const NCoderMixer2::CBond &a2)
{
- return (a1.InIndex == a2.InIndex) &&
- (a1.OutIndex == a2.OutIndex);
+ return
+ (a1.PackIndex == a2.PackIndex) &&
+ (a1.UnpackIndex == a2.UnpackIndex);
}
static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
{
if (a1.Coders.Size() != a2.Coders.Size())
return false;
- int i;
+ unsigned i;
for (i = 0; i < a1.Coders.Size(); i++)
if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))
return false;
- if (a1.BindPairs.Size() != a2.BindPairs.Size())
+
+ if (a1.Bonds.Size() != a2.Bonds.Size())
return false;
- for (i = 0; i < a1.BindPairs.Size(); i++)
- if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i]))
+ for (i = 0; i < a1.Bonds.Size(); i++)
+ if (!AreBondsEqual(a1.Bonds[i], a2.Bonds[i]))
return false;
+
for (i = 0; i < a1.CoderMethodIDs.Size(); i++)
if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i])
return false;
- if (a1.InStreams.Size() != a2.InStreams.Size())
+
+ if (a1.PackStreams.Size() != a2.PackStreams.Size())
return false;
- if (a1.OutStreams.Size() != a2.OutStreams.Size())
+ for (i = 0; i < a1.PackStreams.Size(); i++)
+ if (a1.PackStreams[i] != a2.PackStreams[i])
+ return false;
+
+ /*
+ if (a1.UnpackCoder != a2.UnpackCoder)
return false;
+ */
return true;
}
-CDecoder::CDecoder(bool multiThread)
+CDecoder::CDecoder(bool useMixerMT):
+ _bindInfoPrev_Defined(false),
+ _useMixerMT(useMixerMT)
+{}
+
+
+struct CLockedInStream:
+ public IUnknown,
+ public CMyUnknownImp
{
- #ifndef _ST_MODE
- multiThread = true;
+ CMyComPtr<IInStream> Stream;
+ UInt64 Pos;
+
+ MY_UNKNOWN_IMP
+
+ #ifdef USE_MIXER_MT
+ NWindows::NSynchronization::CCriticalSection CriticalSection;
#endif
- _multiThread = multiThread;
- _bindInfoExPrevIsDefined = false;
+};
+
+
+#ifdef USE_MIXER_MT
+
+class CLockedSequentialInStreamMT:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CLockedInStream *_glob;
+ UInt64 _pos;
+ CMyComPtr<IUnknown> _globRef;
+public:
+ void Init(CLockedInStream *lockedInStream, UInt64 startPos)
+ {
+ _globRef = lockedInStream;
+ _glob = lockedInStream;
+ _pos = startPos;
+ }
+
+ MY_UNKNOWN_IMP1(ISequentialInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ NWindows::NSynchronization::CCriticalSectionLock lock(_glob->CriticalSection);
+
+ if (_pos != _glob->Pos)
+ {
+ RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL));
+ _glob->Pos = _pos;
+ }
+
+ UInt32 realProcessedSize = 0;
+ HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize);
+ _pos += realProcessedSize;
+ _glob->Pos = _pos;
+ if (processedSize)
+ *processedSize = realProcessedSize;
+ return res;
}
+#endif
+
+
+#ifdef USE_MIXER_ST
+
+class CLockedSequentialInStreamST:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CLockedInStream *_glob;
+ UInt64 _pos;
+ CMyComPtr<IUnknown> _globRef;
+public:
+ void Init(CLockedInStream *lockedInStream, UInt64 startPos)
+ {
+ _globRef = lockedInStream;
+ _glob = lockedInStream;
+ _pos = startPos;
+ }
+
+ MY_UNKNOWN_IMP1(ISequentialInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (_pos != _glob->Pos)
+ {
+ RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL));
+ _glob->Pos = _pos;
+ }
+
+ UInt32 realProcessedSize = 0;
+ HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize);
+ _pos += realProcessedSize;
+ _glob->Pos = _pos;
+ if (processedSize)
+ *processedSize = realProcessedSize;
+ return res;
+}
+
+#endif
+
+
+
HRESULT CDecoder::Decode(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
UInt64 startPos,
- const UInt64 *packSizes,
- const CFolder &folderInfo,
- ISequentialOutStream *outStream,
- ICompressProgressInfo *compressProgress
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
+ const CFolders &folders, unsigned folderIndex,
+ const UInt64 *unpackSize
+
+ , ISequentialOutStream *outStream
+ , ICompressProgressInfo *compressProgress
+ , ISequentialInStream **
+
+ #ifdef USE_MIXER_ST
+ inStreamMainRes
#endif
+
+ _7Z_DECODER_CRYPRO_VARS_DECL
+
#if !defined(_7ZIP_ST) && !defined(_SFX)
, bool mtMode, UInt32 numThreads
#endif
)
{
- if (!folderInfo.CheckStructure())
+ const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]];
+ CFolderEx folderInfo;
+ folders.ParseFolderEx(folderIndex, folderInfo);
+
+ if (!folderInfo.IsDecodingSupported())
+ return E_NOTIMPL;
+
+ CBindInfoEx bindInfo;
+ Convert_FolderInfo_to_BindInfo(folderInfo, bindInfo);
+ if (!bindInfo.CalcMapsAndCheck())
return E_NOTIMPL;
- #ifndef _NO_CRYPTO
- passwordIsDefined = false;
- #endif
- CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
-
- CLockedInStream lockedInStream;
- lockedInStream.Init(inStream);
- for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
+ UInt64 folderUnpackSize = folders.GetFolderUnpackSize(folderIndex);
+ bool fullUnpack = true;
+ if (unpackSize)
{
- CLockedSequentialInStreamImp *lockedStreamImpSpec = new
- CLockedSequentialInStreamImp;
- CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
- lockedStreamImpSpec->Init(&lockedInStream, startPos);
- startPos += packSizes[j];
-
- CLimitedSequentialInStream *streamSpec = new
- CLimitedSequentialInStream;
- CMyComPtr<ISequentialInStream> inStream = streamSpec;
- streamSpec->SetStream(lockedStreamImp);
- streamSpec->Init(packSizes[j]);
- inStreams.Add(inStream);
+ if (*unpackSize > folderUnpackSize)
+ return E_FAIL;
+ fullUnpack = (*unpackSize == folderUnpackSize);
}
+
+ /*
+ We don't need to init isEncrypted and passwordIsDefined
+ We must upgrade them only
- int numCoders = folderInfo.Coders.Size();
+ #ifndef _NO_CRYPTO
+ isEncrypted = false;
+ passwordIsDefined = false;
+ #endif
+ */
- CBindInfoEx bindInfo;
- ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
- bool createNewCoders;
- if (!_bindInfoExPrevIsDefined)
- createNewCoders = true;
- else
- createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
- if (createNewCoders)
+ if (!_bindInfoPrev_Defined || !AreBindInfoExEqual(bindInfo, _bindInfoPrev))
{
- int i;
- _decoders.Clear();
- // _decoders2.Clear();
-
- _mixerCoder.Release();
+ _mixerRef.Release();
- if (_multiThread)
+ #ifdef USE_MIXER_MT
+ #ifdef USE_MIXER_ST
+ if (_useMixerMT)
+ #endif
{
- _mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT;
- _mixerCoder = _mixerCoderMTSpec;
- _mixerCoderCommon = _mixerCoderMTSpec;
+ _mixerMT = new NCoderMixer2::CMixerMT(false);
+ _mixerRef = _mixerMT;
+ _mixer = _mixerMT;
}
+ #ifdef USE_MIXER_ST
else
+ #endif
+ #endif
{
- #ifdef _ST_MODE
- _mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST;
- _mixerCoder = _mixerCoderSTSpec;
- _mixerCoderCommon = _mixerCoderSTSpec;
+ #ifdef USE_MIXER_ST
+ _mixerST = new NCoderMixer2::CMixerST(false);
+ _mixerRef = _mixerST;
+ _mixer = _mixerST;
#endif
}
- RINOK(_mixerCoderCommon->SetBindInfo(bindInfo));
- for (i = 0; i < numCoders; i++)
+ RINOK(_mixer->SetBindInfo(bindInfo));
+
+ FOR_VECTOR(i, folderInfo.Coders)
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
+ #ifndef _SFX
+ // we don't support RAR codecs here
+ if ((coderInfo.MethodID >> 8) == 0x403)
+ return E_NOTIMPL;
+ #endif
- CMyComPtr<ICompressCoder> decoder;
- CMyComPtr<ICompressCoder2> decoder2;
+ CCreatedCoder cod;
RINOK(CreateCoder(
EXTERNAL_CODECS_LOC_VARS
- coderInfo.MethodID, decoder, decoder2, false));
- CMyComPtr<IUnknown> decoderUnknown;
+ coderInfo.MethodID, false, cod));
+
if (coderInfo.IsSimpleCoder())
{
- if (decoder == 0)
+ if (!cod.Coder)
return E_NOTIMPL;
-
- decoderUnknown = (IUnknown *)decoder;
-
- if (_multiThread)
- _mixerCoderMTSpec->AddCoder(decoder);
- #ifdef _ST_MODE
- else
- _mixerCoderSTSpec->AddCoder(decoder, false);
- #endif
+ // CMethodId m = coderInfo.MethodID;
+ // isFilter = (IsFilterMethod(m) || m == k_AES);
}
else
{
- if (decoder2 == 0)
+ if (!cod.Coder2 || cod.NumStreams != coderInfo.NumStreams)
return E_NOTIMPL;
- decoderUnknown = (IUnknown *)decoder2;
- if (_multiThread)
- _mixerCoderMTSpec->AddCoder2(decoder2);
- #ifdef _ST_MODE
- else
- _mixerCoderSTSpec->AddCoder2(decoder2, false);
- #endif
}
- _decoders.Add(decoderUnknown);
+ _mixer->AddCoder(cod);
+
+ // now there is no codec that uses another external codec
+ /*
#ifdef EXTERNAL_CODECS
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
if (setCompressCodecsInfo)
{
- RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));
+ // we must use g_ExternalCodecs also
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
}
#endif
+ */
}
- _bindInfoExPrev = bindInfo;
- _bindInfoExPrevIsDefined = true;
+
+ _bindInfoPrev = bindInfo;
+ _bindInfoPrev_Defined = true;
}
- int i;
- _mixerCoderCommon->ReInit();
-
- UInt32 packStreamIndex = 0, unpackStreamIndex = 0;
- UInt32 coderIndex = 0;
- // UInt32 coder2Index = 0;
+
+ _mixer->ReInit();
- for (i = 0; i < numCoders; i++)
+ UInt32 packStreamIndex = 0;
+ UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex];
+
+ unsigned i;
+
+ for (i = 0; i < folderInfo.Coders.Size(); i++)
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
- CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
-
+ IUnknown *decoder = _mixer->GetCoder(i).GetUnknown();
+
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
- decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
+ decoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
if (setDecoderProperties)
{
const CByteBuffer &props = coderInfo.Props;
- size_t size = props.GetCapacity();
+ size_t size = props.Size();
if (size > 0xFFFFFFFF)
return E_NOTIMPL;
- // if (size > 0)
- {
- RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size));
- }
+ HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size);
+ if (res == E_INVALIDARG)
+ res = E_NOTIMPL;
+ RINOK(res);
}
}
@@ -243,7 +376,7 @@ HRESULT CDecoder::Decode(
if (mtMode)
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
- decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+ decoder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
@@ -254,79 +387,157 @@ HRESULT CDecoder::Decode(
#ifndef _NO_CRYPTO
{
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
- decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
+ decoder->QueryInterface(IID_ICryptoSetPassword, (void **)&cryptoSetPassword);
if (cryptoSetPassword)
{
- if (getTextPassword == 0)
- return E_FAIL;
+ isEncrypted = true;
+ if (!getTextPassword)
+ return E_NOTIMPL;
CMyComBSTR passwordBSTR;
RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
- CByteBuffer buffer;
passwordIsDefined = true;
- const UString password(passwordBSTR);
- const UInt32 sizeInBytes = password.Length() * 2;
- buffer.SetCapacity(sizeInBytes);
- for (int i = 0; i < password.Length(); i++)
+ password.Empty();
+ size_t len = 0;
+ if (passwordBSTR)
+ {
+ password = passwordBSTR;
+ len = password.Len();
+ }
+ CByteBuffer buffer(len * 2);
+ for (size_t i = 0; i < len; i++)
{
- wchar_t c = password[i];
+ wchar_t c = passwordBSTR[i];
((Byte *)buffer)[i * 2] = (Byte)c;
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
}
- RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
+ RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size()));
}
}
#endif
- coderIndex++;
+ {
+ CMyComPtr<ICompressSetFinishMode> setFinishMode;
+ decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
+ if (setFinishMode)
+ {
+ RINOK(setFinishMode->SetFinishMode(BoolToInt(fullUnpack)));
+ }
+ }
- UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
- UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
- CRecordVector<const UInt64 *> packSizesPointers;
- CRecordVector<const UInt64 *> unpackSizesPointers;
- packSizesPointers.Reserve(numInStreams);
- unpackSizesPointers.Reserve(numOutStreams);
- UInt32 j;
- for (j = 0; j < numOutStreams; j++, unpackStreamIndex++)
- unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]);
+ UInt32 numStreams = (UInt32)coderInfo.NumStreams;
- for (j = 0; j < numInStreams; j++, packStreamIndex++)
+ CObjArray<UInt64> packSizes(numStreams);
+ CObjArray<const UInt64 *> packSizesPointers(numStreams);
+
+ for (UInt32 j = 0; j < numStreams; j++, packStreamIndex++)
{
- int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
- if (bindPairIndex >= 0)
- packSizesPointers.Add(
- &folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
+ int bond = folderInfo.FindBond_for_PackStream(packStreamIndex);
+
+ if (bond >= 0)
+ packSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndexStart + folderInfo.Bonds[(unsigned)bond].UnpackIndex];
else
{
- int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
+ int index = folderInfo.Find_in_PackStreams(packStreamIndex);
if (index < 0)
- return E_FAIL;
- packSizesPointers.Add(&packSizes[index]);
+ return E_NOTIMPL;
+ packSizes[j] = packPositions[(unsigned)index + 1] - packPositions[(unsigned)index];
+ packSizesPointers[j] = &packSizes[j];
}
}
+
+ const UInt64 *unpackSizesPointer =
+ (unpackSize && i == bindInfo.UnpackCoder) ?
+ unpackSize :
+ &folders.CoderUnpackSizes[unpackStreamIndexStart + i];
- _mixerCoderCommon->SetCoderInfo(i,
- &packSizesPointers.Front(),
- &unpackSizesPointers.Front());
+ _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers);
}
- UInt32 mainCoder, temp;
- bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
- if (_multiThread)
- _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
- /*
- else
- _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
- */
+ if (outStream)
+ {
+ _mixer->SelectMainCoder(!fullUnpack);
+ }
+
+ CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
- if (numCoders == 0)
- return 0;
- CRecordVector<ISequentialInStream *> inStreamPointers;
- inStreamPointers.Reserve(inStreams.Size());
- for (i = 0; i < inStreams.Size(); i++)
- inStreamPointers.Add(inStreams[i]);
- ISequentialOutStream *outStreamPointer = outStream;
- return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
- inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
+ CLockedInStream *lockedInStreamSpec = new CLockedInStream;
+ CMyComPtr<IUnknown> lockedInStream = lockedInStreamSpec;
+
+ bool needMtLock = false;
+
+ if (folderInfo.PackStreams.Size() > 1)
+ {
+ // lockedInStream.Pos = (UInt64)(Int64)-1;
+ // RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &lockedInStream.Pos));
+ RINOK(inStream->Seek(startPos + packPositions[0], STREAM_SEEK_SET, &lockedInStreamSpec->Pos));
+ lockedInStreamSpec->Stream = inStream;
+
+ #ifdef USE_MIXER_ST
+ if (_mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex))
+ #endif
+ needMtLock = true;
+ }
+
+ for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++)
+ {
+ CMyComPtr<ISequentialInStream> packStream;
+ UInt64 packPos = startPos + packPositions[j];
+
+ if (folderInfo.PackStreams.Size() == 1)
+ {
+ RINOK(inStream->Seek(packPos, STREAM_SEEK_SET, NULL));
+ packStream = inStream;
+ }
+ else
+ {
+ #ifdef USE_MIXER_MT
+ #ifdef USE_MIXER_ST
+ if (_useMixerMT || needMtLock)
+ #endif
+ {
+ CLockedSequentialInStreamMT *lockedStreamImpSpec = new CLockedSequentialInStreamMT;
+ packStream = lockedStreamImpSpec;
+ lockedStreamImpSpec->Init(lockedInStreamSpec, packPos);
+ }
+ #ifdef USE_MIXER_ST
+ else
+ #endif
+ #endif
+ {
+ #ifdef USE_MIXER_ST
+ CLockedSequentialInStreamST *lockedStreamImpSpec = new CLockedSequentialInStreamST;
+ packStream = lockedStreamImpSpec;
+ lockedStreamImpSpec->Init(lockedInStreamSpec, packPos);
+ #endif
+ }
+ }
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ inStreams.AddNew() = streamSpec;
+ streamSpec->SetStream(packStream);
+ streamSpec->Init(packPositions[j + 1] - packPositions[j]);
+ }
+
+ unsigned num = inStreams.Size();
+ CObjArray<ISequentialInStream *> inStreamPointers(num);
+ for (i = 0; i < num; i++)
+ inStreamPointers[i] = inStreams[i];
+
+ if (outStream)
+ {
+ CMyComPtr<ICompressProgressInfo> progress2;
+ if (compressProgress && !_mixer->Is_PackSize_Correct_for_Coder(_mixer->MainCoderIndex))
+ progress2 = new CDecProgress(compressProgress);
+
+ ISequentialOutStream *outStreamPointer = outStream;
+ return _mixer->Code(inStreamPointers, &outStreamPointer, progress2 ? (ICompressProgressInfo *)progress2 : compressProgress);
+ }
+
+ #ifdef USE_MIXER_ST
+ return _mixerST->GetMainUnpackStream(inStreamPointers, inStreamMainRes);
+ #else
+ return E_FAIL;
+ #endif
}
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h
index d8a424a36c9..5b729f6c86d 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h
@@ -3,25 +3,17 @@
#ifndef __7Z_DECODE_H
#define __7Z_DECODE_H
-#include "../../IStream.h"
-#include "../../IPassword.h"
-
#include "../Common/CoderMixer2.h"
-#include "../Common/CoderMixer2MT.h"
-#ifdef _ST_MODE
-#include "../Common/CoderMixer2ST.h"
-#endif
-
-#include "../../Common/CreateCoder.h"
-#include "7zItem.h"
+#include "7zIn.h"
namespace NArchive {
namespace N7z {
-struct CBindInfoEx: public NCoderMixer::CBindInfo
+struct CBindInfoEx: public NCoderMixer2::CBindInfo
{
CRecordVector<CMethodId> CoderMethodIDs;
+
void Clear()
{
CBindInfo::Clear();
@@ -31,32 +23,40 @@ struct CBindInfoEx: public NCoderMixer::CBindInfo
class CDecoder
{
- bool _bindInfoExPrevIsDefined;
- CBindInfoEx _bindInfoExPrev;
+ bool _bindInfoPrev_Defined;
+ CBindInfoEx _bindInfoPrev;
+
+ bool _useMixerMT;
+
+ #ifdef USE_MIXER_ST
+ NCoderMixer2::CMixerST *_mixerST;
+ #endif
- bool _multiThread;
- #ifdef _ST_MODE
- NCoderMixer::CCoderMixer2ST *_mixerCoderSTSpec;
+ #ifdef USE_MIXER_MT
+ NCoderMixer2::CMixerMT *_mixerMT;
#endif
- NCoderMixer::CCoderMixer2MT *_mixerCoderMTSpec;
- NCoderMixer::CCoderMixer2 *_mixerCoderCommon;
- CMyComPtr<ICompressCoder2> _mixerCoder;
- CObjectVector<CMyComPtr<IUnknown> > _decoders;
- // CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
+ NCoderMixer2::CMixer *_mixer;
+ CMyComPtr<IUnknown> _mixerRef;
+
public:
- CDecoder(bool multiThread);
+
+ CDecoder(bool useMixerMT);
+
HRESULT Decode(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
UInt64 startPos,
- const UInt64 *packSizes,
- const CFolder &folder,
- ISequentialOutStream *outStream,
- ICompressProgressInfo *compressProgress
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPasswordSpec, bool &passwordIsDefined
- #endif
+ const CFolders &folders, unsigned folderIndex,
+ const UInt64 *unpackSize // if (!unpackSize), then full folder is required
+ // if (unpackSize), then only *unpackSize bytes from folder are required
+
+ , ISequentialOutStream *outStream
+ , ICompressProgressInfo *compressProgress
+ , ISequentialInStream **inStreamMainRes
+
+ _7Z_DECODER_CRYPRO_VARS_DECL
+
#if !defined(_7ZIP_ST) && !defined(_SFX)
, bool mtMode, UInt32 numThreads
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp
index 614f9913d15..ab251711fd2 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp
@@ -12,43 +12,80 @@
#include "7zEncode.h"
#include "7zSpecStream.h"
-static const UInt64 k_Delta = 0x03;
-static const UInt64 k_BCJ = 0x03030103;
-static const UInt64 k_BCJ2 = 0x0303011B;
-
namespace NArchive {
namespace N7z {
-static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindInfo,
- const CRecordVector<CMethodId> decompressionMethods,
- CFolder &folder)
+void CEncoder::InitBindConv()
{
- folder.Coders.Clear();
- // bindInfo.CoderMethodIDs.Clear();
- // folder.OutStreams.Clear();
- folder.PackStreams.Clear();
- folder.BindPairs.Clear();
- int i;
- for (i = 0; i < bindInfo.BindPairs.Size(); i++)
+ unsigned numIn = _bindInfo.Coders.Size();
+
+ _SrcIn_to_DestOut.ClearAndSetSize(numIn);
+ _DestOut_to_SrcIn.ClearAndSetSize(numIn);
+
+ unsigned numOut = _bindInfo.GetNum_Bonds_and_PackStreams();
+ _SrcOut_to_DestIn.ClearAndSetSize(numOut);
+ // _DestIn_to_SrcOut.ClearAndSetSize(numOut);
+
+ UInt32 destIn = 0;
+ UInt32 destOut = 0;
+
+ for (unsigned i = _bindInfo.Coders.Size(); i != 0;)
+ {
+ i--;
+
+ const NCoderMixer2::CCoderStreamsInfo &coder = _bindInfo.Coders[i];
+
+ numIn--;
+ numOut -= coder.NumStreams;
+
+ _SrcIn_to_DestOut[numIn] = destOut;
+ _DestOut_to_SrcIn[destOut] = numIn;
+
+ destOut++;
+
+ for (UInt32 j = 0; j < coder.NumStreams; j++, destIn++)
+ {
+ UInt32 index = numOut + j;
+ _SrcOut_to_DestIn[index] = destIn;
+ // _DestIn_to_SrcOut[destIn] = index;
+ }
+ }
+}
+
+void CEncoder::SetFolder(CFolder &folder)
+{
+ folder.Bonds.SetSize(_bindInfo.Bonds.Size());
+
+ unsigned i;
+
+ for (i = 0; i < _bindInfo.Bonds.Size(); i++)
{
- CBindPair bindPair;
- bindPair.InIndex = bindInfo.BindPairs[i].InIndex;
- bindPair.OutIndex = bindInfo.BindPairs[i].OutIndex;
- folder.BindPairs.Add(bindPair);
+ CBond &fb = folder.Bonds[i];
+ const NCoderMixer2::CBond &mixerBond = _bindInfo.Bonds[_bindInfo.Bonds.Size() - 1 - i];
+ fb.PackIndex = _SrcOut_to_DestIn[mixerBond.PackIndex];
+ fb.UnpackIndex = _SrcIn_to_DestOut[mixerBond.UnpackIndex];
}
- for (i = 0; i < bindInfo.Coders.Size(); i++)
+
+ folder.Coders.SetSize(_bindInfo.Coders.Size());
+
+ for (i = 0; i < _bindInfo.Coders.Size(); i++)
{
- CCoderInfo coderInfo;
- const NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
- coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;
- coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;
- coderInfo.MethodID = decompressionMethods[i];
- folder.Coders.Add(coderInfo);
+ CCoderInfo &coderInfo = folder.Coders[i];
+ const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[_bindInfo.Coders.Size() - 1 - i];
+
+ coderInfo.NumStreams = coderStreamsInfo.NumStreams;
+ coderInfo.MethodID = _decompressionMethods[i];
+ // we don't free coderInfo.Props here. So coderInfo.Props can be non-empty.
}
- for (i = 0; i < bindInfo.InStreams.Size(); i++)
- folder.PackStreams.Add(bindInfo.InStreams[i]);
+
+ folder.PackStreams.SetSize(_bindInfo.PackStreams.Size());
+
+ for (i = 0; i < _bindInfo.PackStreams.Size(); i++)
+ folder.PackStreams[i] = _SrcOut_to_DestIn[_bindInfo.PackStreams[i]];
}
+
+
static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder)
{
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
@@ -58,31 +95,75 @@ static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce,
return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK;
}
+
+
+void CMtEncMultiProgress::Init(ICompressProgressInfo *progress)
+{
+ _progress = progress;
+ OutSize = 0;
+}
+
+STDMETHODIMP CMtEncMultiProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)
+{
+ UInt64 outSize2;
+ {
+ #ifndef _7ZIP_ST
+ NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
+ #endif
+ outSize2 = OutSize;
+ }
+
+ if (_progress)
+ return _progress->SetRatioInfo(inSize, &outSize2);
+
+ return S_OK;
+}
+
+
+
HRESULT CEncoder::CreateMixerCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
const UInt64 *inSizeForReduce)
{
- _mixerCoderSpec = new NCoderMixer::CCoderMixer2MT;
- _mixerCoder = _mixerCoderSpec;
- RINOK(_mixerCoderSpec->SetBindInfo(_bindInfo));
- for (int i = 0; i < _options.Methods.Size(); i++)
+ #ifdef USE_MIXER_MT
+ #ifdef USE_MIXER_ST
+ if (_options.MultiThreadMixer)
+ #endif
+ {
+ _mixerMT = new NCoderMixer2::CMixerMT(true);
+ _mixerRef = _mixerMT;
+ _mixer = _mixerMT;
+ }
+ #ifdef USE_MIXER_ST
+ else
+ #endif
+ #endif
+ {
+ #ifdef USE_MIXER_ST
+ _mixerST = new NCoderMixer2::CMixerST(true);
+ _mixerRef = _mixerST;
+ _mixer = _mixerST;
+ #endif
+ }
+
+ RINOK(_mixer->SetBindInfo(_bindInfo));
+
+ FOR_VECTOR (i, _options.Methods)
{
const CMethodFull &methodFull = _options.Methods[i];
- _codersInfo.Add(CCoderInfo());
- CCoderInfo &encodingInfo = _codersInfo.Back();
- encodingInfo.MethodID = methodFull.Id;
- CMyComPtr<ICompressCoder> encoder;
- CMyComPtr<ICompressCoder2> encoder2;
-
+ CCreatedCoder cod;
+
RINOK(CreateCoder(
EXTERNAL_CODECS_LOC_VARS
- methodFull.Id, encoder, encoder2, true));
+ methodFull.Id, true, cod));
- if (!encoder && !encoder2)
+ if (cod.NumStreams != methodFull.NumStreams)
+ return E_FAIL;
+ if (!cod.Coder && !cod.Coder2)
return E_FAIL;
- CMyComPtr<IUnknown> encoderCommon = encoder ? (IUnknown *)encoder : (IUnknown *)encoder2;
+ CMyComPtr<IUnknown> encoderCommon = cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2;
#ifndef _7ZIP_ST
{
@@ -100,78 +181,151 @@ HRESULT CEncoder::CreateMixerCoder(
/*
CMyComPtr<ICryptoResetSalt> resetSalt;
encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt);
- if (resetSalt != NULL)
+ if (resetSalt)
{
resetSalt->ResetSalt();
}
*/
+ // now there is no codec that uses another external codec
+ /*
#ifdef EXTERNAL_CODECS
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
if (setCompressCodecsInfo)
{
- RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));
+ // we must use g_ExternalCodecs also
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
}
#endif
+ */
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
if (cryptoSetPassword)
{
- CByteBuffer buffer;
- const UInt32 sizeInBytes = _options.Password.Length() * 2;
- buffer.SetCapacity(sizeInBytes);
- for (int i = 0; i < _options.Password.Length(); i++)
+ const unsigned sizeInBytes = _options.Password.Len() * 2;
+ CByteBuffer buffer(sizeInBytes);
+ for (unsigned i = 0; i < _options.Password.Len(); i++)
{
wchar_t c = _options.Password[i];
((Byte *)buffer)[i * 2] = (Byte)c;
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
}
- RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
+ RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)sizeInBytes));
}
- if (encoder)
- _mixerCoderSpec->AddCoder(encoder);
- else
- _mixerCoderSpec->AddCoder2(encoder2);
+ _mixer->AddCoder(cod);
}
return S_OK;
}
+
+
+class CSequentialOutTempBufferImp2:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CInOutTempBuffer *_buf;
+public:
+ CMtEncMultiProgress *_mtProgresSpec;
+
+ CSequentialOutTempBufferImp2(): _buf(0), _mtProgresSpec(NULL) {}
+ void Init(CInOutTempBuffer *buffer) { _buf = buffer; }
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed)
+{
+ if (!_buf->Write(data, size))
+ {
+ if (processed)
+ *processed = 0;
+ return E_FAIL;
+ }
+ if (processed)
+ *processed = size;
+ if (_mtProgresSpec)
+ _mtProgresSpec->AddOutSize(size);
+ return S_OK;
+}
+
+
+class CSequentialOutMtNotify:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ CMyComPtr<ISequentialOutStream> _stream;
+ CMtEncMultiProgress *_mtProgresSpec;
+
+ CSequentialOutMtNotify(): _mtProgresSpec(NULL) {}
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CSequentialOutMtNotify::Write(const void *data, UInt32 size, UInt32 *processed)
+{
+ UInt32 realProcessed = 0;
+ HRESULT res = _stream->Write(data, size, &realProcessed);
+ if (processed)
+ *processed = realProcessed;
+ if (_mtProgresSpec)
+ _mtProgresSpec->AddOutSize(size);
+ return res;
+}
+
+
+
HRESULT CEncoder::Encode(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream,
- const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
+ // const UInt64 *inStreamSize,
+ const UInt64 *inSizeForReduce,
CFolder &folderItem,
+ CRecordVector<UInt64> &coderUnpackSizes,
+ UInt64 &unpackSize,
ISequentialOutStream *outStream,
CRecordVector<UInt64> &packSizes,
ICompressProgressInfo *compressProgress)
{
RINOK(EncoderConstr());
- if (_mixerCoderSpec == NULL)
+ if (!_mixerRef)
{
RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
}
- _mixerCoderSpec->ReInit();
- // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);
+
+ _mixer->ReInit();
+
+ CMtEncMultiProgress *mtProgressSpec = NULL;
+ CMyComPtr<ICompressProgressInfo> mtProgress;
+
+ CSequentialOutMtNotify *mtOutStreamNotifySpec = NULL;
+ CMyComPtr<ISequentialOutStream> mtOutStreamNotify;
CObjectVector<CInOutTempBuffer> inOutTempBuffers;
- CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
+ CObjectVector<CSequentialOutTempBufferImp2 *> tempBufferSpecs;
CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
- int numMethods = _bindInfo.Coders.Size();
- int i;
- for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+
+ unsigned numMethods = _bindInfo.Coders.Size();
+
+ unsigned i;
+
+ for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
{
- inOutTempBuffers.Add(CInOutTempBuffer());
- inOutTempBuffers.Back().Create();
- inOutTempBuffers.Back().InitWriting();
+ CInOutTempBuffer &iotb = inOutTempBuffers.AddNew();
+ iotb.Create();
+ iotb.InitWriting();
}
- for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+
+ for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
{
- CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp;
+ CSequentialOutTempBufferImp2 *tempBufferSpec = new CSequentialOutTempBufferImp2;
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
tempBuffers.Add(tempBuffer);
@@ -179,120 +333,157 @@ HRESULT CEncoder::Encode(
}
for (i = 0; i < numMethods; i++)
- _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);
+ _mixer->SetCoderInfo(i, NULL, NULL);
- if (_bindInfo.InStreams.IsEmpty())
- return E_FAIL;
- UInt32 mainCoderIndex, mainStreamIndex;
- _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
-
- if (inStreamSize != NULL)
- {
- CRecordVector<const UInt64 *> sizePointers;
- for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
- if (i == mainStreamIndex)
- sizePointers.Add(inStreamSize);
- else
- sizePointers.Add(NULL);
- _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
- }
-
- // UInt64 outStreamStartPos;
- // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
+ /* inStreamSize can be used by BCJ2 to set optimal range of conversion.
+ But current BCJ2 encoder uses also another way to check exact size of current file.
+ So inStreamSize is not required. */
+
+ /*
+ if (inStreamSize)
+ _mixer->SetCoderInfo(_bindInfo.UnpackCoder, inStreamSize, NULL);
+ */
+
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
- CSequentialOutStreamSizeCount *outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
- CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
+
+ CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL;
+ CMyComPtr<ISequentialOutStream> outStreamSizeCount;
inStreamSizeCountSpec->Init(inStream);
- outStreamSizeCountSpec->SetStream(outStream);
- outStreamSizeCountSpec->Init();
- CRecordVector<ISequentialInStream *> inStreamPointers;
+ ISequentialInStream *inStreamPointer = inStreamSizeCount;
CRecordVector<ISequentialOutStream *> outStreamPointers;
- inStreamPointers.Add(inStreamSizeCount);
- outStreamPointers.Add(outStreamSizeCount);
- for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
- outStreamPointers.Add(tempBuffers[i - 1]);
+
+ SetFolder(folderItem);
- for (i = 0; i < _codersInfo.Size(); i++)
+ for (i = 0; i < numMethods; i++)
{
- CCoderInfo &encodingInfo = _codersInfo[i];
-
+ IUnknown *coder = _mixer->GetCoder(i).GetUnknown();
+
CMyComPtr<ICryptoResetInitVector> resetInitVector;
- _mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
- if (resetInitVector != NULL)
+ coder->QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
+ if (resetInitVector)
{
resetInitVector->ResetInitVector();
}
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
- _mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
- if (writeCoderProperties != NULL)
+ coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
+
+ CByteBuffer &props = folderItem.Coders[numMethods - 1 - i].Props;
+
+ if (writeCoderProperties)
{
CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
- CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ CMyComPtr<ISequentialOutStream> dynOutStream(outStreamSpec);
outStreamSpec->Init();
- writeCoderProperties->WriteCoderProperties(outStream);
- outStreamSpec->CopyToBuffer(encodingInfo.Props);
+ writeCoderProperties->WriteCoderProperties(dynOutStream);
+ outStreamSpec->CopyToBuffer(props);
}
+ else
+ props.Free();
}
- UInt32 progressIndex = mainCoderIndex;
+ _mixer->SelectMainCoder(false);
+ UInt32 mainCoder = _mixer->MainCoderIndex;
- for (i = 0; i + 1 < _codersInfo.Size(); i++)
+ bool useMtProgress = false;
+ if (!_mixer->Is_PackSize_Correct_for_Coder(mainCoder))
{
- UInt64 m = _codersInfo[i].MethodID;
- if (m == k_Delta || m == k_BCJ || m == k_BCJ2)
- progressIndex = i + 1;
+ #ifdef _7ZIP_ST
+ if (!_mixer->IsThere_ExternalCoder_in_PackTree(mainCoder))
+ #endif
+ useMtProgress = true;
}
- _mixerCoderSpec->SetProgressCoderIndex(progressIndex);
+ if (useMtProgress)
+ {
+ mtProgressSpec = new CMtEncMultiProgress;
+ mtProgress = mtProgressSpec;
+ mtProgressSpec->Init(compressProgress);
+
+ mtOutStreamNotifySpec = new CSequentialOutMtNotify;
+ mtOutStreamNotify = mtOutStreamNotifySpec;
+ mtOutStreamNotifySpec->_stream = outStream;
+ mtOutStreamNotifySpec->_mtProgresSpec = mtProgressSpec;
+
+ FOR_VECTOR(i, tempBufferSpecs)
+ {
+ tempBufferSpecs[i]->_mtProgresSpec = mtProgressSpec;
+ }
+ }
- RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
- &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
- ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem);
+ if (_bindInfo.PackStreams.Size() != 0)
+ {
+ outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
+ outStreamSizeCount = outStreamSizeCountSpec;
+ outStreamSizeCountSpec->SetStream(mtOutStreamNotify ? (ISequentialOutStream *)mtOutStreamNotify : outStream);
+ outStreamSizeCountSpec->Init();
+ outStreamPointers.Add(outStreamSizeCount);
+ }
+
+ for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
+ outStreamPointers.Add(tempBuffers[i - 1]);
+
+ RINOK(_mixer->Code(
+ &inStreamPointer,
+ &outStreamPointers.Front(),
+ mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress));
- packSizes.Add(outStreamSizeCountSpec->GetSize());
+ if (_bindInfo.PackStreams.Size() != 0)
+ packSizes.Add(outStreamSizeCountSpec->GetSize());
- for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+ for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
{
CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
RINOK(inOutTempBuffer.WriteToStream(outStream));
packSizes.Add(inOutTempBuffer.GetDataSize());
}
+
+ unpackSize = 0;
- for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
+ for (i = 0; i < _bindInfo.Coders.Size(); i++)
{
- int binder = _bindInfo.FindBinderForInStream(
- _bindReverseConverter->DestOutToSrcInMap[i]);
+ int bond = _bindInfo.FindBond_for_UnpackStream(_DestOut_to_SrcIn[i]);
UInt64 streamSize;
- if (binder < 0)
+ if (bond < 0)
+ {
streamSize = inStreamSizeCountSpec->GetSize();
+ unpackSize = streamSize;
+ }
else
- streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
- folderItem.UnpackSizes.Add(streamSize);
+ streamSize = _mixer->GetBondStreamSize(bond);
+ coderUnpackSizes.Add(streamSize);
}
- for (i = numMethods - 1; i >= 0; i--)
- folderItem.Coders[numMethods - 1 - i].Props = _codersInfo[i].Props;
+
return S_OK;
}
CEncoder::CEncoder(const CCompressionMethodMode &options):
- _bindReverseConverter(0),
- _constructed(false)
+ _constructed(false)
{
if (options.IsEmpty())
throw 1;
_options = options;
- _mixerCoderSpec = NULL;
+
+ #ifdef USE_MIXER_ST
+ _mixerST = NULL;
+ #endif
+
+ #ifdef USE_MIXER_MT
+ _mixerMT = NULL;
+ #endif
+
+ _mixer = NULL;
}
+
HRESULT CEncoder::EncoderConstr()
{
if (_constructed)
@@ -302,112 +493,125 @@ HRESULT CEncoder::EncoderConstr()
// it has only password method;
if (!_options.PasswordIsDefined)
throw 1;
- if (!_options.Binds.IsEmpty())
+ if (!_options.Bonds.IsEmpty())
throw 1;
- NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
+
CMethodFull method;
-
- method.NumInStreams = 1;
- method.NumOutStreams = 1;
- coderStreamsInfo.NumInStreams = 1;
- coderStreamsInfo.NumOutStreams = 1;
method.Id = k_AES;
-
+ method.NumStreams = 1;
_options.Methods.Add(method);
+
+ NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
+ coderStreamsInfo.NumStreams = 1;
_bindInfo.Coders.Add(coderStreamsInfo);
- _bindInfo.InStreams.Add(0);
- _bindInfo.OutStreams.Add(0);
+ _bindInfo.PackStreams.Add(0);
+ _bindInfo.UnpackCoder = 0;
}
else
{
- UInt32 numInStreams = 0, numOutStreams = 0;
- int i;
+ UInt32 numOutStreams = 0;
+ unsigned i;
+
for (i = 0; i < _options.Methods.Size(); i++)
{
const CMethodFull &methodFull = _options.Methods[i];
- NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
- coderStreamsInfo.NumInStreams = methodFull.NumOutStreams;
- coderStreamsInfo.NumOutStreams = methodFull.NumInStreams;
- if (_options.Binds.IsEmpty())
+ NCoderMixer2::CCoderStreamsInfo cod;
+
+ cod.NumStreams = methodFull.NumStreams;
+
+ if (_options.Bonds.IsEmpty())
{
- if (i < _options.Methods.Size() - 1)
+ // if there are no bonds in options, we create bonds via first streams of coders
+ if (i != _options.Methods.Size() - 1)
{
- NCoderMixer::CBindPair bindPair;
- bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams;
- bindPair.OutIndex = numOutStreams;
- _bindInfo.BindPairs.Add(bindPair);
+ NCoderMixer2::CBond bond;
+ bond.PackIndex = numOutStreams;
+ bond.UnpackIndex = i + 1; // it's next coder
+ _bindInfo.Bonds.Add(bond);
}
- else
- _bindInfo.OutStreams.Insert(0, numOutStreams);
- for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
- _bindInfo.OutStreams.Add(numOutStreams + j);
+ else if (cod.NumStreams != 0)
+ _bindInfo.PackStreams.Insert(0, numOutStreams);
+
+ for (UInt32 j = 1; j < cod.NumStreams; j++)
+ _bindInfo.PackStreams.Add(numOutStreams + j);
}
- numInStreams += coderStreamsInfo.NumInStreams;
- numOutStreams += coderStreamsInfo.NumOutStreams;
+ numOutStreams += cod.NumStreams;
- _bindInfo.Coders.Add(coderStreamsInfo);
+ _bindInfo.Coders.Add(cod);
}
- if (!_options.Binds.IsEmpty())
+ if (!_options.Bonds.IsEmpty())
{
- for (i = 0; i < _options.Binds.Size(); i++)
+ for (i = 0; i < _options.Bonds.Size(); i++)
{
- NCoderMixer::CBindPair bindPair;
- const CBind &bind = _options.Binds[i];
- bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream;
- bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;
- _bindInfo.BindPairs.Add(bindPair);
+ NCoderMixer2::CBond mixerBond;
+ const CBond2 &bond = _options.Bonds[i];
+ if (bond.InCoder >= _bindInfo.Coders.Size()
+ || bond.OutCoder >= _bindInfo.Coders.Size()
+ || bond.OutStream >= _bindInfo.Coders[bond.OutCoder].NumStreams)
+ return E_INVALIDARG;
+ mixerBond.PackIndex = _bindInfo.GetStream_for_Coder(bond.OutCoder) + bond.OutStream;
+ mixerBond.UnpackIndex = bond.InCoder;
+ _bindInfo.Bonds.Add(mixerBond);
}
- for (i = 0; i < (int)numOutStreams; i++)
- if (_bindInfo.FindBinderForOutStream(i) == -1)
- _bindInfo.OutStreams.Add(i);
+
+ for (i = 0; i < numOutStreams; i++)
+ if (_bindInfo.FindBond_for_PackStream(i) == -1)
+ _bindInfo.PackStreams.Add(i);
}
- for (i = 0; i < (int)numInStreams; i++)
- if (_bindInfo.FindBinderForInStream(i) == -1)
- _bindInfo.InStreams.Add(i);
+ if (!_bindInfo.SetUnpackCoder())
+ return E_INVALIDARG;
- if (_bindInfo.InStreams.IsEmpty())
- throw 1; // this is error
+ if (!_bindInfo.CalcMapsAndCheck())
+ return E_INVALIDARG;
- // Make main stream first in list
- int inIndex = _bindInfo.InStreams[0];
- for (;;)
+ if (_bindInfo.PackStreams.Size() != 1)
{
- UInt32 coderIndex, coderStreamIndex;
- _bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
- UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
- int binder = _bindInfo.FindBinderForOutStream(outIndex);
- if (binder >= 0)
+ /* main_PackStream is pack stream of main path of coders tree.
+ We find main_PackStream, and place to start of list of out streams.
+ It allows to use more optimal memory usage for temp buffers,
+ if main_PackStream is largest stream. */
+
+ UInt32 ci = _bindInfo.UnpackCoder;
+
+ for (;;)
{
- inIndex = _bindInfo.BindPairs[binder].InIndex;
- continue;
- }
- for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
- if (_bindInfo.OutStreams[i] == outIndex)
- {
- _bindInfo.OutStreams.Delete(i);
- _bindInfo.OutStreams.Insert(0, outIndex);
+ if (_bindInfo.Coders[ci].NumStreams == 0)
break;
+
+ UInt32 outIndex = _bindInfo.Coder_to_Stream[ci];
+ int bond = _bindInfo.FindBond_for_PackStream(outIndex);
+ if (bond >= 0)
+ {
+ ci = _bindInfo.Bonds[bond].UnpackIndex;
+ continue;
}
- break;
+
+ int i = _bindInfo.FindStream_in_PackStreams(outIndex);
+ if (i >= 0)
+ _bindInfo.PackStreams.MoveToFront(i);
+ break;
+ }
}
if (_options.PasswordIsDefined)
{
- int numCryptoStreams = _bindInfo.OutStreams.Size();
+ unsigned numCryptoStreams = _bindInfo.PackStreams.Size();
+ unsigned numInStreams = _bindInfo.Coders.Size();
+
for (i = 0; i < numCryptoStreams; i++)
{
- NCoderMixer::CBindPair bindPair;
- bindPair.InIndex = numInStreams + i;
- bindPair.OutIndex = _bindInfo.OutStreams[i];
- _bindInfo.BindPairs.Add(bindPair);
+ NCoderMixer2::CBond bond;
+ bond.UnpackIndex = numInStreams + i;
+ bond.PackIndex = _bindInfo.PackStreams[i];
+ _bindInfo.Bonds.Add(bond);
}
- _bindInfo.OutStreams.Clear();
+ _bindInfo.PackStreams.Clear();
/*
if (numCryptoStreams == 0)
@@ -416,37 +620,37 @@ HRESULT CEncoder::EncoderConstr()
for (i = 0; i < numCryptoStreams; i++)
{
- NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
CMethodFull method;
- method.NumInStreams = 1;
- method.NumOutStreams = 1;
- coderStreamsInfo.NumInStreams = method.NumOutStreams;
- coderStreamsInfo.NumOutStreams = method.NumInStreams;
+ method.NumStreams = 1;
method.Id = k_AES;
-
_options.Methods.Add(method);
- _bindInfo.Coders.Add(coderStreamsInfo);
- _bindInfo.OutStreams.Add(numOutStreams + i);
+
+ NCoderMixer2::CCoderStreamsInfo cod;
+ cod.NumStreams = 1;
+ _bindInfo.Coders.Add(cod);
+
+ _bindInfo.PackStreams.Add(numOutStreams++);
}
}
}
- for (int i = _options.Methods.Size() - 1; i >= 0; i--)
- {
- const CMethodFull &methodFull = _options.Methods[i];
- _decompressionMethods.Add(methodFull.Id);
- }
+ for (unsigned i = _options.Methods.Size(); i != 0;)
+ _decompressionMethods.Add(_options.Methods[--i].Id);
- _bindReverseConverter = new NCoderMixer::CBindReverseConverter(_bindInfo);
- _bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo);
+ if (_bindInfo.Coders.Size() > 16)
+ return E_INVALIDARG;
+ if (_bindInfo.GetNum_Bonds_and_PackStreams() > 16)
+ return E_INVALIDARG;
+
+ if (!_bindInfo.CalcMapsAndCheck())
+ return E_INVALIDARG;
+
+ InitBindConv();
_constructed = true;
return S_OK;
}
-CEncoder::~CEncoder()
-{
- delete _bindReverseConverter;
-}
+CEncoder::~CEncoder() {}
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h
index 4909a6e8972..f1a9b5ad720 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h
@@ -3,48 +3,85 @@
#ifndef __7Z_ENCODE_H
#define __7Z_ENCODE_H
-// #include "../../Common/StreamObjects.h"
-
#include "7zCompressionMode.h"
#include "../Common/CoderMixer2.h"
-#include "../Common/CoderMixer2MT.h"
-#ifdef _ST_MODE
-#include "../Common/CoderMixer2ST.h"
-#endif
-#include "7zItem.h"
-#include "../../Common/CreateCoder.h"
+#include "7zItem.h"
namespace NArchive {
namespace N7z {
-class CEncoder
+class CMtEncMultiProgress:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
{
- NCoderMixer::CCoderMixer2MT *_mixerCoderSpec;
- CMyComPtr<ICompressCoder2> _mixerCoder;
+ CMyComPtr<ICompressProgressInfo> _progress;
+ #ifndef _7ZIP_ST
+ NWindows::NSynchronization::CCriticalSection CriticalSection;
+ #endif
+
+public:
+ UInt64 OutSize;
+
+ CMtEncMultiProgress(): OutSize(0) {}
+
+ void Init(ICompressProgressInfo *progress);
- CObjectVector<CCoderInfo> _codersInfo;
+ void AddOutSize(UInt64 addOutSize)
+ {
+ #ifndef _7ZIP_ST
+ NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
+ #endif
+ OutSize += addOutSize;
+ }
+
+ MY_UNKNOWN_IMP1(ICompressProgressInfo)
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+class CEncoder
+{
+ #ifdef USE_MIXER_ST
+ NCoderMixer2::CMixerST *_mixerST;
+ #endif
+ #ifdef USE_MIXER_MT
+ NCoderMixer2::CMixerMT *_mixerMT;
+ #endif
+
+ NCoderMixer2::CMixer *_mixer;
+ CMyComPtr<IUnknown> _mixerRef;
CCompressionMethodMode _options;
- NCoderMixer::CBindInfo _bindInfo;
- NCoderMixer::CBindInfo _decompressBindInfo;
- NCoderMixer::CBindReverseConverter *_bindReverseConverter;
+ NCoderMixer2::CBindInfo _bindInfo;
CRecordVector<CMethodId> _decompressionMethods;
+ CRecordVector<UInt32> _SrcIn_to_DestOut;
+ CRecordVector<UInt32> _SrcOut_to_DestIn;
+ // CRecordVector<UInt32> _DestIn_to_SrcOut;
+ CRecordVector<UInt32> _DestOut_to_SrcIn;
+
+ void InitBindConv();
+ void SetFolder(CFolder &folder);
+
HRESULT CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS
const UInt64 *inSizeForReduce);
bool _constructed;
public:
+
CEncoder(const CCompressionMethodMode &options);
~CEncoder();
HRESULT EncoderConstr();
HRESULT Encode(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream,
- const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
+ // const UInt64 *inStreamSize,
+ const UInt64 *inSizeForReduce,
CFolder &folderItem,
+ CRecordVector<UInt64> &coderUnpackSizes,
+ UInt64 &unpackSize,
ISequentialOutStream *outStream,
CRecordVector<UInt64> &packSizes,
ICompressProgressInfo *compressProgress);
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp
index d55f38e131d..8396516423c 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp
@@ -2,210 +2,334 @@
#include "StdAfx.h"
+#include "../../../../C/7zCrc.h"
+
#include "../../../Common/ComTry.h"
#include "../../Common/ProgressUtils.h"
#include "7zDecode.h"
-// #include "7z1Decode.h"
-#include "7zFolderOutStream.h"
#include "7zHandler.h"
+// EXTERN_g_ExternalCodecs
+
namespace NArchive {
namespace N7z {
-struct CExtractFolderInfo
+class CFolderOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
{
- #ifdef _7Z_VOL
- int VolumeIndex;
- #endif
- CNum FileIndex;
- CNum FolderIndex;
- CBoolVector ExtractStatuses;
- UInt64 UnpackSize;
- CExtractFolderInfo(
- #ifdef _7Z_VOL
- int volumeIndex,
- #endif
- CNum fileIndex, CNum folderIndex):
- #ifdef _7Z_VOL
- VolumeIndex(volumeIndex),
- #endif
- FileIndex(fileIndex),
- FolderIndex(folderIndex),
- UnpackSize(0)
+ CMyComPtr<ISequentialOutStream> _stream;
+public:
+ bool TestMode;
+ bool CheckCrc;
+private:
+ bool _fileIsOpen;
+ bool _calcCrc;
+ UInt32 _crc;
+ UInt64 _rem;
+
+ const UInt32 *_indexes;
+ unsigned _numFiles;
+ unsigned _fileIndex;
+
+ HRESULT OpenFile(bool isCorrupted = false);
+ HRESULT CloseFile_and_SetResult(Int32 res);
+ HRESULT CloseFile();
+ HRESULT ProcessEmptyFiles();
+
+public:
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
+
+ const CDbEx *_db;
+ CMyComPtr<IArchiveExtractCallback> ExtractCallback;
+
+ bool ExtraWriteWasCut;
+
+ CFolderOutStream():
+ TestMode(false),
+ CheckCrc(true)
+ {}
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+
+ HRESULT Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles);
+ HRESULT FlushCorrupted(Int32 callbackOperationResult);
+
+ bool WasWritingFinished() const { return _numFiles == 0; }
+};
+
+
+HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles)
+{
+ _fileIndex = startIndex;
+ _indexes = indexes;
+ _numFiles = numFiles;
+
+ _fileIsOpen = false;
+ ExtraWriteWasCut = false;
+
+ return ProcessEmptyFiles();
+}
+
+HRESULT CFolderOutStream::OpenFile(bool isCorrupted)
+{
+ const CFileItem &fi = _db->Files[_fileIndex];
+ UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex);
+ Int32 askMode = (_fileIndex == nextFileIndex) ?
+ (TestMode ?
+ NExtract::NAskMode::kTest :
+ NExtract::NAskMode::kExtract) :
+ NExtract::NAskMode::kSkip;
+
+ if (isCorrupted
+ && askMode == NExtract::NAskMode::kExtract
+ && !_db->IsItemAnti(_fileIndex)
+ && !fi.IsDir)
+ askMode = NExtract::NAskMode::kTest;
+
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode));
+
+ _stream = realOutStream;
+ _crc = CRC_INIT_VAL;
+ _calcCrc = (CheckCrc && fi.CrcDefined && !fi.IsDir);
+
+ _fileIsOpen = true;
+ _rem = fi.Size;
+
+ if (askMode == NExtract::NAskMode::kExtract
+ && !realOutStream
+ && !_db->IsItemAnti(_fileIndex)
+ && !fi.IsDir)
+ askMode = NExtract::NAskMode::kSkip;
+ return ExtractCallback->PrepareOperation(askMode);
+}
+
+HRESULT CFolderOutStream::CloseFile_and_SetResult(Int32 res)
+{
+ _stream.Release();
+ _fileIsOpen = false;
+
+ if (!_indexes)
+ _numFiles--;
+ else if (*_indexes == _fileIndex)
{
- if (fileIndex != kNumNoIndex)
+ _indexes++;
+ _numFiles--;
+ }
+
+ _fileIndex++;
+ return ExtractCallback->SetOperationResult(res);
+}
+
+HRESULT CFolderOutStream::CloseFile()
+{
+ const CFileItem &fi = _db->Files[_fileIndex];
+ return CloseFile_and_SetResult((!_calcCrc || fi.Crc == CRC_GET_DIGEST(_crc)) ?
+ NExtract::NOperationResult::kOK :
+ NExtract::NOperationResult::kCRCError);
+}
+
+HRESULT CFolderOutStream::ProcessEmptyFiles()
+{
+ while (_numFiles != 0 && _db->Files[_fileIndex].Size == 0)
+ {
+ RINOK(OpenFile());
+ RINOK(CloseFile());
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+
+ while (size != 0)
+ {
+ if (_fileIsOpen)
{
- ExtractStatuses.Reserve(1);
- ExtractStatuses.Add(true);
+ UInt32 cur = (size < _rem ? size : (UInt32)_rem);
+ HRESULT result = S_OK;
+ if (_stream)
+ result = _stream->Write(data, cur, &cur);
+ if (_calcCrc)
+ _crc = CrcUpdate(_crc, data, cur);
+ if (processedSize)
+ *processedSize += cur;
+ data = (const Byte *)data + cur;
+ size -= cur;
+ _rem -= cur;
+ if (_rem == 0)
+ {
+ RINOK(CloseFile());
+ RINOK(ProcessEmptyFiles());
+ }
+ RINOK(result);
+ if (cur == 0)
+ break;
+ continue;
}
- };
-};
+
+ RINOK(ProcessEmptyFiles());
+ if (_numFiles == 0)
+ {
+ // we support partial extracting
+ /*
+ if (processedSize)
+ *processedSize += size;
+ break;
+ */
+ ExtraWriteWasCut = true;
+ // return S_FALSE;
+ return k_My_HRESULT_WritingWasCut;
+ }
+ RINOK(OpenFile());
+ }
+
+ return S_OK;
+}
+
+HRESULT CFolderOutStream::FlushCorrupted(Int32 callbackOperationResult)
+{
+ while (_numFiles != 0)
+ {
+ if (_fileIsOpen)
+ {
+ RINOK(CloseFile_and_SetResult(callbackOperationResult));
+ }
+ else
+ {
+ RINOK(OpenFile(true));
+ }
+ }
+ return S_OK;
+}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
{
COM_TRY_BEGIN
- bool testMode = (testModeSpec != 0);
+
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
+
UInt64 importantTotalUnpacked = 0;
- bool allFilesMode = (numItems == (UInt32)-1);
+ // numItems = (UInt32)(Int32)-1;
+
+ bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
- numItems =
- #ifdef _7Z_VOL
- _refs.Size();
- #else
- _db.Files.Size();
- #endif
+ numItems = _db.Files.Size();
- if(numItems == 0)
+ if (numItems == 0)
return S_OK;
- /*
- if(_volumes.Size() != 1)
- return E_FAIL;
- const CVolume &volume = _volumes.Front();
- const CArchiveDatabaseEx &_db = volume.Database;
- IInStream *_inStream = volume.Stream;
- */
-
- CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
- for (UInt32 ii = 0; ii < numItems; ii++)
{
- // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
- UInt32 ref2Index = allFilesMode ? ii : indices[ii];
- // const CRef2 &ref2 = _refs[ref2Index];
-
- // for (UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
+ CNum prevFolder = kNumNoIndex;
+ UInt32 nextFile = 0;
+
+ UInt32 i;
+
+ for (i = 0; i < numItems; i++)
{
- #ifdef _7Z_VOL
- // const CRef &ref = ref2.Refs[ri];
- const CRef &ref = _refs[ref2Index];
-
- int volumeIndex = ref.VolumeIndex;
- const CVolume &volume = _volumes[volumeIndex];
- const CArchiveDatabaseEx &db = volume.Database;
- UInt32 fileIndex = ref.ItemIndex;
- #else
- const CArchiveDatabaseEx &db = _db;
- UInt32 fileIndex = ref2Index;
- #endif
-
- CNum folderIndex = db.FileIndexToFolderIndexMap[fileIndex];
+ UInt32 fileIndex = allFilesMode ? i : indices[i];
+ CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
if (folderIndex == kNumNoIndex)
- {
- extractFolderInfoVector.Add(CExtractFolderInfo(
- #ifdef _7Z_VOL
- volumeIndex,
- #endif
- fileIndex, kNumNoIndex));
continue;
- }
- if (extractFolderInfoVector.IsEmpty() ||
- folderIndex != extractFolderInfoVector.Back().FolderIndex
- #ifdef _7Z_VOL
- || volumeIndex != extractFolderInfoVector.Back().VolumeIndex
- #endif
- )
- {
- extractFolderInfoVector.Add(CExtractFolderInfo(
- #ifdef _7Z_VOL
- volumeIndex,
- #endif
- kNumNoIndex, folderIndex));
- const CFolder &folderInfo = db.Folders[folderIndex];
- UInt64 unpackSize = folderInfo.GetUnpackSize();
- importantTotalUnpacked += unpackSize;
- extractFolderInfoVector.Back().UnpackSize = unpackSize;
- }
-
- CExtractFolderInfo &efi = extractFolderInfoVector.Back();
-
- // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
- CNum startIndex = db.FolderStartFileIndex[folderIndex];
- for (CNum index = efi.ExtractStatuses.Size();
- index <= fileIndex - startIndex; index++)
- {
- // UInt64 unpackSize = _db.Files[startIndex + index].UnpackSize;
- // Count partial_folder_size
- // efi.UnpackSize += unpackSize;
- // importantTotalUnpacked += unpackSize;
- efi.ExtractStatuses.Add(index == fileIndex - startIndex);
- }
+ if (folderIndex != prevFolder || fileIndex < nextFile)
+ nextFile = _db.FolderStartFileIndex[folderIndex];
+ for (CNum index = nextFile; index <= fileIndex; index++)
+ importantTotalUnpacked += _db.Files[index].Size;
+ nextFile = fileIndex + 1;
+ prevFolder = folderIndex;
}
}
RINOK(extractCallback->SetTotal(importantTotalUnpacked));
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
CDecoder decoder(
- #ifdef _ST_MODE
- false
+ #if !defined(USE_MIXER_MT)
+ false
+ #elif !defined(USE_MIXER_ST)
+ true
+ #elif !defined(__7Z_SET_PROPERTIES)
+ #ifdef _7ZIP_ST
+ false
+ #else
+ true
+ #endif
#else
- true
+ _useMultiThreadMixer
#endif
);
- // CDecoder1 decoder;
- UInt64 totalPacked = 0;
- UInt64 totalUnpacked = 0;
UInt64 curPacked, curUnpacked;
- CLocalProgress *lps = new CLocalProgress;
- CMyComPtr<ICompressProgressInfo> progress = lps;
- lps->Init(extractCallback, false);
+ CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage;
+ extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage);
+
+ CFolderOutStream *folderOutStream = new CFolderOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
- for (int i = 0;; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)
+ folderOutStream->_db = &_db;
+ folderOutStream->ExtractCallback = extractCallback;
+ folderOutStream->TestMode = (testModeSpec != 0);
+ folderOutStream->CheckCrc = (_crcSize != 0);
+
+ for (UInt32 i = 0;; lps->OutSize += curUnpacked, lps->InSize += curPacked)
{
- lps->OutSize = totalUnpacked;
- lps->InSize = totalPacked;
RINOK(lps->SetCur());
- if (i >= extractFolderInfoVector.Size())
+ if (i >= numItems)
break;
-
- const CExtractFolderInfo &efi = extractFolderInfoVector[i];
- curUnpacked = efi.UnpackSize;
+
+ curUnpacked = 0;
curPacked = 0;
- CFolderOutStream *folderOutStream = new CFolderOutStream;
- CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
+ UInt32 fileIndex = allFilesMode ? i : indices[i];
+ CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
- #ifdef _7Z_VOL
- const CVolume &volume = _volumes[efi.VolumeIndex];
- const CArchiveDatabaseEx &db = volume.Database;
- #else
- const CArchiveDatabaseEx &db = _db;
- #endif
-
- CNum startIndex;
- if (efi.FileIndex != kNumNoIndex)
- startIndex = efi.FileIndex;
- else
- startIndex = db.FolderStartFileIndex[efi.FolderIndex];
+ UInt32 numSolidFiles = 1;
- HRESULT result = folderOutStream->Init(&db,
- #ifdef _7Z_VOL
- volume.StartRef2Index,
- #else
- 0,
- #endif
- startIndex,
- &efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0);
+ if (folderIndex != kNumNoIndex)
+ {
+ curPacked = _db.GetFolderFullPackSize(folderIndex);
+ UInt32 nextFile = fileIndex + 1;
+ fileIndex = _db.FolderStartFileIndex[folderIndex];
+ UInt32 k;
- RINOK(result);
+ for (k = i + 1; k < numItems; k++)
+ {
+ UInt32 fileIndex2 = allFilesMode ? k : indices[k];
+ if (_db.FileIndexToFolderIndexMap[fileIndex2] != folderIndex
+ || fileIndex2 < nextFile)
+ break;
+ nextFile = fileIndex2 + 1;
+ }
+
+ numSolidFiles = k - i;
+
+ for (k = fileIndex; k < nextFile; k++)
+ curUnpacked += _db.Files[k].Size;
+ }
- if (efi.FileIndex != kNumNoIndex)
- continue;
+ HRESULT result = folderOutStream->Init(fileIndex,
+ allFilesMode ? NULL : indices + i,
+ numSolidFiles);
- CNum folderIndex = efi.FolderIndex;
- const CFolder &folderInfo = db.Folders[folderIndex];
+ i += numSolidFiles;
- curPacked = _db.GetFolderFullPackSize(folderIndex);
+ RINOK(result);
- CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex];
- UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0);
+ // to test solid block with zero unpacked size we disable that code
+ if (folderOutStream->WasWritingFinished())
+ continue;
#ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
@@ -216,54 +340,66 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
try
{
#ifndef _NO_CRYPTO
- bool passwordIsDefined;
+ bool isEncrypted = false;
+ bool passwordIsDefined = false;
+ UString password;
#endif
+
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_VARS
- #ifdef _7Z_VOL
- volume.Stream,
- #else
_inStream,
- #endif
- folderStartPackPos,
- &db.PackSizes[packStreamIndex],
- folderInfo,
+ _db.ArcInfo.DataStartPosition,
+ _db, folderIndex,
+ &curUnpacked,
+
outStream,
- progress
- #ifndef _NO_CRYPTO
- , getTextPassword, passwordIsDefined
- #endif
+ progress,
+ NULL // *inStreamMainRes
+
+ _7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) && !defined(_SFX)
- , true, _numThreads
+ , true, _numThreads
#endif
);
- if (result == S_FALSE)
- {
- RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
- continue;
- }
- if (result == E_NOTIMPL)
+ if (result == S_FALSE || result == E_NOTIMPL)
{
- RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kUnSupportedMethod));
+ bool wasFinished = folderOutStream->WasWritingFinished();
+
+ int resOp = (result == S_FALSE ?
+ NExtract::NOperationResult::kDataError :
+ NExtract::NOperationResult::kUnsupportedMethod);
+
+ RINOK(folderOutStream->FlushCorrupted(resOp));
+
+ if (wasFinished)
+ {
+ // we don't show error, if it's after required files
+ if (/* !folderOutStream->ExtraWriteWasCut && */ callbackMessage)
+ {
+ RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp));
+ }
+ }
continue;
}
+
if (result != S_OK)
return result;
- if (folderOutStream->WasWritingFinished() != S_OK)
- {
- RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
- continue;
- }
+
+ RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
+ continue;
}
catch(...)
{
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
- continue;
+ // continue;
+ return E_FAIL;
}
}
+
return S_OK;
+
COM_TRY_END
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp
index edd276bc116..14cdc436452 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp
@@ -7,96 +7,103 @@
namespace NArchive {
namespace N7z {
-CFolderInStream::CFolderInStream()
-{
- _inStreamWithHashSpec = new CSequentialInStreamWithCRC;
- _inStreamWithHash = _inStreamWithHashSpec;
-}
-
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
- const UInt32 *fileIndices, UInt32 numFiles)
+ const UInt32 *indexes, unsigned numFiles)
{
_updateCallback = updateCallback;
+ _indexes = indexes;
_numFiles = numFiles;
- _fileIndex = 0;
- _fileIndices = fileIndices;
- Processed.Clear();
- CRCs.Clear();
- Sizes.Clear();
- _fileIsOpen = false;
- _currentSizeIsDefined = false;
+ _index = 0;
+
+ Processed.ClearAndReserve(numFiles);
+ CRCs.ClearAndReserve(numFiles);
+ Sizes.ClearAndReserve(numFiles);
+
+ _pos = 0;
+ _crc = CRC_INIT_VAL;
+ _size_Defined = false;
+ _size = 0;
+
+ _stream.Release();
}
HRESULT CFolderInStream::OpenStream()
{
- _filePos = 0;
- while (_fileIndex < _numFiles)
+ _pos = 0;
+ _crc = CRC_INIT_VAL;
+ _size_Defined = false;
+ _size = 0;
+
+ while (_index < _numFiles)
{
CMyComPtr<ISequentialInStream> stream;
- HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
- if (result != S_OK && result != S_FALSE)
- return result;
- _fileIndex++;
- _inStreamWithHashSpec->SetStream(stream);
- _inStreamWithHashSpec->Init();
+ HRESULT result = _updateCallback->GetStream(_indexes[_index], &stream);
+ if (result != S_OK)
+ {
+ if (result != S_FALSE)
+ return result;
+ }
+
+ _stream = stream;
+
if (stream)
{
- _fileIsOpen = true;
CMyComPtr<IStreamGetSize> streamGetSize;
stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
if (streamGetSize)
{
- RINOK(streamGetSize->GetSize(&_currentSize));
- _currentSizeIsDefined = true;
+ if (streamGetSize->GetSize(&_size) == S_OK)
+ _size_Defined = true;
}
return S_OK;
}
+
+ _index++;
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
- Sizes.Add(0);
- Processed.Add(result == S_OK);
- AddDigest();
+ AddFileInfo(result == S_OK);
}
return S_OK;
}
-void CFolderInStream::AddDigest()
+void CFolderInStream::AddFileInfo(bool isProcessed)
{
- CRCs.Add(_inStreamWithHashSpec->GetCRC());
-}
-
-HRESULT CFolderInStream::CloseStream()
-{
- RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
- _inStreamWithHashSpec->ReleaseStream();
- _fileIsOpen = false;
- _currentSizeIsDefined = false;
- Processed.Add(true);
- Sizes.Add(_filePos);
- AddDigest();
- return S_OK;
+ Processed.Add(isProcessed);
+ Sizes.Add(_pos);
+ CRCs.Add(CRC_GET_DIGEST(_crc));
}
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != 0)
+ if (processedSize)
*processedSize = 0;
- while (size > 0)
+ while (size != 0)
{
- if (_fileIsOpen)
+ if (_stream)
{
UInt32 processed2;
- RINOK(_inStreamWithHash->Read(data, size, &processed2));
- if (processed2 == 0)
+ RINOK(_stream->Read(data, size, &processed2));
+ if (processed2 != 0)
{
- RINOK(CloseStream());
- continue;
+ _crc = CrcUpdate(_crc, data, processed2);
+ _pos += processed2;
+ if (processedSize)
+ *processedSize = processed2;
+ return S_OK;
}
- if (processedSize != 0)
- *processedSize = processed2;
- _filePos += processed2;
- break;
+
+ _stream.Release();
+ _index++;
+ AddFileInfo(true);
+
+ _pos = 0;
+ _crc = CRC_INIT_VAL;
+ _size_Defined = false;
+ _size = 0;
+
+ RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
}
- if (_fileIndex >= _numFiles)
+
+ if (_index >= _numFiles)
break;
RINOK(OpenStream());
}
@@ -106,17 +113,23 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
*value = 0;
- int index2 = (int)subStream;
- if (index2 < 0 || subStream > Sizes.Size())
- return E_FAIL;
- if (index2 < Sizes.Size())
+ if (subStream > Sizes.Size())
+ return S_FALSE; // E_FAIL;
+
+ unsigned index = (unsigned)subStream;
+ if (index < Sizes.Size())
{
- *value = Sizes[index2];
+ *value = Sizes[index];
return S_OK;
}
- if (!_currentSizeIsDefined)
+
+ if (!_size_Defined)
+ {
+ *value = _pos;
return S_FALSE;
- *value = _currentSize;
+ }
+
+ *value = (_pos > _size ? _pos : _size);
return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h
index 6df3672a1ca..805db54e9d3 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h
@@ -3,11 +3,13 @@
#ifndef __7Z_FOLDER_IN_STREAM_H
#define __7Z_FOLDER_IN_STREAM_H
+#include "../../../../C/7zCrc.h"
+
+#include "../../../Common/MyCom.h"
+#include "../../../Common/MyVector.h"
+
#include "../../ICoder.h"
#include "../IArchive.h"
-#include "../Common/InStreamWithCRC.h"
-
-#include "7zItem.h"
namespace NArchive {
namespace N7z {
@@ -17,37 +19,38 @@ class CFolderInStream:
public ICompressGetSubStreamSize,
public CMyUnknownImp
{
- CSequentialInStreamWithCRC *_inStreamWithHashSpec;
- CMyComPtr<ISequentialInStream> _inStreamWithHash;
- CMyComPtr<IArchiveUpdateCallback> _updateCallback;
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _pos;
+ UInt32 _crc;
+ bool _size_Defined;
+ UInt64 _size;
- bool _currentSizeIsDefined;
- bool _fileIsOpen;
- UInt64 _currentSize;
- UInt64 _filePos;
- const UInt32 *_fileIndices;
- UInt32 _numFiles;
- UInt32 _fileIndex;
+ const UInt32 *_indexes;
+ unsigned _numFiles;
+ unsigned _index;
+
+ CMyComPtr<IArchiveUpdateCallback> _updateCallback;
HRESULT OpenStream();
- HRESULT CloseStream();
- void AddDigest();
+ void AddFileInfo(bool isProcessed);
public:
CRecordVector<bool> Processed;
CRecordVector<UInt32> CRCs;
CRecordVector<UInt64> Sizes;
- MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
+ MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
- CFolderInStream();
- void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *fileIndices, UInt32 numFiles);
+ void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *indexes, unsigned numFiles);
+
+ bool WasFinished() const { return _index == _numFiles; }
+
UInt64 GetFullSize() const
{
UInt64 size = 0;
- for (int i = 0; i < Sizes.Size(); i++)
+ FOR_VECTOR (i, Sizes)
size += Sizes[i];
return size;
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
deleted file mode 100644
index 22c4600ecf4..00000000000
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-// 7zFolderOutStream.cpp
-
-#include "StdAfx.h"
-
-#include "7zFolderOutStream.h"
-
-namespace NArchive {
-namespace N7z {
-
-CFolderOutStream::CFolderOutStream()
-{
- _crcStreamSpec = new COutStreamWithCRC;
- _crcStream = _crcStreamSpec;
-}
-
-HRESULT CFolderOutStream::Init(
- const CArchiveDatabaseEx *db,
- UInt32 ref2Offset, UInt32 startIndex,
- const CBoolVector *extractStatuses,
- IArchiveExtractCallback *extractCallback,
- bool testMode, bool checkCrc)
-{
- _db = db;
- _ref2Offset = ref2Offset;
- _startIndex = startIndex;
-
- _extractStatuses = extractStatuses;
- _extractCallback = extractCallback;
- _testMode = testMode;
- _checkCrc = checkCrc;
-
- _currentIndex = 0;
- _fileIsOpen = false;
- return ProcessEmptyFiles();
-}
-
-HRESULT CFolderOutStream::OpenFile()
-{
- Int32 askMode = ((*_extractStatuses)[_currentIndex]) ? (_testMode ?
- NExtract::NAskMode::kTest :
- NExtract::NAskMode::kExtract) :
- NExtract::NAskMode::kSkip;
- CMyComPtr<ISequentialOutStream> realOutStream;
- UInt32 index = _startIndex + _currentIndex;
- RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
- _crcStreamSpec->SetStream(realOutStream);
- _crcStreamSpec->Init(_checkCrc);
- _fileIsOpen = true;
- const CFileItem &fi = _db->Files[index];
- _rem = fi.Size;
- if (askMode == NExtract::NAskMode::kExtract && !realOutStream &&
- !_db->IsItemAnti(index) && !fi.IsDir)
- askMode = NExtract::NAskMode::kSkip;
- return _extractCallback->PrepareOperation(askMode);
-}
-
-HRESULT CFolderOutStream::CloseFileAndSetResult(Int32 res)
-{
- _crcStreamSpec->ReleaseStream();
- _fileIsOpen = false;
- _currentIndex++;
- return _extractCallback->SetOperationResult(res);
-}
-
-HRESULT CFolderOutStream::CloseFileAndSetResult()
-{
- const CFileItem &fi = _db->Files[_startIndex + _currentIndex];
- return CloseFileAndSetResult(
- (fi.IsDir || !fi.CrcDefined || !_checkCrc || fi.Crc == _crcStreamSpec->GetCRC()) ?
- NExtract::NOperationResult::kOK :
- NExtract::NOperationResult::kCRCError);
-}
-
-HRESULT CFolderOutStream::ProcessEmptyFiles()
-{
- while (_currentIndex < _extractStatuses->Size() && _db->Files[_startIndex + _currentIndex].Size == 0)
- {
- RINOK(OpenFile());
- RINOK(CloseFileAndSetResult());
- }
- return S_OK;
-}
-
-STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
-{
- if (processedSize != NULL)
- *processedSize = 0;
- while (size != 0)
- {
- if (_fileIsOpen)
- {
- UInt32 cur = size < _rem ? size : (UInt32)_rem;
- RINOK(_crcStream->Write(data, cur, &cur));
- if (cur == 0)
- break;
- data = (const Byte *)data + cur;
- size -= cur;
- _rem -= cur;
- if (processedSize != NULL)
- *processedSize += cur;
- if (_rem == 0)
- {
- RINOK(CloseFileAndSetResult());
- RINOK(ProcessEmptyFiles());
- continue;
- }
- }
- else
- {
- RINOK(ProcessEmptyFiles());
- if (_currentIndex == _extractStatuses->Size())
- {
- // we support partial extracting
- if (processedSize != NULL)
- *processedSize += size;
- break;
- }
- RINOK(OpenFile());
- }
- }
- return S_OK;
-}
-
-STDMETHODIMP CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
-{
- *value = 0;
- if ((int)subStream >= _extractStatuses->Size())
- return S_FALSE;
- *value = _db->Files[_startIndex + (int)subStream].Size;
- return S_OK;
-}
-
-HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
-{
- while (_currentIndex < _extractStatuses->Size())
- {
- if (_fileIsOpen)
- {
- RINOK(CloseFileAndSetResult(resultEOperationResult));
- }
- else
- {
- RINOK(OpenFile());
- }
- }
- return S_OK;
-}
-
-}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.h
deleted file mode 100644
index f9bb1af4273..00000000000
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// 7zFolderOutStream.h
-
-#ifndef __7Z_FOLDER_OUT_STREAM_H
-#define __7Z_FOLDER_OUT_STREAM_H
-
-#include "../../IStream.h"
-#include "../IArchive.h"
-#include "../Common/OutStreamWithCRC.h"
-
-#include "7zIn.h"
-
-namespace NArchive {
-namespace N7z {
-
-class CFolderOutStream:
- public ISequentialOutStream,
- public ICompressGetSubStreamSize,
- public CMyUnknownImp
-{
- COutStreamWithCRC *_crcStreamSpec;
- CMyComPtr<ISequentialOutStream> _crcStream;
- const CArchiveDatabaseEx *_db;
- const CBoolVector *_extractStatuses;
- CMyComPtr<IArchiveExtractCallback> _extractCallback;
- UInt32 _ref2Offset;
- UInt32 _startIndex;
- int _currentIndex;
- bool _testMode;
- bool _checkCrc;
- bool _fileIsOpen;
- UInt64 _rem;
-
- HRESULT OpenFile();
- HRESULT CloseFileAndSetResult(Int32 res);
- HRESULT CloseFileAndSetResult();
- HRESULT ProcessEmptyFiles();
-public:
- MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
-
- CFolderOutStream();
-
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
-
- HRESULT Init(
- const CArchiveDatabaseEx *db,
- UInt32 ref2Offset, UInt32 startIndex,
- const CBoolVector *extractStatuses,
- IArchiveExtractCallback *extractCallback,
- bool testMode, bool checkCrc);
- HRESULT FlushCorrupted(Int32 resultEOperationResult);
- HRESULT WasWritingFinished() const
- { return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; }
-};
-
-}}
-
-#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp
index 93d4f51ee98..a95fc6a0752 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp
@@ -23,6 +23,7 @@
#endif
using namespace NWindows;
+using namespace NCOM;
namespace NArchive {
namespace N7z {
@@ -30,14 +31,19 @@ namespace N7z {
CHandler::CHandler()
{
#ifndef _NO_CRYPTO
+ _isEncrypted = false;
_passwordIsDefined = false;
#endif
#ifdef EXTRACT_ONLY
+
_crcSize = 4;
+
#ifdef __7Z_SET_PROPERTIES
_numThreads = NSystem::GetNumberOfProcessors();
+ _useMultiThreadMixer = true;
#endif
+
#endif
}
@@ -49,11 +55,12 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
#ifdef _SFX
-IMP_IInArchive_ArcProps_NO
+IMP_IInArchive_ArcProps_NO_Table
-STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
{
- return E_NOTIMPL;
+ *numProps = 0;
+ return S_OK;
}
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
@@ -62,156 +69,468 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
return E_NOTIMPL;
}
-
#else
-static const STATPROPSTG kArcProps[] =
+static const Byte kArcProps[] =
{
- { NULL, kpidMethod, VT_BSTR},
- { NULL, kpidSolid, VT_BOOL},
- { NULL, kpidNumBlocks, VT_UI4},
- { NULL, kpidPhySize, VT_UI8},
- { NULL, kpidHeadersSize, VT_UI8},
- { NULL, kpidOffset, VT_UI8}
+ kpidHeadersSize,
+ kpidMethod,
+ kpidSolid,
+ kpidNumBlocks
+ // , kpidIsTree
};
-static inline wchar_t GetHex(Byte value)
+IMP_IInArchive_ArcProps
+
+static inline char GetHex(unsigned value)
{
- return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+ return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
}
-static UString ConvertMethodIdToString(UInt64 id)
+static unsigned ConvertMethodIdToString_Back(char *s, UInt64 id)
{
- wchar_t s[32];
- int len = 32;
- s[--len] = 0;
+ int len = 0;
do
{
- s[--len] = GetHex((Byte)id & 0xF); id >>= 4;
- s[--len] = GetHex((Byte)id & 0xF); id >>= 4;
+ s[--len] = GetHex((unsigned)id & 0xF); id >>= 4;
+ s[--len] = GetHex((unsigned)id & 0xF); id >>= 4;
}
while (id != 0);
- return s + len;
+ return (unsigned)-len;
+}
+
+static void ConvertMethodIdToString(AString &res, UInt64 id)
+{
+ const unsigned kLen = 32;
+ char s[kLen];
+ unsigned len = kLen - 1;
+ s[len] = 0;
+ res += s + len - ConvertMethodIdToString_Back(s + len, id);
+}
+
+static unsigned GetStringForSizeValue(char *s, UInt32 val)
+{
+ unsigned i;
+ for (i = 0; i <= 31; i++)
+ if (((UInt32)1 << i) == val)
+ {
+ if (i < 10)
+ {
+ s[0] = (char)('0' + i);
+ s[1] = 0;
+ return 1;
+ }
+ if (i < 20) { s[0] = '1'; s[1] = (char)('0' + i - 10); }
+ else if (i < 30) { s[0] = '2'; s[1] = (char)('0' + i - 20); }
+ else { s[0] = '3'; s[1] = (char)('0' + i - 30); }
+ s[2] = 0;
+ return 2;
+ }
+ char c = 'b';
+ if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
+ else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
+ ::ConvertUInt32ToString(val, s);
+ unsigned pos = MyStringLen(s);
+ s[pos++] = c;
+ s[pos] = 0;
+ return pos;
+}
+
+/*
+static inline void AddHexToString(UString &res, Byte value)
+{
+ res += GetHex((Byte)(value >> 4));
+ res += GetHex((Byte)(value & 0xF));
+}
+*/
+
+static char *AddProp32(char *s, const char *name, UInt32 v)
+{
+ *s++ = ':';
+ s = MyStpCpy(s, name);
+ ::ConvertUInt32ToString(v, s);
+ return s + MyStringLen(s);
}
+
+void CHandler::AddMethodName(AString &s, UInt64 id)
+{
+ AString name;
+ FindMethod(EXTERNAL_CODECS_VARS id, name);
+ if (name.IsEmpty())
+ ConvertMethodIdToString(s, id);
+ else
+ s += name;
+}
+
+#endif
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
+ #ifndef _SFX
COM_TRY_BEGIN
+ #endif
NCOM::CPropVariant prop;
- switch(propID)
+ switch (propID)
{
+ #ifndef _SFX
case kpidMethod:
{
- UString resString;
- CRecordVector<UInt64> ids;
- int i;
- for (i = 0; i < _db.Folders.Size(); i++)
- {
- const CFolder &f = _db.Folders[i];
- for (int j = f.Coders.Size() - 1; j >= 0; j--)
- ids.AddToUniqueSorted(f.Coders[j].MethodID);
- }
-
- for (i = 0; i < ids.Size(); i++)
+ AString s;
+ const CParsedMethods &pm = _db.ParsedMethods;
+ FOR_VECTOR (i, pm.IDs)
{
- UInt64 id = ids[i];
- UString methodName;
- /* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName);
- if (methodName.IsEmpty())
- methodName = ConvertMethodIdToString(id);
- if (!resString.IsEmpty())
- resString += L' ';
- resString += methodName;
+ UInt64 id = pm.IDs[i];
+ s.Add_Space_if_NotEmpty();
+ char temp[16];
+ if (id == k_LZMA2)
+ {
+ s += "LZMA2:";
+ if ((pm.Lzma2Prop & 1) == 0)
+ ConvertUInt32ToString((pm.Lzma2Prop >> 1) + 12, temp);
+ else
+ GetStringForSizeValue(temp, 3 << ((pm.Lzma2Prop >> 1) + 11));
+ s += temp;
+ }
+ else if (id == k_LZMA)
+ {
+ s += "LZMA:";
+ GetStringForSizeValue(temp, pm.LzmaDic);
+ s += temp;
+ }
+ else
+ AddMethodName(s, id);
}
- prop = resString;
+ prop = s;
break;
}
case kpidSolid: prop = _db.IsSolid(); break;
- case kpidNumBlocks: prop = (UInt32)_db.Folders.Size(); break;
+ case kpidNumBlocks: prop = (UInt32)_db.NumFolders; break;
case kpidHeadersSize: prop = _db.HeadersSize; break;
case kpidPhySize: prop = _db.PhySize; break;
- case kpidOffset: if (_db.ArchiveInfo.StartPosition != 0) prop = _db.ArchiveInfo.StartPosition; break;
+ case kpidOffset: if (_db.ArcInfo.StartPosition != 0) prop = _db.ArcInfo.StartPosition; break;
+ /*
+ case kpidIsTree: if (_db.IsTree) prop = true; break;
+ case kpidIsAltStream: if (_db.ThereAreAltStreams) prop = true; break;
+ case kpidIsAux: if (_db.IsTree) prop = true; break;
+ */
+ // case kpidError: if (_db.ThereIsHeaderError) prop = "Header error"; break;
+ #endif
+
+ case kpidWarningFlags:
+ {
+ UInt32 v = 0;
+ if (_db.StartHeaderWasRecovered) v |= kpv_ErrorFlags_HeadersError;
+ if (_db.UnsupportedFeatureWarning) v |= kpv_ErrorFlags_UnsupportedFeature;
+ if (v != 0)
+ prop = v;
+ break;
+ }
+
+ case kpidErrorFlags:
+ {
+ UInt32 v = 0;
+ if (!_db.IsArc) v |= kpv_ErrorFlags_IsNotArc;
+ if (_db.ThereIsHeaderError) v |= kpv_ErrorFlags_HeadersError;
+ if (_db.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
+ // if (_db.UnsupportedVersion) v |= kpv_ErrorFlags_Unsupported;
+ if (_db.UnsupportedFeatureError) v |= kpv_ErrorFlags_UnsupportedFeature;
+ prop = v;
+ break;
+ }
}
prop.Detach(value);
return S_OK;
+ #ifndef _SFX
COM_TRY_END
+ #endif
}
-IMP_IInArchive_ArcProps
-
-#endif
-
-static void SetPropFromUInt64Def(CUInt64DefVector &v, int index, NCOM::CPropVariant &prop)
+static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, int index)
{
UInt64 value;
if (v.GetItem(index, value))
+ PropVarEm_Set_FileTime64(prop, value);
+}
+
+bool CHandler::IsFolderEncrypted(CNum folderIndex) const
+{
+ if (folderIndex == kNumNoIndex)
+ return false;
+ size_t startPos = _db.FoCodersDataOffset[folderIndex];
+ const Byte *p = _db.CodersData + startPos;
+ size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos;
+ CInByte2 inByte;
+ inByte.Init(p, size);
+
+ CNum numCoders = inByte.ReadNum();
+ for (; numCoders != 0; numCoders--)
{
- FILETIME ft;
- ft.dwLowDateTime = (DWORD)value;
- ft.dwHighDateTime = (DWORD)(value >> 32);
- prop = ft;
+ Byte mainByte = inByte.ReadByte();
+ unsigned idSize = (mainByte & 0xF);
+ const Byte *longID = inByte.GetPtr();
+ UInt64 id64 = 0;
+ for (unsigned j = 0; j < idSize; j++)
+ id64 = ((id64 << 8) | longID[j]);
+ inByte.SkipDataNoCheck(idSize);
+ if (id64 == k_AES)
+ return true;
+ if ((mainByte & 0x20) != 0)
+ inByte.SkipDataNoCheck(inByte.ReadNum());
}
+ return false;
}
-#ifndef _SFX
+STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps)
+{
+ *numProps = 0;
+ return S_OK;
+}
-static UString ConvertUInt32ToString(UInt32 value)
+STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)
{
- wchar_t buffer[32];
- ConvertUInt64ToString(value, buffer);
- return buffer;
+ *name = NULL;
+ *propID = kpidNtSecure;
+ return S_OK;
}
-static UString GetStringForSizeValue(UInt32 value)
+STDMETHODIMP CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)
{
- for (int i = 31; i >= 0; i--)
- if ((UInt32(1) << i) == value)
- return ConvertUInt32ToString(i);
- UString result;
- if (value % (1 << 20) == 0)
- {
- result += ConvertUInt32ToString(value >> 20);
- result += L"m";
- }
- else if (value % (1 << 10) == 0)
+ /*
+ const CFileItem &file = _db.Files[index];
+ *parentType = (file.IsAltStream ? NParentType::kAltStream : NParentType::kDir);
+ *parent = (UInt32)(Int32)file.Parent;
+ */
+ *parentType = NParentType::kDir;
+ *parent = (UInt32)(Int32)-1;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
+{
+ *data = NULL;
+ *dataSize = 0;
+ *propType = 0;
+
+ if (/* _db.IsTree && propID == kpidName ||
+ !_db.IsTree && */ propID == kpidPath)
{
- result += ConvertUInt32ToString(value >> 10);
- result += L"k";
+ if (_db.NameOffsets && _db.NamesBuf)
+ {
+ size_t offset = _db.NameOffsets[index];
+ size_t size = (_db.NameOffsets[index + 1] - offset) * 2;
+ if (size < ((UInt32)1 << 31))
+ {
+ *data = (const void *)(_db.NamesBuf + offset * 2);
+ *dataSize = (UInt32)size;
+ *propType = NPropDataType::kUtf16z;
+ }
+ }
+ return S_OK;
}
- else
+ /*
+ if (propID == kpidNtSecure)
{
- result += ConvertUInt32ToString(value);
- result += L"b";
+ if (index < (UInt32)_db.SecureIDs.Size())
+ {
+ int id = _db.SecureIDs[index];
+ size_t offs = _db.SecureOffsets[id];
+ size_t size = _db.SecureOffsets[id + 1] - offs;
+ if (size >= 0)
+ {
+ *data = _db.SecureBuf + offs;
+ *dataSize = (UInt32)size;
+ *propType = NPropDataType::kRaw;
+ }
+ }
}
- return result;
+ */
+ return S_OK;
}
-static inline void AddHexToString(UString &res, Byte value)
-{
- res += GetHex((Byte)(value >> 4));
- res += GetHex((Byte)(value & 0xF));
-}
+#ifndef _SFX
-static void AddProp32(UString &s, const wchar_t *name, UInt32 v)
+HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
{
- s += name;
- s += ConvertUInt32ToString(v);
-}
+ PropVariant_Clear(prop);
+ if (folderIndex == kNumNoIndex)
+ return S_OK;
+ // for (int ttt = 0; ttt < 1; ttt++) {
+ const unsigned kTempSize = 256;
+ char temp[kTempSize];
+ unsigned pos = kTempSize;
+ temp[--pos] = 0;
-#endif
-
-bool CHandler::IsEncrypted(UInt32 index2) const
-{
- CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
- if (folderIndex != kNumNoIndex)
- return _db.Folders[folderIndex].IsEncrypted();
- return false;
+ size_t startPos = _db.FoCodersDataOffset[folderIndex];
+ const Byte *p = _db.CodersData + startPos;
+ size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos;
+ CInByte2 inByte;
+ inByte.Init(p, size);
+
+ // numCoders == 0 ???
+ CNum numCoders = inByte.ReadNum();
+ bool needSpace = false;
+
+ for (; numCoders != 0; numCoders--, needSpace = true)
+ {
+ if (pos < 32) // max size of property
+ break;
+ Byte mainByte = inByte.ReadByte();
+ unsigned idSize = (mainByte & 0xF);
+ const Byte *longID = inByte.GetPtr();
+ UInt64 id64 = 0;
+ for (unsigned j = 0; j < idSize; j++)
+ id64 = ((id64 << 8) | longID[j]);
+ inByte.SkipDataNoCheck(idSize);
+
+ if ((mainByte & 0x10) != 0)
+ {
+ inByte.ReadNum(); // NumInStreams
+ inByte.ReadNum(); // NumOutStreams
+ }
+
+ CNum propsSize = 0;
+ const Byte *props = NULL;
+ if ((mainByte & 0x20) != 0)
+ {
+ propsSize = inByte.ReadNum();
+ props = inByte.GetPtr();
+ inByte.SkipDataNoCheck(propsSize);
+ }
+
+ const char *name = NULL;
+ char s[32];
+ s[0] = 0;
+
+ if (id64 <= (UInt32)0xFFFFFFFF)
+ {
+ UInt32 id = (UInt32)id64;
+ if (id == k_LZMA)
+ {
+ name = "LZMA";
+ if (propsSize == 5)
+ {
+ UInt32 dicSize = GetUi32((const Byte *)props + 1);
+ char *dest = s + GetStringForSizeValue(s, dicSize);
+ UInt32 d = props[0];
+ if (d != 0x5D)
+ {
+ UInt32 lc = d % 9;
+ d /= 9;
+ UInt32 pb = d / 5;
+ UInt32 lp = d % 5;
+ if (lc != 3) dest = AddProp32(dest, "lc", lc);
+ if (lp != 0) dest = AddProp32(dest, "lp", lp);
+ if (pb != 2) dest = AddProp32(dest, "pb", pb);
+ }
+ }
+ }
+ else if (id == k_LZMA2)
+ {
+ name = "LZMA2";
+ if (propsSize == 1)
+ {
+ Byte p = props[0];
+ if ((p & 1) == 0)
+ ConvertUInt32ToString((UInt32)((p >> 1) + 12), s);
+ else
+ GetStringForSizeValue(s, 3 << ((p >> 1) + 11));
+ }
+ }
+ else if (id == k_PPMD)
+ {
+ name = "PPMD";
+ if (propsSize == 5)
+ {
+ Byte order = *props;
+ char *dest = s;
+ *dest++ = 'o';
+ ConvertUInt32ToString(order, dest);
+ dest += MyStringLen(dest);
+ dest = MyStpCpy(dest, ":mem");
+ GetStringForSizeValue(dest, GetUi32(props + 1));
+ }
+ }
+ else if (id == k_Delta)
+ {
+ name = "Delta";
+ if (propsSize == 1)
+ ConvertUInt32ToString((UInt32)props[0] + 1, s);
+ }
+ else if (id == k_BCJ2) name = "BCJ2";
+ else if (id == k_BCJ) name = "BCJ";
+ else if (id == k_AES)
+ {
+ name = "7zAES";
+ if (propsSize >= 1)
+ {
+ Byte firstByte = props[0];
+ UInt32 numCyclesPower = firstByte & 0x3F;
+ ConvertUInt32ToString(numCyclesPower, s);
+ }
+ }
+ }
+
+ if (name)
+ {
+ unsigned nameLen = MyStringLen(name);
+ unsigned propsLen = MyStringLen(s);
+ unsigned totalLen = nameLen + propsLen;
+ if (propsLen != 0)
+ totalLen++;
+ if (needSpace)
+ totalLen++;
+ if (totalLen + 5 >= pos)
+ break;
+ pos -= totalLen;
+ MyStringCopy(temp + pos, name);
+ if (propsLen != 0)
+ {
+ char *dest = temp + pos + nameLen;
+ *dest++ = ':';
+ MyStringCopy(dest, s);
+ }
+ if (needSpace)
+ temp[pos + totalLen - 1] = ' ';
+ }
+ else
+ {
+ AString methodName;
+ FindMethod(EXTERNAL_CODECS_VARS id64, methodName);
+ if (needSpace)
+ temp[--pos] = ' ';
+ if (methodName.IsEmpty())
+ pos -= ConvertMethodIdToString_Back(temp + pos, id64);
+ else
+ {
+ unsigned len = methodName.Len();
+ if (len + 5 > pos)
+ break;
+ pos -= len;
+ for (unsigned i = 0; i < len; i++)
+ temp[pos + i] = methodName[i];
+ }
+ }
+ }
+
+ if (numCoders != 0 && pos >= 4)
+ {
+ temp[--pos] = ' ';
+ temp[--pos] = '.';
+ temp[--pos] = '.';
+ temp[--pos] = '.';
+ }
+
+ return PropVarEm_Set_Str(prop, temp + pos);
+ // }
}
-STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+#endif
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
- COM_TRY_BEGIN
- NCOM::CPropVariant prop;
+ PropVariant_Clear(value);
+ // COM_TRY_BEGIN
+ // NCOM::CPropVariant prop;
/*
const CRef2 &ref2 = _refs[index];
@@ -223,16 +542,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
const CFileItem &item = _db.Files[index];
UInt32 index2 = index;
- switch(propID)
+ switch (propID)
{
- case kpidPath:
- if (!item.Name.IsEmpty())
- prop = NItemName::GetOSName(item.Name);
- break;
- case kpidIsDir: prop = item.IsDir; break;
+ case kpidIsDir: PropVarEm_Set_Bool(value, item.IsDir); break;
case kpidSize:
{
- prop = item.Size;
+ PropVarEm_Set_UInt64(value, item.Size);
// prop = ref2.Size;
break;
}
@@ -244,132 +559,54 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
if (folderIndex != kNumNoIndex)
{
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2)
- prop = _db.GetFolderFullPackSize(folderIndex);
+ PropVarEm_Set_UInt64(value, _db.GetFolderFullPackSize(folderIndex));
/*
else
- prop = (UInt64)0;
+ PropVarEm_Set_UInt64(value, 0);
*/
}
else
- prop = (UInt64)0;
+ PropVarEm_Set_UInt64(value, 0);
}
break;
}
- case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) prop = v; break; }
- case kpidCTime: SetPropFromUInt64Def(_db.CTime, index2, prop); break;
- case kpidATime: SetPropFromUInt64Def(_db.ATime, index2, prop); break;
- case kpidMTime: SetPropFromUInt64Def(_db.MTime, index2, prop); break;
- case kpidAttrib: if (item.AttribDefined) prop = item.Attrib; break;
- case kpidCRC: if (item.CrcDefined) prop = item.Crc; break;
- case kpidEncrypted: prop = IsEncrypted(index2); break;
- case kpidIsAnti: prop = _db.IsItemAnti(index2); break;
- #ifndef _SFX
- case kpidMethod:
+ // case kpidIsAux: prop = _db.IsItemAux(index2); break;
+ case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) PropVarEm_Set_UInt64(value, v); break; }
+ 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 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;
+ /*
+ case kpidIsAltStream: prop = item.IsAltStream; break;
+ case kpidNtSecure:
{
- CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
- if (folderIndex != kNumNoIndex)
+ int id = _db.SecureIDs[index];
+ size_t offs = _db.SecureOffsets[id];
+ size_t size = _db.SecureOffsets[id + 1] - offs;
+ if (size >= 0)
{
- const CFolder &folderInfo = _db.Folders[folderIndex];
- UString methodsString;
- for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
- {
- const CCoderInfo &coder = folderInfo.Coders[i];
- if (!methodsString.IsEmpty())
- methodsString += L' ';
-
- UString methodName, propsString;
- bool methodIsKnown = FindMethod(
- EXTERNAL_CODECS_VARS
- coder.MethodID, methodName);
-
- if (!methodIsKnown)
- methodsString += ConvertMethodIdToString(coder.MethodID);
- else
- {
- methodsString += methodName;
- if (coder.MethodID == k_Delta && coder.Props.GetCapacity() == 1)
- propsString = ConvertUInt32ToString((UInt32)coder.Props[0] + 1);
- else if (coder.MethodID == k_LZMA && coder.Props.GetCapacity() == 5)
- {
- UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);
- propsString = GetStringForSizeValue(dicSize);
- UInt32 d = coder.Props[0];
- UInt32 lc = d % 9;
- d /= 9;
- UInt32 pb = d / 5;
- UInt32 lp = d % 5;
- if (lc != 3) AddProp32(propsString, L":lc", lc);
- if (lp != 0) AddProp32(propsString, L":lp", lp);
- if (pb != 2) AddProp32(propsString, L":pb", pb);
- }
- else if (coder.MethodID == k_LZMA2 && coder.Props.GetCapacity() == 1)
- {
- Byte p = coder.Props[0];
- UInt32 dicSize = (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11));
- propsString = GetStringForSizeValue(dicSize);
- }
- else if (coder.MethodID == k_PPMD && coder.Props.GetCapacity() == 5)
- {
- Byte order = *(const Byte *)coder.Props;
- propsString = L'o';
- propsString += ConvertUInt32ToString(order);
- propsString += L":mem";
- UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);
- propsString += GetStringForSizeValue(dicSize);
- }
- else if (coder.MethodID == k_AES && coder.Props.GetCapacity() >= 1)
- {
- const Byte *data = (const Byte *)coder.Props;
- Byte firstByte = *data++;
- UInt32 numCyclesPower = firstByte & 0x3F;
- propsString = ConvertUInt32ToString(numCyclesPower);
- /*
- if ((firstByte & 0xC0) != 0)
- {
- UInt32 saltSize = (firstByte >> 7) & 1;
- UInt32 ivSize = (firstByte >> 6) & 1;
- if (coder.Props.GetCapacity() >= 2)
- {
- Byte secondByte = *data++;
- saltSize += (secondByte >> 4);
- ivSize += (secondByte & 0x0F);
- }
- }
- */
- }
- }
- if (!propsString.IsEmpty())
- {
- methodsString += L':';
- methodsString += propsString;
- }
- else if (coder.Props.GetCapacity() > 0)
- {
- methodsString += L":[";
- for (size_t bi = 0; bi < coder.Props.GetCapacity(); bi++)
- {
- if (bi > 5 && bi + 1 < coder.Props.GetCapacity())
- {
- methodsString += L"..";
- break;
- }
- else
- AddHexToString(methodsString, coder.Props[bi]);
- }
- methodsString += L']';
- }
- }
- prop = methodsString;
+ prop.SetBlob(_db.SecureBuf + offs, (ULONG)size);
}
+ break;
}
- break;
+ */
+
+ case kpidPath: return _db.GetPath_Prop(index, value);
+
+ #ifndef _SFX
+
+ case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value);
case kpidBlock:
{
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
- prop = (UInt32)folderIndex;
+ PropVarEm_Set_UInt32(value, (UInt32)folderIndex);
}
break;
+ /*
case kpidPackedSize0:
case kpidPackedSize1:
case kpidPackedSize2:
@@ -379,24 +616,24 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
- const CFolder &folderInfo = _db.Folders[folderIndex];
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
- folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
+ _db.FoStartPackStreamIndex[folderIndex + 1] -
+ _db.FoStartPackStreamIndex[folderIndex] > (propID - kpidPackedSize0))
{
- prop = _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
+ PropVarEm_Set_UInt64(value, _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0));
}
- else
- prop = (UInt64)0;
}
else
- prop = (UInt64)0;
+ PropVarEm_Set_UInt64(value, 0);
}
break;
+ */
+
#endif
}
- prop.Detach(value);
+ // prop.Detach(value);
return S_OK;
- COM_TRY_END
+ // COM_TRY_END
}
STDMETHODIMP CHandler::Open(IInStream *stream,
@@ -408,6 +645,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
#ifndef _SFX
_fileInfoPopIDs.Clear();
#endif
+
try
{
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
@@ -415,32 +653,38 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
#ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (openArchiveCallback)
- {
- openArchiveCallbackTemp.QueryInterface(
- IID_ICryptoGetTextPassword, &getTextPassword);
- }
+ openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
#endif
- CInArchive archive;
+
+ CInArchive archive(
+ #ifdef __7Z_SET_PROPERTIES
+ _useMultiThreadMixer
+ #else
+ true
+ #endif
+ );
+ _db.IsArc = false;
RINOK(archive.Open(stream, maxCheckStartPosition));
- #ifndef _NO_CRYPTO
- _passwordIsDefined = false;
- UString password;
- #endif
+ _db.IsArc = true;
+
HRESULT result = archive.ReadDatabase(
- EXTERNAL_CODECS_VARS
- _db
- #ifndef _NO_CRYPTO
- , getTextPassword, _passwordIsDefined
- #endif
- );
+ EXTERNAL_CODECS_VARS
+ _db
+ #ifndef _NO_CRYPTO
+ , getTextPassword, _isEncrypted, _passwordIsDefined, _password
+ #endif
+ );
RINOK(result);
- _db.Fill();
+
_inStream = stream;
}
catch(...)
{
Close();
- return S_FALSE;
+ // return E_INVALIDARG;
+ // return S_FALSE;
+ // we must return out_of_memory here
+ return E_OUTOFMEMORY;
}
// _inStream = stream;
#ifndef _SFX
@@ -455,6 +699,11 @@ STDMETHODIMP CHandler::Close()
COM_TRY_BEGIN
_inStream.Release();
_db.Clear();
+ #ifndef _NO_CRYPTO
+ _isEncrypted = false;
+ _passwordIsDefined = false;
+ _password.Empty();
+ #endif
return S_OK;
COM_TRY_END
}
@@ -462,26 +711,32 @@ STDMETHODIMP CHandler::Close()
#ifdef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
-STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
COM_TRY_BEGIN
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
_numThreads = numProcessors;
+ _useMultiThreadMixer = true;
- for (int i = 0; i < numProperties; i++)
+ for (UInt32 i = 0; i < numProps; i++)
{
UString name = names[i];
- name.MakeUpper();
+ name.MakeLower_Ascii();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
UInt32 number;
- int index = ParseStringToUInt32(name, number);
+ unsigned index = ParseStringToUInt32(name, number);
if (index == 0)
{
- if(name.Left(2).CompareNoCase(L"MT") == 0)
+ if (name.IsEqualTo("mtf"))
+ {
+ RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer));
+ continue;
+ }
+ if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
- RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
+ RINOK(ParseMtProp(name.Ptr(2), value, numProcessors, _numThreads));
continue;
}
else
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h
index 247b55f79dc..d46401afe3c 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h
@@ -18,24 +18,14 @@
namespace NArchive {
namespace N7z {
-const UInt32 k_Copy = 0x0;
-const UInt32 k_Delta = 3;
-const UInt32 k_LZMA2 = 0x21;
-const UInt32 k_LZMA = 0x030101;
-const UInt32 k_PPMD = 0x030401;
-const UInt32 k_BCJ = 0x03030103;
-const UInt32 k_BCJ2 = 0x0303011B;
-const UInt32 k_Deflate = 0x040108;
-const UInt32 k_BZip2 = 0x040202;
-
#ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
-#if !defined(_7ZIP_ST) && !defined(_SFX)
-#define __7Z_SET_PROPERTIES
-#endif
+ #if !defined(_7ZIP_ST) && !defined(_SFX)
+ #define __7Z_SET_PROPERTIES
+ #endif
#else
-#define __7Z_SET_PROPERTIES
+ #define __7Z_SET_PROPERTIES
#endif
#endif
@@ -54,16 +44,20 @@ public:
UInt64 _numSolidBytes;
bool _numSolidBytesDefined;
bool _solidExtension;
+ bool _useTypeSorting;
bool _compressHeaders;
bool _encryptHeadersSpecified;
bool _encryptHeaders;
+ // bool _useParents; 9.26
- bool WriteCTime;
- bool WriteATime;
- bool WriteMTime;
+ CBoolPair Write_CTime;
+ CBoolPair Write_ATime;
+ CBoolPair Write_MTime;
- bool _volumeMode;
+ bool _useMultiThreadMixer;
+
+ // bool _volumeMode;
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
@@ -85,10 +79,8 @@ public:
#endif
class CHandler:
- #ifndef EXTRACT_ONLY
- public COutHandler,
- #endif
public IInArchive,
+ public IArchiveGetRawProps,
#ifdef __7Z_SET_PROPERTIES
public ISetProperties,
#endif
@@ -97,9 +89,13 @@ class CHandler:
#endif
PUBLIC_ISetCompressCodecsInfo
public CMyUnknownImp
+ #ifndef EXTRACT_ONLY
+ , public COutHandler
+ #endif
{
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
+ MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
#ifdef __7Z_SET_PROPERTIES
MY_QUERYINTERFACE_ENTRY(ISetProperties)
#endif
@@ -111,9 +107,10 @@ public:
MY_ADDREF_RELEASE
INTERFACE_IInArchive(;)
+ INTERFACE_IArchiveGetRawProps(;)
#ifdef __7Z_SET_PROPERTIES
- STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
+ STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
#endif
#ifndef EXTRACT_ONLY
@@ -126,28 +123,30 @@ public:
private:
CMyComPtr<IInStream> _inStream;
- NArchive::N7z::CArchiveDatabaseEx _db;
+ NArchive::N7z::CDbEx _db;
+
#ifndef _NO_CRYPTO
+ bool _isEncrypted;
bool _passwordIsDefined;
+ UString _password;
#endif
#ifdef EXTRACT_ONLY
#ifdef __7Z_SET_PROPERTIES
UInt32 _numThreads;
+ bool _useMultiThreadMixer;
#endif
UInt32 _crcSize;
#else
- CRecordVector<CBind> _binds;
+ CRecordVector<CBond2> _bonds;
HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
- void AddDefaultMethod();
- HRESULT SetMainMethod(CCompressionMethodMode &method,
- CObjectVector<COneMethodInfo> &methodsInfo
+ HRESULT SetMainMethod(CCompressionMethodMode &method
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
@@ -156,11 +155,13 @@ private:
#endif
- bool IsEncrypted(UInt32 index2) const;
+ bool IsFolderEncrypted(CNum folderIndex) const;
#ifndef _SFX
CRecordVector<UInt64> _fileInfoPopIDs;
void FillPopIDs();
+ void AddMethodName(AString &s, UInt64 id);
+ HRESULT SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const;
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
index dd73ee842f5..41bd6520c80 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
@@ -4,6 +4,7 @@
#include "../../../Common/ComTry.h"
#include "../../../Common/StringToInt.h"
+#include "../../../Common/Wildcard.h"
#include "../Common/ItemNameUtils.h"
#include "../Common/ParseProperties.h"
@@ -17,11 +18,11 @@ using namespace NWindows;
namespace NArchive {
namespace N7z {
-static const wchar_t *k_LZMA_Name = L"LZMA";
-static const wchar_t *kDefaultMethodName = k_LZMA_Name;
-static const wchar_t *k_Copy_Name = L"Copy";
+static const char *k_LZMA_Name = "LZMA";
+static const char *kDefaultMethodName = "LZMA2";
+static const char *k_Copy_Name = "Copy";
-static const wchar_t *k_MatchFinder_ForHeaders = L"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 =
@@ -41,7 +42,7 @@ HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodI
{
if (!FindMethod(
EXTERNAL_CODECS_VARS
- m.MethodName, dest.Id, dest.NumInStreams, dest.NumOutStreams))
+ m.MethodName, dest.Id, dest.NumStreams))
return E_INVALIDARG;
(CProps &)dest = (CProps &)m;
return S_OK;
@@ -53,49 +54,63 @@ HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
return S_OK;
COneMethodInfo m;
m.MethodName = k_LZMA_Name;
- m.AddPropString(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
- m.AddProp32(NCoderPropID::kLevel, k_Level_ForHeaders);
+ m.AddProp_Ascii(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
+ m.AddProp_Level(k_Level_ForHeaders);
m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders);
m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders);
- m.AddNumThreadsProp(1);
+ m.AddProp_NumThreads(1);
- CMethodFull methodFull;
- RINOK(PropsMethod_To_FullMethod(methodFull, m));
- headerMethod.Methods.Add(methodFull);
- return S_OK;
-}
-
-void CHandler::AddDefaultMethod()
-{
- for (int i = 0; i < _methods.Size(); i++)
- {
- UString &methodName = _methods[0].MethodName;
- if (methodName.IsEmpty())
- methodName = kDefaultMethodName;
- }
- if (_methods.IsEmpty())
- {
- COneMethodInfo m;
- m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName);
- _methods.Add(m);
- }
+ CMethodFull &methodFull = headerMethod.Methods.AddNew();
+ return PropsMethod_To_FullMethod(methodFull, m);
}
HRESULT CHandler::SetMainMethod(
- CCompressionMethodMode &methodMode,
- CObjectVector<COneMethodInfo> &methods
+ CCompressionMethodMode &methodMode
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
)
{
- AddDefaultMethod();
+ methodMode.Bonds = _bonds;
+
+ CObjectVector<COneMethodInfo> methods = _methods;
+
+ {
+ FOR_VECTOR (i, methods)
+ {
+ AString &methodName = methods[i].MethodName;
+ if (methodName.IsEmpty())
+ methodName = kDefaultMethodName;
+ }
+ if (methods.IsEmpty())
+ {
+ COneMethodInfo &m = methods.AddNew();
+ m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName);
+ methodMode.DefaultMethod_was_Inserted = true;
+ }
+ }
+
+ if (!_filterMethod.MethodName.IsEmpty())
+ {
+ // if (methodMode.Bonds.IsEmpty())
+ {
+ FOR_VECTOR (k, methodMode.Bonds)
+ {
+ CBond2 &bond = methodMode.Bonds[k];
+ bond.InCoder++;
+ bond.OutCoder++;
+ }
+ methods.Insert(0, _filterMethod);
+ methodMode.Filter_was_Inserted = true;
+ }
+ }
const UInt64 kSolidBytes_Min = (1 << 24);
const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
bool needSolid = false;
- for (int i = 0; i < methods.Size(); i++)
+
+ FOR_VECTOR (i, methods)
{
COneMethodInfo &oneMethodInfo = methods[i];
SetGlobalLevelAndThreads(oneMethodInfo
@@ -104,9 +119,8 @@ HRESULT CHandler::SetMainMethod(
#endif
);
- CMethodFull methodFull;
+ CMethodFull &methodFull = methodMode.Methods.AddNew();
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
- methodMode.Methods.Add(methodFull);
if (methodFull.Id != k_Copy)
needSolid = true;
@@ -124,6 +138,7 @@ HRESULT CHandler::SetMainMethod(
case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
default: continue;
}
+
_numSolidBytes = (UInt64)dicSize << 7;
if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
@@ -139,12 +154,10 @@ HRESULT CHandler::SetMainMethod(
return S_OK;
}
-static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool writeTime, PROPID propID, UInt64 &ft, bool &ftDefined)
+static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, UInt64 &ft, bool &ftDefined)
{
- ft = 0;
- ftDefined = false;
- if (!writeTime)
- return S_OK;
+ // ft = 0;
+ // ftDefined = false;
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(index, propID, &prop));
if (prop.vt == VT_FILETIME)
@@ -154,15 +167,87 @@ static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool w
}
else if (prop.vt != VT_EMPTY)
return E_INVALIDARG;
+ else
+ {
+ ft = 0;
+ ftDefined = false;
+ }
return S_OK;
}
+/*
+
+#ifdef _WIN32
+static const wchar_t kDirDelimiter1 = L'\\';
+#endif
+static const wchar_t kDirDelimiter2 = L'/';
+
+static inline bool IsCharDirLimiter(wchar_t c)
+{
+ return (
+ #ifdef _WIN32
+ c == kDirDelimiter1 ||
+ #endif
+ c == kDirDelimiter2);
+}
+
+static int FillSortIndex(CObjectVector<CTreeFolder> &treeFolders, int cur, int curSortIndex)
+{
+ CTreeFolder &tf = treeFolders[cur];
+ tf.SortIndex = curSortIndex++;
+ for (int i = 0; i < tf.SubFolders.Size(); i++)
+ curSortIndex = FillSortIndex(treeFolders, tf.SubFolders[i], curSortIndex);
+ tf.SortIndexEnd = curSortIndex;
+ return curSortIndex;
+}
+
+static int FindSubFolder(const CObjectVector<CTreeFolder> &treeFolders, int cur, const UString &name, int &insertPos)
+{
+ const CIntVector &subFolders = treeFolders[cur].SubFolders;
+ int left = 0, right = subFolders.Size();
+ insertPos = -1;
+ for (;;)
+ {
+ if (left == right)
+ {
+ insertPos = left;
+ return -1;
+ }
+ int mid = (left + right) / 2;
+ int midFolder = subFolders[mid];
+ int compare = CompareFileNames(name, treeFolders[midFolder].Name);
+ if (compare == 0)
+ return midFolder;
+ if (compare < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+}
+
+static int AddFolder(CObjectVector<CTreeFolder> &treeFolders, int cur, const UString &name)
+{
+ int insertPos;
+ int folderIndex = FindSubFolder(treeFolders, cur, name, insertPos);
+ if (folderIndex < 0)
+ {
+ folderIndex = treeFolders.Size();
+ CTreeFolder &newFolder = treeFolders.AddNew();
+ newFolder.Parent = cur;
+ newFolder.Name = name;
+ treeFolders[cur].SubFolders.Insert(insertPos, folderIndex);
+ }
+ // else if (treeFolders[folderIndex].IsAltStreamFolder != isAltStreamFolder) throw 1123234234;
+ return folderIndex;
+}
+*/
+
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
{
COM_TRY_BEGIN
- const CArchiveDatabaseEx *db = 0;
+ const CDbEx *db = 0;
#ifdef _7Z_VOL
if (_volumes.Size() > 1)
return E_FAIL;
@@ -177,8 +262,36 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
db = &_db;
#endif
+ /*
+ CMyComPtr<IArchiveGetRawProps> getRawProps;
+ updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps);
+
+ CUniqBlocks secureBlocks;
+ secureBlocks.AddUniq(NULL, 0);
+
+ CObjectVector<CTreeFolder> treeFolders;
+ {
+ CTreeFolder folder;
+ folder.Parent = -1;
+ treeFolders.Add(folder);
+ }
+ */
+
CObjectVector<CUpdateItem> updateItems;
+
+ bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
+ bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
+ bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
+ 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();
+ }
+
+ UString s;
+
for (UInt32 i = 0; i < numItems; i++)
{
Int32 newData, newProps;
@@ -194,24 +307,32 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
ui.IsAnti = false;
ui.Size = 0;
+ UString name;
+ // bool isAltStream = false;
if (ui.IndexInArchive != -1)
{
- if (db == 0 || ui.IndexInArchive >= db->Files.Size())
+ if (db == 0 || (unsigned)ui.IndexInArchive >= db->Files.Size())
return E_INVALIDARG;
const CFileItem &fi = db->Files[ui.IndexInArchive];
- ui.Name = fi.Name;
+ if (!ui.NewProps)
+ {
+ _db.GetPath(ui.IndexInArchive, name);
+ }
ui.IsDir = fi.IsDir;
ui.Size = fi.Size;
+ // isAltStream = fi.IsAltStream;
ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
- ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
- ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
- ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
+ if (!ui.NewProps)
+ {
+ ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
+ ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
+ ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
+ }
}
if (ui.NewProps)
{
- bool nameIsDefined;
bool folderStatusIsDefined;
{
NCOM::CPropVariant prop;
@@ -228,21 +349,35 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
// we need MTime to sort files.
- RINOK(GetTime(updateCallback, i, WriteCTime, kpidCTime, ui.CTime, ui.CTimeDefined));
- RINOK(GetTime(updateCallback, i, WriteATime, kpidATime, ui.ATime, ui.ATimeDefined));
- RINOK(GetTime(updateCallback, i, true, kpidMTime, ui.MTime, ui.MTimeDefined));
+ if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined));
+ if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined));
+ if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined));
+
+ /*
+ if (getRawProps)
+ {
+ const void *data;
+ UInt32 dataSize;
+ UInt32 propType;
+
+ getRawProps->GetRawProp(i, kpidNtSecure, &data, &dataSize, &propType);
+ if (dataSize != 0 && propType != NPropDataType::kRaw)
+ return E_FAIL;
+ ui.SecureIndex = secureBlocks.AddUniq((const Byte *)data, dataSize);
+ }
+ */
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
if (prop.vt == VT_EMPTY)
- nameIsDefined = false;
+ {
+ }
else if (prop.vt != VT_BSTR)
return E_INVALIDARG;
else
{
- ui.Name = NItemName::MakeLegalName(prop.bstrVal);
- nameIsDefined = true;
+ name = NItemName::MakeLegalName(prop.bstrVal);
}
}
{
@@ -270,6 +405,19 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
ui.IsAnti = (prop.boolVal != VARIANT_FALSE);
}
+ /*
+ {
+ NCOM::CPropVariant prop;
+ RINOK(updateCallback->GetProperty(i, kpidIsAltStream, &prop));
+ if (prop.vt == VT_EMPTY)
+ isAltStream = false;
+ else if (prop.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ isAltStream = (prop.boolVal != VARIANT_FALSE);
+ }
+ */
+
if (ui.IsAnti)
{
ui.AttribDefined = false;
@@ -284,55 +432,155 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (!folderStatusIsDefined && ui.AttribDefined)
ui.SetDirStatusFromAttrib();
}
+ else
+ {
+ /*
+ if (_db.SecureIDs.IsEmpty())
+ ui.SecureIndex = secureBlocks.AddUniq(NULL, 0);
+ else
+ {
+ int id = _db.SecureIDs[ui.IndexInArchive];
+ size_t offs = _db.SecureOffsets[id];
+ size_t size = _db.SecureOffsets[id + 1] - offs;
+ ui.SecureIndex = secureBlocks.AddUniq(_db.SecureBuf + offs, size);
+ }
+ */
+ }
+
+ /*
+ {
+ int folderIndex = 0;
+ if (_useParents)
+ {
+ int j;
+ s.Empty();
+ for (j = 0; j < name.Len(); j++)
+ {
+ wchar_t c = name[j];
+ if (IsCharDirLimiter(c))
+ {
+ folderIndex = AddFolder(treeFolders, folderIndex, s);
+ s.Empty();
+ continue;
+ }
+ s += c;
+ }
+ if (isAltStream)
+ {
+ int colonPos = s.Find(':');
+ if (colonPos < 0)
+ {
+ // isAltStream = false;
+ return E_INVALIDARG;
+ }
+ UString mainName = s.Left(colonPos);
+ int newFolderIndex = AddFolder(treeFolders, folderIndex, mainName);
+ if (treeFolders[newFolderIndex].UpdateItemIndex < 0)
+ {
+ for (int j = updateItems.Size() - 1; j >= 0; j--)
+ {
+ CUpdateItem &ui2 = updateItems[j];
+ if (ui2.ParentFolderIndex == folderIndex
+ && ui2.Name == mainName)
+ {
+ ui2.TreeFolderIndex = newFolderIndex;
+ treeFolders[newFolderIndex].UpdateItemIndex = j;
+ }
+ }
+ }
+ folderIndex = newFolderIndex;
+ s.Delete(0, colonPos + 1);
+ }
+ ui.Name = s;
+ }
+ else
+ ui.Name = name;
+ ui.IsAltStream = isAltStream;
+ ui.ParentFolderIndex = folderIndex;
+ ui.TreeFolderIndex = -1;
+ if (ui.IsDir && !s.IsEmpty())
+ {
+ ui.TreeFolderIndex = AddFolder(treeFolders, folderIndex, s);
+ treeFolders[ui.TreeFolderIndex].UpdateItemIndex = updateItems.Size();
+ }
+ }
+ */
+ ui.Name = name;
if (ui.NewData)
{
- NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
- if (prop.vt != VT_UI8)
- return E_INVALIDARG;
- ui.Size = (UInt64)prop.uhVal.QuadPart;
- if (ui.Size != 0 && ui.IsAnti)
- return E_INVALIDARG;
+ ui.Size = 0;
+ if (!ui.IsDir)
+ {
+ NCOM::CPropVariant prop;
+ RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
+ if (prop.vt != VT_UI8)
+ return E_INVALIDARG;
+ ui.Size = (UInt64)prop.uhVal.QuadPart;
+ if (ui.Size != 0 && ui.IsAnti)
+ return E_INVALIDARG;
+ }
}
+
updateItems.Add(ui);
}
+ /*
+ FillSortIndex(treeFolders, 0, 0);
+ for (i = 0; i < (UInt32)updateItems.Size(); i++)
+ {
+ CUpdateItem &ui = updateItems[i];
+ ui.ParentSortIndex = treeFolders[ui.ParentFolderIndex].SortIndex;
+ ui.ParentSortIndexEnd = treeFolders[ui.ParentFolderIndex].SortIndexEnd;
+ }
+ */
+
CCompressionMethodMode methodMode, headerMethod;
- HRESULT res = SetMainMethod(methodMode, _methods
+ HRESULT res = SetMainMethod(methodMode
#ifndef _7ZIP_ST
, _numThreads
#endif
);
RINOK(res);
- methodMode.Binds = _binds;
RINOK(SetHeaderMethod(headerMethod));
+
#ifndef _7ZIP_ST
methodMode.NumThreads = _numThreads;
+ methodMode.MultiThreadMixer = _useMultiThreadMixer;
headerMethod.NumThreads = 1;
+ headerMethod.MultiThreadMixer = _useMultiThreadMixer;
#endif
CMyComPtr<ICryptoGetTextPassword2> getPassword2;
updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2);
+ methodMode.PasswordIsDefined = false;
+ methodMode.Password.Empty();
if (getPassword2)
{
CMyComBSTR password;
Int32 passwordIsDefined;
RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password));
methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
- if (methodMode.PasswordIsDefined)
+ if (methodMode.PasswordIsDefined && password)
methodMode.Password = password;
}
- else
- methodMode.PasswordIsDefined = false;
bool compressMainHeader = _compressHeaders; // check it
bool encryptHeaders = false;
+ #ifndef _NO_CRYPTO
+ if (!methodMode.PasswordIsDefined && _passwordIsDefined)
+ {
+ // if header is compressed, we use that password for updated archive
+ methodMode.PasswordIsDefined = true;
+ methodMode.Password = _password;
+ }
+ #endif
+
if (methodMode.PasswordIsDefined)
{
if (_encryptHeadersSpecified)
@@ -352,30 +600,50 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (numItems < 2)
compressMainHeader = false;
+ int level = GetLevel();
+
CUpdateOptions options;
options.Method = &methodMode;
- options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
- int level = GetLevel();
- options.UseFilters = level != 0 && _autoFilter;
- options.MaxFilter = level >= 8;
+ options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : NULL;
+ options.UseFilters = (level != 0 && _autoFilter && !methodMode.Filter_was_Inserted);
+ options.MaxFilter = (level >= 8);
+ options.AnalysisLevel = GetAnalysisLevel();
options.HeaderOptions.CompressMainHeader = compressMainHeader;
- options.HeaderOptions.WriteCTime = WriteCTime;
- options.HeaderOptions.WriteATime = WriteATime;
- options.HeaderOptions.WriteMTime = WriteMTime;
+ /*
+ options.HeaderOptions.WriteCTime = Write_CTime;
+ options.HeaderOptions.WriteATime = Write_ATime;
+ options.HeaderOptions.WriteMTime = Write_MTime;
+ */
options.NumSolidFiles = _numSolidFiles;
options.NumSolidBytes = _numSolidBytes;
options.SolidExtension = _solidExtension;
+ options.UseTypeSorting = _useTypeSorting;
+
options.RemoveSfxBlock = _removeSfxBlock;
- options.VolumeMode = _volumeMode;
+ // options.VolumeMode = _volumeMode;
+
+ options.MultiThreadMixer = _useMultiThreadMixer;
COutArchive archive;
- CArchiveDatabase newDatabase;
+ CArchiveDatabaseOut newDatabase;
CMyComPtr<ICryptoGetTextPassword> getPassword;
updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword);
+ /*
+ if (secureBlocks.Sorted.Size() > 1)
+ {
+ secureBlocks.GetReverseMap();
+ for (int i = 0; i < updateItems.Size(); i++)
+ {
+ int &secureIndex = updateItems[i].SecureIndex;
+ secureIndex = secureBlocks.BufIndexToSortedIndex[secureIndex];
+ }
+ }
+ */
+
res = Update(
EXTERNAL_CODECS_VARS
#ifdef _7Z_VOL
@@ -386,6 +654,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
db,
#endif
updateItems,
+ // treeFolders,
+ // secureBlocks,
archive, newDatabase, outStream, updateCallback, options
#ifndef _NO_CRYPTO
, getPassword
@@ -402,20 +672,20 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
COM_TRY_END
}
-static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
+static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
{
stream = 0;
int index = ParseStringToUInt32(srcString, coder);
if (index == 0)
return E_INVALIDARG;
- srcString.Delete(0, index);
- if (srcString[0] == 'S')
+ srcString.DeleteFrontal(index);
+ if (srcString[0] == 's')
{
srcString.Delete(0);
int index = ParseStringToUInt32(srcString, stream);
if (index == 0)
return E_INVALIDARG;
- srcString.Delete(0, index);
+ srcString.DeleteFrontal(index);
}
return S_OK;
}
@@ -428,36 +698,41 @@ void COutHandler::InitProps()
_compressHeaders = true;
_encryptHeadersSpecified = false;
_encryptHeaders = false;
+ // _useParents = false;
- WriteCTime = false;
- WriteATime = false;
- WriteMTime = true;
-
- _volumeMode = false;
+ Write_CTime.Init();
+ Write_ATime.Init();
+ Write_MTime.Init();
+
+ _useMultiThreadMixer = true;
+
+ // _volumeMode = false;
+
InitSolid();
+ _useTypeSorting = false;
}
HRESULT COutHandler::SetSolidFromString(const UString &s)
{
UString s2 = s;
- s2.MakeUpper();
- for (int i = 0; i < s2.Length();)
+ s2.MakeLower_Ascii();
+ for (unsigned i = 0; i < s2.Len();)
{
const wchar_t *start = ((const wchar_t *)s2) + i;
const wchar_t *end;
UInt64 v = ConvertStringToUInt64(start, &end);
if (start == end)
{
- if (s2[i++] != 'E')
+ if (s2[i++] != 'e')
return E_INVALIDARG;
_solidExtension = true;
continue;
}
i += (int)(end - start);
- if (i == s2.Length())
+ if (i == s2.Len())
return E_INVALIDARG;
wchar_t c = s2[i++];
- if (c == 'F')
+ if (c == 'f')
{
if (v < 1)
v = 1;
@@ -468,10 +743,11 @@ HRESULT COutHandler::SetSolidFromString(const UString &s)
unsigned numBits;
switch (c)
{
- case 'B': numBits = 0; break;
- case 'K': numBits = 10; break;
- case 'M': numBits = 20; break;
- case 'G': numBits = 30; break;
+ 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 E_INVALIDARG;
}
_numSolidBytes = (v << numBits);
@@ -501,14 +777,21 @@ HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value)
return S_OK;
}
+static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest)
+{
+ RINOK(PROPVARIANT_to_bool(prop, dest.Val));
+ dest.Def = true;
+ return S_OK;
+}
+
HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
UString name = nameSpec;
- name.MakeUpper();
+ name.MakeLower_Ascii();
if (name.IsEmpty())
return E_INVALIDARG;
- if (name[0] == L'S')
+ if (name[0] == L's')
{
name.Delete(0);
if (name.IsEmpty())
@@ -520,104 +803,104 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
UInt32 number;
int index = ParseStringToUInt32(name, number);
- UString realName = name.Mid(index);
+ // UString realName = name.Ptr(index);
if (index == 0)
{
- if (name.CompareNoCase(L"RSFX") == 0) return PROPVARIANT_to_bool(value, _removeSfxBlock);
- if (name.CompareNoCase(L"HC") == 0) return PROPVARIANT_to_bool(value, _compressHeaders);
- if (name.CompareNoCase(L"HCF") == 0)
+ if (name.IsEqualTo("rsfx")) return PROPVARIANT_to_bool(value, _removeSfxBlock);
+ if (name.IsEqualTo("hc")) return PROPVARIANT_to_bool(value, _compressHeaders);
+ // if (name.IsEqualToNoCase(L"HS")) return PROPVARIANT_to_bool(value, _useParents);
+
+ if (name.IsEqualTo("hcf"))
{
bool compressHeadersFull = true;
RINOK(PROPVARIANT_to_bool(value, compressHeadersFull));
return compressHeadersFull ? S_OK: E_INVALIDARG;
}
- if (name.CompareNoCase(L"HE") == 0)
+
+ if (name.IsEqualTo("he"))
{
RINOK(PROPVARIANT_to_bool(value, _encryptHeaders));
_encryptHeadersSpecified = true;
return S_OK;
}
- if (name.CompareNoCase(L"TC") == 0) return PROPVARIANT_to_bool(value, WriteCTime);
- if (name.CompareNoCase(L"TA") == 0) return PROPVARIANT_to_bool(value, WriteATime);
- if (name.CompareNoCase(L"TM") == 0) return PROPVARIANT_to_bool(value, WriteMTime);
- if (name.CompareNoCase(L"V") == 0) return PROPVARIANT_to_bool(value, _volumeMode);
+
+ if (name.IsEqualTo("tc")) return PROPVARIANT_to_BoolPair(value, Write_CTime);
+ if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
+ if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
+
+ if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
+
+ if (name.IsEqualTo("qs")) return PROPVARIANT_to_bool(value, _useTypeSorting);
+
+ // if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode);
}
return CMultiMethodProps::SetProperty(name, value);
}
-STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
+STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
COM_TRY_BEGIN
- _binds.Clear();
+ _bonds.Clear();
InitProps();
- for (int i = 0; i < numProps; i++)
+ for (UInt32 i = 0; i < numProps; i++)
{
UString name = names[i];
- name.MakeUpper();
+ name.MakeLower_Ascii();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
- if (name[0] == 'B')
+ if (name[0] == 'b')
{
if (value.vt != VT_EMPTY)
return E_INVALIDARG;
name.Delete(0);
- CBind bind;
- RINOK(GetBindInfoPart(name, bind.OutCoder, bind.OutStream));
+
+ CBond2 bond;
+ RINOK(ParseBond(name, bond.OutCoder, bond.OutStream));
if (name[0] != ':')
return E_INVALIDARG;
name.Delete(0);
- RINOK(GetBindInfoPart(name, bind.InCoder, bind.InStream));
+ UInt32 inStream = 0;
+ RINOK(ParseBond(name, bond.InCoder, inStream));
+ if (inStream != 0)
+ return E_INVALIDARG;
if (!name.IsEmpty())
return E_INVALIDARG;
- _binds.Add(bind);
+ _bonds.Add(bond);
continue;
}
RINOK(SetProperty(name, value));
}
- int numEmptyMethods = GetNumEmptyMethods();
+ unsigned numEmptyMethods = GetNumEmptyMethods();
if (numEmptyMethods > 0)
{
- int k;
- for (k = 0; k < _binds.Size(); k++)
+ unsigned k;
+ for (k = 0; k < _bonds.Size(); k++)
{
- const CBind &bind = _binds[k];
- if (bind.InCoder < (UInt32)numEmptyMethods ||
- bind.OutCoder < (UInt32)numEmptyMethods)
+ const CBond2 &bond = _bonds[k];
+ if (bond.InCoder < (UInt32)numEmptyMethods ||
+ bond.OutCoder < (UInt32)numEmptyMethods)
return E_INVALIDARG;
}
- for (k = 0; k < _binds.Size(); k++)
+ for (k = 0; k < _bonds.Size(); k++)
{
- CBind &bind = _binds[k];
- bind.InCoder -= (UInt32)numEmptyMethods;
- bind.OutCoder -= (UInt32)numEmptyMethods;
+ CBond2 &bond = _bonds[k];
+ bond.InCoder -= (UInt32)numEmptyMethods;
+ bond.OutCoder -= (UInt32)numEmptyMethods;
}
- _methods.Delete(0, numEmptyMethods);
+ _methods.DeleteFrontal(numEmptyMethods);
}
- AddDefaultMethod();
-
- if (!_filterMethod.MethodName.IsEmpty())
- {
- for (int k = 0; k < _binds.Size(); k++)
- {
- CBind &bind = _binds[k];
- bind.InCoder++;
- bind.OutCoder++;
- }
- _methods.Insert(0, _filterMethod);
- }
-
- for (int k = 0; k < _binds.Size(); k++)
+ FOR_VECTOR (k, _bonds)
{
- const CBind &bind = _binds[k];
- if (bind.InCoder >= (UInt32)_methods.Size() ||
- bind.OutCoder >= (UInt32)_methods.Size())
+ const CBond2 &bond = _bonds[k];
+ if (bond.InCoder >= (UInt32)_methods.Size() ||
+ bond.OutCoder >= (UInt32)_methods.Size())
return E_INVALIDARG;
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp
index 5b5f2fb3755..acff2fdd8d9 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp
@@ -1,6 +1,7 @@
// 7zHeader.cpp
#include "StdAfx.h"
+
#include "7zHeader.h"
namespace NArchive {
@@ -11,4 +12,8 @@ Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
#endif
+// We can change signature. So file doesn't contain correct signature.
+// struct SignatureInitializer { SignatureInitializer() { kSignature[0]--; } };
+// static SignatureInitializer g_SignatureInitializer;
+
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h
index 30622b90e83..d7f0ae365b9 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h
@@ -3,12 +3,12 @@
#ifndef __7Z_HEADER_H
#define __7Z_HEADER_H
-#include "../../../Common/Types.h"
+#include "../../../Common/MyTypes.h"
namespace NArchive {
namespace N7z {
-const int kSignatureSize = 6;
+const unsigned kSignatureSize = 6;
extern Byte kSignature[kSignatureSize];
// #define _7Z_VOL
@@ -82,16 +82,67 @@ namespace NID
kCTime,
kATime,
kMTime,
- kWinAttributes,
+ kWinAttrib,
kComment,
kEncodedHeader,
kStartPos,
kDummy
+
+ // kNtSecure,
+ // kParent,
+ // kIsAux
};
}
+
+const UInt32 k_Copy = 0;
+const UInt32 k_Delta = 3;
+
+const UInt32 k_LZMA2 = 0x21;
+
+const UInt32 k_SWAP2 = 0x20302;
+const UInt32 k_SWAP4 = 0x20304;
+
+const UInt32 k_LZMA = 0x30101;
+const UInt32 k_PPMD = 0x30401;
+
+const UInt32 k_Deflate = 0x40108;
+const UInt32 k_BZip2 = 0x40202;
+
+const UInt32 k_BCJ = 0x3030103;
+const UInt32 k_BCJ2 = 0x303011B;
+const UInt32 k_PPC = 0x3030205;
+const UInt32 k_IA64 = 0x3030401;
+const UInt32 k_ARM = 0x3030501;
+const UInt32 k_ARMT = 0x3030701;
+const UInt32 k_SPARC = 0x3030805;
+
+const UInt32 k_AES = 0x6F10701;
+
+
+static inline bool IsFilterMethod(UInt64 m)
+{
+ if (m > (UInt64)0xFFFFFFFF)
+ return false;
+ switch ((UInt32)m)
+ {
+ case k_Delta:
+ case k_BCJ:
+ case k_BCJ2:
+ case k_PPC:
+ case k_IA64:
+ case k_ARM:
+ case k_ARMT:
+ case k_SPARC:
+ case k_SWAP2:
+ case k_SWAP4:
+ return true;
+ }
+ return false;
+}
+
}}
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp
index fd751a7483f..fc527be653b 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp
@@ -2,6 +2,12 @@
#include "StdAfx.h"
+#ifdef _WIN32
+#include <wchar.h>
+#else
+#include <ctype.h>
+#endif
+
#include "../../../../C/7zCrc.h"
#include "../../../../C/CpuArch.h"
@@ -20,127 +26,38 @@
#define FORMAT_7Z_RECOVERY
#endif
+using namespace NWindows;
+using namespace NCOM;
+
namespace NArchive {
namespace N7z {
-static void BoolVector_Fill_False(CBoolVector &v, int size)
-{
- v.Clear();
- v.Reserve(size);
- for (int i = 0; i < size; i++)
- v.Add(false);
-}
-
-static bool BoolVector_GetAndSet(CBoolVector &v, UInt32 index)
+static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
{
- if (index >= (UInt32)v.Size())
- return true;
- bool res = v[index];
- v[index] = true;
- return res;
-}
-
-bool CFolder::CheckStructure() const
-{
- const int kNumCodersMax = sizeof(UInt32) * 8; // don't change it
- const int kMaskSize = sizeof(UInt32) * 8; // it must be >= kNumCodersMax
- const int kNumBindsMax = 32;
-
- if (Coders.Size() > kNumCodersMax || BindPairs.Size() > kNumBindsMax)
- return false;
-
- {
- CBoolVector v;
- BoolVector_Fill_False(v, BindPairs.Size() + PackStreams.Size());
-
- int i;
- for (i = 0; i < BindPairs.Size(); i++)
- if (BoolVector_GetAndSet(v, BindPairs[i].InIndex))
- return false;
- for (i = 0; i < PackStreams.Size(); i++)
- if (BoolVector_GetAndSet(v, PackStreams[i]))
- return false;
-
- BoolVector_Fill_False(v, UnpackSizes.Size());
- for (i = 0; i < BindPairs.Size(); i++)
- if (BoolVector_GetAndSet(v, BindPairs[i].OutIndex))
- return false;
- }
-
- UInt32 mask[kMaskSize];
- int i;
- for (i = 0; i < kMaskSize; i++)
- mask[i] = 0;
-
- {
- CIntVector inStreamToCoder, outStreamToCoder;
- for (i = 0; i < Coders.Size(); i++)
- {
- CNum j;
- const CCoderInfo &coder = Coders[i];
- for (j = 0; j < coder.NumInStreams; j++)
- inStreamToCoder.Add(i);
- for (j = 0; j < coder.NumOutStreams; j++)
- outStreamToCoder.Add(i);
- }
-
- for (i = 0; i < BindPairs.Size(); i++)
- {
- const CBindPair &bp = BindPairs[i];
- mask[inStreamToCoder[bp.InIndex]] |= (1 << outStreamToCoder[bp.OutIndex]);
- }
- }
-
- for (i = 0; i < kMaskSize; i++)
- for (int j = 0; j < kMaskSize; j++)
- if (((1 << j) & mask[i]) != 0)
- mask[i] |= mask[j];
-
- for (i = 0; i < kMaskSize; i++)
- if (((1 << i) & mask[i]) != 0)
- return false;
-
- return true;
+ v.ClearAndSetSize(size);
+ bool *p = &v[0];
+ for (unsigned i = 0; i < size; i++)
+ p[i] = false;
}
class CInArchiveException {};
+class CUnsupportedFeatureException: public CInArchiveException {};
static void ThrowException() { throw CInArchiveException(); }
static inline void ThrowEndOfData() { ThrowException(); }
-static inline void ThrowUnsupported() { ThrowException(); }
+static inline void ThrowUnsupported() { throw CUnsupportedFeatureException(); }
static inline void ThrowIncorrect() { ThrowException(); }
-static inline void ThrowUnsupportedVersion() { ThrowException(); }
-
-/*
-class CInArchiveException
-{
-public:
- enum CCauseType
- {
- kUnsupportedVersion = 0,
- kUnsupported,
- kIncorrect,
- kEndOfData
- } Cause;
- CInArchiveException(CCauseType cause): Cause(cause) {};
-};
-
-static void ThrowException(CInArchiveException::CCauseType c) { throw CInArchiveException(c); }
-static void ThrowEndOfData() { ThrowException(CInArchiveException::kEndOfData); }
-static void ThrowUnsupported() { ThrowException(CInArchiveException::kUnsupported); }
-static void ThrowIncorrect() { ThrowException(CInArchiveException::kIncorrect); }
-static void ThrowUnsupportedVersion() { ThrowException(CInArchiveException::kUnsupportedVersion); }
-*/
class CStreamSwitch
{
CInArchive *_archive;
bool _needRemove;
+ bool _needUpdatePos;
public:
- CStreamSwitch(): _needRemove(false) {}
+ CStreamSwitch(): _needRemove(false), _needUpdatePos(false) {}
~CStreamSwitch() { Remove(); }
void Remove();
- void Set(CInArchive *archive, const Byte *data, size_t size);
+ void Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos);
void Set(CInArchive *archive, const CByteBuffer &byteBuffer);
void Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector);
};
@@ -149,22 +66,25 @@ void CStreamSwitch::Remove()
{
if (_needRemove)
{
- _archive->DeleteByteStream();
+ if (_archive->_inByteBack->GetRem() != 0)
+ _archive->ThereIsHeaderError = true;
+ _archive->DeleteByteStream(_needUpdatePos);
_needRemove = false;
}
}
-void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size)
+void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos)
{
Remove();
_archive = archive;
_archive->AddByteStream(data, size);
_needRemove = true;
+ _needUpdatePos = needUpdatePos;
}
void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer)
{
- Set(archive, byteBuffer, byteBuffer.GetCapacity());
+ Set(archive, byteBuffer, byteBuffer.Size(), false);
}
void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector)
@@ -173,13 +93,22 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *d
Byte external = archive->ReadByte();
if (external != 0)
{
- int dataIndex = (int)archive->ReadNum();
- if (dataIndex < 0 || dataIndex >= dataVector->Size())
+ CNum dataIndex = archive->ReadNum();
+ if (dataIndex >= dataVector->Size())
ThrowIncorrect();
Set(archive, (*dataVector)[dataIndex]);
}
}
+void CInArchive::AddByteStream(const Byte *buf, size_t size)
+{
+ if (_numInByteBufs == kNumBufLevelsMax)
+ ThrowIncorrect();
+ _inByteBack = &_inByteVector[_numInByteBufs++];
+ _inByteBack->Init(buf, size);
+}
+
+
Byte CInByte2::ReadByte()
{
if (_pos >= _size)
@@ -189,10 +118,12 @@ Byte CInByte2::ReadByte()
void CInByte2::ReadBytes(Byte *data, size_t size)
{
+ if (size == 0)
+ return;
if (size > _size - _pos)
ThrowEndOfData();
- for (size_t i = 0; i < size; i++)
- data[i] = _buffer[_pos++];
+ memcpy(data, _buffer + _pos, size);
+ _pos += size;
}
void CInByte2::SkipData(UInt64 size)
@@ -207,31 +138,82 @@ void CInByte2::SkipData()
SkipData(ReadNumber());
}
-UInt64 CInByte2::ReadNumber()
+static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed)
{
- if (_pos >= _size)
- ThrowEndOfData();
- Byte firstByte = _buffer[_pos++];
- Byte mask = 0x80;
- UInt64 value = 0;
- for (int i = 0; i < 8; i++)
+ if (size == 0)
+ {
+ processed = 0;
+ return 0;
+ }
+
+ unsigned b = *p++;
+ size--;
+
+ if ((b & 0x80) == 0)
+ {
+ processed = 1;
+ return b;
+ }
+
+ if (size == 0)
{
- if ((firstByte & mask) == 0)
+ processed = 0;
+ return 0;
+ }
+
+ UInt64 value = (UInt64)*p;
+ p++;
+ size--;
+
+ for (unsigned i = 1; i < 8; i++)
+ {
+ unsigned mask = (unsigned)0x80 >> i;
+ if ((b & mask) == 0)
{
- UInt64 highPart = firstByte & (mask - 1);
- value += (highPart << (i * 8));
+ UInt64 high = b & (mask - 1);
+ value |= (high << (i * 8));
+ processed = i + 1;
return value;
}
- if (_pos >= _size)
- ThrowEndOfData();
- value |= ((UInt64)_buffer[_pos++] << (8 * i));
- mask >>= 1;
+
+ if (size == 0)
+ {
+ processed = 0;
+ return 0;
+ }
+
+ value |= ((UInt64)*p << (i * 8));
+ p++;
+ size--;
}
+
+ processed = 9;
return value;
}
+UInt64 CInByte2::ReadNumber()
+{
+ size_t processed;
+ UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed);
+ if (processed == 0)
+ ThrowEndOfData();
+ _pos += processed;
+ return res;
+}
+
CNum CInByte2::ReadNum()
{
+ /*
+ if (_pos < _size)
+ {
+ Byte val = _buffer[_pos];
+ if ((unsigned)val < 0x80)
+ {
+ _pos++;
+ return (unsigned)val;
+ }
+ }
+ */
UInt64 value = ReadNumber();
if (value > kNumMax)
ThrowUnsupported();
@@ -256,48 +238,21 @@ UInt64 CInByte2::ReadUInt64()
return res;
}
-void CInByte2::ReadString(UString &s)
-{
- const Byte *buf = _buffer + _pos;
- size_t rem = (_size - _pos) / 2 * 2;
- {
- size_t i;
- for (i = 0; i < rem; i += 2)
- if (buf[i] == 0 && buf[i + 1] == 0)
- break;
- if (i == rem)
- ThrowEndOfData();
- rem = i;
- }
- int len = (int)(rem / 2);
- if (len < 0 || (size_t)len * 2 != rem)
- ThrowUnsupported();
- wchar_t *p = s.GetBuffer(len);
- int i;
- for (i = 0; i < len; i++, buf += 2)
- p[i] = (wchar_t)Get16(buf);
- s.ReleaseBuffer(len);
- _pos += rem + 2;
-}
+#define CHECK_SIGNATURE if (p[0] != '7' || p[1] != 'z' || p[2] != 0xBC || p[3] != 0xAF || p[4] != 0x27 || p[5] != 0x1C) return false;
static inline bool TestSignature(const Byte *p)
{
- for (int i = 0; i < kSignatureSize; i++)
- if (p[i] != kSignature[i])
- return false;
- return CrcCalc(p + 12, 20) == GetUi32(p + 8);
+ CHECK_SIGNATURE
+ return CrcCalc(p + 12, 20) == Get32(p + 8);
}
#ifdef FORMAT_7Z_RECOVERY
static inline bool TestSignature2(const Byte *p)
{
- int i;
- for (i = 0; i < kSignatureSize; i++)
- if (p[i] != kSignature[i])
- return false;
- if (CrcCalc(p + 12, 20) == GetUi32(p + 8))
+ CHECK_SIGNATURE;
+ if (CrcCalc(p + 12, 20) == Get32(p + 8))
return true;
- for (i = 8; i < kHeaderSize; i++)
+ for (unsigned i = 8; i < kHeaderSize; i++)
if (p[i] != 0)
return false;
return (p[6] != 0 || p[7] != 0);
@@ -312,39 +267,56 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
if (TestSignature2(_header))
return S_OK;
+ if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0)
+ return S_FALSE;
- CByteBuffer byteBuffer;
- const UInt32 kBufferSize = (1 << 16);
- byteBuffer.SetCapacity(kBufferSize);
- Byte *buffer = byteBuffer;
- memcpy(buffer, _header, kHeaderSize);
- UInt64 curTestPos = _arhiveBeginStreamPosition;
+ const UInt32 kBufSize = 1 << 15;
+ CByteArr buf(kBufSize);
+ memcpy(buf, _header, kHeaderSize);
+ UInt64 offset = 0;
+
for (;;)
{
- if (searchHeaderSizeLimit != NULL)
- if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
- break;
- UInt32 processedSize;
- RINOK(stream->Read(buffer + kHeaderSize, kBufferSize - kHeaderSize, &processedSize));
- if (processedSize == 0)
+ UInt32 readSize = kBufSize - kHeaderSize;
+ if (searchHeaderSizeLimit)
+ {
+ UInt64 rem = *searchHeaderSizeLimit - offset;
+ if (readSize > rem)
+ readSize = (UInt32)rem;
+ if (readSize == 0)
+ return S_FALSE;
+ }
+
+ UInt32 processed = 0;
+ RINOK(stream->Read(buf + kHeaderSize, readSize, &processed));
+ if (processed == 0)
return S_FALSE;
- for (UInt32 pos = 1; pos <= processedSize; pos++)
+
+ for (UInt32 pos = 0;;)
{
- for (; buffer[pos] != '7' && pos <= processedSize; pos++);
- if (pos > processedSize)
+ const Byte *p = buf + pos + 1;
+ const Byte *lim = buf + processed;
+ for (; p <= lim; p += 4)
+ {
+ if (p[0] == '7') break;
+ if (p[1] == '7') { p += 1; break; }
+ if (p[2] == '7') { p += 2; break; }
+ if (p[3] == '7') { p += 3; break; }
+ };
+ if (p > lim)
break;
- if (TestSignature(buffer + pos))
+ pos = (UInt32)(p - buf);
+ if (TestSignature(p))
{
- memcpy(_header, buffer + pos, kHeaderSize);
- curTestPos += pos;
- _arhiveBeginStreamPosition = curTestPos;
- return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
+ memcpy(_header, p, kHeaderSize);
+ _arhiveBeginStreamPosition += offset + pos;
+ return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL);
}
}
- curTestPos += processedSize;
- memmove(buffer, buffer + processedSize, kHeaderSize);
+
+ offset += processed;
+ memmove(buf, buf + processed, kHeaderSize);
}
- return S_FALSE;
}
// S_FALSE means that file is not archive
@@ -362,7 +334,9 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
void CInArchive::Close()
{
+ _numInByteBufs = 0;
_stream.Release();
+ ThereIsHeaderError = false;
}
void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)
@@ -375,92 +349,214 @@ void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)
}
}
-void CInArchive::GetNextFolderItem(CFolder &folder)
+// CFolder &folder can be non empty. So we must set all fields
+
+void CInByte2::ParseFolder(CFolder &folder)
{
- CNum numCoders = ReadNum();
+ UInt32 numCoders = ReadNum();
- folder.Coders.Clear();
- folder.Coders.Reserve((int)numCoders);
- CNum numInStreams = 0;
- CNum numOutStreams = 0;
- CNum i;
+ if (numCoders == 0)
+ ThrowUnsupported();
+
+ folder.Coders.SetSize(numCoders);
+
+ UInt32 numInStreams = 0;
+ UInt32 i;
for (i = 0; i < numCoders; i++)
{
- folder.Coders.Add(CCoderInfo());
- CCoderInfo &coder = folder.Coders.Back();
-
+ CCoderInfo &coder = folder.Coders[i];
{
Byte mainByte = ReadByte();
- int idSize = (mainByte & 0xF);
- Byte longID[15];
- ReadBytes(longID, idSize);
- if (idSize > 8)
+ if ((mainByte & 0xC0) != 0)
ThrowUnsupported();
+ unsigned idSize = (mainByte & 0xF);
+ if (idSize > 8 || idSize > GetRem())
+ ThrowUnsupported();
+ const Byte *longID = GetPtr();
UInt64 id = 0;
- for (int j = 0; j < idSize; j++)
- id |= (UInt64)longID[idSize - 1 - j] << (8 * j);
+ for (unsigned j = 0; j < idSize; j++)
+ id = ((id << 8) | longID[j]);
+ SkipDataNoCheck(idSize);
coder.MethodID = id;
if ((mainByte & 0x10) != 0)
{
- coder.NumInStreams = ReadNum();
- coder.NumOutStreams = ReadNum();
+ coder.NumStreams = ReadNum();
+ /* numOutStreams = */ ReadNum();
}
else
{
- coder.NumInStreams = 1;
- coder.NumOutStreams = 1;
+ coder.NumStreams = 1;
}
+
if ((mainByte & 0x20) != 0)
{
CNum propsSize = ReadNum();
- coder.Props.SetCapacity((size_t)propsSize);
+ coder.Props.Alloc((size_t)propsSize);
ReadBytes((Byte *)coder.Props, (size_t)propsSize);
}
- if ((mainByte & 0x80) != 0)
- ThrowUnsupported();
+ else
+ coder.Props.Free();
}
- numInStreams += coder.NumInStreams;
- numOutStreams += coder.NumOutStreams;
+ numInStreams += coder.NumStreams;
}
- CNum numBindPairs = numOutStreams - 1;
- folder.BindPairs.Clear();
- folder.BindPairs.Reserve(numBindPairs);
- for (i = 0; i < numBindPairs; i++)
+ UInt32 numBonds = numCoders - 1;
+ folder.Bonds.SetSize(numBonds);
+ for (i = 0; i < numBonds; i++)
{
- CBindPair bp;
- bp.InIndex = ReadNum();
- bp.OutIndex = ReadNum();
- folder.BindPairs.Add(bp);
+ CBond &bp = folder.Bonds[i];
+ bp.PackIndex = ReadNum();
+ bp.UnpackIndex = ReadNum();
}
- if (numInStreams < numBindPairs)
+ if (numInStreams < numBonds)
ThrowUnsupported();
- CNum numPackStreams = numInStreams - numBindPairs;
- folder.PackStreams.Reserve(numPackStreams);
+ UInt32 numPackStreams = numInStreams - numBonds;
+ folder.PackStreams.SetSize(numPackStreams);
+
if (numPackStreams == 1)
{
for (i = 0; i < numInStreams; i++)
- if (folder.FindBindPairForInStream(i) < 0)
+ if (folder.FindBond_for_PackStream(i) < 0)
{
- folder.PackStreams.Add(i);
+ folder.PackStreams[0] = i;
break;
}
- if (folder.PackStreams.Size() != 1)
+ if (i == numInStreams)
ThrowUnsupported();
}
else
for (i = 0; i < numPackStreams; i++)
- folder.PackStreams.Add(ReadNum());
+ folder.PackStreams[i] = ReadNum();
+}
+
+void CFolders::ParseFolderInfo(unsigned folderIndex, CFolder &folder) const
+{
+ size_t startPos = FoCodersDataOffset[folderIndex];
+ CInByte2 inByte;
+ inByte.Init(CodersData + startPos, FoCodersDataOffset[folderIndex + 1] - startPos);
+ inByte.ParseFolder(folder);
+ if (inByte.GetRem() != 0)
+ throw 20120424;
+}
+
+
+void CDatabase::GetPath(unsigned index, UString &path) const
+{
+ path.Empty();
+ if (!NameOffsets || !NamesBuf)
+ return;
+
+ size_t offset = NameOffsets[index];
+ size_t size = NameOffsets[index + 1] - offset;
+
+ if (size >= (1 << 28))
+ return;
+
+ wchar_t *s = path.GetBuf((unsigned)size - 1);
+
+ const Byte *p = ((const Byte *)NamesBuf + offset * 2);
+
+ #if defined(_WIN32) && defined(MY_CPU_LE)
+
+ wmemcpy(s, (const wchar_t *)p, size);
+
+ #else
+
+ for (size_t i = 0; i < size; i++)
+ {
+ *s = Get16(p);
+ p += 2;
+ s++;
+ }
+
+ #endif
+
+ path.ReleaseBuf_SetLen((unsigned)size - 1);
+}
+
+HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
+{
+ PropVariant_Clear(path);
+ if (!NameOffsets || !NamesBuf)
+ return S_OK;
+
+ size_t offset = NameOffsets[index];
+ size_t size = NameOffsets[index + 1] - offset;
+
+ if (size >= (1 << 14))
+ return S_OK;
+
+ RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1));
+ wchar_t *s = path->bstrVal;
+
+ const Byte *p = ((const Byte *)NamesBuf + offset * 2);
+
+ for (size_t i = 0; i < size; i++)
+ {
+ wchar_t c = Get16(p);
+ p += 2;
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ if (c == L'/')
+ c = WCHAR_PATH_SEPARATOR;
+ #endif
+ *s++ = c;
+ }
+
+ return S_OK;
+
+ /*
+ unsigned cur = index;
+ unsigned size = 0;
+
+ for (int i = 0;; i++)
+ {
+ size_t len = NameOffsets[cur + 1] - NameOffsets[cur];
+ size += (unsigned)len;
+ if (i > 256 || len > (1 << 14) || size > (1 << 14))
+ return PropVarEm_Set_Str(path, "[TOO-LONG]");
+ cur = Files[cur].Parent;
+ if (cur < 0)
+ break;
+ }
+ size--;
+
+ RINOK(PropVarEm_Alloc_Bstr(path, size));
+ wchar_t *s = path->bstrVal;
+ s += size;
+ *s = 0;
+ cur = index;
+
+ for (;;)
+ {
+ unsigned len = (unsigned)(NameOffsets[cur + 1] - NameOffsets[cur] - 1);
+ const Byte *p = (const Byte *)NamesBuf + (NameOffsets[cur + 1] * 2) - 2;
+ for (; len != 0; len--)
+ {
+ p -= 2;
+ --s;
+ wchar_t c = Get16(p);
+ if (c == '/')
+ c = WCHAR_PATH_SEPARATOR;
+ *s = c;
+ }
+
+ const CFileItem &file = Files[cur];
+ cur = file.Parent;
+ if (cur < 0)
+ return S_OK;
+ *(--s) = (file.IsAltStream ? ':' : WCHAR_PATH_SEPARATOR);
+ }
+ */
}
-void CInArchive::WaitAttribute(UInt64 attribute)
+void CInArchive::WaitId(UInt64 id)
{
for (;;)
{
UInt64 type = ReadID();
- if (type == attribute)
+ if (type == id)
return;
if (type == NID::kEnd)
ThrowIncorrect();
@@ -468,91 +564,219 @@ void CInArchive::WaitAttribute(UInt64 attribute)
}
}
-void CInArchive::ReadHashDigests(int numItems,
- CBoolVector &digestsDefined,
- CRecordVector<UInt32> &digests)
+void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
{
- ReadBoolVector2(numItems, digestsDefined);
- digests.Clear();
- digests.Reserve(numItems);
- for (int i = 0; i < numItems; i++)
+ ReadBoolVector2(numItems, crcs.Defs);
+ crcs.Vals.ClearAndSetSize(numItems);
+ UInt32 *p = &crcs.Vals[0];
+ const bool *defs = &crcs.Defs[0];
+ for (unsigned i = 0; i < numItems; i++)
{
UInt32 crc = 0;
- if (digestsDefined[i])
+ if (defs[i])
crc = ReadUInt32();
- digests.Add(crc);
+ p[i] = crc;
}
}
-void CInArchive::ReadPackInfo(
- UInt64 &dataOffset,
- CRecordVector<UInt64> &packSizes,
- CBoolVector &packCRCsDefined,
- CRecordVector<UInt32> &packCRCs)
+#define k_Scan_NumCoders_MAX 64
+#define k_Scan_NumCodersStreams_in_Folder_MAX 64
+
+void CInArchive::ReadPackInfo(CFolders &f)
{
- dataOffset = ReadNumber();
CNum numPackStreams = ReadNum();
-
- WaitAttribute(NID::kSize);
- packSizes.Clear();
- packSizes.Reserve(numPackStreams);
+
+ WaitId(NID::kSize);
+ f.PackPositions.Alloc(numPackStreams + 1);
+ f.NumPackStreams = numPackStreams;
+ UInt64 sum = 0;
for (CNum i = 0; i < numPackStreams; i++)
- packSizes.Add(ReadNumber());
+ {
+ f.PackPositions[i] = sum;
+ UInt64 packSize = ReadNumber();
+ sum += packSize;
+ if (sum < packSize)
+ ThrowIncorrect();
+ }
+ f.PackPositions[numPackStreams] = sum;
UInt64 type;
for (;;)
{
type = ReadID();
if (type == NID::kEnd)
- break;
+ return;
if (type == NID::kCRC)
{
- ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs);
+ CUInt32DefVector PackCRCs;
+ ReadHashDigests(numPackStreams, PackCRCs);
continue;
}
SkipData();
}
- if (packCRCsDefined.IsEmpty())
- {
- BoolVector_Fill_False(packCRCsDefined, numPackStreams);
- packCRCs.Reserve(numPackStreams);
- packCRCs.Clear();
- for (CNum i = 0; i < numPackStreams; i++)
- packCRCs.Add(0);
- }
}
void CInArchive::ReadUnpackInfo(
const CObjectVector<CByteBuffer> *dataVector,
- CObjectVector<CFolder> &folders)
+ CFolders &folders)
{
- WaitAttribute(NID::kFolder);
+ WaitId(NID::kFolder);
CNum numFolders = ReadNum();
+ CNum numCodersOutStreams = 0;
{
CStreamSwitch streamSwitch;
streamSwitch.Set(this, dataVector);
- folders.Clear();
- folders.Reserve(numFolders);
- for (CNum i = 0; i < numFolders; i++)
+ const Byte *startBufPtr = _inByteBack->GetPtr();
+ folders.NumFolders = numFolders;
+
+ folders.FoStartPackStreamIndex.Alloc(numFolders + 1);
+ folders.FoToMainUnpackSizeIndex.Alloc(numFolders);
+ folders.FoCodersDataOffset.Alloc(numFolders + 1);
+ folders.FoToCoderUnpackSizes.Alloc(numFolders + 1);
+
+ CBoolVector StreamUsed;
+ CBoolVector CoderUsed;
+
+ CNum packStreamIndex = 0;
+ CNum fo;
+ CInByte2 *inByte = _inByteBack;
+
+ for (fo = 0; fo < numFolders; fo++)
{
- folders.Add(CFolder());
- GetNextFolderItem(folders.Back());
- }
- }
+ UInt32 indexOfMainStream = 0;
+ UInt32 numPackStreams = 0;
+ folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
- WaitAttribute(NID::kCodersUnpackSize);
+ CNum numInStreams = 0;
+ CNum numCoders = inByte->ReadNum();
+
+ if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX)
+ ThrowUnsupported();
- CNum i;
- for (i = 0; i < numFolders; i++)
- {
- CFolder &folder = folders[i];
- CNum numOutStreams = folder.GetNumOutStreams();
- folder.UnpackSizes.Reserve(numOutStreams);
- for (CNum j = 0; j < numOutStreams; j++)
- folder.UnpackSizes.Add(ReadNumber());
+ for (CNum ci = 0; ci < numCoders; ci++)
+ {
+ Byte mainByte = inByte->ReadByte();
+ if ((mainByte & 0xC0) != 0)
+ ThrowUnsupported();
+
+ unsigned idSize = (mainByte & 0xF);
+ if (idSize > 8)
+ ThrowUnsupported();
+ if (idSize > inByte->GetRem())
+ ThrowEndOfData();
+ const Byte *longID = inByte->GetPtr();
+ UInt64 id = 0;
+ for (unsigned j = 0; j < idSize; j++)
+ id = ((id << 8) | longID[j]);
+ inByte->SkipDataNoCheck(idSize);
+ if (folders.ParsedMethods.IDs.Size() < 128)
+ folders.ParsedMethods.IDs.AddToUniqueSorted(id);
+
+ CNum coderInStreams = 1;
+ if ((mainByte & 0x10) != 0)
+ {
+ coderInStreams = inByte->ReadNum();
+ if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
+ ThrowUnsupported();
+ if (inByte->ReadNum() != 1)
+ ThrowUnsupported();
+ }
+
+ numInStreams += coderInStreams;
+ if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
+ ThrowUnsupported();
+
+ if ((mainByte & 0x20) != 0)
+ {
+ CNum propsSize = inByte->ReadNum();
+ if (propsSize > inByte->GetRem())
+ ThrowEndOfData();
+ if (id == k_LZMA2 && propsSize == 1)
+ {
+ Byte v = *_inByteBack->GetPtr();
+ if (folders.ParsedMethods.Lzma2Prop < v)
+ folders.ParsedMethods.Lzma2Prop = v;
+ }
+ else if (id == k_LZMA && propsSize == 5)
+ {
+ UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1);
+ if (folders.ParsedMethods.LzmaDic < dicSize)
+ folders.ParsedMethods.LzmaDic = dicSize;
+ }
+ inByte->SkipDataNoCheck((size_t)propsSize);
+ }
+ }
+
+ if (numCoders == 1 && numInStreams == 1)
+ {
+ indexOfMainStream = 0;
+ numPackStreams = 1;
+ }
+ else
+ {
+ UInt32 i;
+ CNum numBonds = numCoders - 1;
+ if (numInStreams < numBonds)
+ ThrowUnsupported();
+
+ BoolVector_Fill_False(StreamUsed, numInStreams);
+ BoolVector_Fill_False(CoderUsed, numCoders);
+
+ for (i = 0; i < numBonds; i++)
+ {
+ CNum index = ReadNum();
+ if (index >= numInStreams || StreamUsed[index])
+ ThrowUnsupported();
+ StreamUsed[index] = true;
+
+ index = ReadNum();
+ if (index >= numCoders || CoderUsed[index])
+ ThrowUnsupported();
+ CoderUsed[index] = true;
+ }
+
+ numPackStreams = numInStreams - numBonds;
+
+ if (numPackStreams != 1)
+ for (i = 0; i < numPackStreams; i++)
+ {
+ CNum index = inByte->ReadNum(); // PackStreams
+ if (index >= numInStreams || StreamUsed[index])
+ ThrowUnsupported();
+ StreamUsed[index] = true;
+ }
+
+ for (i = 0; i < numCoders; i++)
+ if (!CoderUsed[i])
+ {
+ indexOfMainStream = i;
+ break;
+ }
+
+ if (i == numCoders)
+ ThrowUnsupported();
+ }
+
+ folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
+ numCodersOutStreams += numCoders;
+ folders.FoStartPackStreamIndex[fo] = packStreamIndex;
+ packStreamIndex += numPackStreams;
+ folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
+ }
+
+ size_t dataSize = _inByteBack->GetPtr() - startBufPtr;
+ folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
+ folders.FoStartPackStreamIndex[fo] = packStreamIndex;
+ folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
+ folders.CodersData.CopyFrom(startBufPtr, dataSize);
}
+ WaitId(NID::kCodersUnpackSize);
+ folders.CoderUnpackSizes.Alloc(numCodersOutStreams);
+ for (CNum i = 0; i < numCodersOutStreams; i++)
+ folders.CoderUnpackSizes[i] = ReadNumber();
+
for (;;)
{
UInt64 type = ReadID();
@@ -560,15 +784,7 @@ void CInArchive::ReadUnpackInfo(
return;
if (type == NID::kCRC)
{
- CBoolVector crcsDefined;
- CRecordVector<UInt32> crcs;
- ReadHashDigests(numFolders, crcsDefined, crcs);
- for (i = 0; i < numFolders; i++)
- {
- CFolder &folder = folders[i];
- folder.UnpackCRCDefined = crcsDefined[i];
- folder.UnpackCRC = crcs[i];
- }
+ ReadHashDigests(numFolders, folders.FolderCRCs);
continue;
}
SkipData();
@@ -576,170 +792,217 @@ void CInArchive::ReadUnpackInfo(
}
void CInArchive::ReadSubStreamsInfo(
- const CObjectVector<CFolder> &folders,
- CRecordVector<CNum> &numUnpackStreamsInFolders,
+ CFolders &folders,
CRecordVector<UInt64> &unpackSizes,
- CBoolVector &digestsDefined,
- CRecordVector<UInt32> &digests)
+ CUInt32DefVector &digests)
{
- numUnpackStreamsInFolders.Clear();
- numUnpackStreamsInFolders.Reserve(folders.Size());
+ folders.NumUnpackStreamsVector.Alloc(folders.NumFolders);
+ CNum i;
+ for (i = 0; i < folders.NumFolders; i++)
+ folders.NumUnpackStreamsVector[i] = 1;
+
UInt64 type;
+
for (;;)
{
type = ReadID();
if (type == NID::kNumUnpackStream)
{
- for (int i = 0; i < folders.Size(); i++)
- numUnpackStreamsInFolders.Add(ReadNum());
+ for (i = 0; i < folders.NumFolders; i++)
+ folders.NumUnpackStreamsVector[i] = ReadNum();
continue;
}
- if (type == NID::kCRC || type == NID::kSize)
- break;
- if (type == NID::kEnd)
+ if (type == NID::kCRC || type == NID::kSize || type == NID::kEnd)
break;
SkipData();
}
- if (numUnpackStreamsInFolders.IsEmpty())
- for (int i = 0; i < folders.Size(); i++)
- numUnpackStreamsInFolders.Add(1);
-
- int i;
- for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
+ if (type == NID::kSize)
{
- // v3.13 incorrectly worked with empty folders
- // v4.07: we check that folder is empty
- CNum numSubstreams = numUnpackStreamsInFolders[i];
- if (numSubstreams == 0)
- continue;
- UInt64 sum = 0;
- for (CNum j = 1; j < numSubstreams; j++)
- if (type == NID::kSize)
+ for (i = 0; i < folders.NumFolders; i++)
+ {
+ // v3.13 incorrectly worked with empty folders
+ // v4.07: we check that folder is empty
+ CNum numSubstreams = folders.NumUnpackStreamsVector[i];
+ if (numSubstreams == 0)
+ continue;
+ UInt64 sum = 0;
+ for (CNum j = 1; j < numSubstreams; j++)
{
UInt64 size = ReadNumber();
unpackSizes.Add(size);
sum += size;
+ if (sum < size)
+ ThrowIncorrect();
}
- unpackSizes.Add(folders[i].GetUnpackSize() - sum);
- }
- if (type == NID::kSize)
+ UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i);
+ if (folderUnpackSize < sum)
+ ThrowIncorrect();
+ unpackSizes.Add(folderUnpackSize - sum);
+ }
type = ReadID();
+ }
+ else
+ {
+ for (i = 0; i < folders.NumFolders; i++)
+ {
+ /* v9.26 - v9.29 incorrectly worked:
+ if (folders.NumUnpackStreamsVector[i] == 0), it threw error */
+ CNum val = folders.NumUnpackStreamsVector[i];
+ if (val > 1)
+ ThrowIncorrect();
+ if (val == 1)
+ unpackSizes.Add(folders.GetFolderUnpackSize(i));
+ }
+ }
- int numDigests = 0;
- int numDigestsTotal = 0;
- for (i = 0; i < folders.Size(); i++)
+ unsigned numDigests = 0;
+ for (i = 0; i < folders.NumFolders; i++)
{
- CNum numSubstreams = numUnpackStreamsInFolders[i];
- if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
+ CNum numSubstreams = folders.NumUnpackStreamsVector[i];
+ if (numSubstreams != 1 || !folders.FolderCRCs.ValidAndDefined(i))
numDigests += numSubstreams;
- numDigestsTotal += numSubstreams;
}
for (;;)
{
+ if (type == NID::kEnd)
+ break;
if (type == NID::kCRC)
{
- CBoolVector digestsDefined2;
- CRecordVector<UInt32> digests2;
- ReadHashDigests(numDigests, digestsDefined2, digests2);
- int digestIndex = 0;
- for (i = 0; i < folders.Size(); i++)
+ // CUInt32DefVector digests2;
+ // ReadHashDigests(numDigests, digests2);
+ CBoolVector digests2;
+ ReadBoolVector2(numDigests, digests2);
+
+ digests.ClearAndSetSize(unpackSizes.Size());
+
+ unsigned k = 0;
+ unsigned k2 = 0;
+
+ for (i = 0; i < folders.NumFolders; i++)
{
- CNum numSubstreams = numUnpackStreamsInFolders[i];
- const CFolder &folder = folders[i];
- if (numSubstreams == 1 && folder.UnpackCRCDefined)
+ CNum numSubstreams = folders.NumUnpackStreamsVector[i];
+ if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i))
{
- digestsDefined.Add(true);
- digests.Add(folder.UnpackCRC);
+ digests.Defs[k] = true;
+ digests.Vals[k] = folders.FolderCRCs.Vals[i];
+ k++;
+ }
+ else for (CNum j = 0; j < numSubstreams; j++)
+ {
+ bool defined = digests2[k2++];
+ digests.Defs[k] = defined;
+ UInt32 crc = 0;
+ if (defined)
+ crc = ReadUInt32();
+ digests.Vals[k] = crc;
+ k++;
}
- else
- for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
- {
- digestsDefined.Add(digestsDefined2[digestIndex]);
- digests.Add(digests2[digestIndex]);
- }
}
+ // if (k != unpackSizes.Size()) throw 1234567;
}
- else if (type == NID::kEnd)
+ else
+ SkipData();
+
+ type = ReadID();
+ }
+
+ if (digests.Defs.Size() != unpackSizes.Size())
+ {
+ digests.ClearAndSetSize(unpackSizes.Size());
+ unsigned k = 0;
+ for (i = 0; i < folders.NumFolders; i++)
{
- if (digestsDefined.IsEmpty())
+ CNum numSubstreams = folders.NumUnpackStreamsVector[i];
+ if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i))
{
- BoolVector_Fill_False(digestsDefined, numDigestsTotal);
- digests.Clear();
- for (int i = 0; i < numDigestsTotal; i++)
- digests.Add(0);
+ digests.Defs[k] = true;
+ digests.Vals[k] = folders.FolderCRCs.Vals[i];
+ k++;
+ }
+ else for (CNum j = 0; j < numSubstreams; j++)
+ {
+ digests.Defs[k] = false;
+ digests.Vals[k] = 0;
+ k++;
}
- return;
}
- else
- SkipData();
- type = ReadID();
}
}
void CInArchive::ReadStreamsInfo(
const CObjectVector<CByteBuffer> *dataVector,
UInt64 &dataOffset,
- CRecordVector<UInt64> &packSizes,
- CBoolVector &packCRCsDefined,
- CRecordVector<UInt32> &packCRCs,
- CObjectVector<CFolder> &folders,
- CRecordVector<CNum> &numUnpackStreamsInFolders,
+ CFolders &folders,
CRecordVector<UInt64> &unpackSizes,
- CBoolVector &digestsDefined,
- CRecordVector<UInt32> &digests)
+ CUInt32DefVector &digests)
{
- for (;;)
+ UInt64 type = ReadID();
+
+ if (type == NID::kPackInfo)
{
- UInt64 type = ReadID();
- if (type > ((UInt32)1 << 30))
- ThrowIncorrect();
- switch((UInt32)type)
+ dataOffset = ReadNumber();
+ ReadPackInfo(folders);
+ type = ReadID();
+ }
+
+ if (type == NID::kUnpackInfo)
+ {
+ ReadUnpackInfo(dataVector, folders);
+ type = ReadID();
+ }
+
+ if (folders.NumFolders != 0 && !folders.PackPositions)
+ {
+ // if there are folders, we need PackPositions also
+ folders.PackPositions.Alloc(1);
+ folders.PackPositions[0] = 0;
+ }
+
+ if (type == NID::kSubStreamsInfo)
+ {
+ ReadSubStreamsInfo(folders, unpackSizes, digests);
+ type = ReadID();
+ }
+ else
+ {
+ folders.NumUnpackStreamsVector.Alloc(folders.NumFolders);
+ /* If digests.Defs.Size() == 0, it means that there are no crcs.
+ So we don't need to fill digests with values. */
+ // digests.Vals.ClearAndSetSize(folders.NumFolders);
+ // BoolVector_Fill_False(digests.Defs, folders.NumFolders);
+ for (CNum i = 0; i < folders.NumFolders; i++)
{
- case NID::kEnd:
- return;
- case NID::kPackInfo:
- {
- ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs);
- break;
- }
- case NID::kUnpackInfo:
- {
- ReadUnpackInfo(dataVector, folders);
- break;
- }
- case NID::kSubStreamsInfo:
- {
- ReadSubStreamsInfo(folders, numUnpackStreamsInFolders,
- unpackSizes, digestsDefined, digests);
- break;
- }
- default:
- ThrowIncorrect();
+ folders.NumUnpackStreamsVector[i] = 1;
+ unpackSizes.Add(folders.GetFolderUnpackSize(i));
+ // digests.Vals[i] = 0;
}
}
+
+ if (type != NID::kEnd)
+ ThrowIncorrect();
}
-void CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
+void CInArchive::ReadBoolVector(unsigned numItems, CBoolVector &v)
{
- v.Clear();
- v.Reserve(numItems);
+ v.ClearAndSetSize(numItems);
Byte b = 0;
Byte mask = 0;
- for (int i = 0; i < numItems; i++)
+ bool *p = &v[0];
+ for (unsigned i = 0; i < numItems; i++)
{
if (mask == 0)
{
b = ReadByte();
mask = 0x80;
}
- v.Add((b & mask) != 0);
+ p[i] = ((b & mask) != 0);
mask >>= 1;
}
}
-void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
+void CInArchive::ReadBoolVector2(unsigned numItems, CBoolVector &v)
{
Byte allAreDefined = ReadByte();
if (allAreDefined == 0)
@@ -747,27 +1010,30 @@ void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
ReadBoolVector(numItems, v);
return;
}
- v.Clear();
- v.Reserve(numItems);
- for (int i = 0; i < numItems; i++)
- v.Add(true);
+ v.ClearAndSetSize(numItems);
+ bool *p = &v[0];
+ for (unsigned i = 0; i < numItems; i++)
+ p[i] = true;
}
void CInArchive::ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
- CUInt64DefVector &v, int numFiles)
+ CUInt64DefVector &v, unsigned numItems)
{
- ReadBoolVector2(numFiles, v.Defined);
+ ReadBoolVector2(numItems, v.Defs);
CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector);
- v.Values.Reserve(numFiles);
+
+ v.Vals.ClearAndSetSize(numItems);
+ UInt64 *p = &v.Vals[0];
+ const bool *defs = &v.Defs[0];
- for (int i = 0; i < numFiles; i++)
+ for (unsigned i = 0; i < numItems; i++)
{
UInt64 t = 0;
- if (v.Defined[i])
+ if (defs[i])
t = ReadUInt64();
- v.Values.Add(t);
+ p[i] = t;
}
}
@@ -775,97 +1041,71 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 baseOffset,
UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS_DECL
)
{
- CRecordVector<UInt64> packSizes;
- CBoolVector packCRCsDefined;
- CRecordVector<UInt32> packCRCs;
- CObjectVector<CFolder> folders;
-
- CRecordVector<CNum> numUnpackStreamsInFolders;
+ CFolders folders;
CRecordVector<UInt64> unpackSizes;
- CBoolVector digestsDefined;
- CRecordVector<UInt32> digests;
+ CUInt32DefVector digests;
ReadStreamsInfo(NULL,
dataOffset,
- packSizes,
- packCRCsDefined,
- packCRCs,
folders,
- numUnpackStreamsInFolders,
unpackSizes,
- digestsDefined,
digests);
- // db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
-
- CNum packIndex = 0;
- CDecoder decoder(
- #ifdef _ST_MODE
- false
- #else
- true
- #endif
- );
- UInt64 dataStartPos = baseOffset + dataOffset;
- for (int i = 0; i < folders.Size(); i++)
+ CDecoder decoder(_useMixerMT);
+
+ for (CNum i = 0; i < folders.NumFolders; i++)
{
- const CFolder &folder = folders[i];
- dataVector.Add(CByteBuffer());
- CByteBuffer &data = dataVector.Back();
- UInt64 unpackSize64 = folder.GetUnpackSize();
+ CByteBuffer &data = dataVector.AddNew();
+ UInt64 unpackSize64 = folders.GetFolderUnpackSize(i);
size_t unpackSize = (size_t)unpackSize64;
if (unpackSize != unpackSize64)
ThrowUnsupported();
- data.SetCapacity(unpackSize);
+ data.Alloc(unpackSize);
CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->Init(data, unpackSize);
HRESULT result = decoder.Decode(
- EXTERNAL_CODECS_LOC_VARS
- _stream, dataStartPos,
- &packSizes[packIndex], folder, outStream, NULL
- #ifndef _NO_CRYPTO
- , getTextPassword, passwordIsDefined
- #endif
- #if !defined(_7ZIP_ST) && !defined(_SFX)
- , false, 1
- #endif
+ EXTERNAL_CODECS_LOC_VARS
+ _stream, baseOffset + dataOffset,
+ folders, i,
+ NULL, // *unpackSize
+
+ outStream,
+ NULL, // *compressProgress
+ NULL // **inStreamMainRes
+
+ _7Z_DECODER_CRYPRO_VARS
+ #if !defined(_7ZIP_ST) && !defined(_SFX)
+ , false // mtMode
+ , 1 // numThreads
+ #endif
);
RINOK(result);
- if (folder.UnpackCRCDefined)
- if (CrcCalc(data, unpackSize) != folder.UnpackCRC)
+ if (folders.FolderCRCs.ValidAndDefined(i))
+ if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
ThrowIncorrect();
- for (int j = 0; j < folder.PackStreams.Size(); j++)
- {
- UInt64 packSize = packSizes[packIndex++];
- dataStartPos += packSize;
- HeadersSize += packSize;
- }
}
+ HeadersSize += folders.PackPositions[folders.NumPackStreams];
return S_OK;
}
HRESULT CInArchive::ReadHeader(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &db
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ CDbEx &db
+ _7Z_DECODER_CRYPRO_VARS_DECL
)
{
UInt64 type = ReadID();
if (type == NID::kArchiveProperties)
{
- ReadArchiveProperties(db.ArchiveInfo);
+ ReadArchiveProperties(db.ArcInfo);
type = ReadID();
}
@@ -875,70 +1115,53 @@ HRESULT CInArchive::ReadHeader(
{
HRESULT result = ReadAndDecodePackedStreams(
EXTERNAL_CODECS_LOC_VARS
- db.ArchiveInfo.StartPositionAfterHeader,
- db.ArchiveInfo.DataStartPosition2,
+ db.ArcInfo.StartPositionAfterHeader,
+ db.ArcInfo.DataStartPosition2,
dataVector
- #ifndef _NO_CRYPTO
- , getTextPassword, passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS
);
RINOK(result);
- db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
+ db.ArcInfo.DataStartPosition2 += db.ArcInfo.StartPositionAfterHeader;
type = ReadID();
}
CRecordVector<UInt64> unpackSizes;
- CBoolVector digestsDefined;
- CRecordVector<UInt32> digests;
+ CUInt32DefVector digests;
if (type == NID::kMainStreamsInfo)
{
ReadStreamsInfo(&dataVector,
- db.ArchiveInfo.DataStartPosition,
- db.PackSizes,
- db.PackCRCsDefined,
- db.PackCRCs,
- db.Folders,
- db.NumUnpackStreamsVector,
+ db.ArcInfo.DataStartPosition,
+ (CFolders &)db,
unpackSizes,
- digestsDefined,
digests);
- db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader;
+ db.ArcInfo.DataStartPosition += db.ArcInfo.StartPositionAfterHeader;
type = ReadID();
}
- else
- {
- for (int i = 0; i < db.Folders.Size(); i++)
- {
- db.NumUnpackStreamsVector.Add(1);
- CFolder &folder = db.Folders[i];
- unpackSizes.Add(folder.GetUnpackSize());
- digestsDefined.Add(folder.UnpackCRCDefined);
- digests.Add(folder.UnpackCRC);
- }
- }
db.Files.Clear();
- if (type == NID::kEnd)
- return S_OK;
- if (type != NID::kFilesInfo)
- ThrowIncorrect();
+ if (type == NID::kFilesInfo)
+ {
CNum numFiles = ReadNum();
+ db.Files.ClearAndSetSize(numFiles);
+ CNum i;
+ /*
db.Files.Reserve(numFiles);
CNum i;
for (i = 0; i < numFiles; i++)
db.Files.Add(CFileItem());
+ */
- db.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
- if (!db.PackSizes.IsEmpty())
- db.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
- if (numFiles > 0 && !digests.IsEmpty())
- db.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
+ db.ArcInfo.FileInfoPopIDs.Add(NID::kSize);
+ // if (!db.PackSizes.IsEmpty())
+ db.ArcInfo.FileInfoPopIDs.Add(NID::kPackInfo);
+ if (numFiles > 0 && !digests.Defs.IsEmpty())
+ db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC);
CBoolVector emptyStreamVector;
- BoolVector_Fill_False(emptyStreamVector, (int)numFiles);
+ BoolVector_Fill_False(emptyStreamVector, (unsigned)numFiles);
CBoolVector emptyFileVector;
CBoolVector antiFileVector;
CNum numEmptyStreams = 0;
@@ -949,22 +1172,43 @@ HRESULT CInArchive::ReadHeader(
if (type == NID::kEnd)
break;
UInt64 size = ReadNumber();
- size_t ppp = _inByteBack->_pos;
+ if (size > _inByteBack->GetRem())
+ ThrowIncorrect();
+ CStreamSwitch switchProp;
+ switchProp.Set(this, _inByteBack->GetPtr(), (size_t)size, true);
bool addPropIdToList = true;
bool isKnownType = true;
if (type > ((UInt32)1 << 30))
isKnownType = false;
- else switch((UInt32)type)
+ else switch ((UInt32)type)
{
case NID::kName:
{
CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector);
- for (int i = 0; i < db.Files.Size(); i++)
- _inByteBack->ReadString(db.Files[i].Name);
+ size_t rem = _inByteBack->GetRem();
+ db.NamesBuf.Alloc(rem);
+ ReadBytes(db.NamesBuf, rem);
+ db.NameOffsets.Alloc(db.Files.Size() + 1);
+ size_t pos = 0;
+ unsigned i;
+ for (i = 0; i < db.Files.Size(); i++)
+ {
+ size_t curRem = (rem - pos) / 2;
+ const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos);
+ size_t j;
+ for (j = 0; j < curRem && buf[j] != 0; j++);
+ if (j == curRem)
+ ThrowEndOfData();
+ db.NameOffsets[i] = pos / 2;
+ pos += j * 2 + 2;
+ }
+ db.NameOffsets[i] = pos / 2;
+ if (pos != rem)
+ ThereIsHeaderError = true;
break;
}
- case NID::kWinAttributes:
+ case NID::kWinAttrib:
{
CBoolVector boolVector;
ReadBoolVector2(db.Files.Size(), boolVector);
@@ -979,9 +1223,40 @@ HRESULT CInArchive::ReadHeader(
}
break;
}
+ /*
+ case NID::kIsAux:
+ {
+ ReadBoolVector(db.Files.Size(), db.IsAux);
+ break;
+ }
+ case NID::kParent:
+ {
+ db.IsTree = true;
+ // CBoolVector boolVector;
+ // ReadBoolVector2(db.Files.Size(), boolVector);
+ // CStreamSwitch streamSwitch;
+ // streamSwitch.Set(this, &dataVector);
+ CBoolVector boolVector;
+ ReadBoolVector2(db.Files.Size(), boolVector);
+
+ db.ThereAreAltStreams = false;
+ for (i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = db.Files[i];
+ // file.Parent = -1;
+ // if (boolVector[i])
+ file.Parent = (int)ReadUInt32();
+ file.IsAltStream = !boolVector[i];
+ if (file.IsAltStream)
+ db.ThereAreAltStreams = true;
+ }
+ break;
+ }
+ */
case NID::kEmptyStream:
{
ReadBoolVector(numFiles, emptyStreamVector);
+ numEmptyStreams = 0;
for (i = 0; i < (CNum)emptyStreamVector.Size(); i++)
if (emptyStreamVector[i])
numEmptyStreams++;
@@ -993,34 +1268,86 @@ HRESULT CInArchive::ReadHeader(
}
case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break;
case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break;
- case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (int)numFiles); break;
- case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (int)numFiles); break;
- case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (int)numFiles); break;
- case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (int)numFiles); break;
+ case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (unsigned)numFiles); break;
+ case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (unsigned)numFiles); break;
+ case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (unsigned)numFiles); break;
+ case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (unsigned)numFiles); break;
case NID::kDummy:
{
for (UInt64 j = 0; j < size; j++)
if (ReadByte() != 0)
- ThrowIncorrect();
+ ThereIsHeaderError = true;
addPropIdToList = false;
break;
}
+ /*
+ case NID::kNtSecure:
+ {
+ try
+ {
+ {
+ CStreamSwitch streamSwitch;
+ streamSwitch.Set(this, &dataVector);
+ UInt32 numDescriptors = ReadUInt32();
+ size_t offset = 0;
+ db.SecureOffsets.Clear();
+ for (i = 0; i < numDescriptors; i++)
+ {
+ UInt32 size = ReadUInt32();
+ db.SecureOffsets.Add(offset);
+ offset += size;
+ }
+ // ThrowIncorrect();;
+ db.SecureOffsets.Add(offset);
+ db.SecureBuf.SetCapacity(offset);
+ for (i = 0; i < numDescriptors; i++)
+ {
+ offset = db.SecureOffsets[i];
+ ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset);
+ }
+ db.SecureIDs.Clear();
+ for (unsigned i = 0; i < db.Files.Size(); i++)
+ {
+ db.SecureIDs.Add(ReadNum());
+ // db.SecureIDs.Add(ReadUInt32());
+ }
+ // ReadUInt32();
+ if (_inByteBack->GetRem() != 0)
+ ThrowIncorrect();;
+ }
+ }
+ catch(CInArchiveException &)
+ {
+ ThereIsHeaderError = true;
+ addPropIdToList = isKnownType = false;
+ db.ClearSecure();
+ }
+ break;
+ }
+ */
default:
addPropIdToList = isKnownType = false;
}
if (isKnownType)
{
- if(addPropIdToList)
- db.ArchiveInfo.FileInfoPopIDs.Add(type);
+ if (addPropIdToList)
+ db.ArcInfo.FileInfoPopIDs.Add(type);
}
else
- SkipData(size);
- bool checkRecordsSize = (db.ArchiveInfo.Version.Major > 0 ||
- db.ArchiveInfo.Version.Minor > 2);
- if (checkRecordsSize && _inByteBack->_pos - ppp != size)
+ {
+ db.UnsupportedFeatureWarning = true;
+ _inByteBack->SkipRem();
+ }
+ // SkipData worked incorrectly in some versions before v4.59 (7zVer <= 0.02)
+ if (_inByteBack->GetRem() != 0)
ThrowIncorrect();
}
+ type = ReadID(); // Read (NID::kEnd) end of headers
+
+ if (numFiles - numEmptyStreams != unpackSizes.Size())
+ ThrowUnsupported();
+
CNum emptyFileIndex = 0;
CNum sizeIndex = 0;
@@ -1028,19 +1355,21 @@ HRESULT CInArchive::ReadHeader(
for (i = 0; i < numEmptyStreams; i++)
if (antiFileVector[i])
numAntiItems++;
-
+
for (i = 0; i < numFiles; i++)
{
CFileItem &file = db.Files[i];
bool isAnti;
file.HasStream = !emptyStreamVector[i];
+ file.Crc = 0;
if (file.HasStream)
{
file.IsDir = false;
isAnti = false;
file.Size = unpackSizes[sizeIndex];
- file.Crc = digests[sizeIndex];
- file.CrcDefined = digestsDefined[sizeIndex];
+ file.CrcDefined = digests.ValidAndDefined(sizeIndex);
+ if (file.CrcDefined)
+ file.Crc = digests.Vals[sizeIndex];
sizeIndex++;
}
else
@@ -1054,158 +1383,182 @@ HRESULT CInArchive::ReadHeader(
if (numAntiItems != 0)
db.IsAnti.Add(isAnti);
}
- return S_OK;
-}
-
-
-void CArchiveDatabaseEx::FillFolderStartPackStream()
-{
- FolderStartPackStreamIndex.Clear();
- FolderStartPackStreamIndex.Reserve(Folders.Size());
- CNum startPos = 0;
- for (int i = 0; i < Folders.Size(); i++)
- {
- FolderStartPackStreamIndex.Add(startPos);
- startPos += (CNum)Folders[i].PackStreams.Size();
- }
-}
-
-void CArchiveDatabaseEx::FillStartPos()
-{
- PackStreamStartPositions.Clear();
- PackStreamStartPositions.Reserve(PackSizes.Size());
- UInt64 startPos = 0;
- for (int i = 0; i < PackSizes.Size(); i++)
- {
- PackStreamStartPositions.Add(startPos);
- startPos += PackSizes[i];
}
+ db.FillLinks();
+ /*
+ if (type != NID::kEnd)
+ ThrowIncorrect();
+ if (_inByteBack->GetRem() != 0)
+ ThrowIncorrect();
+ */
+ return S_OK;
}
-void CArchiveDatabaseEx::FillFolderStartFileIndex()
+void CDbEx::FillLinks()
{
- FolderStartFileIndex.Clear();
- FolderStartFileIndex.Reserve(Folders.Size());
- FileIndexToFolderIndexMap.Clear();
- FileIndexToFolderIndexMap.Reserve(Files.Size());
+ FolderStartFileIndex.Alloc(NumFolders);
+ FileIndexToFolderIndexMap.Alloc(Files.Size());
- int folderIndex = 0;
+ CNum folderIndex = 0;
CNum indexInFolder = 0;
- for (int i = 0; i < Files.Size(); i++)
+ unsigned i;
+
+ for (i = 0; i < Files.Size(); i++)
{
- const CFileItem &file = Files[i];
- bool emptyStream = !file.HasStream;
- if (emptyStream && indexInFolder == 0)
- {
- FileIndexToFolderIndexMap.Add(kNumNoIndex);
- continue;
- }
+ bool emptyStream = !Files[i].HasStream;
if (indexInFolder == 0)
{
+ if (emptyStream)
+ {
+ FileIndexToFolderIndexMap[i] = kNumNoIndex;
+ continue;
+ }
// v3.13 incorrectly worked with empty folders
- // v4.07: Loop for skipping empty folders
+ // v4.07: we skip empty folders
for (;;)
{
- if (folderIndex >= Folders.Size())
+ if (folderIndex >= NumFolders)
ThrowIncorrect();
- FolderStartFileIndex.Add(i); // check it
+ FolderStartFileIndex[folderIndex] = i;
if (NumUnpackStreamsVector[folderIndex] != 0)
break;
folderIndex++;
}
}
- FileIndexToFolderIndexMap.Add(folderIndex);
+ FileIndexToFolderIndexMap[i] = folderIndex;
if (emptyStream)
continue;
- indexInFolder++;
- if (indexInFolder >= NumUnpackStreamsVector[folderIndex])
+ if (++indexInFolder >= NumUnpackStreamsVector[folderIndex])
{
folderIndex++;
indexInFolder = 0;
}
}
+
+ if (indexInFolder != 0)
+ folderIndex++;
+ /*
+ if (indexInFolder != 0)
+ ThrowIncorrect();
+ */
+
+ for (;;)
+ {
+ if (folderIndex >= NumFolders)
+ return;
+ FolderStartFileIndex[folderIndex] = i;
+ /*
+ if (NumUnpackStreamsVector[folderIndex] != 0)
+ ThrowIncorrect();;
+ */
+ folderIndex++;
+ }
}
HRESULT CInArchive::ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &db
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ CDbEx &db
+ _7Z_DECODER_CRYPRO_VARS_DECL
)
{
db.Clear();
- db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
+ db.ArcInfo.StartPosition = _arhiveBeginStreamPosition;
- db.ArchiveInfo.Version.Major = _header[6];
- db.ArchiveInfo.Version.Minor = _header[7];
+ db.ArcInfo.Version.Major = _header[6];
+ db.ArcInfo.Version.Minor = _header[7];
- if (db.ArchiveInfo.Version.Major != kMajorVersion)
- ThrowUnsupportedVersion();
+ if (db.ArcInfo.Version.Major != kMajorVersion)
+ {
+ // db.UnsupportedVersion = true;
+ return S_FALSE;
+ }
- UInt32 crcFromArchive = Get32(_header + 8);
- UInt64 nextHeaderOffset = Get64(_header + 0xC);
- UInt64 nextHeaderSize = Get64(_header + 0x14);
- UInt32 nextHeaderCRC = Get32(_header + 0x1C);
- UInt32 crc = CrcCalc(_header + 0xC, 20);
+ UInt64 nextHeaderOffset = Get64(_header + 12);
+ UInt64 nextHeaderSize = Get64(_header + 20);
+ UInt32 nextHeaderCRC = Get32(_header + 28);
#ifdef FORMAT_7Z_RECOVERY
- if (crcFromArchive == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0)
+ UInt32 crcFromArc = Get32(_header + 8);
+ if (crcFromArc == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0)
{
- UInt64 cur, cur2;
+ UInt64 cur, fileSize;
RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur));
- const int kCheckSize = 500;
+ const unsigned kCheckSize = 512;
Byte buf[kCheckSize];
- RINOK(_stream->Seek(0, STREAM_SEEK_END, &cur2));
- int checkSize = kCheckSize;
- if (cur2 - cur < kCheckSize)
- checkSize = (int)(cur2 - cur);
- RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2));
-
+ RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize));
+ UInt64 rem = fileSize - cur;
+ unsigned checkSize = kCheckSize;
+ if (rem < kCheckSize)
+ checkSize = (unsigned)(rem);
+ if (checkSize < 3)
+ return S_FALSE;
+ RINOK(_stream->Seek(fileSize - checkSize, STREAM_SEEK_SET, NULL));
RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize));
- int i;
- for (i = (int)checkSize - 2; i >= 0; i--)
- if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04)
- break;
- if (i < 0)
+ if (buf[checkSize - 1] != 0)
return S_FALSE;
+
+ unsigned i;
+ for (i = checkSize - 2;; i--)
+ {
+ if (buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo ||
+ buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo)
+ break;
+ if (i == 0)
+ return S_FALSE;
+ }
nextHeaderSize = checkSize - i;
- nextHeaderOffset = cur2 - cur + i;
+ nextHeaderOffset = rem - nextHeaderSize;
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
+ db.StartHeaderWasRecovered = true;
}
else
#endif
{
- if (crc != crcFromArchive)
- ThrowIncorrect();
+ // Crc was tested already at signature check
+ // if (CrcCalc(_header + 12, 20) != crcFromArchive) ThrowIncorrect();
}
- db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
+ db.ArcInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
+ db.PhySize = kHeaderSize;
+ db.IsArc = false;
+ if ((Int64)nextHeaderOffset < 0 ||
+ nextHeaderSize > ((UInt64)1 << 62))
+ return S_FALSE;
if (nextHeaderSize == 0)
+ {
+ if (nextHeaderOffset != 0)
+ return S_FALSE;
+ db.IsArc = true;
return S_OK;
-
- if (nextHeaderSize > (UInt64)(UInt32)0xFFFFFFFF)
- return S_FALSE;
-
- if ((Int64)nextHeaderOffset < 0)
- return S_FALSE;
-
- if (db.ArchiveInfo.StartPositionAfterHeader + nextHeaderOffset > _fileEndPosition)
+ }
+
+ if (!db.StartHeaderWasRecovered)
+ db.IsArc = true;
+
+ HeadersSize += kHeaderSize + nextHeaderSize;
+ db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;
+ if (_fileEndPosition - db.ArcInfo.StartPositionAfterHeader < nextHeaderOffset + nextHeaderSize)
+ {
+ db.UnexpectedEnd = true;
return S_FALSE;
+ }
RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
- CByteBuffer buffer2;
- buffer2.SetCapacity((size_t)nextHeaderSize);
+ size_t nextHeaderSize_t = (size_t)nextHeaderSize;
+ if (nextHeaderSize_t != nextHeaderSize)
+ return E_OUTOFMEMORY;
+ CByteBuffer buffer2(nextHeaderSize_t);
- RINOK(ReadStream_FALSE(_stream, buffer2, (size_t)nextHeaderSize));
- HeadersSize += kHeaderSize + nextHeaderSize;
- db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;
+ RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t));
- if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC)
+ if (CrcCalc(buffer2, nextHeaderSize_t) != nextHeaderCRC)
ThrowIncorrect();
+
+ if (!db.StartHeaderWasRecovered)
+ db.PhySizeWasConfirmed = true;
CStreamSwitch streamSwitch;
streamSwitch.Set(this, buffer2);
@@ -1219,12 +1572,10 @@ HRESULT CInArchive::ReadDatabase2(
ThrowIncorrect();
HRESULT result = ReadAndDecodePackedStreams(
EXTERNAL_CODECS_LOC_VARS
- db.ArchiveInfo.StartPositionAfterHeader,
- db.ArchiveInfo.DataStartPosition2,
+ db.ArcInfo.StartPositionAfterHeader,
+ db.ArcInfo.DataStartPosition2,
dataVector
- #ifndef _NO_CRYPTO
- , getTextPassword, passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS
);
RINOK(result);
if (dataVector.Size() == 0)
@@ -1237,35 +1588,45 @@ HRESULT CInArchive::ReadDatabase2(
ThrowIncorrect();
}
+ db.IsArc = true;
+
db.HeadersSize = HeadersSize;
return ReadHeader(
EXTERNAL_CODECS_LOC_VARS
db
- #ifndef _NO_CRYPTO
- , getTextPassword, passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS
);
}
HRESULT CInArchive::ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &db
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ CDbEx &db
+ _7Z_DECODER_CRYPRO_VARS_DECL
)
{
try
{
- return ReadDatabase2(
+ HRESULT res = ReadDatabase2(
EXTERNAL_CODECS_LOC_VARS db
- #ifndef _NO_CRYPTO
- , getTextPassword, passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS
);
+ if (ThereIsHeaderError)
+ db.ThereIsHeaderError = true;
+ if (res == E_NOTIMPL)
+ ThrowUnsupported();
+ return res;
+ }
+ catch(CUnsupportedFeatureException &)
+ {
+ db.UnsupportedFeatureError = true;
+ return S_FALSE;
+ }
+ catch(CInArchiveException &)
+ {
+ db.ThereIsHeaderError = true;
+ return S_FALSE;
}
- catch(CInArchiveException &) { return S_FALSE; }
}
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h
index 4305a8c5252..3592e99b530 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h
@@ -5,6 +5,8 @@
#include "../../../Common/MyCom.h"
+#include "../../../Windows/PropVariant.h"
+
#include "../../IPassword.h"
#include "../../IStream.h"
@@ -15,7 +17,161 @@
namespace NArchive {
namespace N7z {
+
+/*
+ We don't need to init isEncrypted and passwordIsDefined
+ We must upgrade them only */
+
+#ifdef _NO_CRYPTO
+#define _7Z_DECODER_CRYPRO_VARS_DECL
+#define _7Z_DECODER_CRYPRO_VARS
+#else
+#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password
+#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password
+#endif
+
+struct CParsedMethods
+{
+ Byte Lzma2Prop;
+ UInt32 LzmaDic;
+ CRecordVector<UInt64> IDs;
+
+ CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {}
+};
+
+struct CFolderEx: public CFolder
+{
+ unsigned UnpackCoder;
+};
+
+struct CFolders
+{
+ CNum NumPackStreams;
+ CNum NumFolders;
+
+ CObjArray<UInt64> PackPositions; // NumPackStreams + 1
+ // CUInt32DefVector PackCRCs; // we don't use PackCRCs now
+
+ CUInt32DefVector FolderCRCs; // NumFolders
+ CObjArray<CNum> NumUnpackStreamsVector; // NumFolders
+
+ CObjArray<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders
+ CObjArray<CNum> FoToCoderUnpackSizes; // NumFolders + 1
+ CObjArray<CNum> FoStartPackStreamIndex; // NumFolders + 1
+ CObjArray<Byte> FoToMainUnpackSizeIndex; // NumFolders
+
+ CObjArray<size_t> FoCodersDataOffset; // NumFolders + 1
+ CByteBuffer CodersData;
+
+ CParsedMethods ParsedMethods;
+
+ void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const;
+ void ParseFolderEx(unsigned folderIndex, CFolderEx &folder) const
+ {
+ ParseFolderInfo(folderIndex, folder);
+ folder.UnpackCoder = FoToMainUnpackSizeIndex[folderIndex];
+ }
+ unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const
+ {
+ return (unsigned)(FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]);
+ }
+
+ UInt64 GetFolderUnpackSize(unsigned folderIndex) const
+ {
+ return CoderUnpackSizes[FoToCoderUnpackSizes[folderIndex] + FoToMainUnpackSizeIndex[folderIndex]];
+ }
+
+ UInt64 GetStreamPackSize(unsigned index) const
+ {
+ return PackPositions[index + 1] - PackPositions[index];
+ }
+
+ CFolders(): NumPackStreams(0), NumFolders(0) {}
+
+ void Clear()
+ {
+ NumPackStreams = 0;
+ PackPositions.Free();
+ // PackCRCs.Clear();
+
+ NumFolders = 0;
+ FolderCRCs.Clear();
+ NumUnpackStreamsVector.Free();
+ CoderUnpackSizes.Free();
+ FoToCoderUnpackSizes.Free();
+ FoStartPackStreamIndex.Free();
+ FoToMainUnpackSizeIndex.Free();
+ FoCodersDataOffset.Free();
+ CodersData.Free();
+ }
+};
+
+struct CDatabase: public CFolders
+{
+ CRecordVector<CFileItem> Files;
+
+ CUInt64DefVector CTime;
+ CUInt64DefVector ATime;
+ CUInt64DefVector MTime;
+ CUInt64DefVector StartPos;
+ CBoolVector IsAnti;
+ /*
+ CBoolVector IsAux;
+ CByteBuffer SecureBuf;
+ CRecordVector<UInt32> SecureIDs;
+ */
+
+ CByteBuffer NamesBuf;
+ CObjArray<size_t> NameOffsets; // numFiles + 1, offsets of utf-16 symbols
+
+ /*
+ void ClearSecure()
+ {
+ SecureBuf.Free();
+ SecureIDs.Clear();
+ }
+ */
+
+ void Clear()
+ {
+ CFolders::Clear();
+ // ClearSecure();
+
+ NamesBuf.Free();
+ NameOffsets.Free();
+
+ Files.Clear();
+ CTime.Clear();
+ ATime.Clear();
+ MTime.Clear();
+ StartPos.Clear();
+ IsAnti.Clear();
+ // IsAux.Clear();
+ }
+
+ bool IsSolid() const
+ {
+ for (CNum i = 0; i < NumFolders; i++)
+ if (NumUnpackStreamsVector[i] > 1)
+ return true;
+ return false;
+ }
+ bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
+ // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
+
+ /*
+ const void* GetName(unsigned index) const
+ {
+ if (!NameOffsets || !NamesBuf)
+ return NULL;
+ return (void *)((const Byte *)NamesBuf + NameOffsets[index] * 2);
+ };
+ */
+ void GetPath(unsigned index, UString &path) const;
+ HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw();
+};
+
struct CInArchiveInfo
{
CArchiveVersion Version;
@@ -24,66 +180,100 @@ struct CInArchiveInfo
UInt64 DataStartPosition;
UInt64 DataStartPosition2;
CRecordVector<UInt64> FileInfoPopIDs;
+
void Clear()
{
+ StartPosition = 0;
+ StartPositionAfterHeader = 0;
+ DataStartPosition = 0;
+ DataStartPosition2 = 0;
FileInfoPopIDs.Clear();
}
};
-struct CArchiveDatabaseEx: public CArchiveDatabase
+struct CDbEx: public CDatabase
{
- CInArchiveInfo ArchiveInfo;
- CRecordVector<UInt64> PackStreamStartPositions;
- CRecordVector<CNum> FolderStartPackStreamIndex;
- CRecordVector<CNum> FolderStartFileIndex;
- CRecordVector<CNum> FileIndexToFolderIndexMap;
+ CInArchiveInfo ArcInfo;
+
+ CObjArray<CNum> FolderStartFileIndex;
+ CObjArray<CNum> FileIndexToFolderIndexMap;
UInt64 HeadersSize;
UInt64 PhySize;
+ /*
+ CRecordVector<size_t> SecureOffsets;
+ bool IsTree;
+ bool ThereAreAltStreams;
+ */
+
+ bool IsArc;
+ bool PhySizeWasConfirmed;
+
+ bool ThereIsHeaderError;
+ bool UnexpectedEnd;
+ // bool UnsupportedVersion;
+
+ bool StartHeaderWasRecovered;
+ bool UnsupportedFeatureWarning;
+ bool UnsupportedFeatureError;
+
+ /*
+ void ClearSecureEx()
+ {
+ ClearSecure();
+ SecureOffsets.Clear();
+ }
+ */
+
void Clear()
{
- CArchiveDatabase::Clear();
- ArchiveInfo.Clear();
- PackStreamStartPositions.Clear();
- FolderStartPackStreamIndex.Clear();
- FolderStartFileIndex.Clear();
- FileIndexToFolderIndexMap.Clear();
+ IsArc = false;
+ PhySizeWasConfirmed = false;
+
+ ThereIsHeaderError = false;
+ UnexpectedEnd = false;
+ // UnsupportedVersion = false;
+
+ StartHeaderWasRecovered = false;
+ UnsupportedFeatureError = false;
+ UnsupportedFeatureWarning = false;
+
+ /*
+ IsTree = false;
+ ThereAreAltStreams = false;
+ */
+
+ CDatabase::Clear();
+
+ // SecureOffsets.Clear();
+ ArcInfo.Clear();
+ FolderStartFileIndex.Free();
+ FileIndexToFolderIndexMap.Free();
HeadersSize = 0;
PhySize = 0;
}
- void FillFolderStartPackStream();
- void FillStartPos();
- void FillFolderStartFileIndex();
-
- void Fill()
- {
- FillFolderStartPackStream();
- FillStartPos();
- FillFolderStartFileIndex();
- }
+ void FillLinks();
- UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
+ UInt64 GetFolderStreamPos(CNum folderIndex, unsigned indexInFolder) const
{
- return ArchiveInfo.DataStartPosition +
- PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder];
+ return ArcInfo.DataStartPosition +
+ PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder];
}
- UInt64 GetFolderFullPackSize(int folderIndex) const
+ UInt64 GetFolderFullPackSize(CNum folderIndex) const
{
- CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
- const CFolder &folder = Folders[folderIndex];
- UInt64 size = 0;
- for (int i = 0; i < folder.PackStreams.Size(); i++)
- size += PackSizes[packStreamIndex + i];
- return size;
+ return
+ PackPositions[FoStartPackStreamIndex[folderIndex + 1]] -
+ PackPositions[FoStartPackStreamIndex[folderIndex]];
}
- UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+ UInt64 GetFolderPackStreamSize(CNum folderIndex, unsigned streamIndex) const
{
- return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+ size_t i = FoStartPackStreamIndex[folderIndex] + streamIndex;
+ return PackPositions[i + 1] - PackPositions[i];
}
UInt64 GetFilePackSize(CNum fileIndex) const
@@ -96,12 +286,17 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
}
};
-class CInByte2
+const unsigned kNumBufLevelsMax = 4;
+
+struct CInByte2
{
const Byte *_buffer;
- size_t _size;
public:
+ size_t _size;
size_t _pos;
+
+ size_t GetRem() const { return _size - _pos; }
+ const Byte *GetPtr() const { return _buffer + _pos; }
void Init(const Byte *buffer, size_t size)
{
_buffer = buffer;
@@ -110,13 +305,17 @@ public:
}
Byte ReadByte();
void ReadBytes(Byte *data, size_t size);
+ void SkipDataNoCheck(UInt64 size) { _pos += (size_t)size; }
void SkipData(UInt64 size);
+
void SkipData();
+ void SkipRem() { _pos = _size; }
UInt64 ReadNumber();
CNum ReadNum();
UInt32 ReadUInt32();
UInt64 ReadUInt64();
- void ReadString(UString &s);
+
+ void ParseFolder(CFolder &folder);
};
class CStreamSwitch;
@@ -129,8 +328,11 @@ class CInArchive
CMyComPtr<IInStream> _stream;
- CObjectVector<CInByte2> _inByteVector;
+ unsigned _numInByteBufs;
+ CInByte2 _inByteVector[kNumBufLevelsMax];
+
CInByte2 *_inByteBack;
+ bool ThereIsHeaderError;
UInt64 _arhiveBeginStreamPosition;
UInt64 _fileEndPosition;
@@ -139,21 +341,21 @@ class CInArchive
UInt64 HeadersSize;
- void AddByteStream(const Byte *buffer, size_t size)
- {
- _inByteVector.Add(CInByte2());
- _inByteBack = &_inByteVector.Back();
- _inByteBack->Init(buffer, size);
- }
+ bool _useMixerMT;
+
+ void AddByteStream(const Byte *buffer, size_t size);
- void DeleteByteStream()
+ void DeleteByteStream(bool needUpdatePos)
{
- _inByteVector.DeleteBack();
- if (!_inByteVector.IsEmpty())
- _inByteBack = &_inByteVector.Back();
+ _numInByteBufs--;
+ if (_numInByteBufs > 0)
+ {
+ _inByteBack = &_inByteVector[_numInByteBufs - 1];
+ if (needUpdatePos)
+ _inByteBack->_pos += _inByteVector[_numInByteBufs]._pos;
+ }
}
-private:
HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
@@ -165,79 +367,62 @@ private:
UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); }
void SkipData(UInt64 size) { _inByteBack->SkipData(size); }
void SkipData() { _inByteBack->SkipData(); }
- void WaitAttribute(UInt64 attribute);
+ void WaitId(UInt64 id);
void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
- void GetNextFolderItem(CFolder &itemInfo);
- void ReadHashDigests(int numItems,
- CBoolVector &digestsDefined, CRecordVector<UInt32> &digests);
+ void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs);
- void ReadPackInfo(
- UInt64 &dataOffset,
- CRecordVector<UInt64> &packSizes,
- CBoolVector &packCRCsDefined,
- CRecordVector<UInt32> &packCRCs);
+ void ReadPackInfo(CFolders &f);
void ReadUnpackInfo(
const CObjectVector<CByteBuffer> *dataVector,
- CObjectVector<CFolder> &folders);
+ CFolders &folders);
void ReadSubStreamsInfo(
- const CObjectVector<CFolder> &folders,
- CRecordVector<CNum> &numUnpackStreamsInFolders,
+ CFolders &folders,
CRecordVector<UInt64> &unpackSizes,
- CBoolVector &digestsDefined,
- CRecordVector<UInt32> &digests);
+ CUInt32DefVector &digests);
void ReadStreamsInfo(
const CObjectVector<CByteBuffer> *dataVector,
UInt64 &dataOffset,
- CRecordVector<UInt64> &packSizes,
- CBoolVector &packCRCsDefined,
- CRecordVector<UInt32> &packCRCs,
- CObjectVector<CFolder> &folders,
- CRecordVector<CNum> &numUnpackStreamsInFolders,
+ CFolders &folders,
CRecordVector<UInt64> &unpackSizes,
- CBoolVector &digestsDefined,
- CRecordVector<UInt32> &digests);
+ CUInt32DefVector &digests);
-
- void ReadBoolVector(int numItems, CBoolVector &v);
- void ReadBoolVector2(int numItems, CBoolVector &v);
+ void ReadBoolVector(unsigned numItems, CBoolVector &v);
+ void ReadBoolVector2(unsigned numItems, CBoolVector &v);
void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
- CUInt64DefVector &v, int numFiles);
+ CUInt64DefVector &v, unsigned numItems);
HRESULT ReadAndDecodePackedStreams(
DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 baseOffset, UInt64 &dataOffset,
CObjectVector<CByteBuffer> &dataVector
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS_DECL
);
HRESULT ReadHeader(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &db
- #ifndef _NO_CRYPTO
- ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ CDbEx &db
+ _7Z_DECODER_CRYPRO_VARS_DECL
);
HRESULT ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &db
- #ifndef _NO_CRYPTO
- ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ CDbEx &db
+ _7Z_DECODER_CRYPRO_VARS_DECL
);
public:
+ CInArchive(bool useMixerMT):
+ _numInByteBufs(0),
+ _useMixerMT(useMixerMT)
+ {}
+
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
void Close();
HRESULT ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &db
- #ifndef _NO_CRYPTO
- ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ CDbEx &db
+ _7Z_DECODER_CRYPRO_VARS_DECL
);
};
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h
index 34f10775cbf..5e2b58f2ef4 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h
@@ -3,7 +3,7 @@
#ifndef __7Z_ITEM_H
#define __7Z_ITEM_H
-#include "../../../Common/Buffer.h"
+#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyString.h"
#include "../../Common/MethodId.h"
@@ -13,8 +13,6 @@
namespace NArchive {
namespace N7z {
-const UInt64 k_AES = 0x06F10701;
-
typedef UInt32 CNum;
const CNum kNumMax = 0x7FFFFFFF;
const CNum kNumNoIndex = 0xFFFFFFFF;
@@ -23,120 +21,129 @@ struct CCoderInfo
{
CMethodId MethodID;
CByteBuffer Props;
- CNum NumInStreams;
- CNum NumOutStreams;
- bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
+ UInt32 NumStreams;
+
+ bool IsSimpleCoder() const { return NumStreams == 1; }
};
-struct CBindPair
+struct CBond
{
- CNum InIndex;
- CNum OutIndex;
+ UInt32 PackIndex;
+ UInt32 UnpackIndex;
};
struct CFolder
{
- CObjectVector<CCoderInfo> Coders;
- CRecordVector<CBindPair> BindPairs;
- CRecordVector<CNum> PackStreams;
- CRecordVector<UInt64> UnpackSizes;
- UInt32 UnpackCRC;
- bool UnpackCRCDefined;
+ CLASS_NO_COPY(CFolder)
+public:
+ CObjArray2<CCoderInfo> Coders;
+ CObjArray2<CBond> Bonds;
+ CObjArray2<UInt32> PackStreams;
- CFolder(): UnpackCRCDefined(false) {}
+ CFolder() {}
- UInt64 GetUnpackSize() const // test it
- {
- if (UnpackSizes.IsEmpty())
- return 0;
- for (int i = UnpackSizes.Size() - 1; i >= 0; i--)
- if (FindBindPairForOutStream(i) < 0)
- return UnpackSizes[i];
- throw 1;
- }
+ bool IsDecodingSupported() const { return Coders.Size() <= 32; }
- CNum GetNumOutStreams() const
+ int Find_in_PackStreams(UInt32 packStream) const
{
- CNum result = 0;
- for (int i = 0; i < Coders.Size(); i++)
- result += Coders[i].NumOutStreams;
- return result;
+ FOR_VECTOR(i, PackStreams)
+ if (PackStreams[i] == packStream)
+ return i;
+ return -1;
}
- int FindBindPairForInStream(CNum inStreamIndex) const
+ int FindBond_for_PackStream(UInt32 packStream) const
{
- for(int i = 0; i < BindPairs.Size(); i++)
- if (BindPairs[i].InIndex == inStreamIndex)
+ FOR_VECTOR(i, Bonds)
+ if (Bonds[i].PackIndex == packStream)
return i;
return -1;
}
- int FindBindPairForOutStream(CNum outStreamIndex) const
+
+ /*
+ int FindBond_for_UnpackStream(UInt32 unpackStream) const
{
- for(int i = 0; i < BindPairs.Size(); i++)
- if (BindPairs[i].OutIndex == outStreamIndex)
+ FOR_VECTOR(i, Bonds)
+ if (Bonds[i].UnpackIndex == unpackStream)
return i;
return -1;
}
- int FindPackStreamArrayIndex(CNum inStreamIndex) const
+
+ int FindOutCoder() const
{
- for(int i = 0; i < PackStreams.Size(); i++)
- if (PackStreams[i] == inStreamIndex)
+ for (int i = (int)Coders.Size() - 1; i >= 0; i--)
+ if (FindBond_for_UnpackStream(i) < 0)
return i;
return -1;
}
+ */
bool IsEncrypted() const
{
- for (int i = Coders.Size() - 1; i >= 0; i--)
+ FOR_VECTOR(i, Coders)
if (Coders[i].MethodID == k_AES)
return true;
return false;
}
+};
+
+struct CUInt32DefVector
+{
+ CBoolVector Defs;
+ CRecordVector<UInt32> Vals;
+
+ void ClearAndSetSize(unsigned newSize)
+ {
+ Defs.ClearAndSetSize(newSize);
+ Vals.ClearAndSetSize(newSize);
+ }
- bool CheckStructure() const;
+ void Clear()
+ {
+ Defs.Clear();
+ Vals.Clear();
+ }
+
+ void ReserveDown()
+ {
+ Defs.ReserveDown();
+ Vals.ReserveDown();
+ }
+
+ bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; }
};
struct CUInt64DefVector
{
- CRecordVector<UInt64> Values;
- CRecordVector<bool> Defined;
+ CBoolVector Defs;
+ CRecordVector<UInt64> Vals;
void Clear()
{
- Values.Clear();
- Defined.Clear();
+ Defs.Clear();
+ Vals.Clear();
}
void ReserveDown()
{
- Values.ReserveDown();
- Values.ReserveDown();
+ Defs.ReserveDown();
+ Vals.ReserveDown();
}
- bool GetItem(int index, UInt64 &value) const
+ bool GetItem(unsigned index, UInt64 &value) const
{
- if (index < Defined.Size() && Defined[index])
+ if (index < Defs.Size() && Defs[index])
{
- value = Values[index];
+ value = Vals[index];
return true;
}
value = 0;
return false;
}
- void SetItem(int index, bool defined, UInt64 value)
- {
- while (index >= Defined.Size())
- Defined.Add(false);
- Defined[index] = defined;
- if (!defined)
- return;
- while (index >= Values.Size())
- Values.Add(0);
- Values[index] = value;
- }
+ void SetItem(unsigned index, bool defined, UInt64 value);
- bool CheckSize(int size) const { return Defined.Size() == size || Defined.Size() == 0; }
+ bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
};
struct CFileItem
@@ -144,8 +151,10 @@ struct CFileItem
UInt64 Size;
UInt32 Attrib;
UInt32 Crc;
- UString Name;
-
+ /*
+ int Parent;
+ bool IsAltStream;
+ */
bool HasStream; // Test it !!! it means that there is
// stream in some folder. It can be empty stream
bool IsDir;
@@ -153,6 +162,10 @@ struct CFileItem
bool AttribDefined;
CFileItem():
+ /*
+ Parent(-1),
+ IsAltStream(false),
+ */
HasStream(true),
IsDir(false),
CrcDefined(false),
@@ -165,104 +178,6 @@ struct CFileItem
}
};
-struct CFileItem2
-{
- UInt64 CTime;
- UInt64 ATime;
- UInt64 MTime;
- UInt64 StartPos;
- bool CTimeDefined;
- bool ATimeDefined;
- bool MTimeDefined;
- bool StartPosDefined;
- bool IsAnti;
-};
-
-struct CArchiveDatabase
-{
- CRecordVector<UInt64> PackSizes;
- CRecordVector<bool> PackCRCsDefined;
- CRecordVector<UInt32> PackCRCs;
- CObjectVector<CFolder> Folders;
- CRecordVector<CNum> NumUnpackStreamsVector;
- CObjectVector<CFileItem> Files;
-
- CUInt64DefVector CTime;
- CUInt64DefVector ATime;
- CUInt64DefVector MTime;
- CUInt64DefVector StartPos;
- CRecordVector<bool> IsAnti;
-
- void Clear()
- {
- PackSizes.Clear();
- PackCRCsDefined.Clear();
- PackCRCs.Clear();
- Folders.Clear();
- NumUnpackStreamsVector.Clear();
- Files.Clear();
- CTime.Clear();
- ATime.Clear();
- MTime.Clear();
- StartPos.Clear();
- IsAnti.Clear();
- }
-
- void ReserveDown()
- {
- PackSizes.ReserveDown();
- PackCRCsDefined.ReserveDown();
- PackCRCs.ReserveDown();
- Folders.ReserveDown();
- NumUnpackStreamsVector.ReserveDown();
- Files.ReserveDown();
- CTime.ReserveDown();
- ATime.ReserveDown();
- MTime.ReserveDown();
- StartPos.ReserveDown();
- IsAnti.ReserveDown();
- }
-
- bool IsEmpty() const
- {
- return (PackSizes.IsEmpty() &&
- PackCRCsDefined.IsEmpty() &&
- PackCRCs.IsEmpty() &&
- Folders.IsEmpty() &&
- NumUnpackStreamsVector.IsEmpty() &&
- Files.IsEmpty());
- }
-
- bool CheckNumFiles() const
- {
- int size = Files.Size();
- return (
- CTime.CheckSize(size) &&
- ATime.CheckSize(size) &&
- MTime.CheckSize(size) &&
- StartPos.CheckSize(size) &&
- (size == IsAnti.Size() || IsAnti.Size() == 0));
- }
-
- bool IsSolid() const
- {
- for (int i = 0; i < NumUnpackStreamsVector.Size(); i++)
- if (NumUnpackStreamsVector[i] > 1)
- return true;
- return false;
- }
- bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); }
- void SetItemAnti(int index, bool isAnti)
- {
- while (index >= IsAnti.Size())
- IsAnti.Add(false);
- IsAnti[index] = isAnti;
- }
-
- void GetFile(int index, CFileItem &file, CFileItem2 &file2) const;
- void AddFile(const CFileItem &file, const CFileItem2 &file2);
-};
-
}}
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp
index 0c8aa7e8c66..2f9065884f8 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp
@@ -10,35 +10,15 @@
#include "7zOut.h"
-static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t size)
-{
- while (size > 0)
- {
- UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF);
- UInt32 processedSize;
- RINOK(stream->Write(data, curSize, &processedSize));
- if (processedSize == 0)
- return E_FAIL;
- data = (const void *)((const Byte *)data + processedSize);
- size -= processedSize;
- }
- return S_OK;
-}
-
namespace NArchive {
namespace N7z {
-HRESULT COutArchive::WriteDirect(const void *data, UInt32 size)
-{
- return ::WriteBytes(SeqStream, data, size);
-}
-
HRESULT COutArchive::WriteSignature()
{
Byte buf[8];
memcpy(buf, kSignature, kSignatureSize);
buf[kSignatureSize] = kMajorVersion;
- buf[kSignatureSize + 1] = 3;
+ buf[kSignatureSize + 1] = 4;
return WriteDirect(buf, 8);
}
@@ -145,7 +125,9 @@ HRESULT COutArchive::SkipPrefixArchiveHeader()
if (_endMarker)
return S_OK;
#endif
- return Stream->Seek(24, STREAM_SEEK_CUR, NULL);
+ Byte buf[24];
+ memset(buf, 0, 24);
+ return WriteDirect(buf, 24);
}
UInt64 COutArchive::GetPos() const
@@ -217,7 +199,7 @@ void COutArchive::WriteNumber(UInt64 value)
mask >>= 1;
}
WriteByte(firstByte);
- for (;i > 0; i--)
+ for (; i > 0; i--)
{
WriteByte((Byte)value);
value >>= 8;
@@ -271,32 +253,34 @@ UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props)
void COutArchive::WriteFolder(const CFolder &folder)
{
WriteNumber(folder.Coders.Size());
- int i;
+ unsigned i;
+
for (i = 0; i < folder.Coders.Size(); i++)
{
const CCoderInfo &coder = folder.Coders[i];
{
- size_t propsSize = coder.Props.GetCapacity();
-
UInt64 id = coder.MethodID;
- int idSize;
+ unsigned idSize;
for (idSize = 1; idSize < sizeof(id); idSize++)
if ((id >> (8 * idSize)) == 0)
break;
- BYTE longID[15];
- for (int t = idSize - 1; t >= 0 ; t--, id >>= 8)
- longID[t] = (Byte)(id & 0xFF);
- Byte b;
- b = (Byte)(idSize & 0xF);
+ idSize &= 0xF;
+ Byte temp[16];
+ for (unsigned t = idSize; t != 0; t--, id >>= 8)
+ temp[t] = (Byte)(id & 0xFF);
+
+ Byte b = (Byte)(idSize);
bool isComplex = !coder.IsSimpleCoder();
b |= (isComplex ? 0x10 : 0);
- b |= ((propsSize != 0) ? 0x20 : 0 );
- WriteByte(b);
- WriteBytes(longID, idSize);
+
+ size_t propsSize = coder.Props.Size();
+ b |= ((propsSize != 0) ? 0x20 : 0);
+ temp[0] = b;
+ WriteBytes(temp, idSize + 1);
if (isComplex)
{
- WriteNumber(coder.NumInStreams);
- WriteNumber(coder.NumOutStreams);
+ WriteNumber(coder.NumStreams);
+ WriteNumber(1); // NumOutStreams;
}
if (propsSize == 0)
continue;
@@ -304,24 +288,24 @@ void COutArchive::WriteFolder(const CFolder &folder)
WriteBytes(coder.Props, propsSize);
}
}
- for (i = 0; i < folder.BindPairs.Size(); i++)
+
+ for (i = 0; i < folder.Bonds.Size(); i++)
{
- const CBindPair &bindPair = folder.BindPairs[i];
- WriteNumber(bindPair.InIndex);
- WriteNumber(bindPair.OutIndex);
+ const CBond &bond = folder.Bonds[i];
+ WriteNumber(bond.PackIndex);
+ WriteNumber(bond.UnpackIndex);
}
+
if (folder.PackStreams.Size() > 1)
for (i = 0; i < folder.PackStreams.Size(); i++)
- {
WriteNumber(folder.PackStreams[i]);
- }
}
void COutArchive::WriteBoolVector(const CBoolVector &boolVector)
{
Byte b = 0;
Byte mask = 0x80;
- for (int i = 0; i < boolVector.Size(); i++)
+ FOR_VECTOR (i, boolVector)
{
if (boolVector[i])
b |= mask;
@@ -337,37 +321,42 @@ void COutArchive::WriteBoolVector(const CBoolVector &boolVector)
WriteByte(b);
}
+static inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; }
-void COutArchive::WriteHashDigests(
- const CRecordVector<bool> &digestsDefined,
- const CRecordVector<UInt32> &digests)
+void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector)
{
- int numDefined = 0;
- int i;
- for (i = 0; i < digestsDefined.Size(); i++)
- if (digestsDefined[i])
+ WriteByte(id);
+ WriteNumber(Bv_GetSizeInBytes(boolVector));
+ WriteBoolVector(boolVector);
+}
+
+void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
+{
+ unsigned numDefined = 0;
+ unsigned i;
+ for (i = 0; i < digests.Defs.Size(); i++)
+ if (digests.Defs[i])
numDefined++;
if (numDefined == 0)
return;
WriteByte(NID::kCRC);
- if (numDefined == digestsDefined.Size())
+ if (numDefined == digests.Defs.Size())
WriteByte(1);
else
{
WriteByte(0);
- WriteBoolVector(digestsDefined);
+ WriteBoolVector(digests.Defs);
}
- for (i = 0; i < digests.Size(); i++)
- if (digestsDefined[i])
- WriteUInt32(digests[i]);
+ for (i = 0; i < digests.Defs.Size(); i++)
+ if (digests.Defs[i])
+ WriteUInt32(digests.Vals[i]);
}
void COutArchive::WritePackInfo(
UInt64 dataOffset,
const CRecordVector<UInt64> &packSizes,
- const CRecordVector<bool> &packCRCsDefined,
- const CRecordVector<UInt32> &packCRCs)
+ const CUInt32DefVector &packCRCs)
{
if (packSizes.IsEmpty())
return;
@@ -375,15 +364,15 @@ void COutArchive::WritePackInfo(
WriteNumber(dataOffset);
WriteNumber(packSizes.Size());
WriteByte(NID::kSize);
- for (int i = 0; i < packSizes.Size(); i++)
+ FOR_VECTOR (i, packSizes)
WriteNumber(packSizes[i]);
- WriteHashDigests(packCRCsDefined, packCRCs);
+ WriteHashDigests(packCRCs);
WriteByte(NID::kEnd);
}
-void COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders)
+void COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders, const COutFolders &outFolders)
{
if (folders.IsEmpty())
return;
@@ -394,44 +383,29 @@ void COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders)
WriteNumber(folders.Size());
{
WriteByte(0);
- for (int i = 0; i < folders.Size(); i++)
+ FOR_VECTOR (i, folders)
WriteFolder(folders[i]);
}
WriteByte(NID::kCodersUnpackSize);
- int i;
- for (i = 0; i < folders.Size(); i++)
- {
- const CFolder &folder = folders[i];
- for (int j = 0; j < folder.UnpackSizes.Size(); j++)
- WriteNumber(folder.UnpackSizes[j]);
- }
-
- CRecordVector<bool> unpackCRCsDefined;
- CRecordVector<UInt32> unpackCRCs;
- for (i = 0; i < folders.Size(); i++)
- {
- const CFolder &folder = folders[i];
- unpackCRCsDefined.Add(folder.UnpackCRCDefined);
- unpackCRCs.Add(folder.UnpackCRC);
- }
- WriteHashDigests(unpackCRCsDefined, unpackCRCs);
-
+ FOR_VECTOR (i, outFolders.CoderUnpackSizes)
+ WriteNumber(outFolders.CoderUnpackSizes[i]);
+
+ WriteHashDigests(outFolders.FolderUnpackCRCs);
+
WriteByte(NID::kEnd);
}
-void COutArchive::WriteSubStreamsInfo(
- const CObjectVector<CFolder> &folders,
- const CRecordVector<CNum> &numUnpackStreamsInFolders,
+void COutArchive::WriteSubStreamsInfo(const CObjectVector<CFolder> &folders,
+ const COutFolders &outFolders,
const CRecordVector<UInt64> &unpackSizes,
- const CRecordVector<bool> &digestsDefined,
- const CRecordVector<UInt32> &digests)
+ const CUInt32DefVector &digests)
{
+ const CRecordVector<CNum> &numUnpackStreamsInFolders = outFolders.NumUnpackStreamsVector;
WriteByte(NID::kSubStreamsInfo);
- int i;
+ unsigned i;
for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
- {
if (numUnpackStreamsInFolders[i] != 1)
{
WriteByte(NID::kNumUnpackStream);
@@ -439,54 +413,50 @@ void COutArchive::WriteSubStreamsInfo(
WriteNumber(numUnpackStreamsInFolders[i]);
break;
}
- }
-
- bool needFlag = true;
- CNum index = 0;
for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
- for (CNum j = 0; j < numUnpackStreamsInFolders[i]; j++)
+ if (numUnpackStreamsInFolders[i] > 1)
{
- if (j + 1 != numUnpackStreamsInFolders[i])
+ WriteByte(NID::kSize);
+ CNum index = 0;
+ for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
{
- if (needFlag)
- WriteByte(NID::kSize);
- needFlag = false;
- WriteNumber(unpackSizes[index]);
+ CNum num = numUnpackStreamsInFolders[i];
+ for (CNum j = 0; j < num; j++)
+ {
+ if (j + 1 != num)
+ WriteNumber(unpackSizes[index]);
+ index++;
+ }
}
- index++;
+ break;
}
- CRecordVector<bool> digestsDefined2;
- CRecordVector<UInt32> digests2;
+ CUInt32DefVector digests2;
- int digestIndex = 0;
+ unsigned digestIndex = 0;
for (i = 0; i < folders.Size(); i++)
{
- int numSubStreams = (int)numUnpackStreamsInFolders[i];
- if (numSubStreams == 1 && folders[i].UnpackCRCDefined)
+ unsigned numSubStreams = (unsigned)numUnpackStreamsInFolders[i];
+ if (numSubStreams == 1 && outFolders.FolderUnpackCRCs.ValidAndDefined(i))
digestIndex++;
else
- for (int j = 0; j < numSubStreams; j++, digestIndex++)
+ for (unsigned j = 0; j < numSubStreams; j++, digestIndex++)
{
- digestsDefined2.Add(digestsDefined[digestIndex]);
- digests2.Add(digests[digestIndex]);
+ digests2.Defs.Add(digests.Defs[digestIndex]);
+ digests2.Vals.Add(digests.Vals[digestIndex]);
}
}
- WriteHashDigests(digestsDefined2, digests2);
+ WriteHashDigests(digests2);
WriteByte(NID::kEnd);
}
-void COutArchive::SkipAlign(unsigned /* pos */, unsigned /* alignSize */)
-{
- return;
-}
-
-/*
-7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field.
+// 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)
{
+ if (!_useAlign)
+ return;
pos += (unsigned)GetPos();
pos &= (alignSize - 1);
if (pos == 0)
@@ -500,11 +470,8 @@ void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
for (unsigned i = 0; i < skip; i++)
WriteByte(0);
}
-*/
-
-static inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; }
-void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize)
+void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize)
{
const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);
const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2;
@@ -524,48 +491,56 @@ void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, B
void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type)
{
- int numDefined = 0;
+ unsigned numDefined = 0;
- int i;
- for (i = 0; i < v.Defined.Size(); i++)
- if (v.Defined[i])
+ unsigned i;
+ for (i = 0; i < v.Defs.Size(); i++)
+ if (v.Defs[i])
numDefined++;
if (numDefined == 0)
return;
- WriteAlignedBoolHeader(v.Defined, numDefined, type, 8);
+ WriteAlignedBoolHeader(v.Defs, numDefined, type, 8);
- for (i = 0; i < v.Defined.Size(); i++)
- if (v.Defined[i])
- WriteUInt64(v.Values[i]);
+ for (i = 0; i < v.Defs.Size(); i++)
+ if (v.Defs[i])
+ WriteUInt64(v.Vals[i]);
}
HRESULT COutArchive::EncodeStream(
DECL_EXTERNAL_CODECS_LOC_VARS
CEncoder &encoder, const CByteBuffer &data,
- CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
+ CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders)
{
CBufInStream *streamSpec = new CBufInStream;
CMyComPtr<ISequentialInStream> stream = streamSpec;
- streamSpec->Init(data, data.GetCapacity());
- CFolder folderItem;
- folderItem.UnpackCRCDefined = true;
- folderItem.UnpackCRC = CrcCalc(data, data.GetCapacity());
- UInt64 dataSize64 = data.GetCapacity();
+ streamSpec->Init(data, data.Size());
+ outFolders.FolderUnpackCRCs.Defs.Add(true);
+ outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size()));
+ // outFolders.NumUnpackStreamsVector.Add(1);
+ UInt64 dataSize64 = data.Size();
+ UInt64 unpackSize;
RINOK(encoder.Encode(
EXTERNAL_CODECS_LOC_VARS
- stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL))
- folders.Add(folderItem);
+ stream,
+ // NULL,
+ &dataSize64,
+ folders.AddNew(), outFolders.CoderUnpackSizes, unpackSize, SeqStream, packSizes, NULL))
return S_OK;
}
void COutArchive::WriteHeader(
- const CArchiveDatabase &db,
- const CHeaderOptions &headerOptions,
+ const CArchiveDatabaseOut &db,
+ // const CHeaderOptions &headerOptions,
UInt64 &headerOffset)
{
- int i;
+ /*
+ bool thereIsSecure = (db.SecureBuf.Size() != 0);
+ */
+ _useAlign = true;
+
+ unsigned i;
UInt64 packedSize = 0;
for (i = 0; i < db.PackSizes.Size(); i++)
@@ -580,31 +555,22 @@ void COutArchive::WriteHeader(
if (db.Folders.Size() > 0)
{
WriteByte(NID::kMainStreamsInfo);
- WritePackInfo(0, db.PackSizes,
- db.PackCRCsDefined,
- db.PackCRCs);
-
- WriteUnpackInfo(db.Folders);
+ WritePackInfo(0, db.PackSizes, db.PackCRCs);
+ WriteUnpackInfo(db.Folders, (const COutFolders &)db);
CRecordVector<UInt64> unpackSizes;
- CRecordVector<bool> digestsDefined;
- CRecordVector<UInt32> digests;
+ CUInt32DefVector digests;
for (i = 0; i < db.Files.Size(); i++)
{
const CFileItem &file = db.Files[i];
if (!file.HasStream)
continue;
unpackSizes.Add(file.Size);
- digestsDefined.Add(file.CrcDefined);
- digests.Add(file.Crc);
+ digests.Defs.Add(file.CrcDefined);
+ digests.Vals.Add(file.Crc);
}
- WriteSubStreamsInfo(
- db.Folders,
- db.NumUnpackStreamsVector,
- unpackSizes,
- digestsDefined,
- digests);
+ WriteSubStreamsInfo(db.Folders, (const COutFolders &)db, unpackSizes, digests);
WriteByte(NID::kEnd);
}
@@ -618,85 +584,75 @@ void COutArchive::WriteHeader(
WriteNumber(db.Files.Size());
{
- /* ---------- Empty Streams ---------- */
- CBoolVector emptyStreamVector;
- emptyStreamVector.Reserve(db.Files.Size());
- int numEmptyStreams = 0;
- for (i = 0; i < db.Files.Size(); i++)
- if (db.Files[i].HasStream)
- emptyStreamVector.Add(false);
- else
- {
- emptyStreamVector.Add(true);
- numEmptyStreams++;
- }
- if (numEmptyStreams > 0)
- {
- WriteByte(NID::kEmptyStream);
- WriteNumber(Bv_GetSizeInBytes(emptyStreamVector));
- WriteBoolVector(emptyStreamVector);
-
- CBoolVector emptyFileVector, antiVector;
- emptyFileVector.Reserve(numEmptyStreams);
- antiVector.Reserve(numEmptyStreams);
- CNum numEmptyFiles = 0, numAntiItems = 0;
+ /* ---------- Empty Streams ---------- */
+ CBoolVector emptyStreamVector;
+ emptyStreamVector.ClearAndSetSize(db.Files.Size());
+ unsigned numEmptyStreams = 0;
for (i = 0; i < db.Files.Size(); i++)
+ if (db.Files[i].HasStream)
+ emptyStreamVector[i] = false;
+ else
+ {
+ emptyStreamVector[i] = true;
+ numEmptyStreams++;
+ }
+ if (numEmptyStreams != 0)
{
- const CFileItem &file = db.Files[i];
- if (!file.HasStream)
+ WritePropBoolVector(NID::kEmptyStream, emptyStreamVector);
+
+ CBoolVector emptyFileVector, antiVector;
+ emptyFileVector.ClearAndSetSize(numEmptyStreams);
+ antiVector.ClearAndSetSize(numEmptyStreams);
+ bool thereAreEmptyFiles = false, thereAreAntiItems = false;
+ unsigned cur = 0;
+ for (i = 0; i < db.Files.Size(); i++)
{
- emptyFileVector.Add(!file.IsDir);
+ const CFileItem &file = db.Files[i];
+ if (file.HasStream)
+ continue;
+ emptyFileVector[cur] = !file.IsDir;
if (!file.IsDir)
- numEmptyFiles++;
+ thereAreEmptyFiles = true;
bool isAnti = db.IsItemAnti(i);
- antiVector.Add(isAnti);
+ antiVector[cur] = isAnti;
if (isAnti)
- numAntiItems++;
+ thereAreAntiItems = true;
+ cur++;
}
- }
-
- if (numEmptyFiles > 0)
- {
- WriteByte(NID::kEmptyFile);
- WriteNumber(Bv_GetSizeInBytes(emptyFileVector));
- WriteBoolVector(emptyFileVector);
- }
-
- if (numAntiItems > 0)
- {
- WriteByte(NID::kAnti);
- WriteNumber(Bv_GetSizeInBytes(antiVector));
- WriteBoolVector(antiVector);
+
+ if (thereAreEmptyFiles)
+ WritePropBoolVector(NID::kEmptyFile, emptyFileVector);
+ if (thereAreAntiItems)
+ WritePropBoolVector(NID::kAnti, antiVector);
}
}
- }
{
/* ---------- Names ---------- */
- int numDefined = 0;
+ unsigned numDefined = 0;
size_t namesDataSize = 0;
- for (int i = 0; i < db.Files.Size(); i++)
+ FOR_VECTOR (i, db.Files)
{
- const UString &name = db.Files[i].Name;
+ const UString &name = db.Names[i];
if (!name.IsEmpty())
numDefined++;
- namesDataSize += (name.Length() + 1) * 2;
+ namesDataSize += (name.Len() + 1) * 2;
}
if (numDefined > 0)
{
namesDataSize++;
- SkipAlign(2 + GetBigNumberSize(namesDataSize), 2);
+ SkipAlign(2 + GetBigNumberSize(namesDataSize), 16);
WriteByte(NID::kName);
WriteNumber(namesDataSize);
WriteByte(0);
- for (int i = 0; i < db.Files.Size(); i++)
+ FOR_VECTOR (i, db.Files)
{
- const UString &name = db.Files[i].Name;
- for (int t = 0; t <= name.Length(); t++)
+ const UString &name = db.Names[i];
+ for (unsigned t = 0; t <= name.Len(); t++)
{
wchar_t c = name[t];
WriteByte((Byte)c);
@@ -706,26 +662,26 @@ void COutArchive::WriteHeader(
}
}
- if (headerOptions.WriteCTime) WriteUInt64DefVector(db.CTime, NID::kCTime);
- if (headerOptions.WriteATime) WriteUInt64DefVector(db.ATime, NID::kATime);
- if (headerOptions.WriteMTime) WriteUInt64DefVector(db.MTime, NID::kMTime);
+ /* if (headerOptions.WriteCTime) */ WriteUInt64DefVector(db.CTime, NID::kCTime);
+ /* if (headerOptions.WriteATime) */ WriteUInt64DefVector(db.ATime, NID::kATime);
+ /* if (headerOptions.WriteMTime) */ WriteUInt64DefVector(db.MTime, NID::kMTime);
WriteUInt64DefVector(db.StartPos, NID::kStartPos);
{
/* ---------- Write Attrib ---------- */
CBoolVector boolVector;
- boolVector.Reserve(db.Files.Size());
- int numDefined = 0;
+ boolVector.ClearAndSetSize(db.Files.Size());
+ unsigned numDefined = 0;
for (i = 0; i < db.Files.Size(); i++)
{
bool defined = db.Files[i].AttribDefined;
- boolVector.Add(defined);
+ boolVector[i] = defined;
if (defined)
numDefined++;
}
- if (numDefined > 0)
+ if (numDefined != 0)
{
- WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttributes, 4);
+ WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttrib, 4);
for (i = 0; i < db.Files.Size(); i++)
{
const CFileItem &file = db.Files[i];
@@ -735,13 +691,95 @@ 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);
+ }
+ }
+
+ {
+ // ---------- Write Parent ----------
+ CBoolVector boolVector;
+ boolVector.Reserve(db.Files.Size());
+ unsigned numIsDir = 0;
+ unsigned numParentLinks = 0;
+ for (i = 0; i < db.Files.Size(); i++)
+ {
+ const CFileItem &file = db.Files[i];
+ bool defined = !file.IsAltStream;
+ boolVector.Add(defined);
+ if (defined)
+ numIsDir++;
+ if (file.Parent >= 0)
+ numParentLinks++;
+ }
+ if (numParentLinks > 0)
+ {
+ // WriteAlignedBoolHeader(boolVector, numDefined, NID::kParent, 4);
+ 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);
+
+ WriteByte(NID::kParent);
+ WriteNumber(dataSize);
+ if (numIsDir == boolVector.Size())
+ WriteByte(1);
+ else
+ {
+ WriteByte(0);
+ WriteBoolVector(boolVector);
+ }
+ for (i = 0; i < db.Files.Size(); i++)
+ {
+ const CFileItem &file = db.Files[i];
+ // if (file.Parent >= 0)
+ WriteUInt32(file.Parent);
+ }
+ }
+ }
+
+ if (thereIsSecure)
+ {
+ UInt64 secureDataSize = 1 + 4 +
+ db.SecureBuf.Size() +
+ db.SecureSizes.Size() * 4;
+ // secureDataSize += db.SecureIDs.Size() * 4;
+ for (i = 0; i < db.SecureIDs.Size(); i++)
+ secureDataSize += GetBigNumberSize(db.SecureIDs[i]);
+ SkipAlign(2 + GetBigNumberSize(secureDataSize), 4);
+ WriteByte(NID::kNtSecure);
+ WriteNumber(secureDataSize);
+ WriteByte(0);
+ WriteUInt32(db.SecureSizes.Size());
+ for (i = 0; i < db.SecureSizes.Size(); i++)
+ WriteUInt32(db.SecureSizes[i]);
+ WriteBytes(db.SecureBuf, db.SecureBuf.Size());
+ for (i = 0; i < db.SecureIDs.Size(); i++)
+ {
+ WriteNumber(db.SecureIDs[i]);
+ // WriteUInt32(db.SecureIDs[i]);
+ }
+ }
+ */
+
WriteByte(NID::kEnd); // for files
WriteByte(NID::kEnd); // for headers
}
HRESULT COutArchive::WriteDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
- const CArchiveDatabase &db,
+ const CArchiveDatabaseOut &db,
const CCompressionMethodMode *options,
const CHeaderOptions &headerOptions)
{
@@ -773,17 +811,16 @@ HRESULT COutArchive::WriteDatabase(
_countMode = encodeHeaders;
_writeToStream = true;
_countSize = 0;
- WriteHeader(db, headerOptions, headerOffset);
+ WriteHeader(db, /* headerOptions, */ headerOffset);
if (encodeHeaders)
{
- CByteBuffer buf;
- buf.SetCapacity(_countSize);
+ CByteBuffer buf(_countSize);
_outByte2.Init((Byte *)buf, _countSize);
_countMode = false;
_writeToStream = false;
- WriteHeader(db, headerOptions, headerOffset);
+ WriteHeader(db, /* headerOptions, */ headerOffset);
if (_countSize != _outByte2.GetPos())
return E_FAIL;
@@ -794,10 +831,12 @@ HRESULT COutArchive::WriteDatabase(
CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions);
CRecordVector<UInt64> packSizes;
CObjectVector<CFolder> folders;
+ COutFolders outFolders;
+
RINOK(EncodeStream(
EXTERNAL_CODECS_LOC_VARS
encoder, buf,
- packSizes, folders));
+ packSizes, folders, outFolders));
_writeToStream = true;
@@ -805,11 +844,10 @@ HRESULT COutArchive::WriteDatabase(
throw 1;
WriteID(NID::kEncodedHeader);
- WritePackInfo(headerOffset, packSizes,
- CRecordVector<bool>(), CRecordVector<UInt32>());
- WriteUnpackInfo(folders);
+ WritePackInfo(headerOffset, packSizes, CUInt32DefVector());
+ WriteUnpackInfo(folders, outFolders);
WriteByte(NID::kEnd);
- for (int i = 0; i < packSizes.Size(); i++)
+ FOR_VECTOR (i, packSizes)
headerOffset += packSizes[i];
}
RINOK(_outByte.Flush());
@@ -842,24 +880,28 @@ HRESULT COutArchive::WriteDatabase(
}
}
-void CArchiveDatabase::GetFile(int index, CFileItem &file, CFileItem2 &file2) const
+void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value)
{
- file = Files[index];
- file2.CTimeDefined = CTime.GetItem(index, file2.CTime);
- file2.ATimeDefined = ATime.GetItem(index, file2.ATime);
- file2.MTimeDefined = MTime.GetItem(index, file2.MTime);
- file2.StartPosDefined = StartPos.GetItem(index, file2.StartPos);
- file2.IsAnti = IsItemAnti(index);
+ while (index >= Defs.Size())
+ Defs.Add(false);
+ Defs[index] = defined;
+ if (!defined)
+ return;
+ while (index >= Vals.Size())
+ Vals.Add(0);
+ Vals[index] = value;
}
-void CArchiveDatabase::AddFile(const CFileItem &file, const CFileItem2 &file2)
+void CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name)
{
- int index = Files.Size();
+ unsigned index = Files.Size();
CTime.SetItem(index, file2.CTimeDefined, file2.CTime);
ATime.SetItem(index, file2.ATimeDefined, file2.ATime);
MTime.SetItem(index, file2.MTimeDefined, file2.MTime);
StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos);
- SetItemAnti(index, file2.IsAnti);
+ SetItem_Anti(index, file2.IsAnti);
+ // SetItem_Aux(index, file2.IsAux);
+ Names.Add(name);
Files.Add(file);
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h
index 7b1b528e6c4..6c902668939 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h
@@ -9,6 +9,7 @@
#include "7zItem.h"
#include "../../Common/OutBuffer.h"
+#include "../../Common/StreamUtils.h"
namespace NArchive {
namespace N7z {
@@ -28,6 +29,8 @@ public:
}
void WriteBytes(const void *data, size_t size)
{
+ if (size == 0)
+ return;
if (size > _size - _pos)
throw 1;
memcpy(_data + _pos, data, size);
@@ -45,27 +48,191 @@ public:
struct CHeaderOptions
{
bool CompressMainHeader;
+ /*
bool WriteCTime;
bool WriteATime;
bool WriteMTime;
+ */
CHeaderOptions():
- CompressMainHeader(true),
- WriteCTime(false),
- WriteATime(false),
- WriteMTime(true)
+ CompressMainHeader(true)
+ /*
+ , WriteCTime(false)
+ , WriteATime(false)
+ , WriteMTime(true)
+ */
{}
};
+
+struct CFileItem2
+{
+ UInt64 CTime;
+ UInt64 ATime;
+ UInt64 MTime;
+ UInt64 StartPos;
+ bool CTimeDefined;
+ bool ATimeDefined;
+ bool MTimeDefined;
+ bool StartPosDefined;
+ bool IsAnti;
+ // bool IsAux;
+
+ void Init()
+ {
+ CTimeDefined = false;
+ ATimeDefined = false;
+ MTimeDefined = false;
+ StartPosDefined = false;
+ IsAnti = false;
+ // IsAux = false;
+ }
+};
+
+struct COutFolders
+{
+ CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
+
+ CRecordVector<CNum> NumUnpackStreamsVector;
+ CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders
+
+ void OutFoldersClear()
+ {
+ FolderUnpackCRCs.Clear();
+ NumUnpackStreamsVector.Clear();
+ CoderUnpackSizes.Clear();
+ }
+
+ void OutFoldersReserveDown()
+ {
+ FolderUnpackCRCs.ReserveDown();
+ NumUnpackStreamsVector.ReserveDown();
+ CoderUnpackSizes.ReserveDown();
+ }
+};
+
+struct CArchiveDatabaseOut: public COutFolders
+{
+ CRecordVector<UInt64> PackSizes;
+ CUInt32DefVector PackCRCs;
+ CObjectVector<CFolder> Folders;
+
+ CRecordVector<CFileItem> Files;
+ UStringVector Names;
+ CUInt64DefVector CTime;
+ CUInt64DefVector ATime;
+ CUInt64DefVector MTime;
+ CUInt64DefVector StartPos;
+ CRecordVector<bool> IsAnti;
+
+ /*
+ CRecordVector<bool> IsAux;
+
+ CByteBuffer SecureBuf;
+ CRecordVector<UInt32> SecureSizes;
+ CRecordVector<UInt32> SecureIDs;
+
+ void ClearSecure()
+ {
+ SecureBuf.Free();
+ SecureSizes.Clear();
+ SecureIDs.Clear();
+ }
+ */
+
+ void Clear()
+ {
+ OutFoldersClear();
+
+ PackSizes.Clear();
+ PackCRCs.Clear();
+ Folders.Clear();
+
+ Files.Clear();
+ Names.Clear();
+ CTime.Clear();
+ ATime.Clear();
+ MTime.Clear();
+ StartPos.Clear();
+ IsAnti.Clear();
+
+ /*
+ IsAux.Clear();
+ ClearSecure();
+ */
+ }
+
+ void ReserveDown()
+ {
+ OutFoldersReserveDown();
+
+ PackSizes.ReserveDown();
+ PackCRCs.ReserveDown();
+ Folders.ReserveDown();
+
+ Files.ReserveDown();
+ Names.ReserveDown();
+ CTime.ReserveDown();
+ ATime.ReserveDown();
+ MTime.ReserveDown();
+ StartPos.ReserveDown();
+ IsAnti.ReserveDown();
+
+ /*
+ IsAux.ReserveDown();
+ */
+ }
+
+ bool IsEmpty() const
+ {
+ return (
+ PackSizes.IsEmpty() &&
+ NumUnpackStreamsVector.IsEmpty() &&
+ Folders.IsEmpty() &&
+ Files.IsEmpty());
+ }
+
+ bool CheckNumFiles() const
+ {
+ unsigned size = Files.Size();
+ return (
+ CTime.CheckSize(size) &&
+ ATime.CheckSize(size) &&
+ MTime.CheckSize(size) &&
+ StartPos.CheckSize(size) &&
+ (size == IsAnti.Size() || IsAnti.Size() == 0));
+ }
+
+ bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
+ // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
+
+ void SetItem_Anti(unsigned index, bool isAnti)
+ {
+ while (index >= IsAnti.Size())
+ IsAnti.Add(false);
+ IsAnti[index] = isAnti;
+ }
+ /*
+ void SetItem_Aux(unsigned index, bool isAux)
+ {
+ while (index >= IsAux.Size())
+ IsAux.Add(false);
+ IsAux[index] = isAux;
+ }
+ */
+
+ void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name);
+};
+
class COutArchive
{
UInt64 _prefixHeaderPos;
- HRESULT WriteDirect(const void *data, UInt32 size);
+ HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); }
UInt64 GetPos() const;
void WriteBytes(const void *data, size_t size);
- void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.GetCapacity()); }
+ void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.Size()); }
void WriteByte(Byte b);
void WriteUInt32(UInt32 value);
void WriteUInt64(UInt64 value);
@@ -75,36 +242,36 @@ class COutArchive
void WriteFolder(const CFolder &folder);
HRESULT WriteFileHeader(const CFileItem &itemInfo);
void WriteBoolVector(const CBoolVector &boolVector);
- void WriteHashDigests(
- const CRecordVector<bool> &digestsDefined,
- const CRecordVector<UInt32> &hashDigests);
+ void WritePropBoolVector(Byte id, const CBoolVector &boolVector);
+
+ void WriteHashDigests(const CUInt32DefVector &digests);
void WritePackInfo(
UInt64 dataOffset,
const CRecordVector<UInt64> &packSizes,
- const CRecordVector<bool> &packCRCsDefined,
- const CRecordVector<UInt32> &packCRCs);
+ const CUInt32DefVector &packCRCs);
- void WriteUnpackInfo(const CObjectVector<CFolder> &folders);
+ void WriteUnpackInfo(
+ const CObjectVector<CFolder> &folders,
+ const COutFolders &outFolders);
void WriteSubStreamsInfo(
const CObjectVector<CFolder> &folders,
- const CRecordVector<CNum> &numUnpackStreamsInFolders,
+ const COutFolders &outFolders,
const CRecordVector<UInt64> &unpackSizes,
- const CRecordVector<bool> &digestsDefined,
- const CRecordVector<UInt32> &hashDigests);
+ const CUInt32DefVector &digests);
void SkipAlign(unsigned pos, unsigned alignSize);
- void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize);
+ void WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize);
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
HRESULT EncodeStream(
DECL_EXTERNAL_CODECS_LOC_VARS
CEncoder &encoder, const CByteBuffer &data,
- CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
+ CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders);
void WriteHeader(
- const CArchiveDatabase &db,
- const CHeaderOptions &headerOptions,
+ const CArchiveDatabaseOut &db,
+ // const CHeaderOptions &headerOptions,
UInt64 &headerOffset);
bool _countMode;
@@ -118,6 +285,8 @@ class COutArchive
bool _endMarker;
#endif
+ bool _useAlign;
+
HRESULT WriteSignature();
#ifdef _7Z_VOL
HRESULT WriteFinishSignature();
@@ -136,7 +305,7 @@ public:
HRESULT SkipPrefixArchiveHeader();
HRESULT WriteDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
- const CArchiveDatabase &db,
+ const CArchiveDatabaseOut &db,
const CCompressionMethodMode *options,
const CHeaderOptions &headerOptions);
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp
index fd4af49c74e..4cb5a5e6469 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp
@@ -13,56 +13,47 @@ namespace N7z {
struct CPropMap
{
- UInt64 FilePropID;
- STATPROPSTG StatPROPSTG;
+ UInt32 FilePropID;
+ CStatProp StatProp;
};
-CPropMap kPropMap[] =
+static const CPropMap kPropMap[] =
{
{ NID::kName, { NULL, kpidPath, VT_BSTR } },
{ NID::kSize, { NULL, kpidSize, VT_UI8 } },
{ NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },
#ifdef _MULTI_PACK
- { 100, { L"Pack0", kpidPackedSize0, VT_UI8 } },
- { 101, { L"Pack1", kpidPackedSize1, VT_UI8 } },
- { 102, { L"Pack2", kpidPackedSize2, VT_UI8 } },
- { 103, { L"Pack3", kpidPackedSize3, VT_UI8 } },
- { 104, { L"Pack4", kpidPackedSize4, VT_UI8 } },
+ { 100, { "Pack0", kpidPackedSize0, VT_UI8 } },
+ { 101, { "Pack1", kpidPackedSize1, VT_UI8 } },
+ { 102, { "Pack2", kpidPackedSize2, VT_UI8 } },
+ { 103, { "Pack3", kpidPackedSize3, VT_UI8 } },
+ { 104, { "Pack4", kpidPackedSize4, VT_UI8 } },
#endif
{ NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },
{ NID::kMTime, { NULL, kpidMTime, VT_FILETIME } },
{ NID::kATime, { NULL, kpidATime, VT_FILETIME } },
- { NID::kWinAttributes, { NULL, kpidAttrib, VT_UI4 } },
- { NID::kStartPos, { NULL, kpidPosition, VT_UI4 } },
+ { NID::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } },
+ { NID::kStartPos, { NULL, kpidPosition, VT_UI8 } },
{ NID::kCRC, { NULL, kpidCRC, VT_UI4 } },
+// { NID::kIsAux, { NULL, kpidIsAux, VT_BOOL } },
{ NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } }
#ifndef _SFX
,
- { 97, { NULL,kpidEncrypted, VT_BOOL } },
- { 98, { NULL,kpidMethod, VT_BSTR } },
- { 99, { NULL,kpidBlock, VT_UI4 } }
+ { 97, { NULL, kpidEncrypted, VT_BOOL } },
+ { 98, { NULL, kpidMethod, VT_BSTR } },
+ { 99, { NULL, kpidBlock, VT_UI4 } }
#endif
};
-static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
-
-static int FindPropInMap(UInt64 filePropID)
-{
- for (int i = 0; i < kPropMapSize; i++)
- if (kPropMap[i].FilePropID == filePropID)
- return i;
- return -1;
-}
-
static void CopyOneItem(CRecordVector<UInt64> &src,
CRecordVector<UInt64> &dest, UInt32 item)
{
- for (int i = 0; i < src.Size(); i++)
+ FOR_VECTOR (i, src)
if (src[i] == item)
{
dest.Add(item);
@@ -73,7 +64,7 @@ static void CopyOneItem(CRecordVector<UInt64> &src,
static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
{
- for (int i = 0; i < src.Size(); i++)
+ FOR_VECTOR (i, src)
if (src[i] == item)
{
src.Delete(i);
@@ -83,7 +74,7 @@ static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
{
- for (int i = 0; i < dest.Size(); i++)
+ FOR_VECTOR (i, dest)
if (dest[i] == item)
{
dest.Delete(i);
@@ -92,32 +83,39 @@ static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
dest.Insert(0, item);
}
+#define COPY_ONE_ITEM(id) CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::id);
+
void CHandler::FillPopIDs()
{
_fileInfoPopIDs.Clear();
#ifdef _7Z_VOL
- if(_volumes.Size() < 1)
+ if (_volumes.Size() < 1)
return;
const CVolume &volume = _volumes.Front();
const CArchiveDatabaseEx &_db = volume.Database;
#endif
- CRecordVector<UInt64> fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs;
+ CRecordVector<UInt64> fileInfoPopIDs = _db.ArcInfo.FileInfoPopIDs;
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
+ /*
+ RemoveOneItem(fileInfoPopIDs, NID::kParent);
+ RemoveOneItem(fileInfoPopIDs, NID::kNtSecure);
+ */
+
+ COPY_ONE_ITEM(kName);
+ COPY_ONE_ITEM(kAnti);
+ COPY_ONE_ITEM(kSize);
+ COPY_ONE_ITEM(kPackInfo);
+ COPY_ONE_ITEM(kCTime);
+ COPY_ONE_ITEM(kMTime);
+ COPY_ONE_ITEM(kATime);
+ COPY_ONE_ITEM(kWinAttrib);
+ COPY_ONE_ITEM(kCRC);
+ COPY_ONE_ITEM(kComment);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
_fileInfoPopIDs += fileInfoPopIDs;
#ifndef _SFX
@@ -125,6 +123,7 @@ void CHandler::FillPopIDs()
_fileInfoPopIDs.Add(98);
_fileInfoPopIDs.Add(99);
#endif
+
#ifdef _MULTI_PACK
_fileInfoPopIDs.Add(100);
_fileInfoPopIDs.Add(101);
@@ -141,24 +140,35 @@ void CHandler::FillPopIDs()
#endif
}
-STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
{
- *numProperties = _fileInfoPopIDs.Size();
+ *numProps = _fileInfoPopIDs.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
{
- if ((int)index >= _fileInfoPopIDs.Size())
- return E_INVALIDARG;
- int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
- if (indexInMap == -1)
+ if (index >= _fileInfoPopIDs.Size())
return E_INVALIDARG;
- const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
- *propID = srcItem.propid;
- *varType = srcItem.vt;
- *name = 0;
- return S_OK;
+ UInt64 id = _fileInfoPopIDs[index];
+ for (unsigned i = 0; i < ARRAY_SIZE(kPropMap); i++)
+ {
+ const CPropMap &pr = kPropMap[i];
+ if (pr.FilePropID == id)
+ {
+ const CStatProp &st = pr.StatProp;
+ *propID = st.PropID;
+ *varType = st.vt;
+ /*
+ if (st.lpwstrName)
+ *name = ::SysAllocString(st.lpwstrName);
+ else
+ */
+ *name = NULL;
+ return S_OK;
+ }
+ }
+ return E_INVALIDARG;
}
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp
index 6e9bf6b99db..389b54074e4 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp
@@ -5,14 +5,17 @@
#include "../../Common/RegisterArc.h"
#include "7zHandler.h"
-static IInArchive *CreateArc() { return new NArchive::N7z::CHandler; }
-#ifndef EXTRACT_ONLY
-static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler; }
-#else
-#define CreateArcOut 0
-#endif
-static CArcInfo g_ArcInfo =
- { L"7z", L"7z", 0, 7, {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut };
+namespace NArchive {
+namespace N7z {
-REGISTER_ARC(7z)
+static Byte k_Signature_Dec[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
+
+REGISTER_ARC_IO_DECREMENT_SIG(
+ "7z", "7z", NULL, 7,
+ k_Signature_Dec,
+ 0,
+ NArcInfoFlags::kFindSignature,
+ NULL);
+
+}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp
index 06969636da2..8e45d98756c 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp
@@ -9,16 +9,14 @@ STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32
UInt32 realProcessedSize;
HRESULT result = _stream->Read(data, size, &realProcessedSize);
_size += realProcessedSize;
- if (processedSize != 0)
+ if (processedSize)
*processedSize = realProcessedSize;
return result;
}
-STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
- UInt64 subStream, UInt64 *value)
+STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
- if (_getSubStreamSize == NULL)
+ if (!_getSubStreamSize)
return E_NOTIMPL;
- return _getSubStreamSize->GetSubStreamSize(subStream, value);
+ return _getSubStreamSize->GetSubStreamSize(subStream, value);
}
-
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h
index 2e26efd5cbd..21155069f2d 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h
@@ -3,10 +3,10 @@
#ifndef __7Z_SPEC_STREAM_H
#define __7Z_SPEC_STREAM_H
-#include "../../IStream.h"
-#include "../../ICoder.h"
#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+
class CSequentialInStreamSizeCount2:
public ISequentialInStream,
public ICompressGetSubStreamSize,
@@ -18,14 +18,14 @@ class CSequentialInStreamSizeCount2:
public:
void Init(ISequentialInStream *stream)
{
+ _size = 0;
+ _getSubStreamSize.Release();
_stream = stream;
- _getSubStreamSize = 0;
_stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
- _size = 0;
}
UInt64 GetSize() const { return _size; }
- MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
+ MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp
index e63b09d2802..7e9478fc5ac 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp
@@ -4,15 +4,15 @@
#include "../../../../C/CpuArch.h"
-#include "../../Common/LimitedStreams.h"
-#include "../../Common/ProgressUtils.h"
+#include "../../../Common/Wildcard.h"
#include "../../Common/CreateCoder.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/ProgressUtils.h"
#include "../../Compress/CopyCoder.h"
#include "../Common/ItemNameUtils.h"
-#include "../Common/OutStreamWithCRC.h"
#include "7zDecode.h"
#include "7zEncode.h"
@@ -24,9 +24,392 @@
namespace NArchive {
namespace N7z {
-#ifdef MY_CPU_X86_OR_AMD64
-#define USE_86_FILTER
-#endif
+
+#define k_X86 k_BCJ
+
+struct CFilterMode
+{
+ UInt32 Id;
+ UInt32 Delta;
+
+ CFilterMode(): Id(0), Delta(0) {}
+
+ void SetDelta()
+ {
+ if (Id == k_IA64)
+ Delta = 16;
+ else if (Id == k_ARM || Id == k_PPC || Id == k_PPC)
+ Delta = 4;
+ else if (Id == k_ARMT)
+ Delta = 2;
+ else
+ Delta = 0;
+ }
+};
+
+
+/* ---------- PE ---------- */
+
+#define MZ_SIG 0x5A4D
+
+#define PE_SIG 0x00004550
+#define PE_OptHeader_Magic_32 0x10B
+#define PE_OptHeader_Magic_64 0x20B
+#define PE_SectHeaderSize 40
+#define PE_SECT_EXECUTE 0x20000000
+
+static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
+{
+ if (size < 512 || GetUi16(buf) != MZ_SIG)
+ return 0;
+
+ const Byte *p;
+ UInt32 peOffset, optHeaderSize, filterId;
+
+ peOffset = GetUi32(buf + 0x3C);
+ if (peOffset >= 0x1000 || peOffset + 512 > size || (peOffset & 7) != 0)
+ return 0;
+ p = buf + peOffset;
+ if (GetUi32(p) != PE_SIG)
+ return 0;
+ p += 4;
+
+ switch (GetUi16(p))
+ {
+ case 0x014C:
+ case 0x8664: filterId = k_X86; break;
+
+ /*
+ IMAGE_FILE_MACHINE_ARM 0x01C0 // ARM LE
+ IMAGE_FILE_MACHINE_THUMB 0x01C2 // ARM Thumb / Thumb-2 LE
+ IMAGE_FILE_MACHINE_ARMNT 0x01C4 // ARM Thumb-2, LE
+ Note: We use ARM filter for 0x01C2. (WinCE 5 - 0x01C2) files mostly contain ARM code (not Thumb/Thumb-2).
+ */
+
+ case 0x01C0: // WinCE old
+ case 0x01C2: filterId = k_ARM; break; // WinCE new
+ case 0x01C4: filterId = k_ARMT; break; // WinRT
+
+ case 0x0200: filterId = k_IA64; break;
+ default: return 0;
+ }
+
+ optHeaderSize = GetUi16(p + 16);
+ if (optHeaderSize > (1 << 10))
+ return 0;
+
+ p += 20; /* headerSize */
+
+ switch (GetUi16(p))
+ {
+ case PE_OptHeader_Magic_32:
+ case PE_OptHeader_Magic_64:
+ break;
+ default:
+ return 0;
+ }
+
+ filterMode->Id = filterId;
+ return 1;
+}
+
+
+/* ---------- ELF ---------- */
+
+#define ELF_SIG 0x464C457F
+
+#define ELF_CLASS_32 1
+#define ELF_CLASS_64 2
+
+#define ELF_DATA_2LSB 1
+#define ELF_DATA_2MSB 2
+
+static UInt16 Get16(const Byte *p, Bool be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); }
+static UInt32 Get32(const Byte *p, Bool be) { if (be) return GetBe32(p); return GetUi32(p); }
+// static UInt64 Get64(const Byte *p, Bool be) { if (be) return GetBe64(p); return GetUi64(p); }
+
+static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode)
+{
+ Bool /* is32, */ be;
+ UInt32 filterId;
+
+ if (size < 512 || buf[6] != 1) /* ver */
+ return 0;
+
+ if (GetUi32(buf) != ELF_SIG)
+ return 0;
+
+ switch (buf[4])
+ {
+ case ELF_CLASS_32: /* is32 = True; */ break;
+ case ELF_CLASS_64: /* is32 = False; */ break;
+ default: return 0;
+ }
+
+ switch (buf[5])
+ {
+ case ELF_DATA_2LSB: be = False; break;
+ case ELF_DATA_2MSB: be = True; break;
+ default: return 0;
+ }
+
+ switch (Get16(buf + 0x12, be))
+ {
+ case 3:
+ case 6:
+ case 62: filterId = k_X86; break;
+ case 2:
+ case 18:
+ case 43: filterId = k_SPARC; break;
+ case 20:
+ case 21: if (!be) return 0; filterId = k_PPC; break;
+ case 40: if ( be) return 0; filterId = k_ARM; break;
+
+ /* Some IA-64 ELF exacutable have size that is not aligned for 16 bytes.
+ So we don't use IA-64 filter for IA-64 ELF */
+ // case 50: if ( be) return 0; filterId = k_IA64; break;
+
+ default: return 0;
+ }
+
+ filterMode->Id = filterId;
+ return 1;
+}
+
+
+
+/* ---------- Mach-O ---------- */
+
+#define MACH_SIG_BE_32 0xCEFAEDFE
+#define MACH_SIG_BE_64 0xCFFAEDFE
+#define MACH_SIG_LE_32 0xFEEDFACE
+#define MACH_SIG_LE_64 0xFEEDFACF
+
+#define MACH_ARCH_ABI64 (1 << 24)
+#define MACH_MACHINE_386 7
+#define MACH_MACHINE_ARM 12
+#define MACH_MACHINE_SPARC 14
+#define MACH_MACHINE_PPC 18
+#define MACH_MACHINE_PPC64 (MACH_ARCH_ABI64 | MACH_MACHINE_PPC)
+#define MACH_MACHINE_AMD64 (MACH_ARCH_ABI64 | MACH_MACHINE_386)
+
+static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode)
+{
+ UInt32 filterId, numCommands, commandsSize;
+
+ if (size < 512)
+ return 0;
+
+ Bool /* mode64, */ be;
+ switch (GetUi32(buf))
+ {
+ case MACH_SIG_BE_32: /* mode64 = False; */ be = True; break;
+ case MACH_SIG_BE_64: /* mode64 = True; */ be = True; break;
+ case MACH_SIG_LE_32: /* mode64 = False; */ be = False; break;
+ case MACH_SIG_LE_64: /* mode64 = True; */ be = False; break;
+ default: return 0;
+ }
+
+ switch (Get32(buf + 4, be))
+ {
+ case MACH_MACHINE_386:
+ case MACH_MACHINE_AMD64: filterId = k_X86; break;
+ case MACH_MACHINE_ARM: if ( be) return 0; filterId = k_ARM; break;
+ case MACH_MACHINE_SPARC: if (!be) return 0; filterId = k_SPARC; break;
+ case MACH_MACHINE_PPC:
+ case MACH_MACHINE_PPC64: if (!be) return 0; filterId = k_PPC; break;
+ default: return 0;
+ }
+
+ numCommands = Get32(buf + 0x10, be);
+ commandsSize = Get32(buf + 0x14, be);
+
+ if (commandsSize > (1 << 24) || numCommands > (1 << 18))
+ return 0;
+
+ filterMode->Id = filterId;
+ return 1;
+}
+
+
+/* ---------- WAV ---------- */
+
+#define WAV_SUBCHUNK_fmt 0x20746D66
+#define WAV_SUBCHUNK_data 0x61746164
+
+#define RIFF_SIG 0x46464952
+
+static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
+{
+ UInt32 subChunkSize, pos;
+ if (size < 0x2C)
+ return False;
+
+ if (GetUi32(buf + 0) != RIFF_SIG ||
+ GetUi32(buf + 8) != 0x45564157 || // WAVE
+ GetUi32(buf + 0xC) != WAV_SUBCHUNK_fmt)
+ return False;
+ subChunkSize = GetUi32(buf + 0x10);
+ /* [0x14 = format] = 1 (PCM) */
+ if (subChunkSize < 0x10 || subChunkSize > 0x12 || GetUi16(buf + 0x14) != 1)
+ return False;
+
+ unsigned numChannels = GetUi16(buf + 0x16);
+ unsigned bitsPerSample = GetUi16(buf + 0x22);
+
+ if ((bitsPerSample & 0x7) != 0 || bitsPerSample >= 256 || numChannels >= 256)
+ return False;
+
+ pos = 0x14 + subChunkSize;
+
+ const int kNumSubChunksTests = 10;
+ // Do we need to scan more than 3 sub-chunks?
+ for (int i = 0; i < kNumSubChunksTests; i++)
+ {
+ if (pos + 8 > size)
+ return False;
+ subChunkSize = GetUi32(buf + pos + 4);
+ if (GetUi32(buf + pos) == WAV_SUBCHUNK_data)
+ {
+ unsigned delta = numChannels * (bitsPerSample >> 3);
+ if (delta >= 256)
+ return False;
+ filterMode->Id = k_Delta;
+ filterMode->Delta = delta;
+ return True;
+ }
+ if (subChunkSize > (1 << 16))
+ return False;
+ pos += subChunkSize + 8;
+ }
+ return False;
+}
+
+static Bool ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode)
+{
+ filterMode->Id = 0;
+ filterMode->Delta = 0;
+
+ if (Parse_EXE(buf, size, filterMode)) return True;
+ if (Parse_ELF(buf, size, filterMode)) return True;
+ if (Parse_MACH(buf, size, filterMode)) return True;
+ return Parse_WAV(buf, size, filterMode);
+}
+
+
+
+
+struct CFilterMode2: public CFilterMode
+{
+ bool Encrypted;
+ unsigned GroupIndex;
+
+ CFilterMode2(): Encrypted(false) {}
+
+ int Compare(const CFilterMode2 &m) const
+ {
+ if (!Encrypted)
+ {
+ if (m.Encrypted)
+ return -1;
+ }
+ else if (!m.Encrypted)
+ return 1;
+
+ if (Id < m.Id) return -1;
+ if (Id > m.Id) return 1;
+
+ if (Delta < m.Delta) return -1;
+ if (Delta > m.Delta) return 1;
+
+ return 0;
+ }
+
+ bool operator ==(const CFilterMode2 &m) const
+ {
+ return Id == m.Id && Delta == m.Delta && Encrypted == m.Encrypted;
+ }
+};
+
+static unsigned GetGroup(CRecordVector<CFilterMode2> &filters, const CFilterMode2 &m)
+{
+ unsigned i;
+ for (i = 0; i < filters.Size(); i++)
+ {
+ const CFilterMode2 &m2 = filters[i];
+ if (m == m2)
+ return i;
+ /*
+ if (m.Encrypted != m2.Encrypted)
+ {
+ if (!m.Encrypted)
+ break;
+ continue;
+ }
+
+ if (m.Id < m2.Id) break;
+ if (m.Id != m2.Id) continue;
+
+ if (m.Delta < m2.Delta) break;
+ if (m.Delta != m2.Delta) continue;
+ */
+ }
+ // filters.Insert(i, m);
+ // return i;
+ return filters.Add(m);
+}
+
+static inline bool Is86Filter(CMethodId m)
+{
+ return (m == k_BCJ || m == k_BCJ2);
+}
+
+static inline bool IsExeFilter(CMethodId m)
+{
+ switch (m)
+ {
+ case k_BCJ:
+ case k_BCJ2:
+ case k_ARM:
+ case k_ARMT:
+ case k_PPC:
+ case k_SPARC:
+ case k_IA64:
+ return true;
+ }
+ return false;
+}
+
+static unsigned Get_FilterGroup_for_Folder(CRecordVector<CFilterMode2> &filters, const CFolderEx &f)
+{
+ CFilterMode2 m;
+ m.Id = 0;
+ m.Delta = 0;
+ m.Encrypted = f.IsEncrypted();
+
+ const CCoderInfo &coder = f.Coders[f.UnpackCoder];
+
+ if (coder.MethodID == k_Delta)
+ {
+ if (coder.Props.Size() == 1)
+ {
+ m.Delta = (unsigned)coder.Props[0] + 1;
+ m.Id = k_Delta;
+ }
+ }
+ else if (IsExeFilter(coder.MethodID))
+ {
+ m.Id = (UInt32)coder.MethodID;
+ if (m.Id == k_BCJ2)
+ m.Id = k_BCJ;
+ m.SetDelta();
+ }
+
+ return GetGroup(filters, m);
+}
+
+
+
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
UInt64 position, UInt64 size, ICompressProgressInfo *progress)
@@ -43,34 +426,27 @@ static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL);
}
-static int GetReverseSlashPos(const UString &name)
-{
- int slashPos = name.ReverseFind(L'/');
- #ifdef _WIN32
- int slash1Pos = name.ReverseFind(L'\\');
- slashPos = MyMax(slashPos, slash1Pos);
- #endif
- return slashPos;
-}
-
-int CUpdateItem::GetExtensionPos() const
+/*
+unsigned CUpdateItem::GetExtensionPos() const
{
- int slashPos = GetReverseSlashPos(Name);
- int dotPos = Name.ReverseFind(L'.');
- if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
- return Name.Length();
+ int slashPos = Name.ReverseFind_PathSepar();
+ int dotPos = Name.ReverseFind_Dot();
+ if (dotPos <= slashPos)
+ return Name.Len();
return dotPos + 1;
}
UString CUpdateItem::GetExtension() const
{
- return Name.Mid(GetExtensionPos());
+ return Name.Ptr(GetExtensionPos());
}
+*/
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
#define RINOZ_COMP(a, b) RINOZ(MyCompare(a, b))
+/*
static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
{
size_t c1 = a1.GetCapacity();
@@ -89,7 +465,7 @@ static int CompareCoders(const CCoderInfo &c1, const CCoderInfo &c2)
return CompareBuffers(c1.Props, c2.Props);
}
-static int CompareBindPairs(const CBindPair &b1, const CBindPair &b2)
+static int CompareBonds(const CBond &b1, const CBond &b2)
{
RINOZ_COMP(b1.InIndex, b2.InIndex);
return MyCompare(b1.OutIndex, b2.OutIndex);
@@ -103,77 +479,86 @@ static int CompareFolders(const CFolder &f1, const CFolder &f2)
int i;
for (i = 0; i < s1; i++)
RINOZ(CompareCoders(f1.Coders[i], f2.Coders[i]));
- s1 = f1.BindPairs.Size();
- s2 = f2.BindPairs.Size();
+ s1 = f1.Bonds.Size();
+ s2 = f2.Bonds.Size();
RINOZ_COMP(s1, s2);
for (i = 0; i < s1; i++)
- RINOZ(CompareBindPairs(f1.BindPairs[i], f2.BindPairs[i]));
+ RINOZ(CompareBonds(f1.Bonds[i], f2.Bonds[i]));
return 0;
}
+*/
/*
static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
{
- return MyStringCompareNoCase(f1.Name, f2.Name);
+ return CompareFileNames(f1.Name, f2.Name);
}
*/
struct CFolderRepack
{
- int FolderIndex;
- int Group;
+ unsigned FolderIndex;
CNum NumCopyFiles;
};
-static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2, void *param)
+/*
+static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2, void *)
{
- RINOZ_COMP(p1->Group, p2->Group);
int i1 = p1->FolderIndex;
int i2 = p2->FolderIndex;
- const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param;
- RINOZ(CompareFolders(
- db.Folders[i1],
- db.Folders[i2]));
+ // In that version we don't want to parse folders here, so we don't compare folders
+ // probably it must be improved in future
+ // const CDbEx &db = *(const CDbEx *)param;
+ // RINOZ(CompareFolders(
+ // db.Folders[i1],
+ // db.Folders[i2]));
+
return MyCompare(i1, i2);
- /*
- RINOZ_COMP(
- db.NumUnpackStreamsVector[i1],
- db.NumUnpackStreamsVector[i2]);
- if (db.NumUnpackStreamsVector[i1] == 0)
- return 0;
- return CompareFiles(
- db.Files[db.FolderStartFileIndex[i1]],
- db.Files[db.FolderStartFileIndex[i2]]);
- */
+
+ // RINOZ_COMP(
+ // db.NumUnpackStreamsVector[i1],
+ // db.NumUnpackStreamsVector[i2]);
+ // if (db.NumUnpackStreamsVector[i1] == 0)
+ // return 0;
+ // return CompareFiles(
+ // db.Files[db.FolderStartFileIndex[i1]],
+ // db.Files[db.FolderStartFileIndex[i2]]);
}
+*/
-////////////////////////////////////////////////////////////
+/*
+ we sort empty files and dirs in such order:
+ - Dir.NonAnti (name sorted)
+ - File.NonAnti (name sorted)
+ - File.Anti (name sorted)
+ - Dir.Anti (reverse name sorted)
+*/
-static int CompareEmptyItems(const int *p1, const int *p2, void *param)
+static int CompareEmptyItems(const unsigned *p1, const unsigned *p2, void *param)
{
const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
const CUpdateItem &u1 = updateItems[*p1];
const CUpdateItem &u2 = updateItems[*p2];
+ // NonAnti < Anti
+ if (u1.IsAnti != u2.IsAnti)
+ return (u1.IsAnti ? 1 : -1);
if (u1.IsDir != u2.IsDir)
- return (u1.IsDir) ? 1 : -1;
- if (u1.IsDir)
{
- if (u1.IsAnti != u2.IsAnti)
+ // Dir.NonAnti < File < Dir.Anti
+ if (u1.IsDir)
return (u1.IsAnti ? 1 : -1);
- int n = MyStringCompareNoCase(u1.Name, u2.Name);
- return -n;
+ return (u2.IsAnti ? -1 : 1);
}
- if (u1.IsAnti != u2.IsAnti)
- return (u1.IsAnti ? 1 : -1);
- return MyStringCompareNoCase(u1.Name, u2.Name);
+ int n = CompareFileNames(u1.Name, u2.Name);
+ return (u1.IsDir && u1.IsAnti) ? -n : n;
}
static const char *g_Exts =
- " lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo"
+ " 7z xz lzma ace arc arj bz tbz bz2 tbz2 cab deb gz tgz ha lha lzh lzo lzx pak rar rpm sit zoo"
" zip jar ear war msi"
" 3gp avi mov mpeg mpg mpe wmv"
" aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"
- " swf "
+ " swf"
" chm hxi hxs"
" gif jpeg jpg jp2 png tiff bmp ico psd psp"
" awg ps eps cgm dxf svg vrml wmf emf ai md"
@@ -182,25 +567,28 @@ static const char *g_Exts =
" iso bin nrg mdf img pdi tar cpio xpi"
" vfd vhd vud vmc vsv"
" vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
- " inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def"
+ " inl inc idl acf asa"
+ " h hpp hxx c cpp cxx m mm go swift"
+ " rc java cs rs pas bas vb cls ctl frm dlg def"
" f77 f f90 f95"
- " asm sql manifest dep "
- " mak clw csproj vcproj sln dsp dsw "
- " class "
- " bat cmd"
+ " asm s"
+ " sql manifest dep"
+ " mak clw csproj vcproj sln dsp dsw"
+ " class"
+ " bat cmd bash sh"
" xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"
- " awk sed hta js php php3 php4 php5 phptml pl pm py pyo rb sh tcl vbs"
+ " awk sed hta js json php php3 php4 php5 phptml pl pm py pyo rb tcl ts vbs"
" text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf"
" sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf"
" abw afp cwk lwp wpd wps wpt wrf wri"
" abf afm bdf fon mgf otf pcf pfa snf ttf"
" dbf mdb nsf ntf wdb db fdb gdb"
- " exe dll ocx vbx sfx sys tlb awx com obj lib out o so "
+ " exe dll ocx vbx sfx sys tlb awx com obj lib out o so"
" pdb pch idb ncb opt";
-int GetExtIndex(const char *ext)
+static unsigned GetExtIndex(const char *ext)
{
- int extIndex = 1;
+ unsigned extIndex = 1;
const char *p = g_Exts;
for (;;)
{
@@ -209,7 +597,7 @@ int GetExtIndex(const char *ext)
return extIndex;
if (c == ' ')
continue;
- int pos = 0;
+ unsigned pos = 0;
for (;;)
{
char c2 = ext[pos++];
@@ -235,9 +623,11 @@ struct CRefItem
{
const CUpdateItem *UpdateItem;
UInt32 Index;
- UInt32 ExtensionPos;
- UInt32 NamePos;
- int ExtensionIndex;
+ unsigned ExtensionPos;
+ unsigned NamePos;
+ unsigned ExtensionIndex;
+
+ CRefItem() {};
CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType):
UpdateItem(&ui),
Index(index),
@@ -247,99 +637,327 @@ struct CRefItem
{
if (sortByType)
{
- int slashPos = GetReverseSlashPos(ui.Name);
- NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0);
- int dotPos = ui.Name.ReverseFind(L'.');
- if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
- ExtensionPos = ui.Name.Length();
+ int slashPos = ui.Name.ReverseFind_PathSepar();
+ NamePos = slashPos + 1;
+ int dotPos = ui.Name.ReverseFind_Dot();
+ if (dotPos <= slashPos)
+ ExtensionPos = ui.Name.Len();
else
{
ExtensionPos = dotPos + 1;
- UString us = ui.Name.Mid(ExtensionPos);
- if (!us.IsEmpty())
+ if (ExtensionPos != ui.Name.Len())
{
- us.MakeLower();
- int i;
AString s;
- for (i = 0; i < us.Length(); i++)
+ for (unsigned pos = ExtensionPos;; pos++)
{
- wchar_t c = us[i];
+ wchar_t c = ui.Name[pos];
if (c >= 0x80)
break;
- s += (char)c;
+ if (c == 0)
+ {
+ ExtensionIndex = GetExtIndex(s);
+ break;
+ }
+ s += (char)MyCharLower_Ascii((char)c);
}
- if (i == us.Length())
- ExtensionIndex = GetExtIndex(s);
- else
- ExtensionIndex = 0;
}
}
}
}
};
+struct CSortParam
+{
+ // const CObjectVector<CTreeFolder> *TreeFolders;
+ bool SortByType;
+};
+
+/*
+ we sort files in such order:
+ - Dir.NonAnti (name sorted)
+ - alt streams
+ - Dirs
+ - Dir.Anti (reverse name sorted)
+*/
+
+
static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param)
{
const CRefItem &a1 = *p1;
const CRefItem &a2 = *p2;
const CUpdateItem &u1 = *a1.UpdateItem;
const CUpdateItem &u2 = *a2.UpdateItem;
- int n;
+
+ /*
+ if (u1.IsAltStream != u2.IsAltStream)
+ return u1.IsAltStream ? 1 : -1;
+ */
+
+ // Actually there are no dirs that time. They were stored in other steps
+ // So that code is unused?
if (u1.IsDir != u2.IsDir)
- return (u1.IsDir) ? 1 : -1;
+ return u1.IsDir ? 1 : -1;
if (u1.IsDir)
{
if (u1.IsAnti != u2.IsAnti)
return (u1.IsAnti ? 1 : -1);
- n = MyStringCompareNoCase(u1.Name, u2.Name);
+ int n = CompareFileNames(u1.Name, u2.Name);
return -n;
}
- bool sortByType = *(bool *)param;
+
+ // bool sortByType = *(bool *)param;
+ const CSortParam *sortParam = (const CSortParam *)param;
+ bool sortByType = sortParam->SortByType;
if (sortByType)
{
RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex);
- RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
- RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
+ RINOZ(CompareFileNames(u1.Name.Ptr(a1.ExtensionPos), u2.Name.Ptr(a2.ExtensionPos)));
+ RINOZ(CompareFileNames(u1.Name.Ptr(a1.NamePos), u2.Name.Ptr(a2.NamePos)));
if (!u1.MTimeDefined && u2.MTimeDefined) return 1;
if (u1.MTimeDefined && !u2.MTimeDefined) return -1;
if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime);
RINOZ_COMP(u1.Size, u2.Size);
}
- return MyStringCompareNoCase(u1.Name, u2.Name);
+ /*
+ int par1 = a1.UpdateItem->ParentFolderIndex;
+ int par2 = a2.UpdateItem->ParentFolderIndex;
+ const CTreeFolder &tf1 = (*sortParam->TreeFolders)[par1];
+ const CTreeFolder &tf2 = (*sortParam->TreeFolders)[par2];
+
+ int b1 = tf1.SortIndex, e1 = tf1.SortIndexEnd;
+ int b2 = tf2.SortIndex, e2 = tf2.SortIndexEnd;
+ if (b1 < b2)
+ {
+ if (e1 <= b2)
+ return -1;
+ // p2 in p1
+ int par = par2;
+ for (;;)
+ {
+ const CTreeFolder &tf = (*sortParam->TreeFolders)[par];
+ par = tf.Parent;
+ if (par == par1)
+ {
+ RINOZ(CompareFileNames(u1.Name, tf.Name));
+ break;
+ }
+ }
+ }
+ else if (b2 < b1)
+ {
+ if (e2 <= b1)
+ return 1;
+ // p1 in p2
+ int par = par1;
+ for (;;)
+ {
+ const CTreeFolder &tf = (*sortParam->TreeFolders)[par];
+ par = tf.Parent;
+ if (par == par2)
+ {
+ RINOZ(CompareFileNames(tf.Name, u2.Name));
+ break;
+ }
+ }
+ }
+ */
+ // RINOZ_COMP(a1.UpdateItem->ParentSortIndex, a2.UpdateItem->ParentSortIndex);
+ RINOK(CompareFileNames(u1.Name, u2.Name));
+ RINOZ_COMP(a1.UpdateItem->IndexInClient, a2.UpdateItem->IndexInClient);
+ RINOZ_COMP(a1.UpdateItem->IndexInArchive, a2.UpdateItem->IndexInArchive);
+ return 0;
}
struct CSolidGroup
{
CRecordVector<UInt32> Indices;
+
+ CRecordVector<CFolderRepack> folderRefs;
};
-static wchar_t *g_ExeExts[] =
+static const char *g_ExeExts[] =
{
- L"dll",
- L"exe",
- L"ocx",
- L"sfx",
- L"sys"
+ "dll"
+ , "exe"
+ , "ocx"
+ , "sfx"
+ , "sys"
};
-static bool IsExeExt(const UString &ext)
+static bool IsExeExt(const wchar_t *ext)
{
- for (int i = 0; i < sizeof(g_ExeExts) / sizeof(g_ExeExts[0]); i++)
- if (ext.CompareNoCase(g_ExeExts[i]) == 0)
+ for (unsigned i = 0; i < ARRAY_SIZE(g_ExeExts); i++)
+ if (StringsAreEqualNoCase_Ascii(ext, g_ExeExts[i]))
return true;
return false;
}
+struct CAnalysis
+{
+ CMyComPtr<IArchiveUpdateCallbackFile> Callback;
+ CByteBuffer Buffer;
+
+ bool ParseWav;
+ bool ParseExe;
+ bool ParseAll;
+
+ CAnalysis():
+ ParseWav(true),
+ ParseExe(false),
+ ParseAll(false)
+ {}
+
+ HRESULT GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMode &filterMode);
+};
+
+static const size_t kAnalysisBufSize = 1 << 14;
+
+HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMode &filterMode)
+{
+ filterMode.Id = 0;
+ filterMode.Delta = 0;
+
+ CFilterMode filterModeTemp = filterMode;
+
+ int slashPos = ui.Name.ReverseFind_PathSepar();
+ int dotPos = ui.Name.ReverseFind_Dot();
-static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &m)
+ // if (dotPos > slashPos)
+ {
+ bool needReadFile = ParseAll;
+
+ bool probablyIsSameIsa = false;
+
+ if (!needReadFile || !Callback)
+ {
+ const wchar_t *ext;
+ if (dotPos > slashPos)
+ ext = ui.Name.Ptr(dotPos + 1);
+ else
+ ext = ui.Name.RightPtr(0);
+
+ // p7zip uses the trick to store posix attributes in high 16 bits
+ if (ui.Attrib & 0x8000)
+ {
+ unsigned st_mode = ui.Attrib >> 16;
+ // st_mode = 00111;
+ if ((st_mode & 00111) && (ui.Size >= 2048))
+ {
+ #ifndef _WIN32
+ probablyIsSameIsa = true;
+ #endif
+ needReadFile = true;
+ }
+ }
+
+ if (IsExeExt(ext))
+ {
+ needReadFile = true;
+ #ifdef _WIN32
+ probablyIsSameIsa = true;
+ needReadFile = ParseExe;
+ #endif
+ }
+ else if (StringsAreEqualNoCase_Ascii(ext, "wav"))
+ {
+ needReadFile = ParseWav;
+ }
+ /*
+ else if (!needReadFile && ParseUnixExt)
+ {
+ if (StringsAreEqualNoCase_Ascii(ext, "so")
+ || StringsAreEqualNoCase_Ascii(ext, ""))
+
+ needReadFile = true;
+ }
+ */
+ }
+
+ if (needReadFile && Callback)
+ {
+ if (Buffer.Size() != kAnalysisBufSize)
+ {
+ Buffer.Alloc(kAnalysisBufSize);
+ }
+ {
+ CMyComPtr<ISequentialInStream> stream;
+ HRESULT result = Callback->GetStream2(index, &stream, NUpdateNotifyOp::kAnalyze);
+ if (result == S_OK && stream)
+ {
+ size_t size = kAnalysisBufSize;
+ result = ReadStream(stream, Buffer, &size);
+ stream.Release();
+ // RINOK(Callback->SetOperationResult2(index, NUpdate::NOperationResult::kOK));
+ if (result == S_OK)
+ {
+ Bool parseRes = ParseFile(Buffer, size, &filterModeTemp);
+ if (parseRes && filterModeTemp.Delta == 0)
+ {
+ filterModeTemp.SetDelta();
+ if (filterModeTemp.Delta != 0 && filterModeTemp.Id != k_Delta)
+ {
+ if (ui.Size % filterModeTemp.Delta != 0)
+ {
+ parseRes = false;
+ }
+ }
+ }
+ if (!parseRes)
+ {
+ filterModeTemp.Id = 0;
+ filterModeTemp.Delta = 0;
+ }
+ }
+ }
+ }
+ }
+ else if ((needReadFile && !Callback) || probablyIsSameIsa)
+ {
+ #ifdef MY_CPU_X86_OR_AMD64
+ if (probablyIsSameIsa)
+ filterModeTemp.Id = k_X86;
+ #endif
+ }
+ }
+
+ filterMode = filterModeTemp;
+ return S_OK;
+}
+
+static inline void GetMethodFull(UInt64 methodID, UInt32 numStreams, CMethodFull &m)
{
m.Id = methodID;
- m.NumInStreams = numInStreams;
- m.NumOutStreams = 1;
+ m.NumStreams = numStreams;
}
-static void AddBcj2Methods(CCompressionMethodMode &mode)
+static HRESULT AddBondForFilter(CCompressionMethodMode &mode)
{
+ for (unsigned c = 1; c < mode.Methods.Size(); c++)
+ {
+ if (!mode.IsThereBond_to_Coder(c))
+ {
+ CBond2 bond;
+ bond.OutCoder = 0;
+ bond.OutStream = 0;
+ bond.InCoder = c;
+ mode.Bonds.Add(bond);
+ return S_OK;
+ }
+ }
+ return E_INVALIDARG;
+}
+
+static HRESULT AddFilterBond(CCompressionMethodMode &mode)
+{
+ if (!mode.Bonds.IsEmpty())
+ return AddBondForFilter(mode);
+ return S_OK;
+}
+
+static HRESULT AddBcj2Methods(CCompressionMethodMode &mode)
+{
+ // mode.Methods[0] must be k_BCJ2 method !
+
CMethodFull m;
GetMethodFull(k_LZMA, 1, m);
@@ -348,61 +966,127 @@ static void AddBcj2Methods(CCompressionMethodMode &mode)
m.AddProp32(NCoderPropID::kNumThreads, 1);
m.AddProp32(NCoderPropID::kLitPosBits, 2);
m.AddProp32(NCoderPropID::kLitContextBits, 0);
- // m.AddPropString(NCoderPropID::kMatchFinder, L"BT2");
+ // m.AddProp_Ascii(NCoderPropID::kMatchFinder, "BT2");
+
+ unsigned methodIndex = mode.Methods.Size();
+
+ if (mode.Bonds.IsEmpty())
+ {
+ for (unsigned i = 1; i + 1 < mode.Methods.Size(); i++)
+ {
+ CBond2 bond;
+ bond.OutCoder = i;
+ bond.OutStream = 0;
+ bond.InCoder = i + 1;
+ mode.Bonds.Add(bond);
+ }
+ }
mode.Methods.Add(m);
mode.Methods.Add(m);
- CBind bind;
- bind.OutCoder = 0;
- bind.InStream = 0;
- bind.InCoder = 1; bind.OutStream = 0; mode.Binds.Add(bind);
- bind.InCoder = 2; bind.OutStream = 1; mode.Binds.Add(bind);
- bind.InCoder = 3; bind.OutStream = 2; mode.Binds.Add(bind);
+ RINOK(AddBondForFilter(mode));
+ CBond2 bond;
+ bond.OutCoder = 0;
+ bond.InCoder = methodIndex; bond.OutStream = 1; mode.Bonds.Add(bond);
+ bond.InCoder = methodIndex + 1; bond.OutStream = 2; mode.Bonds.Add(bond);
+ return S_OK;
}
-static void MakeExeMethod(CCompressionMethodMode &mode,
- bool useFilters, bool addFilter, bool bcj2Filter)
+static HRESULT MakeExeMethod(CCompressionMethodMode &mode,
+ const CFilterMode &filterMode, /* bool addFilter, */ bool bcj2Filter)
{
- if (!mode.Binds.IsEmpty() || !useFilters || mode.Methods.Size() > 2)
- return;
- if (mode.Methods.Size() == 2)
+ if (mode.Filter_was_Inserted)
+ {
+ const CMethodFull &m = mode.Methods[0];
+ CMethodId id = m.Id;
+ if (id == k_BCJ2)
+ return AddBcj2Methods(mode);
+ if (!m.IsSimpleCoder())
+ return E_NOTIMPL;
+ // if (Bonds.IsEmpty()) we can create bonds later
+ return AddFilterBond(mode);
+ }
+
+ if (filterMode.Id == 0)
+ return S_OK;
+
+ CMethodFull &m = mode.Methods.InsertNew(0);
+
{
- if (mode.Methods[0].Id == k_BCJ2)
- AddBcj2Methods(mode);
- return;
+ FOR_VECTOR(k, mode.Bonds)
+ {
+ CBond2 &bond = mode.Bonds[k];
+ bond.InCoder++;
+ bond.OutCoder++;
+ }
}
- if (!addFilter)
- return;
- bcj2Filter = bcj2Filter;
- #ifdef USE_86_FILTER
- if (bcj2Filter)
+
+ HRESULT res;
+
+ if (bcj2Filter && Is86Filter(filterMode.Id))
{
- CMethodFull m;
GetMethodFull(k_BCJ2, 4, m);
- mode.Methods.Insert(0, m);
- AddBcj2Methods(mode);
+ res = AddBcj2Methods(mode);
}
else
{
- CMethodFull m;
- GetMethodFull(k_BCJ, 1, m);
- mode.Methods.Insert(0, m);
- CBind bind;
- bind.OutCoder = 0;
- bind.InStream = 0;
- bind.InCoder = 1;
- bind.OutStream = 0;
- mode.Binds.Add(bind);
+ GetMethodFull(filterMode.Id, 1, m);
+ if (filterMode.Id == k_Delta)
+ m.AddProp32(NCoderPropID::kDefaultProp, filterMode.Delta);
+ res = AddFilterBond(mode);
+
+ int alignBits = -1;
+ if (filterMode.Id == k_Delta || filterMode.Delta != 0)
+ {
+ if (filterMode.Delta == 1) alignBits = 0;
+ else if (filterMode.Delta == 2) alignBits = 1;
+ else if (filterMode.Delta == 4) alignBits = 2;
+ else if (filterMode.Delta == 8) alignBits = 3;
+ else if (filterMode.Delta == 16) alignBits = 4;
+ }
+ else
+ {
+ // alignBits = GetAlignForFilterMethod(filterMode.Id);
+ }
+
+ if (res == S_OK && alignBits >= 0)
+ {
+ unsigned nextCoder = 1;
+ if (!mode.Bonds.IsEmpty())
+ {
+ nextCoder = mode.Bonds.Back().InCoder;
+ }
+ if (nextCoder < mode.Methods.Size())
+ {
+ CMethodFull &nextMethod = mode.Methods[nextCoder];
+ if (nextMethod.Id == k_LZMA || nextMethod.Id == k_LZMA2)
+ {
+ if (!nextMethod.Are_Lzma_Model_Props_Defined())
+ {
+ if (alignBits != 0)
+ {
+ if (alignBits > 2 || filterMode.Id == k_Delta)
+ nextMethod.AddProp32(NCoderPropID::kPosStateBits, alignBits);
+ unsigned lc = 0;
+ if (alignBits < 3)
+ lc = 3 - alignBits;
+ nextMethod.AddProp32(NCoderPropID::kLitContextBits, lc);
+ nextMethod.AddProp32(NCoderPropID::kLitPosBits, alignBits);
+ }
+ }
+ }
+ }
+ }
}
- #endif
+
+ return res;
}
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
CFileItem &file, CFileItem2 &file2)
{
- file.Name = NItemName::MakeLegalName(ui.Name);
if (ui.AttribDefined)
file.SetAttrib(ui.Attrib);
@@ -410,140 +1094,345 @@ static void FromUpdateItemToFileItem(const CUpdateItem &ui,
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;
file.Size = ui.Size;
file.IsDir = ui.IsDir;
file.HasStream = ui.HasStream();
+ // file.IsAltStream = ui.IsAltStream;
}
-class CFolderOutStream2:
- public ISequentialOutStream,
+class CRepackInStreamWithSizes:
+ public ISequentialInStream,
+ public ICompressGetSubStreamSize,
public CMyUnknownImp
{
- COutStreamWithCRC *_crcStreamSpec;
- CMyComPtr<ISequentialOutStream> _crcStream;
- const CArchiveDatabaseEx *_db;
+ CMyComPtr<ISequentialInStream> _stream;
+ // UInt64 _size;
const CBoolVector *_extractStatuses;
- CMyComPtr<ISequentialOutStream> _outStream;
UInt32 _startIndex;
- int _currentIndex;
+public:
+ const CDbEx *_db;
+
+ void Init(ISequentialInStream *stream, UInt32 startIndex, const CBoolVector *extractStatuses)
+ {
+ _startIndex = startIndex;
+ _extractStatuses = extractStatuses;
+ // _size = 0;
+ _stream = stream;
+ }
+ // UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
+ STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
+};
+
+STDMETHODIMP CRepackInStreamWithSizes::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ return _stream->Read(data, size, processedSize);
+ /*
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize)
+ *processedSize = realProcessedSize;
+ return result;
+ */
+}
+
+STDMETHODIMP CRepackInStreamWithSizes::GetSubStreamSize(UInt64 subStream, UInt64 *value)
+{
+ *value = 0;
+ if (subStream >= _extractStatuses->Size())
+ return S_FALSE; // E_FAIL;
+ unsigned index = (unsigned)subStream;
+ if ((*_extractStatuses)[index])
+ {
+ const CFileItem &fi = _db->Files[_startIndex + index];
+ if (fi.HasStream)
+ *value = fi.Size;
+ }
+ return S_OK;
+}
+
+
+class CRepackStreamBase
+{
+protected:
+ bool _needWrite;
bool _fileIsOpen;
+ bool _calcCrc;
+ UInt32 _crc;
UInt64 _rem;
- void OpenFile();
- void CloseFile();
- HRESULT CloseFileAndSetResult();
+ const CBoolVector *_extractStatuses;
+ UInt32 _startIndex;
+ unsigned _currentIndex;
+
+ HRESULT OpenFile();
+ HRESULT CloseFile();
HRESULT ProcessEmptyFiles();
+
public:
- MY_UNKNOWN_IMP
-
- CFolderOutStream2()
- {
- _crcStreamSpec = new COutStreamWithCRC;
- _crcStream = _crcStreamSpec;
- }
+ const CDbEx *_db;
+ CMyComPtr<IArchiveUpdateCallbackFile> _opCallback;
+ CMyComPtr<IArchiveExtractCallbackMessage> _extractCallback;
- HRESULT Init(const CArchiveDatabaseEx *db, UInt32 startIndex,
- const CBoolVector *extractStatuses, ISequentialOutStream *outStream);
- void ReleaseOutStream();
+ HRESULT Init(UInt32 startIndex, const CBoolVector *extractStatuses);
HRESULT CheckFinishedState() const { return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; }
-
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
-HRESULT CFolderOutStream2::Init(const CArchiveDatabaseEx *db, UInt32 startIndex,
- const CBoolVector *extractStatuses, ISequentialOutStream *outStream)
+HRESULT CRepackStreamBase::Init(UInt32 startIndex, const CBoolVector *extractStatuses)
{
- _db = db;
_startIndex = startIndex;
_extractStatuses = extractStatuses;
- _outStream = outStream;
_currentIndex = 0;
_fileIsOpen = false;
+
return ProcessEmptyFiles();
}
-void CFolderOutStream2::ReleaseOutStream()
+HRESULT CRepackStreamBase::OpenFile()
{
- _outStream.Release();
- _crcStreamSpec->ReleaseStream();
-}
+ UInt32 arcIndex = _startIndex + _currentIndex;
+ const CFileItem &fi = _db->Files[arcIndex];
+
+ _needWrite = (*_extractStatuses)[_currentIndex];
+ if (_opCallback)
+ {
+ RINOK(_opCallback->ReportOperation(
+ NEventIndexType::kInArcIndex, arcIndex,
+ _needWrite ?
+ NUpdateNotifyOp::kRepack :
+ NUpdateNotifyOp::kSkip));
+ }
+
+ _crc = CRC_INIT_VAL;
+ _calcCrc = (fi.CrcDefined && !fi.IsDir);
-void CFolderOutStream2::OpenFile()
-{
- _crcStreamSpec->SetStream((*_extractStatuses)[_currentIndex] ? _outStream : NULL);
- _crcStreamSpec->Init(true);
_fileIsOpen = true;
- _rem = _db->Files[_startIndex + _currentIndex].Size;
+ _rem = fi.Size;
+ return S_OK;
}
-void CFolderOutStream2::CloseFile()
+const HRESULT k_My_HRESULT_CRC_ERROR = 0x20000002;
+
+HRESULT CRepackStreamBase::CloseFile()
{
- _crcStreamSpec->ReleaseStream();
+ UInt32 arcIndex = _startIndex + _currentIndex;
+ const CFileItem &fi = _db->Files[arcIndex];
_fileIsOpen = false;
_currentIndex++;
-}
+ if (!_calcCrc || fi.Crc == CRC_GET_DIGEST(_crc))
+ return S_OK;
-HRESULT CFolderOutStream2::CloseFileAndSetResult()
-{
- const CFileItem &file = _db->Files[_startIndex + _currentIndex];
- CloseFile();
- return (file.IsDir || !file.CrcDefined || file.Crc == _crcStreamSpec->GetCRC()) ? S_OK: S_FALSE;
+ if (_extractCallback)
+ {
+ RINOK(_extractCallback->ReportExtractResult(
+ NEventIndexType::kInArcIndex, arcIndex,
+ NExtract::NOperationResult::kCRCError));
+ }
+ // return S_FALSE;
+ return k_My_HRESULT_CRC_ERROR;
}
-HRESULT CFolderOutStream2::ProcessEmptyFiles()
+HRESULT CRepackStreamBase::ProcessEmptyFiles()
{
while (_currentIndex < _extractStatuses->Size() && _db->Files[_startIndex + _currentIndex].Size == 0)
{
- OpenFile();
- RINOK(CloseFileAndSetResult());
+ RINOK(OpenFile());
+ RINOK(CloseFile());
}
return S_OK;
}
+
+
+
+#ifndef _7ZIP_ST
+
+class CFolderOutStream2:
+ public CRepackStreamBase,
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ CMyComPtr<ISequentialOutStream> _stream;
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
STDMETHODIMP CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
+
while (size != 0)
{
if (_fileIsOpen)
{
- UInt32 cur = size < _rem ? size : (UInt32)_rem;
- RINOK(_crcStream->Write(data, cur, &cur));
- if (cur == 0)
- break;
+ UInt32 cur = (size < _rem ? size : (UInt32)_rem);
+ HRESULT result = S_OK;
+ if (_needWrite)
+ result = _stream->Write(data, cur, &cur);
+ if (_calcCrc)
+ _crc = CrcUpdate(_crc, data, cur);
+ if (processedSize)
+ *processedSize += cur;
data = (const Byte *)data + cur;
size -= cur;
_rem -= cur;
- if (processedSize != NULL)
- *processedSize += cur;
if (_rem == 0)
{
- RINOK(CloseFileAndSetResult());
+ RINOK(CloseFile());
RINOK(ProcessEmptyFiles());
- continue;
}
+ RINOK(result);
+ if (cur == 0)
+ break;
+ continue;
}
- else
+
+ RINOK(ProcessEmptyFiles());
+ if (_currentIndex == _extractStatuses->Size())
+ {
+ // we don't support write cut here
+ return E_FAIL;
+ }
+ RINOK(OpenFile());
+ }
+
+ return S_OK;
+}
+
+#endif
+
+
+
+static const UInt32 kTempBufSize = 1 << 16;
+
+class CFolderInStream2:
+ public CRepackStreamBase,
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ Byte *_buf;
+public:
+ CMyComPtr<ISequentialInStream> _inStream;
+ HRESULT Result;
+
+ MY_UNKNOWN_IMP
+
+ CFolderInStream2():
+ Result(S_OK)
+ {
+ _buf = new Byte[kTempBufSize];
+ }
+
+ ~CFolderInStream2()
+ {
+ delete []_buf;
+ }
+
+ void Init() { Result = S_OK; }
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+
+ while (size != 0)
+ {
+ if (_fileIsOpen)
{
- RINOK(ProcessEmptyFiles());
- if (_currentIndex == _extractStatuses->Size())
+ UInt32 cur = (size < _rem ? size : (UInt32)_rem);
+
+ void *buf;
+ if (_needWrite)
+ buf = data;
+ else
{
- // we don't support partial extracting
- return E_FAIL;
+ buf = _buf;
+ if (cur > kTempBufSize)
+ cur = kTempBufSize;
+ }
+
+ HRESULT result = _inStream->Read(buf, cur, &cur);
+ _crc = CrcUpdate(_crc, buf, cur);
+ _rem -= cur;
+
+ if (_needWrite)
+ {
+ data = (Byte *)data + cur;
+ size -= cur;
+ if (processedSize)
+ *processedSize += cur;
+ }
+
+ if (result != S_OK)
+ Result = result;
+
+ if (_rem == 0)
+ {
+ RINOK(CloseFile());
+ RINOK(ProcessEmptyFiles());
}
- OpenFile();
+
+ RINOK(result);
+
+ if (cur == 0)
+ return E_FAIL;
+
+ continue;
+ }
+
+ RINOK(ProcessEmptyFiles());
+ if (_currentIndex == _extractStatuses->Size())
+ {
+ return S_OK;
}
+ RINOK(OpenFile());
}
+
return S_OK;
}
-class CThreadDecoder: public CVirtThread
+
+class CThreadDecoder
+ #ifndef _7ZIP_ST
+ : public CVirtThread
+ #endif
{
public:
+ CDecoder Decoder;
+
+ CThreadDecoder(bool multiThreadMixer):
+ Decoder(multiThreadMixer)
+ {
+ #ifndef _7ZIP_ST
+ if (multiThreadMixer)
+ {
+ MtMode = false;
+ NumThreads = 1;
+ FosSpec = new CFolderOutStream2;
+ Fos = FosSpec;
+ Result = E_FAIL;
+ }
+ #endif
+ // UnpackSize = 0;
+ // send_UnpackSize = false;
+ }
+
+ #ifndef _7ZIP_ST
+
HRESULT Result;
CMyComPtr<IInStream> InStream;
@@ -551,55 +1440,58 @@ public:
CMyComPtr<ISequentialOutStream> Fos;
UInt64 StartPos;
- const UInt64 *PackSizes;
- const CFolder *Folder;
+ const CFolders *Folders;
+ int FolderIndex;
+
+ // bool send_UnpackSize;
+ // UInt64 UnpackSize;
+
#ifndef _NO_CRYPTO
- CMyComPtr<ICryptoGetTextPassword> GetTextPassword;
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
#endif
- DECL_EXTERNAL_CODECS_VARS
- CDecoder Decoder;
+ DECL_EXTERNAL_CODECS_LOC_VARS2;
#ifndef _7ZIP_ST
bool MtMode;
UInt32 NumThreads;
#endif
- CThreadDecoder():
- Decoder(true)
- {
- #ifndef _7ZIP_ST
- MtMode = false;
- NumThreads = 1;
- #endif
- FosSpec = new CFolderOutStream2;
- Fos = FosSpec;
- Result = E_FAIL;
- }
+
~CThreadDecoder() { CVirtThread::WaitThreadFinish(); }
virtual void Execute();
+
+ #endif
};
+#ifndef _7ZIP_ST
+
void CThreadDecoder::Execute()
{
try
{
#ifndef _NO_CRYPTO
- bool passwordIsDefined;
+ bool isEncrypted = false;
+ bool passwordIsDefined = false;
+ UString password;
#endif
+
Result = Decoder.Decode(
- EXTERNAL_CODECS_VARS
+ EXTERNAL_CODECS_LOC_VARS
InStream,
StartPos,
- PackSizes,
- *Folder,
+ *Folders, FolderIndex,
+
+ // send_UnpackSize ? &UnpackSize : NULL,
+ NULL, // unpackSize : FULL unpack
+
Fos,
- NULL
- #ifndef _NO_CRYPTO
- , GetTextPassword, passwordIsDefined
- #endif
+ NULL, // compressProgress
+ NULL // *inStreamMainRes
+
+ _7Z_DECODER_CRYPRO_VARS
#ifndef _7ZIP_ST
- , MtMode, NumThreads
+ , MtMode, NumThreads
#endif
);
}
@@ -607,21 +1499,15 @@ void CThreadDecoder::Execute()
{
Result = E_FAIL;
}
+
+ /*
if (Result == S_OK)
Result = FosSpec->CheckFinishedState();
- FosSpec->ReleaseOutStream();
+ */
+ FosSpec->_stream.Release();
}
-bool static Is86FilteredFolder(const CFolder &f)
-{
- for (int i = 0; i < f.Coders.Size(); i++)
- {
- CMethodId m = f.Coders[i].MethodID;
- if (m == k_BCJ || m == k_BCJ2)
- return true;
- }
- return false;
-}
+#endif
#ifndef _NO_CRYPTO
@@ -643,20 +1529,27 @@ STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password)
#endif
-static const int kNumGroupsMax = 4;
-static bool Is86Group(int group) { return (group & 1) != 0; }
-static bool IsEncryptedGroup(int group) { return (group & 2) != 0; }
-static int GetGroupIndex(bool encrypted, int bcjFiltered)
- { return (encrypted ? 2 : 0) + (bcjFiltered ? 1 : 0); }
+static void GetFile(const CDatabase &inDb, unsigned index, CFileItem &file, CFileItem2 &file2)
+{
+ file = inDb.Files[index];
+ file2.CTimeDefined = inDb.CTime.GetItem(index, file2.CTime);
+ 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.IsAnti = inDb.IsItemAnti(index);
+ // file2.IsAux = inDb.IsItemAux(index);
+}
HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
- const CArchiveDatabaseEx *db,
+ const CDbEx *db,
const CObjectVector<CUpdateItem> &updateItems,
+ // const CObjectVector<CTreeFolder> &treeFolders,
+ // const CUniqBlocks &secureBlocks,
COutArchive &archive,
- CArchiveDatabase &newDatabase,
+ CArchiveDatabaseOut &newDatabase,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options
@@ -668,6 +1561,15 @@ HRESULT Update(
UInt64 numSolidFiles = options.NumSolidFiles;
if (numSolidFiles == 0)
numSolidFiles = 1;
+
+ CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
+ updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
+
+ CMyComPtr<IArchiveExtractCallbackMessage> extractCallback;
+ updateCallback->QueryInterface(IID_IArchiveExtractCallbackMessage, (void **)&extractCallback);
+
+ // size_t totalSecureDataSize = (size_t)secureBlocks.GetTotalSizeInBytes();
+
/*
CMyComPtr<IOutStream> outStream;
RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream));
@@ -675,37 +1577,43 @@ HRESULT Update(
return E_NOTIMPL;
*/
- UInt64 startBlockSize = db != 0 ? db->ArchiveInfo.StartPosition: 0;
+ UInt64 startBlockSize = db != 0 ? db->ArcInfo.StartPosition: 0;
if (startBlockSize > 0 && !options.RemoveSfxBlock)
{
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
}
- CRecordVector<int> fileIndexToUpdateIndexMap;
- CRecordVector<CFolderRepack> folderRefs;
+ CIntArr fileIndexToUpdateIndexMap;
UInt64 complexity = 0;
UInt64 inSizeForReduce2 = 0;
bool needEncryptedRepack = false;
+
+ CRecordVector<CFilterMode2> filters;
+ CObjectVector<CSolidGroup> groups;
+ bool thereAreRepacks = false;
+
if (db != 0)
{
- fileIndexToUpdateIndexMap.Reserve(db->Files.Size());
- int i;
+ fileIndexToUpdateIndexMap.Alloc(db->Files.Size());
+ unsigned i;
+
for (i = 0; i < db->Files.Size(); i++)
- fileIndexToUpdateIndexMap.Add(-1);
+ fileIndexToUpdateIndexMap[i] = -1;
for (i = 0; i < updateItems.Size(); i++)
{
int index = updateItems[i].IndexInArchive;
if (index != -1)
- fileIndexToUpdateIndexMap[index] = i;
+ fileIndexToUpdateIndexMap[(unsigned)index] = i;
}
- for (i = 0; i < db->Folders.Size(); i++)
+ for (i = 0; i < db->NumFolders; i++)
{
CNum indexInFolder = 0;
CNum numCopyItems = 0;
CNum numUnpackStreams = db->NumUnpackStreamsVector[i];
UInt64 repackSize = 0;
+
for (CNum fi = db->FolderStartFileIndex[i]; indexInFolder < numUnpackStreams; fi++)
{
const CFileItem &file = db->Files[fi];
@@ -727,26 +1635,34 @@ HRESULT Update(
CFolderRepack rep;
rep.FolderIndex = i;
rep.NumCopyFiles = numCopyItems;
- const CFolder &f = db->Folders[i];
+ CFolderEx f;
+ db->ParseFolderEx(i, f);
+
bool isEncrypted = f.IsEncrypted();
- rep.Group = GetGroupIndex(isEncrypted, Is86FilteredFolder(f));
- folderRefs.Add(rep);
+
+ unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f);
+
+ while (groupIndex >= groups.Size())
+ groups.AddNew();
+
+ groups[groupIndex].folderRefs.Add(rep);
+
if (numCopyItems == numUnpackStreams)
complexity += db->GetFolderFullPackSize(i);
else
{
+ thereAreRepacks = true;
complexity += repackSize;
- if (repackSize > inSizeForReduce2)
+ if (inSizeForReduce2 < repackSize)
inSizeForReduce2 = repackSize;
if (isEncrypted)
needEncryptedRepack = true;
}
}
- folderRefs.Sort(CompareFolderRepacks, (void *)db);
}
UInt64 inSizeForReduce = 0;
- int i;
+ unsigned i;
for (i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &ui = updateItems[i];
@@ -755,12 +1671,12 @@ HRESULT Update(
complexity += ui.Size;
if (numSolidFiles != 1)
inSizeForReduce += ui.Size;
- else if (ui.Size > inSizeForReduce)
+ else if (inSizeForReduce < ui.Size)
inSizeForReduce = ui.Size;
}
}
- if (inSizeForReduce2 > inSizeForReduce)
+ if (inSizeForReduce < inSizeForReduce2)
inSizeForReduce = inSizeForReduce2;
RINOK(updateCallback->SetTotal(complexity));
@@ -769,53 +1685,102 @@ HRESULT Update(
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
+ #ifndef _7ZIP_ST
+
CStreamBinder sb;
- RINOK(sb.CreateEvents());
+ if (options.MultiThreadMixer)
+ {
+ RINOK(sb.CreateEvents());
+ }
+
+ #endif
- CThreadDecoder threadDecoder;
- if (!folderRefs.IsEmpty())
+ CThreadDecoder threadDecoder(options.MultiThreadMixer);
+
+ #ifndef _7ZIP_ST
+ if (options.MultiThreadMixer && thereAreRepacks)
{
#ifdef EXTERNAL_CODECS
- threadDecoder._codecsInfo = codecsInfo;
- threadDecoder._externalCodecs = *externalCodecs;
+ threadDecoder.__externalCodecs = __externalCodecs;
#endif
RINOK(threadDecoder.Create());
}
-
- CObjectVector<CSolidGroup> groups;
- for (i = 0; i < kNumGroupsMax; i++)
- groups.Add(CSolidGroup());
+ #endif
{
- // ---------- Split files to 2 groups ----------
+ CAnalysis analysis;
+ if (options.AnalysisLevel == 0)
+ {
+ analysis.ParseWav = false;
+ analysis.ParseExe = false;
+ analysis.ParseAll = false;
+ }
+ else
+ {
+ analysis.Callback = opCallback;
+ if (options.AnalysisLevel > 0)
+ {
+ analysis.ParseWav = true;
+ if (options.AnalysisLevel >= 7)
+ {
+ analysis.ParseExe = true;
+ if (options.AnalysisLevel >= 9)
+ analysis.ParseAll = true;
+ }
+ }
+ }
+
+ // ---------- Split files to groups ----------
bool useFilters = options.UseFilters;
const CCompressionMethodMode &method = *options.Method;
- if (method.Methods.Size() != 1 || method.Binds.Size() != 0)
+
+ if (useFilters)
+ for (i = 0; i < method.Methods.Size(); i++)
+ if (IsFilterMethod(method.Methods[i].Id))
+ {
+ useFilters = false;
+ break;
+ }
+
+ /*
+ if (!method.Bonds.IsEmpty())
useFilters = false;
+ */
+
for (i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &ui = updateItems[i];
if (!ui.NewData || !ui.HasStream())
continue;
- bool filteredGroup = false;
+
+ CFilterMode2 fm;
if (useFilters)
{
- int dotPos = ui.Name.ReverseFind(L'.');
- if (dotPos >= 0)
- filteredGroup = IsExeExt(ui.Name.Mid(dotPos + 1));
+ RINOK(analysis.GetFilterGroup(i, ui, fm));
}
- groups[GetGroupIndex(method.PasswordIsDefined, filteredGroup)].Indices.Add(i);
+ fm.Encrypted = method.PasswordIsDefined;
+
+ unsigned groupIndex = GetGroup(filters, fm);
+ while (groupIndex >= groups.Size())
+ groups.AddNew();
+ groups[groupIndex].Indices.Add(i);
}
}
+
#ifndef _NO_CRYPTO
CCryptoGetTextPassword *getPasswordSpec = NULL;
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (needEncryptedRepack)
{
getPasswordSpec = new CCryptoGetTextPassword;
- threadDecoder.GetTextPassword = getPasswordSpec;
+ getTextPassword = getPasswordSpec;
+
+ #ifndef _7ZIP_ST
+ threadDecoder.getTextPassword = getPasswordSpec;
+ #endif
if (options.Method->PasswordIsDefined)
getPasswordSpec->Password = options.Method->Password;
@@ -825,28 +1790,141 @@ HRESULT Update(
return E_NOTIMPL;
CMyComBSTR password;
RINOK(getDecoderPassword->CryptoGetTextPassword(&password));
- getPasswordSpec->Password = password;
+ if (password)
+ getPasswordSpec->Password = password;
}
}
#endif
+
// ---------- Compress ----------
RINOK(archive.Create(seqOutStream, false));
RINOK(archive.SkipPrefixArchiveHeader());
- int folderRefIndex = 0;
+ /*
+ CIntVector treeFolderToArcIndex;
+ treeFolderToArcIndex.Reserve(treeFolders.Size());
+ for (i = 0; i < treeFolders.Size(); i++)
+ treeFolderToArcIndex.Add(-1);
+ // ---------- Write Tree (only AUX dirs) ----------
+ for (i = 1; i < treeFolders.Size(); i++)
+ {
+ const CTreeFolder &treeFolder = treeFolders[i];
+ CFileItem file;
+ CFileItem2 file2;
+ file2.Init();
+ int secureID = 0;
+ if (treeFolder.UpdateItemIndex < 0)
+ {
+ // we can store virtual dir item wuthout attrib, but we want all items have attrib.
+ file.SetAttrib(FILE_ATTRIBUTE_DIRECTORY);
+ file2.IsAux = true;
+ }
+ else
+ {
+ const CUpdateItem &ui = updateItems[treeFolder.UpdateItemIndex];
+ // if item is not dir, then it's parent for alt streams.
+ // we will write such items later
+ if (!ui.IsDir)
+ continue;
+ secureID = ui.SecureIndex;
+ if (ui.NewProps)
+ FromUpdateItemToFileItem(ui, file, file2);
+ else
+ GetFile(*db, ui.IndexInArchive, file, file2);
+ }
+ file.Size = 0;
+ file.HasStream = false;
+ file.IsDir = true;
+ file.Parent = treeFolder.Parent;
+
+ treeFolderToArcIndex[i] = newDatabase.Files.Size();
+ newDatabase.AddFile(file, file2, treeFolder.Name);
+
+ if (totalSecureDataSize != 0)
+ newDatabase.SecureIDs.Add(secureID);
+ }
+ */
+
+ {
+ /* ---------- Write non-AUX dirs and Empty files ---------- */
+ CUIntVector emptyRefs;
+
+ for (i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &ui = updateItems[i];
+ if (ui.NewData)
+ {
+ if (ui.HasStream())
+ continue;
+ }
+ else if (ui.IndexInArchive != -1 && db->Files[ui.IndexInArchive].HasStream)
+ continue;
+ /*
+ if (ui.TreeFolderIndex >= 0)
+ continue;
+ */
+ emptyRefs.Add(i);
+ }
+
+ emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
+
+ for (i = 0; i < emptyRefs.Size(); i++)
+ {
+ const CUpdateItem &ui = updateItems[emptyRefs[i]];
+ CFileItem file;
+ CFileItem2 file2;
+ UString name;
+ if (ui.NewProps)
+ {
+ FromUpdateItemToFileItem(ui, file, file2);
+ name = ui.Name;
+ }
+ else
+ {
+ GetFile(*db, ui.IndexInArchive, file, file2);
+ db->GetPath(ui.IndexInArchive, name);
+ }
+
+ /*
+ if (totalSecureDataSize != 0)
+ newDatabase.SecureIDs.Add(ui.SecureIndex);
+ file.Parent = ui.ParentFolderIndex;
+ */
+ newDatabase.AddFile(file, file2, name);
+ }
+ }
+
lps->ProgressOffset = 0;
- for (int groupIndex = 0; groupIndex < kNumGroupsMax; groupIndex++)
{
- const CSolidGroup &group = groups[groupIndex];
+ // ---------- Sort Filters ----------
+
+ FOR_VECTOR (i, filters)
+ {
+ filters[i].GroupIndex = i;
+ }
+ filters.Sort2();
+ }
+
+ for (unsigned groupIndex = 0; groupIndex < filters.Size(); groupIndex++)
+ {
+ const CFilterMode2 &filterMode = filters[groupIndex];
CCompressionMethodMode method = *options.Method;
- MakeExeMethod(method, options.UseFilters, Is86Group(groupIndex), options.MaxFilter);
+ HRESULT res = MakeExeMethod(method, filterMode,
+ #ifdef _7ZIP_ST
+ false
+ #else
+ options.MaxFilter && options.MultiThreadMixer
+ #endif
+ );
- if (IsEncryptedGroup(groupIndex))
+ RINOK(res);
+
+ if (filterMode.Encrypted)
{
if (!method.PasswordIsDefined)
{
@@ -865,95 +1943,276 @@ HRESULT Update(
CEncoder encoder(method);
- for (; folderRefIndex < folderRefs.Size(); folderRefIndex++)
+ // ---------- Repack and copy old solid blocks ----------
+
+ const CSolidGroup &group = groups[filterMode.GroupIndex];
+
+ FOR_VECTOR(folderRefIndex, group.folderRefs)
{
- const CFolderRepack &rep = folderRefs[folderRefIndex];
- if (rep.Group != groupIndex)
- break;
- int folderIndex = rep.FolderIndex;
+ const CFolderRepack &rep = group.folderRefs[folderRefIndex];
+
+ unsigned folderIndex = rep.FolderIndex;
- if (rep.NumCopyFiles == db->NumUnpackStreamsVector[folderIndex])
+ CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
+
+ if (rep.NumCopyFiles == numUnpackStreams)
{
+ if (opCallback)
+ {
+ RINOK(opCallback->ReportOperation(
+ NEventIndexType::kBlockIndex, (UInt32)folderIndex,
+ NUpdateNotifyOp::kReplicate));
+
+ // ---------- Copy old solid block ----------
+ {
+ CNum indexInFolder = 0;
+ for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
+ {
+ if (db->Files[fi].HasStream)
+ {
+ indexInFolder++;
+ RINOK(opCallback->ReportOperation(
+ NEventIndexType::kInArcIndex, (UInt32)fi,
+ NUpdateNotifyOp::kReplicate));
+ }
+ }
+ }
+ }
+
UInt64 packSize = db->GetFolderFullPackSize(folderIndex);
RINOK(WriteRange(inStream, archive.SeqStream,
- db->GetFolderStreamPos(folderIndex, 0), packSize, progress));
+ db->GetFolderStreamPos(folderIndex, 0), packSize, progress));
lps->ProgressOffset += packSize;
- const CFolder &folder = db->Folders[folderIndex];
- CNum startIndex = db->FolderStartPackStreamIndex[folderIndex];
- for (int j = 0; j < folder.PackStreams.Size(); j++)
+ CFolder &folder = newDatabase.Folders.AddNew();
+ db->ParseFolderInfo(folderIndex, folder);
+ CNum startIndex = db->FoStartPackStreamIndex[folderIndex];
+ FOR_VECTOR(j, folder.PackStreams)
{
- newDatabase.PackSizes.Add(db->PackSizes[startIndex + j]);
+ newDatabase.PackSizes.Add(db->GetStreamPackSize(startIndex + j));
// newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]);
// newDatabase.PackCRCs.Add(db.PackCRCs[startIndex + j]);
}
- newDatabase.Folders.Add(folder);
+
+ size_t indexStart = db->FoToCoderUnpackSizes[folderIndex];
+ size_t indexEnd = db->FoToCoderUnpackSizes[folderIndex + 1];
+ for (; indexStart < indexEnd; indexStart++)
+ newDatabase.CoderUnpackSizes.Add(db->CoderUnpackSizes[indexStart]);
}
else
{
+ // ---------- Repack old solid block ----------
+
CBoolVector extractStatuses;
- CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
CNum indexInFolder = 0;
-
+
+ if (opCallback)
+ {
+ RINOK(opCallback->ReportOperation(
+ NEventIndexType::kBlockIndex, (UInt32)folderIndex,
+ NUpdateNotifyOp::kRepack))
+ }
+
+ /* We could reduce data size of decoded folder, if we don't need to repack
+ last files in folder. But the gain in speed is small in most cases.
+ So we unpack full folder. */
+
+ UInt64 sizeToEncode = 0;
+
+ /*
+ UInt64 importantUnpackSize = 0;
+ unsigned numImportantFiles = 0;
+ UInt64 decodeSize = 0;
+ */
+
for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
{
bool needExtract = false;
- if (db->Files[fi].HasStream)
+ const CFileItem &file = db->Files[fi];
+
+ if (file.HasStream)
{
indexInFolder++;
int updateIndex = fileIndexToUpdateIndexMap[fi];
if (updateIndex >= 0 && !updateItems[updateIndex].NewData)
needExtract = true;
+ // decodeSize += file.Size;
}
+
extractStatuses.Add(needExtract);
+ if (needExtract)
+ {
+ sizeToEncode += file.Size;
+ /*
+ numImportantFiles = extractStatuses.Size();
+ importantUnpackSize = decodeSize;
+ */
+ }
}
- int startPackIndex = newDatabase.PackSizes.Size();
- CFolder newFolder;
+ // extractStatuses.DeleteFrom(numImportantFiles);
+
+ unsigned startPackIndex = newDatabase.PackSizes.Size();
+ UInt64 curUnpackSize;
{
+
CMyComPtr<ISequentialInStream> sbInStream;
+ CRepackStreamBase *repackBase;
+ CFolderInStream2 *FosSpec2 = NULL;
+
+ CRepackInStreamWithSizes *inStreamSizeCountSpec = new CRepackInStreamWithSizes;
+ CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
{
- CMyComPtr<ISequentialOutStream> sbOutStream;
- sb.CreateStreams(&sbInStream, &sbOutStream);
- sb.ReInit();
- RINOK(threadDecoder.FosSpec->Init(db, db->FolderStartFileIndex[folderIndex], &extractStatuses, sbOutStream));
- }
-
- threadDecoder.InStream = inStream;
- threadDecoder.Folder = &db->Folders[folderIndex];
- threadDecoder.StartPos = db->GetFolderStreamPos(folderIndex, 0);
- threadDecoder.PackSizes = &db->PackSizes[db->FolderStartPackStreamIndex[folderIndex]];
-
- threadDecoder.Start();
-
- RINOK(encoder.Encode(
- EXTERNAL_CODECS_LOC_VARS
- sbInStream, NULL, &inSizeForReduce, newFolder,
- archive.SeqStream, newDatabase.PackSizes, progress));
+ #ifndef _7ZIP_ST
+ if (options.MultiThreadMixer)
+ {
+ repackBase = threadDecoder.FosSpec;
+ CMyComPtr<ISequentialOutStream> sbOutStream;
+ sb.CreateStreams(&sbInStream, &sbOutStream);
+ sb.ReInit();
+
+ threadDecoder.FosSpec->_stream = sbOutStream;
+
+ threadDecoder.InStream = inStream;
+ threadDecoder.StartPos = db->ArcInfo.DataStartPosition; // db->GetFolderStreamPos(folderIndex, 0);
+ threadDecoder.Folders = (const CFolders *)db;
+ threadDecoder.FolderIndex = folderIndex;
+
+ // threadDecoder.UnpackSize = importantUnpackSize;
+ // threadDecoder.send_UnpackSize = true;
+ }
+ else
+ #endif
+ {
+ FosSpec2 = new CFolderInStream2;
+ FosSpec2->Init();
+ sbInStream = FosSpec2;
+ repackBase = FosSpec2;
+
+ #ifndef _NO_CRYPTO
+ bool isEncrypted = false;
+ bool passwordIsDefined = false;
+ UString password;
+ #endif
+
+ CMyComPtr<ISequentialInStream> decodedStream;
+ HRESULT res = threadDecoder.Decoder.Decode(
+ EXTERNAL_CODECS_LOC_VARS
+ inStream,
+ db->ArcInfo.DataStartPosition, // db->GetFolderStreamPos(folderIndex, 0);,
+ *db, folderIndex,
+ // &importantUnpackSize, // *unpackSize
+ NULL, // *unpackSize : FULL unpack
+
+ NULL, // *outStream
+ NULL, // *compressProgress
+ &decodedStream
+
+ _7Z_DECODER_CRYPRO_VARS
+ #ifndef _7ZIP_ST
+ , false // mtMode
+ , 1 // numThreads
+ #endif
+ );
- threadDecoder.WaitExecuteFinish();
- }
+ RINOK(res);
+ if (!decodedStream)
+ return E_FAIL;
+
+ FosSpec2->_inStream = decodedStream;
+ }
+
+ repackBase->_db = db;
+ repackBase->_opCallback = opCallback;
+ repackBase->_extractCallback = extractCallback;
+
+ UInt32 startIndex = db->FolderStartFileIndex[folderIndex];
+ RINOK(repackBase->Init(startIndex, &extractStatuses));
+
+ inStreamSizeCountSpec->_db = db;
+ inStreamSizeCountSpec->Init(sbInStream, startIndex, &extractStatuses);
+
+ #ifndef _7ZIP_ST
+ if (options.MultiThreadMixer)
+ {
+ threadDecoder.Start();
+ }
+ #endif
+ }
+
+
+ HRESULT encodeRes = encoder.Encode(
+ EXTERNAL_CODECS_LOC_VARS
+ inStreamSizeCount,
+ // NULL,
+ &inSizeForReduce,
+ newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curUnpackSize,
+ archive.SeqStream, newDatabase.PackSizes, progress);
+
+ if (encodeRes == k_My_HRESULT_CRC_ERROR)
+ return E_FAIL;
+
+ #ifndef _7ZIP_ST
+ if (options.MultiThreadMixer)
+ {
+ threadDecoder.WaitExecuteFinish();
+ HRESULT decodeRes = threadDecoder.Result;
+ // if (res == k_My_HRESULT_CRC_ERROR)
+ if (decodeRes == S_FALSE)
+ {
+ if (extractCallback)
+ {
+ RINOK(extractCallback->ReportExtractResult(
+ NEventIndexType::kInArcIndex, db->FolderStartFileIndex[folderIndex],
+ // NEventIndexType::kBlockIndex, (UInt32)folderIndex,
+ NExtract::NOperationResult::kDataError));
+ }
+ return E_FAIL;
+ }
+ RINOK(decodeRes);
+ if (encodeRes == S_OK)
+ if (sb.ProcessedSize != sizeToEncode)
+ encodeRes = E_FAIL;
+ }
+ else
+ #endif
+ {
+ if (FosSpec2->Result == S_FALSE)
+ {
+ if (extractCallback)
+ {
+ RINOK(extractCallback->ReportExtractResult(
+ NEventIndexType::kBlockIndex, (UInt32)folderIndex,
+ NExtract::NOperationResult::kDataError));
+ }
+ return E_FAIL;
+ }
+ RINOK(FosSpec2->Result);
+ }
- RINOK(threadDecoder.Result);
+ RINOK(encodeRes);
+ RINOK(repackBase->CheckFinishedState());
+
+ if (curUnpackSize != sizeToEncode)
+ return E_FAIL;
+ }
for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
lps->OutSize += newDatabase.PackSizes[startPackIndex];
- lps->InSize += newFolder.GetUnpackSize();
-
- newDatabase.Folders.Add(newFolder);
+ lps->InSize += curUnpackSize;
}
newDatabase.NumUnpackStreamsVector.Add(rep.NumCopyFiles);
- CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
-
CNum indexInFolder = 0;
for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
{
CFileItem file;
CFileItem2 file2;
- db->GetFile(fi, file, file2);
+ GetFile(*db, fi, file, file2);
+ UString name;
+ db->GetPath(fi, name);
if (file.HasStream)
{
indexInFolder++;
@@ -972,30 +2231,43 @@ HRESULT Update(
uf.CrcDefined = file.CrcDefined;
uf.HasStream = file.HasStream;
file = uf;
+ name = ui.Name;
}
- newDatabase.AddFile(file, file2);
+ /*
+ file.Parent = ui.ParentFolderIndex;
+ if (ui.TreeFolderIndex >= 0)
+ treeFolderToArcIndex[ui.TreeFolderIndex] = newDatabase.Files.Size();
+ if (totalSecureDataSize != 0)
+ newDatabase.SecureIDs.Add(ui.SecureIndex);
+ */
+ newDatabase.AddFile(file, file2, name);
}
}
}
}
- int numFiles = group.Indices.Size();
+
+ // ---------- Compress files to new solid blocks ----------
+
+ unsigned numFiles = group.Indices.Size();
if (numFiles == 0)
continue;
CRecordVector<CRefItem> refItems;
- refItems.Reserve(numFiles);
- bool sortByType = (numSolidFiles > 1);
+ refItems.ClearAndSetSize(numFiles);
+ bool sortByType = (options.UseTypeSorting && numSolidFiles > 1);
for (i = 0; i < numFiles; i++)
- refItems.Add(CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType));
- refItems.Sort(CompareUpdateItems, (void *)&sortByType);
+ refItems[i] = CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType);
+ CSortParam sortParam;
+ // sortParam.TreeFolders = &treeFolders;
+ sortParam.SortByType = sortByType;
+ refItems.Sort(CompareUpdateItems, (void *)&sortParam);
- CRecordVector<UInt32> indices;
- indices.Reserve(numFiles);
+ CObjArray<UInt32> indices(numFiles);
for (i = 0; i < numFiles; i++)
{
UInt32 index = refItems[i].Index;
- indices.Add(index);
+ indices[i] = index;
/*
const CUpdateItem &ui = updateItems[index];
CFileItem file;
@@ -1012,10 +2284,11 @@ HRESULT Update(
for (i = 0; i < numFiles;)
{
UInt64 totalSize = 0;
- int numSubFiles;
- UString prevExtension;
- for (numSubFiles = 0; i + numSubFiles < numFiles &&
- numSubFiles < numSolidFiles; numSubFiles++)
+ unsigned numSubFiles;
+
+ const wchar_t *prevExtension = NULL;
+
+ for (numSubFiles = 0; i + numSubFiles < numFiles && numSubFiles < numSolidFiles; numSubFiles++)
{
const CUpdateItem &ui = updateItems[indices[i + numSubFiles]];
totalSize += ui.Size;
@@ -1023,49 +2296,65 @@ HRESULT Update(
break;
if (options.SolidExtension)
{
- UString ext = ui.GetExtension();
+ int slashPos = ui.Name.ReverseFind_PathSepar();
+ int dotPos = ui.Name.ReverseFind_Dot();
+ const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : dotPos + 1);
if (numSubFiles == 0)
prevExtension = ext;
- else
- if (ext.CompareNoCase(prevExtension) != 0)
- break;
+ else if (!StringsAreEqualNoCase(ext, prevExtension))
+ break;
}
}
+
if (numSubFiles < 1)
numSubFiles = 1;
+ RINOK(lps->SetCur());
+
CFolderInStream *inStreamSpec = new CFolderInStream;
CMyComPtr<ISequentialInStream> solidInStream(inStreamSpec);
inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
- CFolder folderItem;
-
- int startPackIndex = newDatabase.PackSizes.Size();
+ unsigned startPackIndex = newDatabase.PackSizes.Size();
+ UInt64 curFolderUnpackSize;
RINOK(encoder.Encode(
EXTERNAL_CODECS_LOC_VARS
- solidInStream, NULL, &inSizeForReduce, folderItem,
+ solidInStream,
+ // NULL,
+ &inSizeForReduce,
+ newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curFolderUnpackSize,
archive.SeqStream, newDatabase.PackSizes, progress));
+ if (!inStreamSpec->WasFinished())
+ return E_FAIL;
+
for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
lps->OutSize += newDatabase.PackSizes[startPackIndex];
- lps->InSize += folderItem.GetUnpackSize();
+ lps->InSize += curFolderUnpackSize;
// for ()
// newDatabase.PackCRCsDefined.Add(false);
// newDatabase.PackCRCs.Add(0);
-
- newDatabase.Folders.Add(folderItem);
-
+
CNum numUnpackStreams = 0;
- for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
+ UInt64 skippedSize = 0;
+
+ for (unsigned subIndex = 0; subIndex < numSubFiles; subIndex++)
{
const CUpdateItem &ui = updateItems[indices[i + subIndex]];
CFileItem file;
CFileItem2 file2;
+ UString name;
if (ui.NewProps)
+ {
FromUpdateItemToFileItem(ui, file, file2);
+ name = ui.Name;
+ }
else
- db->GetFile(ui.IndexInArchive, file, file2);
+ {
+ GetFile(*db, ui.IndexInArchive, file, file2);
+ db->GetPath(ui.IndexInArchive, name);
+ }
if (file2.IsAnti || file.IsDir)
return E_FAIL;
@@ -1075,12 +2364,15 @@ HRESULT Update(
*/
if (!inStreamSpec->Processed[subIndex])
{
+ skippedSize += ui.Size;
continue;
- // file.Name += L".locked";
+ // file.Name.AddAscii(".locked");
}
file.Crc = inStreamSpec->CRCs[subIndex];
file.Size = inStreamSpec->Sizes[subIndex];
+
+ // if (file.Size >= 0) // test purposes
if (file.Size != 0)
{
file.CrcDefined = true;
@@ -1092,57 +2384,65 @@ HRESULT Update(
file.CrcDefined = false;
file.HasStream = false;
}
- newDatabase.AddFile(file, file2);
+
+ /*
+ file.Parent = ui.ParentFolderIndex;
+ if (ui.TreeFolderIndex >= 0)
+ treeFolderToArcIndex[ui.TreeFolderIndex] = newDatabase.Files.Size();
+ if (totalSecureDataSize != 0)
+ newDatabase.SecureIDs.Add(ui.SecureIndex);
+ */
+ newDatabase.AddFile(file, file2, name);
}
+
// numUnpackStreams = 0 is very bad case for locked files
// v3.13 doesn't understand it.
newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);
i += numSubFiles;
+
+ if (skippedSize != 0 && complexity >= skippedSize)
+ {
+ complexity -= skippedSize;
+ RINOK(updateCallback->SetTotal(complexity));
+ }
}
}
- if (folderRefIndex != folderRefs.Size())
- return E_FAIL;
-
RINOK(lps->SetCur());
/*
- folderRefs.ClearAndFree();
fileIndexToUpdateIndexMap.ClearAndFree();
groups.ClearAndFree();
*/
+ /*
+ for (i = 0; i < newDatabase.Files.Size(); i++)
{
- // ---------- Write Folders & Empty Files ----------
-
- CRecordVector<int> emptyRefs;
- for (i = 0; i < updateItems.Size(); i++)
- {
- const CUpdateItem &ui = updateItems[i];
- if (ui.NewData)
- {
- if (ui.HasStream())
- continue;
- }
- else if (ui.IndexInArchive != -1 && db->Files[ui.IndexInArchive].HasStream)
- continue;
- emptyRefs.Add(i);
- }
- emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
- for (i = 0; i < emptyRefs.Size(); i++)
+ CFileItem &file = newDatabase.Files[i];
+ file.Parent = treeFolderToArcIndex[file.Parent];
+ }
+
+ if (totalSecureDataSize != 0)
+ {
+ newDatabase.SecureBuf.SetCapacity(totalSecureDataSize);
+ size_t pos = 0;
+ newDatabase.SecureSizes.Reserve(secureBlocks.Sorted.Size());
+ for (i = 0; i < secureBlocks.Sorted.Size(); i++)
{
- const CUpdateItem &ui = updateItems[emptyRefs[i]];
- CFileItem file;
- CFileItem2 file2;
- if (ui.NewProps)
- FromUpdateItemToFileItem(ui, file, file2);
- else
- db->GetFile(ui.IndexInArchive, file, file2);
- newDatabase.AddFile(file, file2);
+ const CByteBuffer &buf = secureBlocks.Bufs[secureBlocks.Sorted[i]];
+ size_t size = buf.GetCapacity();
+ if (size != 0)
+ memcpy(newDatabase.SecureBuf + pos, buf, size);
+ newDatabase.SecureSizes.Add((UInt32)size);
+ pos += size;
}
}
-
+ */
newDatabase.ReserveDown();
+
+ if (opCallback)
+ RINOK(opCallback->ReportOperation(NEventIndexType::kNoIndex, (UInt32)(Int32)-1, NUpdateNotifyOp::kHeader));
+
return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h
index 31e362246d3..a7abf779a61 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h
@@ -3,15 +3,31 @@
#ifndef __7Z_UPDATE_H
#define __7Z_UPDATE_H
+#include "../IArchive.h"
+
+// #include "../../Common/UniqBlocks.h"
+
#include "7zCompressionMode.h"
#include "7zIn.h"
#include "7zOut.h"
-#include "../IArchive.h"
-
namespace NArchive {
namespace N7z {
+/*
+struct CTreeFolder
+{
+ UString Name;
+ int Parent;
+ CIntVector SubFolders;
+ int UpdateItemIndex;
+ int SortIndex;
+ int SortIndexEnd;
+
+ CTreeFolder(): UpdateItemIndex(-1) {}
+};
+*/
+
struct CUpdateItem
{
int IndexInArchive;
@@ -23,6 +39,15 @@ struct CUpdateItem
UInt64 Size;
UString Name;
+ /*
+ bool IsAltStream;
+ int ParentFolderIndex;
+ int TreeFolderIndex;
+ */
+
+ // that code is not used in 9.26
+ // int ParentSortIndex;
+ // int ParentSortIndexEnd;
UInt32 Attrib;
@@ -37,45 +62,71 @@ struct CUpdateItem
bool ATimeDefined;
bool MTimeDefined;
+ // int SecureIndex; // 0 means (no_security)
+
bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }
+ // bool HasStream() const { return !IsDir && !IsAnti /* && Size != 0 */; } // for test purposes
CUpdateItem():
+ // ParentSortIndex(-1),
+ // IsAltStream(false),
IsAnti(false),
IsDir(false),
AttribDefined(false),
CTimeDefined(false),
ATimeDefined(false),
MTimeDefined(false)
+ // SecureIndex(0)
{}
- void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); };
+ void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); }
- int GetExtensionPos() const;
- UString GetExtension() const;
+ // unsigned GetExtensionPos() const;
+ // UString GetExtension() const;
};
struct CUpdateOptions
{
const CCompressionMethodMode *Method;
const CCompressionMethodMode *HeaderMethod;
- bool UseFilters;
- bool MaxFilter;
+ bool UseFilters; // use additional filters for some files
+ bool MaxFilter; // use BCJ2 filter instead of BCJ
+ int AnalysisLevel;
CHeaderOptions HeaderOptions;
UInt64 NumSolidFiles;
UInt64 NumSolidBytes;
bool SolidExtension;
+
+ bool UseTypeSorting;
+
bool RemoveSfxBlock;
- bool VolumeMode;
+ bool MultiThreadMixer;
+
+ CUpdateOptions():
+ Method(NULL),
+ HeaderMethod(NULL),
+ UseFilters(false),
+ MaxFilter(false),
+ AnalysisLevel(-1),
+ NumSolidFiles((UInt64)(Int64)(-1)),
+ NumSolidBytes((UInt64)(Int64)(-1)),
+ SolidExtension(false),
+ UseTypeSorting(true),
+ RemoveSfxBlock(false),
+ MultiThreadMixer(true)
+ {}
};
HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
- const CArchiveDatabaseEx *db,
+ const CDbEx *db,
const CObjectVector<CUpdateItem> &updateItems,
+ // const CObjectVector<CTreeFolder> &treeFolders, // treeFolders[0] is root
+ // const CUniqBlocks &secureBlocks,
COutArchive &archive,
- CArchiveDatabase &newDatabase,
+ CArchiveDatabaseOut &newDatabase,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h b/3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h
index 2e4be10b291..2854ff3e935 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../../Common/MyWindows.h"
-#include "../../../Common/NewHandler.h"
+#include "../../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Archive.def b/3rdparty/lzma/CPP/7zip/Archive/Archive.def
index 55b530b2d6e..145516d7970 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Archive.def
+++ b/3rdparty/lzma/CPP/7zip/Archive/Archive.def
@@ -1,6 +1,12 @@
EXPORTS
CreateObject PRIVATE
+
GetHandlerProperty PRIVATE
GetNumberOfFormats PRIVATE
GetHandlerProperty2 PRIVATE
- CreateObject PRIVATE
+ GetIsArc PRIVATE
+
+ SetCodecs PRIVATE
+
+ SetLargePageMode PRIVATE
+ SetCaseSensitive PRIVATE
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Archive2.def b/3rdparty/lzma/CPP/7zip/Archive/Archive2.def
index 885d39d149d..c7582742198 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Archive2.def
+++ b/3rdparty/lzma/CPP/7zip/Archive/Archive2.def
@@ -1,9 +1,19 @@
EXPORTS
CreateObject PRIVATE
+
GetHandlerProperty PRIVATE
GetNumberOfFormats PRIVATE
GetHandlerProperty2 PRIVATE
- CreateObject PRIVATE
+ GetIsArc PRIVATE
+
GetNumberOfMethods PRIVATE
GetMethodProperty PRIVATE
+ CreateDecoder PRIVATE
+ CreateEncoder PRIVATE
+
+ GetHashers PRIVATE
+
+ SetCodecs PRIVATE
+
SetLargePageMode PRIVATE
+ SetCaseSensitive PRIVATE
diff --git a/3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp b/3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp
index c7908b5917e..28e9946d5f6 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp
@@ -2,21 +2,24 @@
#include "StdAfx.h"
+#include "../../../C/7zVersion.h"
+
#include "../../Common/ComTry.h"
#include "../../Windows/PropVariant.h"
#include "../Common/RegisterArc.h"
-static const unsigned int kNumArcsMax = 48;
-static unsigned int g_NumArcs = 0;
-static unsigned int g_DefaultArcIndex = 0;
+static const unsigned kNumArcsMax = 64;
+static unsigned g_NumArcs = 0;
+static unsigned g_DefaultArcIndex = 0;
static const CArcInfo *g_Arcs[kNumArcsMax];
-void RegisterArc(const CArcInfo *arcInfo)
+
+void RegisterArc(const CArcInfo *arcInfo) throw()
{
if (g_NumArcs < kNumArcsMax)
{
- const wchar_t *p = arcInfo->Name;
+ const char *p = arcInfo->Name;
if (p[0] == '7' && p[1] == 'z' && p[2] == 0)
g_DefaultArcIndex = g_NumArcs;
g_Arcs[g_NumArcs++] = arcInfo;
@@ -24,11 +27,14 @@ void RegisterArc(const CArcInfo *arcInfo)
}
DEFINE_GUID(CLSID_CArchiveHandler,
-0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
+ k_7zip_GUID_Data1,
+ k_7zip_GUID_Data2,
+ k_7zip_GUID_Data3_Common,
+ 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
-static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value)
+static inline HRESULT SetPropStrFromBin(const char *s, unsigned size, PROPVARIANT *value)
{
if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
value->vt = VT_BSTR;
@@ -37,18 +43,18 @@ static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIAN
static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
{
- return SetPropString((const char *)&guid, sizeof(GUID), value);
+ return SetPropStrFromBin((const char *)&guid, sizeof(guid), value);
}
-int FindFormatCalssId(const GUID *clsID)
+int FindFormatCalssId(const GUID *clsid)
{
- GUID cls = *clsID;
+ GUID cls = *clsid;
CLS_ARC_ID_ITEM(cls) = 0;
if (cls != CLSID_CArchiveHandler)
return -1;
- Byte id = CLS_ARC_ID_ITEM(*clsID);
+ Byte id = CLS_ARC_ID_ITEM(*clsid);
for (unsigned i = 0; i < g_NumArcs; i++)
- if (g_Arcs[i]->ClassId == id)
+ if (g_Arcs[i]->Id == id)
return (int)i;
return -1;
}
@@ -86,37 +92,38 @@ STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
+ NWindows::NCOM::PropVariant_Clear(value);
if (formatIndex >= g_NumArcs)
return E_INVALIDARG;
const CArcInfo &arc = *g_Arcs[formatIndex];
NWindows::NCOM::CPropVariant prop;
- switch(propID)
+ switch (propID)
{
- case NArchive::kName:
- prop = arc.Name;
- break;
- case NArchive::kClassID:
+ case NArchive::NHandlerPropID::kName: prop = arc.Name; break;
+ case NArchive::NHandlerPropID::kClassID:
{
GUID clsId = CLSID_CArchiveHandler;
- CLS_ARC_ID_ITEM(clsId) = arc.ClassId;
+ CLS_ARC_ID_ITEM(clsId) = arc.Id;
return SetPropGUID(clsId, value);
}
- case NArchive::kExtension:
- if (arc.Ext != 0)
- prop = arc.Ext;
- break;
- case NArchive::kAddExtension:
- if (arc.AddExt != 0)
- prop = arc.AddExt;
- break;
- case NArchive::kUpdate:
- prop = (bool)(arc.CreateOutArchive != 0);
+ case NArchive::NHandlerPropID::kExtension: if (arc.Ext) prop = arc.Ext; break;
+ case NArchive::NHandlerPropID::kAddExtension: if (arc.AddExt) prop = arc.AddExt; break;
+ case NArchive::NHandlerPropID::kUpdate: prop = (bool)(arc.CreateOutArchive != NULL); break;
+ case NArchive::NHandlerPropID::kKeepName: prop = ((arc.Flags & NArcInfoFlags::kKeepName) != 0); break;
+ case NArchive::NHandlerPropID::kAltStreams: prop = ((arc.Flags & NArcInfoFlags::kAltStreams) != 0); break;
+ case NArchive::NHandlerPropID::kNtSecure: prop = ((arc.Flags & NArcInfoFlags::kNtSecure) != 0); break;
+ case NArchive::NHandlerPropID::kFlags: prop = (UInt32)arc.Flags; break;
+ case NArchive::NHandlerPropID::kSignatureOffset: prop = (UInt32)arc.SignatureOffset; break;
+ // case NArchive::NHandlerPropID::kVersion: prop = (UInt32)MY_VER_MIX; break;
+
+ case NArchive::NHandlerPropID::kSignature:
+ if (arc.SignatureSize != 0 && !arc.IsMultiSignature())
+ return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value);
break;
- case NArchive::kKeepName:
- prop = arc.KeepName;
+ case NArchive::NHandlerPropID::kMultiSignature:
+ if (arc.SignatureSize != 0 && arc.IsMultiSignature())
+ return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value);
break;
- case NArchive::kStartSignature:
- return SetPropString((const char *)arc.Signature, arc.SignatureSize, value);
}
prop.Detach(value);
return S_OK;
@@ -133,3 +140,12 @@ STDAPI GetNumberOfFormats(UINT32 *numFormats)
*numFormats = g_NumArcs;
return S_OK;
}
+
+STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc)
+{
+ *isArc = NULL;
+ if (formatIndex >= g_NumArcs)
+ return E_INVALIDARG;
+ *isArc = g_Arcs[formatIndex]->IsArc;
+ return S_OK;
+}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp
index 0b06a489f7d..41b5805c115 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp
@@ -4,118 +4,1041 @@
#include "CoderMixer2.h"
-namespace NCoderMixer {
+#ifdef USE_MIXER_ST
-CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo):
- _srcBindInfo(srcBindInfo)
+STDMETHODIMP CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams);
+ UInt32 realProcessed = 0;
+ HRESULT result = S_OK;
+ if (_stream)
+ result = _stream->Read(data, size, &realProcessed);
+ _size += realProcessed;
+ if (size != 0 && realProcessed == 0)
+ _wasFinished = true;
+ if (processedSize)
+ *processedSize = realProcessed;
+ return result;
+}
+
+
+STDMETHODIMP COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ HRESULT result = S_OK;
+ if (_stream)
+ result = _stream->Write(data, size, &size);
+ _size += size;
+ if (processedSize)
+ *processedSize = size;
+ return result;
+}
+
+STDMETHODIMP COutStreamCalcSize::OutStreamFinish()
+{
+ HRESULT result = S_OK;
+ if (_stream)
+ {
+ CMyComPtr<IOutStreamFinish> outStreamFinish;
+ _stream.QueryInterface(IID_IOutStreamFinish, &outStreamFinish);
+ if (outStreamFinish)
+ result = outStreamFinish->OutStreamFinish();
+ }
+ return result;
+}
+
+#endif
+
+
+
+
+namespace NCoderMixer2 {
+
+static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
+{
+ v.ClearAndSetSize(size);
+ bool *p = &v[0];
+ for (unsigned i = 0; i < size; i++)
+ p[i] = false;
+}
+
+class CBondsChecks
+{
+ CBoolVector _coderUsed;
+
+ bool Init();
+ bool CheckCoder(unsigned coderIndex);
+public:
+ const CBindInfo *BindInfo;
+
+ bool Check();
+};
+
+bool CBondsChecks::CheckCoder(unsigned coderIndex)
+{
+ const CCoderStreamsInfo &coder = BindInfo->Coders[coderIndex];
+
+ if (coderIndex >= _coderUsed.Size() || _coderUsed[coderIndex])
+ return false;
+ _coderUsed[coderIndex] = true;
+
+ UInt32 start = BindInfo->Coder_to_Stream[coderIndex];
+
+ for (unsigned i = 0; i < coder.NumStreams; i++)
+ {
+ UInt32 ind = start + i;
+
+ if (BindInfo->IsStream_in_PackStreams(ind))
+ continue;
+
+ int bond = BindInfo->FindBond_for_PackStream(ind);
+ if (bond < 0)
+ return false;
+ if (!CheckCoder(BindInfo->Bonds[bond].UnpackIndex))
+ return false;
+ }
+
+ return true;
+}
+
+bool CBondsChecks::Check()
+{
+ BoolVector_Fill_False(_coderUsed, BindInfo->Coders.Size());
+
+ if (!CheckCoder(BindInfo->UnpackCoder))
+ return false;
+
+ FOR_VECTOR(i, _coderUsed)
+ if (!_coderUsed[i])
+ return false;
+
+ return true;
+}
+
+void CBindInfo::ClearMaps()
+{
+ Coder_to_Stream.Clear();
+ Stream_to_Coder.Clear();
+}
+
+bool CBindInfo::CalcMapsAndCheck()
+{
+ ClearMaps();
+
+ UInt32 numStreams = 0;
+
+ if (Coders.Size() == 0)
+ return false;
+ if (Coders.Size() - 1 != Bonds.Size())
+ return false;
+
+ FOR_VECTOR(i, Coders)
+ {
+ Coder_to_Stream.Add(numStreams);
+
+ const CCoderStreamsInfo &c = Coders[i];
+
+ for (unsigned j = 0; j < c.NumStreams; j++)
+ Stream_to_Coder.Add(i);
+
+ numStreams += c.NumStreams;
+ }
+
+ if (numStreams != GetNum_Bonds_and_PackStreams())
+ return false;
+
+ CBondsChecks bc;
+ bc.BindInfo = this;
+ return bc.Check();
+}
+
+
+void CCoder::SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes)
+{
+ if (unpackSize)
+ {
+ UnpackSize = *unpackSize;
+ UnpackSizePointer = &UnpackSize;
+ }
+ else
+ {
+ UnpackSize = 0;
+ UnpackSizePointer = NULL;
+ }
+
+ PackSizes.ClearAndSetSize((unsigned)NumStreams);
+ PackSizePointers.ClearAndSetSize((unsigned)NumStreams);
+
+ for (unsigned i = 0; i < NumStreams; i++)
+ {
+ if (packSizes && packSizes[i])
+ {
+ PackSizes[i] = *(packSizes[i]);
+ PackSizePointers[i] = &PackSizes[i];
+ }
+ else
+ {
+ PackSizes[i] = 0;
+ PackSizePointers[i] = NULL;
+ }
+ }
+}
+
+bool CMixer::Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex)
+{
+ if (coderIndex == _bi.UnpackCoder)
+ return true;
+
+ int bond = _bi.FindBond_for_UnpackStream(coderIndex);
+ if (bond < 0)
+ throw 20150213;
+
+ /*
+ UInt32 coderIndex, coderStreamIndex;
+ _bi.GetCoder_for_Stream(_bi.Bonds[bond].PackIndex, coderIndex, coderStreamIndex);
+ */
+ UInt32 nextCoder = _bi.Stream_to_Coder[_bi.Bonds[bond].PackIndex];
+
+ if (!IsFilter_Vector[nextCoder])
+ return false;
+
+ return Is_UnpackSize_Correct_for_Coder(nextCoder);
+}
+
+bool CMixer::Is_PackSize_Correct_for_Stream(UInt32 streamIndex)
+{
+ if (_bi.IsStream_in_PackStreams(streamIndex))
+ return true;
+
+ int bond = _bi.FindBond_for_PackStream(streamIndex);
+ if (bond < 0)
+ throw 20150213;
+
+ UInt32 nextCoder = _bi.Bonds[bond].UnpackIndex;
+
+ if (!IsFilter_Vector[nextCoder])
+ return false;
+
+ return Is_PackSize_Correct_for_Coder(nextCoder);
+}
+
+bool CMixer::Is_PackSize_Correct_for_Coder(UInt32 coderIndex)
+{
+ UInt32 startIndex = _bi.Coder_to_Stream[coderIndex];
+ UInt32 numStreams = _bi.Coders[coderIndex].NumStreams;
+ for (UInt32 i = 0; i < numStreams; i++)
+ if (!Is_PackSize_Correct_for_Stream(startIndex + i))
+ return false;
+ return true;
+}
+
+bool CMixer::IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex)
+{
+ if (IsExternal_Vector[coderIndex])
+ return true;
+ UInt32 startIndex = _bi.Coder_to_Stream[coderIndex];
+ UInt32 numStreams = _bi.Coders[coderIndex].NumStreams;
+ for (UInt32 i = 0; i < numStreams; i++)
+ {
+ UInt32 si = startIndex + i;
+ if (_bi.IsStream_in_PackStreams(si))
+ continue;
+
+ int bond = _bi.FindBond_for_PackStream(si);
+ if (bond < 0)
+ throw 20150213;
+
+ if (IsThere_ExternalCoder_in_PackTree(_bi.Bonds[bond].UnpackIndex))
+ return true;
+ }
+ return false;
+}
+
+
+
+
+#ifdef USE_MIXER_ST
+
+CMixerST::CMixerST(bool encodeMode):
+ CMixer(encodeMode)
+ {}
+
+CMixerST::~CMixerST() {}
- UInt32 j;
- for (j = 0; j < NumSrcInStreams; j++)
+void CMixerST::AddCoder(const CCreatedCoder &cod)
+{
+ IsFilter_Vector.Add(cod.IsFilter);
+ IsExternal_Vector.Add(cod.IsExternal);
+ // const CCoderStreamsInfo &c = _bi.Coders[_coders.Size()];
+ CCoderST &c2 = _coders.AddNew();
+ c2.NumStreams = cod.NumStreams;
+ c2.Coder = cod.Coder;
+ c2.Coder2 = cod.Coder2;
+
+ /*
+ if (isFilter)
{
- _srcInToDestOutMap.Add(0);
- DestOutToSrcInMap.Add(0);
+ c2.CanRead = true;
+ c2.CanWrite = true;
}
- for (j = 0; j < _numSrcOutStreams; j++)
+ else
+ */
{
- _srcOutToDestInMap.Add(0);
- _destInToSrcOutMap.Add(0);
+ IUnknown *unk = (cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2);
+ {
+ CMyComPtr<ISequentialInStream> s;
+ unk->QueryInterface(IID_ISequentialInStream, (void**)&s);
+ c2.CanRead = (s != NULL);
+ }
+ {
+ CMyComPtr<ISequentialOutStream> s;
+ unk->QueryInterface(IID_ISequentialOutStream, (void**)&s);
+ c2.CanWrite = (s != NULL);
+ }
}
+}
+
+CCoder &CMixerST::GetCoder(unsigned index)
+{
+ return _coders[index];
+}
- UInt32 destInOffset = 0;
- UInt32 destOutOffset = 0;
- UInt32 srcInOffset = NumSrcInStreams;
- UInt32 srcOutOffset = _numSrcOutStreams;
+void CMixerST::ReInit() {}
- for (int i = srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+HRESULT CMixerST::GetInStream2(
+ ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
+ UInt32 outStreamIndex, ISequentialInStream **inStreamRes)
+{
+ UInt32 coderIndex = outStreamIndex, coderStreamIndex = 0;
+
+ if (EncodeMode)
{
- const CCoderStreamsInfo &srcCoderInfo = srcBindInfo.Coders[i];
+ _bi.GetCoder_for_Stream(outStreamIndex, coderIndex, coderStreamIndex);
+ if (coderStreamIndex != 0)
+ return E_NOTIMPL;
+ }
+
+ const CCoder &coder = _coders[coderIndex];
+
+ CMyComPtr<ISequentialInStream> seqInStream;
+ coder.QueryInterface(IID_ISequentialInStream, (void **)&seqInStream);
+ if (!seqInStream)
+ return E_NOTIMPL;
+
+ UInt32 numInStreams = EncodeMode ? 1 : coder.NumStreams;
+ UInt32 startIndex = EncodeMode ? coderIndex : _bi.Coder_to_Stream[coderIndex];
- srcInOffset -= srcCoderInfo.NumInStreams;
- srcOutOffset -= srcCoderInfo.NumOutStreams;
+ bool isSet = false;
+
+ if (numInStreams == 1)
+ {
+ CMyComPtr<ICompressSetInStream> setStream;
+ coder.QueryInterface(IID_ICompressSetInStream, (void **)&setStream);
+ if (setStream)
+ {
+ CMyComPtr<ISequentialInStream> seqInStream2;
+ RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + 0, &seqInStream2));
+ RINOK(setStream->SetInStream(seqInStream2));
+ isSet = true;
+ }
+ }
+
+ if (!isSet && numInStreams != 0)
+ {
+ CMyComPtr<ICompressSetInStream2> setStream2;
+ coder.QueryInterface(IID_ICompressSetInStream2, (void **)&setStream2);
+ if (!setStream2)
+ return E_NOTIMPL;
- UInt32 j;
- for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++)
+ for (UInt32 i = 0; i < numInStreams; i++)
+ {
+ CMyComPtr<ISequentialInStream> seqInStream2;
+ RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + i, &seqInStream2));
+ RINOK(setStream2->SetInStream2(i, seqInStream2));
+ }
+ }
+
+ *inStreamRes = seqInStream.Detach();
+ return S_OK;
+}
+
+
+HRESULT CMixerST::GetInStream(
+ ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
+ UInt32 inStreamIndex, ISequentialInStream **inStreamRes)
+{
+ CMyComPtr<ISequentialInStream> seqInStream;
+
+ {
+ int index = -1;
+ if (EncodeMode)
+ {
+ if (_bi.UnpackCoder == inStreamIndex)
+ index = 0;
+ }
+ else
+ index = _bi.FindStream_in_PackStreams(inStreamIndex);
+
+ if (index >= 0)
+ {
+ seqInStream = inStreams[(unsigned)index];
+ *inStreamRes = seqInStream.Detach();
+ return S_OK;
+ }
+ }
+
+ int bond = FindBond_for_Stream(
+ true, // forInputStream
+ inStreamIndex);
+ if (bond < 0)
+ return E_INVALIDARG;
+
+ RINOK(GetInStream2(inStreams, /* inSizes, */
+ _bi.Bonds[bond].Get_OutIndex(EncodeMode), &seqInStream));
+
+ while (_binderStreams.Size() <= (unsigned)bond)
+ _binderStreams.AddNew();
+ CStBinderStream &bs = _binderStreams[bond];
+
+ if (bs.StreamRef || bs.InStreamSpec)
+ return E_NOTIMPL;
+
+ CSequentialInStreamCalcSize *spec = new CSequentialInStreamCalcSize;
+ bs.StreamRef = spec;
+ bs.InStreamSpec = spec;
+
+ spec->SetStream(seqInStream);
+ spec->Init();
+
+ seqInStream = bs.InStreamSpec;
+
+ *inStreamRes = seqInStream.Detach();
+ return S_OK;
+}
+
+
+HRESULT CMixerST::GetOutStream(
+ ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */
+ UInt32 outStreamIndex, ISequentialOutStream **outStreamRes)
+{
+ CMyComPtr<ISequentialOutStream> seqOutStream;
+
+ {
+ int index = -1;
+ if (!EncodeMode)
+ {
+ if (_bi.UnpackCoder == outStreamIndex)
+ index = 0;
+ }
+ else
+ index = _bi.FindStream_in_PackStreams(outStreamIndex);
+
+ if (index >= 0)
+ {
+ seqOutStream = outStreams[(unsigned)index];
+ *outStreamRes = seqOutStream.Detach();
+ return S_OK;
+ }
+ }
+
+ int bond = FindBond_for_Stream(
+ false, // forInputStream
+ outStreamIndex);
+ if (bond < 0)
+ return E_INVALIDARG;
+
+ UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode);
+
+ UInt32 coderIndex = inStreamIndex;
+ UInt32 coderStreamIndex = 0;
+
+ if (!EncodeMode)
+ _bi.GetCoder_for_Stream(inStreamIndex, coderIndex, coderStreamIndex);
+
+ CCoder &coder = _coders[coderIndex];
+
+ /*
+ if (!coder.Coder)
+ return E_NOTIMPL;
+ */
+
+ coder.QueryInterface(IID_ISequentialOutStream, (void **)&seqOutStream);
+ if (!seqOutStream)
+ return E_NOTIMPL;
+
+ UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1;
+ UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex;
+
+ bool isSet = false;
+
+ if (numOutStreams == 1)
+ {
+ CMyComPtr<ICompressSetOutStream> setOutStream;
+ coder.Coder.QueryInterface(IID_ICompressSetOutStream, &setOutStream);
+ if (setOutStream)
+ {
+ CMyComPtr<ISequentialOutStream> seqOutStream2;
+ RINOK(GetOutStream(outStreams, /* outSizes, */ startIndex + 0, &seqOutStream2));
+ RINOK(setOutStream->SetOutStream(seqOutStream2));
+ isSet = true;
+ }
+ }
+
+ if (!isSet && numOutStreams != 0)
+ {
+ return E_NOTIMPL;
+ /*
+ CMyComPtr<ICompressSetOutStream2> setStream2;
+ coder.QueryInterface(IID_ICompressSetOutStream2, (void **)&setStream2);
+ if (!setStream2)
+ return E_NOTIMPL;
+ for (UInt32 i = 0; i < numOutStreams; i++)
+ {
+ CMyComPtr<ISequentialOutStream> seqOutStream2;
+ RINOK(GetOutStream(outStreams, startIndex + i, &seqOutStream2));
+ RINOK(setStream2->SetOutStream2(i, seqOutStream2));
+ }
+ */
+ }
+
+ while (_binderStreams.Size() <= (unsigned)bond)
+ _binderStreams.AddNew();
+ CStBinderStream &bs = _binderStreams[bond];
+
+ if (bs.StreamRef || bs.OutStreamSpec)
+ return E_NOTIMPL;
+
+ COutStreamCalcSize *spec = new COutStreamCalcSize;
+ bs.StreamRef = (ISequentialOutStream *)spec;
+ bs.OutStreamSpec = spec;
+
+ spec->SetStream(seqOutStream);
+ spec->Init();
+
+ seqOutStream = bs.OutStreamSpec;
+
+ *outStreamRes = seqOutStream.Detach();
+ return S_OK;
+}
+
+
+static HRESULT GetError(HRESULT res, HRESULT res2)
+{
+ if (res == res2)
+ return res;
+ if (res == S_OK)
+ return res2;
+ if (res == k_My_HRESULT_WritingWasCut)
+ {
+ if (res2 != S_OK)
+ return res2;
+ }
+ return res;
+}
+
+
+HRESULT CMixerST::FinishStream(UInt32 streamIndex)
+{
+ {
+ int index = -1;
+ if (!EncodeMode)
+ {
+ if (_bi.UnpackCoder == streamIndex)
+ index = 0;
+ }
+ else
+ index = _bi.FindStream_in_PackStreams(streamIndex);
+
+ if (index >= 0)
+ return S_OK;
+ }
+
+ int bond = FindBond_for_Stream(
+ false, // forInputStream
+ streamIndex);
+ if (bond < 0)
+ return E_INVALIDARG;
+
+ UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode);
+
+ UInt32 coderIndex = inStreamIndex;
+ UInt32 coderStreamIndex = 0;
+ if (!EncodeMode)
+ _bi.GetCoder_for_Stream(inStreamIndex, coderIndex, coderStreamIndex);
+
+ CCoder &coder = _coders[coderIndex];
+ CMyComPtr<IOutStreamFinish> finish;
+ coder.QueryInterface(IID_IOutStreamFinish, (void **)&finish);
+ HRESULT res = S_OK;
+ if (finish)
+ {
+ res = finish->OutStreamFinish();
+ }
+ return GetError(res, FinishCoder(coderIndex));
+}
+
+
+HRESULT CMixerST::FinishCoder(UInt32 coderIndex)
+{
+ CCoder &coder = _coders[coderIndex];
+
+ UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1;
+ UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex;
+
+ HRESULT res = S_OK;
+ for (unsigned i = 0; i < numOutStreams; i++)
+ res = GetError(res, FinishStream(startIndex + i));
+ return res;
+}
+
+
+void CMixerST::SelectMainCoder(bool useFirst)
+{
+ unsigned ci = _bi.UnpackCoder;
+
+ int firstNonFilter = -1;
+ int firstAllowed = ci;
+
+ for (;;)
+ {
+ const CCoderST &coder = _coders[ci];
+ // break;
+
+ if (ci != _bi.UnpackCoder)
+ if (EncodeMode ? !coder.CanWrite : !coder.CanRead)
+ {
+ firstAllowed = ci;
+ firstNonFilter = -2;
+ }
+
+ if (coder.NumStreams != 1)
+ break;
+
+ UInt32 st = _bi.Coder_to_Stream[ci];
+ if (_bi.IsStream_in_PackStreams(st))
+ break;
+ int bond = _bi.FindBond_for_PackStream(st);
+ if (bond < 0)
+ throw 20150213;
+
+ if (EncodeMode ? !coder.CanRead : !coder.CanWrite)
+ break;
+
+ if (firstNonFilter == -1 && !IsFilter_Vector[ci])
+ firstNonFilter = ci;
+
+ ci = _bi.Bonds[bond].UnpackIndex;
+ }
+
+ if (useFirst)
+ ci = firstAllowed;
+ else if (firstNonFilter >= 0)
+ ci = firstNonFilter;
+
+ MainCoderIndex = ci;
+}
+
+
+HRESULT CMixerST::Code(
+ ISequentialInStream * const *inStreams,
+ ISequentialOutStream * const *outStreams,
+ ICompressProgressInfo *progress)
+{
+ _binderStreams.Clear();
+ unsigned ci = MainCoderIndex;
+
+ const CCoder &mainCoder = _coders[MainCoderIndex];
+
+ CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
+ CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
+
+ UInt32 numInStreams = EncodeMode ? 1 : mainCoder.NumStreams;
+ UInt32 numOutStreams = !EncodeMode ? 1 : mainCoder.NumStreams;
+
+ UInt32 startInIndex = EncodeMode ? ci : _bi.Coder_to_Stream[ci];
+ UInt32 startOutIndex = !EncodeMode ? ci : _bi.Coder_to_Stream[ci];
+
+ UInt32 i;
+
+ for (i = 0; i < numInStreams; i++)
+ {
+ CMyComPtr<ISequentialInStream> seqInStream;
+ RINOK(GetInStream(inStreams, /* inSizes, */ startInIndex + i, &seqInStream));
+ seqInStreams.Add(seqInStream);
+ }
+
+ for (i = 0; i < numOutStreams; i++)
+ {
+ CMyComPtr<ISequentialOutStream> seqOutStream;
+ RINOK(GetOutStream(outStreams, /* outSizes, */ startOutIndex + i, &seqOutStream));
+ seqOutStreams.Add(seqOutStream);
+ }
+
+ CRecordVector< ISequentialInStream * > seqInStreamsSpec;
+ CRecordVector< ISequentialOutStream * > seqOutStreamsSpec;
+
+ for (i = 0; i < numInStreams; i++)
+ seqInStreamsSpec.Add(seqInStreams[i]);
+ for (i = 0; i < numOutStreams; i++)
+ seqOutStreamsSpec.Add(seqOutStreams[i]);
+
+ for (i = 0; i < _coders.Size(); i++)
+ {
+ if (i == ci)
+ continue;
+
+ CCoder &coder = _coders[i];
+
+ if (EncodeMode)
+ {
+ CMyComPtr<ICompressInitEncoder> initEncoder;
+ coder.QueryInterface(IID_ICompressInitEncoder, (void **)&initEncoder);
+ if (initEncoder)
+ RINOK(initEncoder->InitEncoder());
+ }
+ else
{
- UInt32 index = srcInOffset + j;
- _srcInToDestOutMap[index] = destOutOffset;
- DestOutToSrcInMap[destOutOffset] = index;
+ CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
+ coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize);
+ if (setOutStreamSize)
+ RINOK(setOutStreamSize->SetOutStreamSize(
+ EncodeMode ? coder.PackSizePointers[0] : coder.UnpackSizePointer));
}
- for (j = 0; j < srcCoderInfo.NumOutStreams; j++, destInOffset++)
+ }
+
+ const UInt64 * const *isSizes2 = EncodeMode ? &mainCoder.UnpackSizePointer : &mainCoder.PackSizePointers.Front();
+ const UInt64 * const *outSizes2 = EncodeMode ? &mainCoder.PackSizePointers.Front() : &mainCoder.UnpackSizePointer;
+
+ HRESULT res;
+ if (mainCoder.Coder)
+ {
+ res = mainCoder.Coder->Code(
+ seqInStreamsSpec[0], seqOutStreamsSpec[0],
+ isSizes2[0], outSizes2[0],
+ progress);
+ }
+ else
+ {
+ res = mainCoder.Coder2->Code(
+ &seqInStreamsSpec.Front(), isSizes2, numInStreams,
+ &seqOutStreamsSpec.Front(), outSizes2, numOutStreams,
+ progress);
+ }
+
+ if (res == k_My_HRESULT_WritingWasCut)
+ res = S_OK;
+
+ if (res == S_OK || res == S_FALSE)
+ {
+ res = GetError(res, FinishCoder(ci));
+ }
+
+ for (i = 0; i < _binderStreams.Size(); i++)
+ {
+ const CStBinderStream &bs = _binderStreams[i];
+ if (bs.InStreamSpec)
+ bs.InStreamSpec->ReleaseStream();
+ else
+ bs.OutStreamSpec->ReleaseStream();
+ }
+
+ if (res == k_My_HRESULT_WritingWasCut)
+ res = S_OK;
+ return res;
+}
+
+
+HRESULT CMixerST::GetMainUnpackStream(
+ ISequentialInStream * const *inStreams,
+ ISequentialInStream **inStreamRes)
+{
+ CMyComPtr<ISequentialInStream> seqInStream;
+
+ RINOK(GetInStream2(inStreams, /* inSizes, */
+ _bi.UnpackCoder, &seqInStream))
+
+ FOR_VECTOR (i, _coders)
+ {
+ CCoder &coder = _coders[i];
+ CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
+ coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize);
+ if (setOutStreamSize)
{
- UInt32 index = srcOutOffset + j;
- _srcOutToDestInMap[index] = destInOffset;
- _destInToSrcOutMap[destInOffset] = index;
+ RINOK(setOutStreamSize->SetOutStreamSize(coder.UnpackSizePointer));
}
}
+
+ *inStreamRes = seqInStream.Detach();
+ return S_OK;
}
-void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo)
+
+UInt64 CMixerST::GetBondStreamSize(unsigned bondIndex) const
{
- destBindInfo.Coders.Clear();
- destBindInfo.BindPairs.Clear();
- destBindInfo.InStreams.Clear();
- destBindInfo.OutStreams.Clear();
+ const CStBinderStream &bs = _binderStreams[bondIndex];
+ if (bs.InStreamSpec)
+ return bs.InStreamSpec->GetSize();
+ return bs.OutStreamSpec->GetSize();
+}
+
+#endif
+
+
+
+
+
- int i;
- for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+#ifdef USE_MIXER_MT
+
+
+void CCoderMT::Execute()
+{
+ try
+ {
+ Code(NULL);
+ }
+ catch(...)
{
- const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i];
- CCoderStreamsInfo destCoderInfo;
- destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams;
- destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams;
- destBindInfo.Coders.Add(destCoderInfo);
+ Result = E_FAIL;
}
- for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--)
+}
+
+void CCoderMT::Code(ICompressProgressInfo *progress)
+{
+ unsigned numInStreams = EncodeMode ? 1 : NumStreams;
+ unsigned numOutStreams = EncodeMode ? NumStreams : 1;
+
+ InStreamPointers.ClearAndReserve(numInStreams);
+ OutStreamPointers.ClearAndReserve(numOutStreams);
+
+ unsigned i;
+
+ for (i = 0; i < numInStreams; i++)
+ InStreamPointers.AddInReserved((ISequentialInStream *)InStreams[i]);
+
+ for (i = 0; i < numOutStreams; i++)
+ OutStreamPointers.AddInReserved((ISequentialOutStream *)OutStreams[i]);
+
+ // we suppose that UnpackSizePointer and PackSizePointers contain correct pointers.
+ /*
+ if (UnpackSizePointer)
+ UnpackSizePointer = &UnpackSize;
+ for (i = 0; i < NumStreams; i++)
+ if (PackSizePointers[i])
+ PackSizePointers[i] = &PackSizes[i];
+ */
+
+ CReleaser releaser(*this);
+
+ if (Coder)
+ Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],
+ EncodeMode ? UnpackSizePointer : PackSizePointers[0],
+ EncodeMode ? PackSizePointers[0] : UnpackSizePointer,
+ progress);
+ else
+ Result = Coder2->Code(
+ &InStreamPointers.Front(), EncodeMode ? &UnpackSizePointer : &PackSizePointers.Front(), numInStreams,
+ &OutStreamPointers.Front(), EncodeMode ? &PackSizePointers.Front(): &UnpackSizePointer, numOutStreams,
+ progress);
+}
+
+HRESULT CMixerMT::SetBindInfo(const CBindInfo &bindInfo)
+{
+ CMixer::SetBindInfo(bindInfo);
+
+ _streamBinders.Clear();
+ FOR_VECTOR (i, _bi.Bonds)
{
- const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i];
- CBindPair destBindPair;
- destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex];
- destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex];
- destBindInfo.BindPairs.Add(destBindPair);
+ RINOK(_streamBinders.AddNew().CreateEvents());
}
- for (i = 0; i < _srcBindInfo.InStreams.Size(); i++)
- destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]);
- for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++)
- destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]);
+ return S_OK;
+}
+
+void CMixerMT::AddCoder(const CCreatedCoder &cod)
+{
+ IsFilter_Vector.Add(cod.IsFilter);
+ IsExternal_Vector.Add(cod.IsExternal);
+ // const CCoderStreamsInfo &c = _bi.Coders[_coders.Size()];
+ CCoderMT &c2 = _coders.AddNew();
+ c2.NumStreams = cod.NumStreams;
+ c2.Coder = cod.Coder;
+ c2.Coder2 = cod.Coder2;
+ c2.EncodeMode = EncodeMode;
+}
+
+CCoder &CMixerMT::GetCoder(unsigned index)
+{
+ return _coders[index];
}
-CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
- NumInStreams(numInStreams),
- NumOutStreams(numOutStreams)
+void CMixerMT::ReInit()
{
- InSizes.Reserve(NumInStreams);
- InSizePointers.Reserve(NumInStreams);
- OutSizes.Reserve(NumOutStreams);
- OutSizePointers.Reserve(NumOutStreams);
+ FOR_VECTOR (i, _streamBinders)
+ _streamBinders[i].ReInit();
+}
+
+void CMixerMT::SelectMainCoder(bool useFirst)
+{
+ unsigned ci = _bi.UnpackCoder;
+
+ if (!useFirst)
+ for (;;)
+ {
+ if (_coders[ci].NumStreams != 1)
+ break;
+ if (!IsFilter_Vector[ci])
+ break;
+
+ UInt32 st = _bi.Coder_to_Stream[ci];
+ if (_bi.IsStream_in_PackStreams(st))
+ break;
+ int bond = _bi.FindBond_for_PackStream(st);
+ if (bond < 0)
+ throw 20150213;
+ ci = _bi.Bonds[bond].UnpackIndex;
+ }
+
+ MainCoderIndex = ci;
}
-static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
- CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
+HRESULT CMixerMT::Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams)
{
- sizes.Clear();
- sizePointers.Clear();
- for(UInt32 i = 0; i < numItems; i++)
+ unsigned i;
+
+ for (i = 0; i < _coders.Size(); i++)
+ {
+ CCoderMT &coderInfo = _coders[i];
+ const CCoderStreamsInfo &csi = _bi.Coders[i];
+
+ UInt32 j;
+
+ unsigned numInStreams = EncodeMode ? 1 : csi.NumStreams;
+ unsigned numOutStreams = EncodeMode ? csi.NumStreams : 1;
+
+ coderInfo.InStreams.Clear();
+ for (j = 0; j < numInStreams; j++)
+ coderInfo.InStreams.AddNew();
+
+ coderInfo.OutStreams.Clear();
+ for (j = 0; j < numOutStreams; j++)
+ coderInfo.OutStreams.AddNew();
+ }
+
+ for (i = 0; i < _bi.Bonds.Size(); i++)
{
- if (srcSizes == 0 || srcSizes[i] == NULL)
+ const CBond &bond = _bi.Bonds[i];
+
+ UInt32 inCoderIndex, inCoderStreamIndex;
+ UInt32 outCoderIndex, outCoderStreamIndex;
+
+ {
+ UInt32 coderIndex, coderStreamIndex;
+ _bi.GetCoder_for_Stream(bond.PackIndex, coderIndex, coderStreamIndex);
+
+ inCoderIndex = EncodeMode ? bond.UnpackIndex : coderIndex;
+ outCoderIndex = EncodeMode ? coderIndex : bond.UnpackIndex;
+
+ inCoderStreamIndex = EncodeMode ? 0 : coderStreamIndex;
+ outCoderStreamIndex = EncodeMode ? coderStreamIndex : 0;
+ }
+
+ _streamBinders[i].CreateStreams(
+ &_coders[inCoderIndex].InStreams[inCoderStreamIndex],
+ &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
+
+ CMyComPtr<ICompressSetBufSize> inSetSize, outSetSize;
+ _coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize);
+ _coders[outCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&outSetSize);
+ if (inSetSize && outSetSize)
{
- sizes.Add(0);
- sizePointers.Add(NULL);
+ const UInt32 kBufSize = 1 << 19;
+ inSetSize->SetInBufSize(inCoderStreamIndex, kBufSize);
+ outSetSize->SetOutBufSize(outCoderStreamIndex, kBufSize);
}
+ }
+
+ {
+ CCoderMT &cod = _coders[_bi.UnpackCoder];
+ if (EncodeMode)
+ cod.InStreams[0] = inStreams[0];
+ else
+ cod.OutStreams[0] = outStreams[0];
+ }
+
+ for (i = 0; i < _bi.PackStreams.Size(); i++)
+ {
+ UInt32 coderIndex, coderStreamIndex;
+ _bi.GetCoder_for_Stream(_bi.PackStreams[i], coderIndex, coderStreamIndex);
+ CCoderMT &cod = _coders[coderIndex];
+ if (EncodeMode)
+ cod.OutStreams[coderStreamIndex] = outStreams[i];
else
+ cod.InStreams[coderStreamIndex] = inStreams[i];
+ }
+
+ return S_OK;
+}
+
+HRESULT CMixerMT::ReturnIfError(HRESULT code)
+{
+ FOR_VECTOR (i, _coders)
+ if (_coders[i].Result == code)
+ return code;
+ return S_OK;
+}
+
+HRESULT CMixerMT::Code(
+ ISequentialInStream * const *inStreams,
+ ISequentialOutStream * const *outStreams,
+ ICompressProgressInfo *progress)
+{
+ Init(inStreams, outStreams);
+
+ unsigned i;
+ for (i = 0; i < _coders.Size(); i++)
+ if (i != MainCoderIndex)
{
- sizes.Add(*srcSizes[i]);
- sizePointers.Add(&sizes.Back());
+ RINOK(_coders[i].Create());
}
+
+ for (i = 0; i < _coders.Size(); i++)
+ if (i != MainCoderIndex)
+ _coders[i].Start();
+
+ _coders[MainCoderIndex].Code(progress);
+
+ for (i = 0; i < _coders.Size(); i++)
+ if (i != MainCoderIndex)
+ _coders[i].WaitExecuteFinish();
+
+ RINOK(ReturnIfError(E_ABORT));
+ RINOK(ReturnIfError(E_OUTOFMEMORY));
+
+ for (i = 0; i < _coders.Size(); i++)
+ {
+ HRESULT result = _coders[i].Result;
+ if (result != S_OK
+ && result != k_My_HRESULT_WritingWasCut
+ && result != S_FALSE
+ && result != E_FAIL)
+ return result;
+ }
+
+ RINOK(ReturnIfError(S_FALSE));
+
+ for (i = 0; i < _coders.Size(); i++)
+ {
+ HRESULT result = _coders[i].Result;
+ if (result != S_OK && result != k_My_HRESULT_WritingWasCut)
+ return result;
}
+
+ return S_OK;
}
-void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes,
- const UInt64 **outSizes)
+UInt64 CMixerMT::GetBondStreamSize(unsigned bondIndex) const
{
- SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
- SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
+ return _streamBinders[bondIndex].ProcessedSize;
}
+#endif
+
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h
index a03722d61f1..e63f2ff0efa 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h
@@ -3,172 +3,435 @@
#ifndef __CODER_MIXER2_H
#define __CODER_MIXER2_H
-#include "../../../Common/MyVector.h"
-#include "../../../Common/Types.h"
#include "../../../Common/MyCom.h"
+#include "../../../Common/MyVector.h"
+
#include "../../ICoder.h"
-namespace NCoderMixer {
+#include "../../Common/CreateCoder.h"
+
+#ifdef _7ZIP_ST
+ #define USE_MIXER_ST
+#else
+ #define USE_MIXER_MT
+ #ifndef _SFX
+ #define USE_MIXER_ST
+ #endif
+#endif
+
+#ifdef USE_MIXER_MT
+#include "../../Common/StreamBinder.h"
+#include "../../Common/VirtThread.h"
+#endif
+
+
+
+#ifdef USE_MIXER_ST
+
+class CSequentialInStreamCalcSize:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ISequentialInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+private:
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _size;
+ bool _wasFinished;
+public:
+ void SetStream(ISequentialInStream *stream) { _stream = stream; }
+ void Init()
+ {
+ _size = 0;
+ _wasFinished = false;
+ }
+ void ReleaseStream() { _stream.Release(); }
+ UInt64 GetSize() const { return _size; }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+
+class COutStreamCalcSize:
+ public ISequentialOutStream,
+ public IOutStreamFinish,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _size;
+public:
+ MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStreamFinish)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(OutStreamFinish)();
+
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void ReleaseStream() { _stream.Release(); }
+ void Init() { _size = 0; }
+ UInt64 GetSize() const { return _size; }
+};
+
+#endif
+
+
+
+namespace NCoderMixer2 {
-struct CBindPair
+struct CBond
{
- UInt32 InIndex;
- UInt32 OutIndex;
+ UInt32 PackIndex;
+ UInt32 UnpackIndex;
+
+ UInt32 Get_InIndex(bool encodeMode) const { return encodeMode ? UnpackIndex : PackIndex; }
+ UInt32 Get_OutIndex(bool encodeMode) const { return encodeMode ? PackIndex : UnpackIndex; }
};
+
struct CCoderStreamsInfo
{
- UInt32 NumInStreams;
- UInt32 NumOutStreams;
+ UInt32 NumStreams;
};
+
struct CBindInfo
{
CRecordVector<CCoderStreamsInfo> Coders;
- CRecordVector<CBindPair> BindPairs;
- CRecordVector<UInt32> InStreams;
- CRecordVector<UInt32> OutStreams;
+ CRecordVector<CBond> Bonds;
+ CRecordVector<UInt32> PackStreams;
+ unsigned UnpackCoder;
- void Clear()
+ unsigned GetNum_Bonds_and_PackStreams() const { return Bonds.Size() + PackStreams.Size(); }
+
+ int FindBond_for_PackStream(UInt32 packStream) const
{
- Coders.Clear();
- BindPairs.Clear();
- InStreams.Clear();
- OutStreams.Clear();
+ FOR_VECTOR (i, Bonds)
+ if (Bonds[i].PackIndex == packStream)
+ return i;
+ return -1;
}
- /*
- UInt32 GetCoderStartOutStream(UInt32 coderIndex) const
+ int FindBond_for_UnpackStream(UInt32 unpackStream) const
{
- UInt32 numOutStreams = 0;
- for (UInt32 i = 0; i < coderIndex; i++)
- numOutStreams += Coders[i].NumOutStreams;
- return numOutStreams;
+ FOR_VECTOR (i, Bonds)
+ if (Bonds[i].UnpackIndex == unpackStream)
+ return i;
+ return -1;
}
- */
-
- void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const
+ bool SetUnpackCoder()
{
- numInStreams = 0;
- numOutStreams = 0;
- for (int i = 0; i < Coders.Size(); i++)
+ bool isOk = false;
+ FOR_VECTOR(i, Coders)
{
- const CCoderStreamsInfo &coderStreamsInfo = Coders[i];
- numInStreams += coderStreamsInfo.NumInStreams;
- numOutStreams += coderStreamsInfo.NumOutStreams;
+ if (FindBond_for_UnpackStream(i) < 0)
+ {
+ if (isOk)
+ return false;
+ UnpackCoder = i;
+ isOk = true;
+ }
}
+ return isOk;
}
-
- int FindBinderForInStream(UInt32 inStream) const
+
+ bool IsStream_in_PackStreams(UInt32 streamIndex) const
{
- for (int i = 0; i < BindPairs.Size(); i++)
- if (BindPairs[i].InIndex == inStream)
- return i;
- return -1;
+ return FindStream_in_PackStreams(streamIndex) >= 0;
}
- int FindBinderForOutStream(UInt32 outStream) const
+
+ int FindStream_in_PackStreams(UInt32 streamIndex) const
{
- for (int i = 0; i < BindPairs.Size(); i++)
- if (BindPairs[i].OutIndex == outStream)
+ FOR_VECTOR(i, PackStreams)
+ if (PackStreams[i] == streamIndex)
return i;
return -1;
}
- UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const
+
+ // that function is used before Maps is calculated
+
+ UInt32 GetStream_for_Coder(UInt32 coderIndex) const
{
UInt32 streamIndex = 0;
for (UInt32 i = 0; i < coderIndex; i++)
- streamIndex += Coders[i].NumInStreams;
+ streamIndex += Coders[i].NumStreams;
return streamIndex;
}
+
+ // ---------- Maps Section ----------
+
+ CRecordVector<UInt32> Coder_to_Stream;
+ CRecordVector<UInt32> Stream_to_Coder;
+
+ void ClearMaps();
+ bool CalcMapsAndCheck();
+
+ // ---------- End of Maps Section ----------
- UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const
+ void Clear()
{
- UInt32 streamIndex = 0;
- for (UInt32 i = 0; i < coderIndex; i++)
- streamIndex += Coders[i].NumOutStreams;
- return streamIndex;
+ Coders.Clear();
+ Bonds.Clear();
+ PackStreams.Clear();
+
+ ClearMaps();
}
+
+ void GetCoder_for_Stream(UInt32 streamIndex, UInt32 &coderIndex, UInt32 &coderStreamIndex) const
+ {
+ coderIndex = Stream_to_Coder[streamIndex];
+ coderStreamIndex = streamIndex - Coder_to_Stream[coderIndex];
+ }
+};
- void FindInStream(UInt32 streamIndex, UInt32 &coderIndex,
- UInt32 &coderStreamIndex) const
+
+class CCoder
+{
+ CLASS_NO_COPY(CCoder);
+public:
+ CMyComPtr<ICompressCoder> Coder;
+ CMyComPtr<ICompressCoder2> Coder2;
+ UInt32 NumStreams;
+
+ UInt64 UnpackSize;
+ const UInt64 *UnpackSizePointer;
+
+ CRecordVector<UInt64> PackSizes;
+ CRecordVector<const UInt64 *> PackSizePointers;
+
+ CCoder() {}
+
+ void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes);
+
+ IUnknown *GetUnknown() const
{
- for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
- {
- UInt32 curSize = Coders[coderIndex].NumInStreams;
- if (streamIndex < curSize)
- {
- coderStreamIndex = streamIndex;
- return;
- }
- streamIndex -= curSize;
- }
- throw 1;
+ return Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;
}
- void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex,
- UInt32 &coderStreamIndex) const
+
+ HRESULT QueryInterface(REFGUID iid, void** pp) const
{
- for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
- {
- UInt32 curSize = Coders[coderIndex].NumOutStreams;
- if (streamIndex < curSize)
+ return GetUnknown()->QueryInterface(iid, pp);
+ }
+};
+
+
+
+class CMixer
+{
+ bool Is_PackSize_Correct_for_Stream(UInt32 streamIndex);
+
+protected:
+ CBindInfo _bi;
+
+ int FindBond_for_Stream(bool forInputStream, UInt32 streamIndex) const
+ {
+ if (EncodeMode == forInputStream)
+ return _bi.FindBond_for_UnpackStream(streamIndex);
+ else
+ return _bi.FindBond_for_PackStream(streamIndex);
+ }
+
+ CBoolVector IsFilter_Vector;
+ CBoolVector IsExternal_Vector;
+ bool EncodeMode;
+public:
+ unsigned MainCoderIndex;
+
+ CMixer(bool encodeMode):
+ EncodeMode(encodeMode),
+ MainCoderIndex(0)
+ {}
+
+ /*
+ Sequence of calling:
+
+ SetBindInfo();
+ for each coder
+ AddCoder();
+ SelectMainCoder();
+
+ for each file
{
- coderStreamIndex = streamIndex;
- return;
+ ReInit()
+ for each coder
+ SetCoderInfo();
+ Code();
}
- streamIndex -= curSize;
- }
- throw 1;
+ */
+
+ virtual HRESULT SetBindInfo(const CBindInfo &bindInfo)
+ {
+ _bi = bindInfo;
+ IsFilter_Vector.Clear();
+ MainCoderIndex = 0;
+ return S_OK;
}
+
+ virtual void AddCoder(const CCreatedCoder &cod) = 0;
+ virtual CCoder &GetCoder(unsigned index) = 0;
+ virtual void SelectMainCoder(bool useFirst) = 0;
+ virtual void ReInit() = 0;
+ virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes) = 0;
+ virtual HRESULT Code(
+ ISequentialInStream * const *inStreams,
+ ISequentialOutStream * const *outStreams,
+ ICompressProgressInfo *progress) = 0;
+ virtual UInt64 GetBondStreamSize(unsigned bondIndex) const = 0;
+
+ bool Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex);
+ bool Is_PackSize_Correct_for_Coder(UInt32 coderIndex);
+ bool IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex);
};
-class CBindReverseConverter
+
+
+
+#ifdef USE_MIXER_ST
+
+struct CCoderST: public CCoder
{
- UInt32 _numSrcOutStreams;
- NCoderMixer::CBindInfo _srcBindInfo;
- CRecordVector<UInt32> _srcInToDestOutMap;
- CRecordVector<UInt32> _srcOutToDestInMap;
- CRecordVector<UInt32> _destInToSrcOutMap;
-public:
- UInt32 NumSrcInStreams;
- CRecordVector<UInt32> DestOutToSrcInMap;
+ bool CanRead;
+ bool CanWrite;
+
+ CCoderST(): CanRead(false), CanWrite(false) {}
+};
- CBindReverseConverter(const NCoderMixer::CBindInfo &srcBindInfo);
- void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo);
+
+struct CStBinderStream
+{
+ CSequentialInStreamCalcSize *InStreamSpec;
+ COutStreamCalcSize *OutStreamSpec;
+ CMyComPtr<IUnknown> StreamRef;
+
+ CStBinderStream(): InStreamSpec(NULL), OutStreamSpec(NULL) {}
};
-struct CCoderInfo2
+
+class CMixerST:
+ public IUnknown,
+ public CMixer,
+ public CMyUnknownImp
{
- CMyComPtr<ICompressCoder> Coder;
- CMyComPtr<ICompressCoder2> Coder2;
- UInt32 NumInStreams;
- UInt32 NumOutStreams;
+ HRESULT GetInStream2(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
+ UInt32 outStreamIndex, ISequentialInStream **inStreamRes);
+ HRESULT GetInStream(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
+ UInt32 inStreamIndex, ISequentialInStream **inStreamRes);
+ HRESULT GetOutStream(ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */
+ UInt32 outStreamIndex, ISequentialOutStream **outStreamRes);
- CRecordVector<UInt64> InSizes;
- CRecordVector<UInt64> OutSizes;
- CRecordVector<const UInt64 *> InSizePointers;
- CRecordVector<const UInt64 *> OutSizePointers;
+ HRESULT FinishStream(UInt32 streamIndex);
+ HRESULT FinishCoder(UInt32 coderIndex);
- CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams);
- void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
+public:
+ CObjectVector<CCoderST> _coders;
+
+ CObjectVector<CStBinderStream> _binderStreams;
- HRESULT QueryInterface(REFGUID iid, void** pp) const
+ MY_UNKNOWN_IMP
+
+ CMixerST(bool encodeMode);
+ ~CMixerST();
+
+ virtual void AddCoder(const CCreatedCoder &cod);
+ virtual CCoder &GetCoder(unsigned index);
+ virtual void SelectMainCoder(bool useFirst);
+ virtual void ReInit();
+ virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes)
+ { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); }
+ virtual HRESULT Code(
+ ISequentialInStream * const *inStreams,
+ ISequentialOutStream * const *outStreams,
+ ICompressProgressInfo *progress);
+ virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
+
+ HRESULT GetMainUnpackStream(
+ ISequentialInStream * const *inStreams,
+ ISequentialInStream **inStreamRes);
+};
+
+#endif
+
+
+
+
+#ifdef USE_MIXER_MT
+
+class CCoderMT: public CCoder, public CVirtThread
+{
+ CLASS_NO_COPY(CCoderMT)
+ CRecordVector<ISequentialInStream*> InStreamPointers;
+ CRecordVector<ISequentialOutStream*> OutStreamPointers;
+
+private:
+ void Execute();
+public:
+ bool EncodeMode;
+ HRESULT Result;
+ CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
+ CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
+
+ void Release()
{
- IUnknown *p = Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;
- return p->QueryInterface(iid, pp);
+ InStreamPointers.Clear();
+ OutStreamPointers.Clear();
+ unsigned i;
+ for (i = 0; i < InStreams.Size(); i++)
+ InStreams[i].Release();
+ for (i = 0; i < OutStreams.Size(); i++)
+ OutStreams[i].Release();
}
+
+ class CReleaser
+ {
+ CLASS_NO_COPY(CReleaser)
+ CCoderMT &_c;
+ public:
+ CReleaser(CCoderMT &c): _c(c) {}
+ ~CReleaser() { _c.Release(); }
+ };
+
+ CCoderMT(): EncodeMode(false) {}
+ ~CCoderMT() { CVirtThread::WaitThreadFinish(); }
+
+ void Code(ICompressProgressInfo *progress);
};
-class CCoderMixer2
+
+class CMixerMT:
+ public IUnknown,
+ public CMixer,
+ public CMyUnknownImp
{
+ CObjectVector<CStreamBinder> _streamBinders;
+
+ HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams);
+ HRESULT ReturnIfError(HRESULT code);
+
public:
- virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) = 0;
- virtual void ReInit() = 0;
- virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0;
+ CObjectVector<CCoderMT> _coders;
+
+ MY_UNKNOWN_IMP
+
+ virtual HRESULT SetBindInfo(const CBindInfo &bindInfo);
+ virtual void AddCoder(const CCreatedCoder &cod);
+ virtual CCoder &GetCoder(unsigned index);
+ virtual void SelectMainCoder(bool useFirst);
+ virtual void ReInit();
+ virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes)
+ { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); }
+ virtual HRESULT Code(
+ ISequentialInStream * const *inStreams,
+ ISequentialOutStream * const *outStreams,
+ ICompressProgressInfo *progress);
+ virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
+
+ CMixerMT(bool encodeMode): CMixer(encodeMode) {}
};
-}
#endif
+}
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
deleted file mode 100644
index 87686e858e9..00000000000
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
+++ /dev/null
@@ -1,240 +0,0 @@
-// CoderMixer2MT.cpp
-
-#include "StdAfx.h"
-
-#include "CoderMixer2MT.h"
-
-namespace NCoderMixer {
-
-CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams):
- CCoderInfo2(numInStreams, numOutStreams)
-{
- InStreams.Reserve(NumInStreams);
- InStreamPointers.Reserve(NumInStreams);
- OutStreams.Reserve(NumOutStreams);
- OutStreamPointers.Reserve(NumOutStreams);
-}
-
-void CCoder2::Execute() { Code(NULL); }
-
-void CCoder2::Code(ICompressProgressInfo *progress)
-{
- InStreamPointers.Clear();
- OutStreamPointers.Clear();
- UInt32 i;
- for (i = 0; i < NumInStreams; i++)
- {
- if (InSizePointers[i] != NULL)
- InSizePointers[i] = &InSizes[i];
- InStreamPointers.Add((ISequentialInStream *)InStreams[i]);
- }
- for (i = 0; i < NumOutStreams; i++)
- {
- if (OutSizePointers[i] != NULL)
- OutSizePointers[i] = &OutSizes[i];
- OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]);
- }
- if (Coder)
- Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],
- InSizePointers[0], OutSizePointers[0], progress);
- else
- Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams,
- &OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress);
- {
- int i;
- for (i = 0; i < InStreams.Size(); i++)
- InStreams[i].Release();
- for (i = 0; i < OutStreams.Size(); i++)
- OutStreams[i].Release();
- }
-}
-
-static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
- CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
-{
- sizes.Clear();
- sizePointers.Clear();
- for (UInt32 i = 0; i < numItems; i++)
- {
- if (srcSizes == 0 || srcSizes[i] == NULL)
- {
- sizes.Add(0);
- sizePointers.Add(NULL);
- }
- else
- {
- sizes.Add(*srcSizes[i]);
- sizePointers.Add(&sizes.Back());
- }
- }
-}
-
-
-void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)
-{
- SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
- SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
-}
-
-//////////////////////////////////////
-// CCoderMixer2MT
-
-HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
-{
- _bindInfo = bindInfo;
- _streamBinders.Clear();
- for (int i = 0; i < _bindInfo.BindPairs.Size(); i++)
- {
- _streamBinders.Add(CStreamBinder());
- RINOK(_streamBinders.Back().CreateEvents());
- }
- return S_OK;
-}
-
-void CCoderMixer2MT::AddCoderCommon()
-{
- const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()];
- CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams);
- _coders.Add(threadCoderInfo);
-}
-
-void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
-{
- AddCoderCommon();
- _coders.Back().Coder = coder;
-}
-
-void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
-{
- AddCoderCommon();
- _coders.Back().Coder2 = coder;
-}
-
-
-void CCoderMixer2MT::ReInit()
-{
- for (int i = 0; i < _streamBinders.Size(); i++)
- _streamBinders[i].ReInit();
-}
-
-
-HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams)
-{
- /*
- if (_coders.Size() != _bindInfo.Coders.Size())
- throw 0;
- */
- int i;
- for (i = 0; i < _coders.Size(); i++)
- {
- CCoder2 &coderInfo = _coders[i];
- const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
- coderInfo.InStreams.Clear();
- UInt32 j;
- for (j = 0; j < coderStreamsInfo.NumInStreams; j++)
- coderInfo.InStreams.Add(NULL);
- coderInfo.OutStreams.Clear();
- for (j = 0; j < coderStreamsInfo.NumOutStreams; j++)
- coderInfo.OutStreams.Add(NULL);
- }
-
- for (i = 0; i < _bindInfo.BindPairs.Size(); i++)
- {
- const CBindPair &bindPair = _bindInfo.BindPairs[i];
- UInt32 inCoderIndex, inCoderStreamIndex;
- UInt32 outCoderIndex, outCoderStreamIndex;
- _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
- _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
-
- _streamBinders[i].CreateStreams(
- &_coders[inCoderIndex].InStreams[inCoderStreamIndex],
- &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
-
- CMyComPtr<ICompressSetBufSize> inSetSize, outSetSize;
- _coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize);
- _coders[outCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&outSetSize);
- if (inSetSize && outSetSize)
- {
- const UInt32 kBufSize = 1 << 19;
- inSetSize->SetInBufSize(inCoderStreamIndex, kBufSize);
- outSetSize->SetOutBufSize(outCoderStreamIndex, kBufSize);
- }
- }
-
- for (i = 0; i < _bindInfo.InStreams.Size(); i++)
- {
- UInt32 inCoderIndex, inCoderStreamIndex;
- _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
- _coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
- }
-
- for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
- {
- UInt32 outCoderIndex, outCoderStreamIndex;
- _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
- _coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
- }
- return S_OK;
-}
-
-HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)
-{
- for (int i = 0; i < _coders.Size(); i++)
- if (_coders[i].Result == code)
- return code;
- return S_OK;
-}
-
-STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
- const UInt64 ** /* inSizes */,
- UInt32 numInStreams,
- ISequentialOutStream **outStreams,
- const UInt64 ** /* outSizes */,
- UInt32 numOutStreams,
- ICompressProgressInfo *progress)
-{
- if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
- numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
- return E_INVALIDARG;
-
- Init(inStreams, outStreams);
-
- int i;
- for (i = 0; i < _coders.Size(); i++)
- if (i != _progressCoderIndex)
- {
- RINOK(_coders[i].Create());
- }
-
- for (i = 0; i < _coders.Size(); i++)
- if (i != _progressCoderIndex)
- _coders[i].Start();
-
- _coders[_progressCoderIndex].Code(progress);
-
- for (i = 0; i < _coders.Size(); i++)
- if (i != _progressCoderIndex)
- _coders[i].WaitExecuteFinish();
-
- RINOK(ReturnIfError(E_ABORT));
- RINOK(ReturnIfError(E_OUTOFMEMORY));
-
- for (i = 0; i < _coders.Size(); i++)
- {
- HRESULT result = _coders[i].Result;
- if (result != S_OK && result != E_FAIL && result != S_FALSE)
- return result;
- }
-
- RINOK(ReturnIfError(S_FALSE));
-
- for (i = 0; i < _coders.Size(); i++)
- {
- HRESULT result = _coders[i].Result;
- if (result != S_OK)
- return result;
- }
- return S_OK;
-}
-
-}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.h b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.h
deleted file mode 100644
index 81bb3f0bba9..00000000000
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// CoderMixer2MT.h
-
-#ifndef __CODER_MIXER2_MT_H
-#define __CODER_MIXER2_MT_H
-
-#include "CoderMixer2.h"
-#include "../../../Common/MyCom.h"
-#include "../../Common/StreamBinder.h"
-#include "../../Common/VirtThread.h"
-
-namespace NCoderMixer {
-
-struct CCoder2: public CCoderInfo2, public CVirtThread
-{
- HRESULT Result;
- CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
- CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
- CRecordVector<ISequentialInStream*> InStreamPointers;
- CRecordVector<ISequentialOutStream*> OutStreamPointers;
-
- CCoder2(UInt32 numInStreams, UInt32 numOutStreams);
- ~CCoder2() { CVirtThread::WaitThreadFinish(); }
- void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
- virtual void Execute();
- void Code(ICompressProgressInfo *progress);
-};
-
-
-/*
- SetBindInfo()
- for each coder
- AddCoder[2]()
- SetProgressIndex(UInt32 coderIndex);
-
- for each file
- {
- ReInit()
- for each coder
- SetCoderInfo
- Code
- }
-*/
-
-class CCoderMixer2MT:
- public ICompressCoder2,
- public CCoderMixer2,
- public CMyUnknownImp
-{
- CBindInfo _bindInfo;
- CObjectVector<CStreamBinder> _streamBinders;
- int _progressCoderIndex;
-
- void AddCoderCommon();
- HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams);
- HRESULT ReturnIfError(HRESULT code);
-public:
- CObjectVector<CCoder2> _coders;
- MY_UNKNOWN_IMP
-
- STDMETHOD(Code)(ISequentialInStream **inStreams,
- const UInt64 **inSizes,
- UInt32 numInStreams,
- ISequentialOutStream **outStreams,
- const UInt64 **outSizes,
- UInt32 numOutStreams,
- ICompressProgressInfo *progress);
-
- HRESULT SetBindInfo(const CBindInfo &bindInfo);
- void AddCoder(ICompressCoder *coder);
- void AddCoder2(ICompressCoder2 *coder);
- void SetProgressCoderIndex(int coderIndex) { _progressCoderIndex = coderIndex; }
-
- void ReInit();
- void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)
- { _coders[coderIndex].SetCoderInfo(inSizes, outSizes); }
- UInt64 GetWriteProcessedSize(UInt32 binderIndex) const
- { return _streamBinders[binderIndex].ProcessedSize; }
-};
-
-}
-#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
deleted file mode 100644
index a974b54c7e6..00000000000
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-// CrossThreadProgress.cpp
-
-#include "StdAfx.h"
-
-#include "CrossThreadProgress.h"
-
-STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
-{
- InSize = inSize;
- OutSize = outSize;
- ProgressEvent.Set();
- WaitEvent.Lock();
- return Result;
-}
-
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.h b/3rdparty/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.h
deleted file mode 100644
index 7e0b10538f3..00000000000
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// CrossThreadProgress.h
-
-#ifndef __CROSSTHREADPROGRESS_H
-#define __CROSSTHREADPROGRESS_H
-
-#include "../../ICoder.h"
-#include "../../../Windows/Synchronization.h"
-#include "../../../Common/MyCom.h"
-
-class CCrossThreadProgress:
- public ICompressProgressInfo,
- public CMyUnknownImp
-{
-public:
- const UInt64 *InSize;
- const UInt64 *OutSize;
- HRESULT Result;
- NWindows::NSynchronization::CAutoResetEvent ProgressEvent;
- NWindows::NSynchronization::CAutoResetEvent WaitEvent;
-
- HRes Create()
- {
- RINOK(ProgressEvent.CreateIfNotCreated());
- return WaitEvent.CreateIfNotCreated();
- }
- void Init()
- {
- ProgressEvent.Reset();
- WaitEvent.Reset();
- }
-
- MY_UNKNOWN_IMP
-
- STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
-};
-
-#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp
index 54bcfec1108..7c4f54879de 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp
@@ -4,19 +4,14 @@
#include "DummyOutStream.h"
-STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- UInt32 realProcessedSize;
- HRESULT result;
- if(!_stream)
- {
- realProcessedSize = size;
- result = S_OK;
- }
- else
- result = _stream->Write(data, size, &realProcessedSize);
+ UInt32 realProcessedSize = size;
+ HRESULT res = S_OK;
+ if (_stream)
+ res = _stream->Write(data, size, &realProcessedSize);
_size += realProcessedSize;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
- return result;
+ return res;
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h b/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h
index 13d5b62ca78..b5a51fc0755 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h
@@ -1,10 +1,11 @@
// DummyOutStream.h
-#ifndef __DUMMYOUTSTREAM_H
-#define __DUMMYOUTSTREAM_H
+#ifndef __DUMMY_OUT_STREAM_H
+#define __DUMMY_OUT_STREAM_H
+
+#include "../../../Common/MyCom.h"
#include "../../IStream.h"
-#include "Common/MyCom.h"
class CDummyOutStream:
public ISequentialOutStream,
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp
index 7e6f460226a..95381ea31d6 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp
@@ -27,8 +27,9 @@ void CMultiMethodProps::SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
)
{
UInt32 level = _level;
- if (level != (UInt32)(UInt32)-1)
+ if (level != (UInt32)(Int32)-1)
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
+
#ifndef _7ZIP_ST
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
#endif
@@ -40,7 +41,9 @@ void CMultiMethodProps::Init()
_numProcessors = _numThreads = NSystem::GetNumberOfProcessors();
#endif
- _level = (UInt32)(UInt32)-1;
+ _level = (UInt32)(Int32)-1;
+ _analysisLevel = -1;
+
_autoFilter = true;
_crcSize = 4;
_filterMethod.Clear();
@@ -50,18 +53,27 @@ void CMultiMethodProps::Init()
HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
UString name = nameSpec;
- name.MakeUpper();
+ name.MakeLower_Ascii();
if (name.IsEmpty())
return E_INVALIDARG;
- if (name[0] == 'X')
+ if (name[0] == 'x')
{
name.Delete(0);
_level = 9;
return ParsePropToUInt32(name, value, _level);
}
+
+ if (name.IsPrefixedBy_Ascii_NoCase("yx"))
+ {
+ name.Delete(0, 2);
+ UInt32 v = 9;
+ RINOK(ParsePropToUInt32(name, value, v));
+ _analysisLevel = (int)v;
+ return S_OK;
+ }
- if (name == L"CRC")
+ if (name.IsEqualTo("crc"))
{
name.Delete(0, 3);
_crcSize = 4;
@@ -70,24 +82,25 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
UInt32 number;
int index = ParseStringToUInt32(name, number);
- UString realName = name.Mid(index);
+ UString realName = name.Ptr(index);
if (index == 0)
{
- if (name.Left(2).CompareNoCase(L"MT") == 0)
+ if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
#ifndef _7ZIP_ST
- RINOK(ParseMtProp(name.Mid(2), value, _numProcessors, _numThreads));
+ RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads));
#endif
+
return S_OK;
}
- if (name.CompareNoCase(L"F") == 0)
+ if (name.IsEqualTo("f"))
{
HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
if (res == S_OK)
return res;
if (value.vt != VT_BSTR)
return E_INVALIDARG;
- return _filterMethod.ParseMethodFromPROPVARIANT(L"", value);
+ return _filterMethod.ParseMethodFromPROPVARIANT(UString(), value);
}
number = 0;
}
@@ -101,39 +114,42 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
void CSingleMethodProps::Init()
{
Clear();
+ _level = (UInt32)(Int32)-1;
+
#ifndef _7ZIP_ST
_numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
- AddNumThreadsProp(_numThreads);
+ AddProp_NumThreads(_numThreads);
#endif
- _level = (UInt32)(UInt32)-1;
}
-HRESULT CSingleMethodProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
+HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
Init();
- for (int i = 0; i < numProps; i++)
+ for (UInt32 i = 0; i < numProps; i++)
{
UString name = names[i];
- name.MakeUpper();
+ name.MakeLower_Ascii();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
- if (name[0] == L'X')
+ if (name[0] == L'x')
{
UInt32 a = 9;
- RINOK(ParsePropToUInt32(name.Mid(1), value, a));
+ RINOK(ParsePropToUInt32(name.Ptr(1), value, a));
_level = a;
- AddLevelProp(a);
+ AddProp_Level(a);
}
- else if (name.Left(2).CompareNoCase(L"MT") == 0)
+ else if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
#ifndef _7ZIP_ST
- RINOK(ParseMtProp(name.Mid(2), value, _numProcessors, _numThreads));
- AddNumThreadsProp(_numThreads);
+ RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads));
+ AddProp_NumThreads(_numThreads);
#endif
}
else
- return ParseParamsFromPROPVARIANT(name, value);
+ {
+ RINOK(ParseMethodFromPROPVARIANT(names[i], value));
+ }
}
return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h b/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h
index d3c9a237ddc..5a18d9802b3 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h
@@ -10,6 +10,7 @@ namespace NArchive {
class CMultiMethodProps
{
UInt32 _level;
+ int _analysisLevel;
public:
#ifndef _7ZIP_ST
UInt32 _numThreads;
@@ -27,16 +28,17 @@ public:
#endif
);
- int GetNumEmptyMethods() const
+ unsigned GetNumEmptyMethods() const
{
- int i;
+ unsigned i;
for (i = 0; i < _methods.Size(); i++)
if (!_methods[i].IsEmpty())
break;
return i;
}
- int GetLevel() const { return _level == (UInt32)(UInt32)-1 ? 5 : (int)_level; }
+ int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; }
+ int GetAnalysisLevel() const { return _analysisLevel; }
void Init();
@@ -44,20 +46,20 @@ public:
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
-class CSingleMethodProps: public CMethodProps
+class CSingleMethodProps: public COneMethodInfo
{
UInt32 _level;
- void Init();
public:
#ifndef _7ZIP_ST
UInt32 _numThreads;
UInt32 _numProcessors;
#endif
+ void Init();
CSingleMethodProps() { Init(); }
- int GetLevel() const { return _level == (UInt32)(UInt32)-1 ? 5 : (int)_level; }
- HRESULT SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
+ int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; }
+ HRESULT SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
};
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
index 569a56f3bee..a2d68832838 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
@@ -6,29 +6,33 @@
STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- UInt32 realProcessedSize;
- HRESULT result = _stream->Read(data, size, &realProcessedSize);
- _size += realProcessedSize;
- if (size > 0 && realProcessedSize == 0)
+ UInt32 realProcessed = 0;
+ HRESULT result = S_OK;
+ if (_stream)
+ result = _stream->Read(data, size, &realProcessed);
+ _size += realProcessed;
+ if (size != 0 && realProcessed == 0)
_wasFinished = true;
- _crc = CrcUpdate(_crc, data, realProcessedSize);
- if(processedSize != NULL)
- *processedSize = realProcessedSize;
+ _crc = CrcUpdate(_crc, data, realProcessed);
+ if (processedSize)
+ *processedSize = realProcessed;
return result;
}
STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- UInt32 realProcessedSize;
- HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ UInt32 realProcessed = 0;
+ HRESULT result = S_OK;
+ if (_stream)
+ result = _stream->Read(data, size, &realProcessed);
+ _size += realProcessed;
/*
- if (size > 0 && realProcessedSize == 0)
+ if (size != 0 && realProcessed == 0)
_wasFinished = true;
*/
- _size += realProcessedSize;
- _crc = CrcUpdate(_crc, data, realProcessedSize);
- if(processedSize != NULL)
- *processedSize = realProcessedSize;
+ _crc = CrcUpdate(_crc, data, realProcessed);
+ if (processedSize)
+ *processedSize = realProcessed;
return result;
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp
index cc476fadd9d..7cd3037be50 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp
@@ -2,8 +2,6 @@
#include "StdAfx.h"
-#include "../../../../C/Types.h"
-
#include "ItemNameUtils.h"
namespace NArchive {
@@ -12,6 +10,21 @@ namespace NItemName {
static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR;
static const wchar_t kDirDelimiter = L'/';
+void ReplaceToOsPathSeparator(wchar_t *s)
+{
+ #ifdef _WIN32
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c == 0)
+ break;
+ if (c == kDirDelimiter)
+ *s = kOSDirDelimiter;
+ s++;
+ }
+ #endif
+}
+
UString MakeLegalName(const UString &name)
{
UString zipName = name;
@@ -36,15 +49,29 @@ UString GetOSName2(const UString &name)
return newName;
}
-bool HasTailSlash(const AString &name, UINT codePage)
+void ConvertToOSName2(UString &name)
+{
+ if (!name.IsEmpty())
+ {
+ name.Replace(kDirDelimiter, kOSDirDelimiter);
+ if (name.Back() == kOSDirDelimiter)
+ name.DeleteBack();
+ }
+}
+
+bool HasTailSlash(const AString &name, UINT
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ codePage
+ #endif
+ )
{
if (name.IsEmpty())
return false;
LPCSTR prev =
#if defined(_WIN32) && !defined(UNDER_CE)
- CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);
+ CharPrevExA((WORD)codePage, name, &name[name.Len()], 0);
#else
- (LPCSTR)(name) + (name.Length() - 1);
+ (LPCSTR)(name) + (name.Len() - 1);
#endif
return (*prev == '/');
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h b/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h
index 5eafacb12e0..d0dc76a4109 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h
@@ -1,16 +1,19 @@
// Archive/Common/ItemNameUtils.h
-#ifndef __ARCHIVE_ITEMNAMEUTILS_H
-#define __ARCHIVE_ITEMNAMEUTILS_H
+#ifndef __ARCHIVE_ITEM_NAME_UTILS_H
+#define __ARCHIVE_ITEM_NAME_UTILS_H
#include "../../../Common/MyString.h"
namespace NArchive {
namespace NItemName {
+ void ReplaceToOsPathSeparator(wchar_t *s);
+
UString MakeLegalName(const UString &name);
UString GetOSName(const UString &name);
UString GetOSName2(const UString &name);
+ void ConvertToOSName2(UString &name);
bool HasTailSlash(const AString &name, UINT codePage);
#ifdef _WIN32
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp
index 04d11cafb43..1de74afe43e 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp
@@ -11,10 +11,10 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
if (size == 0)
return S_OK;
if (_pos >= _totalLength)
- return (_pos == _totalLength) ? S_OK : E_FAIL;
+ return S_OK;
{
- int left = 0, mid = _streamIndex, right = Streams.Size();
+ unsigned left = 0, mid = _streamIndex, right = Streams.Size();
for (;;)
{
CSubStreamInfo &m = Streams[mid];
@@ -51,15 +51,18 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET: _pos = offset; break;
- case STREAM_SEEK_CUR: _pos = _pos + offset; break;
- case STREAM_SEEK_END: _pos = _totalLength + offset; break;
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _pos; break;
+ case STREAM_SEEK_END: offset += _totalLength; break;
default: return STG_E_INVALIDFUNCTION;
}
- if (newPosition != 0)
- *newPosition = _pos;
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _pos = offset;
+ if (newPosition)
+ *newPosition = offset;
return S_OK;
}
@@ -69,7 +72,7 @@ class COutVolumeStream:
public ISequentialOutStream,
public CMyUnknownImp
{
- int _volIndex;
+ unsigned _volIndex;
UInt64 _volSize;
UInt64 _curPos;
CMyComPtr<ISequentialOutStream> _volumeStream;
@@ -116,9 +119,9 @@ HRESULT COutVolumeStream::Flush()
/*
STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
- while(size > 0)
+ while (size > 0)
{
if (_streamIndex >= Streams.Size())
{
@@ -154,7 +157,7 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce
_absPos += realProcessed;
if (_absPos > _length)
_length = _absPos;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize += realProcessed;
if (subStream.Pos == subStream.Size)
{
@@ -169,22 +172,20 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce
STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- if(seekOrigin >= 3)
- return STG_E_INVALIDFUNCTION;
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET:
- _absPos = offset;
- break;
- case STREAM_SEEK_CUR:
- _absPos += offset;
- break;
- case STREAM_SEEK_END:
- _absPos = _length + offset;
- break;
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _absPos; break;
+ case STREAM_SEEK_END: offset += _length; break;
+ default: return STG_E_INVALIDFUNCTION;
}
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _absPos = offset;
_offsetPos = _absPos;
_streamIndex = 0;
+ if (newPosition)
+ *newPosition = offset;
return S_OK;
}
*/
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h b/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h
index 3fceb7ccee5..c10cd455729 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h
@@ -14,21 +14,26 @@ class CMultiStream:
{
UInt64 _pos;
UInt64 _totalLength;
- int _streamIndex;
+ unsigned _streamIndex;
+
public:
+
struct CSubStreamInfo
{
CMyComPtr<IInStream> Stream;
UInt64 Size;
UInt64 GlobalOffset;
UInt64 LocalPos;
+
+ CSubStreamInfo(): Size(0), GlobalOffset(0), LocalPos(0) {}
};
+
CObjectVector<CSubStreamInfo> Streams;
HRESULT Init()
{
UInt64 total = 0;
- for (int i = 0; i < Streams.Size(); i++)
+ FOR_VECTOR (i, Streams)
{
CSubStreamInfo &s = Streams[i];
s.GlobalOffset = total;
@@ -52,7 +57,7 @@ class COutMultiStream:
public IOutStream,
public CMyUnknownImp
{
- int _streamIndex; // required stream
+ unsigned _streamIndex; // required stream
UInt64 _offsetPos; // offset from start of _streamIndex index
UInt64 _absPos;
UInt64 _length;
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h b/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h
index 115b442aa3d..09b899bbd74 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h
@@ -28,6 +28,7 @@ public:
_calculate = calculate;
_crc = CRC_INIT_VAL;
}
+ void EnableCalc(bool calculate) { _calculate = calculate; }
void InitCRC() { _crc = CRC_INIT_VAL; }
UInt64 GetSize() const { return _size; }
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h b/3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h
index 2e4be10b291..2854ff3e935 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../../Common/MyWindows.h"
-#include "../../../Common/NewHandler.h"
+#include "../../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp b/3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp
index ad14ff06a94..10889e75521 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp
@@ -1,10 +1,12 @@
-// DLLExports.cpp
+// DLLExports2.cpp
#include "StdAfx.h"
+#include "../../Common/MyWindows.h"
+
#include "../../Common/MyInitGuid.h"
-#if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
+#if defined(_7ZIP_LARGE_PAGES)
#include "../../../C/Alloc.h"
#endif
@@ -16,12 +18,15 @@
#include "../ICoder.h"
#include "../IPassword.h"
+#include "../Common/CreateCoder.h"
+
#include "IArchive.h"
HINSTANCE g_hInstance;
#define NT_CHECK_FAIL_ACTION return FALSE;
+#ifdef _WIN32
extern "C"
BOOL WINAPI DllMain(
#ifdef UNDER_CE
@@ -33,42 +38,85 @@ BOOL WINAPI DllMain(
{
if (dwReason == DLL_PROCESS_ATTACH)
{
+ // OutputDebugStringA("7z.dll DLL_PROCESS_ATTACH");
g_hInstance = (HINSTANCE)hInstance;
NT_CHECK;
}
+ /*
+ if (dwReason == DLL_PROCESS_DETACH)
+ {
+ OutputDebugStringA("7z.dll DLL_PROCESS_DETACH");
+ }
+ */
return TRUE;
}
+#endif
DEFINE_GUID(CLSID_CArchiveHandler,
-0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
-
-static const UInt16 kDecodeId = 0x2790;
-
-DEFINE_GUID(CLSID_CCodec,
-0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ k_7zip_GUID_Data1,
+ k_7zip_GUID_Data2,
+ k_7zip_GUID_Data3_Common,
+ 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject);
-STDAPI CreateArchiver(const GUID *classID, const GUID *iid, void **outObject);
+STDAPI CreateHasher(const GUID *clsid, IHasher **hasher);
+STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject);
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
{
// COM_TRY_BEGIN
*outObject = 0;
- if (*iid == IID_ICompressCoder || *iid == IID_ICompressCoder2 || *iid == IID_ICompressFilter)
- {
+ if (*iid == IID_ICompressCoder ||
+ *iid == IID_ICompressCoder2 ||
+ *iid == IID_ICompressFilter)
return CreateCoder(clsid, iid, outObject);
- }
- else
- {
- return CreateArchiver(clsid, iid, outObject);
- }
+ if (*iid == IID_IHasher)
+ return CreateHasher(clsid, (IHasher **)outObject);
+ return CreateArchiver(clsid, iid, outObject);
// COM_TRY_END
}
STDAPI SetLargePageMode()
{
- #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
+ #if defined(_7ZIP_LARGE_PAGES)
SetLargePageSize();
#endif
return S_OK;
}
+
+extern bool g_CaseSensitive;
+
+STDAPI SetCaseSensitive(Int32 caseSensitive)
+{
+ g_CaseSensitive = (caseSensitive != 0);
+ return S_OK;
+}
+
+#ifdef EXTERNAL_CODECS
+
+CExternalCodecs g_ExternalCodecs;
+
+STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo)
+{
+ COM_TRY_BEGIN
+
+ // OutputDebugStringA(compressCodecsInfo ? "SetCodecs" : "SetCodecs NULL");
+ if (compressCodecsInfo)
+ {
+ g_ExternalCodecs.GetCodecs = compressCodecsInfo;
+ return g_ExternalCodecs.Load();
+ }
+ g_ExternalCodecs.ClearAndRelease();
+ return S_OK;
+
+ COM_TRY_END
+}
+
+#else
+
+STDAPI SetCodecs(ICompressCodecsInfo *)
+{
+ return S_OK;
+}
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/IArchive.h b/3rdparty/lzma/CPP/7zip/Archive/IArchive.h
index 853202767e6..0028d76246b 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/IArchive.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/IArchive.h
@@ -20,20 +20,43 @@ namespace NFileTimeType
};
}
+namespace NArcInfoFlags
+{
+ const UInt32 kKeepName = 1 << 0; // keep name of file in archive name
+ const UInt32 kAltStreams = 1 << 1; // the handler supports alt streams
+ const UInt32 kNtSecure = 1 << 2; // the handler supports NT security
+ const UInt32 kFindSignature = 1 << 3; // the handler can find start of archive
+ const UInt32 kMultiSignature = 1 << 4; // there are several signatures
+ const UInt32 kUseGlobalOffset = 1 << 5; // the seek position of stream must be set as global offset
+ const UInt32 kStartOpen = 1 << 6; // call handler for each start position
+ const UInt32 kPureStartOpen = 1 << 7; // call handler only for start of file
+ const UInt32 kBackwardOpen = 1 << 8; // archive can be open backward
+ const UInt32 kPreArc = 1 << 9; // such archive can be stored before real archive (like SFX stub)
+ const UInt32 kSymLinks = 1 << 10; // the handler supports symbolic links
+ const UInt32 kHardLinks = 1 << 11; // the handler supports hard links
+}
+
namespace NArchive
{
- enum
+ namespace NHandlerPropID
{
- kName = 0,
- kClassID,
- kExtension,
- kAddExtension,
- kUpdate,
- kKeepName,
- kStartSignature,
- kFinishSignature,
- kAssociate
- };
+ enum
+ {
+ kName = 0, // VT_BSTR
+ kClassID, // binary GUID in VT_BSTR
+ kExtension, // VT_BSTR
+ kAddExtension, // VT_BSTR
+ kUpdate, // VT_BOOL
+ kKeepName, // VT_BOOL
+ kSignature, // binary in VT_BSTR
+ kMultiSignature, // binary in VT_BSTR
+ kSignatureOffset, // VT_UI4
+ kAltStreams, // VT_BOOL
+ kNtSecure, // VT_BOOL
+ kFlags // VT_UI4
+ // kVersion // VT_UI4 ((VER_MAJOR << 8) | VER_MINOR)
+ };
+ }
namespace NExtract
{
@@ -46,25 +69,44 @@ namespace NArchive
kSkip
};
}
+
namespace NOperationResult
{
enum
{
kOK = 0,
- kUnSupportedMethod,
+ kUnsupportedMethod,
kDataError,
- kCRCError
+ kCRCError,
+ kUnavailable,
+ kUnexpectedEnd,
+ kDataAfterEnd,
+ kIsNotArc,
+ kHeadersError,
+ kWrongPassword
};
}
}
+
+ namespace NEventIndexType
+ {
+ enum
+ {
+ kNoIndex = 0,
+ kInArcIndex,
+ kBlockIndex,
+ kOutArcIndex
+ };
+ }
+
namespace NUpdate
{
namespace NOperationResult
{
enum
{
- kOK = 0,
- kError
+ kOK = 0
+ , // kError
};
}
}
@@ -79,12 +121,60 @@ ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)
INTERFACE_IArchiveOpenCallback(PURE);
};
+/*
+IArchiveExtractCallback::
+
+7-Zip doesn't call IArchiveExtractCallback functions
+ GetStream()
+ PrepareOperation()
+ SetOperationResult()
+from different threads simultaneously.
+But 7-Zip can call functions for IProgress or ICompressProgressInfo functions
+from another threads simultaneously with calls for IArchiveExtractCallback interface.
+
+IArchiveExtractCallback::GetStream()
+ UInt32 index - index of item in Archive
+ Int32 askExtractMode (Extract::NAskMode)
+ if (askMode != NExtract::NAskMode::kExtract)
+ {
+ then the callee can not real stream: (*inStream == NULL)
+ }
+
+ Out:
+ (*inStream == NULL) - for directories
+ (*inStream == NULL) - if link (hard link or symbolic link) was created
+ if (*inStream == NULL && askMode == NExtract::NAskMode::kExtract)
+ {
+ then the caller must skip extracting of that file.
+ }
+
+ returns:
+ S_OK : OK
+ S_FALSE : data error (for decoders)
+
+if (IProgress::SetTotal() was called)
+{
+ IProgress::SetCompleted(completeValue) uses
+ packSize - for some stream formats (xz, gz, bz2, lzma, z, ppmd).
+ unpackSize - for another formats.
+}
+else
+{
+ IProgress::SetCompleted(completeValue) uses packSize.
+}
+
+SetOperationResult()
+ 7-Zip calls SetOperationResult at the end of extracting,
+ so the callee can close the file, set attributes, timestamps and security information.
+
+ Int32 opRes (NExtract::NOperationResult)
+*/
#define INTERFACE_IArchiveExtractCallback(x) \
INTERFACE_IProgress(x) \
- STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \
+ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \
STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \
- STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) x; \
+ STDMETHOD(SetOperationResult)(Int32 opRes) x; \
ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20)
{
@@ -92,6 +182,25 @@ ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20)
};
+
+/*
+IArchiveExtractCallbackMessage can be requested from IArchiveExtractCallback object
+ by Extract() or UpdateItems() functions to report about extracting errors
+ReportExtractResult()
+ UInt32 indexType (NEventIndexType)
+ UInt32 index
+ Int32 opRes (NExtract::NOperationResult)
+*/
+
+#define INTERFACE_IArchiveExtractCallbackMessage(x) \
+ STDMETHOD(ReportExtractResult)(UInt32 indexType, UInt32 index, Int32 opRes) x; \
+
+ARCHIVE_INTERFACE_SUB(IArchiveExtractCallbackMessage, IProgress, 0x21)
+{
+ INTERFACE_IArchiveExtractCallbackMessage(PURE)
+};
+
+
#define INTERFACE_IArchiveOpenVolumeCallback(x) \
STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \
STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \
@@ -115,41 +224,185 @@ ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50)
/*
+IInArchive::Open
+ stream
+ if (kUseGlobalOffset), stream current position can be non 0.
+ if (!kUseGlobalOffset), stream current position is 0.
+ if (maxCheckStartPosition == NULL), the handler can try to search archive start in stream
+ if (*maxCheckStartPosition == 0), the handler must check only current position as archive start
+
IInArchive::Extract:
indices must be sorted
- numItems = 0xFFFFFFFF means "all files"
+ numItems = (UInt32)(Int32)-1 = 0xFFFFFFFF means "all files"
testMode != 0 means "test files without writing to outStream"
+
+IInArchive::GetArchiveProperty:
+ kpidOffset - start offset of archive.
+ VT_EMPTY : means offset = 0.
+ VT_UI4, VT_UI8, VT_I8 : result offset; negative values is allowed
+ kpidPhySize - size of archive. VT_EMPTY means unknown size.
+ kpidPhySize is allowed to be larger than file size. In that case it must show
+ supposed size.
+
+ kpidIsDeleted:
+ kpidIsAltStream:
+ kpidIsAux:
+ kpidINode:
+ must return VARIANT_TRUE (VT_BOOL), if archive can support that property in GetProperty.
+
+
+Notes:
+ Don't call IInArchive functions for same IInArchive object from different threads simultaneously.
+ Some IInArchive handlers will work incorrectly in that case.
*/
+#ifdef _MSC_VER
+ #define MY_NO_THROW_DECL_ONLY throw()
+#else
+ #define MY_NO_THROW_DECL_ONLY
+#endif
+
#define INTERFACE_IInArchive(x) \
- STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \
- STDMETHOD(Close)() x; \
- STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \
- STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
- STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \
- STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \
- STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \
- STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \
- STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \
- STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x;
+ STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
ARCHIVE_INTERFACE(IInArchive, 0x60)
{
INTERFACE_IInArchive(PURE)
};
+namespace NParentType
+{
+ enum
+ {
+ kDir = 0,
+ kAltStream
+ };
+};
+
+namespace NPropDataType
+{
+ const UInt32 kMask_ZeroEnd = 1 << 4;
+ // const UInt32 kMask_BigEndian = 1 << 5;
+ const UInt32 kMask_Utf = 1 << 6;
+ const UInt32 kMask_Utf8 = kMask_Utf | 0;
+ const UInt32 kMask_Utf16 = kMask_Utf | 1;
+ // const UInt32 kMask_Utf32 = kMask_Utf | 2;
+
+ const UInt32 kNotDefined = 0;
+ const UInt32 kRaw = 1;
+
+ const UInt32 kUtf8z = kMask_Utf8 | kMask_ZeroEnd;
+ const UInt32 kUtf16z = kMask_Utf16 | kMask_ZeroEnd;
+};
+
+// UTF string (pointer to wchar_t) with zero end and little-endian.
+#define PROP_DATA_TYPE_wchar_t_PTR_Z_LE ((NPropDataType::kMask_Utf | NPropDataType::kMask_ZeroEnd) + (sizeof(wchar_t) >> 1))
+
+/*
+GetRawProp:
+ Result:
+ S_OK - even if property is not set
+*/
+
+#define INTERFACE_IArchiveGetRawProps(x) \
+ STDMETHOD(GetParent)(UInt32 index, UInt32 *parent, UInt32 *parentType) x; \
+ STDMETHOD(GetRawProp)(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \
+ STDMETHOD(GetNumRawProps)(UInt32 *numProps) x; \
+ STDMETHOD(GetRawPropInfo)(UInt32 index, BSTR *name, PROPID *propID) x;
+
+ARCHIVE_INTERFACE(IArchiveGetRawProps, 0x70)
+{
+ INTERFACE_IArchiveGetRawProps(PURE)
+};
+
+#define INTERFACE_IArchiveGetRootProps(x) \
+ STDMETHOD(GetRootProp)(PROPID propID, PROPVARIANT *value) x; \
+ STDMETHOD(GetRootRawProp)(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \
+
+ARCHIVE_INTERFACE(IArchiveGetRootProps, 0x71)
+{
+ INTERFACE_IArchiveGetRootProps(PURE)
+};
+
ARCHIVE_INTERFACE(IArchiveOpenSeq, 0x61)
{
STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE;
};
+/*
+ OpenForSize
+ Result:
+ S_FALSE - is not archive
+ ? - DATA error
+*/
+
+/*
+const UInt32 kOpenFlags_RealPhySize = 1 << 0;
+const UInt32 kOpenFlags_NoSeek = 1 << 1;
+// const UInt32 kOpenFlags_BeforeExtract = 1 << 2;
+*/
+
+/*
+Flags:
+ 0 - opens archive with IInStream, if IInStream interface is supported
+ - if phySize is not available, it doesn't try to make full parse to get phySize
+ kOpenFlags_NoSeek - ArcOpen2 function doesn't use IInStream interface, even if it's available
+ kOpenFlags_RealPhySize - the handler will try to get PhySize, even if it requires full decompression for file
+
+ if handler is not allowed to use IInStream and the flag kOpenFlags_RealPhySize is not specified,
+ the handler can return S_OK, but it doesn't check even Signature.
+ So next Extract can be called for that sequential stream.
+*/
+
+/*
+ARCHIVE_INTERFACE(IArchiveOpen2, 0x62)
+{
+ STDMETHOD(ArcOpen2)(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback) PURE;
+};
+*/
+
+// ---------- UPDATE ----------
+
+/*
+GetUpdateItemInfo outs:
+*newData *newProps
+ 0 0 - Copy data and properties from archive
+ 0 1 - Copy data from archive, request new properties
+ 1 0 - that combination is unused now
+ 1 1 - Request new data and new properties. It can be used even for folders
+
+ indexInArchive = -1 if there is no item in archive, or if it doesn't matter.
+
+
+GetStream out:
+ Result:
+ S_OK:
+ (*inStream == NULL) - only for directories
+ - the bug was fixed in 9.33: (*Stream == NULL) was in case of anti-file
+ (*inStream != NULL) - for any file, even for empty file or anti-file
+ S_FALSE - skip that file (don't add item to archive) - (client code can't open stream of that file by some reason)
+ (*inStream == NULL)
+
+The order of calling for hard links:
+ - GetStream()
+ - GetProperty(kpidHardLink)
+
+SetOperationResult()
+ Int32 opRes (NExtract::NOperationResult::kOK)
+*/
+
#define INTERFACE_IArchiveUpdateCallback(x) \
INTERFACE_IProgress(x); \
- STDMETHOD(GetUpdateItemInfo)(UInt32 index, \
- Int32 *newData, /*1 - new data, 0 - old data */ \
- Int32 *newProperties, /* 1 - new properties, 0 - old properties */ \
- UInt32 *indexInArchive /* -1 if there is no in archive, or if doesn't matter */ \
- ) x; \
+ STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive) x; \
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \
STDMETHOD(SetOperationResult)(Int32 operationResult) x; \
@@ -169,6 +422,61 @@ ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
INTERFACE_IArchiveUpdateCallback2(PURE);
};
+namespace NUpdateNotifyOp
+{
+ enum
+ {
+ kAdd = 0,
+ kUpdate,
+ kAnalyze,
+ kReplicate,
+ kRepack,
+ kSkip,
+ kDelete,
+ kHeader
+
+ // kNumDefined
+ };
+};
+
+/*
+IArchiveUpdateCallbackFile::ReportOperation
+ UInt32 indexType (NEventIndexType)
+ UInt32 index
+ UInt32 notifyOp (NUpdateNotifyOp)
+*/
+
+#define INTERFACE_IArchiveUpdateCallbackFile(x) \
+ STDMETHOD(GetStream2)(UInt32 index, ISequentialInStream **inStream, UInt32 notifyOp) x; \
+ STDMETHOD(ReportOperation)(UInt32 indexType, UInt32 index, UInt32 notifyOp) x; \
+
+ARCHIVE_INTERFACE(IArchiveUpdateCallbackFile, 0x83)
+{
+ INTERFACE_IArchiveUpdateCallbackFile(PURE);
+};
+
+
+/*
+UpdateItems()
+-------------
+
+ outStream: output stream. (the handler) MUST support the case when
+ Seek position in outStream is not ZERO.
+ but the caller calls with empty outStream and seek position is ZERO??
+
+ archives with stub:
+
+ If archive is open and the handler and (Offset > 0), then the handler
+ knows about stub size.
+ UpdateItems():
+ 1) the handler MUST copy that stub to outStream
+ 2) the caller MUST NOT copy the stub to outStream, if
+ "rsfx" property is set with SetProperties
+
+ the handler must support the case where
+ ISequentialOutStream *outStream
+*/
+
#define INTERFACE_IOutArchive(x) \
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \
@@ -182,47 +490,75 @@ ARCHIVE_INTERFACE(IOutArchive, 0xA0)
ARCHIVE_INTERFACE(ISetProperties, 0x03)
{
- STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE;
+ STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) PURE;
+};
+
+ARCHIVE_INTERFACE(IArchiveKeepModeForNextOpen, 0x04)
+{
+ STDMETHOD(KeepModeForNextOpen)() PURE;
+};
+
+/* Exe handler: the handler for executable format (PE, ELF, Mach-O).
+ SFX archive: executable stub + some tail data.
+ before 9.31: exe handler didn't parse SFX archives as executable format.
+ for 9.31+: exe handler parses SFX archives as executable format, only if AllowTail(1) was called */
+
+ARCHIVE_INTERFACE(IArchiveAllowTail, 0x05)
+{
+ STDMETHOD(AllowTail)(Int32 allowTail) PURE;
};
#define IMP_IInArchive_GetProp(k) \
(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
- { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
- const STATPROPSTG &srcItem = k[index]; \
- *propID = srcItem.propid; *varType = srcItem.vt; *name = 0; return S_OK; } \
+ { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \
+ *propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; *name = 0; return S_OK; } \
+
+
+struct CStatProp
+{
+ const char *Name;
+ UInt32 PropID;
+ VARTYPE vt;
+};
+
+namespace NWindows {
+namespace NCOM {
+// PropVariant.cpp
+BSTR AllocBstrFromAscii(const char *s) throw();
+}}
#define IMP_IInArchive_GetProp_WITH_NAME(k) \
(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
- { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
- const STATPROPSTG &srcItem = k[index]; \
- *propID = srcItem.propid; *varType = srcItem.vt; \
- if (srcItem.lpwstrName == 0) *name = 0; else *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } \
+ { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \
+ const CStatProp &prop = k[index]; \
+ *propID = (PROPID)prop.PropID; *varType = prop.vt; \
+ *name = NWindows::NCOM::AllocBstrFromAscii(prop.Name); return S_OK; } \
#define IMP_IInArchive_Props \
- STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
- { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
+ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \
+ { *numProps = ARRAY_SIZE(kProps); return S_OK; } \
STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps)
#define IMP_IInArchive_Props_WITH_NAME \
- STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
- { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
+ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \
+ { *numProps = ARRAY_SIZE(kProps); return S_OK; } \
STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps)
#define IMP_IInArchive_ArcProps \
- STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
- { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
+ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
+ { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \
STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps)
#define IMP_IInArchive_ArcProps_WITH_NAME \
- STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
- { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
+ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
+ { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \
STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps)
#define IMP_IInArchive_ArcProps_NO_Table \
- STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
- { *numProperties = 0; return S_OK; } \
+ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
+ { *numProps = 0; return S_OK; } \
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \
{ return E_NOTIMPL; } \
@@ -231,4 +567,32 @@ ARCHIVE_INTERFACE(ISetProperties, 0x03)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \
{ value->vt = VT_EMPTY; return S_OK; }
+
+
+#define k_IsArc_Res_NO 0
+#define k_IsArc_Res_YES 1
+#define k_IsArc_Res_NEED_MORE 2
+// #define k_IsArc_Res_YES_LOW_PROB 3
+
+#define API_FUNC_IsArc EXTERN_C UInt32 WINAPI
+#define API_FUNC_static_IsArc extern "C" { static UInt32 WINAPI
+
+extern "C"
+{
+ typedef HRESULT (WINAPI *Func_CreateObject)(const GUID *clsID, const GUID *iid, void **outObject);
+
+ typedef UInt32 (WINAPI *Func_IsArc)(const Byte *p, size_t size);
+ typedef HRESULT (WINAPI *Func_GetIsArc)(UInt32 formatIndex, Func_IsArc *isArc);
+
+ typedef HRESULT (WINAPI *Func_GetNumberOfFormats)(UInt32 *numFormats);
+ typedef HRESULT (WINAPI *Func_GetHandlerProperty)(PROPID propID, PROPVARIANT *value);
+ typedef HRESULT (WINAPI *Func_GetHandlerProperty2)(UInt32 index, PROPID propID, PROPVARIANT *value);
+
+ typedef HRESULT (WINAPI *Func_SetCaseSensitive)(Int32 caseSensitive);
+ typedef HRESULT (WINAPI *Func_SetLargePageMode)();
+
+ typedef IOutArchive * (*Func_CreateOutArchive)();
+ typedef IInArchive * (*Func_CreateInArchive)();
+}
+
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp b/3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp
index 778c2fd8234..e4ac2a42567 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp
@@ -4,16 +4,17 @@
#include "../../../C/CpuArch.h"
-#include "Common/ComTry.h"
-#include "Common/IntToString.h"
+#include "../../Common/ComTry.h"
+#include "../../Common/IntToString.h"
-#include "Windows/PropVariant.h"
+#include "../../Windows/PropVariant.h"
-#include "../Common/CreateCoder.h"
+#include "../Common/FilterCoder.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
+#include "../Compress/BcjCoder.h"
#include "../Compress/LzmaDecoder.h"
#include "Common/DummyOutStream.h"
@@ -26,17 +27,24 @@ namespace NLzma {
static bool CheckDicSize(const Byte *p)
{
UInt32 dicSize = GetUi32(p);
- for (int i = 1; i <= 30; i++)
+ if (dicSize == 1)
+ return true;
+ for (unsigned i = 0; i <= 30; i++)
if (dicSize == ((UInt32)2 << i) || dicSize == ((UInt32)3 << i))
return true;
return (dicSize == 0xFFFFFFFF);
}
-STATPROPSTG kProps[] =
+static const Byte kProps[] =
{
- { NULL, kpidSize, VT_UI8},
- { NULL, kpidPackSize, VT_UI8},
- { NULL, kpidMethod, VT_BSTR}
+ kpidSize,
+ kpidPackSize,
+ kpidMethod
+};
+
+static const Byte kArcProps[] =
+{
+ kpidNumStreams
};
struct CHeader
@@ -62,19 +70,20 @@ bool CHeader::Parse(const Byte *buf, bool isThereFilter)
return
LzmaProps[0] < 5 * 5 * 9 &&
FilterID < 2 &&
- (!HasSize() || Size < ((UInt64)1 << 56)) &&
- CheckDicSize(LzmaProps + 1);
+ (!HasSize() || Size < ((UInt64)1 << 56))
+ && CheckDicSize(LzmaProps + 1);
}
class CDecoder
{
- NCompress::NLzma::CDecoder *_lzmaDecoderSpec;
- CMyComPtr<ICompressCoder> _lzmaDecoder;
CMyComPtr<ISequentialOutStream> _bcjStream;
+ CFilterCoder *_filterCoder;
+ CMyComPtr<ICompressCoder> _lzmaDecoder;
public:
+ NCompress::NLzma::CDecoder *_lzmaDecoderSpec;
+
~CDecoder();
- HRESULT Create(DECL_EXTERNAL_CODECS_LOC_VARS
- bool filtered, ISequentialInStream *inStream);
+ HRESULT Create(bool filtered, ISequentialInStream *inStream);
HRESULT Code(const CHeader &header, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
@@ -86,15 +95,12 @@ public:
{ return _lzmaDecoderSpec->ReadFromInputStream(data, size, processedSize); }
};
-static const UInt64 k_BCJ = 0x03030103;
-
-HRESULT CDecoder::Create(
- DECL_EXTERNAL_CODECS_LOC_VARS
- bool filteredMode, ISequentialInStream *inStream)
+HRESULT CDecoder::Create(bool filteredMode, ISequentialInStream *inStream)
{
if (!_lzmaDecoder)
{
_lzmaDecoderSpec = new NCompress::NLzma::CDecoder;
+ _lzmaDecoderSpec->FinishStream = true;
_lzmaDecoder = _lzmaDecoderSpec;
}
@@ -102,13 +108,10 @@ HRESULT CDecoder::Create(
{
if (!_bcjStream)
{
- CMyComPtr<ICompressCoder> coder;
- RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS k_BCJ, coder, false));
- if (!coder)
- return E_NOTIMPL;
- coder.QueryInterface(IID_ISequentialOutStream, &_bcjStream);
- if (!_bcjStream)
- return E_NOTIMPL;
+ _filterCoder = new CFilterCoder(false);
+ CMyComPtr<ICompressCoder> coder = _filterCoder;
+ _filterCoder->Filter = new CBcjCoder(false);
+ _bcjStream = _filterCoder;
}
}
@@ -134,17 +137,13 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,
RINOK(setDecoderProperties->SetDecoderProperties2(header.LzmaProps, 5));
}
- CMyComPtr<ICompressSetOutStream> setOutStream;
-
bool filteredMode = (header.FilterID == 1);
if (filteredMode)
{
- _bcjStream.QueryInterface(IID_ICompressSetOutStream, &setOutStream);
- if (!setOutStream)
- return E_NOTIMPL;
- RINOK(setOutStream->SetOutStream(outStream));
+ RINOK(_filterCoder->SetOutStream(outStream));
outStream = _bcjStream;
+ RINOK(_filterCoder->SetOutStreamSize(NULL));
}
const UInt64 *Size = header.HasSize() ? &header.Size : NULL;
@@ -152,20 +151,22 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,
if (filteredMode)
{
- CMyComPtr<IOutStreamFlush> flush;
- _bcjStream.QueryInterface(IID_IOutStreamFlush, &flush);
- if (flush)
{
- HRESULT res2 = flush->Flush();
+ HRESULT res2 = _filterCoder->OutStreamFinish();
if (res == S_OK)
res = res2;
}
- HRESULT res2 = setOutStream->ReleaseOutStream();
+ HRESULT res2 = _filterCoder->ReleaseOutStream();
if (res == S_OK)
res = res2;
}
+
RINOK(res);
+ if (header.HasSize())
+ if (_lzmaDecoderSpec->GetOutputProcessedSize() != header.Size)
+ return S_FALSE;
+
return S_OK;
}
@@ -173,26 +174,31 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,
class CHandler:
public IInArchive,
public IArchiveOpenSeq,
- PUBLIC_ISetCompressCodecsInfo
public CMyUnknownImp
{
CHeader _header;
bool _lzma86;
- UInt64 _startPosition;
- UInt64 _packSize;
- bool _packSizeDefined;
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
+
+ bool _isArc;
+ bool _needSeekToStart;
+ bool _dataAfterEnd;
+ bool _needMoreInput;
+
+ bool _packSize_Defined;
+ bool _unpackSize_Defined;
+ bool _numStreams_Defined;
- DECL_EXTERNAL_CODECS_VARS
- DECL_ISetCompressCodecsInfo
+ bool _unsupported;
+ bool _dataError;
+
+ UInt64 _packSize;
+ UInt64 _unpackSize;
+ UInt64 _numStreams;
public:
- MY_QUERYINTERFACE_BEGIN2(IInArchive)
- MY_QUERYINTERFACE_ENTRY(IArchiveOpenSeq)
- QUERY_ENTRY_ISetCompressCodecsInfo
- MY_QUERYINTERFACE_END
- MY_ADDREF_RELEASE
+ MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq)
INTERFACE_IInArchive(;)
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
@@ -204,14 +210,26 @@ public:
};
IMP_IInArchive_Props
-IMP_IInArchive_ArcProps_NO_Table
+IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
- switch(propID)
+ switch (propID)
{
- case kpidPhySize: if (_packSizeDefined) prop = _packSize; break;
+ 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 kpidErrorFlags:
+ {
+ UInt32 v = 0;
+ if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;;
+ if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd;
+ if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
+ if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
+ if (_dataError) v |= kpv_ErrorFlags_DataError;
+ prop = v;
+ }
}
prop.Detach(value);
return S_OK;
@@ -226,50 +244,37 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
static void DictSizeToString(UInt32 value, char *s)
{
for (int i = 0; i <= 31; i++)
- if ((UInt32(1) << i) == value)
+ if (((UInt32)1 << i) == value)
{
::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';
- }
+ if ((value & ((1 << 20) - 1)) == 0) { value >>= 20; c = 'm'; }
+ else if ((value & ((1 << 10) - 1)) == 0) { value >>= 10; c = 'k'; }
::ConvertUInt32ToString(value, s);
- int p = MyStringLen(s);
- s[p++] = c;
- s[p++] = '\0';
-}
-
-static void MyStrCat(char *d, const char *s)
-{
- MyStringCopy(d + MyStringLen(d), s);
+ s += MyStringLen(s);
+ *s++ = c;
+ *s = 0;
}
-STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
+STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
- switch(propID)
+ switch (propID)
{
case kpidSize: if (_stream && _header.HasSize()) prop = _header.Size; break;
- case kpidPackSize: if (_packSizeDefined) prop = _packSize; break;
+ case kpidPackSize: if (_packSize_Defined) prop = _packSize; break;
case kpidMethod:
if (_stream)
{
- char s[64];
- s[0] = '\0';
+ char sz[64];
+ char *s = sz;
if (_header.FilterID != 0)
- MyStrCat(s, "BCJ ");
- MyStrCat(s, "LZMA:");
- DictSizeToString(_header.GetDicSize(), s + MyStringLen(s));
- prop = s;
+ s = MyStpCpy(s, "BCJ ");
+ s = MyStpCpy(s, "LZMA:");
+ DictSizeToString(_header.GetDicSize(), s);
+ prop = sz;
}
break;
}
@@ -277,11 +282,54 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA
return S_OK;
}
+API_FUNC_static_IsArc IsArc_Lzma(const Byte *p, size_t size)
+{
+ const UInt32 kHeaderSize = 1 + 4 + 8;
+ if (size < kHeaderSize)
+ return k_IsArc_Res_NEED_MORE;
+ if (p[0] >= 5 * 5 * 9)
+ return k_IsArc_Res_NO;
+ UInt64 unpackSize = GetUi64(p + 1 + 4);
+ if (unpackSize != (UInt64)(Int64)-1)
+ {
+ if (size >= ((UInt64)1 << 56))
+ return k_IsArc_Res_NO;
+ }
+ if (unpackSize != 0)
+ {
+ if (size < kHeaderSize + 2)
+ return k_IsArc_Res_NEED_MORE;
+ if (p[kHeaderSize] != 0)
+ return k_IsArc_Res_NO;
+ if (unpackSize != (UInt64)(Int64)-1)
+ {
+ if ((p[kHeaderSize + 1] & 0x80) != 0)
+ return k_IsArc_Res_NO;
+ }
+ }
+ if (!CheckDicSize(p + 1))
+ // return k_IsArc_Res_YES_LOW_PROB;
+ return k_IsArc_Res_NO;
+ return k_IsArc_Res_YES;
+}
+}
+
+API_FUNC_static_IsArc IsArc_Lzma86(const Byte *p, size_t size)
+{
+ if (size < 1)
+ return k_IsArc_Res_NEED_MORE;
+ Byte filterID = p[0];
+ if (filterID != 0 && filterID != 1)
+ return k_IsArc_Res_NO;
+ return IsArc_Lzma(p + 1, size - 1);
+}
+}
+
STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)
{
- RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &_startPosition));
+ Close();
- const UInt32 kBufSize = 1 + 5 + 8 + 1;
+ const UInt32 kBufSize = 1 + 5 + 8 + 2;
Byte buf[kBufSize];
RINOK(ReadStream_FALSE(inStream, buf, kBufSize));
@@ -289,46 +337,83 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCal
if (!_header.Parse(buf, _lzma86))
return S_FALSE;
const Byte *start = buf + GetHeaderSize();
- if (start[0] != 0)
+ if (start[0] != 0 /* || (start[1] & 0x80) != 0 */ ) // empty stream with EOS is not 0x80
return S_FALSE;
- UInt64 endPos;
- RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos));
- _packSize = endPos - _startPosition;
- _packSizeDefined = true;
+ RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize));
if (_packSize >= 24 && _header.Size == 0 && _header.FilterID == 0 && _header.LzmaProps[0] == 0)
return S_FALSE;
+ _isArc = true;
_stream = inStream;
_seqStream = inStream;
+ _needSeekToStart = true;
return S_OK;
}
STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
{
Close();
+ _isArc = true;
_seqStream = stream;
return S_OK;
}
STDMETHODIMP CHandler::Close()
{
- _packSizeDefined = false;
+ _isArc = false;
+ _packSize_Defined = false;
+ _unpackSize_Defined = false;
+ _numStreams_Defined = false;
+
+ _dataAfterEnd = false;
+ _needMoreInput = false;
+ _unsupported = false;
+ _dataError = false;
+
+ _packSize = 0;
+
+ _needSeekToStart = false;
+
_stream.Release();
_seqStream.Release();
return S_OK;
}
+class CCompressProgressInfoImp:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ CMyComPtr<IArchiveOpenCallback> Callback;
+public:
+ UInt64 Offset;
+
+ MY_UNKNOWN_IMP1(ICompressProgressInfo)
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+ void Init(IArchiveOpenCallback *callback) { Callback = callback; }
+};
+
+STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)
+{
+ if (Callback)
+ {
+ UInt64 files = 0;
+ UInt64 value = Offset + *inSize;
+ return Callback->SetCompleted(&files, &value);
+ }
+ return S_OK;
+}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
+
if (numItems == 0)
return S_OK;
- if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
+ if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
- if (_stream)
+ if (_packSize_Defined)
extractCallback->SetTotal(_packSize);
@@ -352,80 +437,137 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, true);
- if (_stream)
+ if (_needSeekToStart)
{
- RINOK(_stream->Seek(_startPosition, STREAM_SEEK_SET, NULL));
+ if (!_stream)
+ return E_FAIL;
+ RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
}
+ else
+ _needSeekToStart = true;
CDecoder decoder;
- HRESULT result = decoder.Create(
- EXTERNAL_CODECS_VARS
- _lzma86, _seqStream);
+ HRESULT result = decoder.Create(_lzma86, _seqStream);
RINOK(result);
- Int32 opRes = NExtract::NOperationResult::kOK;
bool firstItem = true;
+ UInt64 packSize = 0;
+ UInt64 unpackSize = 0;
+ UInt64 numStreams = 0;
+
+ bool dataAfterEnd = false;
+
for (;;)
{
- lps->OutSize = outStreamSpec->GetSize();
- lps->InSize = _packSize = decoder.GetInputProcessedSize();
- _packSizeDefined = true;
+ lps->InSize = packSize;
+ lps->OutSize = unpackSize;
RINOK(lps->SetCur());
- CHeader st;
-
const UInt32 kBufSize = 1 + 5 + 8;
Byte buf[kBufSize];
const UInt32 headerSize = GetHeaderSize();
UInt32 processed;
RINOK(decoder.ReadInput(buf, headerSize, &processed));
if (processed != headerSize)
+ {
+ if (processed != 0)
+ dataAfterEnd = true;
break;
+ }
+ CHeader st;
if (!st.Parse(buf, _lzma86))
+ {
+ dataAfterEnd = true;
break;
+ }
+ numStreams++;
firstItem = false;
result = decoder.Code(st, outStream, progress);
+
+ packSize = decoder.GetInputProcessedSize();
+ unpackSize = outStreamSpec->GetSize();
+
if (result == E_NOTIMPL)
{
- opRes = NExtract::NOperationResult::kUnSupportedMethod;
+ _unsupported = true;
+ result = S_FALSE;
break;
}
if (result == S_FALSE)
- {
- opRes = NExtract::NOperationResult::kDataError;
break;
- }
RINOK(result);
}
+
if (firstItem)
- return E_FAIL;
+ {
+ _isArc = false;
+ result = S_FALSE;
+ }
+ else if (result == S_OK || result == S_FALSE)
+ {
+ if (dataAfterEnd)
+ _dataAfterEnd = true;
+ else if (decoder._lzmaDecoderSpec->NeedMoreInput)
+ _needMoreInput = true;
+
+ _packSize = packSize;
+ _unpackSize = unpackSize;
+ _numStreams = numStreams;
+
+ _packSize_Defined = true;
+ _unpackSize_Defined = true;
+ _numStreams_Defined = true;
+ }
+
+ Int32 opResult = NExtract::NOperationResult::kOK;
+
+ if (!_isArc)
+ opResult = NExtract::NOperationResult::kIsNotArc;
+ else if (_needMoreInput)
+ opResult = NExtract::NOperationResult::kUnexpectedEnd;
+ else if (_unsupported)
+ opResult = NExtract::NOperationResult::kUnsupportedMethod;
+ else if (_dataAfterEnd)
+ opResult = NExtract::NOperationResult::kDataAfterEnd;
+ else if (result == S_FALSE)
+ opResult = NExtract::NOperationResult::kDataError;
+ else if (result == S_OK)
+ opResult = NExtract::NOperationResult::kOK;
+ else
+ return result;
+
outStream.Release();
- return extractCallback->SetOperationResult(opRes);
+ return extractCallback->SetOperationResult(opResult);
+
COM_TRY_END
}
-IMPL_ISetCompressCodecsInfo
-
-static IInArchive *CreateArc() { return new CHandler(false); }
-static IInArchive *CreateArc86() { return new CHandler(true); }
-
namespace NLzmaAr {
-
-static CArcInfo g_ArcInfo =
- { L"lzma", L"lzma", 0, 0xA, { 0 }, 0, true, CreateArc, NULL };
-REGISTER_ARC(Lzma)
+// 2, { 0x5D, 0x00 },
+
+REGISTER_ARC_I_CLS_NO_SIG(
+ CHandler(false),
+ "lzma", "lzma", 0, 0xA,
+ 0,
+ NArcInfoFlags::kStartOpen |
+ NArcInfoFlags::kKeepName,
+ IsArc_Lzma)
+
}
namespace NLzma86Ar {
-static CArcInfo g_ArcInfo =
- { L"lzma86", L"lzma86", 0, 0xB, { 0 }, 0, true, CreateArc86, NULL };
-REGISTER_ARC(Lzma86)
-
+REGISTER_ARC_I_CLS_NO_SIG(
+ CHandler(true),
+ "lzma86", "lzma86", 0, 0xB,
+ 0,
+ NArcInfoFlags::kKeepName,
+ IsArc_Lzma86)
+
}
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp b/3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp
index 5d84de4ed9a..23187064fab 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp
@@ -2,10 +2,10 @@
#include "StdAfx.h"
-#include "Common/ComTry.h"
-#include "Common/MyString.h"
+#include "../../Common/ComTry.h"
+#include "../../Common/MyString.h"
-#include "Windows/PropVariant.h"
+#include "../../Windows/PropVariant.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
@@ -19,15 +19,16 @@ using namespace NWindows;
namespace NArchive {
namespace NSplit {
-STATPROPSTG kProps[] =
+static const Byte kProps[] =
{
- { NULL, kpidPath, VT_BSTR},
- { NULL, kpidSize, VT_UI8}
+ kpidPath,
+ kpidSize
};
-STATPROPSTG kArcProps[] =
+static const Byte kArcProps[] =
{
- { NULL, kpidNumVolumes, VT_UI4}
+ kpidNumVolumes,
+ kpidTotalPhySize
};
class CHandler:
@@ -35,10 +36,12 @@ class CHandler:
public IInArchiveGetStream,
public CMyUnknownImp
{
- UString _subName;
CObjectVector<CMyComPtr<IInStream> > _streams;
CRecordVector<UInt64> _sizes;
+ UString _subName;
UInt64 _totalSize;
+
+ HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback);
public:
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
INTERFACE_IInArchive(;)
@@ -51,9 +54,11 @@ IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
- switch(propID)
+ switch (propID)
{
case kpidMainSubfile: prop = (UInt32)0; break;
+ case kpidPhySize: if (!_sizes.IsEmpty()) prop = _sizes[0]; break;
+ case kpidTotalPhySize: prop = _totalSize; break;
case kpidNumVolumes: prop = (UInt32)_streams.Size(); break;
}
prop.Detach(value);
@@ -66,210 +71,191 @@ struct CSeqName
UString _changedPart;
bool _splitStyle;
- UString GetNextName()
+ bool GetNextName(UString &s)
{
- UString newName;
- if (_splitStyle)
{
- int i;
- int numLetters = _changedPart.Length();
- for (i = numLetters - 1; i >= 0; i--)
+ unsigned i = _changedPart.Len();
+ for (;;)
{
- wchar_t c = _changedPart[i];
- if (c == 'z')
+ wchar_t c = _changedPart[--i];
+
+ if (_splitStyle)
{
- c = 'a';
- newName = c + newName;
- continue;
+ if (c == 'z')
+ {
+ _changedPart.ReplaceOneCharAtPos(i, L'a');
+ if (i == 0)
+ return false;
+ continue;
+ }
+ else if (c == 'Z')
+ {
+ _changedPart.ReplaceOneCharAtPos(i, L'A');
+ if (i == 0)
+ return false;
+ continue;
+ }
}
- else if (c == 'Z')
- {
- c = 'A';
- newName = c + newName;
- continue;
- }
- c++;
- if ((c == 'z' || c == 'Z') && i == 0)
+ else
{
- _unchangedPart += c;
- wchar_t newChar = (c == 'z') ? L'a' : L'A';
- newName.Empty();
- numLetters++;
- for (int k = 0; k < numLetters; k++)
- newName += newChar;
- break;
- }
- newName = c + newName;
- i--;
- for (; i >= 0; i--)
- newName = _changedPart[i] + newName;
- break;
- }
- }
- else
- {
- int i;
- int numLetters = _changedPart.Length();
- for (i = numLetters - 1; i >= 0; i--)
- {
- wchar_t c = _changedPart[i];
- if (c == L'9')
- {
- c = L'0';
- newName = c + newName;
- if (i == 0)
- newName = UString(L'1') + newName;
- continue;
+ if (c == '9')
+ {
+ _changedPart.ReplaceOneCharAtPos(i, L'0');
+ if (i == 0)
+ {
+ _changedPart.InsertAtFront(L'1');
+ break;
+ }
+ continue;
+ }
}
+
c++;
- newName = c + newName;
- i--;
- for (; i >= 0; i--)
- newName = _changedPart[i] + newName;
+ _changedPart.ReplaceOneCharAtPos(i, c);
break;
}
}
- _changedPart = newName;
- return _unchangedPart + _changedPart;
+
+ s = _unchangedPart + _changedPart;
+ return true;
}
};
-STDMETHODIMP CHandler::Open(IInStream *stream,
- const UInt64 * /* maxCheckStartPosition */,
- IArchiveOpenCallback *openArchiveCallback)
+HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{
- COM_TRY_BEGIN
Close();
- if (openArchiveCallback == 0)
+ if (!callback)
return S_FALSE;
- // try
+
+ CMyComPtr<IArchiveOpenVolumeCallback> volumeCallback;
+ callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback);
+ if (!volumeCallback)
+ return S_FALSE;
+
+ UString name;
{
- CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
- CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback;
- if (openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback,
- &openVolumeCallback) != S_OK)
+ NCOM::CPropVariant prop;
+ RINOK(volumeCallback->GetProperty(kpidName, &prop));
+ if (prop.vt != VT_BSTR)
return S_FALSE;
-
- UString name;
- {
- NCOM::CPropVariant prop;
- RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
- if (prop.vt != VT_BSTR)
- return S_FALSE;
- name = prop.bstrVal;
- }
-
- int dotPos = name.ReverseFind('.');
- UString prefix, ext;
- if (dotPos >= 0)
- {
- prefix = name.Left(dotPos + 1);
- ext = name.Mid(dotPos + 1);
- }
- else
- ext = name;
- UString extBig = ext;
- extBig.MakeUpper();
-
- CSeqName seqName;
-
- int numLetters = 2;
- bool splitStyle = false;
- if (extBig.Right(2) == L"AA")
+ name = prop.bstrVal;
+ }
+
+ int dotPos = name.ReverseFind_Dot();
+ const UString prefix = name.Left(dotPos + 1);
+ const UString ext = name.Ptr(dotPos + 1);
+ UString ext2 = ext;
+ ext2.MakeLower_Ascii();
+
+ CSeqName seqName;
+
+ unsigned numLetters = 2;
+ bool splitStyle = false;
+
+ if (ext2.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "aa"))
+ {
+ splitStyle = true;
+ while (numLetters < ext2.Len())
{
- splitStyle = true;
- while (numLetters < extBig.Length())
- {
- if (extBig[extBig.Length() - numLetters - 1] != 'A')
- break;
- numLetters++;
- }
+ if (ext2[ext2.Len() - numLetters - 1] != 'a')
+ break;
+ numLetters++;
}
- else if (ext.Right(2) == L"01")
+ }
+ else if (ext.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "01"))
+ {
+ while (numLetters < ext2.Len())
{
- while (numLetters < extBig.Length())
- {
- if (extBig[extBig.Length() - numLetters - 1] != '0')
- break;
- numLetters++;
- }
- if (numLetters != ext.Length())
- return S_FALSE;
+ if (ext2[ext2.Len() - numLetters - 1] != '0')
+ break;
+ numLetters++;
}
- else
+ if (numLetters != ext.Len())
return S_FALSE;
-
- _streams.Add(stream);
-
- seqName._unchangedPart = prefix + ext.Left(extBig.Length() - numLetters);
- seqName._changedPart = ext.Right(numLetters);
- seqName._splitStyle = splitStyle;
-
- if (prefix.Length() < 1)
- _subName = L"file";
- else
- _subName = prefix.Left(prefix.Length() - 1);
-
- _totalSize = 0;
- UInt64 size;
+ }
+ else
+ return S_FALSE;
+
+ seqName._unchangedPart = prefix + ext.Left(ext2.Len() - numLetters);
+ seqName._changedPart = ext.RightPtr(numLetters);
+ seqName._splitStyle = splitStyle;
+
+ if (prefix.Len() < 1)
+ _subName.SetFromAscii("file");
+ else
+ _subName.SetFrom(prefix, prefix.Len() - 1);
+
+ UInt64 size;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(volumeCallback->GetProperty(kpidSize, &prop));
+ if (prop.vt != VT_UI8)
+ return E_INVALIDARG;
+ size = prop.uhVal.QuadPart;
+ }
+
+ _totalSize += size;
+ _sizes.Add(size);
+ _streams.Add(stream);
+
+ {
+ UInt64 numFiles = _streams.Size();
+ RINOK(callback->SetCompleted(&numFiles, NULL));
+ }
+
+ for (;;)
+ {
+ UString fullName;
+ if (!seqName.GetNextName(fullName))
+ break;
+ CMyComPtr<IInStream> nextStream;
+ HRESULT result = volumeCallback->GetStream(fullName, &nextStream);
+ if (result == S_FALSE)
+ break;
+ if (result != S_OK)
+ return result;
+ if (!stream)
+ break;
{
NCOM::CPropVariant prop;
- RINOK(openVolumeCallback->GetProperty(kpidSize, &prop));
+ RINOK(volumeCallback->GetProperty(kpidSize, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
_totalSize += size;
_sizes.Add(size);
-
- if (openArchiveCallback != NULL)
+ _streams.Add(nextStream);
{
UInt64 numFiles = _streams.Size();
- RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
- }
-
- for (;;)
- {
- UString fullName = seqName.GetNextName();
- CMyComPtr<IInStream> nextStream;
- HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream);
- if (result == S_FALSE)
- break;
- if (result != S_OK)
- return result;
- if (!stream)
- break;
- {
- NCOM::CPropVariant prop;
- RINOK(openVolumeCallback->GetProperty(kpidSize, &prop));
- if (prop.vt != VT_UI8)
- return E_INVALIDARG;
- size = prop.uhVal.QuadPart;
- }
- _totalSize += size;
- _sizes.Add(size);
- _streams.Add(nextStream);
- if (openArchiveCallback != NULL)
- {
- UInt64 numFiles = _streams.Size();
- RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
- }
+ RINOK(callback->SetCompleted(&numFiles, NULL));
}
}
- /*
- catch(...)
+
+ if (_streams.Size() == 1)
{
- return S_FALSE;
+ if (splitStyle)
+ return S_FALSE;
}
- */
return S_OK;
+}
+
+STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)
+{
+ COM_TRY_BEGIN
+ HRESULT res = Open2(stream, callback);
+ if (res != S_OK)
+ Close();
+ return res;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
- _sizes.Clear();
+ _totalSize = 0;
+ _subName.Empty();
_streams.Clear();
+ _sizes.Clear();
return S_OK;
}
@@ -281,8 +267,8 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
- NWindows::NCOM::CPropVariant prop;
- switch(propID)
+ NCOM::CPropVariant prop;
+ switch (propID)
{
case kpidPath: prop = _subName; break;
case kpidSize:
@@ -300,7 +286,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
COM_TRY_BEGIN
if (numItems == 0)
return S_OK;
- if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
+ if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
UInt64 currentTotalSize = 0;
@@ -321,7 +307,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
- for (int i = 0; i < _streams.Size(); i++)
+ FOR_VECTOR (i, _streams)
{
lps->InSize = lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
@@ -343,7 +329,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
*stream = 0;
CMultiStream *streamSpec = new CMultiStream;
CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
- for (int i = 0; i < _streams.Size(); i++)
+ FOR_VECTOR (i, _streams)
{
CMultiStream::CSubStreamInfo subStreamInfo;
subStreamInfo.Stream = _streams[i];
@@ -356,11 +342,10 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
COM_TRY_END
}
-static IInArchive *CreateArc() { return new CHandler; }
-
-static CArcInfo g_ArcInfo =
-{ L"Split", L"001", 0, 0xEA, { 0 }, 0, false, CreateArc, 0 };
-
-REGISTER_ARC(Split)
+REGISTER_ARC_I_NO_SIG(
+ "Split", "001", 0, 0xEA,
+ 0,
+ 0,
+ NULL)
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/StdAfx.h b/3rdparty/lzma/CPP/7zip/Archive/StdAfx.h
index ef555ec12ac..1cbd7feaeec 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../Common/MyWindows.h"
-#include "../../Common/NewHandler.h"
+#include "../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp b/3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp
index 8383488b14f..11f4b44427c 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp
@@ -7,8 +7,8 @@
#include "../../../C/XzEnc.h"
#include "../../Common/ComTry.h"
+#include "../../Common/Defs.h"
#include "../../Common/IntToString.h"
-#include "../../Common/StringConvert.h"
#include "../ICoder.h"
@@ -23,6 +23,8 @@
#include "Common/HandlerOut.h"
+#include "XzHandler.h"
+
using namespace NWindows;
namespace NCompress {
@@ -32,16 +34,35 @@ HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzm
}}
-static void *SzAlloc(void *, size_t size) { return MyAlloc(size); }
-static void SzFree(void *, void *address) { MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
namespace NArchive {
namespace NXz {
struct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit;
-static const wchar_t *k_LZMA2_Name = L"LZMA2";
+static const char *k_LZMA2_Name = "LZMA2";
+
+void CStatInfo::Clear()
+{
+ 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;
+}
class CHandler:
public IInArchive,
@@ -53,19 +74,17 @@ class CHandler:
#endif
public CMyUnknownImp
{
- Int64 _startPosition;
- UInt64 _packSize;
- UInt64 _unpackSize;
- UInt64 _numBlocks;
- AString _methodsString;
- bool _useSeq;
- UInt64 _unpackSizeDefined;
- UInt64 _packSizeDefined;
+ CStatInfo _stat;
+
+ bool _isArc;
+ bool _needSeekToStart;
+ bool _phySize_Defined;
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
UInt32 _filterId;
+ AString _methodsString;
void Init()
{
@@ -73,7 +92,16 @@ class CHandler:
CMultiMethodProps::Init();
}
- HRESULT Open2(IInStream *inStream, IArchiveOpenCallback *callback);
+ HRESULT Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback);
+
+ HRESULT Decode2(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
+ CDecoder &decoder, ICompressProgressInfo *progress)
+ {
+ RINOK(decoder.Decode(seqInStream, outStream, progress));
+ _stat = decoder;
+ _phySize_Defined = true;
+ return S_OK;
+ }
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
@@ -90,7 +118,7 @@ public:
#ifndef EXTRACT_ONLY
INTERFACE_IOutArchive(;)
- STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
+ STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
#endif
CHandler();
@@ -101,60 +129,60 @@ CHandler::CHandler()
Init();
}
-static STATPROPSTG const kProps[] =
+static const Byte kProps[] =
{
- { NULL, kpidSize, VT_UI8},
- { NULL, kpidPackSize, VT_UI8},
- { NULL, kpidMethod, VT_BSTR}
+ kpidSize,
+ kpidPackSize,
+ kpidMethod
};
-static STATPROPSTG const kArcProps[] =
+static const Byte kArcProps[] =
{
- { NULL, kpidMethod, VT_BSTR},
- { NULL, kpidNumBlocks, VT_UI4}
+ kpidMethod,
+ kpidNumStreams,
+ kpidNumBlocks
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
-static char GetHex(Byte value)
+static inline char GetHex(unsigned value)
{
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
}
-static inline void AddHexToString(AString &res, Byte value)
+static inline void AddHexToString(AString &s, Byte value)
{
- res += GetHex((Byte)(value >> 4));
- res += GetHex((Byte)(value & 0xF));
+ s += GetHex(value >> 4);
+ s += GetHex(value & 0xF);
}
-static AString ConvertUInt32ToString(UInt32 value)
+static void AddUInt32ToString(AString &s, UInt32 value)
{
- char temp[32];
- ::ConvertUInt32ToString(value, temp);
- return temp;
+ char temp[16];
+ ConvertUInt32ToString(value, temp);
+ s += temp;
}
-static AString Lzma2PropToString(int prop)
+static void Lzma2PropToString(AString &s, unsigned prop)
{
+ char c = 0;
+ UInt32 size;
if ((prop & 1) == 0)
- return ConvertUInt32ToString(prop / 2 + 12);
- AString res;
- char c;
-
- UInt32 size = (2 | ((prop) & 1)) << ((prop) / 2 + 1);
-
- if (prop > 17)
- {
- res = ConvertUInt32ToString(size >> 10);
- c = 'm';
- }
+ size = prop / 2 + 12;
else
{
- res = ConvertUInt32ToString(size);
c = 'k';
+ size = (UInt32)(2 | (prop & 1)) << (prop / 2 + 1);
+ if (prop > 17)
+ {
+ size >>= 10;
+ c = 'm';
+ }
}
- return res + c;
+ AddUInt32ToString(s, size);
+ if (c != 0)
+ s += c;
}
struct CMethodNamePair
@@ -178,25 +206,29 @@ static const CMethodNamePair g_NamePairs[] =
static AString GetMethodString(const CXzFilter &f)
{
- AString s;
-
- for (int i = 0; i < sizeof(g_NamePairs) / sizeof(g_NamePairs[i]); i++)
+ const char *p = NULL;
+ for (unsigned i = 0; i < ARRAY_SIZE(g_NamePairs); i++)
if (g_NamePairs[i].Id == f.id)
- s = g_NamePairs[i].Name;
- if (s.IsEmpty())
+ {
+ p = g_NamePairs[i].Name;
+ break;
+ }
+ char temp[32];
+ if (!p)
{
- char temp[32];
::ConvertUInt64ToString(f.id, temp);
- s = temp;
+ p = temp;
}
+ AString s = p;
+
if (f.propsSize > 0)
{
s += ':';
if (f.id == XZ_ID_LZMA2 && f.propsSize == 1)
- s += Lzma2PropToString(f.props[0]);
+ Lzma2PropToString(s, f.props[0]);
else if (f.id == XZ_ID_Delta && f.propsSize == 1)
- s += ConvertUInt32ToString((UInt32)f.props[0] + 1);
+ AddUInt32ToString(s, (UInt32)f.props[0] + 1);
else
{
s += '[';
@@ -210,29 +242,28 @@ static AString GetMethodString(const CXzFilter &f)
static void AddString(AString &dest, const AString &src)
{
- if (!dest.IsEmpty())
- dest += ' ';
+ dest.Add_Space_if_NotEmpty();
dest += src;
}
-static const char *kChecks[] =
-{
- "NoCheck",
- "CRC32",
- NULL,
- NULL,
- "CRC64",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- "SHA256",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
+static const char * const kChecks[] =
+{
+ "NoCheck"
+ , "CRC32"
+ , NULL
+ , NULL
+ , "CRC64"
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , "SHA256"
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
};
static AString GetCheckString(const CXzs &xzs)
@@ -249,7 +280,10 @@ static AString GetCheckString(const CXzs &xzs)
if (kChecks[i])
s2 = kChecks[i];
else
- s2 = "Check-" + ConvertUInt32ToString((UInt32)i);
+ {
+ s2 = "Check-";
+ AddUInt32ToString(s2, (UInt32)i);
+ }
AddString(s, s2);
}
return s;
@@ -258,12 +292,26 @@ static AString GetCheckString(const CXzs &xzs)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
- NWindows::NCOM::CPropVariant prop;
- switch(propID)
+ NCOM::CPropVariant prop;
+ switch (propID)
{
- case kpidNumBlocks: if (!_useSeq) prop = _numBlocks; break;
- case kpidPhySize: if (_packSizeDefined) prop = _packSize; break;
+ case kpidPhySize: if (_phySize_Defined) prop = _stat.PhySize; break;
+ case kpidNumStreams: if (_stat.NumStreams_Defined) prop = _stat.NumStreams; break;
+ case kpidNumBlocks: if (_stat.NumBlocks_Defined) prop = _stat.NumBlocks; break;
+ case kpidUnpackSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break;
case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;
+ case kpidErrorFlags:
+ {
+ UInt32 v = 0;
+ if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;;
+ if (_stat.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
+ if (_stat.DataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
+ if (_stat.HeadersError) v |= kpv_ErrorFlags_HeadersError;
+ if (_stat.Unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
+ if (_stat.DataError) v |= kpv_ErrorFlags_DataError;
+ if (_stat.CrcError) v |= kpv_ErrorFlags_CrcError;
+ prop = v;
+ }
}
prop.Detach(value);
return S_OK;
@@ -276,14 +324,14 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
-STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)
+STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
- NWindows::NCOM::CPropVariant prop;
- switch(propID)
+ NCOM::CPropVariant prop;
+ switch (propID)
{
- case kpidSize: if (_unpackSizeDefined) prop = _unpackSize; break;
- case kpidPackSize: if (_packSizeDefined) prop = _packSize; break;
+ case kpidSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break;
+ case kpidPackSize: if (_phySize_Defined) prop = _stat.PhySize; break;
case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;
}
prop.Detach(value);
@@ -303,7 +351,8 @@ struct COpenCallbackWrap
static SRes OpenCallbackProgress(void *pp, UInt64 inSize, UInt64 /* outSize */)
{
COpenCallbackWrap *p = (COpenCallbackWrap *)pp;
- p->Res = p->OpenCallback->SetCompleted(NULL, &inSize);
+ if (p->OpenCallback)
+ p->Res = p->OpenCallback->SetCompleted(NULL, &inSize);
return (SRes)p->Res;
}
@@ -321,82 +370,108 @@ struct CXzsCPP
~CXzsCPP() { Xzs_Free(&p, &g_Alloc); }
};
-HRESULT CHandler::Open2(IInStream *inStream, IArchiveOpenCallback *callback)
+static HRESULT SRes_to_Open_HRESULT(SRes res)
{
- CSeekInStreamWrap inStreamImp(inStream);
-
- CLookToRead lookStream;
- LookToRead_CreateVTable(&lookStream, True);
- lookStream.realStream = &inStreamImp.p;
- LookToRead_Init(&lookStream);
+ switch (res)
+ {
+ case SZ_OK: return S_OK;
+ case SZ_ERROR_MEM: return E_OUTOFMEMORY;
+ case SZ_ERROR_PROGRESS: return E_ABORT;
+ /*
+ case SZ_ERROR_UNSUPPORTED:
+ case SZ_ERROR_CRC:
+ case SZ_ERROR_DATA:
+ case SZ_ERROR_ARCHIVE:
+ case SZ_ERROR_NO_ARCHIVE:
+ return S_FALSE;
+ */
+ }
+ return S_FALSE;
+}
- COpenCallbackWrap openWrap(callback);
- RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize));
- RINOK(callback->SetTotal(NULL, &_packSize));
+HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback)
+{
+ _needSeekToStart = true;
- CXzsCPP xzs;
- SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.s, &_startPosition, &openWrap.p, &g_Alloc);
- if (res == SZ_ERROR_NO_ARCHIVE && xzs.p.num > 0)
- res = SZ_OK;
- if (res == SZ_OK)
{
- _packSize -= _startPosition;
- _unpackSize = Xzs_GetUnpackSize(&xzs.p);
- _unpackSizeDefined = _packSizeDefined = true;
- _numBlocks = (UInt64)Xzs_GetNumBlocks(&xzs.p);
-
- RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
CXzStreamFlags st;
CSeqInStreamWrap inStreamWrap(inStream);
- SRes res2 = Xz_ReadHeader(&st, &inStreamWrap.p);
+ SRes res = Xz_ReadHeader(&st, &inStreamWrap.p);
+ if (res != SZ_OK)
+ return SRes_to_Open_HRESULT(res);
- if (res2 == SZ_OK)
{
CXzBlock block;
Bool isIndex;
UInt32 headerSizeRes;
- res2 = XzBlock_ReadHeader(&block, &inStreamWrap.p, &isIndex, &headerSizeRes);
+ SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.p, &isIndex, &headerSizeRes);
if (res2 == SZ_OK && !isIndex)
{
- int numFilters = XzBlock_GetNumFilters(&block);
- for (int i = 0; i < numFilters; i++)
+ unsigned numFilters = XzBlock_GetNumFilters(&block);
+ for (unsigned i = 0; i < numFilters; i++)
AddString(_methodsString, GetMethodString(block.filters[i]));
}
}
- AddString(_methodsString, GetCheckString(xzs.p));
}
- if (res != SZ_OK || _startPosition != 0)
+ RINOK(inStream->Seek(0, STREAM_SEEK_END, &_stat.PhySize));
+ if (callback)
{
- RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
- CXzStreamFlags st;
- CSeqInStreamWrap inStreamWrap(inStream);
- SRes res2 = Xz_ReadHeader(&st, &inStreamWrap.p);
- if (res2 == SZ_OK)
- {
- res = res2;
- _startPosition = 0;
- _useSeq = True;
- _unpackSizeDefined = _packSizeDefined = false;
- }
+ RINOK(callback->SetTotal(NULL, &_stat.PhySize));
}
- if (res == SZ_ERROR_NO_ARCHIVE)
- return S_FALSE;
- RINOK(SResToHRESULT(res));
+
+ CSeekInStreamWrap inStreamImp(inStream);
+
+ CLookToRead lookStream;
+ LookToRead_CreateVTable(&lookStream, True);
+ lookStream.realStream = &inStreamImp.p;
+ LookToRead_Init(&lookStream);
+
+ COpenCallbackWrap openWrap(callback);
+
+ CXzsCPP xzs;
+ Int64 startPosition;
+ SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.s, &startPosition, &openWrap.p, &g_Alloc);
+ if (res == SZ_ERROR_PROGRESS)
+ return (openWrap.Res == S_OK) ? E_FAIL : openWrap.Res;
+ /*
+ if (res == SZ_ERROR_NO_ARCHIVE && xzs.p.num > 0)
+ res = SZ_OK;
+ */
+ if (res == SZ_OK && startPosition == 0)
+ {
+ _phySize_Defined = true;
+
+ _stat.OutSize = Xzs_GetUnpackSize(&xzs.p);
+ _stat.UnpackSize_Defined = true;
+
+ _stat.NumStreams = xzs.p.num;
+ _stat.NumStreams_Defined = true;
+
+ _stat.NumBlocks = Xzs_GetNumBlocks(&xzs.p);
+ _stat.NumBlocks_Defined = true;
+
+ AddString(_methodsString, GetCheckString(xzs.p));
+ }
+ else
+ {
+ res = SZ_OK;
+ }
+
+ RINOK(SRes_to_Open_HRESULT(res));
_stream = inStream;
_seqStream = inStream;
+ _isArc = true;
return S_OK;
}
STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)
{
COM_TRY_BEGIN
- try
{
Close();
return Open2(inStream, callback);
}
- catch(...) { return S_FALSE; }
COM_TRY_END
}
@@ -404,15 +479,21 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
{
Close();
_seqStream = stream;
+ _isArc = true;
+ _needSeekToStart = false;
return S_OK;
}
STDMETHODIMP CHandler::Close()
{
- _numBlocks = 0;
- _useSeq = true;
- _unpackSizeDefined = _packSizeDefined = false;
- _methodsString.Empty();
+ _stat.Clear();
+
+ _isArc = false;
+ _needSeekToStart = false;
+
+ _phySize_Defined = false;
+
+ _methodsString.Empty();
_stream.Release();
_seqStream.Release();
return S_OK;
@@ -437,146 +518,213 @@ STDMETHODIMP CSeekToSeqStream::Read(void *data, UInt32 size, UInt32 *processedSi
STDMETHODIMP CSeekToSeqStream::Seek(Int64, UInt32, UInt64 *) { return E_NOTIMPL; }
-struct CXzUnpackerCPP
+CXzUnpackerCPP::CXzUnpackerCPP(): InBuf(0), OutBuf(0)
{
- Byte *InBuf;
- Byte *OutBuf;
- CXzUnpacker p;
- CXzUnpackerCPP(): InBuf(0), OutBuf(0)
- {
- XzUnpacker_Construct(&p, &g_Alloc);
- }
- ~CXzUnpackerCPP()
- {
- XzUnpacker_Free(&p);
- MyFree(InBuf);
- MyFree(OutBuf);
- }
-};
+ XzUnpacker_Construct(&p, &g_Alloc);
+}
-STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
- Int32 testMode, IArchiveExtractCallback *extractCallback)
+CXzUnpackerCPP::~CXzUnpackerCPP()
{
- COM_TRY_BEGIN
- if (numItems == 0)
- return S_OK;
- if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
- return E_INVALIDARG;
-
- extractCallback->SetTotal(_packSize);
- UInt64 currentTotalPacked = 0;
- RINOK(extractCallback->SetCompleted(&currentTotalPacked));
- CMyComPtr<ISequentialOutStream> realOutStream;
- Int32 askMode = testMode ?
- NExtract::NAskMode::kTest :
- NExtract::NAskMode::kExtract;
-
- RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
-
- if (!testMode && !realOutStream)
- return S_OK;
-
- extractCallback->PrepareOperation(askMode);
-
- if (_stream)
- {
- RINOK(_stream->Seek(_startPosition, STREAM_SEEK_SET, NULL));
- }
-
- CLocalProgress *lps = new CLocalProgress;
- CMyComPtr<ICompressProgressInfo> progress = lps;
- lps->Init(extractCallback, true);
-
- CCompressProgressWrap progressWrap(progress);
+ XzUnpacker_Free(&p);
+ MyFree(InBuf);
+ MyFree(OutBuf);
+}
- SRes res = S_OK;
+HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
+{
+ const size_t kInBufSize = 1 << 15;
+ const size_t kOutBufSize = 1 << 21;
- const UInt32 kInBufSize = 1 << 15;
- const UInt32 kOutBufSize = 1 << 21;
+ Clear();
+ DecodeRes = SZ_OK;
- UInt32 inPos = 0;
- UInt32 inSize = 0;
- UInt32 outPos = 0;
- CXzUnpackerCPP xzu;
XzUnpacker_Init(&xzu.p);
- {
+ if (!xzu.InBuf)
xzu.InBuf = (Byte *)MyAlloc(kInBufSize);
+ if (!xzu.OutBuf)
xzu.OutBuf = (Byte *)MyAlloc(kOutBufSize);
- if (xzu.InBuf == 0 || xzu.OutBuf == 0)
- res = SZ_ERROR_MEM;
- }
- if (res == SZ_OK)
+
+ UInt32 inSize = 0;
+ SizeT inPos = 0;
+ SizeT outPos = 0;
+
for (;;)
{
if (inPos == inSize)
{
inPos = inSize = 0;
- RINOK(_seqStream->Read(xzu.InBuf, kInBufSize, &inSize));
+ RINOK(seqInStream->Read(xzu.InBuf, kInBufSize, &inSize));
}
SizeT inLen = inSize - inPos;
SizeT outLen = kOutBufSize - outPos;
ECoderStatus status;
- res = XzUnpacker_Code(&xzu.p,
+
+ SRes res = XzUnpacker_Code(&xzu.p,
xzu.OutBuf + outPos, &outLen,
xzu.InBuf + inPos, &inLen,
(inSize == 0 ? CODER_FINISH_END : CODER_FINISH_ANY), &status);
- // printf("\n_inPos = %6d inLen = %5d, outLen = %5d", inPos, inLen, outLen);
+ inPos += inLen;
+ outPos += outLen;
+
+ InSize += inLen;
+ OutSize += outLen;
- inPos += (UInt32)inLen;
- outPos += (UInt32)outLen;
- lps->InSize += inLen;
- lps->OutSize += outLen;
+ DecodeRes = res;
- bool finished = (((inLen == 0) && (outLen == 0)) || res != SZ_OK);
+ bool finished = ((inLen == 0 && outLen == 0) || res != SZ_OK);
- if (outPos == kOutBufSize || finished)
+ if (outStream)
{
- if (realOutStream && outPos > 0)
+ if (outPos == kOutBufSize || finished)
{
- RINOK(WriteStream(realOutStream, xzu.OutBuf, outPos));
+ if (outPos != 0)
+ {
+ RINOK(WriteStream(outStream, xzu.OutBuf, outPos));
+ outPos = 0;
+ }
}
+ }
+ else
outPos = 0;
+
+ if (progress)
+ {
+ RINOK(progress->SetRatioInfo(&InSize, &OutSize));
}
- RINOK(lps->SetCur());
+
if (finished)
{
- _packSize = lps->InSize;
- _unpackSize = lps->OutSize;
- _packSizeDefined = _unpackSizeDefined = true;
+ PhySize = InSize;
+ NumStreams = xzu.p.numStartedStreams;
+ if (NumStreams > 0)
+ IsArc = true;
+ NumBlocks = xzu.p.numTotalBlocks;
+
+ UnpackSize_Defined = true;
+ NumStreams_Defined = true;
+ NumBlocks_Defined = true;
+
+ UInt64 extraSize = XzUnpacker_GetExtraSize(&xzu.p);
+
if (res == SZ_OK)
{
if (status == CODER_STATUS_NEEDS_MORE_INPUT)
{
- if (XzUnpacker_IsStreamWasFinished(&xzu.p))
- _packSize -= xzu.p.padSize;
- else
+ 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
+ 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;
+ }
+ }
+ }
+
+ DecodeRes = res;
+ PhySize -= extraSize;
+
+ 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;
+ }
+
break;
}
}
+ return S_OK;
+}
+
+Int32 CDecoder::Get_Extract_OperationResult() const
+{
Int32 opRes;
- switch(res)
+ if (!IsArc)
+ opRes = NExtract::NOperationResult::kIsNotArc;
+ else if (UnexpectedEnd)
+ opRes = NExtract::NOperationResult::kUnexpectedEnd;
+ else if (DataAfterEnd)
+ opRes = NExtract::NOperationResult::kDataAfterEnd;
+ else if (CrcError)
+ opRes = NExtract::NOperationResult::kCRCError;
+ else if (Unsupported)
+ opRes = NExtract::NOperationResult::kUnsupportedMethod;
+ else if (HeadersError)
+ opRes = NExtract::NOperationResult::kDataError;
+ else if (DataError)
+ opRes = NExtract::NOperationResult::kDataError;
+ else if (DecodeRes != 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)
+{
+ COM_TRY_BEGIN
+ if (numItems == 0)
+ return S_OK;
+ if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
+ return E_INVALIDARG;
+
+ if (_phySize_Defined)
+ extractCallback->SetTotal(_stat.PhySize);
+
+ UInt64 currentTotalPacked = 0;
+ RINOK(extractCallback->SetCompleted(&currentTotalPacked));
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode = testMode ?
+ NExtract::NAskMode::kTest :
+ NExtract::NAskMode::kExtract;
+
+ RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
+
+ if (!testMode && !realOutStream)
+ return S_OK;
+
+ extractCallback->PrepareOperation(askMode);
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> lpsRef = lps;
+ lps->Init(extractCallback, true);
+
+ if (_needSeekToStart)
{
- case SZ_OK:
- opRes = NExtract::NOperationResult::kOK; break;
- case SZ_ERROR_UNSUPPORTED:
- opRes = NExtract::NOperationResult::kUnSupportedMethod; break;
- case SZ_ERROR_CRC:
- opRes = NExtract::NOperationResult::kCRCError; break;
- case SZ_ERROR_DATA:
- case SZ_ERROR_ARCHIVE:
- case SZ_ERROR_NO_ARCHIVE:
- opRes = NExtract::NOperationResult::kDataError; break;
- default:
- return SResToHRESULT(res);
+ if (!_stream)
+ return E_FAIL;
+ RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
}
+ else
+ _needSeekToStart = true;
+
+ CDecoder decoder;
+ RINOK(Decode2(_seqStream, realOutStream, decoder, lpsRef));
+ Int32 opRes = decoder.Get_Extract_OperationResult();
+
realOutStream.Release();
return extractCallback->SetOperationResult(opRes);
COM_TRY_END
@@ -593,6 +741,8 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
{
+ COM_TRY_BEGIN
+
CSeqOutStreamWrap seqOutStream(outStream);
if (numItems == 0)
@@ -648,7 +798,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
RINOK(NCompress::NLzma2::SetLzma2Prop(NCoderPropID::kReduceSize, prop, lzma2Props));
}
- for (int i = 0; i < _methods.Size(); i++)
+ FOR_VECTOR (i, _methods)
{
COneMethodInfo &m = _methods[i];
SetGlobalLevelAndThreads(m
@@ -657,7 +807,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
#endif
);
{
- for (int j = 0; j < m.Props.Size(); j++)
+ FOR_VECTOR (j, m.Props)
{
const CProp &prop = m.Props[j];
RINOK(NCompress::NLzma2::SetLzma2Prop(prop.Id, prop.Value, lzma2Props));
@@ -692,7 +842,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (_filterId == XZ_ID_Delta)
{
bool deltaDefined = false;
- for (int j = 0; j < _filterMethod.Props.Size(); j++)
+ FOR_VECTOR (j, _filterMethod.Props)
{
const CProp &prop = _filterMethod.Props[j];
if (prop.Id == NCoderPropID::kDefaultProp && prop.Value.vt == VT_UI4)
@@ -712,32 +862,50 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
return SResToHRESULT(res);
}
+
if (indexInArchive != 0)
return E_INVALIDARG;
+
+ CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
+ updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
+ if (opCallback)
+ {
+ RINOK(opCallback->ReportOperation(NEventIndexType::kInArcIndex, 0, NUpdateNotifyOp::kReplicate))
+ }
+
if (_stream)
- RINOK(_stream->Seek(_startPosition, STREAM_SEEK_SET, NULL));
- return NCompress::CopyStream(_stream, outStream, 0);
-}
+ {
+ if (_phySize_Defined)
+ RINOK(updateCallback->SetTotal(_stat.PhySize));
+ RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
+ }
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(updateCallback, true);
-STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
+ return NCompress::CopyStream(_stream, outStream, progress);
+
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
COM_TRY_BEGIN
+
Init();
- for (int i = 0; i < numProps; i++)
+ for (UInt32 i = 0; i < numProps; i++)
{
RINOK(SetProperty(names[i], values[i]));
}
if (!_filterMethod.MethodName.IsEmpty())
{
- int k;
+ unsigned k;
for (k = 0; k < ARRAY_SIZE(g_NamePairs); k++)
{
const CMethodNamePair &pair = g_NamePairs[k];
- UString m = GetUnicodeString(pair.Name);
- if (_filterMethod.MethodName.CompareNoCase(m) == 0)
+ if (StringsAreEqualNoCase_Ascii(_filterMethod.MethodName, pair.Name))
{
_filterId = pair.Id;
break;
@@ -747,34 +915,30 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
return E_INVALIDARG;
}
- int numEmptyMethods = GetNumEmptyMethods();
- _methods.Delete(0, numEmptyMethods);
+ _methods.DeleteFrontal(GetNumEmptyMethods());
if (_methods.Size() > 1)
return E_INVALIDARG;
if (_methods.Size() == 1)
{
- UString &methodName = _methods[0].MethodName;
+ AString &methodName = _methods[0].MethodName;
if (methodName.IsEmpty())
methodName = k_LZMA2_Name;
- else if (methodName.CompareNoCase(k_LZMA2_Name) != 0)
+ else if (!methodName.IsEqualTo_Ascii_NoCase(k_LZMA2_Name))
return E_INVALIDARG;
}
+
return S_OK;
+
COM_TRY_END
}
#endif
-static IInArchive *CreateArc() { return new NArchive::NXz::CHandler; }
-#ifndef EXTRACT_ONLY
-static IOutArchive *CreateArcOut() { return new NArchive::NXz::CHandler; }
-#else
-#define CreateArcOut 0
-#endif
-
-static CArcInfo g_ArcInfo =
- { L"xz", L"xz txz", L"* .tar", 0xC, {0xFD, '7' , 'z', 'X', 'Z', '\0'}, 6, true, CreateArc, CreateArcOut };
-
-REGISTER_ARC(xz)
+REGISTER_ARC_IO(
+ "xz", "xz txz", "* .tar", 0xC,
+ XZ_SIG,
+ 0,
+ NArcInfoFlags::kKeepName,
+ NULL)
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/XzHandler.h b/3rdparty/lzma/CPP/7zip/Archive/XzHandler.h
new file mode 100644
index 00000000000..4a59e356a85
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Archive/XzHandler.h
@@ -0,0 +1,65 @@
+// XzHandler.h
+
+#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/3rdparty/lzma/CPP/7zip/Asm.mak b/3rdparty/lzma/CPP/7zip/Asm.mak
index 4ab94f153f1..4f77dddfad0 100644
--- a/3rdparty/lzma/CPP/7zip/Asm.mak
+++ b/3rdparty/lzma/CPP/7zip/Asm.mak
@@ -1,3 +1,4 @@
+!IFDEF ASM_OBJS
!IF "$(CPU)" == "ARM"
$(ASM_OBJS): ../../../../Asm/Arm/$(*B).asm
$(COMPL_ASM)
@@ -5,3 +6,4 @@ $(ASM_OBJS): ../../../../Asm/Arm/$(*B).asm
$(ASM_OBJS): ../../../../Asm/x86/$(*B).asm
$(COMPL_ASM)
!ENDIF
+!ENDIF
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp
index a89e85170d6..d220b198b37 100644
--- a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp
+++ b/3rdparty/lzma/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 /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_NO_CRYPTO" /Yu"StdAfx.h" /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 BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -52,7 +52,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
@@ -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 /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_NO_CRYPTO" /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" /Yu"StdAfx.h" /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
@@ -77,7 +77,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept
!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
@@ -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 /Gz /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "_NO_CRYPTO" /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 BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -103,7 +103,7 @@ BSC32=bscmake.exe
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za.exe" /opt:NOWIN98
# SUBTRACT BASE LINK32 /pdb:none
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
@@ -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 /Gz /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "_NO_CRYPTO" /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 BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
@@ -129,7 +129,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za.exe" /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept
!ENDIF
@@ -176,6 +176,14 @@ SOURCE=..\..\UI\Console\ExtractCallbackConsole.h
# End Source File
# Begin Source File
+SOURCE=..\..\UI\Console\HashCon.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\HashCon.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\UI\Console\List.cpp
# End Source File
# Begin Source File
@@ -185,6 +193,7 @@ SOURCE=..\..\UI\Console\List.h
# Begin Source File
SOURCE=..\..\UI\Console\Main.cpp
+# ADD CPP /D "PROG_VARIANT_R"
# End Source File
# Begin Source File
@@ -269,6 +278,10 @@ SOURCE=..\..\..\Common\CRC.cpp
# End Source File
# Begin Source File
+SOURCE=..\..\..\Common\CrcReg.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Common\Defs.h
# End Source File
# Begin Source File
@@ -337,6 +350,10 @@ SOURCE=..\..\..\Common\NewHandler.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Common\Sha256Reg.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Common\StdInStream.cpp
# End Source File
# Begin Source File
@@ -387,6 +404,10 @@ SOURCE=..\..\..\Common\Wildcard.cpp
SOURCE=..\..\..\Common\Wildcard.h
# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\XzCrc64Reg.cpp
+# End Source File
# End Group
# Begin Group "Windows"
@@ -409,11 +430,11 @@ SOURCE=..\..\..\Windows\DLL.h
# End Source File
# Begin Source File
-SOURCE=..\..\..\Windows\Error.cpp
+SOURCE=..\..\..\Windows\ErrorMsg.cpp
# End Source File
# Begin Source File
-SOURCE=..\..\..\Windows\Error.h
+SOURCE=..\..\..\Windows\ErrorMsg.h
# End Source File
# Begin Source File
@@ -441,6 +462,10 @@ SOURCE=..\..\..\Windows\FileIO.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Windows\FileLink.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Windows\FileMapping.h
# End Source File
# Begin Source File
@@ -473,11 +498,11 @@ SOURCE=..\..\..\Windows\PropVariant.h
# End Source File
# Begin Source File
-SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+SOURCE=..\..\..\Windows\PropVariantConv.cpp
# End Source File
# Begin Source File
-SOURCE=..\..\..\Windows\PropVariantConversions.h
+SOURCE=..\..\..\Windows\PropVariantConv.h
# End Source File
# Begin Source File
@@ -501,11 +526,11 @@ SOURCE=..\..\..\Windows\Thread.h
# End Source File
# Begin Source File
-SOURCE=..\..\..\Windows\Time.cpp
+SOURCE=..\..\..\Windows\TimeUtils.cpp
# End Source File
# Begin Source File
-SOURCE=..\..\..\Windows\Time.h
+SOURCE=..\..\..\Windows\TimeUtils.h
# End Source File
# End Group
# Begin Group "7zip Common"
@@ -521,14 +546,6 @@ SOURCE=..\..\Common\CreateCoder.h
# End Source File
# Begin Source File
-SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\Archive\Common\CrossThreadProgress.h
-# End Source File
-# Begin Source File
-
SOURCE=..\..\Common\CWrappers.cpp
# End Source File
# Begin Source File
@@ -633,6 +650,10 @@ SOURCE=..\..\Common\ProgressUtils.h
# End Source File
# Begin Source File
+SOURCE=..\..\Common\PropId.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Common\RegisterArc.h
# End Source File
# Begin Source File
@@ -665,6 +686,14 @@ SOURCE=..\..\Common\StreamUtils.h
# End Source File
# Begin Source File
+SOURCE=..\..\Common\UniqBlocks.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\UniqBlocks.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Common\VirtThread.cpp
# End Source File
# Begin Source File
@@ -701,14 +730,6 @@ SOURCE=..\..\Compress\BcjRegister.cpp
# End Source File
# Begin Source File
-SOURCE=..\..\Compress\BranchCoder.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\Compress\BranchCoder.h
-# End Source File
-# Begin Source File
-
SOURCE=..\..\Compress\BranchMisc.cpp
# End Source File
# Begin Source File
@@ -783,22 +804,6 @@ SOURCE=..\..\Compress\LzmaEncoder.h
SOURCE=..\..\Compress\LzmaRegister.cpp
# End Source File
-# Begin Source File
-
-SOURCE=..\..\Compress\RangeCoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\Compress\RangeCoderBit.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\Compress\RangeCoderBitTree.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\Compress\RangeCoderOpt.h
-# End Source File
# End Group
# Begin Group "Archive"
@@ -844,14 +849,6 @@ SOURCE=..\..\Archive\7z\7zFolderInStream.h
# End Source File
# Begin Source File
-SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\Archive\7z\7zFolderOutStream.h
-# End Source File
-# Begin Source File
-
SOURCE=..\..\Archive\7z\7zHandler.cpp
# End Source File
# Begin Source File
@@ -932,14 +929,6 @@ SOURCE=..\..\Archive\Common\CoderMixer2.h
# End Source File
# Begin Source File
-SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\Archive\Common\CoderMixer2MT.h
-# End Source File
-# Begin Source File
-
SOURCE=..\..\Archive\Common\DummyOutStream.cpp
# End Source File
# Begin Source File
@@ -997,6 +986,10 @@ SOURCE=..\..\Archive\Common\ParseProperties.h
# End Group
# Begin Source File
+SOURCE=..\..\Archive\IArchive.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Archive\LzmaHandler.cpp
# End Source File
# Begin Source File
@@ -1077,6 +1070,14 @@ SOURCE=..\..\UI\Common\ExtractingFilePath.h
# End Source File
# Begin Source File
+SOURCE=..\..\UI\Common\HashCalc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\HashCalc.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\UI\Common\LoadCodecs.cpp
# End Source File
# Begin Source File
@@ -1288,6 +1289,30 @@ SOURCE=..\..\..\..\C\XzCrc64.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\XzCrc64Opt.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\XzDec.c
!IF "$(CFG)" == "Alone - Win32 Release"
@@ -1404,6 +1429,58 @@ SOURCE=..\..\..\..\C\7zStream.c
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\Aes.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\Aes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\AesOpt.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\Alloc.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -1413,6 +1490,58 @@ SOURCE=..\..\..\..\C\Alloc.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\Bcj2.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\Bcj2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bcj2Enc.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\Bra.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -1652,5 +1781,37 @@ SOURCE=..\..\..\..\C\Threads.h
SOURCE=..\..\..\..\C\Types.h
# End Source File
# End Group
+# Begin Group "Crypto"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAes.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAesRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\MyAes.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\MyAes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\RandGen.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\RandGen.h
+# End Source File
+# End Group
# End Target
# End Project
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h
index 2e4be10b291..2854ff3e935 100644
--- a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../../Common/MyWindows.h"
-#include "../../../Common/NewHandler.h"
+#include "../../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/makefile b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/makefile
index 8de884f7318..15c51f91987 100644
--- a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/makefile
+++ b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/makefile
@@ -1,52 +1,43 @@
PROG = 7zr.exe
MY_CONSOLE = 1
-CFLAGS = $(CFLAGS) -I ../../../ \
- -D_NO_CRYPTO \
+CFLAGS = $(CFLAGS) -DPROG_VARIANT_R
!IFNDEF UNDER_CE
CFLAGS = $(CFLAGS) -DWIN_LONG_PATH
!ENDIF
-CONSOLE_OBJS = \
- $O\BenchCon.obj \
- $O\ConsoleClose.obj \
- $O\ExtractCallbackConsole.obj \
- $O\List.obj \
- $O\Main.obj \
- $O\MainAr.obj \
- $O\OpenCallbackConsole.obj \
- $O\PercentPrinter.obj \
- $O\UpdateCallbackConsole.obj \
- $O\UserInputUtils.obj \
-
COMMON_OBJS = \
$O\CommandLineParser.obj \
$O\CRC.obj \
+ $O\CrcReg.obj \
$O\IntToString.obj \
$O\ListFileUtils.obj \
$O\NewHandler.obj \
$O\StdInStream.obj \
$O\StdOutStream.obj \
$O\MyString.obj \
+ $O\Sha256Reg.obj \
$O\StringConvert.obj \
$O\StringToInt.obj \
$O\UTFConvert.obj \
$O\MyVector.obj \
$O\Wildcard.obj \
+ $O\XzCrc64Reg.obj \
WIN_OBJS = \
$O\DLL.obj \
- $O\Error.obj \
+ $O\ErrorMsg.obj \
$O\FileDir.obj \
$O\FileFind.obj \
$O\FileIO.obj \
+ $O\FileLink.obj \
$O\FileName.obj \
$O\MemoryLock.obj \
$O\PropVariant.obj \
- $O\PropVariantConversions.obj \
+ $O\PropVariantConv.obj \
$O\Synchronization.obj \
$O\System.obj \
- $O\Time.obj \
+ $O\TimeUtils.obj \
7ZIP_COMMON_OBJS = \
$O\CreateCoder.obj \
@@ -57,38 +48,18 @@ WIN_OBJS = \
$O\InOutTempBuffer.obj \
$O\FilterCoder.obj \
$O\LimitedStreams.obj \
- $O\LockedStream.obj \
$O\MethodId.obj \
$O\MethodProps.obj \
$O\OffsetStream.obj \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
+ $O\PropId.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
$O\StreamUtils.obj \
+ $O\UniqBlocks.obj \
$O\VirtThread.obj \
-UI_COMMON_OBJS = \
- $O\ArchiveCommandLine.obj \
- $O\ArchiveExtractCallback.obj \
- $O\ArchiveOpenCallback.obj \
- $O\Bench.obj \
- $O\DefaultName.obj \
- $O\EnumDirItems.obj \
- $O\Extract.obj \
- $O\ExtractingFilePath.obj \
- $O\LoadCodecs.obj \
- $O\OpenArchive.obj \
- $O\PropIDUtils.obj \
- $O\SetProperties.obj \
- $O\SortUtils.obj \
- $O\TempFiles.obj \
- $O\Update.obj \
- $O\UpdateAction.obj \
- $O\UpdateCallback.obj \
- $O\UpdatePair.obj \
- $O\UpdateProduce.obj \
-
AR_OBJS = \
$O\LzmaHandler.obj \
$O\SplitHandler.obj \
@@ -96,8 +67,6 @@ AR_OBJS = \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
- $O\CoderMixer2MT.obj \
- $O\CrossThreadProgress.obj \
$O\DummyOutStream.obj \
$O\HandlerOut.obj \
$O\InStreamWithCRC.obj \
@@ -113,7 +82,6 @@ AR_COMMON_OBJS = \
$O\7zEncode.obj \
$O\7zExtract.obj \
$O\7zFolderInStream.obj \
- $O\7zFolderOutStream.obj \
$O\7zHandler.obj \
$O\7zHandlerOut.obj \
$O\7zHeader.obj \
@@ -129,7 +97,6 @@ COMPRESS_OBJS = \
$O\Bcj2Register.obj \
$O\BcjCoder.obj \
$O\BcjRegister.obj \
- $O\BranchCoder.obj \
$O\BranchMisc.obj \
$O\BranchRegister.obj \
$O\ByteSwap.obj \
@@ -143,9 +110,18 @@ COMPRESS_OBJS = \
$O\LzmaEncoder.obj \
$O\LzmaRegister.obj \
+CRYPTO_OBJS = \
+ $O\7zAes.obj \
+ $O\7zAesRegister.obj \
+ $O\MyAes.obj \
+ $O\MyAesReg.obj \
+ $O\RandGen.obj \
+
C_OBJS = \
$O\7zStream.obj \
$O\Alloc.obj \
+ $O\Bcj2.obj \
+ $O\Bcj2Enc.obj \
$O\Bra.obj \
$O\Bra86.obj \
$O\BraIA64.obj \
@@ -159,54 +135,17 @@ C_OBJS = \
$O\LzmaEnc.obj \
$O\MtCoder.obj \
$O\Sha256.obj \
+ $O\Sort.obj \
$O\Threads.obj \
$O\Xz.obj \
- $O\XzCrc64.obj \
$O\XzDec.obj \
$O\XzEnc.obj \
$O\XzIn.obj \
-!include "../../Crc.mak"
-
-OBJS = \
- $O\StdAfx.obj \
- $(CONSOLE_OBJS) \
- $(COMMON_OBJS) \
- $(WIN_OBJS) \
- $(7ZIP_COMMON_OBJS) \
- $(UI_COMMON_OBJS) \
- $(AR_OBJS) \
- $(AR_COMMON_OBJS) \
- $(7Z_OBJS) \
- $(COMPRESS_OBJS) \
- $(C_OBJS) \
- $(ASM_OBJS) \
- $O\resource.res
+!include "../../UI/Console/Console.mak"
+!include "../../Aes.mak"
+!include "../../Crc.mak"
+!include "../../Crc64.mak"
-!include "../../../Build.mak"
-
-$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp
- $(COMPL)
-
-$(COMMON_OBJS): ../../../Common/$(*B).cpp
- $(COMPL)
-$(WIN_OBJS): ../../../Windows/$(*B).cpp
- $(COMPL)
-$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
- $(COMPL)
-$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
- $(COMPL)
-$(AR_OBJS): ../../Archive/$(*B).cpp
- $(COMPL)
-$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
- $(COMPL)
-
-$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
- $(COMPL)
-$(COMPRESS_OBJS): ../../Compress/$(*B).cpp
- $(COMPL_O2)
-$(C_OBJS): ../../../../C/$(*B).c
- $(COMPL_O2)
-
-!include "../../Asm.mak"
+!include "../../7zip.mak"
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
index 2e4be10b291..2854ff3e935 100644
--- a/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../../Common/MyWindows.h"
-#include "../../../Common/NewHandler.h"
+#include "../../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile b/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile
index e953af905e7..724477e9493 100644
--- a/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile
+++ b/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile
@@ -1,11 +1,12 @@
PROG = 7zxr.dll
DEF_FILE = ../../Archive/Archive2.def
-CFLAGS = $(CFLAGS) -I ../../../ \
+CFLAGS = $(CFLAGS) \
-DEXTRACT_ONLY \
-D_NO_CRYPTO
COMMON_OBJS = \
$O\CRC.obj \
+ $O\CrcReg.obj \
$O\IntToString.obj \
$O\NewHandler.obj \
$O\MyString.obj \
@@ -25,11 +26,11 @@ WIN_OBJS = \
$O\InBuffer.obj \
$O\FilterCoder.obj \
$O\LimitedStreams.obj \
- $O\LockedStream.obj \
$O\MethodId.obj \
$O\MethodProps.obj \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
+ $O\PropId.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
$O\StreamUtils.obj \
@@ -41,8 +42,6 @@ AR_OBJS = \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
- $O\CoderMixer2MT.obj \
- $O\CrossThreadProgress.obj \
$O\HandlerOut.obj \
$O\ItemNameUtils.obj \
$O\OutStreamWithCRC.obj \
@@ -53,7 +52,6 @@ AR_COMMON_OBJS = \
$O\7zCompressionMode.obj \
$O\7zDecode.obj \
$O\7zExtract.obj \
- $O\7zFolderOutStream.obj \
$O\7zHandler.obj \
$O\7zHeader.obj \
$O\7zIn.obj \
@@ -67,7 +65,6 @@ COMPRESS_OBJS = \
$O\Bcj2Register.obj \
$O\BcjCoder.obj \
$O\BcjRegister.obj \
- $O\BranchCoder.obj \
$O\BranchMisc.obj \
$O\BranchRegister.obj \
$O\ByteSwap.obj \
@@ -81,6 +78,7 @@ COMPRESS_OBJS = \
C_OBJS = \
$O\Alloc.obj \
+ $O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
$O\BraIA64.obj \
@@ -92,41 +90,4 @@ C_OBJS = \
!include "../../Crc.mak"
-OBJS = \
- $O\StdAfx.obj \
- $(CONSOLE_OBJS) \
- $(COMMON_OBJS) \
- $(WIN_OBJS) \
- $(7ZIP_COMMON_OBJS) \
- $(AR_OBJS) \
- $(AR_COMMON_OBJS) \
- $(7Z_OBJS) \
- $(COMPRESS_OBJS) \
- $(C_OBJS) \
- $(ASM_OBJS) \
- $O\resource.res
-
-
-!include "../../../Build.mak"
-
-$(COMMON_OBJS): ../../../Common/$(*B).cpp
- $(COMPL)
-$(WIN_OBJS): ../../../Windows/$(*B).cpp
- $(COMPL)
-$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
- $(COMPL)
-$(AR_OBJS): ../../Archive/$(*B).cpp
- $(COMPL)
-$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
- $(COMPL)
-
-$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
- $(COMPL)
-
-$(COMPRESS_OBJS): ../../Compress/$(*B).cpp
- $(COMPL_O2)
-
-$(C_OBJS): ../../../../C/$(*B).c
- $(COMPL_O2)
-
-!include "../../Asm.mak"
+!include "../../7zip.mak"
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h
index 2e4be10b291..2854ff3e935 100644
--- a/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../../Common/MyWindows.h"
-#include "../../../Common/NewHandler.h"
+#include "../../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/makefile b/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/makefile
index d7ffcea1654..916dc568c38 100644
--- a/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/makefile
+++ b/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/makefile
@@ -1,10 +1,11 @@
PROG = 7zra.dll
DEF_FILE = ../../Archive/Archive2.def
-CFLAGS = $(CFLAGS) -I ../../../ \
+CFLAGS = $(CFLAGS) \
-D_NO_CRYPTO
COMMON_OBJS = \
$O\CRC.obj \
+ $O\CrcReg.obj \
$O\IntToString.obj \
$O\NewHandler.obj \
$O\MyString.obj \
@@ -17,6 +18,7 @@ WIN_OBJS = \
$O\FileDir.obj \
$O\FileFind.obj \
$O\FileIO.obj \
+ $O\FileName.obj \
$O\PropVariant.obj \
$O\Synchronization.obj \
$O\System.obj \
@@ -28,14 +30,15 @@ WIN_OBJS = \
$O\InOutTempBuffer.obj \
$O\FilterCoder.obj \
$O\LimitedStreams.obj \
- $O\LockedStream.obj \
$O\MethodId.obj \
$O\MethodProps.obj \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
+ $O\PropId.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
$O\StreamUtils.obj \
+ $O\UniqBlocks.obj \
$O\VirtThread.obj \
AR_OBJS = \
@@ -44,8 +47,6 @@ AR_OBJS = \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
- $O\CoderMixer2MT.obj \
- $O\CrossThreadProgress.obj \
$O\HandlerOut.obj \
$O\InStreamWithCRC.obj \
$O\ItemNameUtils.obj \
@@ -59,7 +60,6 @@ AR_COMMON_OBJS = \
$O\7zEncode.obj \
$O\7zExtract.obj \
$O\7zFolderInStream.obj \
- $O\7zFolderOutStream.obj \
$O\7zHandler.obj \
$O\7zHandlerOut.obj \
$O\7zHeader.obj \
@@ -77,7 +77,6 @@ COMPRESS_OBJS = \
$O\Bcj2Register.obj \
$O\BcjCoder.obj \
$O\BcjRegister.obj \
- $O\BranchCoder.obj \
$O\BranchMisc.obj \
$O\BranchRegister.obj \
$O\ByteSwap.obj \
@@ -93,6 +92,8 @@ COMPRESS_OBJS = \
C_OBJS = \
$O\Alloc.obj \
+ $O\Bcj2.obj \
+ $O\Bcj2Enc.obj \
$O\Bra.obj \
$O\Bra86.obj \
$O\BraIA64.obj \
@@ -109,41 +110,4 @@ C_OBJS = \
!include "../../Crc.mak"
-OBJS = \
- $O\StdAfx.obj \
- $(CONSOLE_OBJS) \
- $(COMMON_OBJS) \
- $(WIN_OBJS) \
- $(7ZIP_COMMON_OBJS) \
- $(AR_OBJS) \
- $(AR_COMMON_OBJS) \
- $(7Z_OBJS) \
- $(COMPRESS_OBJS) \
- $(C_OBJS) \
- $(ASM_OBJS) \
- $O\resource.res
-
-
-!include "../../../Build.mak"
-
-$(COMMON_OBJS): ../../../Common/$(*B).cpp
- $(COMPL)
-$(WIN_OBJS): ../../../Windows/$(*B).cpp
- $(COMPL)
-$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
- $(COMPL)
-$(AR_OBJS): ../../Archive/$(*B).cpp
- $(COMPL)
-$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
- $(COMPL)
-
-$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
- $(COMPL)
-
-$(COMPRESS_OBJS): ../../Compress/$(*B).cpp
- $(COMPL_O2)
-
-$(C_OBJS): ../../../../C/$(*B).c
- $(COMPL_O2)
-
-!include "../../Asm.mak"
+!include "../../7zip.mak"
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
index e0f4dcba3d4..5ca288f4696 100644
--- a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
+++ b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
@@ -12,7 +12,7 @@
#define MY_SET_BINARY_MODE(file)
#endif
-// #include "../../../Common/MyWindows.h"
+#include "../../../Common/MyWindows.h"
#include "../../../Common/MyInitGuid.h"
#include "../../../../C/7zVersion.h"
@@ -25,6 +25,7 @@
#include "../../../Windows/System.h"
#endif
+#include "../../../Common/IntToString.h"
#include "../../../Common/CommandLineParser.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
@@ -36,14 +37,41 @@
#include "../../Compress/LzmaEncoder.h"
#include "../../UI/Console/BenchCon.h"
-
+#include "../../UI/Console/ConsoleClose.h"
using namespace NCommandLineParser;
+static const unsigned kDictSizeLog = 24;
+
+static const char *kCopyrightString = "\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n\n";
+
+static const char *kHelpString =
+ "Usage: LZMA <command> [inputFile] [outputFile] [<switches>...]\n"
+ "\n"
+ "<command>\n"
+ " e : Encode file\n"
+ " d : Decode file\n"
+ " b : Benchmark\n"
+ "<switches>\n"
+ " -a{N} : set compression mode : [0, 1] : default = 1 (max)\n"
+ " -d{N} : set dictionary size : [12, 30] : default = 24 (16 MiB)\n"
+ " -fb{N} : set number of fast bytes : [5, 273] : default = 128\n"
+ " -mc{N} : set number of cycles for match finder\n"
+ " -lc{N} : set number of literal context bits : [0, 8] : default = 3\n"
+ " -lp{N} : set number of literal pos bits : [0, 4] : default = 0\n"
+ " -pb{N} : set number of pos bits : [0, 4] : default = 2\n"
+ " -mf{M} : set match finder: [hc4, bt2, bt3, bt4] : default = bt4\n"
+ " -mt{N} : set number of CPU threads\n"
+ " -eos : write end of stream marker\n"
+ " -si : read data from stdin\n"
+ " -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";
+
namespace NKey {
enum Enum
{
@@ -69,101 +97,214 @@ enum Enum
static const CSwitchForm kSwitchForms[] =
{
- { L"?", NSwitchType::kSimple, false },
- { L"H", NSwitchType::kSimple, false },
- { L"MM", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"X", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"A", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"D", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"FB", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"MC", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"LC", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"LP", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"PB", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"MF", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"MT", NSwitchType::kUnLimitedPostString, false, 0 },
- { L"EOS", NSwitchType::kSimple, false },
- { L"SI", NSwitchType::kSimple, false },
- { L"SO", NSwitchType::kSimple, false },
- { L"F86", NSwitchType::kPostChar, false, 0, 0, L"+" }
+ { "?", NSwitchType::kSimple, false },
+ { "H", NSwitchType::kSimple, false },
+ { "MM", NSwitchType::kString, false, 1 },
+ { "X", NSwitchType::kString, false, 1 },
+ { "A", NSwitchType::kString, false, 1 },
+ { "D", NSwitchType::kString, false, 1 },
+ { "FB", NSwitchType::kString, false, 1 },
+ { "MC", NSwitchType::kString, false, 1 },
+ { "LC", NSwitchType::kString, false, 1 },
+ { "LP", NSwitchType::kString, false, 1 },
+ { "PB", NSwitchType::kString, false, 1 },
+ { "MF", NSwitchType::kString, false, 1 },
+ { "MT", NSwitchType::kString, false, 0 },
+ { "EOS", NSwitchType::kSimple, false },
+ { "SI", NSwitchType::kSimple, false },
+ { "SO", NSwitchType::kSimple, false },
+ { "F86", NSwitchType::kChar, false, 0, "+" }
};
-static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]);
-static void PrintMessage(const char *s)
+static void PrintErr(const char *s)
{
fputs(s, stderr);
}
+static void PrintErr_LF(const char *s)
+{
+ PrintErr(s);
+ fputc('\n', stderr);
+}
+
+
+static void PrintError(const char *s)
+{
+ PrintErr("\nERROR: ");
+ PrintErr_LF(s);
+}
+
+static void PrintError2(const char *s1, const wchar_t *s2)
+{
+ PrintError(s1);
+ PrintErr_LF(GetOemString(s2));
+}
+
+static void PrintError_int(const char *s, int code)
+{
+ PrintError(s);
+ char temp[32];
+ ConvertInt64ToString(code, temp);
+ PrintErr("Error code = ");
+ PrintErr_LF(temp);
+}
+
+
+
+static void Print(const char *s)
+{
+ fputs(s, stdout);
+}
+
+static void Print_UInt64(UInt64 v)
+{
+ char temp[32];
+ ConvertUInt64ToString(v, temp);
+ Print(temp);
+}
+
+static void Print_MB(UInt64 v)
+{
+ Print_UInt64(v);
+ Print(" MiB");
+}
+
+static void Print_Size(const char *s, UInt64 v)
+{
+ Print(s);
+ Print_UInt64(v);
+ Print(" (");
+ Print_MB(v >> 20);
+ Print(")\n");
+}
+
+static void PrintTitle()
+{
+ Print(kCopyrightString);
+}
+
static void PrintHelp()
{
- PrintMessage("\nUsage: LZMA <e|d> inputFile outputFile [<switches>...]\n"
- " e: encode file\n"
- " d: decode file\n"
- " b: Benchmark\n"
- "<Switches>\n"
- " -a{N}: set compression mode - [0, 1], default: 1 (max)\n"
- " -d{N}: set dictionary size - [12, 30], default: 23 (8MB)\n"
- " -fb{N}: set number of fast bytes - [5, 273], default: 128\n"
- " -mc{N}: set number of cycles for match finder\n"
- " -lc{N}: set number of literal context bits - [0, 8], default: 3\n"
- " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n"
- " -pb{N}: set number of pos bits - [0, 4], default: 2\n"
- " -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, hc4], default: bt4\n"
- " -mt{N}: set number of CPU threads\n"
- " -eos: write End Of Stream marker\n"
- " -si: read data from stdin\n"
- " -so: write data to stdout\n"
- );
+ PrintTitle();
+ Print(kHelpString);
}
-static void PrintHelpAndExit(const char *s)
+class CProgressPrint:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
{
- fprintf(stderr, "\nError: %s\n\n", s);
- PrintHelp();
- throw -1;
+ UInt64 _size1;
+ UInt64 _size2;
+public:
+ CProgressPrint(): _size1(0), _size2(0) {}
+
+ void ClosePrint();
+
+ MY_UNKNOWN_IMP1(ICompressProgressInfo)
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+#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 =
+BACK_STR
+" "
+BACK_STR;
+
+
+void CProgressPrint::ClosePrint()
+{
+ Print(kBackSpaces);
}
-static void IncorrectCommand()
+STDMETHODIMP CProgressPrint::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
{
- PrintHelpAndExit("Incorrect command");
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ if (inSize)
+ {
+ UInt64 v1 = *inSize >> 20;
+ UInt64 v2 = _size2;
+ if (outSize)
+ v2 = *outSize >> 20;
+ if (v1 != _size1 || v2 != _size2)
+ {
+ _size1 = v1;
+ _size2 = v2;
+ ClosePrint();
+ Print_MB(_size1);
+ Print(" -> ");
+ Print_MB(_size2);
+ }
+ }
+ return S_OK;
}
-static void WriteArgumentsToStringList(int numArgs, const char *args[], UStringVector &strings)
+
+static void IncorrectCommand()
{
- for (int i = 1; i < numArgs; i++)
- strings.Add(MultiByteToUnicodeString(args[i]));
+ throw "Incorrect command";
}
-static bool GetNumber(const wchar_t *s, UInt32 &value)
+static UInt32 GetNumber(const wchar_t *s)
{
- value = 0;
- if (MyStringLen(s) == 0)
- return false;
const wchar_t *end;
- UInt64 res = ConvertStringToUInt64(s, &end);
- if (*end != L'\0')
- return false;
- if (res > 0xFFFFFFFF)
- return false;
- value = UInt32(res);
- return true;
+ UInt32 v = ConvertStringToUInt32(s, &end);
+ if (*end != 0)
+ IncorrectCommand();
+ return v;
}
-static void ParseUInt32(const CParser &parser, int index, UInt32 &res)
+static void ParseUInt32(const CParser &parser, unsigned index, UInt32 &res)
{
if (parser[index].ThereIs)
- if (!GetNumber(parser[index].PostStrings[0], res))
- IncorrectCommand();
+ res = GetNumber(parser[index].PostStrings[0]);
}
-#define NT_CHECK_FAIL_ACTION PrintMessage("Unsupported Windows version"); return 1;
-int main2(int numArgs, const char *args[])
+static int Error_HRESULT(const char *s, HRESULT res)
{
- NT_CHECK
+ if (res == E_ABORT)
+ {
+ Print("\n\nBreak signaled\n");
+ return 255;
+ }
+
+ PrintError(s);
+
+ if (res == E_OUTOFMEMORY)
+ {
+ PrintErr_LF(kCantAllocate);
+ return 8;
+ }
+ if (res == E_INVALIDARG)
+ {
+ PrintErr_LF("Ununsupported parameter");
+ }
+ else
+ {
+ char temp[32];
+ ConvertUInt32ToHex(res, temp);
+ PrintErr("Error code = 0x");
+ PrintErr_LF(temp);
+ }
+ return 1;
+}
- PrintMessage("\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n");
+#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1;
+
+static void AddProp(CObjectVector<CProperty> &props2, const char *name, const wchar_t *val)
+{
+ CProperty &prop = props2.AddNew();
+ prop.Name.SetFromAscii(name);
+ prop.Value = val;
+}
+
+static int main2(int numArgs, const char *args[])
+{
+ NT_CHECK
if (numArgs == 1)
{
@@ -171,19 +312,24 @@ int main2(int numArgs, const char *args[])
return 0;
}
- bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4);
+ /*
+ bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 8);
if (unsupportedTypes)
- {
- PrintMessage("Unsupported base types. Edit Common/Types.h and recompile");
- return 1;
- }
+ throw "Unsupported base types. Edit Common/Types.h and recompile";
+ */
UStringVector commandStrings;
- WriteArgumentsToStringList(numArgs, args, commandStrings);
- CParser parser(kNumSwitches);
+ for (int i = 1; i < numArgs; i++)
+ commandStrings.Add(MultiByteToUnicodeString(args[i]));
+
+ CParser parser(ARRAY_SIZE(kSwitchForms));
try
{
- parser.ParseStrings(kSwitchForms, commandStrings);
+ if (!parser.ParseStrings(kSwitchForms, commandStrings))
+ {
+ PrintError2(parser.ErrorMessage, parser.ErrorLine);
+ return 1;
+ }
}
catch(...)
{
@@ -195,40 +341,41 @@ int main2(int numArgs, const char *args[])
PrintHelp();
return 0;
}
- const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
- int paramIndex = 0;
- if (paramIndex >= nonSwitchStrings.Size())
+ bool stdInMode = parser[NKey::kStdIn].ThereIs;
+ bool stdOutMode = parser[NKey::kStdOut].ThereIs;
+
+ if (!stdOutMode)
+ PrintTitle();
+
+ const UStringVector &params = parser.NonSwitchStrings;
+
+ unsigned paramIndex = 0;
+ if (paramIndex >= params.Size())
IncorrectCommand();
- const UString &command = nonSwitchStrings[paramIndex++];
+ const UString &command = params[paramIndex++];
- CObjectVector<CProperty> props;
+ CObjectVector<CProperty> props2;
bool dictDefined = false;
UInt32 dict = (UInt32)(Int32)-1;
+
if (parser[NKey::kDict].ThereIs)
{
- UInt32 dicLog;
+ UInt32 dictLog;
const UString &s = parser[NKey::kDict].PostStrings[0];
- if (!GetNumber(s, dicLog))
- IncorrectCommand();
- dict = 1 << dicLog;
+ dictLog = GetNumber(s);
+ dict = 1 << dictLog;
dictDefined = true;
- CProperty prop;
- prop.Name = L"d";
- prop.Value = s;
- props.Add(prop);
+ AddProp(props2, "d", s);
}
+
if (parser[NKey::kLevel].ThereIs)
{
- UInt32 level = 5;
const UString &s = parser[NKey::kLevel].PostStrings[0];
- if (!GetNumber(s, level))
- IncorrectCommand();
- CProperty prop;
- prop.Name = L"x";
- prop.Value = s;
- props.Add(prop);
+ /* UInt32 level = */ GetNumber(s);
+ AddProp(props2, "x", s);
}
+
UString mf = L"BT4";
if (parser[NKey::kMatchFinder].ThereIs)
mf = parser[NKey::kMatchFinder].PostStrings[0];
@@ -236,70 +383,64 @@ int main2(int numArgs, const char *args[])
UInt32 numThreads = (UInt32)(Int32)-1;
#ifndef _7ZIP_ST
+
if (parser[NKey::kMultiThread].ThereIs)
{
- UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
const UString &s = parser[NKey::kMultiThread].PostStrings[0];
if (s.IsEmpty())
- numThreads = numCPUs;
+ numThreads = NWindows::NSystem::GetNumberOfProcessors();
else
- if (!GetNumber(s, numThreads))
- IncorrectCommand();
- CProperty prop;
- prop.Name = L"mt";
- prop.Value = s;
- props.Add(prop);
+ numThreads = GetNumber(s);
+ AddProp(props2, "mt", s);
}
+
#endif
+
if (parser[NKey::kMethod].ThereIs)
{
- UString s = parser[NKey::kMethod].PostStrings[0];
+ const UString &s = parser[NKey::kMethod].PostStrings[0];
if (s.IsEmpty() || s[0] != '=')
IncorrectCommand();
- CProperty prop;
- prop.Name = L"m";
- prop.Value = s.Mid(1);
- props.Add(prop);
+ AddProp(props2, "m", s.Ptr(1));
}
- if (command.CompareNoCase(L"b") == 0)
+ if (StringsAreEqualNoCase_Ascii(command, "b"))
{
- const UInt32 kNumDefaultItereations = 1;
- UInt32 numIterations = kNumDefaultItereations;
- {
- if (paramIndex < nonSwitchStrings.Size())
- if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
- numIterations = kNumDefaultItereations;
- }
- HRESULT res = BenchCon(props, numIterations, stderr);
- if (res != S_OK)
- {
- if (res != E_ABORT)
- {
- PrintMessage("Benchmark Error");
- return 1;
- }
- }
- return 0;
+ UInt32 numIterations = 1;
+ if (paramIndex < params.Size())
+ numIterations = GetNumber(params[paramIndex++]);
+ if (params.Size() != paramIndex)
+ IncorrectCommand();
+
+ HRESULT res = BenchCon(props2, numIterations, stdout);
+
+ if (res == S_OK)
+ return 0;
+ return Error_HRESULT("Benchmark error", res);
+ }
+
+ {
+ UInt32 needParams = 3;
+ if (stdInMode) needParams--;
+ if (stdOutMode) needParams--;
+ if (needParams != params.Size())
+ IncorrectCommand();
}
if (numThreads == (UInt32)(Int32)-1)
numThreads = 1;
bool encodeMode = false;
- if (command.CompareNoCase(L"e") == 0)
+
+ if (StringsAreEqualNoCase_Ascii(command, "e"))
encodeMode = true;
- else if (command.CompareNoCase(L"d") == 0)
- encodeMode = false;
- else
+ else if (!StringsAreEqualNoCase_Ascii(command, "d"))
IncorrectCommand();
- bool stdInMode = parser[NKey::kStdIn].ThereIs;
- bool stdOutMode = parser[NKey::kStdOut].ThereIs;
-
CMyComPtr<ISequentialInStream> inStream;
- CInFileStream *inStreamSpec = 0;
+ CInFileStream *inStreamSpec = NULL;
+
if (stdInMode)
{
inStream = new CStdInFileStream;
@@ -307,21 +448,19 @@ int main2(int numArgs, const char *args[])
}
else
{
- if (paramIndex >= nonSwitchStrings.Size())
- IncorrectCommand();
- const UString &inputName = nonSwitchStrings[paramIndex++];
+ const UString &inputName = params[paramIndex++];
inStreamSpec = new CInFileStream;
inStream = inStreamSpec;
if (!inStreamSpec->Open(us2fs(inputName)))
{
- fprintf(stderr, "\nError: can not open input file %s\n",
- (const char *)GetOemString(inputName));
+ PrintError2("can not open input file", inputName);
return 1;
}
}
CMyComPtr<ISequentialOutStream> outStream;
COutFileStream *outStreamSpec = NULL;
+
if (stdOutMode)
{
outStream = new CStdOutFileStream;
@@ -329,99 +468,148 @@ int main2(int numArgs, const char *args[])
}
else
{
- if (paramIndex >= nonSwitchStrings.Size())
- IncorrectCommand();
- const UString &outputName = nonSwitchStrings[paramIndex++];
+ const UString &outputName = params[paramIndex++];
outStreamSpec = new COutFileStream;
outStream = outStreamSpec;
if (!outStreamSpec->Create(us2fs(outputName), true))
{
- fprintf(stderr, "\nError: can not open output file %s\n",
- (const char *)GetOemString(outputName));
+ PrintError2("can not open output file", outputName);
return 1;
}
}
+ bool fileSizeDefined = false;
+ UInt64 fileSize = 0;
+
+ if (inStreamSpec)
+ {
+ if (!inStreamSpec->File.GetLength(fileSize))
+ throw "Can not get file length";
+ fileSizeDefined = true;
+ if (!stdOutMode)
+ Print_Size("Input size: ", fileSize);
+ }
+
+ if (encodeMode && !dictDefined)
+ {
+ dict = 1 << kDictSizeLog;
+ if (fileSizeDefined)
+ {
+ unsigned i;
+ for (i = 16; i < kDictSizeLog; i++)
+ if ((UInt32)((UInt32)1 << i) >= fileSize)
+ break;
+ dict = (UInt32)1 << i;
+ }
+ }
+
if (parser[NKey::kFilter86].ThereIs)
{
- // -f86 switch is for x86 filtered mode: BCJ + LZMA.
+ /* -f86 switch is for x86 filtered mode: BCJ + LZMA.
+ It uses modified header format.
+ It's not recommended to use -f86 mode now.
+ You can use xz format instead, if you want to use filters */
+
if (parser[NKey::kEOS].ThereIs || stdInMode)
throw "Can not use stdin in this mode";
- UInt64 fileSize;
- inStreamSpec->File.GetLength(fileSize);
- if (fileSize > 0xF0000000)
- throw "File is too big";
+
size_t inSize = (size_t)fileSize;
- Byte *inBuffer = 0;
+
+ if (inSize != fileSize)
+ throw "File is too big";
+
+ Byte *inBuffer = NULL;
+
if (inSize != 0)
{
inBuffer = (Byte *)MyAlloc((size_t)inSize);
- if (inBuffer == 0)
+ if (!inBuffer)
throw kCantAllocate;
}
if (ReadStream_FAIL(inStream, inBuffer, inSize) != S_OK)
throw "Can not read";
- Byte *outBuffer = 0;
+ Byte *outBuffer = NULL;
size_t outSize;
+
if (encodeMode)
{
// we allocate 105% of original size for output buffer
- outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
+ UInt64 outSize64 = fileSize / 20 * 21 + (1 << 16);
+
+ outSize = (size_t)outSize64;
+
+ if (outSize != outSize64)
+ throw "File is too big";
+
if (outSize != 0)
{
outBuffer = (Byte *)MyAlloc((size_t)outSize);
- if (outBuffer == 0)
+ if (!outBuffer)
throw kCantAllocate;
}
- if (!dictDefined)
- dict = 1 << 23;
+
int res = Lzma86_Encode(outBuffer, &outSize, inBuffer, inSize,
5, dict, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO);
+
if (res != 0)
{
- fprintf(stderr, "\nEncoder error = %d\n", (int)res);
+ PrintError_int("Encode error", (int)res);
return 1;
}
}
else
{
UInt64 outSize64;
+
if (Lzma86_GetUnpackSize(inBuffer, inSize, &outSize64) != 0)
throw "data error";
+
outSize = (size_t)outSize64;
if (outSize != outSize64)
- throw "too big";
+ throw "Unpack size is too big";
if (outSize != 0)
{
outBuffer = (Byte *)MyAlloc(outSize);
- if (outBuffer == 0)
+ if (!outBuffer)
throw kCantAllocate;
}
+
int res = Lzma86_Decode(outBuffer, &outSize, inBuffer, &inSize);
+
if (inSize != (size_t)fileSize)
throw "incorrect processed size";
if (res != 0)
- throw "LzmaDecoder error";
+ {
+ PrintError_int("Decode error", (int)res);
+ return 1;
+ }
}
+
if (WriteStream(outStream, outBuffer, outSize) != S_OK)
throw kWriteError;
+
MyFree(outBuffer);
MyFree(inBuffer);
- return 0;
}
+ else
+ {
+ CProgressPrint *progressSpec = NULL;
+ CMyComPtr<ICompressProgressInfo> progress;
+
+ if (!stdOutMode)
+ {
+ progressSpec = new CProgressPrint;
+ progress = progressSpec;
+ }
- UInt64 fileSize;
if (encodeMode)
{
NCompress::NLzma::CEncoder *encoderSpec = new NCompress::NLzma::CEncoder;
CMyComPtr<ICompressCoder> encoder = encoderSpec;
- if (!dictDefined)
- dict = 1 << 23;
-
UInt32 pb = 2;
UInt32 lc = 3; // = 0; for 32-bit data
UInt32 lp = 0; // = 2; for 32-bit data
@@ -440,8 +628,7 @@ int main2(int numArgs, const char *args[])
mcDefined = parser[NKey::kMc].ThereIs;
if (mcDefined)
- if (!GetNumber(parser[NKey::kMc].PostStrings[0], mc))
- IncorrectCommand();
+ mc = GetNumber(parser[NKey::kMc].PostStrings[0]);
const PROPID propIDs[] =
{
@@ -456,7 +643,8 @@ int main2(int numArgs, const char *args[])
NCoderPropID::kNumThreads,
NCoderPropID::kMatchFinderCycles,
};
- const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]);
+
+ const unsigned kNumPropsMax = ARRAY_SIZE(propIDs);
PROPVARIANT props[kNumPropsMax];
for (int p = 0; p < 6; p++)
@@ -482,89 +670,110 @@ int main2(int numArgs, const char *args[])
props[9].vt = VT_UI4;
props[9].ulVal = (UInt32)mc;
- int numProps = kNumPropsMax;
+ unsigned numProps = kNumPropsMax;
if (!mcDefined)
numProps--;
- if (encoderSpec->SetCoderProperties(propIDs, props, numProps) != S_OK)
- IncorrectCommand();
- encoderSpec->WriteCoderProperties(outStream);
+ HRESULT res = encoderSpec->SetCoderProperties(propIDs, props, numProps);
+ if (res != S_OK)
+ return Error_HRESULT("incorrect encoder properties", res);
- if (eos || stdInMode)
- fileSize = (UInt64)(Int64)-1;
- else
- inStreamSpec->File.GetLength(fileSize);
+ if (encoderSpec->WriteCoderProperties(outStream) != S_OK)
+ throw kWriteError;
- for (int i = 0; i < 8; i++)
- {
- Byte b = Byte(fileSize >> (8 * i));
- if (outStream->Write(&b, 1, 0) != S_OK)
- {
- PrintMessage(kWriteError);
- return 1;
- }
- }
- HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
- if (result == E_OUTOFMEMORY)
+ bool fileSizeWasUsed = true;
+ if (eos || stdInMode)
{
- PrintMessage("\nError: Can not allocate memory\n");
- return 1;
+ fileSize = (UInt64)(Int64)-1;
+ fileSizeWasUsed = false;
}
- else if (result != S_OK)
+
{
- fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result);
- return 1;
+ Byte temp[8];
+ for (int i = 0; i < 8; i++)
+ temp[i]= (Byte)(fileSize >> (8 * i));
+ if (WriteStream(outStream, temp, 8) != S_OK)
+ throw kWriteError;
}
+
+ res = encoder->Code(inStream, outStream, NULL, NULL, progress);
+ if (progressSpec)
+ progressSpec->ClosePrint();
+
+ if (res != S_OK)
+ return Error_HRESULT("Encoding error", res);
+
+ UInt64 processedSize = encoderSpec->GetInputProcessedSize();
+
+ if (fileSizeWasUsed && processedSize != fileSize)
+ throw "Incorrect size of processed data";
}
else
{
NCompress::NLzma::CDecoder *decoderSpec = new NCompress::NLzma::CDecoder;
CMyComPtr<ICompressCoder> decoder = decoderSpec;
+
decoderSpec->FinishStream = true;
- const UInt32 kPropertiesSize = 5;
+
+ const unsigned kPropertiesSize = 5;
Byte header[kPropertiesSize + 8];
+
if (ReadStream_FALSE(inStream, header, kPropertiesSize + 8) != S_OK)
- {
- PrintMessage(kReadError);
- return 1;
- }
+ throw kReadError;
+
if (decoderSpec->SetDecoderProperties2(header, kPropertiesSize) != S_OK)
- {
- PrintMessage("SetDecoderProperties error");
- return 1;
- }
- fileSize = 0;
+ throw "SetDecoderProperties error";
+
+ UInt64 unpackSize = 0;
for (int i = 0; i < 8; i++)
- fileSize |= ((UInt64)header[kPropertiesSize + i]) << (8 * i);
+ unpackSize |= ((UInt64)header[kPropertiesSize + i]) << (8 * i);
+
+ bool unpackSizeDefined = (unpackSize != (UInt64)(Int64)-1);
+
+ HRESULT res = decoder->Code(inStream, outStream, NULL, unpackSizeDefined ? &unpackSize : NULL, progress);
+ if (progressSpec)
+ progressSpec->ClosePrint();
- if (decoder->Code(inStream, outStream, 0, (fileSize == (UInt64)(Int64)-1) ? 0 : &fileSize, 0) != S_OK)
+ if (res != S_OK)
{
- PrintMessage("Decoder error");
- return 1;
+ if (res == S_FALSE)
+ {
+ PrintError("Decoding error");
+ return 1;
+ }
+ return Error_HRESULT("Decoding error", res);
}
+
+ if (unpackSizeDefined && unpackSize != decoderSpec->GetOutputProcessedSize())
+ throw "incorrect uncompressed size in header";
}
- if (outStreamSpec != NULL)
+ }
+
+ if (!stdOutMode)
+ Print_Size("Output size: ", outStreamSpec->ProcessedSize);
+
+ if (outStreamSpec)
{
if (outStreamSpec->Close() != S_OK)
- {
- PrintMessage("File closing error");
- return 1;
- }
+ throw "File closing error";
}
+
return 0;
}
int MY_CDECL main(int numArgs, const char *args[])
{
+ NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter;
+
try { return main2(numArgs, args); }
catch (const char *s)
{
- fprintf(stderr, "\nError: %s\n", s);
+ PrintError(s);
return 1;
}
catch(...)
{
- PrintMessage("\nError\n");
+ PrintError("Unknown Error");
return 1;
}
}
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp
index 6111aa7e52c..f8267a11f24 100644
--- a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp
+++ b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp
@@ -42,7 +42,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 /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -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" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /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
@@ -180,6 +180,10 @@ SOURCE=..\..\..\Common\CRC.cpp
# End Source File
# Begin Source File
+SOURCE=..\..\..\Common\CrcReg.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Common\Defs.h
# End Source File
# Begin Source File
@@ -362,6 +366,10 @@ SOURCE=..\..\..\..\C\7zCrcOpt.c
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\7zTypes.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\Alloc.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -460,10 +468,6 @@ SOURCE=..\..\..\..\C\Threads.c
SOURCE=..\..\..\..\C\Threads.h
# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\C\Types.h
-# End Source File
# End Group
# Begin Source File
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/StdAfx.h
index e7fb6986d2a..2854ff3e935 100644
--- a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/StdAfx.h
@@ -3,6 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../../Common/MyWindows.h"
+#include "../../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile
index 35d031af9e3..54919f73374 100644
--- a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile
+++ b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile
@@ -2,7 +2,7 @@ PROG = lzma.exe
MY_CONSOLE = 1
CFLAGS = $(CFLAGS)
-LZMA_OBJS = \
+CURRENT_OBJS = \
$O\LzmaAlone.obj \
COMPRESS_OBJS = \
@@ -13,8 +13,10 @@ COMPRESS_OBJS = \
COMMON_OBJS = \
$O\CommandLineParser.obj \
$O\CRC.obj \
+ $O\CrcReg.obj \
$O\IntToString.obj \
$O\MyString.obj \
+ $O\NewHandler.obj \
$O\StringConvert.obj \
$O\StringToInt.obj \
$O\MyVector.obj
@@ -54,36 +56,4 @@ C_OBJS = \
!include "../../Crc.mak"
-OBJS = \
- $O\StdAfx.obj \
- $(LZMA_OBJS) \
- $(COMPRESS_OBJS) \
- $(COMMON_OBJS) \
- $(WIN_OBJS) \
- $(7ZIP_COMMON_OBJS) \
- $(UI_COMMON_OBJS) \
- $(CONSOLE_OBJS) \
- $(C_OBJS) \
- $(ASM_OBJS) \
-
-!include "../../../Build.mak"
-
-
-$(LZMA_OBJS): $(*B).cpp
- $(COMPL)
-$(COMPRESS_OBJS): ../../Compress/$(*B).cpp
- $(COMPL_O2)
-$(COMMON_OBJS): ../../../Common/$(*B).cpp
- $(COMPL)
-$(WIN_OBJS): ../../../Windows/$(*B).cpp
- $(COMPL)
-$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
- $(COMPL)
-$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
- $(COMPL)
-$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp
- $(COMPL)
-$(C_OBJS): ../../../../C/$(*B).c
- $(COMPL_O2)
-
-!include "../../Asm.mak"
+!include "../../7zip.mak"
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile.gcc b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile.gcc
index 0f9f498cb02..97fe450841f 100644
--- a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile.gcc
+++ b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile.gcc
@@ -1,24 +1,41 @@
PROG = lzma
-CXX = g++ -O2 -Wall
-CXX_C = gcc -O2 -Wall
-LIB = -lm
-RM = rm -f
-CFLAGS = -c -D_7ZIP_ST
+CXX = g++ -O2
+# -Wall -Werror -Wno-delete-non-virtual-dtor
+CXX_C = gcc -O2 -Wall -Werror
ifdef SystemDrive
IS_MINGW = 1
endif
ifdef IS_MINGW
+
+RM = del
+CFLAGS = -c
+LIB2 = -loleaut32 -luuid
+LDFLAGS = -s
+
FILE_IO =FileIO
FILE_IO_2 =Windows/$(FILE_IO)
-LIB2 = -luuid
+
+MT_FILES = \
+ LzFindMt.o \
+ Threads.o \
+
else
+
+RM = rm -f
+CFLAGS = -c -D_7ZIP_ST
+
FILE_IO =C_FileIO
FILE_IO_2 =Common/$(FILE_IO)
+
+
endif
+
OBJS = \
+ $(MT_FILES) \
+ $(FILE_IO).o \
LzmaAlone.o \
Bench.o \
BenchCon.o \
@@ -32,9 +49,9 @@ OBJS = \
FilterCoder.o \
MethodProps.o \
StreamUtils.o \
- $(FILE_IO).o \
CommandLineParser.o \
CRC.o \
+ CrcReg.o \
IntToString.o \
MyString.o \
MyVector.o \
@@ -42,6 +59,7 @@ OBJS = \
StringConvert.o \
StringToInt.o \
PropVariant.o \
+ System.o \
7zCrc.o \
7zCrcOpt.o \
Alloc.o \
@@ -57,7 +75,7 @@ OBJS = \
all: $(PROG)
$(PROG): $(OBJS)
- $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(LIB2)
+ $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB2)
LzmaAlone.o: LzmaAlone.cpp
$(CXX) $(CFLAGS) LzmaAlone.cpp
@@ -108,6 +126,9 @@ CommandLineParser.o: ../../../Common/CommandLineParser.cpp
CRC.o: ../../../Common/CRC.cpp
$(CXX) $(CFLAGS) ../../../Common/CRC.cpp
+CrcReg.o: ../../../Common/CrcReg.cpp
+ $(CXX) $(CFLAGS) ../../../Common/CrcReg.cpp
+
IntToString.o: ../../../Common/IntToString.cpp
$(CXX) $(CFLAGS) ../../../Common/IntToString.cpp
@@ -129,6 +150,9 @@ StringToInt.o: ../../../Common/StringToInt.cpp
PropVariant.o: ../../../Windows/PropVariant.cpp
$(CXX) $(CFLAGS) ../../../Windows/PropVariant.cpp
+System.o: ../../../Windows/System.cpp
+ $(CXX) $(CFLAGS) ../../../Windows/System.cpp
+
7zCrc.o: ../../../../C/7zCrc.c
$(CXX_C) $(CFLAGS) ../../../../C/7zCrc.c
@@ -147,6 +171,14 @@ CpuArch.o: ../../../../C/CpuArch.c
LzFind.o: ../../../../C/LzFind.c
$(CXX_C) $(CFLAGS) ../../../../C/LzFind.c
+ifdef MT_FILES
+LzFindMt.o: ../../../../C/LzFindMt.c
+ $(CXX_C) $(CFLAGS) ../../../../C/LzFindMt.c
+
+Threads.o: ../../../../C/Threads.c
+ $(CXX_C) $(CFLAGS) ../../../../C/Threads.c
+endif
+
LzmaDec.o: ../../../../C/LzmaDec.c
$(CXX_C) $(CFLAGS) ../../../../C/LzmaDec.c
@@ -161,4 +193,3 @@ Lzma86Enc.o: ../../../../C/Lzma86Enc.c
clean:
-$(RM) $(PROG) $(OBJS)
-
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/resource.rc b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/resource.rc
new file mode 100644
index 00000000000..43b50738ef2
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_APP("LZMA", "lzma")
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/LzmaSpec/LzmaSpec.cpp b/3rdparty/lzma/CPP/7zip/Bundles/LzmaSpec/LzmaSpec.cpp
new file mode 100644
index 00000000000..8e0f9b99b4c
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/LzmaSpec/LzmaSpec.cpp
@@ -0,0 +1,715 @@
+/* LzmaSpec.cpp -- LZMA Reference Decoder
+2015-06-14 : Igor Pavlov : Public domain */
+
+// This code implements LZMA file decoding according to LZMA specification.
+// This code is not optimized for speed.
+
+#include <stdio.h>
+
+#ifdef _MSC_VER
+ #pragma warning(disable : 4710) // function not inlined
+ #pragma warning(disable : 4996) // This function or variable may be unsafe
+#endif
+
+typedef unsigned char Byte;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+ typedef unsigned long UInt32;
+#else
+ typedef unsigned int UInt32;
+#endif
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+ typedef unsigned __int64 UInt64;
+#else
+ typedef unsigned long long int UInt64;
+#endif
+
+
+struct CInputStream
+{
+ FILE *File;
+ UInt64 Processed;
+
+ void Init() { Processed = 0; }
+
+ Byte ReadByte()
+ {
+ int c = getc(File);
+ if (c < 0)
+ throw "Unexpected end of file";
+ Processed++;
+ return (Byte)c;
+ }
+};
+
+
+struct COutStream
+{
+ FILE *File;
+ UInt64 Processed;
+
+ void Init() { Processed = 0; }
+
+ void WriteByte(Byte b)
+ {
+ if (putc(b, File) == EOF)
+ throw "File writing error";
+ Processed++;
+ }
+};
+
+
+class COutWindow
+{
+ Byte *Buf;
+ UInt32 Pos;
+ UInt32 Size;
+ bool IsFull;
+
+public:
+ unsigned TotalPos;
+ COutStream OutStream;
+
+ COutWindow(): Buf(NULL) {}
+ ~COutWindow() { delete []Buf; }
+
+ void Create(UInt32 dictSize)
+ {
+ Buf = new Byte[dictSize];
+ Pos = 0;
+ Size = dictSize;
+ IsFull = false;
+ TotalPos = 0;
+ }
+
+ void PutByte(Byte b)
+ {
+ TotalPos++;
+ Buf[Pos++] = b;
+ if (Pos == Size)
+ {
+ Pos = 0;
+ IsFull = true;
+ }
+ OutStream.WriteByte(b);
+ }
+
+ Byte GetByte(UInt32 dist) const
+ {
+ return Buf[dist <= Pos ? Pos - dist : Size - dist + Pos];
+ }
+
+ void CopyMatch(UInt32 dist, unsigned len)
+ {
+ for (; len > 0; len--)
+ PutByte(GetByte(dist));
+ }
+
+ bool CheckDistance(UInt32 dist) const
+ {
+ return dist <= Pos || IsFull;
+ }
+
+ bool IsEmpty() const
+ {
+ return Pos == 0 && !IsFull;
+ }
+};
+
+
+#define kNumBitModelTotalBits 11
+#define kNumMoveBits 5
+
+typedef UInt16 CProb;
+
+#define PROB_INIT_VAL ((1 << kNumBitModelTotalBits) / 2)
+
+#define INIT_PROBS(p) \
+ { for (unsigned i = 0; i < sizeof(p) / sizeof(p[0]); i++) p[i] = PROB_INIT_VAL; }
+
+class CRangeDecoder
+{
+ UInt32 Range;
+ UInt32 Code;
+
+ void Normalize();
+
+public:
+
+ CInputStream *InStream;
+ bool Corrupted;
+
+ bool Init();
+ bool IsFinishedOK() const { return Code == 0; }
+
+ UInt32 DecodeDirectBits(unsigned numBits);
+ unsigned DecodeBit(CProb *prob);
+};
+
+bool CRangeDecoder::Init()
+{
+ Corrupted = false;
+ Range = 0xFFFFFFFF;
+ Code = 0;
+
+ Byte b = InStream->ReadByte();
+
+ for (int i = 0; i < 4; i++)
+ Code = (Code << 8) | InStream->ReadByte();
+
+ if (b != 0 || Code == Range)
+ Corrupted = true;
+ return b == 0;
+}
+
+#define kTopValue ((UInt32)1 << 24)
+
+void CRangeDecoder::Normalize()
+{
+ if (Range < kTopValue)
+ {
+ Range <<= 8;
+ Code = (Code << 8) | InStream->ReadByte();
+ }
+}
+
+UInt32 CRangeDecoder::DecodeDirectBits(unsigned numBits)
+{
+ UInt32 res = 0;
+ do
+ {
+ Range >>= 1;
+ Code -= Range;
+ UInt32 t = 0 - ((UInt32)Code >> 31);
+ Code += Range & t;
+
+ if (Code == Range)
+ Corrupted = true;
+
+ Normalize();
+ res <<= 1;
+ res += t + 1;
+ }
+ while (--numBits);
+ return res;
+}
+
+unsigned CRangeDecoder::DecodeBit(CProb *prob)
+{
+ unsigned v = *prob;
+ UInt32 bound = (Range >> kNumBitModelTotalBits) * v;
+ unsigned symbol;
+ if (Code < bound)
+ {
+ v += ((1 << kNumBitModelTotalBits) - v) >> kNumMoveBits;
+ Range = bound;
+ symbol = 0;
+ }
+ else
+ {
+ v -= v >> kNumMoveBits;
+ Code -= bound;
+ Range -= bound;
+ symbol = 1;
+ }
+ *prob = (CProb)v;
+ Normalize();
+ return symbol;
+}
+
+
+unsigned BitTreeReverseDecode(CProb *probs, unsigned numBits, CRangeDecoder *rc)
+{
+ unsigned m = 1;
+ unsigned symbol = 0;
+ for (unsigned i = 0; i < numBits; i++)
+ {
+ unsigned bit = rc->DecodeBit(&probs[m]);
+ m <<= 1;
+ m += bit;
+ symbol |= (bit << i);
+ }
+ return symbol;
+}
+
+template <unsigned NumBits>
+class CBitTreeDecoder
+{
+ CProb Probs[(unsigned)1 << NumBits];
+
+public:
+
+ void Init()
+ {
+ INIT_PROBS(Probs);
+ }
+
+ unsigned Decode(CRangeDecoder *rc)
+ {
+ unsigned m = 1;
+ for (unsigned i = 0; i < NumBits; i++)
+ m = (m << 1) + rc->DecodeBit(&Probs[m]);
+ return m - ((unsigned)1 << NumBits);
+ }
+
+ unsigned ReverseDecode(CRangeDecoder *rc)
+ {
+ return BitTreeReverseDecode(Probs, NumBits, rc);
+ }
+};
+
+#define kNumPosBitsMax 4
+
+#define kNumStates 12
+#define kNumLenToPosStates 4
+#define kNumAlignBits 4
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+#define kMatchMinLen 2
+
+class CLenDecoder
+{
+ CProb Choice;
+ CProb Choice2;
+ CBitTreeDecoder<3> LowCoder[1 << kNumPosBitsMax];
+ CBitTreeDecoder<3> MidCoder[1 << kNumPosBitsMax];
+ CBitTreeDecoder<8> HighCoder;
+
+public:
+
+ void Init()
+ {
+ Choice = PROB_INIT_VAL;
+ Choice2 = PROB_INIT_VAL;
+ HighCoder.Init();
+ for (unsigned i = 0; i < (1 << kNumPosBitsMax); i++)
+ {
+ LowCoder[i].Init();
+ MidCoder[i].Init();
+ }
+ }
+
+ unsigned Decode(CRangeDecoder *rc, unsigned posState)
+ {
+ if (rc->DecodeBit(&Choice) == 0)
+ return LowCoder[posState].Decode(rc);
+ if (rc->DecodeBit(&Choice2) == 0)
+ return 8 + MidCoder[posState].Decode(rc);
+ return 16 + HighCoder.Decode(rc);
+ }
+};
+
+unsigned UpdateState_Literal(unsigned state)
+{
+ if (state < 4) return 0;
+ else if (state < 10) return state - 3;
+ else return state - 6;
+}
+unsigned UpdateState_Match (unsigned state) { return state < 7 ? 7 : 10; }
+unsigned UpdateState_Rep (unsigned state) { return state < 7 ? 8 : 11; }
+unsigned UpdateState_ShortRep(unsigned state) { return state < 7 ? 9 : 11; }
+
+#define LZMA_DIC_MIN (1 << 12)
+
+class CLzmaDecoder
+{
+public:
+ CRangeDecoder RangeDec;
+ COutWindow OutWindow;
+
+ bool markerIsMandatory;
+ unsigned lc, pb, lp;
+ UInt32 dictSize;
+ UInt32 dictSizeInProperties;
+
+ void DecodeProperties(const Byte *properties)
+ {
+ unsigned d = properties[0];
+ if (d >= (9 * 5 * 5))
+ throw "Incorrect LZMA properties";
+ lc = d % 9;
+ d /= 9;
+ pb = d / 5;
+ lp = d % 5;
+ dictSizeInProperties = 0;
+ for (int i = 0; i < 4; i++)
+ dictSizeInProperties |= (UInt32)properties[i + 1] << (8 * i);
+ dictSize = dictSizeInProperties;
+ if (dictSize < LZMA_DIC_MIN)
+ dictSize = LZMA_DIC_MIN;
+ }
+
+ CLzmaDecoder(): LitProbs(NULL) {}
+ ~CLzmaDecoder() { delete []LitProbs; }
+
+ void Create()
+ {
+ OutWindow.Create(dictSize);
+ CreateLiterals();
+ }
+
+ int Decode(bool unpackSizeDefined, UInt64 unpackSize);
+
+private:
+
+ CProb *LitProbs;
+
+ void CreateLiterals()
+ {
+ LitProbs = new CProb[(UInt32)0x300 << (lc + lp)];
+ }
+
+ void InitLiterals()
+ {
+ UInt32 num = (UInt32)0x300 << (lc + lp);
+ for (UInt32 i = 0; i < num; i++)
+ LitProbs[i] = PROB_INIT_VAL;
+ }
+
+ void DecodeLiteral(unsigned state, UInt32 rep0)
+ {
+ unsigned prevByte = 0;
+ if (!OutWindow.IsEmpty())
+ prevByte = OutWindow.GetByte(1);
+
+ unsigned symbol = 1;
+ unsigned litState = ((OutWindow.TotalPos & ((1 << lp) - 1)) << lc) + (prevByte >> (8 - lc));
+ CProb *probs = &LitProbs[(UInt32)0x300 * litState];
+
+ if (state >= 7)
+ {
+ unsigned matchByte = OutWindow.GetByte(rep0 + 1);
+ do
+ {
+ unsigned matchBit = (matchByte >> 7) & 1;
+ matchByte <<= 1;
+ unsigned bit = RangeDec.DecodeBit(&probs[((1 + matchBit) << 8) + symbol]);
+ symbol = (symbol << 1) | bit;
+ if (matchBit != bit)
+ break;
+ }
+ while (symbol < 0x100);
+ }
+ while (symbol < 0x100)
+ symbol = (symbol << 1) | RangeDec.DecodeBit(&probs[symbol]);
+ OutWindow.PutByte((Byte)(symbol - 0x100));
+ }
+
+ CBitTreeDecoder<6> PosSlotDecoder[kNumLenToPosStates];
+ CBitTreeDecoder<kNumAlignBits> AlignDecoder;
+ CProb PosDecoders[1 + kNumFullDistances - kEndPosModelIndex];
+
+ void InitDist()
+ {
+ for (unsigned i = 0; i < kNumLenToPosStates; i++)
+ PosSlotDecoder[i].Init();
+ AlignDecoder.Init();
+ INIT_PROBS(PosDecoders);
+ }
+
+ unsigned DecodeDistance(unsigned len)
+ {
+ unsigned lenState = len;
+ if (lenState > kNumLenToPosStates - 1)
+ lenState = kNumLenToPosStates - 1;
+
+ unsigned posSlot = PosSlotDecoder[lenState].Decode(&RangeDec);
+ if (posSlot < 4)
+ return posSlot;
+
+ unsigned numDirectBits = (unsigned)((posSlot >> 1) - 1);
+ UInt32 dist = ((2 | (posSlot & 1)) << numDirectBits);
+ if (posSlot < kEndPosModelIndex)
+ dist += BitTreeReverseDecode(PosDecoders + dist - posSlot, numDirectBits, &RangeDec);
+ else
+ {
+ dist += RangeDec.DecodeDirectBits(numDirectBits - kNumAlignBits) << kNumAlignBits;
+ dist += AlignDecoder.ReverseDecode(&RangeDec);
+ }
+ return dist;
+ }
+
+ CProb IsMatch[kNumStates << kNumPosBitsMax];
+ CProb IsRep[kNumStates];
+ CProb IsRepG0[kNumStates];
+ CProb IsRepG1[kNumStates];
+ CProb IsRepG2[kNumStates];
+ CProb IsRep0Long[kNumStates << kNumPosBitsMax];
+
+ CLenDecoder LenDecoder;
+ CLenDecoder RepLenDecoder;
+
+ void Init()
+ {
+ InitLiterals();
+ InitDist();
+
+ INIT_PROBS(IsMatch);
+ INIT_PROBS(IsRep);
+ INIT_PROBS(IsRepG0);
+ INIT_PROBS(IsRepG1);
+ INIT_PROBS(IsRepG2);
+ INIT_PROBS(IsRep0Long);
+
+ LenDecoder.Init();
+ RepLenDecoder.Init();
+ }
+};
+
+
+#define LZMA_RES_ERROR 0
+#define LZMA_RES_FINISHED_WITH_MARKER 1
+#define LZMA_RES_FINISHED_WITHOUT_MARKER 2
+
+int CLzmaDecoder::Decode(bool unpackSizeDefined, UInt64 unpackSize)
+{
+ if (!RangeDec.Init())
+ return LZMA_RES_ERROR;
+
+ Init();
+
+ UInt32 rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
+ unsigned state = 0;
+
+ for (;;)
+ {
+ if (unpackSizeDefined && unpackSize == 0 && !markerIsMandatory)
+ if (RangeDec.IsFinishedOK())
+ return LZMA_RES_FINISHED_WITHOUT_MARKER;
+
+ unsigned posState = OutWindow.TotalPos & ((1 << pb) - 1);
+
+ if (RangeDec.DecodeBit(&IsMatch[(state << kNumPosBitsMax) + posState]) == 0)
+ {
+ if (unpackSizeDefined && unpackSize == 0)
+ return LZMA_RES_ERROR;
+ DecodeLiteral(state, rep0);
+ state = UpdateState_Literal(state);
+ unpackSize--;
+ continue;
+ }
+
+ unsigned len;
+
+ if (RangeDec.DecodeBit(&IsRep[state]) != 0)
+ {
+ if (unpackSizeDefined && unpackSize == 0)
+ return LZMA_RES_ERROR;
+ if (OutWindow.IsEmpty())
+ return LZMA_RES_ERROR;
+ if (RangeDec.DecodeBit(&IsRepG0[state]) == 0)
+ {
+ if (RangeDec.DecodeBit(&IsRep0Long[(state << kNumPosBitsMax) + posState]) == 0)
+ {
+ state = UpdateState_ShortRep(state);
+ OutWindow.PutByte(OutWindow.GetByte(rep0 + 1));
+ unpackSize--;
+ continue;
+ }
+ }
+ else
+ {
+ UInt32 dist;
+ if (RangeDec.DecodeBit(&IsRepG1[state]) == 0)
+ dist = rep1;
+ else
+ {
+ if (RangeDec.DecodeBit(&IsRepG2[state]) == 0)
+ dist = rep2;
+ else
+ {
+ dist = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = dist;
+ }
+ len = RepLenDecoder.Decode(&RangeDec, posState);
+ state = UpdateState_Rep(state);
+ }
+ else
+ {
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ len = LenDecoder.Decode(&RangeDec, posState);
+ state = UpdateState_Match(state);
+ rep0 = DecodeDistance(len);
+ if (rep0 == 0xFFFFFFFF)
+ return RangeDec.IsFinishedOK() ?
+ LZMA_RES_FINISHED_WITH_MARKER :
+ LZMA_RES_ERROR;
+
+ if (unpackSizeDefined && unpackSize == 0)
+ return LZMA_RES_ERROR;
+ if (rep0 >= dictSize || !OutWindow.CheckDistance(rep0))
+ return LZMA_RES_ERROR;
+ }
+ len += kMatchMinLen;
+ bool isError = false;
+ if (unpackSizeDefined && unpackSize < len)
+ {
+ len = (unsigned)unpackSize;
+ isError = true;
+ }
+ OutWindow.CopyMatch(rep0 + 1, len);
+ unpackSize -= len;
+ if (isError)
+ return LZMA_RES_ERROR;
+ }
+}
+
+static void Print(const char *s)
+{
+ fputs(s, stdout);
+}
+
+static void PrintError(const char *s)
+{
+ fputs(s, stderr);
+}
+
+
+#define CONVERT_INT_TO_STR(charType, tempSize) \
+
+void ConvertUInt64ToString(UInt64 val, char *s)
+{
+ char temp[32];
+ unsigned i = 0;
+ while (val >= 10)
+ {
+ temp[i++] = (char)('0' + (unsigned)(val % 10));
+ val /= 10;
+ }
+ *s++ = (char)('0' + (unsigned)val);
+ while (i != 0)
+ {
+ i--;
+ *s++ = temp[i];
+ }
+ *s = 0;
+}
+
+void PrintUInt64(const char *title, UInt64 v)
+{
+ Print(title);
+ Print(" : ");
+ char s[32];
+ ConvertUInt64ToString(v, s);
+ Print(s);
+ Print(" bytes \n");
+}
+
+int main2(int numArgs, const char *args[])
+{
+ Print("\nLZMA Reference Decoder 15.00 : Igor Pavlov : Public domain : 2015-04-16\n");
+ if (numArgs == 1)
+ Print("\nUse: lzmaSpec a.lzma outFile");
+
+ if (numArgs != 3)
+ throw "you must specify two parameters";
+
+ CInputStream inStream;
+ inStream.File = fopen(args[1], "rb");
+ inStream.Init();
+ if (inStream.File == 0)
+ throw "Can't open input file";
+
+ CLzmaDecoder lzmaDecoder;
+ lzmaDecoder.OutWindow.OutStream.File = fopen(args[2], "wb+");
+ lzmaDecoder.OutWindow.OutStream.Init();
+ if (inStream.File == 0)
+ throw "Can't open output file";
+
+ Byte header[13];
+ int i;
+ for (i = 0; i < 13; i++)
+ header[i] = inStream.ReadByte();
+
+ lzmaDecoder.DecodeProperties(header);
+
+ printf("\nlc=%d, lp=%d, pb=%d", lzmaDecoder.lc, lzmaDecoder.lp, lzmaDecoder.pb);
+ printf("\nDictionary Size in properties = %u", lzmaDecoder.dictSizeInProperties);
+ printf("\nDictionary Size for decoding = %u", lzmaDecoder.dictSize);
+
+ UInt64 unpackSize = 0;
+ bool unpackSizeDefined = false;
+ for (i = 0; i < 8; i++)
+ {
+ Byte b = header[5 + i];
+ if (b != 0xFF)
+ unpackSizeDefined = true;
+ unpackSize |= (UInt64)b << (8 * i);
+ }
+
+ lzmaDecoder.markerIsMandatory = !unpackSizeDefined;
+
+ Print("\n");
+ if (unpackSizeDefined)
+ PrintUInt64("Uncompressed Size", unpackSize);
+ else
+ Print("End marker is expected\n");
+ lzmaDecoder.RangeDec.InStream = &inStream;
+
+ Print("\n");
+
+ lzmaDecoder.Create();
+
+ int res = lzmaDecoder.Decode(unpackSizeDefined, unpackSize);
+
+ PrintUInt64("Read ", inStream.Processed);
+ PrintUInt64("Written ", lzmaDecoder.OutWindow.OutStream.Processed);
+
+ if (res == LZMA_RES_ERROR)
+ throw "LZMA decoding error";
+ else if (res == LZMA_RES_FINISHED_WITHOUT_MARKER)
+ Print("Finished without end marker");
+ else if (res == LZMA_RES_FINISHED_WITH_MARKER)
+ {
+ if (unpackSizeDefined)
+ {
+ if (lzmaDecoder.OutWindow.OutStream.Processed != unpackSize)
+ throw "Finished with end marker before than specified size";
+ Print("Warning: ");
+ }
+ Print("Finished with end marker");
+ }
+ else
+ throw "Internal Error";
+
+ Print("\n");
+
+ if (lzmaDecoder.RangeDec.Corrupted)
+ {
+ Print("\nWarning: LZMA stream is corrupted\n");
+ }
+
+ return 0;
+}
+
+
+int
+ #ifdef _MSC_VER
+ __cdecl
+ #endif
+main(int numArgs, const char *args[])
+{
+ try { return main2(numArgs, args); }
+ catch (const char *s)
+ {
+ PrintError("\nError:\n");
+ PrintError(s);
+ PrintError("\n");
+ return 1;
+ }
+ catch(...)
+ {
+ PrintError("\nError\n");
+ return 1;
+ }
+}
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/7z.ico b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/7z.ico
new file mode 100644
index 00000000000..47ffb781e0b
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/7z.ico
Binary files differ
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SFXCon.dsp b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
new file mode 100644
index 00000000000..4f55d013fee
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
@@ -0,0 +1,869 @@
+# Microsoft Developer Studio Project File - Name="SFXCon" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=SFXCon - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "SFXCon.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "SFXCon.mak" CFG="SFXCon - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "SFXCon - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "SFXCon - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "SFXCon - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# 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 /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EXTRACT_ONLY" /D "_SFX" /D "NO_READ_FROM_CODER" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\Util\7zCon.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "SFXCon - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# 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 /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EXTRACT_ONLY" /D "_SFX" /D "NO_READ_FROM_CODER" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\Util\7zCon.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "SFXCon - Win32 Release"
+# Name "SFXCon - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\MultiStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# End Group
+# Begin Group "Console"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ConsoleClose.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ConsoleClose.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\List.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\List.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\MainAr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\PercentPrinter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\PercentPrinter.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UserInputUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UserInputUtils.h
+# End Source File
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\SplitHandler.cpp
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Bcj2Coder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Bcj2Register.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BcjCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BcjRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BranchMisc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BranchMisc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BranchRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\CopyRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\DeltaFilter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzma2Decoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzma2Register.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LzmaDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LzmaRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PpmdDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PpmdRegister.cpp
+# End Source File
+# End Group
+# Begin Group "Crypto"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAes.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAesRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\MyAes.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\MyAes.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ErrorMsg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ErrorMsg.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConv.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\CreateCoder.cpp
+# End Source File
+# Begin Source File
+
+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\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\PropId.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\RegisterArc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\RegisterCodec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\VirtThread.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\VirtThread.h
+# End Source File
+# End Group
+# Begin Group "UI"
+
+# PROP Default_Filter ""
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExitCode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\LoadCodecs.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\LoadCodecs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\PropIDUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\PropIDUtils.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "C"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrcOpt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Aes.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Aes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\AesOpt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bcj2.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bcj2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bra.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bra.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bra86.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\BraIA64.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\CpuArch.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Delta.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Delta.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Lzma2Dec.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Lzma2Dec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\LzmaDec.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\LzmaDec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Ppmd7.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Ppmd7.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Ppmd7Dec.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Sha256.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Sha256.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\7z.ico
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\IArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SfxCon.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SFXCon.dsw b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SFXCon.dsw
new file mode 100644
index 00000000000..27bf7e6d19b
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SFXCon.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "SFXCon"=.\SFXCon.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SfxCon.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SfxCon.cpp
new file mode 100644
index 00000000000..781f810cfd6
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SfxCon.cpp
@@ -0,0 +1,459 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/MyWindows.h"
+
+#include "../../../Common/MyInitGuid.h"
+
+#include "../../../Common/CommandLineParser.h"
+#include "../../../Common/MyException.h"
+
+#ifdef _WIN32
+#include "../../../Windows/DLL.h"
+#include "../../../Windows/FileDir.h"
+#endif
+#include "../../../Windows/FileName.h"
+
+#include "../../UI/Common/ExitCode.h"
+#include "../../UI/Common/Extract.h"
+
+#include "../../UI/Console/ExtractCallbackConsole.h"
+#include "../../UI/Console/List.h"
+#include "../../UI/Console/OpenCallbackConsole.h"
+
+#include "../../MyVersion.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDir;
+using namespace NCommandLineParser;
+
+#ifdef _WIN32
+HINSTANCE g_hInstance = 0;
+#endif
+int g_CodePage = -1;
+extern CStdOutStream *g_StdStream;
+
+static const char *kCopyrightString =
+"\n7-Zip SFX " MY_VERSION_COPYRIGHT_DATE "\n";
+
+static const int kNumSwitches = 6;
+
+namespace NKey {
+enum Enum
+{
+ kHelp1 = 0,
+ kHelp2,
+ kDisablePercents,
+ kYes,
+ kPassword,
+ kOutputDir
+};
+
+}
+
+namespace NRecursedType {
+enum EEnum
+{
+ kRecursed,
+ kWildcardOnlyRecursed,
+ kNonRecursed
+};
+}
+/*
+static const char kRecursedIDChar = 'R';
+static const wchar_t *kRecursedPostCharSet = L"0-";
+
+namespace NRecursedPostCharIndex {
+ enum EEnum
+ {
+ kWildcardRecursionOnly = 0,
+ kNoRecursion = 1
+ };
+}
+
+static const char kFileListID = '@';
+static const char kImmediateNameID = '!';
+
+static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
+static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
+*/
+static const CSwitchForm kSwitchForms[kNumSwitches] =
+{
+ { "?", NSwitchType::kSimple },
+ { "H", NSwitchType::kSimple },
+ { "BD", NSwitchType::kSimple },
+ { "Y", NSwitchType::kSimple },
+ { "P", NSwitchType::kString, false, 1 },
+ { "O", NSwitchType::kString, false, 1 },
+};
+
+static const int kNumCommandForms = 3;
+
+static const NRecursedType::EEnum kCommandRecursedDefault[kNumCommandForms] =
+{
+ NRecursedType::kRecursed
+};
+
+// static const bool kTestExtractRecursedDefault = true;
+// static const bool kAddRecursedDefault = false;
+
+static const wchar_t *kUniversalWildcard = L"*";
+static const int kCommandIndex = 0;
+
+static const char *kHelpString =
+ "\nUsage: 7zSFX [<command>] [<switches>...]\n"
+ "\n"
+ "<Commands>\n"
+ // " l: List contents of archive\n"
+ " t: Test integrity of archive\n"
+ " x: eXtract files with full pathname (default)\n"
+ "<Switches>\n"
+ // " -bd Disable percentage indicator\n"
+ " -o{Directory}: set Output directory\n"
+ " -p{Password}: set Password\n"
+ " -y: assume Yes on all queries\n";
+
+
+// ---------------------------
+// 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 CSysString kFileIsNotArchiveMessageBefore = "File \"";
+// static const CSysString kFileIsNotArchiveMessageAfter = "\" is not archive";
+
+// static const char *kProcessArchiveMessage = " archive: ";
+
+static const char *kCantFindSFX = " cannot find sfx";
+
+namespace NCommandType
+{
+ enum EEnum
+ {
+ kTest = 0,
+ kFullExtract,
+ kList
+ };
+}
+
+static const char *g_Commands = "txl";
+
+struct CArchiveCommand
+{
+ NCommandType::EEnum CommandType;
+
+ NRecursedType::EEnum DefaultRecursedType() const;
+};
+
+bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command)
+{
+ UString s = commandString;
+ s.MakeLower_Ascii();
+ if (s.Len() != 1)
+ return false;
+ if (s[0] >= 0x80)
+ return false;
+ int index = FindCharPosInString(g_Commands, (char)s[0]);
+ if (index < 0)
+ return false;
+ command.CommandType = (NCommandType::EEnum)index;
+ return true;
+}
+
+NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const
+{
+ return kCommandRecursedDefault[CommandType];
+}
+
+void PrintHelp(void)
+{
+ g_StdOut << kHelpString;
+}
+
+static void ShowMessageAndThrowException(const char *message, NExitCode::EEnum code)
+{
+ g_StdOut << message << endl;
+ throw code;
+}
+
+static void PrintHelpAndExit() // yyy
+{
+ PrintHelp();
+ ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError);
+}
+
+// ------------------------------------------------------------------
+// filenames functions
+
+static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,
+ const UString &name, bool include, NRecursedType::EEnum type)
+{
+ /*
+ if (!IsWildcardFilePathLegal(name))
+ return false;
+ */
+ bool isWildcard = DoesNameContainWildcard(name);
+ bool recursed = false;
+
+ switch (type)
+ {
+ case NRecursedType::kWildcardOnlyRecursed:
+ recursed = isWildcard;
+ break;
+ case NRecursedType::kRecursed:
+ recursed = true;
+ break;
+ case NRecursedType::kNonRecursed:
+ recursed = false;
+ break;
+ }
+ wildcardCensor.AddPreItem(include, name, recursed, true);
+ return true;
+}
+
+void AddCommandLineWildcardToCensor(NWildcard::CCensor &wildcardCensor,
+ const UString &name, bool include, NRecursedType::EEnum type)
+{
+ if (!AddNameToCensor(wildcardCensor, name, include, type))
+ ShowMessageAndThrowException(kIncorrectWildcardInCommandLine, NExitCode::kUserError);
+}
+
+void AddToCensorFromNonSwitchesStrings(NWildcard::CCensor &wildcardCensor,
+ const UStringVector & /* nonSwitchStrings */, NRecursedType::EEnum type,
+ bool /* thereAreSwitchIncludeWildcards */)
+{
+ AddCommandLineWildcardToCensor(wildcardCensor, kUniversalWildcard, true, type);
+}
+
+
+#ifndef _WIN32
+static void GetArguments(int numArgs, const char *args[], UStringVector &parts)
+{
+ parts.Clear();
+ for (int i = 0; i < numArgs; i++)
+ {
+ UString s = MultiByteToUnicodeString(args[i]);
+ parts.Add(s);
+ }
+}
+#endif
+
+int Main2(
+ #ifndef _WIN32
+ int numArgs, const char *args[]
+ #endif
+)
+{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ SetFileApisToOEM();
+ #endif
+
+ g_StdOut << kCopyrightString;
+
+ UStringVector commandStrings;
+ #ifdef _WIN32
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
+ #else
+ GetArguments(numArgs, args, commandStrings);
+ #endif
+
+ #ifdef _WIN32
+
+ FString arcPath;
+ {
+ FString path;
+ NDLL::MyGetModuleFileName(path);
+ if (!MyGetFullPathName(path, arcPath))
+ {
+ g_StdOut << "GetFullPathName Error";
+ return NExitCode::kFatalError;
+ }
+ }
+
+ #else
+
+ UString arcPath = commandStrings.Front();
+
+ #endif
+
+ commandStrings.Delete(0);
+
+ NCommandLineParser::CParser parser(kNumSwitches);
+ try
+ {
+ parser.ParseStrings(kSwitchForms, commandStrings);
+ }
+ catch(...)
+ {
+ PrintHelpAndExit();
+ }
+
+ if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
+ {
+ PrintHelp();
+ return 0;
+ }
+ const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
+
+ int numNonSwitchStrings = nonSwitchStrings.Size();
+
+ CArchiveCommand command;
+ if (numNonSwitchStrings == 0)
+ command.CommandType = NCommandType::kFullExtract;
+ else
+ {
+ if (numNonSwitchStrings > 1)
+ PrintHelpAndExit();
+ if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], command))
+ PrintHelpAndExit();
+ }
+
+
+ NRecursedType::EEnum recursedType;
+ recursedType = command.DefaultRecursedType();
+
+ NWildcard::CCensor wildcardCensor;
+
+ bool thereAreSwitchIncludeWildcards;
+ thereAreSwitchIncludeWildcards = false;
+
+ AddToCensorFromNonSwitchesStrings(wildcardCensor, nonSwitchStrings, recursedType,
+ thereAreSwitchIncludeWildcards);
+
+ bool yesToAll = parser[NKey::kYes].ThereIs;
+
+ // NExtractMode::EEnum extractMode;
+ // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode);
+
+ bool passwordEnabled = parser[NKey::kPassword].ThereIs;
+
+ UString password;
+ if (passwordEnabled)
+ password = parser[NKey::kPassword].PostStrings[0];
+
+ if (!NFind::DoesFileExist(arcPath))
+ throw kCantFindSFX;
+
+ FString outputDir;
+ if (parser[NKey::kOutputDir].ThereIs)
+ {
+ outputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]);
+ NName::NormalizeDirPathPrefix(outputDir);
+ }
+
+
+ wildcardCensor.AddPathsToCensor(NWildcard::k_RelatPath);
+
+ {
+ UStringVector v1, v2;
+ v1.Add(fs2us(arcPath));
+ v2.Add(fs2us(arcPath));
+ const NWildcard::CCensorNode &wildcardCensorHead =
+ wildcardCensor.Pairs.Front().Head;
+
+ CCodecs *codecs = new CCodecs;
+ CMyComPtr<
+ #ifdef EXTERNAL_CODECS
+ ICompressCodecsInfo
+ #else
+ IUnknown
+ #endif
+ > compressCodecsInfo = codecs;
+ HRESULT result = codecs->Load();
+ if (result != S_OK)
+ throw CSystemException(result);
+
+ if (command.CommandType != NCommandType::kList)
+ {
+ CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
+ CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
+ ecs->Init(g_StdStream, &g_StdErr, g_StdStream);
+
+ #ifndef _NO_CRYPTO
+ ecs->PasswordIsDefined = passwordEnabled;
+ ecs->Password = password;
+ #endif
+
+ /*
+ COpenCallbackConsole openCallback;
+ openCallback.Init(g_StdStream, g_StdStream);
+
+ #ifndef _NO_CRYPTO
+ openCallback.PasswordIsDefined = passwordEnabled;
+ openCallback.Password = password;
+ #endif
+ */
+
+ CExtractOptions eo;
+ eo.StdOutMode = false;
+ eo.YesToAll = yesToAll;
+ eo.TestMode = command.CommandType == NCommandType::kTest;
+ eo.PathMode = NExtract::NPathMode::kFullPaths;
+ eo.OverwriteMode = yesToAll ?
+ NExtract::NOverwriteMode::kOverwrite :
+ NExtract::NOverwriteMode::kAsk;
+ eo.OutputDir = outputDir;
+
+ UString errorMessage;
+ CDecompressStat stat;
+ HRESULT result = Extract(
+ codecs, CObjectVector<COpenType>(), CIntVector(),
+ v1, v2,
+ wildcardCensorHead,
+ eo, ecs, ecs,
+ // NULL, // hash
+ errorMessage, stat);
+ if (!errorMessage.IsEmpty())
+ {
+ (*g_StdStream) << endl << "Error: " << errorMessage;;
+ if (result == S_OK)
+ result = E_FAIL;
+ }
+
+ if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0)
+ {
+ if (ecs->NumArcsWithError != 0)
+ (*g_StdStream) << endl << "Archive Errors" << endl;
+ if (ecs->NumFileErrors != 0)
+ (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl;
+ return NExitCode::kFatalError;
+ }
+ if (result != S_OK)
+ throw CSystemException(result);
+ }
+ else
+ {
+ throw CSystemException(E_NOTIMPL);
+
+ /*
+ UInt64 numErrors = 0;
+ UInt64 numWarnings = 0;
+ HRESULT result = ListArchives(
+ codecs, CObjectVector<COpenType>(), CIntVector(),
+ false, // stdInMode
+ v1, v2,
+ true, // processAltStreams
+ false, // showAltStreams
+ wildcardCensorHead,
+ true, // enableHeaders
+ false, // techMode
+ #ifndef _NO_CRYPTO
+ passwordEnabled, password,
+ #endif
+ numErrors, numWarnings);
+ if (numErrors > 0)
+ {
+ g_StdOut << endl << "Errors: " << numErrors;
+ return NExitCode::kFatalError;
+ }
+ if (result != S_OK)
+ throw CSystemException(result);
+ */
+ }
+ }
+ return 0;
+}
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/StdAfx.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/StdAfx.cpp
new file mode 100644
index 00000000000..d0feea85c7b
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/StdAfx.h
new file mode 100644
index 00000000000..2854ff3e935
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/Common.h"
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/makefile b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/makefile
new file mode 100644
index 00000000000..f1cd2f57fd7
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/makefile
@@ -0,0 +1,127 @@
+PROG = 7zCon.sfx
+MY_CONSOLE = 1
+CFLAGS = $(CFLAGS) \
+ -DEXTRACT_ONLY \
+ -DNO_READ_FROM_CODER \
+ -D_SFX \
+
+CURRENT_OBJS = \
+ $O\SfxCon.obj \
+
+CONSOLE_OBJS = \
+ $O\ConsoleClose.obj \
+ $O\ExtractCallbackConsole.obj \
+ $O\List.obj \
+ $O\MainAr.obj \
+ $O\OpenCallbackConsole.obj \
+ $O\PercentPrinter.obj \
+ $O\UserInputUtils.obj \
+
+COMMON_OBJS = \
+ $O\CommandLineParser.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\MyString.obj \
+ $O\MyVector.obj \
+ $O\NewHandler.obj \
+ $O\StdInStream.obj \
+ $O\StdOutStream.obj \
+ $O\StringConvert.obj \
+ $O\Wildcard.obj \
+ $O\UTFConvert.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\ErrorMsg.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConv.obj \
+ $O\Synchronization.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\CreateCoder.obj \
+ $O\CWrappers.obj \
+ $O\FilePathAutoRename.obj \
+ $O\FileStreams.obj \
+ $O\InBuffer.obj \
+ $O\FilterCoder.obj \
+ $O\LimitedStreams.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\PropId.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+ $O\VirtThread.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveExtractCallback.obj \
+ $O\ArchiveOpenCallback.obj \
+ $O\DefaultName.obj \
+ $O\LoadCodecs.obj \
+ $O\Extract.obj \
+ $O\ExtractingFilePath.obj \
+ $O\OpenArchive.obj \
+ $O\PropIDUtils.obj \
+
+AR_OBJS = \
+ $O\SplitHandler.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\ItemNameUtils.obj \
+ $O\MultiStream.obj \
+ $O\OutStreamWithCRC.obj \
+
+
+7Z_OBJS = \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zHandler.obj \
+ $O\7zIn.obj \
+ $O\7zRegister.obj \
+
+COMPRESS_OBJS = \
+ $O\Bcj2Coder.obj \
+ $O\Bcj2Register.obj \
+ $O\BcjCoder.obj \
+ $O\BcjRegister.obj \
+ $O\BranchMisc.obj \
+ $O\BranchRegister.obj \
+ $O\CopyCoder.obj \
+ $O\CopyRegister.obj \
+ $O\DeltaFilter.obj \
+ $O\Lzma2Decoder.obj \
+ $O\Lzma2Register.obj \
+ $O\LzmaDecoder.obj \
+ $O\LzmaRegister.obj \
+ $O\PpmdDecoder.obj \
+ $O\PpmdRegister.obj \
+
+CRYPTO_OBJS = \
+ $O\7zAes.obj \
+ $O\7zAesRegister.obj \
+ $O\MyAes.obj \
+
+C_OBJS = \
+ $O\Alloc.obj \
+ $O\Bcj2.obj \
+ $O\Bra.obj \
+ $O\Bra86.obj \
+ $O\BraIA64.obj \
+ $O\CpuArch.obj \
+ $O\Delta.obj \
+ $O\Lzma2Dec.obj \
+ $O\LzmaDec.obj \
+ $O\Ppmd7.obj \
+ $O\Ppmd7Dec.obj \
+ $O\Sha256.obj \
+ $O\Threads.obj \
+
+!include "../../Aes.mak"
+!include "../../Crc.mak"
+
+!include "../../7zip.mak"
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/resource.rc b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/resource.rc
new file mode 100644
index 00000000000..58331b81f8f
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_APP("7z Console SFX", "7z.sfx")
+
+101 ICON "7z.ico" \ No newline at end of file
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp
new file mode 100644
index 00000000000..793306303c5
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp
@@ -0,0 +1,246 @@
+// ExtractCallbackSfx.h
+
+#include "StdAfx.h"
+
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/PropVariant.h"
+
+#include "ExtractCallbackSfx.h"
+
+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";
+
+void CExtractCallbackImp::Init(IInArchive *archiveHandler,
+ const FString &directoryPath,
+ const UString &itemDefaultName,
+ const FILETIME &defaultMTime,
+ UInt32 defaultAttributes)
+{
+ _message.Empty();
+ _isCorrupt = false;
+ _itemDefaultName = itemDefaultName;
+ _defaultMTime = defaultMTime;
+ _defaultAttributes = defaultAttributes;
+ _archiveHandler = archiveHandler;
+ _directoryPath = directoryPath;
+ NName::NormalizeDirPathPrefix(_directoryPath);
+}
+
+HRESULT CExtractCallbackImp::Open_CheckBreak()
+{
+ #ifndef _NO_PROGRESS
+ return ProgressDialog.Sync.ProcessStopAndPause();
+ #else
+ return S_OK;
+ #endif
+}
+
+HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */)
+{
+ return S_OK;
+}
+
+HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */)
+{
+ #ifndef _NO_PROGRESS
+ return ProgressDialog.Sync.ProcessStopAndPause();
+ #else
+ return S_OK;
+ #endif
+}
+
+HRESULT CExtractCallbackImp::Open_Finished()
+{
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size)
+{
+ #ifndef _NO_PROGRESS
+ ProgressDialog.Sync.SetProgress(size, 0);
+ #endif
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)
+{
+ #ifndef _NO_PROGRESS
+ RINOK(ProgressDialog.Sync.ProcessStopAndPause());
+ if (completeValue != NULL)
+ ProgressDialog.Sync.SetPos(*completeValue);
+ #endif
+ return S_OK;
+}
+
+void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)
+{
+ FString fullPath = _directoryPath;
+ FOR_VECTOR (i, dirPathParts)
+ {
+ fullPath += us2fs(dirPathParts[i]);
+ CreateDir(fullPath);
+ fullPath.Add_PathSepar();
+ }
+}
+
+STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
+ ISequentialOutStream **outStream, Int32 askExtractMode)
+{
+ #ifndef _NO_PROGRESS
+ if (ProgressDialog.Sync.GetStopped())
+ return E_ABORT;
+ #endif
+ _outFileStream.Release();
+
+ UString fullPath;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));
+ if (prop.vt == VT_EMPTY)
+ fullPath = _itemDefaultName;
+ else
+ {
+ if (prop.vt != VT_BSTR)
+ return E_FAIL;
+ fullPath.SetFromBstr(prop.bstrVal);
+ }
+ _filePath = fullPath;
+ }
+
+ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract)
+ {
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop));
+ if (prop.vt == VT_EMPTY)
+ _processedFileInfo.Attributes = _defaultAttributes;
+ else
+ {
+ if (prop.vt != VT_UI4)
+ return E_FAIL;
+ _processedFileInfo.Attributes = prop.ulVal;
+ }
+
+ RINOK(_archiveHandler->GetProperty(index, kpidIsDir, &prop));
+ _processedFileInfo.IsDir = VARIANT_BOOLToBool(prop.boolVal);
+
+ bool isAnti = false;
+ {
+ NCOM::CPropVariant propTemp;
+ RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propTemp));
+ if (propTemp.vt == VT_BOOL)
+ isAnti = VARIANT_BOOLToBool(propTemp.boolVal);
+ }
+
+ RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));
+ switch (prop.vt)
+ {
+ case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break;
+ case VT_FILETIME: _processedFileInfo.MTime = prop.filetime; break;
+ default: return E_FAIL;
+ }
+
+ UStringVector pathParts;
+ SplitPathToParts(fullPath, pathParts);
+ if (pathParts.IsEmpty())
+ return E_FAIL;
+
+ UString processedPath = fullPath;
+
+ if (!_processedFileInfo.IsDir)
+ pathParts.DeleteBack();
+ if (!pathParts.IsEmpty())
+ {
+ if (!isAnti)
+ CreateComplexDirectory(pathParts);
+ }
+
+ FString fullProcessedPath = _directoryPath + us2fs(processedPath);
+
+ if (_processedFileInfo.IsDir)
+ {
+ _diskFilePath = fullProcessedPath;
+
+ if (isAnti)
+ RemoveDir(_diskFilePath);
+ else
+ SetDirTime(_diskFilePath, NULL, NULL, &_processedFileInfo.MTime);
+ return S_OK;
+ }
+
+ NFind::CFileInfo fileInfo;
+ if (fileInfo.Find(fullProcessedPath))
+ {
+ if (!DeleteFileAlways(fullProcessedPath))
+ {
+ _message = kCantDeleteFile;
+ return E_FAIL;
+ }
+ }
+
+ if (!isAnti)
+ {
+ _outFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+ if (!_outFileStreamSpec->Create(fullProcessedPath, true))
+ {
+ _message = kCantOpenFile;
+ return E_FAIL;
+ }
+ _outFileStream = outStreamLoc;
+ *outStream = outStreamLoc.Detach();
+ }
+ _diskFilePath = fullProcessedPath;
+ }
+ else
+ {
+ *outStream = NULL;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)
+{
+ _extractMode = (askExtractMode == NArchive::NExtract::NAskMode::kExtract);
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult)
+{
+ switch (resultEOperationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ break;
+
+ default:
+ {
+ _outFileStream.Release();
+ switch (resultEOperationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
+ _message = kUnsupportedMethod;
+ break;
+ default:
+ _isCorrupt = true;
+ }
+ return E_FAIL;
+ }
+ }
+ if (_outFileStream != NULL)
+ {
+ _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
+ RINOK(_outFileStreamSpec->Close());
+ }
+ _outFileStream.Release();
+ if (_extractMode)
+ SetFileAttrib(_diskFilePath, _processedFileInfo.Attributes);
+ return S_OK;
+}
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h
new file mode 100644
index 00000000000..cfbc5c07aa0
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h
@@ -0,0 +1,86 @@
+// ExtractCallbackSfx.h
+
+#ifndef __EXTRACT_CALLBACK_SFX_H
+#define __EXTRACT_CALLBACK_SFX_H
+
+#include "resource.h"
+
+#include "../../../Windows/ResourceString.h"
+
+#include "../../Archive/IArchive.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../ICoder.h"
+
+#include "../../UI/FileManager/LangUtils.h"
+
+#ifndef _NO_PROGRESS
+#include "../../UI/FileManager/ProgressDialog.h"
+#endif
+#include "../../UI/Common/ArchiveOpenCallback.h"
+
+class CExtractCallbackImp:
+ public IArchiveExtractCallback,
+ public IOpenCallbackUI,
+ public CMyUnknownImp
+{
+public:
+
+ MY_UNKNOWN_IMP
+
+ INTERFACE_IArchiveExtractCallback(;)
+ INTERFACE_IOpenCallbackUI(;)
+
+private:
+ CMyComPtr<IInArchive> _archiveHandler;
+ FString _directoryPath;
+ UString _filePath;
+ FString _diskFilePath;
+
+ bool _extractMode;
+ struct CProcessedFileInfo
+ {
+ FILETIME MTime;
+ bool IsDir;
+ UInt32 Attributes;
+ } _processedFileInfo;
+
+ COutFileStream *_outFileStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outFileStream;
+
+ UString _itemDefaultName;
+ FILETIME _defaultMTime;
+ UInt32 _defaultAttributes;
+
+ void CreateComplexDirectory(const UStringVector &dirPathParts);
+public:
+ #ifndef _NO_PROGRESS
+ CProgressDialog ProgressDialog;
+ #endif
+
+ bool _isCorrupt;
+ UString _message;
+
+ void Init(IInArchive *archiveHandler,
+ const FString &directoryPath,
+ const UString &itemDefaultName,
+ const FILETIME &defaultMTime,
+ UInt32 defaultAttributes);
+
+ #ifndef _NO_PROGRESS
+ HRESULT StartProgressDialog(const UString &title, NWindows::CThread &thread)
+ {
+ ProgressDialog.Create(title, thread, 0);
+ {
+ ProgressDialog.SetText(LangString(IDS_PROGRESS_EXTRACTING));
+ }
+
+ ProgressDialog.Show(SW_SHOWNORMAL);
+ return S_OK;
+ }
+ virtual ~CExtractCallbackImp() { ProgressDialog.Destroy(); }
+ #endif
+
+};
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
new file mode 100644
index 00000000000..ba41fd1add8
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
@@ -0,0 +1,138 @@
+// ExtractEngine.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/Thread.h"
+
+#include "../../UI/Common/OpenArchive.h"
+
+#include "../../UI/FileManager/FormatUtils.h"
+#include "../../UI/FileManager/LangUtils.h"
+
+#include "ExtractCallbackSfx.h"
+#include "ExtractEngine.h"
+
+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";
+
+struct CThreadExtracting
+{
+ CCodecs *Codecs;
+ FString FileName;
+ FString DestFolder;
+
+ CExtractCallbackImp *ExtractCallbackSpec;
+ CMyComPtr<IArchiveExtractCallback> ExtractCallback;
+
+ CArchiveLink ArchiveLink;
+ HRESULT Result;
+ UString ErrorMessage;
+
+ void Process2()
+ {
+ NFind::CFileInfo fi;
+ if (!fi.Find(FileName))
+ {
+ ErrorMessage = kCantFindArchive;
+ Result = E_FAIL;
+ return;
+ }
+
+ CObjectVector<COpenType> incl;
+ CIntVector excl;
+ COpenOptions options;
+ options.codecs = Codecs;
+ options.types = &incl;
+ options.excludedFormats = &excl;
+ options.filePath = fs2us(FileName);
+
+ Result = ArchiveLink.Open2(options, ExtractCallbackSpec);
+ if (Result != S_OK)
+ {
+ if (Result != S_OK)
+ ErrorMessage = kCantOpenArchive;
+ return;
+ }
+
+ FString dirPath = DestFolder;
+ NName::NormalizeDirPathPrefix(dirPath);
+
+ if (!CreateComplexDir(dirPath))
+ {
+ ErrorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
+ #ifdef LANG
+ 0x02000603,
+ #endif
+ fs2us(dirPath));
+ Result = E_FAIL;
+ return;
+ }
+
+ ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, L"Default", fi.MTime, 0);
+
+ Result = ArchiveLink.GetArchive()->Extract(0, (UInt32)(Int32)-1 , BoolToInt(false), ExtractCallback);
+ }
+
+ void Process()
+ {
+ try
+ {
+ #ifndef _NO_PROGRESS
+ CProgressCloser closer(ExtractCallbackSpec->ProgressDialog);
+ #endif
+ Process2();
+ }
+ catch(...) { Result = E_FAIL; }
+ }
+
+ static THREAD_FUNC_DECL MyThreadFunction(void *param)
+ {
+ ((CThreadExtracting *)param)->Process();
+ return 0;
+ }
+};
+
+HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString &destFolder,
+ bool showProgress, bool &isCorrupt, UString &errorMessage)
+{
+ isCorrupt = false;
+ CThreadExtracting t;
+
+ t.Codecs = codecs;
+ t.FileName = fileName;
+ t.DestFolder = destFolder;
+
+ t.ExtractCallbackSpec = new CExtractCallbackImp;
+ t.ExtractCallback = t.ExtractCallbackSpec;
+
+ #ifndef _NO_PROGRESS
+
+ if (showProgress)
+ {
+ t.ExtractCallbackSpec->ProgressDialog.IconID = IDI_ICON;
+ NWindows::CThread thread;
+ RINOK(thread.Create(CThreadExtracting::MyThreadFunction, &t));
+
+ UString title;
+ LangString(IDS_PROGRESS_EXTRACTING, title);
+ t.ExtractCallbackSpec->StartProgressDialog(title, thread);
+ }
+ else
+
+ #endif
+ {
+ t.Process2();
+ }
+
+ errorMessage = t.ErrorMessage;
+ if (errorMessage.IsEmpty())
+ errorMessage = t.ExtractCallbackSpec->_message;
+ isCorrupt = t.ExtractCallbackSpec->_isCorrupt;
+ return t.Result;
+}
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h
new file mode 100644
index 00000000000..295d77b9957
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h
@@ -0,0 +1,11 @@
+// ExtractEngine.h
+
+#ifndef __EXTRACT_ENGINE_H
+#define __EXTRACT_ENGINE_H
+
+#include "../../UI/Common/LoadCodecs.h"
+
+HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString &destFolder,
+ bool showProgress, bool &isCorrupt, UString &errorMessage);
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp
new file mode 100644
index 00000000000..f2783e028cf
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp
@@ -0,0 +1,760 @@
+# Microsoft Developer Studio Project File - Name="SFXSetup" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=SFXSetup - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "SFXSetup.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "SFXSetup.mak" CFG="SFXSetup - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "SFXSetup - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "SFXSetup - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "SFXSetup - Win32 ReleaseD" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "SFXSetup - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /Gz /MT /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zS.sfx" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "SFXSetup - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zSfxS.exe" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "SFXSetup - Win32 ReleaseD"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseD"
+# PROP BASE Intermediate_Dir "ReleaseD"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseD"
+# PROP Intermediate_Dir "ReleaseD"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_SFX" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zWinSR.exe"
+# SUBTRACT BASE LINK32 /debug /nodefaultlib
+# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zSD.sfx" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "SFXSetup - Win32 Release"
+# Name "SFXSetup - Win32 Debug"
+# Name "SFXSetup - Win32 ReleaseD"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Interface"
+
+# PROP Default_Filter ""
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zRegister.cpp
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Bcj2Coder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Bcj2Register.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BcjCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BcjRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BranchMisc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BranchMisc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BranchRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\CopyRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\DeltaFilter.cpp
+# End Source File
+# Begin Source File
+
+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
+
+SOURCE=..\..\Compress\LzmaDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LzmaRegister.cpp
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\TextConfig.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\TextConfig.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Group "Control"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ErrorMsg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ErrorMsg.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.h
+# End Source File
+# End Group
+# Begin Group "7z Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\CreateCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\CreateCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\PropId.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\VirtThread.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\VirtThread.h
+# End Source File
+# End Group
+# Begin Group "UI"
+
+# PROP Default_Filter ""
+# Begin Group "Explorer"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Explorer\MyMessages.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Explorer\MyMessages.h
+# End Source File
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\LoadCodecs.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\LoadCodecs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "File Manager"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\FormatUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\FormatUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\LangUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\ProgressDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\ProgressDialog.h
+# End Source File
+# End Group
+# Begin Group "C"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrcOpt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bcj2.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bcj2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bra.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bra.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bra86.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\BraIA64.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\CpuArch.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\CpuArch.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Delta.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Delta.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Lzma2Dec.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Lzma2Dec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\LzmaDec.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\LzmaDec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\ExtractCallbackSfx.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractCallbackSfx.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractEngine.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractEngine.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\setup.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\SfxSetup.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw
new file mode 100644
index 00000000000..f563b21f254
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "SFXSetup"=.\SFXSetup.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp
new file mode 100644
index 00000000000..d389023574f
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp
@@ -0,0 +1,356 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/MyWindows.h"
+
+#include "../../../Common/MyInitGuid.h"
+
+#include "../../../Common/CommandLineParser.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/TextConfig.h"
+
+#include "../../../Windows/DLL.h"
+#include "../../../Windows/ErrorMsg.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/FileIO.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/NtCheck.h"
+#include "../../../Windows/ResourceString.h"
+
+#include "../../UI/Explorer/MyMessages.h"
+
+#include "ExtractEngine.h"
+
+#include "resource.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDir;
+
+HINSTANCE g_hInstance;
+
+static CFSTR kTempDirPrefix = FTEXT("7zS");
+
+#define _SHELL_EXECUTE
+
+static bool ReadDataString(CFSTR fileName, LPCSTR startID,
+ LPCSTR endID, AString &stringResult)
+{
+ stringResult.Empty();
+ NIO::CInFile inFile;
+ if (!inFile.Open(fileName))
+ return false;
+ const int kBufferSize = (1 << 12);
+
+ Byte buffer[kBufferSize];
+ int signatureStartSize = MyStringLen(startID);
+ int signatureEndSize = MyStringLen(endID);
+
+ UInt32 numBytesPrev = 0;
+ bool writeMode = false;
+ UInt64 posTotal = 0;
+ for (;;)
+ {
+ if (posTotal > (1 << 20))
+ return (stringResult.IsEmpty());
+ UInt32 numReadBytes = kBufferSize - numBytesPrev;
+ UInt32 processedSize;
+ if (!inFile.Read(buffer + numBytesPrev, numReadBytes, processedSize))
+ return false;
+ if (processedSize == 0)
+ return true;
+ UInt32 numBytesInBuffer = numBytesPrev + processedSize;
+ UInt32 pos = 0;
+ for (;;)
+ {
+ if (writeMode)
+ {
+ if (pos > numBytesInBuffer - signatureEndSize)
+ break;
+ if (memcmp(buffer + pos, endID, signatureEndSize) == 0)
+ return true;
+ char b = buffer[pos];
+ if (b == 0)
+ return false;
+ stringResult += b;
+ pos++;
+ }
+ else
+ {
+ if (pos > numBytesInBuffer - signatureStartSize)
+ break;
+ if (memcmp(buffer + pos, startID, signatureStartSize) == 0)
+ {
+ writeMode = true;
+ pos += signatureStartSize;
+ }
+ else
+ pos++;
+ }
+ }
+ numBytesPrev = numBytesInBuffer - pos;
+ posTotal += pos;
+ memmove(buffer, buffer + pos, numBytesPrev);
+ }
+}
+
+static char kStartID[] = { ',','!','@','I','n','s','t','a','l','l','@','!','U','T','F','-','8','!', 0 };
+static char kEndID[] = { ',','!','@','I','n','s','t','a','l','l','E','n','d','@','!', 0 };
+
+struct CInstallIDInit
+{
+ CInstallIDInit()
+ {
+ kStartID[0] = ';';
+ kEndID[0] = ';';
+ };
+} g_CInstallIDInit;
+
+
+#define NT_CHECK_FAIL_ACTION ShowErrorMessage(L"Unsupported Windows version"); return 1;
+
+static void ShowErrorMessageSpec(const UString &name)
+{
+ UString message = NError::MyFormatMessage(::GetLastError());
+ int pos = message.Find(L"%1");
+ if (pos >= 0)
+ {
+ message.Delete(pos, 2);
+ message.Insert(pos, name);
+ }
+ ShowErrorMessage(NULL, message);
+}
+
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
+ #ifdef UNDER_CE
+ LPWSTR
+ #else
+ LPSTR
+ #endif
+ /* lpCmdLine */,int /* nCmdShow */)
+{
+ g_hInstance = (HINSTANCE)hInstance;
+
+ NT_CHECK
+
+ // InitCommonControls();
+
+ UString archiveName, switches;
+ #ifdef _SHELL_EXECUTE
+ UString executeFile, executeParameters;
+ #endif
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches);
+
+ FString fullPath;
+ NDLL::MyGetModuleFileName(fullPath);
+
+ switches.Trim();
+ bool assumeYes = false;
+ if (switches.IsPrefixedBy_Ascii_NoCase("-y"))
+ {
+ assumeYes = true;
+ switches = switches.Ptr(2);
+ switches.Trim();
+ }
+
+ AString config;
+ if (!ReadDataString(fullPath, kStartID, kEndID, config))
+ {
+ if (!assumeYes)
+ ShowErrorMessage(L"Can't load config info");
+ return 1;
+ }
+
+ UString dirPrefix = L"." WSTRING_PATH_SEPARATOR;
+ UString appLaunched;
+ bool showProgress = true;
+ if (!config.IsEmpty())
+ {
+ CObjectVector<CTextConfigPair> pairs;
+ if (!GetTextConfig(config, pairs))
+ {
+ if (!assumeYes)
+ ShowErrorMessage(L"Config failed");
+ return 1;
+ }
+ UString friendlyName = GetTextConfigValue(pairs, L"Title");
+ UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt");
+ UString progress = GetTextConfigValue(pairs, L"Progress");
+ if (progress.IsEqualTo_Ascii_NoCase("no"))
+ showProgress = false;
+ int index = FindTextConfigItem(pairs, L"Directory");
+ if (index >= 0)
+ dirPrefix = pairs[index].String;
+ if (!installPrompt.IsEmpty() && !assumeYes)
+ {
+ if (MessageBoxW(0, installPrompt, friendlyName, MB_YESNO |
+ MB_ICONQUESTION) != IDYES)
+ return 0;
+ }
+ appLaunched = GetTextConfigValue(pairs, L"RunProgram");
+
+ #ifdef _SHELL_EXECUTE
+ executeFile = GetTextConfigValue(pairs, L"ExecuteFile");
+ executeParameters = GetTextConfigValue(pairs, L"ExecuteParameters");
+ #endif
+ }
+
+ CTempDir tempDir;
+ if (!tempDir.Create(kTempDirPrefix))
+ {
+ if (!assumeYes)
+ ShowErrorMessage(L"Can not create temp folder archive");
+ return 1;
+ }
+
+ CCodecs *codecs = new CCodecs;
+ CMyComPtr<IUnknown> compressCodecsInfo = codecs;
+ HRESULT result = codecs->Load();
+ if (result != S_OK)
+ {
+ ShowErrorMessage(L"Can not load codecs");
+ return 1;
+ }
+
+ const FString tempDirPath = tempDir.GetPath();
+ // tempDirPath = L"M:\\1\\"; // to test low disk space
+ {
+ bool isCorrupt = false;
+ UString errorMessage;
+ HRESULT result = ExtractArchive(codecs, fullPath, tempDirPath, showProgress,
+ isCorrupt, errorMessage);
+
+ if (result != S_OK)
+ {
+ if (!assumeYes)
+ {
+ if (result == S_FALSE || isCorrupt)
+ {
+ NWindows::MyLoadString(IDS_EXTRACTION_ERROR_MESSAGE, errorMessage);
+ result = E_FAIL;
+ }
+ if (result != E_ABORT)
+ {
+ if (errorMessage.IsEmpty())
+ errorMessage = NError::MyFormatMessage(result);
+ ::MessageBoxW(0, errorMessage, NWindows::MyLoadString(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR);
+ }
+ }
+ return 1;
+ }
+ }
+
+ #ifndef UNDER_CE
+ CCurrentDirRestorer currentDirRestorer;
+ if (!SetCurrentDir(tempDirPath))
+ return 1;
+ #endif
+
+ HANDLE hProcess = 0;
+#ifdef _SHELL_EXECUTE
+ if (!executeFile.IsEmpty())
+ {
+ CSysString filePath = GetSystemString(executeFile);
+ SHELLEXECUTEINFO execInfo;
+ execInfo.cbSize = sizeof(execInfo);
+ execInfo.fMask = SEE_MASK_NOCLOSEPROCESS
+ #ifndef UNDER_CE
+ | SEE_MASK_FLAG_DDEWAIT
+ #endif
+ ;
+ execInfo.hwnd = NULL;
+ execInfo.lpVerb = NULL;
+ execInfo.lpFile = filePath;
+
+ if (!switches.IsEmpty())
+ {
+ executeParameters.Add_Space_if_NotEmpty();
+ executeParameters += switches;
+ }
+
+ CSysString parametersSys = GetSystemString(executeParameters);
+ if (parametersSys.IsEmpty())
+ execInfo.lpParameters = NULL;
+ else
+ execInfo.lpParameters = parametersSys;
+
+ execInfo.lpDirectory = NULL;
+ execInfo.nShow = SW_SHOWNORMAL;
+ execInfo.hProcess = 0;
+ /* BOOL success = */ ::ShellExecuteEx(&execInfo);
+ UINT32 result = (UINT32)(UINT_PTR)execInfo.hInstApp;
+ if (result <= 32)
+ {
+ if (!assumeYes)
+ ShowErrorMessage(L"Can not open file");
+ return 1;
+ }
+ hProcess = execInfo.hProcess;
+ }
+ else
+#endif
+ {
+ if (appLaunched.IsEmpty())
+ {
+ appLaunched = L"setup.exe";
+ if (!NFind::DoesFileExist(us2fs(appLaunched)))
+ {
+ if (!assumeYes)
+ ShowErrorMessage(L"Can not find setup.exe");
+ return 1;
+ }
+ }
+
+ {
+ FString s2 = tempDirPath;
+ NName::NormalizeDirPathPrefix(s2);
+ appLaunched.Replace(L"%%T" WSTRING_PATH_SEPARATOR, fs2us(s2));
+ }
+
+ UString appNameForError = appLaunched; // actually we need to rtemove parameters also
+
+ appLaunched.Replace(L"%%T", fs2us(tempDirPath));
+
+ if (!switches.IsEmpty())
+ {
+ appLaunched.Add_Space();
+ appLaunched += switches;
+ }
+ STARTUPINFO startupInfo;
+ startupInfo.cb = sizeof(startupInfo);
+ startupInfo.lpReserved = 0;
+ startupInfo.lpDesktop = 0;
+ startupInfo.lpTitle = 0;
+ startupInfo.dwFlags = 0;
+ startupInfo.cbReserved2 = 0;
+ startupInfo.lpReserved2 = 0;
+
+ PROCESS_INFORMATION processInformation;
+
+ CSysString appLaunchedSys = GetSystemString(dirPrefix + appLaunched);
+
+ BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys,
+ NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */,
+ &startupInfo, &processInformation);
+ if (createResult == 0)
+ {
+ if (!assumeYes)
+ {
+ // we print name of exe file, if error message is
+ // ERROR_BAD_EXE_FORMAT: "%1 is not a valid Win32 application".
+ ShowErrorMessageSpec(appNameForError);
+ }
+ return 1;
+ }
+ ::CloseHandle(processInformation.hThread);
+ hProcess = processInformation.hProcess;
+ }
+ if (hProcess != 0)
+ {
+ WaitForSingleObject(hProcess, INFINITE);
+ ::CloseHandle(hProcess);
+ }
+ return 0;
+}
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp
new file mode 100644
index 00000000000..d0feea85c7b
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/StdAfx.h
new file mode 100644
index 00000000000..37bbd0c33b7
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/StdAfx.h
@@ -0,0 +1,13 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/Common.h"
+
+#include <commctrl.h>
+
+// #define printf(x) NO_PRINTF_(x)
+// #define sprintf(x) NO_SPRINTF_(x)
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/makefile b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/makefile
new file mode 100644
index 00000000000..5f6f6032430
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/makefile
@@ -0,0 +1,109 @@
+PROG = 7zS.sfx
+CFLAGS = $(CFLAGS) \
+ -DNO_REGISTRY \
+ -DEXTRACT_ONLY \
+ -DNO_READ_FROM_CODER \
+ -D_SFX \
+ -D_NO_CRYPTO \
+
+CURRENT_OBJS = \
+ $O\SfxSetup.obj \
+ $O\ExtractCallbackSfx.obj \
+ $O\ExtractEngine.obj \
+
+COMMON_OBJS = \
+ $O\CommandLineParser.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\MyString.obj \
+ $O\StringConvert.obj \
+ $O\TextConfig.obj \
+ $O\UTFConvert.obj \
+ $O\MyVector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\ErrorMsg.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\PropVariant.obj \
+ $O\ResourceString.obj \
+ $O\Synchronization.obj \
+ $O\Window.obj \
+
+WIN_CTRL_OBJS = \
+ $O\Dialog.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\CreateCoder.obj \
+ $O\FileStreams.obj \
+ $O\InBuffer.obj \
+ $O\FilterCoder.obj \
+ $O\LimitedStreams.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\PropId.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+ $O\VirtThread.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveOpenCallback.obj \
+ $O\DefaultName.obj \
+ $O\LoadCodecs.obj \
+ $O\OpenArchive.obj \
+
+EXPLORER_OBJS = \
+ $O\MyMessages.obj \
+
+FM_OBJS = \
+ $O\FormatUtils.obj \
+ $O\ProgressDialog.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\ItemNameUtils.obj \
+ $O\OutStreamWithCRC.obj \
+
+7Z_OBJS = \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zHandler.obj \
+ $O\7zIn.obj \
+ $O\7zRegister.obj \
+
+COMPRESS_OBJS = \
+ $O\Bcj2Coder.obj \
+ $O\Bcj2Register.obj \
+ $O\BcjCoder.obj \
+ $O\BcjRegister.obj \
+ $O\BranchMisc.obj \
+ $O\BranchRegister.obj \
+ $O\CopyCoder.obj \
+ $O\CopyRegister.obj \
+ $O\DeltaFilter.obj \
+ $O\Lzma2Decoder.obj \
+ $O\Lzma2Register.obj \
+ $O\LzmaDecoder.obj \
+ $O\LzmaRegister.obj \
+
+C_OBJS = \
+ $O\Alloc.obj \
+ $O\Bcj2.obj \
+ $O\Bra.obj \
+ $O\Bra86.obj \
+ $O\BraIA64.obj \
+ $O\CpuArch.obj \
+ $O\Delta.obj \
+ $O\Lzma2Dec.obj \
+ $O\LzmaDec.obj \
+ $O\Threads.obj \
+
+!include "../../Crc.mak"
+
+!include "../../7zip.mak"
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/resource.h b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/resource.h
new file mode 100644
index 00000000000..d5f440bb8fe
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/resource.h
@@ -0,0 +1,6 @@
+#define IDI_ICON 1
+
+#define IDS_EXTRACTION_ERROR_TITLE 7
+#define IDS_EXTRACTION_ERROR_MESSAGE 8
+#define IDS_CANNOT_CREATE_FOLDER 3003
+#define IDS_PROGRESS_EXTRACTING 3300
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/resource.rc b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/resource.rc
new file mode 100644
index 00000000000..47e1b7620e9
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/resource.rc
@@ -0,0 +1,16 @@
+#include "../../MyVersionInfo.rc"
+#include "resource.h"
+
+MY_VERSION_INFO_APP("7z Setup SFX", "7zS.sfx")
+
+IDI_ICON ICON "setup.ico"
+
+STRINGTABLE
+BEGIN
+ IDS_EXTRACTION_ERROR_TITLE "Extraction Failed"
+ IDS_EXTRACTION_ERROR_MESSAGE "File is corrupt"
+ IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'"
+ IDS_PROGRESS_EXTRACTING "Extracting"
+END
+
+#include "../../UI/FileManager/ProgressDialog.rc"
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/setup.ico b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/setup.ico
new file mode 100644
index 00000000000..bb455be1e7a
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/setup.ico
Binary files differ
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/7z.ico b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/7z.ico
new file mode 100644
index 00000000000..47ffb781e0b
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/7z.ico
Binary files differ
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SFXWin.dsp b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
new file mode 100644
index 00000000000..1f3d88d13b6
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
@@ -0,0 +1,953 @@
+# Microsoft Developer Studio Project File - Name="SFXWin" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=SFXWin - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "SFXWin.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "SFXWin.mak" CFG="SFXWin - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "SFXWin - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "SFXWin - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "SFXWin - Win32 ReleaseD" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "SFXWin - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_SFXWIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "NO_READ_FROM_CODER" /D "_SFX" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7z.sfx" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "SFXWin - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_SFXWIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "NO_READ_FROM_CODER" /D "_SFX" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7zsfx.exe" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "SFXWin - Win32 ReleaseD"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "SFXWin___Win32_ReleaseD"
+# PROP BASE Intermediate_Dir "SFXWin___Win32_ReleaseD"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "SFXWin___Win32_ReleaseD"
+# PROP Intermediate_Dir "SFXWin___Win32_ReleaseD"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_SFX" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_SFXWIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "NO_READ_FROM_CODER" /D "_SFX" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7z.sfx" /opt:NOWIN98
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zD.sfx" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "SFXWin - Win32 Release"
+# Name "SFXWin - Win32 Debug"
+# Name "SFXWin - Win32 ReleaseD"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\SplitHandler.cpp
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\MultiStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Bcj2Coder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Bcj2Register.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BcjCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BcjRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BranchMisc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BranchMisc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BranchRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\CopyRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\DeltaFilter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzma2Decoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzma2Register.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LzmaDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LzmaRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PpmdDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PpmdRegister.cpp
+# End Source File
+# End Group
+# Begin Group "Crypto"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAes.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAesRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\MyAes.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\MyAes.h
+# End Source File
+# End Group
+# Begin Group "Dialogs"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\BrowseDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\BrowseDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\ComboDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\ComboDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\OverwriteDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\OverwriteDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\PasswordDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\PasswordDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\ProgressDialog2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\ProgressDialog2.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\CreateCoder.cpp
+# End Source File
+# Begin Source File
+
+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\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\PropId.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\VirtThread.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\VirtThread.h
+# End Source File
+# End Group
+# Begin Group "File Manager"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\ExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\ExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\FormatUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\FormatUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\PropertyName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\PropertyName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\SysIconUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\FileManager\SysIconUtils.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Group "Control"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\ComboBox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\ComboBox.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\ListView.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\ListView.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\Windows\CommonDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\CommonDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ErrorMsg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ErrorMsg.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConv.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Shell.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Shell.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "UI"
+
+# PROP Default_Filter ""
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\LoadCodecs.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\LoadCodecs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.h
+# End Source File
+# End Group
+# Begin Group "GUI"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\ExtractDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\ExtractDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\ExtractGUI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\ExtractGUI.h
+# End Source File
+# End Group
+# Begin Group "Explorer"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Explorer\MyMessages.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Explorer\MyMessages.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "C"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrcOpt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Aes.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Aes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\AesOpt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bcj2.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bcj2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bra.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bra.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Bra86.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\BraIA64.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\CpuArch.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Delta.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Delta.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Lzma2Dec.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Lzma2Dec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\LzmaDec.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\LzmaDec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Ppmd7.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Ppmd7.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Ppmd7Dec.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Sha256.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\7z.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\7z1.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\SfxWin.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SFXWin.dsw b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SFXWin.dsw
new file mode 100644
index 00000000000..a9926c719bf
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SFXWin.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "SFXWin"=.\SFXWin.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SfxWin.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SfxWin.cpp
new file mode 100644
index 00000000000..c301ecf8894
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SfxWin.cpp
@@ -0,0 +1,235 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/MyWindows.h"
+
+#include <Shlwapi.h>
+
+#include "../../../Common/MyInitGuid.h"
+
+#include "../../../Common/CommandLineParser.h"
+#include "../../../Common/StringConvert.h"
+
+#include "../../../Windows/DLL.h"
+#include "../../../Windows/ErrorMsg.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/NtCheck.h"
+#include "../../../Windows/ResourceString.h"
+
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+#include "../../Archive/IArchive.h"
+#include "../../UI/Common/Extract.h"
+#include "../../UI/Common/ExitCode.h"
+#include "../../UI/Explorer/MyMessages.h"
+#include "../../UI/FileManager/MyWindowsNew.h"
+#include "../../UI/GUI/ExtractGUI.h"
+#include "../../UI/GUI/ExtractRes.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDir;
+
+HINSTANCE g_hInstance;
+
+#ifndef UNDER_CE
+
+DWORD g_ComCtl32Version;
+
+static DWORD GetDllVersion(LPCTSTR dllName)
+{
+ DWORD dwVersion = 0;
+ HINSTANCE hinstDll = LoadLibrary(dllName);
+ if (hinstDll)
+ {
+ DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
+ if (pDllGetVersion)
+ {
+ DLLVERSIONINFO dvi;
+ ZeroMemory(&dvi, sizeof(dvi));
+ dvi.cbSize = sizeof(dvi);
+ HRESULT hr = (*pDllGetVersion)(&dvi);
+ if (SUCCEEDED(hr))
+ dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion);
+ }
+ FreeLibrary(hinstDll);
+ }
+ return dwVersion;
+}
+
+#endif
+
+bool g_LVN_ITEMACTIVATE_Support = true;
+
+static const wchar_t *kUnknownExceptionMessage = L"ERROR: Unknown Error!";
+
+void ErrorMessageForHRESULT(HRESULT res)
+{
+ ShowErrorMessage(HResultToMessage(res));
+}
+
+int APIENTRY WinMain2()
+{
+ // OleInitialize is required for ProgressBar in TaskBar.
+ #ifndef UNDER_CE
+ OleInitialize(NULL);
+ #endif
+
+ #ifndef UNDER_CE
+ g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll"));
+ g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4));
+ #endif
+
+ UString password;
+ bool assumeYes = false;
+ bool outputFolderDefined = false;
+ FString outputFolder;
+ UStringVector commandStrings;
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
+
+ #ifndef UNDER_CE
+ if (commandStrings.Size() > 0)
+ commandStrings.Delete(0);
+ #endif
+
+ FOR_VECTOR (i, commandStrings)
+ {
+ const UString &s = commandStrings[i];
+ if (s.Len() > 1 && s[0] == '-')
+ {
+ wchar_t c = MyCharLower_Ascii(s[1]);
+ if (c == 'y')
+ {
+ assumeYes = true;
+ if (s.Len() != 2)
+ {
+ ShowErrorMessage(L"Bad command");
+ return 1;
+ }
+ }
+ else if (c == 'o')
+ {
+ outputFolder = us2fs(s.Ptr(2));
+ NName::NormalizeDirPathPrefix(outputFolder);
+ outputFolderDefined = !outputFolder.IsEmpty();
+ }
+ else if (c == 'p')
+ {
+ password = s.Ptr(2);
+ }
+ }
+ }
+
+ FString path;
+ NDLL::MyGetModuleFileName(path);
+
+ FString fullPath;
+ if (!MyGetFullPathName(path, fullPath))
+ {
+ ShowErrorMessage(L"Error 1329484");
+ return 1;
+ }
+
+ CCodecs *codecs = new CCodecs;
+ CMyComPtr<IUnknown> compressCodecsInfo = codecs;
+ HRESULT result = codecs->Load();
+ if (result != S_OK)
+ {
+ ErrorMessageForHRESULT(result);
+ return 1;
+ }
+
+ // COpenCallbackGUI openCallback;
+
+ // openCallback.PasswordIsDefined = !password.IsEmpty();
+ // openCallback.Password = password;
+
+ CExtractCallbackImp *ecs = new CExtractCallbackImp;
+ CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
+ ecs->Init();
+
+ #ifndef _NO_CRYPTO
+ ecs->PasswordIsDefined = !password.IsEmpty();
+ ecs->Password = password;
+ #endif
+
+ CExtractOptions eo;
+
+ FString dirPrefix;
+ if (!GetOnlyDirPrefix(path, dirPrefix))
+ {
+ ShowErrorMessage(L"Error 1329485");
+ return 1;
+ }
+
+ eo.OutputDir = outputFolderDefined ? outputFolder : dirPrefix;
+ eo.YesToAll = assumeYes;
+ eo.OverwriteMode = assumeYes ?
+ NExtract::NOverwriteMode::kOverwrite :
+ NExtract::NOverwriteMode::kAsk;
+ eo.PathMode = NExtract::NPathMode::kFullPaths;
+ eo.TestMode = false;
+
+ UStringVector v1, v2;
+ v1.Add(fs2us(fullPath));
+ v2.Add(fs2us(fullPath));
+ NWildcard::CCensorNode wildcardCensor;
+ wildcardCensor.AddItem(true, L"*", true, true, true, true);
+
+ bool messageWasDisplayed = false;
+ result = ExtractGUI(codecs,
+ CObjectVector<COpenType>(), CIntVector(),
+ v1, v2,
+ wildcardCensor, eo, (assumeYes ? false: true), messageWasDisplayed, ecs);
+
+ if (result == S_OK)
+ {
+ if (!ecs->IsOK())
+ return NExitCode::kFatalError;
+ return 0;
+ }
+ if (result == E_ABORT)
+ return NExitCode::kUserBreak;
+ if (!messageWasDisplayed)
+ {
+ if (result == S_FALSE)
+ ShowErrorMessage(L"Error in archive");
+ else
+ ErrorMessageForHRESULT(result);
+ }
+ if (result == E_OUTOFMEMORY)
+ return NExitCode::kMemoryError;
+ return NExitCode::kFatalError;
+}
+
+#define NT_CHECK_FAIL_ACTION ShowErrorMessage(L"Unsupported Windows version"); return NExitCode::kFatalError;
+
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
+ #ifdef UNDER_CE
+ LPWSTR
+ #else
+ LPSTR
+ #endif
+ /* lpCmdLine */, int /* nCmdShow */)
+{
+ g_hInstance = (HINSTANCE)hInstance;
+
+ NT_CHECK
+
+ try
+ {
+ return WinMain2();
+ }
+ catch(const CNewException &)
+ {
+ ErrorMessageForHRESULT(E_OUTOFMEMORY);
+ return NExitCode::kMemoryError;
+ }
+ catch(...)
+ {
+ ShowErrorMessage(kUnknownExceptionMessage);
+ return NExitCode::kFatalError;
+ }
+}
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/StdAfx.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/StdAfx.cpp
new file mode 100644
index 00000000000..d0feea85c7b
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/StdAfx.h
new file mode 100644
index 00000000000..975a17e8bf7
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/StdAfx.h
@@ -0,0 +1,14 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/Common.h"
+
+#include <commctrl.h>
+#include <ShlObj.h>
+
+// #define printf(x) NO_PRINTF_(x)
+// #define sprintf(x) NO_SPRINTF_(x)
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/makefile b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/makefile
new file mode 100644
index 00000000000..0ffec922d58
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/makefile
@@ -0,0 +1,146 @@
+PROG = 7z.sfx
+CFLAGS = $(CFLAGS) \
+ -DNO_REGISTRY \
+ -DEXTRACT_ONLY \
+ -DNO_READ_FROM_CODER \
+ -D_SFX \
+
+!IFDEF UNDER_CE
+LIBS = $(LIBS) ceshell.lib Commctrl.lib
+!ELSE
+LIBS = $(LIBS) comctl32.lib comdlg32.lib
+!ENDIF
+
+CURRENT_OBJS = \
+ $O\SfxWin.obj \
+
+GUI_OBJS = \
+ $O\ExtractDialog.obj \
+ $O\ExtractGUI.obj \
+
+COMMON_OBJS = \
+ $O\CRC.obj \
+ $O\CommandLineParser.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\MyString.obj \
+ $O\StringConvert.obj \
+ $O\MyVector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\CommonDialog.obj \
+ $O\DLL.obj \
+ $O\ErrorMsg.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConv.obj \
+ $O\ResourceString.obj \
+ $O\Shell.obj \
+ $O\Synchronization.obj \
+ $O\Window.obj \
+
+WIN_CTRL_OBJS = \
+ $O\ComboBox.obj \
+ $O\Dialog.obj \
+ $O\ListView.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\CreateCoder.obj \
+ $O\CWrappers.obj \
+ $O\FilePathAutoRename.obj \
+ $O\FileStreams.obj \
+ $O\InBuffer.obj \
+ $O\FilterCoder.obj \
+ $O\LimitedStreams.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\PropId.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+ $O\VirtThread.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveExtractCallback.obj \
+ $O\ArchiveOpenCallback.obj \
+ $O\DefaultName.obj \
+ $O\Extract.obj \
+ $O\ExtractingFilePath.obj \
+ $O\LoadCodecs.obj \
+ $O\OpenArchive.obj \
+
+EXPLORER_OBJS = \
+ $O\MyMessages.obj \
+
+FM_OBJS = \
+ $O\BrowseDialog.obj \
+ $O\ComboDialog.obj \
+ $O\ExtractCallback.obj \
+ $O\FormatUtils.obj \
+ $O\OverwriteDialog.obj \
+ $O\PasswordDialog.obj \
+ $O\ProgressDialog2.obj \
+ $O\PropertyName.obj \
+ $O\SysIconUtils.obj \
+
+AR_OBJS = \
+ $O\SplitHandler.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\ItemNameUtils.obj \
+ $O\MultiStream.obj \
+ $O\OutStreamWithCRC.obj \
+
+7Z_OBJS = \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zHandler.obj \
+ $O\7zIn.obj \
+ $O\7zRegister.obj \
+
+COMPRESS_OBJS = \
+ $O\Bcj2Coder.obj \
+ $O\Bcj2Register.obj \
+ $O\BcjCoder.obj \
+ $O\BcjRegister.obj \
+ $O\BranchMisc.obj \
+ $O\BranchRegister.obj \
+ $O\CopyCoder.obj \
+ $O\CopyRegister.obj \
+ $O\DeltaFilter.obj \
+ $O\Lzma2Decoder.obj \
+ $O\Lzma2Register.obj \
+ $O\LzmaDecoder.obj \
+ $O\LzmaRegister.obj \
+ $O\PpmdDecoder.obj \
+ $O\PpmdRegister.obj \
+
+CRYPTO_OBJS = \
+ $O\7zAes.obj \
+ $O\7zAesRegister.obj \
+ $O\MyAes.obj \
+
+C_OBJS = \
+ $O\Alloc.obj \
+ $O\Bcj2.obj \
+ $O\Bra.obj \
+ $O\Bra86.obj \
+ $O\BraIA64.obj \
+ $O\Delta.obj \
+ $O\CpuArch.obj \
+ $O\Lzma2Dec.obj \
+ $O\LzmaDec.obj \
+ $O\Ppmd7.obj \
+ $O\Ppmd7Dec.obj \
+ $O\Sha256.obj \
+ $O\Threads.obj \
+
+!include "../../Aes.mak"
+!include "../../Crc.mak"
+
+!include "../../7zip.mak"
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/resource.h b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/resource.h
new file mode 100644
index 00000000000..30fe2030e1d
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/resource.h
@@ -0,0 +1 @@
+#define IDI_ICON 1
diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/resource.rc b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/resource.rc
new file mode 100644
index 00000000000..91292b2f11a
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/resource.rc
@@ -0,0 +1,50 @@
+#include "../../MyVersionInfo.rc"
+#include "../../GuiCommon.rc"
+#include "../../UI/GUI/ExtractDialogRes.h"
+#include "../../UI/FileManager/PropertyNameRes.h"
+
+#include "resource.h"
+
+MY_VERSION_INFO_APP("7z SFX", "7z.sfx")
+
+#define xc 240
+#define yc 64
+
+IDI_ICON ICON "7z.ico"
+
+IDD_EXTRACT DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT
+CAPTION "7-Zip self-extracting archive"
+BEGIN
+ LTEXT "E&xtract to:", IDT_EXTRACT_EXTRACT_TO, m, m, xc, 8
+ EDITTEXT IDC_EXTRACT_PATH, m, 21, xc - bxsDots - 12, 14, ES_AUTOHSCROLL
+ PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, 20, bxsDots, bys, WS_GROUP
+ DEFPUSHBUTTON "Extract", IDOK, bx2, by, bxs, bys, WS_GROUP
+ PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
+END
+
+#ifdef UNDER_CE
+
+#undef xc
+#define xc 144
+
+IDD_EXTRACT_2 DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT
+CAPTION "7-Zip self-extracting archive"
+BEGIN
+ LTEXT "E&xtract to:", IDT_EXTRACT_EXTRACT_TO, m, m, xc - bxsDots - 12, 8
+ EDITTEXT IDC_EXTRACT_PATH, m, m + bys + 4, xc, 14, ES_AUTOHSCROLL
+ PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, m, bxsDots, bys, WS_GROUP
+ DEFPUSHBUTTON "Extract", IDOK, bx2, by, bxs, bys, WS_GROUP
+ PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
+END
+
+#endif
+
+#include "../../UI/FileManager/OverwriteDialog.rc"
+#include "../../UI/FileManager/PasswordDialog.rc"
+#include "../../UI/FileManager/ProgressDialog2.rc"
+#include "../../UI/GUI/Extract.rc"
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PROP_MTIME "Modified"
+END
diff --git a/3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp b/3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp
index ef21228e45b..a77b67e8664 100644
--- a/3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp
@@ -12,14 +12,14 @@
#define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x)
-static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize)
+static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize) throw()
{
CCompressProgressWrap *p = (CCompressProgressWrap *)pp;
p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize));
return (SRes)p->Res;
}
-CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress)
+CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress) throw()
{
p.Progress = CompressProgress;
Progress = progress;
@@ -30,7 +30,7 @@ static const UInt32 kStreamStepSize = (UInt32)1 << 31;
SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes)
{
- switch(res)
+ switch (res)
{
case S_OK: return SZ_OK;
case E_OUTOFMEMORY: return SZ_ERROR_MEM;
@@ -42,18 +42,19 @@ SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes)
return defaultRes;
}
-static SRes MyRead(void *object, void *data, size_t *size)
+static SRes MyRead(void *object, void *data, size_t *size) throw()
{
CSeqInStreamWrap *p = (CSeqInStreamWrap *)object;
UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
p->Res = (p->Stream->Read(data, curSize, &curSize));
*size = curSize;
+ p->Processed += curSize;
if (p->Res == S_OK)
return SZ_OK;
return HRESULT_To_SRes(p->Res, SZ_ERROR_READ);
}
-static size_t MyWrite(void *object, const void *data, size_t size)
+static size_t MyWrite(void *object, const void *data, size_t size) throw()
{
CSeqOutStreamWrap *p = (CSeqOutStreamWrap *)object;
if (p->Stream)
@@ -68,13 +69,14 @@ static size_t MyWrite(void *object, const void *data, size_t size)
return size;
}
-CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream)
+CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream) throw()
{
p.Read = MyRead;
Stream = stream;
+ Processed = 0;
}
-CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream)
+CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw()
{
p.Write = MyWrite;
Stream = stream;
@@ -82,9 +84,9 @@ CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream)
Processed = 0;
}
-HRESULT SResToHRESULT(SRes res)
+HRESULT SResToHRESULT(SRes res) throw()
{
- switch(res)
+ switch (res)
{
case SZ_OK: return S_OK;
case SZ_ERROR_MEM: return E_OUTOFMEMORY;
@@ -96,7 +98,7 @@ HRESULT SResToHRESULT(SRes res)
return E_FAIL;
}
-static SRes InStreamWrap_Read(void *pp, void *data, size_t *size)
+static SRes InStreamWrap_Read(void *pp, void *data, size_t *size) throw()
{
CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;
UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
@@ -105,11 +107,11 @@ static SRes InStreamWrap_Read(void *pp, void *data, size_t *size)
return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
}
-static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin)
+static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw()
{
CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;
UInt32 moveMethod;
- switch(origin)
+ switch (origin)
{
case SZ_SEEK_SET: moveMethod = STREAM_SEEK_SET; break;
case SZ_SEEK_CUR: moveMethod = STREAM_SEEK_CUR; break;
@@ -122,7 +124,7 @@ static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin)
return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
}
-CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream)
+CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw()
{
Stream = stream;
p.Read = InStreamWrap_Read;
@@ -133,13 +135,13 @@ CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream)
/* ---------- CByteInBufWrap ---------- */
-void CByteInBufWrap::Free()
+void CByteInBufWrap::Free() throw()
{
::MidFree(Buf);
Buf = 0;
}
-bool CByteInBufWrap::Alloc(UInt32 size)
+bool CByteInBufWrap::Alloc(UInt32 size) throw()
{
if (Buf == 0 || size != Size)
{
@@ -150,7 +152,7 @@ bool CByteInBufWrap::Alloc(UInt32 size)
return (Buf != 0);
}
-Byte CByteInBufWrap::ReadByteFromNewBlock()
+Byte CByteInBufWrap::ReadByteFromNewBlock() throw()
{
if (Res == S_OK)
{
@@ -166,7 +168,7 @@ Byte CByteInBufWrap::ReadByteFromNewBlock()
return 0;
}
-static Byte Wrap_ReadByte(void *pp)
+static Byte Wrap_ReadByte(void *pp) throw()
{
CByteInBufWrap *p = (CByteInBufWrap *)pp;
if (p->Cur != p->Lim)
@@ -182,13 +184,13 @@ CByteInBufWrap::CByteInBufWrap(): Buf(0)
/* ---------- CByteOutBufWrap ---------- */
-void CByteOutBufWrap::Free()
+void CByteOutBufWrap::Free() throw()
{
::MidFree(Buf);
Buf = 0;
}
-bool CByteOutBufWrap::Alloc(size_t size)
+bool CByteOutBufWrap::Alloc(size_t size) throw()
{
if (Buf == 0 || size != Size)
{
@@ -199,7 +201,7 @@ bool CByteOutBufWrap::Alloc(size_t size)
return (Buf != 0);
}
-HRESULT CByteOutBufWrap::Flush()
+HRESULT CByteOutBufWrap::Flush() throw()
{
if (Res == S_OK)
{
@@ -212,7 +214,7 @@ HRESULT CByteOutBufWrap::Flush()
return Res;
}
-static void Wrap_WriteByte(void *pp, Byte b)
+static void Wrap_WriteByte(void *pp, Byte b) throw()
{
CByteOutBufWrap *p = (CByteOutBufWrap *)pp;
Byte *dest = p->Cur;
@@ -222,7 +224,7 @@ static void Wrap_WriteByte(void *pp, Byte b)
p->Flush();
}
-CByteOutBufWrap::CByteOutBufWrap(): Buf(0)
+CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0)
{
p.Write = Wrap_WriteByte;
}
diff --git a/3rdparty/lzma/CPP/7zip/Common/CWrappers.h b/3rdparty/lzma/CPP/7zip/Common/CWrappers.h
index 80a8a1b6113..acadc170edc 100644
--- a/3rdparty/lzma/CPP/7zip/Common/CWrappers.h
+++ b/3rdparty/lzma/CPP/7zip/Common/CWrappers.h
@@ -11,7 +11,8 @@ struct CCompressProgressWrap
ICompressProgress p;
ICompressProgressInfo *Progress;
HRESULT Res;
- CCompressProgressWrap(ICompressProgressInfo *progress);
+
+ CCompressProgressWrap(ICompressProgressInfo *progress) throw();
};
struct CSeqInStreamWrap
@@ -19,7 +20,9 @@ struct CSeqInStreamWrap
ISeqInStream p;
ISequentialInStream *Stream;
HRESULT Res;
- CSeqInStreamWrap(ISequentialInStream *stream);
+ UInt64 Processed;
+
+ CSeqInStreamWrap(ISequentialInStream *stream) throw();
};
struct CSeekInStreamWrap
@@ -27,7 +30,8 @@ struct CSeekInStreamWrap
ISeekInStream p;
IInStream *Stream;
HRESULT Res;
- CSeekInStreamWrap(IInStream *stream);
+
+ CSeekInStreamWrap(IInStream *stream) throw();
};
struct CSeqOutStreamWrap
@@ -36,10 +40,11 @@ struct CSeqOutStreamWrap
ISequentialOutStream *Stream;
HRESULT Res;
UInt64 Processed;
- CSeqOutStreamWrap(ISequentialOutStream *stream);
+
+ CSeqOutStreamWrap(ISequentialOutStream *stream) throw();
};
-HRESULT SResToHRESULT(SRes res);
+HRESULT SResToHRESULT(SRes res) throw();
struct CByteInBufWrap
{
@@ -54,9 +59,9 @@ struct CByteInBufWrap
HRESULT Res;
CByteInBufWrap();
- ~CByteInBufWrap() { Free(); }
- void Free();
- bool Alloc(UInt32 size);
+ ~CByteInBufWrap() { Free(); }
+ void Free() throw();
+ bool Alloc(UInt32 size) throw();
void Init()
{
Lim = Cur = Buf;
@@ -65,7 +70,7 @@ struct CByteInBufWrap
Res = S_OK;
}
UInt64 GetProcessed() const { return Processed + (Cur - Buf); }
- Byte ReadByteFromNewBlock();
+ Byte ReadByteFromNewBlock() throw();
Byte ReadByte()
{
if (Cur != Lim)
@@ -85,10 +90,10 @@ struct CByteOutBufWrap
UInt64 Processed;
HRESULT Res;
- CByteOutBufWrap();
- ~CByteOutBufWrap() { Free(); }
- void Free();
- bool Alloc(size_t size);
+ CByteOutBufWrap() throw();
+ ~CByteOutBufWrap() { Free(); }
+ void Free() throw();
+ bool Alloc(size_t size) throw();
void Init()
{
Cur = Buf;
@@ -97,7 +102,7 @@ struct CByteOutBufWrap
Res = S_OK;
}
UInt64 GetProcessed() const { return Processed + (Cur - Buf); }
- HRESULT Flush();
+ HRESULT Flush() throw();
void WriteByte(Byte b)
{
*Cur++ = b;
diff --git a/3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp b/3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp
index cc82a0db531..75074ad891f 100644
--- a/3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp
@@ -10,16 +10,40 @@
#include "FilterCoder.h"
#include "RegisterCodec.h"
-static const unsigned int kNumCodecsMax = 64;
-unsigned int g_NumCodecs = 0;
+static const unsigned kNumCodecsMax = 64;
+unsigned g_NumCodecs = 0;
const CCodecInfo *g_Codecs[kNumCodecsMax];
-void RegisterCodec(const CCodecInfo *codecInfo)
+
+// We use g_ExternalCodecs in other stages.
+/*
+#ifdef EXTERNAL_CODECS
+extern CExternalCodecs g_ExternalCodecs;
+#define CHECK_GLOBAL_CODECS \
+ if (!__externalCodecs || !__externalCodecs->IsSet()) __externalCodecs = &g_ExternalCodecs;
+#endif
+*/
+
+#define CHECK_GLOBAL_CODECS
+
+void RegisterCodec(const CCodecInfo *codecInfo) throw()
{
if (g_NumCodecs < kNumCodecsMax)
g_Codecs[g_NumCodecs++] = codecInfo;
}
+static const unsigned kNumHashersMax = 16;
+unsigned g_NumHashers = 0;
+const CHasherInfo *g_Hashers[kNumHashersMax];
+
+void RegisterHasher(const CHasherInfo *hashInfo) throw()
+{
+ if (g_NumHashers < kNumHashersMax)
+ g_Hashers[g_NumHashers++] = hashInfo;
+}
+
+
#ifdef EXTERNAL_CODECS
+
static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res)
{
NWindows::NCOM::CPropVariant prop;
@@ -46,87 +70,130 @@ static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index,
return S_OK;
}
-HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs)
+HRESULT CExternalCodecs::Load()
{
- UInt32 num;
- RINOK(codecsInfo->GetNumberOfMethods(&num));
- for (UInt32 i = 0; i < num; i++)
+ Codecs.Clear();
+ Hashers.Clear();
+
+ if (GetCodecs)
{
CCodecInfoEx info;
- NWindows::NCOM::CPropVariant prop;
- RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop));
- // if (prop.vt != VT_BSTR)
- // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);
- // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize);
- if (prop.vt != VT_UI8)
- {
- continue; // old Interface
- // return E_INVALIDARG;
- }
- info.Id = prop.uhVal.QuadPart;
- prop.Clear();
- RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop));
- if (prop.vt == VT_BSTR)
- info.Name = prop.bstrVal;
- else if (prop.vt != VT_EMPTY)
- return E_INVALIDARG;;
+ UString s;
+ UInt32 num;
+ RINOK(GetCodecs->GetNumMethods(&num));
- RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams));
- RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams));
- RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
- RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
+ for (UInt32 i = 0; i < num; i++)
+ {
+ NWindows::NCOM::CPropVariant prop;
+
+ RINOK(GetCodecs->GetProperty(i, NMethodPropID::kID, &prop));
+ if (prop.vt != VT_UI8)
+ continue; // old Interface
+ info.Id = prop.uhVal.QuadPart;
+
+ prop.Clear();
+
+ info.Name.Empty();
+ RINOK(GetCodecs->GetProperty(i, NMethodPropID::kName, &prop));
+ if (prop.vt == VT_BSTR)
+ info.Name.SetFromWStr_if_Ascii(prop.bstrVal);
+ else if (prop.vt != VT_EMPTY)
+ continue;
+
+ RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kPackStreams, info.NumStreams));
+ {
+ UInt32 numUnpackStreams = 1;
+ RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kUnpackStreams, numUnpackStreams));
+ if (numUnpackStreams != 1)
+ continue;
+ }
+ RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
+ RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
+
+ Codecs.Add(info);
+ }
+ }
+
+ if (GetHashers)
+ {
+ UInt32 num = GetHashers->GetNumHashers();
+ CHasherInfoEx info;
- externalCodecs.Add(info);
+ for (UInt32 i = 0; i < num; i++)
+ {
+ NWindows::NCOM::CPropVariant prop;
+
+ RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kID, &prop));
+ if (prop.vt != VT_UI8)
+ continue;
+ info.Id = prop.uhVal.QuadPart;
+
+ prop.Clear();
+
+ info.Name.Empty();
+ RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kName, &prop));
+ if (prop.vt == VT_BSTR)
+ info.Name.SetFromWStr_if_Ascii(prop.bstrVal);
+ else if (prop.vt != VT_EMPTY)
+ continue;
+
+ Hashers.Add(info);
+ }
}
+
return S_OK;
}
#endif
+
bool FindMethod(
- #ifdef EXTERNAL_CODECS
- ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
- #endif
- const UString &name,
- CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const AString &name,
+ CMethodId &methodId, UInt32 &numStreams)
{
- UInt32 i;
+ unsigned i;
for (i = 0; i < g_NumCodecs; i++)
{
const CCodecInfo &codec = *g_Codecs[i];
- if (name.CompareNoCase(codec.Name) == 0)
+ if (StringsAreEqualNoCase_Ascii(name, codec.Name))
{
methodId = codec.Id;
- numInStreams = codec.NumInStreams;
- numOutStreams = 1;
+ numStreams = codec.NumStreams;
return true;
}
}
+
#ifdef EXTERNAL_CODECS
- if (externalCodecs)
- for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+
+ CHECK_GLOBAL_CODECS
+
+ if (__externalCodecs)
+ for (i = 0; i < __externalCodecs->Codecs.Size(); i++)
{
- const CCodecInfoEx &codec = (*externalCodecs)[i];
- if (codec.Name.CompareNoCase(name) == 0)
+ const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
+ if (StringsAreEqualNoCase_Ascii(name, codec.Name))
{
methodId = codec.Id;
- numInStreams = codec.NumInStreams;
- numOutStreams = codec.NumOutStreams;
+ numStreams = codec.NumStreams;
return true;
}
}
+
#endif
+
return false;
}
bool FindMethod(
- #ifdef EXTERNAL_CODECS
- ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
- #endif
- CMethodId methodId, UString &name)
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ AString &name)
{
- UInt32 i;
+ name.Empty();
+
+ unsigned i;
for (i = 0; i < g_NumCodecs; i++)
{
const CCodecInfo &codec = *g_Codecs[i];
@@ -136,31 +203,94 @@ bool FindMethod(
return true;
}
}
+
#ifdef EXTERNAL_CODECS
- if (externalCodecs)
- for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+
+ CHECK_GLOBAL_CODECS
+
+ if (__externalCodecs)
+ for (i = 0; i < __externalCodecs->Codecs.Size(); i++)
{
- const CCodecInfoEx &codec = (*externalCodecs)[i];
+ const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
if (methodId == codec.Id)
{
name = codec.Name;
return true;
}
}
+
#endif
+
return false;
}
+bool FindHashMethod(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const AString &name,
+ CMethodId &methodId)
+{
+ unsigned i;
+ for (i = 0; i < g_NumHashers; i++)
+ {
+ const CHasherInfo &codec = *g_Hashers[i];
+ if (StringsAreEqualNoCase_Ascii(name, codec.Name))
+ {
+ methodId = codec.Id;
+ return true;
+ }
+ }
+
+ #ifdef EXTERNAL_CODECS
+
+ CHECK_GLOBAL_CODECS
+
+ if (__externalCodecs)
+ for (i = 0; i < __externalCodecs->Hashers.Size(); i++)
+ {
+ const CHasherInfoEx &codec = __externalCodecs->Hashers[i];
+ if (StringsAreEqualNoCase_Ascii(name, codec.Name))
+ {
+ methodId = codec.Id;
+ return true;
+ }
+ }
+
+ #endif
+
+ return false;
+}
+
+void GetHashMethods(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CRecordVector<CMethodId> &methods)
+{
+ methods.ClearAndSetSize(g_NumHashers);
+ unsigned i;
+ for (i = 0; i < g_NumHashers; i++)
+ methods[i] = (*g_Hashers[i]).Id;
+
+ #ifdef EXTERNAL_CODECS
+
+ CHECK_GLOBAL_CODECS
+
+ if (__externalCodecs)
+ for (i = 0; i < __externalCodecs->Hashers.Size(); i++)
+ methods.Add(__externalCodecs->Hashers[i].Id);
+
+ #endif
+}
+
HRESULT CreateCoder(
- DECL_EXTERNAL_CODECS_LOC_VARS
- CMethodId methodId,
- CMyComPtr<ICompressFilter> &filter,
- CMyComPtr<ICompressCoder> &coder,
- CMyComPtr<ICompressCoder2> &coder2,
- bool encode, bool onlyCoder)
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, bool encode,
+ CMyComPtr<ICompressFilter> &filter,
+ CCreatedCoder &cod)
{
- bool created = false;
- UInt32 i;
+ cod.IsExternal = false;
+ cod.IsFilter = false;
+ cod.NumStreams = 1;
+
+ unsigned i;
for (i = 0; i < g_NumCodecs; i++)
{
const CCodecInfo &codec = *g_Codecs[i];
@@ -172,10 +302,9 @@ HRESULT CreateCoder(
{
void *p = codec.CreateEncoder();
if (codec.IsFilter) filter = (ICompressFilter *)p;
- else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
- else coder2 = (ICompressCoder2 *)p;
- created = (p != 0);
- break;
+ else if (codec.NumStreams == 1) cod.Coder = (ICompressCoder *)p;
+ else { cod.Coder2 = (ICompressCoder2 *)p; cod.NumStreams = codec.NumStreams; }
+ return S_OK;
}
}
else
@@ -183,111 +312,150 @@ HRESULT CreateCoder(
{
void *p = codec.CreateDecoder();
if (codec.IsFilter) filter = (ICompressFilter *)p;
- else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
- else coder2 = (ICompressCoder2 *)p;
- created = (p != 0);
- break;
+ else if (codec.NumStreams == 1) cod.Coder = (ICompressCoder *)p;
+ else { cod.Coder2 = (ICompressCoder2 *)p; cod.NumStreams = codec.NumStreams; }
+ return S_OK;
}
}
}
#ifdef EXTERNAL_CODECS
- if (!created && externalCodecs)
- for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+
+ CHECK_GLOBAL_CODECS
+
+ if (__externalCodecs)
+ {
+ cod.IsExternal = true;
+ for (i = 0; i < __externalCodecs->Codecs.Size(); i++)
{
- const CCodecInfoEx &codec = (*externalCodecs)[i];
+ const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
if (codec.Id == methodId)
{
if (encode)
{
if (codec.EncoderIsAssigned)
{
- if (codec.IsSimpleCodec())
+ if (codec.NumStreams == 1)
{
- HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);
- if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
- return result;
- if (!coder)
- {
- RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));
- }
+ HRESULT res = __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder, (void **)&cod.Coder);
+ if (res != S_OK && res != E_NOINTERFACE && res != CLASS_E_CLASSNOTAVAILABLE)
+ return res;
+ if (cod.Coder)
+ return res;
+ return __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter);
}
- else
- {
- RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));
- }
- break;
+ cod.NumStreams = codec.NumStreams;
+ return __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2);
}
}
else
if (codec.DecoderIsAssigned)
{
- if (codec.IsSimpleCodec())
+ if (codec.NumStreams == 1)
{
- HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);
- if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
- return result;
- if (!coder)
- {
- RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));
- }
+ HRESULT res = __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder, (void **)&cod.Coder);
+ if (res != S_OK && res != E_NOINTERFACE && res != CLASS_E_CLASSNOTAVAILABLE)
+ return res;
+ if (cod.Coder)
+ return res;
+ return __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter);
}
- else
- {
- RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2));
- }
- break;
+ cod.NumStreams = codec.NumStreams;
+ return __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2);
}
}
}
+ }
#endif
- if (onlyCoder && filter)
- {
- CFilterCoder *coderSpec = new CFilterCoder;
- coder = coderSpec;
- coderSpec->Filter = filter;
- }
return S_OK;
}
HRESULT CreateCoder(
- DECL_EXTERNAL_CODECS_LOC_VARS
- CMethodId methodId,
- CMyComPtr<ICompressCoder> &coder,
- CMyComPtr<ICompressCoder2> &coder2,
- bool encode)
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, bool encode,
+ CCreatedCoder &cod)
{
CMyComPtr<ICompressFilter> filter;
- return CreateCoder(
- EXTERNAL_CODECS_LOC_VARS
- methodId,
- filter, coder, coder2, encode, true);
+ HRESULT res = CreateCoder(
+ EXTERNAL_CODECS_LOC_VARS
+ methodId, encode,
+ filter, cod);
+
+ if (filter)
+ {
+ cod.IsFilter = true;
+ CFilterCoder *coderSpec = new CFilterCoder(encode);
+ cod.Coder = coderSpec;
+ coderSpec->Filter = filter;
+ }
+
+ return res;
}
HRESULT CreateCoder(
- DECL_EXTERNAL_CODECS_LOC_VARS
- CMethodId methodId,
- CMyComPtr<ICompressCoder> &coder, bool encode)
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, bool encode,
+ CMyComPtr<ICompressCoder> &coder)
{
- CMyComPtr<ICompressFilter> filter;
- CMyComPtr<ICompressCoder2> coder2;
- return CreateCoder(
- EXTERNAL_CODECS_LOC_VARS
- methodId,
- coder, coder2, encode);
+ CCreatedCoder cod;
+ HRESULT res = CreateCoder(
+ EXTERNAL_CODECS_LOC_VARS
+ methodId, encode,
+ cod);
+ coder = cod.Coder;
+ return res;
}
HRESULT CreateFilter(
- DECL_EXTERNAL_CODECS_LOC_VARS
- CMethodId methodId,
- CMyComPtr<ICompressFilter> &filter,
- bool encode)
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, bool encode,
+ CMyComPtr<ICompressFilter> &filter)
{
- CMyComPtr<ICompressCoder> coder;
- CMyComPtr<ICompressCoder2> coder2;
+ CCreatedCoder cod;
return CreateCoder(
- EXTERNAL_CODECS_LOC_VARS
- methodId,
- filter, coder, coder2, encode, false);
+ EXTERNAL_CODECS_LOC_VARS
+ methodId, encode,
+ filter, cod);
+}
+
+
+HRESULT CreateHasher(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ AString &name,
+ CMyComPtr<IHasher> &hasher)
+{
+ name.Empty();
+
+ unsigned i;
+ for (i = 0; i < g_NumHashers; i++)
+ {
+ const CHasherInfo &codec = *g_Hashers[i];
+ if (codec.Id == methodId)
+ {
+ hasher = codec.CreateHasher();
+ name = codec.Name;
+ break;
+ }
+ }
+
+ #ifdef EXTERNAL_CODECS
+
+ CHECK_GLOBAL_CODECS
+
+ if (!hasher && __externalCodecs)
+ for (i = 0; i < __externalCodecs->Hashers.Size(); i++)
+ {
+ const CHasherInfoEx &codec = __externalCodecs->Hashers[i];
+ if (codec.Id == methodId)
+ {
+ name = codec.Name;
+ return __externalCodecs->GetHashers->CreateHasher((UInt32)i, &hasher);
+ }
+ }
+
+ #endif
+
+ return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/Common/CreateCoder.h b/3rdparty/lzma/CPP/7zip/Common/CreateCoder.h
index bf0e96a38ad..f06064b6a6f 100644
--- a/3rdparty/lzma/CPP/7zip/Common/CreateCoder.h
+++ b/3rdparty/lzma/CPP/7zip/Common/CreateCoder.h
@@ -5,41 +5,95 @@
#include "../../Common/MyCom.h"
#include "../../Common/MyString.h"
+
#include "../ICoder.h"
#include "MethodId.h"
+/*
+ if EXTERNAL_CODECS is not defined, the code supports only codecs that
+ are statically linked at compile-time and link-time.
+
+ if EXTERNAL_CODECS is defined, the code supports also codecs from another
+ executable modules, that can be linked dynamically at run-time:
+ - EXE module can use codecs from external DLL files.
+ - DLL module can use codecs from external EXE and DLL files.
+
+ CExternalCodecs contains information about codecs and interfaces to create them.
+
+ The order of codecs:
+ 1) Internal codecs
+ 2) External codecs
+*/
+
#ifdef EXTERNAL_CODECS
struct CCodecInfoEx
{
- UString Name;
CMethodId Id;
- UInt32 NumInStreams;
- UInt32 NumOutStreams;
+ AString Name;
+ UInt32 NumStreams;
bool EncoderIsAssigned;
bool DecoderIsAssigned;
- bool IsSimpleCodec() const { return NumOutStreams == 1 && NumInStreams == 1; }
+
CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {}
};
-HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs);
+struct CHasherInfoEx
+{
+ CMethodId Id;
+ AString Name;
+};
#define PUBLIC_ISetCompressCodecsInfo public ISetCompressCodecsInfo,
#define QUERY_ENTRY_ISetCompressCodecsInfo MY_QUERYINTERFACE_ENTRY(ISetCompressCodecsInfo)
#define DECL_ISetCompressCodecsInfo STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo);
#define IMPL_ISetCompressCodecsInfo2(x) \
STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) { \
- COM_TRY_BEGIN _codecsInfo = compressCodecsInfo; return LoadExternalCodecs(_codecsInfo, _externalCodecs); COM_TRY_END }
+ COM_TRY_BEGIN __externalCodecs.GetCodecs = compressCodecsInfo; return __externalCodecs.Load(); COM_TRY_END }
#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler)
-#define EXTERNAL_CODECS_VARS2 _codecsInfo, &_externalCodecs
+struct CExternalCodecs
+{
+ CMyComPtr<ICompressCodecsInfo> GetCodecs;
+ CMyComPtr<IHashers> GetHashers;
+
+ CObjectVector<CCodecInfoEx> Codecs;
+ CObjectVector<CHasherInfoEx> Hashers;
+
+ bool IsSet() const { return GetCodecs != NULL || GetHashers != NULL; }
+
+ HRESULT Load();
+
+ void ClearAndRelease()
+ {
+ Hashers.Clear();
+ Codecs.Clear();
+ GetHashers.Release();
+ GetCodecs.Release();
+ }
+
+ ~CExternalCodecs()
+ {
+ GetHashers.Release();
+ GetCodecs.Release();
+ }
+};
+
+extern CExternalCodecs g_ExternalCodecs;
+
+#define EXTERNAL_CODECS_VARS2 (__externalCodecs.IsSet() ? &__externalCodecs : &g_ExternalCodecs)
+#define EXTERNAL_CODECS_VARS2_L (&__externalCodecs)
+#define EXTERNAL_CODECS_VARS2_G (&g_ExternalCodecs)
+
+#define DECL_EXTERNAL_CODECS_VARS CExternalCodecs __externalCodecs;
-#define DECL_EXTERNAL_CODECS_VARS CMyComPtr<ICompressCodecsInfo> _codecsInfo; CObjectVector<CCodecInfoEx> _externalCodecs;
-#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2,
+#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2,
+#define EXTERNAL_CODECS_VARS_L EXTERNAL_CODECS_VARS2_L,
+#define EXTERNAL_CODECS_VARS_G EXTERNAL_CODECS_VARS2_G,
-#define DECL_EXTERNAL_CODECS_LOC_VARS2 ICompressCodecsInfo *codecsInfo, const CObjectVector<CCodecInfoEx> *externalCodecs
-#define EXTERNAL_CODECS_LOC_VARS2 codecsInfo, externalCodecs
+#define DECL_EXTERNAL_CODECS_LOC_VARS2 const CExternalCodecs *__externalCodecs
+#define EXTERNAL_CODECS_LOC_VARS2 __externalCodecs
#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2,
#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2,
@@ -52,7 +106,9 @@ STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) {
#define IMPL_ISetCompressCodecsInfo
#define EXTERNAL_CODECS_VARS2
#define DECL_EXTERNAL_CODECS_VARS
-#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2
+#define EXTERNAL_CODECS_VARS
+#define EXTERNAL_CODECS_VARS_L
+#define EXTERNAL_CODECS_VARS_G
#define DECL_EXTERNAL_CODECS_LOC_VARS2
#define EXTERNAL_CODECS_LOC_VARS2
#define DECL_EXTERNAL_CODECS_LOC_VARS
@@ -60,39 +116,67 @@ STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) {
#endif
+
+
+
bool FindMethod(
- DECL_EXTERNAL_CODECS_LOC_VARS
- const UString &name, CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams);
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const AString &name,
+ CMethodId &methodId, UInt32 &numStreams);
bool FindMethod(
- DECL_EXTERNAL_CODECS_LOC_VARS
- CMethodId methodId, UString &name);
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ AString &name);
+
+bool FindHashMethod(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const AString &name,
+ CMethodId &methodId);
+
+void GetHashMethods(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CRecordVector<CMethodId> &methods);
+
+
+struct CCreatedCoder
+{
+ CMyComPtr<ICompressCoder> Coder;
+ CMyComPtr<ICompressCoder2> Coder2;
+
+ bool IsExternal;
+ bool IsFilter; // = true, if Coder was created from filter
+ UInt32 NumStreams;
+
+ // CCreatedCoder(): IsExternal(false), IsFilter(false), NumStreams(1) {}
+};
HRESULT CreateCoder(
- DECL_EXTERNAL_CODECS_LOC_VARS
- CMethodId methodId,
- CMyComPtr<ICompressFilter> &filter,
- CMyComPtr<ICompressCoder> &coder,
- CMyComPtr<ICompressCoder2> &coder2,
- bool encode, bool onlyCoder);
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, bool encode,
+ CMyComPtr<ICompressFilter> &filter,
+ CCreatedCoder &cod);
HRESULT CreateCoder(
- DECL_EXTERNAL_CODECS_LOC_VARS
- CMethodId methodId,
- CMyComPtr<ICompressCoder> &coder,
- CMyComPtr<ICompressCoder2> &coder2,
- bool encode);
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, bool encode,
+ CCreatedCoder &cod);
HRESULT CreateCoder(
- DECL_EXTERNAL_CODECS_LOC_VARS
- CMethodId methodId,
- CMyComPtr<ICompressCoder> &coder, bool encode);
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, bool encode,
+ CMyComPtr<ICompressCoder> &coder);
HRESULT CreateFilter(
- DECL_EXTERNAL_CODECS_LOC_VARS
- CMethodId methodId,
- CMyComPtr<ICompressFilter> &filter,
- bool encode);
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, bool encode,
+ CMyComPtr<ICompressFilter> &filter);
+
+HRESULT CreateHasher(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ AString &name,
+ CMyComPtr<IHasher> &hasher);
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp b/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp
index 495f886b379..d186e599333 100644
--- a/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp
@@ -2,54 +2,50 @@
#include "StdAfx.h"
-#include "Common/Defs.h"
-#include "Common/IntToString.h"
+#include "../../Common/Defs.h"
+#include "../../Common/IntToString.h"
-#include "Windows/FileFind.h"
+#include "../../Windows/FileFind.h"
#include "FilePathAutoRename.h"
using namespace NWindows;
static bool MakeAutoName(const FString &name,
- const FString &extension, unsigned value, FString &path)
+ const FString &extension, UInt32 value, FString &path)
{
- FChar number[16];
- ConvertUInt32ToString(value, number);
+ char temp[16];
+ ConvertUInt32ToString(value, temp);
path = name;
- path += number;
+ path.AddAscii(temp);
path += extension;
return NFile::NFind::DoesFileOrDirExist(path);
}
-bool AutoRenamePath(FString &fullProcessedPath)
+bool AutoRenamePath(FString &path)
{
- FString path;
- int dotPos = fullProcessedPath.ReverseFind(FTEXT('.'));
+ int dotPos = path.ReverseFind_Dot();
+ int slashPos = path.ReverseFind_PathSepar();
- int slashPos = fullProcessedPath.ReverseFind(FTEXT('/'));
- #ifdef _WIN32
- int slash1Pos = fullProcessedPath.ReverseFind(FTEXT('\\'));
- slashPos = MyMax(slashPos, slash1Pos);
- #endif
-
- FString name, extension;
- if (dotPos > slashPos && dotPos > 0)
+ FString name = path;
+ FString extension;
+ if (dotPos > slashPos + 1)
{
- name = fullProcessedPath.Left(dotPos);
- extension = fullProcessedPath.Mid(dotPos);
+ name.DeleteFrom(dotPos);
+ extension = path.Ptr(dotPos);
}
- else
- name = fullProcessedPath;
- name += L'_';
- unsigned left = 1, right = (1 << 30);
+ name += FTEXT('_');
+
+ FString temp;
+
+ UInt32 left = 1, right = ((UInt32)1 << 30);
while (left != right)
{
- unsigned mid = (left + right) / 2;
- if (MakeAutoName(name, extension, mid, path))
+ UInt32 mid = (left + right) / 2;
+ if (MakeAutoName(name, extension, mid, temp))
left = mid + 1;
else
right = mid;
}
- return !MakeAutoName(name, extension, right, fullProcessedPath);
+ return !MakeAutoName(name, extension, right, path);
}
diff --git a/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h b/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h
index eee0aba7f89..7b576591c9a 100644
--- a/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h
+++ b/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h
@@ -3,7 +3,7 @@
#ifndef __FILE_PATH_AUTO_RENAME_H
#define __FILE_PATH_AUTO_RENAME_H
-#include "Common/MyString.h"
+#include "../../Common/MyString.h"
bool AutoRenamePath(FString &fullProcessedPath);
diff --git a/3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp b/3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp
index a8be8aa46e3..f3a322fc9be 100644
--- a/3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp
@@ -29,24 +29,29 @@ static inline HRESULT ConvertBoolToHRESULT(bool result)
#endif
}
-#ifdef SUPPORT_DEVICE_FILE
static const UInt32 kClusterSize = 1 << 18;
CInFileStream::CInFileStream():
+ #ifdef SUPPORT_DEVICE_FILE
VirtPos(0),
PhyPos(0),
- Buffer(0),
- BufferSize(0)
+ Buf(0),
+ BufSize(0),
+ #endif
+ SupportHardLinks(false),
+ Callback(NULL),
+ CallbackRef(0)
{
}
-#endif
-
CInFileStream::~CInFileStream()
{
#ifdef SUPPORT_DEVICE_FILE
- MidFree(Buffer);
+ MidFree(Buf);
#endif
+
+ if (Callback)
+ Callback->InFileStream_On_Destroy(CallbackRef);
}
STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
@@ -54,41 +59,41 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
#ifdef USE_WIN_FILE
#ifdef SUPPORT_DEVICE_FILE
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
if (size == 0)
return S_OK;
if (File.IsDeviceFile)
{
- if (File.LengthDefined)
+ if (File.SizeDefined)
{
- if (VirtPos >= File.Length)
- return VirtPos == File.Length ? S_OK : E_FAIL;
- UInt64 rem = File.Length - VirtPos;
+ if (VirtPos >= File.Size)
+ return VirtPos == File.Size ? S_OK : E_FAIL;
+ UInt64 rem = File.Size - VirtPos;
if (size > rem)
size = (UInt32)rem;
}
for (;;)
{
const UInt32 mask = kClusterSize - 1;
- UInt64 mask2 = ~(UInt64)mask;
+ const UInt64 mask2 = ~(UInt64)mask;
UInt64 alignedPos = VirtPos & mask2;
- if (BufferSize > 0 && BufferStartPos == alignedPos)
+ if (BufSize > 0 && BufStartPos == alignedPos)
{
UInt32 pos = (UInt32)VirtPos & mask;
- if (pos >= BufferSize)
+ if (pos >= BufSize)
return S_OK;
- UInt32 rem = MyMin(BufferSize - pos, size);
- memcpy(data, Buffer + pos, rem);
+ UInt32 rem = MyMin(BufSize - pos, size);
+ memcpy(data, Buf + pos, rem);
VirtPos += rem;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize += rem;
return S_OK;
}
- bool useBuffer = false;
+ bool useBuf = false;
if ((VirtPos & mask) != 0 || ((ptrdiff_t)data & mask) != 0 )
- useBuffer = true;
+ useBuf = true;
else
{
UInt64 end = VirtPos + size;
@@ -96,12 +101,12 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
end &= mask2;
if (end <= VirtPos)
- useBuffer = true;
+ useBuf = true;
else
size = (UInt32)(end - VirtPos);
}
}
- if (!useBuffer)
+ if (!useBuf)
break;
if (alignedPos != PhyPos)
{
@@ -112,24 +117,24 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
PhyPos = realNewPosition;
}
- BufferStartPos = alignedPos;
+ BufStartPos = alignedPos;
UInt32 readSize = kClusterSize;
- if (File.LengthDefined)
- readSize = (UInt32)MyMin(File.Length - PhyPos, (UInt64)kClusterSize);
+ if (File.SizeDefined)
+ readSize = (UInt32)MyMin(File.Size - PhyPos, (UInt64)kClusterSize);
- if (Buffer == 0)
+ if (!Buf)
{
- Buffer = (Byte *)MidAlloc(kClusterSize);
- if (Buffer == 0)
+ Buf = (Byte *)MidAlloc(kClusterSize);
+ if (!Buf)
return E_OUTOFMEMORY;
}
- bool result = File.Read1(Buffer, readSize, BufferSize);
+ bool result = File.Read1(Buf, readSize, BufSize);
if (!result)
return ConvertBoolToHRESULT(result);
- if (BufferSize == 0)
+ if (BufSize == 0)
return S_OK;
- PhyPos += BufferSize;
+ PhyPos += BufSize;
}
if (VirtPos != PhyPos)
@@ -145,22 +150,40 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
UInt32 realProcessedSize;
bool result = File.ReadPart(data, size, realProcessedSize);
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
+
#ifdef SUPPORT_DEVICE_FILE
VirtPos += realProcessedSize;
PhyPos += realProcessedSize;
#endif
- return ConvertBoolToHRESULT(result);
-
+
+ if (result)
+ return S_OK;
+
+ {
+ DWORD error = ::GetLastError();
+
+ if (Callback)
+ return Callback->InFileStream_On_Error(CallbackRef, error);
+ if (error == 0)
+ return E_FAIL;
+
+ return HRESULT_FROM_WIN32(error);
+ }
+
#else
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
ssize_t res = File.Read(data, (size_t)size);
if (res == -1)
+ {
+ if (Callback)
+ return Callback->InFileStream_On_Error(CallbackRef, E_FAIL);
return E_FAIL;
- if (processedSize != NULL)
+ }
+ if (processedSize)
*processedSize = (UInt32)res;
return S_OK;
@@ -170,10 +193,13 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
#ifdef UNDER_CE
STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- size_t s2 = fread(data, 1, size, stdout);
- if (processedSize != 0)
+ size_t s2 = fread(data, 1, size, stdin);
+ int error = ferror(stdin);
+ if (processedSize)
*processedSize = s2;
- return (s2 = size) ? S_OK : E_FAIL;
+ if (s2 <= size && error == 0)
+ return S_OK;
+ return E_FAIL;
}
#else
STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
@@ -185,7 +211,7 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi
if (sizeTemp > size)
sizeTemp = size;
BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL);
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
return S_OK;
@@ -193,7 +219,7 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi
#else
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
ssize_t res;
do
@@ -203,7 +229,7 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi
while (res < 0 && (errno == EINTR));
if (res == -1)
return E_FAIL;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = (UInt32)res;
return S_OK;
@@ -212,8 +238,7 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi
#endif
-STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
- UInt64 *newPosition)
+STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
if (seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
@@ -221,19 +246,20 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
#ifdef USE_WIN_FILE
#ifdef SUPPORT_DEVICE_FILE
- if (File.IsDeviceFile)
+ if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END))
{
- UInt64 newVirtPos = offset;
- switch(seekOrigin)
+ switch (seekOrigin)
{
case STREAM_SEEK_SET: break;
- case STREAM_SEEK_CUR: newVirtPos += VirtPos; break;
- case STREAM_SEEK_END: newVirtPos += File.Length; break;
+ case STREAM_SEEK_CUR: offset += VirtPos; break;
+ case STREAM_SEEK_END: offset += File.Size; break;
default: return STG_E_INVALIDFUNCTION;
}
- VirtPos = newVirtPos;
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ VirtPos = offset;
if (newPosition)
- *newPosition = newVirtPos;
+ *newPosition = offset;
return S_OK;
}
#endif
@@ -245,7 +271,7 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
PhyPos = VirtPos = realNewPosition;
#endif
- if (newPosition != NULL)
+ if (newPosition)
*newPosition = realNewPosition;
return ConvertBoolToHRESULT(result);
@@ -254,7 +280,7 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
off_t res = File.Seek((off_t)offset, seekOrigin);
if (res == -1)
return E_FAIL;
- if (newPosition != NULL)
+ if (newPosition)
*newPosition = (UInt64)res;
return S_OK;
@@ -266,6 +292,43 @@ STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
return ConvertBoolToHRESULT(File.GetLength(*size));
}
+#ifdef USE_WIN_FILE
+
+STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ if (File.GetFileInformation(&info))
+ {
+ if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
+ if (cTime) *cTime = info.ftCreationTime;
+ if (aTime) *aTime = info.ftLastAccessTime;
+ if (mTime) *mTime = info.ftLastWriteTime;
+ if (attrib) *attrib = info.dwFileAttributes;
+ return S_OK;
+ }
+ return GetLastError();
+}
+
+STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ if (File.GetFileInformation(&info))
+ {
+ props->Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
+ props->VolID = info.dwVolumeSerialNumber;
+ props->FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
+ props->FileID_High = 0;
+ props->NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1;
+ props->Attrib = info.dwFileAttributes;
+ props->CTime = info.ftCreationTime;
+ props->ATime = info.ftLastAccessTime;
+ props->MTime = info.ftLastWriteTime;
+ return S_OK;
+ }
+ return GetLastError();
+}
+
+#endif
//////////////////////////
// COutFileStream
@@ -280,20 +343,20 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces
#ifdef USE_WIN_FILE
UInt32 realProcessedSize;
- bool result = File.WritePart(data, size, realProcessedSize);
+ bool result = File.Write(data, size, realProcessedSize);
ProcessedSize += realProcessedSize;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
return ConvertBoolToHRESULT(result);
#else
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
ssize_t res = File.Write(data, (size_t)size);
if (res == -1)
return E_FAIL;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = (UInt32)res;
ProcessedSize += res;
return S_OK;
@@ -305,11 +368,12 @@ STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo
{
if (seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
+
#ifdef USE_WIN_FILE
UInt64 realNewPosition;
bool result = File.Seek(offset, seekOrigin, realNewPosition);
- if (newPosition != NULL)
+ if (newPosition)
*newPosition = realNewPosition;
return ConvertBoolToHRESULT(result);
@@ -318,7 +382,7 @@ STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo
off_t res = File.Seek((off_t)offset, seekOrigin);
if (res == -1)
return E_FAIL;
- if (newPosition != NULL)
+ if (newPosition)
*newPosition = (UInt64)res;
return S_OK;
@@ -328,6 +392,7 @@ STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo
STDMETHODIMP COutFileStream::SetSize(UInt64 newSize)
{
#ifdef USE_WIN_FILE
+
UInt64 currentPos;
if (!File.Seek(0, FILE_CURRENT, currentPos))
return E_FAIL;
@@ -335,26 +400,38 @@ STDMETHODIMP COutFileStream::SetSize(UInt64 newSize)
UInt64 currentPos2;
result = result && File.Seek(currentPos, currentPos2);
return result ? S_OK : E_FAIL;
+
#else
+
return E_FAIL;
+
#endif
}
+HRESULT COutFileStream::GetSize(UInt64 *size)
+{
+ return ConvertBoolToHRESULT(File.GetLength(*size));
+}
+
#ifdef UNDER_CE
+
STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
size_t s2 = fwrite(data, 1, size, stdout);
- if (processedSize != 0)
+ if (processedSize)
*processedSize = s2;
- return (s2 = size) ? S_OK : E_FAIL;
+ return (s2 == size) ? S_OK : E_FAIL;
}
+
#else
+
STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
#ifdef _WIN32
+
UInt32 realProcessedSize;
BOOL res = TRUE;
if (size > 0)
@@ -366,9 +443,10 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
sizeTemp = size;
res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
+ _size += realProcessedSize;
size -= realProcessedSize;
data = (const void *)((const Byte *)data + realProcessedSize);
- if (processedSize != NULL)
+ if (processedSize)
*processedSize += realProcessedSize;
}
return ConvertBoolToHRESULT(res != FALSE);
@@ -376,18 +454,21 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
#else
ssize_t res;
+
do
{
res = write(1, data, (size_t)size);
}
while (res < 0 && (errno == EINTR));
+
if (res == -1)
return E_FAIL;
- if (processedSize != NULL)
+
+ _size += (size_t)res;
+ if (processedSize)
*processedSize = (UInt32)res;
return S_OK;
- return S_OK;
#endif
}
diff --git a/3rdparty/lzma/CPP/7zip/Common/FileStreams.h b/3rdparty/lzma/CPP/7zip/Common/FileStreams.h
index bb2b1d41f1d..ef2986fdd88 100644
--- a/3rdparty/lzma/CPP/7zip/Common/FileStreams.h
+++ b/3rdparty/lzma/CPP/7zip/Common/FileStreams.h
@@ -19,29 +19,51 @@
#include "../IStream.h"
+#ifdef _WIN32
+typedef UINT_PTR My_UINT_PTR;
+#else
+typedef UINT My_UINT_PTR;
+#endif
+
+struct IInFileStream_Callback
+{
+ virtual HRESULT InFileStream_On_Error(My_UINT_PTR val, DWORD error) = 0;
+ virtual void InFileStream_On_Destroy(My_UINT_PTR val) = 0;
+};
+
class CInFileStream:
public IInStream,
public IStreamGetSize,
+ #ifdef USE_WIN_FILE
+ public IStreamGetProps,
+ public IStreamGetProps2,
+ #endif
public CMyUnknownImp
{
public:
#ifdef USE_WIN_FILE
NWindows::NFile::NIO::CInFile File;
+
#ifdef SUPPORT_DEVICE_FILE
UInt64 VirtPos;
UInt64 PhyPos;
- UInt64 BufferStartPos;
- Byte *Buffer;
- UInt32 BufferSize;
+ UInt64 BufStartPos;
+ Byte *Buf;
+ UInt32 BufSize;
#endif
+
#else
NC::NFile::NIO::CInFile File;
#endif
+
+ bool SupportHardLinks;
+
+ IInFileStream_Callback *Callback;
+ My_UINT_PTR CallbackRef;
+
virtual ~CInFileStream();
- #ifdef SUPPORT_DEVICE_FILE
CInFileStream();
- #endif
bool Open(CFSTR fileName)
{
@@ -53,12 +75,23 @@ public:
return File.OpenShared(fileName, shareForWrite);
}
- MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
+ MY_QUERYINTERFACE_BEGIN2(IInStream)
+ MY_QUERYINTERFACE_ENTRY(IStreamGetSize)
+ #ifdef USE_WIN_FILE
+ MY_QUERYINTERFACE_ENTRY(IStreamGetProps)
+ MY_QUERYINTERFACE_ENTRY(IStreamGetProps2)
+ #endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
STDMETHOD(GetSize)(UInt64 *size);
+ #ifdef USE_WIN_FILE
+ STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib);
+ STDMETHOD(GetProps2)(CStreamFileProps *props);
+ #endif
};
class CStdInFileStream:
@@ -112,15 +145,20 @@ public:
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
STDMETHOD(SetSize)(UInt64 newSize);
+
+ HRESULT GetSize(UInt64 *size);
};
class CStdOutFileStream:
public ISequentialOutStream,
public CMyUnknownImp
{
+ UInt64 _size;
public:
MY_UNKNOWN_IMP
+ UInt64 GetSize() const { return _size; }
+ CStdOutFileStream(): _size(0) {}
virtual ~CStdOutFileStream() {}
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
diff --git a/3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp b/3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp
index 6967352789a..4f3ae4e7dcf 100644
--- a/3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp
@@ -2,90 +2,144 @@
#include "StdAfx.h"
-#include "../../../C/Alloc.h"
-
#include "../../Common/Defs.h"
#include "FilterCoder.h"
#include "StreamUtils.h"
-static const UInt32 kBufferSize = 1 << 17;
+/*
+ AES filters need 16-bytes alignment for HARDWARE-AES instructions.
+ So we call IFilter::Filter(, size), where (size != 16 * N) only for last data block.
+
+ AES-CBC filters need data size aligned for 16-bytes.
+ So the encoder can add zeros to the end of original stream.
+
+ Some filters (BCJ and others) don't process data at the end of stream in some cases.
+ So the encoder and decoder write such last bytes without change.
+*/
+
+
+static const UInt32 kBufSize = 1 << 20;
-CFilterCoder::CFilterCoder()
+STDMETHODIMP CFilterCoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; }
+STDMETHODIMP CFilterCoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; }
+
+HRESULT CFilterCoder::Alloc()
{
- _buffer = (Byte *)::MidAlloc(kBufferSize);
- if (_buffer == 0)
- throw 1;
+ UInt32 size = MyMin(_inBufSize, _outBufSize);
+ /* minimal bufSize is 16 bytes for AES and IA64 filter.
+ bufSize for AES must be aligned for 16 bytes.
+ We use (1 << 12) min size to support future aligned filters. */
+ const UInt32 kMinSize = 1 << 12;
+ size &= ~(UInt32)(kMinSize - 1);
+ if (size < kMinSize)
+ size = kMinSize;
+ if (!_buf || _bufSize != size)
+ {
+ AllocAlignedMask(size, 16 - 1);
+ if (!_buf)
+ return E_OUTOFMEMORY;
+ _bufSize = size;
+ }
+ return S_OK;
}
-CFilterCoder::~CFilterCoder()
+HRESULT CFilterCoder::Init_and_Alloc()
{
- ::MidFree(_buffer);
+ RINOK(Filter->Init());
+ return Alloc();
}
-HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size)
+CFilterCoder::CFilterCoder(bool encodeMode):
+ _bufSize(0),
+ _inBufSize(kBufSize),
+ _outBufSize(kBufSize),
+ _encodeMode(encodeMode),
+ _outSizeIsDefined(false),
+ _outSize(0),
+ _nowPos64(0)
+ {}
+
+CFilterCoder::~CFilterCoder()
{
- if (_outSizeIsDefined)
- {
- UInt64 remSize = _outSize - _nowPos64;
- if (size > remSize)
- size = (UInt32)remSize;
- }
- RINOK(WriteStream(outStream, _buffer, size));
- _nowPos64 += size;
- return S_OK;
}
STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
{
- RINOK(Init());
- UInt32 bufferPos = 0;
- _outSizeIsDefined = (outSize != 0);
- if (_outSizeIsDefined)
- _outSize = *outSize;
+ RINOK(Init_and_Alloc());
+
+ UInt64 nowPos64 = 0;
+ bool inputFinished = false;
+ UInt32 pos = 0;
- while (!_outSizeIsDefined || _nowPos64 < _outSize)
+ while (!outSize || nowPos64 < *outSize)
{
- size_t processedSize = kBufferSize - bufferPos;
+ UInt32 endPos = pos;
- // Change it: It can be optimized using ReadPart
- RINOK(ReadStream(inStream, _buffer + bufferPos, &processedSize));
-
- UInt32 endPos = bufferPos + (UInt32)processedSize;
-
- bufferPos = Filter->Filter(_buffer, endPos);
- if (bufferPos > endPos)
+ if (!inputFinished)
{
- for (; endPos < bufferPos; endPos++)
- _buffer[endPos] = 0;
- bufferPos = Filter->Filter(_buffer, endPos);
+ size_t processedSize = _bufSize - pos;
+ RINOK(ReadStream(inStream, _buf + pos, &processedSize));
+ endPos = pos + (UInt32)processedSize;
+ inputFinished = (endPos != _bufSize);
}
- if (bufferPos == 0)
+ pos = Filter->Filter(_buf, endPos);
+
+ if (pos > endPos)
{
- if (endPos == 0)
- return S_OK;
- return WriteWithLimit(outStream, endPos);
+ // AES
+ if (!inputFinished || pos > _bufSize)
+ return E_FAIL;
+ if (!_encodeMode)
+ return S_FALSE;
+
+ do
+ _buf[endPos] = 0;
+ while (++endPos != pos);
+
+ if (pos != Filter->Filter(_buf, pos))
+ return E_FAIL;
}
- RINOK(WriteWithLimit(outStream, bufferPos));
- if (progress != NULL)
+
+ if (endPos == 0)
+ return S_OK;
+
+ UInt32 size = (pos != 0 ? pos : endPos);
+ if (outSize)
{
- RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64));
+ UInt64 remSize = *outSize - nowPos64;
+ if (size > remSize)
+ size = (UInt32)remSize;
}
+
+ RINOK(WriteStream(outStream, _buf, size));
+ nowPos64 += size;
+
+ if (pos == 0)
+ return S_OK;
+
+ if (progress)
+ RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
+
UInt32 i = 0;
- while (bufferPos < endPos)
- _buffer[i++] = _buffer[bufferPos++];
- bufferPos = i;
+ while (pos < endPos)
+ _buf[i++] = _buf[pos++];
+ pos = i;
}
+
return S_OK;
}
+
+
+// ---------- Write to Filter ----------
+
STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream)
{
- _bufferPos = 0;
_outStream = outStream;
- return Init();
+ return S_OK;
}
STDMETHODIMP CFilterCoder::ReleaseOutStream()
@@ -94,70 +148,154 @@ STDMETHODIMP CFilterCoder::ReleaseOutStream()
return S_OK;
}
+HRESULT CFilterCoder::Flush2()
+{
+ while (_convSize != 0)
+ {
+ UInt32 num = _convSize;
+ if (_outSizeIsDefined)
+ {
+ UInt64 rem = _outSize - _nowPos64;
+ if (num > rem)
+ num = (UInt32)rem;
+ if (num == 0)
+ return k_My_HRESULT_WritingWasCut;
+ }
+
+ UInt32 processed = 0;
+ HRESULT res = _outStream->Write(_buf + _convPos, num, &processed);
+ if (processed == 0)
+ return res != S_OK ? res : E_FAIL;
+
+ _convPos += processed;
+ _convSize -= processed;
+ _nowPos64 += processed;
+ RINOK(res);
+ }
+
+ if (_convPos != 0)
+ {
+ UInt32 num = _bufPos - _convPos;
+ for (UInt32 i = 0; i < num; i++)
+ _buf[i] = _buf[_convPos + i];
+ _bufPos = num;
+ _convPos = 0;
+ }
+
+ return S_OK;
+}
STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
- while (size > 0)
+
+ while (size != 0)
{
- UInt32 sizeTemp = MyMin(size, kBufferSize - _bufferPos);
- memcpy(_buffer + _bufferPos, data, sizeTemp);
- size -= sizeTemp;
- if (processedSize != NULL)
- *processedSize += sizeTemp;
- data = (const Byte *)data + sizeTemp;
- UInt32 endPos = _bufferPos + sizeTemp;
- _bufferPos = Filter->Filter(_buffer, endPos);
- if (_bufferPos == 0)
+ RINOK(Flush2());
+
+ // _convSize is 0
+ // _convPos is 0
+ // _bufPos is small
+
+ if (_bufPos != _bufSize)
{
- _bufferPos = endPos;
- break;
+ UInt32 num = MyMin(size, _bufSize - _bufPos);
+ memcpy(_buf + _bufPos, data, num);
+ size -= num;
+ data = (const Byte *)data + num;
+ if (processedSize)
+ *processedSize += num;
+ _bufPos += num;
+ if (_bufPos != _bufSize)
+ continue;
}
- if (_bufferPos > endPos)
- {
- if (size != 0)
- return E_FAIL;
+
+ // _bufPos == _bufSize
+ _convSize = Filter->Filter(_buf, _bufPos);
+
+ if (_convSize == 0)
break;
+ if (_convSize > _bufPos)
+ {
+ // that case is not possible.
+ _convSize = 0;
+ return E_FAIL;
}
- RINOK(WriteWithLimit(_outStream, _bufferPos));
- UInt32 i = 0;
- while (_bufferPos < endPos)
- _buffer[i++] = _buffer[_bufferPos++];
- _bufferPos = i;
}
+
return S_OK;
}
-STDMETHODIMP CFilterCoder::Flush()
+STDMETHODIMP CFilterCoder::OutStreamFinish()
{
- if (_bufferPos != 0)
+ for (;;)
{
- // _buffer contains only data refused by previous Filter->Filter call.
- UInt32 endPos = Filter->Filter(_buffer, _bufferPos);
- if (endPos > _bufferPos)
+ RINOK(Flush2());
+ if (_bufPos == 0)
+ break;
+ _convSize = Filter->Filter(_buf, _bufPos);
+ if (_convSize == 0)
+ _convSize = _bufPos;
+ else if (_convSize > _bufPos)
{
- for (; _bufferPos < endPos; _bufferPos++)
- _buffer[_bufferPos] = 0;
- if (Filter->Filter(_buffer, endPos) != endPos)
+ // AES
+ if (_convSize > _bufSize)
+ {
+ _convSize = 0;
+ return E_FAIL;
+ }
+ if (!_encodeMode)
+ {
+ _convSize = 0;
+ return S_FALSE;
+ }
+ for (; _bufPos < _convSize; _bufPos++)
+ _buf[_bufPos] = 0;
+ _convSize = Filter->Filter(_buf, _bufPos);
+ if (_convSize != _bufPos)
return E_FAIL;
}
- RINOK(WriteWithLimit(_outStream, _bufferPos));
- _bufferPos = 0;
}
- CMyComPtr<IOutStreamFlush> flush;
- _outStream.QueryInterface(IID_IOutStreamFlush, &flush);
- if (flush)
- return flush->Flush();
+
+ CMyComPtr<IOutStreamFinish> finish;
+ _outStream.QueryInterface(IID_IOutStreamFinish, &finish);
+ if (finish)
+ return finish->OutStreamFinish();
return S_OK;
}
+// ---------- Init functions ----------
+
+STDMETHODIMP CFilterCoder::InitEncoder()
+{
+ InitSpecVars();
+ return Init_and_Alloc();
+}
+
+HRESULT CFilterCoder::Init_NoSubFilterInit()
+{
+ InitSpecVars();
+ return Alloc();
+}
+
+STDMETHODIMP CFilterCoder::SetOutStreamSize(const UInt64 *outSize)
+{
+ InitSpecVars();
+ if (outSize)
+ {
+ _outSize = *outSize;
+ _outSizeIsDefined = true;
+ }
+ return Init_and_Alloc();
+}
+
+// ---------- Read from Filter ----------
STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
{
- _convertedPosBegin = _convertedPosEnd = _bufferPos = 0;
_inStream = inStream;
- return Init();
+ return S_OK;
}
STDMETHODIMP CFilterCoder::ReleaseInStream()
@@ -166,82 +304,115 @@ STDMETHODIMP CFilterCoder::ReleaseInStream()
return S_OK;
}
+
STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
- while (size > 0)
+
+ while (size != 0)
{
- if (_convertedPosBegin != _convertedPosEnd)
+ if (_convSize != 0)
{
- UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin);
- memcpy(data, _buffer + _convertedPosBegin, sizeTemp);
- _convertedPosBegin += sizeTemp;
- data = (void *)((Byte *)data + sizeTemp);
- size -= sizeTemp;
- if (processedSize != NULL)
- *processedSize += sizeTemp;
+ if (size > _convSize)
+ size = _convSize;
+ if (_outSizeIsDefined)
+ {
+ UInt64 rem = _outSize - _nowPos64;
+ if (size > rem)
+ size = (UInt32)rem;
+ }
+ memcpy(data, _buf + _convPos, size);
+ _convPos += size;
+ _convSize -= size;
+ _nowPos64 += size;
+ if (processedSize)
+ *processedSize = size;
break;
}
- UInt32 i;
- for (i = 0; _convertedPosEnd + i < _bufferPos; i++)
- _buffer[i] = _buffer[_convertedPosEnd + i];
- _bufferPos = i;
- _convertedPosBegin = _convertedPosEnd = 0;
- size_t processedSizeTemp = kBufferSize - _bufferPos;
- RINOK(ReadStream(_inStream, _buffer + _bufferPos, &processedSizeTemp));
- _bufferPos += (UInt32)processedSizeTemp;
- _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
- if (_convertedPosEnd == 0)
+
+ if (_convPos != 0)
+ {
+ UInt32 num = _bufPos - _convPos;
+ for (UInt32 i = 0; i < num; i++)
+ _buf[i] = _buf[_convPos + i];
+ _bufPos = num;
+ _convPos = 0;
+ }
+
+ {
+ size_t readSize = _bufSize - _bufPos;
+ HRESULT res = ReadStream(_inStream, _buf + _bufPos, &readSize);
+ _bufPos += (UInt32)readSize;
+ RINOK(res);
+ }
+
+ _convSize = Filter->Filter(_buf, _bufPos);
+
+ if (_convSize == 0)
{
- if (_bufferPos == 0)
+ if (_bufPos == 0)
break;
- _convertedPosEnd = _bufferPos; // check it
+ // BCJ
+ _convSize = _bufPos;
continue;
}
- if (_convertedPosEnd > _bufferPos)
+
+ if (_convSize > _bufPos)
{
- for (; _bufferPos < _convertedPosEnd; _bufferPos++)
- _buffer[_bufferPos] = 0;
- _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+ // AES
+ if (_convSize > _bufSize)
+ return E_FAIL;
+ if (!_encodeMode)
+ return S_FALSE;
+
+ do
+ _buf[_bufPos] = 0;
+ while (++_bufPos != _convSize);
+
+ _convSize = Filter->Filter(_buf, _convSize);
+ if (_convSize != _bufPos)
+ return E_FAIL;
}
}
+
return S_OK;
}
+
#ifndef _NO_CRYPTO
+
STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)
-{
- return _setPassword->CryptoSetPassword(data, size);
-}
+ { return _SetPassword->CryptoSetPassword(data, size); }
+
+STDMETHODIMP CFilterCoder::SetKey(const Byte *data, UInt32 size)
+ { return _CryptoProperties->SetKey(data, size); }
+
+STDMETHODIMP CFilterCoder::SetInitVector(const Byte *data, UInt32 size)
+ { return _CryptoProperties->SetInitVector(data, size); }
+
#endif
+
#ifndef EXTRACT_ONLY
+
STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs,
- const PROPVARIANT *properties, UInt32 numProperties)
-{
- return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties);
-}
+ const PROPVARIANT *properties, UInt32 numProperties)
+ { return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties); }
STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)
-{
- return _writeCoderProperties->WriteCoderProperties(outStream);
-}
+ { return _WriteCoderProperties->WriteCoderProperties(outStream); }
/*
STDMETHODIMP CFilterCoder::ResetSalt()
-{
- return _CryptoResetSalt->ResetSalt();
-}
+ { return _CryptoResetSalt->ResetSalt(); }
*/
STDMETHODIMP CFilterCoder::ResetInitVector()
-{
- return _CryptoResetInitVector->ResetInitVector();
-}
+ { return _CryptoResetInitVector->ResetInitVector(); }
+
#endif
+
STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
-{
- return _setDecoderProperties->SetDecoderProperties2(data, size);
-}
+ { return _SetDecoderProperties2->SetDecoderProperties2(data, size); }
diff --git a/3rdparty/lzma/CPP/7zip/Common/FilterCoder.h b/3rdparty/lzma/CPP/7zip/Common/FilterCoder.h
index 8132a6dd74e..224ff2ca459 100644
--- a/3rdparty/lzma/CPP/7zip/Common/FilterCoder.h
+++ b/3rdparty/lzma/CPP/7zip/Common/FilterCoder.h
@@ -3,102 +3,212 @@
#ifndef __FILTER_CODER_H
#define __FILTER_CODER_H
+#include "../../../C/Alloc.h"
+
#include "../../Common/MyCom.h"
#include "../ICoder.h"
+
+#ifndef _NO_CRYPTO
#include "../IPassword.h"
+#endif
+
+#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) else if (iid == IID_ ## i) \
+ { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
+ *outObject = (void *)(i *)this; }
+
+
+struct CAlignedMidBuffer
+{
+ #ifdef _WIN32
-#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \
-{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
-*outObject = (void *)(i *)this; AddRef(); return S_OK; }
+ Byte *_buf;
+
+ CAlignedMidBuffer(): _buf(NULL) {}
+ ~CAlignedMidBuffer() { ::MidFree(_buf); }
+
+ void AllocAlignedMask(size_t size, size_t)
+ {
+ ::MidFree(_buf);
+ _buf = (Byte *)::MidAlloc(size);
+ }
+
+ #else
+
+ Byte *_bufBase;
+ Byte *_buf;
+
+ CAlignedMidBuffer(): _bufBase(NULL), _buf(NULL) {}
+ ~CAlignedMidBuffer() { ::MidFree(_bufBase); }
+
+ void AllocAlignedMask(size_t size, size_t alignMask)
+ {
+ ::MidFree(_bufBase);
+ _buf = NULL;
+ _bufBase = (Byte *)::MidAlloc(size + alignMask);
+
+ if (_bufBase)
+ {
+ // _buf = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask);
+ _buf = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask);
+ }
+ }
+
+ #endif
+};
class CFilterCoder:
public ICompressCoder,
+
+ public ICompressSetOutStreamSize,
+ public ICompressInitEncoder,
+
public ICompressSetInStream,
public ISequentialInStream,
+
public ICompressSetOutStream,
public ISequentialOutStream,
- public IOutStreamFlush,
+ public IOutStreamFinish,
+
+ public ICompressSetBufSize,
#ifndef _NO_CRYPTO
public ICryptoSetPassword,
+ public ICryptoProperties,
#endif
+
#ifndef EXTRACT_ONLY
public ICompressSetCoderProperties,
public ICompressWriteCoderProperties,
// public ICryptoResetSalt,
public ICryptoResetInitVector,
#endif
+
public ICompressSetDecoderProperties2,
- public CMyUnknownImp
+ public CMyUnknownImp,
+ public CAlignedMidBuffer
{
-protected:
- Byte *_buffer;
- CMyComPtr<ISequentialInStream> _inStream;
- CMyComPtr<ISequentialOutStream> _outStream;
- UInt32 _bufferPos;
- UInt32 _convertedPosBegin;
- UInt32 _convertedPosEnd;
+ UInt32 _bufSize;
+ UInt32 _inBufSize;
+ UInt32 _outBufSize;
+
+ bool _encodeMode;
bool _outSizeIsDefined;
UInt64 _outSize;
UInt64 _nowPos64;
- HRESULT Init()
+ CMyComPtr<ISequentialInStream> _inStream;
+ CMyComPtr<ISequentialOutStream> _outStream;
+ UInt32 _bufPos;
+ UInt32 _convPos; // current pos in buffer for converted data
+ UInt32 _convSize; // size of converted data starting from _convPos
+
+ void InitSpecVars()
{
- _nowPos64 = 0;
+ _bufPos = 0;
+ _convPos = 0;
+ _convSize = 0;
+
_outSizeIsDefined = false;
- return Filter->Init();
+ _outSize = 0;
+ _nowPos64 = 0;
}
- CMyComPtr<ICryptoSetPassword> _setPassword;
+ HRESULT Alloc();
+ HRESULT Init_and_Alloc();
+ HRESULT Flush2();
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoSetPassword> _SetPassword;
+ CMyComPtr<ICryptoProperties> _CryptoProperties;
+ #endif
+
#ifndef EXTRACT_ONLY
CMyComPtr<ICompressSetCoderProperties> _SetCoderProperties;
- CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties;
+ CMyComPtr<ICompressWriteCoderProperties> _WriteCoderProperties;
// CMyComPtr<ICryptoResetSalt> _CryptoResetSalt;
CMyComPtr<ICryptoResetInitVector> _CryptoResetInitVector;
#endif
- CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties;
+
+ CMyComPtr<ICompressSetDecoderProperties2> _SetDecoderProperties2;
+
public:
CMyComPtr<ICompressFilter> Filter;
- CFilterCoder();
+ CFilterCoder(bool encodeMode);
~CFilterCoder();
- HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size);
-public:
+ class C_InStream_Releaser
+ {
+ public:
+ CFilterCoder *FilterCoder;
+ C_InStream_Releaser(): FilterCoder(NULL) {}
+ ~C_InStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); }
+ };
+
+ class C_OutStream_Releaser
+ {
+ public:
+ CFilterCoder *FilterCoder;
+ C_OutStream_Releaser(): FilterCoder(NULL) {}
+ ~C_OutStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); }
+ };
+
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
+
+ MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
+ MY_QUERYINTERFACE_ENTRY(ICompressInitEncoder)
+
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
+
MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream)
MY_QUERYINTERFACE_ENTRY(ISequentialOutStream)
- MY_QUERYINTERFACE_ENTRY(IOutStreamFlush)
+ MY_QUERYINTERFACE_ENTRY(IOutStreamFinish)
+
+ MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize)
#ifndef _NO_CRYPTO
- MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword)
+ MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _SetPassword)
+ MY_QUERYINTERFACE_ENTRY_AG(ICryptoProperties, Filter, _CryptoProperties)
#endif
#ifndef EXTRACT_ONLY
MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties)
- MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties)
+ MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _WriteCoderProperties)
// MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt)
MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector)
#endif
- MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties)
+ MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _SetDecoderProperties2)
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
+
+
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
- STDMETHOD(ReleaseInStream)();
+
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+ STDMETHOD(InitEncoder)();
+
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
STDMETHOD(ReleaseOutStream)();
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(Flush)();
+ STDMETHOD(OutStreamFinish)();
+
+ STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
+ STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
#ifndef _NO_CRYPTO
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size);
+ STDMETHOD(SetInitVector)(const Byte *data, UInt32 size);
#endif
+
#ifndef EXTRACT_ONLY
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
const PROPVARIANT *properties, UInt32 numProperties);
@@ -106,23 +216,11 @@ public:
// STDMETHOD(ResetSalt)();
STDMETHOD(ResetInitVector)();
#endif
+
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
-};
-class CInStreamReleaser
-{
-public:
- CFilterCoder *FilterCoder;
- CInStreamReleaser(): FilterCoder(0) {}
- ~CInStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); }
-};
-
-class COutStreamReleaser
-{
-public:
- CFilterCoder *FilterCoder;
- COutStreamReleaser(): FilterCoder(0) {}
- ~COutStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); }
+
+ HRESULT Init_NoSubFilterInit();
};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp b/3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp
index ad4f8825e9e..133d95b3885 100644
--- a/3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp
@@ -6,50 +6,49 @@
#include "InBuffer.h"
-CInBuffer::CInBuffer():
- _buffer(0),
- _bufferLimit(0),
- _bufferBase(0),
+CInBufferBase::CInBufferBase() throw():
+ _buf(0),
+ _bufLim(0),
+ _bufBase(0),
_stream(0),
- _bufferSize(0)
+ _processedSize(0),
+ _bufSize(0),
+ _wasFinished(false),
+ NumExtraBytes(0)
{}
-bool CInBuffer::Create(UInt32 bufferSize)
+bool CInBuffer::Create(size_t bufSize) throw()
{
- const UInt32 kMinBlockSize = 1;
- if (bufferSize < kMinBlockSize)
- bufferSize = kMinBlockSize;
- if (_bufferBase != 0 && _bufferSize == bufferSize)
+ const unsigned kMinBlockSize = 1;
+ if (bufSize < kMinBlockSize)
+ bufSize = kMinBlockSize;
+ if (_bufBase != 0 && _bufSize == bufSize)
return true;
Free();
- _bufferSize = bufferSize;
- _bufferBase = (Byte *)::MidAlloc(bufferSize);
- return (_bufferBase != 0);
+ _bufSize = bufSize;
+ _bufBase = (Byte *)::MidAlloc(bufSize);
+ return (_bufBase != 0);
}
-void CInBuffer::Free()
+void CInBuffer::Free() throw()
{
- ::MidFree(_bufferBase);
- _bufferBase = 0;
+ ::MidFree(_bufBase);
+ _bufBase = 0;
}
-void CInBuffer::SetStream(ISequentialInStream *stream)
-{
- _stream = stream;
-}
-
-void CInBuffer::Init()
+void CInBufferBase::Init() throw()
{
_processedSize = 0;
- _buffer = _bufferBase;
- _bufferLimit = _buffer;
+ _buf = _bufBase;
+ _bufLim = _buf;
_wasFinished = false;
#ifdef _NO_EXCEPTIONS
ErrorCode = S_OK;
#endif
+ NumExtraBytes = 0;
}
-bool CInBuffer::ReadBlock()
+bool CInBufferBase::ReadBlock()
{
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
@@ -57,27 +56,80 @@ bool CInBuffer::ReadBlock()
#endif
if (_wasFinished)
return false;
- _processedSize += (_buffer - _bufferBase);
- UInt32 numProcessedBytes;
- HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
+ _processedSize += (_buf - _bufBase);
+ _buf = _bufBase;
+ _bufLim = _bufBase;
+ UInt32 processed;
+ // FIX_ME: we can improve it to support (_bufSize >= (1 << 32))
+ HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed);
#ifdef _NO_EXCEPTIONS
ErrorCode = result;
#else
if (result != S_OK)
throw CInBufferException(result);
#endif
- _buffer = _bufferBase;
- _bufferLimit = _buffer + numProcessedBytes;
- _wasFinished = (numProcessedBytes == 0);
- return (!_wasFinished);
+ _bufLim = _buf + processed;
+ _wasFinished = (processed == 0);
+ return !_wasFinished;
}
-Byte CInBuffer::ReadBlock2()
+bool CInBufferBase::ReadByte_FromNewBlock(Byte &b)
{
if (!ReadBlock())
{
- _processedSize++;
+ NumExtraBytes++;
+ b = 0xFF;
+ return false;
+ }
+ b = *_buf++;
+ return true;
+}
+
+Byte CInBufferBase::ReadByte_FromNewBlock()
+{
+ if (!ReadBlock())
+ {
+ NumExtraBytes++;
return 0xFF;
}
- return *_buffer++;
+ return *_buf++;
+}
+
+size_t CInBufferBase::ReadBytes(Byte *buf, size_t size)
+{
+ if ((size_t)(_bufLim - _buf) >= size)
+ {
+ const Byte *src = _buf;
+ for (size_t i = 0; i < size; i++)
+ buf[i] = src[i];
+ _buf += size;
+ return size;
+ }
+ for (size_t i = 0; i < size; i++)
+ {
+ if (_buf >= _bufLim)
+ if (!ReadBlock())
+ return i;
+ buf[i] = *_buf++;
+ }
+ return size;
+}
+
+size_t CInBufferBase::Skip(size_t size)
+{
+ size_t processed = 0;
+ for (;;)
+ {
+ size_t rem = (_bufLim - _buf);
+ if (rem >= size)
+ {
+ _buf += size;
+ return processed + size;
+ }
+ _buf += rem;
+ processed += rem;
+ size -= rem;
+ if (!ReadBlock())
+ return processed;
+ }
}
diff --git a/3rdparty/lzma/CPP/7zip/Common/InBuffer.h b/3rdparty/lzma/CPP/7zip/Common/InBuffer.h
index 75625bfd936..4b8662bb9d5 100644
--- a/3rdparty/lzma/CPP/7zip/Common/InBuffer.h
+++ b/3rdparty/lzma/CPP/7zip/Common/InBuffer.h
@@ -1,11 +1,10 @@
// InBuffer.h
-#ifndef __INBUFFER_H
-#define __INBUFFER_H
+#ifndef __IN_BUFFER_H
+#define __IN_BUFFER_H
-#include "../IStream.h"
-#include "../../Common/MyCom.h"
#include "../../Common/MyException.h"
+#include "../IStream.h"
#ifndef _NO_EXCEPTIONS
struct CInBufferException: public CSystemException
@@ -14,68 +13,78 @@ struct CInBufferException: public CSystemException
};
#endif
-class CInBuffer
+class CInBufferBase
{
- Byte *_buffer;
- Byte *_bufferLimit;
- Byte *_bufferBase;
- CMyComPtr<ISequentialInStream> _stream;
+protected:
+ Byte *_buf;
+ Byte *_bufLim;
+ Byte *_bufBase;
+
+ ISequentialInStream *_stream;
UInt64 _processedSize;
- UInt32 _bufferSize;
+ size_t _bufSize; // actually it's number of Bytes for next read. The buf can be larger
+ // only up to 32-bits values now are supported!
bool _wasFinished;
bool ReadBlock();
- Byte ReadBlock2();
+ bool ReadByte_FromNewBlock(Byte &b);
+ Byte ReadByte_FromNewBlock();
public:
#ifdef _NO_EXCEPTIONS
HRESULT ErrorCode;
#endif
+ UInt32 NumExtraBytes;
- CInBuffer();
- ~CInBuffer() { Free(); }
+ CInBufferBase() throw();
+
+ UInt64 GetStreamSize() const { return _processedSize + (_buf - _bufBase); }
+ UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (_buf - _bufBase); }
+ bool WasFinished() const { return _wasFinished; }
- bool Create(UInt32 bufferSize);
- void Free();
+ void SetStream(ISequentialInStream *stream) { _stream = stream; }
- void SetStream(ISequentialInStream *stream);
- void Init();
- void ReleaseStream() { _stream.Release(); }
+ void SetBuf(Byte *buf, size_t bufSize, size_t end, size_t pos)
+ {
+ _bufBase = buf;
+ _bufSize = bufSize;
+ _processedSize = 0;
+ _buf = buf + pos;
+ _bufLim = buf + end;
+ _wasFinished = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+ NumExtraBytes = 0;
+ }
+
+ void Init() throw();
bool ReadByte(Byte &b)
{
- if (_buffer >= _bufferLimit)
- if (!ReadBlock())
- return false;
- b = *_buffer++;
+ if (_buf >= _bufLim)
+ return ReadByte_FromNewBlock(b);
+ b = *_buf++;
return true;
}
+
Byte ReadByte()
{
- if (_buffer >= _bufferLimit)
- return ReadBlock2();
- return *_buffer++;
+ if (_buf >= _bufLim)
+ return ReadByte_FromNewBlock();
+ return *_buf++;
}
- UInt32 ReadBytes(Byte *buf, UInt32 size)
- {
- if ((UInt32)(_bufferLimit - _buffer) >= size)
- {
- for (UInt32 i = 0; i < size; i++)
- buf[i] = _buffer[i];
- _buffer += size;
- return size;
- }
- for (UInt32 i = 0; i < size; i++)
- {
- if (_buffer >= _bufferLimit)
- if (!ReadBlock())
- return i;
- buf[i] = *_buffer++;
- }
- return size;
- }
- UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
- bool WasFinished() const { return _wasFinished; }
+
+ size_t ReadBytes(Byte *buf, size_t size);
+ size_t Skip(size_t size);
+};
+
+class CInBuffer: public CInBufferBase
+{
+public:
+ ~CInBuffer() { Free(); }
+ bool Create(size_t bufSize) throw(); // only up to 32-bits values now are supported!
+ void Free() throw();
};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp b/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp
index 442374dab79..85d6a1aa921 100644
--- a/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp
@@ -4,14 +4,16 @@
#include "../../../C/7zCrc.h"
+#include "../../Common/Defs.h"
+
#include "InOutTempBuffer.h"
#include "StreamUtils.h"
using namespace NWindows;
using namespace NFile;
-using namespace NDirectory;
+using namespace NDir;
-static const UInt32 kTempBufSize = (1 << 20);
+static const size_t kTempBufSize = (1 << 20);
static CFSTR kTempFilePrefixString = FTEXT("7zt");
@@ -56,15 +58,19 @@ bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
bool CInOutTempBuffer::Write(const void *data, UInt32 size)
{
- if (_bufPos < kTempBufSize)
+ if (size == 0)
+ return true;
+ size_t cur = kTempBufSize - _bufPos;
+ if (cur != 0)
{
- UInt32 cur = MyMin(kTempBufSize - _bufPos, size);
+ if (cur > size)
+ cur = size;
memcpy(_buf + _bufPos, data, cur);
_crc = CrcUpdate(_crc, data, cur);
_bufPos += cur;
- size -= cur;
- data = ((const Byte *)data) + cur;
_size += cur;
+ size -= (UInt32)cur;
+ data = ((const Byte *)data) + cur;
}
return WriteToFile(data, size);
}
@@ -77,12 +83,13 @@ HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
UInt64 size = 0;
UInt32 crc = CRC_INIT_VAL;
- if (_bufPos > 0)
+ if (_bufPos != 0)
{
RINOK(WriteStream(stream, _buf, _bufPos));
crc = CrcUpdate(crc, _buf, _bufPos);
size += _bufPos;
}
+
if (_tempFileCreated)
{
NIO::CInFile inFile;
@@ -100,18 +107,21 @@ HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
size += processed;
}
}
+
return (_crc == crc && size == _size) ? S_OK : E_FAIL;
}
+/*
STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processed)
{
if (!_buf->Write(data, size))
{
- if (processed != NULL)
+ if (processed)
*processed = 0;
return E_FAIL;
}
- if (processed != NULL)
+ if (processed)
*processed = size;
return S_OK;
}
+*/
diff --git a/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h b/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h
index bdf937ded81..204a105f1de 100644
--- a/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h
+++ b/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h
@@ -10,13 +10,13 @@
class CInOutTempBuffer
{
- NWindows::NFile::NDirectory::CTempFile _tempFile;
+ NWindows::NFile::NDir::CTempFile _tempFile;
NWindows::NFile::NIO::COutFile _outFile;
Byte *_buf;
- UInt32 _bufPos;
- bool _tempFileCreated;
+ size_t _bufPos;
UInt64 _size;
UInt32 _crc;
+ bool _tempFileCreated;
bool WriteToFile(const void *data, UInt32 size);
public:
@@ -31,6 +31,7 @@ public:
UInt64 GetDataSize() const { return _size; }
};
+/*
class CSequentialOutTempBufferImp:
public ISequentialOutStream,
public CMyUnknownImp
@@ -42,5 +43,6 @@ public:
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
+*/
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp b/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp
index 1837e32012a..c7962167ffc 100644
--- a/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include <string.h>
+
#include "LimitedStreams.h"
#include "../../Common/Defs.h"
@@ -17,17 +19,21 @@ STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *p
if (realProcessedSize == 0)
_wasFinished = true;
}
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
return result;
}
STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
if (_virtPos >= _size)
- return (_virtPos == _size) ? S_OK: E_FAIL;
+ {
+ // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case.
+ return S_OK;
+ // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF
+ }
UInt64 rem = _size - _virtPos;
if (rem < size)
size = (UInt32)rem;
@@ -38,7 +44,7 @@ STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSi
RINOK(SeekToPhys());
}
HRESULT res = _stream->Read(data, size, &size);
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
_physPos += size;
_virtPos += size;
@@ -47,48 +53,71 @@ STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSi
STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET: _virtPos = offset; break;
- case STREAM_SEEK_CUR: _virtPos += offset; break;
- case STREAM_SEEK_END: _virtPos = _size + offset; break;
+ 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 = _virtPos;
return S_OK;
}
+HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream)
+{
+ *resStream = 0;
+ CLimitedInStream *streamSpec = new CLimitedInStream;
+ CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
+ streamSpec->SetStream(inStream);
+ RINOK(streamSpec->InitAndSeek(pos, size));
+ streamSpec->SeekToStart();
+ *resStream = streamTemp.Detach();
+ return S_OK;
+}
+
STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
if (_virtPos >= Size)
- return (_virtPos == Size) ? S_OK: E_FAIL;
+ return S_OK;
+ {
+ UInt64 rem = Size - _virtPos;
+ if (size > rem)
+ size = (UInt32)rem;
+ }
+ if (size == 0)
+ return S_OK;
if (_curRem == 0)
{
- UInt32 blockSize = (UInt32)1 << BlockSizeLog;
- UInt32 virtBlock = (UInt32)(_virtPos >> BlockSizeLog);
- UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1);
- UInt32 phyBlock = Vector[virtBlock];
+ const UInt32 blockSize = (UInt32)1 << BlockSizeLog;
+ const UInt32 virtBlock = (UInt32)(_virtPos >> BlockSizeLog);
+ const UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1);
+ const UInt32 phyBlock = Vector[virtBlock];
+
UInt64 newPos = StartOffset + ((UInt64)phyBlock << BlockSizeLog) + offsetInBlock;
if (newPos != _physPos)
{
_physPos = newPos;
RINOK(SeekToPhys());
}
+
_curRem = blockSize - offsetInBlock;
+
for (int i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++)
_curRem += (UInt32)1 << BlockSizeLog;
- UInt64 rem = Size - _virtPos;
- if (_curRem > rem)
- _curRem = (UInt32)rem;
}
+
if (size > _curRem)
size = _curRem;
HRESULT res = Stream->Read(data, size, &size);
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
_physPos += size;
_virtPos += size;
@@ -98,39 +127,88 @@ STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSi
STDMETHODIMP CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- UInt64 newVirtPos = offset;
- switch(seekOrigin)
+ switch (seekOrigin)
{
case STREAM_SEEK_SET: break;
- case STREAM_SEEK_CUR: newVirtPos += _virtPos; break;
- case STREAM_SEEK_END: newVirtPos += Size; break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END: offset += Size; break;
default: return STG_E_INVALIDFUNCTION;
}
- if (_virtPos != newVirtPos)
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ if (_virtPos != (UInt64)offset)
_curRem = 0;
- _virtPos = newVirtPos;
+ _virtPos = offset;
if (newPosition)
- *newPosition = newVirtPos;
+ *newPosition = offset;
return S_OK;
}
-HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream)
+STDMETHODIMP CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- *resStream = 0;
- CLimitedInStream *streamSpec = new CLimitedInStream;
- CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
- streamSpec->SetStream(inStream);
- RINOK(streamSpec->InitAndSeek(pos, size));
- streamSpec->SeekToStart();
- *resStream = streamTemp.Detach();
+ if (processedSize)
+ *processedSize = 0;
+ if (_virtPos >= Extents.Back().Virt)
+ return S_OK;
+ if (size == 0)
+ return S_OK;
+
+ unsigned left = 0, right = Extents.Size() - 1;
+ for (;;)
+ {
+ unsigned mid = (left + right) / 2;
+ if (mid == left)
+ break;
+ if (_virtPos < Extents[mid].Virt)
+ right = mid;
+ else
+ left = mid;
+ }
+
+ const CSeekExtent &extent = Extents[left];
+ UInt64 phyPos = extent.Phy + (_virtPos - extent.Virt);
+ if (_needStartSeek || _phyPos != phyPos)
+ {
+ _needStartSeek = false;
+ _phyPos = phyPos;
+ RINOK(SeekToPhys());
+ }
+
+ UInt64 rem = Extents[left + 1].Virt - _virtPos;
+ if (size > rem)
+ size = (UInt32)rem;
+
+ HRESULT res = Stream->Read(data, size, &size);
+ _phyPos += size;
+ _virtPos += size;
+ if (processedSize)
+ *processedSize = size;
+ return res;
+}
+
+STDMETHODIMP CExtentsStream::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 += Extents.Back().Virt; break;
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
+ if (newPosition)
+ *newPosition = _virtPos;
return S_OK;
}
+
STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
HRESULT result = S_OK;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
if (size > _size)
{
@@ -139,7 +217,7 @@ STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, U
_overflow = true;
if (!_overflowIsAllowed)
return E_FAIL;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
return S_OK;
}
@@ -148,7 +226,137 @@ STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, U
if (_stream)
result = _stream->Write(data, size, &size);
_size -= size;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
return result;
}
+
+
+STDMETHODIMP CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 cur;
+ HRESULT res = Stream->Read(data, size, &cur);
+ if (processedSize)
+ *processedSize = cur;
+ _virtPos += cur;
+ return res;
+}
+
+STDMETHODIMP CTailInStream::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:
+ {
+ UInt64 pos = 0;
+ RINOK(Stream->Seek(offset, STREAM_SEEK_END, &pos));
+ if (pos < Offset)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = pos - Offset;
+ if (newPosition)
+ *newPosition = _virtPos;
+ return S_OK;
+ }
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
+ if (newPosition)
+ *newPosition = _virtPos;
+ return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL);
+}
+
+STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+ if (_virtPos >= _size)
+ {
+ // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case.
+ return S_OK;
+ // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF
+ }
+ UInt64 rem = _size - _virtPos;
+ if (rem < size)
+ size = (UInt32)rem;
+
+ UInt64 newPos = _startOffset + _virtPos;
+ UInt64 offsetInCache = newPos - _cachePhyPos;
+ HRESULT res = S_OK;
+ if (newPos >= _cachePhyPos &&
+ offsetInCache <= _cacheSize &&
+ size <= _cacheSize - (size_t)offsetInCache)
+ {
+ if (size != 0)
+ memcpy(data, _cache + (size_t)offsetInCache, size);
+ }
+ else
+ {
+ if (newPos != _physPos)
+ {
+ _physPos = newPos;
+ RINOK(SeekToPhys());
+ }
+ res = _stream->Read(data, size, &size);
+ _physPos += size;
+ }
+ if (processedSize)
+ *processedSize = size;
+ _virtPos += size;
+ return res;
+}
+
+STDMETHODIMP CLimitedCachedInStream::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 = _virtPos;
+ return S_OK;
+}
+
+STDMETHODIMP CTailOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 cur;
+ HRESULT res = Stream->Write(data, size, &cur);
+ if (processedSize)
+ *processedSize = cur;
+ _virtPos += cur;
+ if (_virtSize < _virtPos)
+ _virtSize = _virtPos;
+ return res;
+}
+
+STDMETHODIMP CTailOutStream::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 += _virtSize; break;
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
+ if (newPosition)
+ *newPosition = _virtPos;
+ return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL);
+}
+
+STDMETHODIMP CTailOutStream::SetSize(UInt64 newSize)
+{
+ _virtSize = newSize;
+ return Stream->SetSize(Offset + newSize);
+}
diff --git a/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h b/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h
index 2cbe18e4848..b521eeb933c 100644
--- a/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h
+++ b/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h
@@ -3,6 +3,7 @@
#ifndef __LIMITED_STREAMS_H
#define __LIMITED_STREAMS_H
+#include "../../Common/MyBuffer.h"
#include "../../Common/MyCom.h"
#include "../../Common/MyVector.h"
#include "../IStream.h"
@@ -25,7 +26,7 @@ public:
_wasFinished = false;
}
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
UInt64 GetSize() const { return _pos; }
@@ -54,7 +55,7 @@ public:
return SeekToPhys();
}
- MY_UNKNOWN_IMP1(IInStream)
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
@@ -62,6 +63,8 @@ public:
HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); }
};
+HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream);
+
class CClusterInStream:
public IInStream,
public CMyUnknownImp
@@ -70,11 +73,11 @@ class CClusterInStream:
UInt64 _physPos;
UInt32 _curRem;
public:
- CMyComPtr<IInStream> Stream;
- UInt64 StartOffset;
+ unsigned BlockSizeLog;
UInt64 Size;
- int BlockSizeLog;
+ CMyComPtr<IInStream> Stream;
CRecordVector<UInt32> Vector;
+ UInt64 StartOffset;
HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
@@ -91,13 +94,44 @@ public:
return S_OK;
}
- MY_UNKNOWN_IMP1(IInStream)
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
-HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream);
+struct CSeekExtent
+{
+ UInt64 Phy;
+ UInt64 Virt;
+};
+
+class CExtentsStream:
+ public IInStream,
+ public CMyUnknownImp
+{
+ UInt64 _phyPos;
+ UInt64 _virtPos;
+ bool _needStartSeek;
+
+ HRESULT SeekToPhys() { return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); }
+
+public:
+ CMyComPtr<IInStream> Stream;
+ CRecordVector<CSeekExtent> Extents;
+
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ void ReleaseStream() { Stream.Release(); }
+
+ void Init()
+ {
+ _virtPos = 0;
+ _phyPos = 0;
+ _needStartSeek = true;
+ }
+};
class CLimitedSequentialOutStream:
public ISequentialOutStream,
@@ -108,7 +142,7 @@ class CLimitedSequentialOutStream:
bool _overflow;
bool _overflowIsAllowed;
public:
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
@@ -122,4 +156,96 @@ public:
UInt64 GetRem() const { return _size; }
};
+
+class CTailInStream:
+ public IInStream,
+ public CMyUnknownImp
+{
+ UInt64 _virtPos;
+public:
+ CMyComPtr<IInStream> Stream;
+ UInt64 Offset;
+
+ void Init()
+ {
+ _virtPos = 0;
+ }
+
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+
+ HRESULT SeekToStart() { return Stream->Seek(Offset, STREAM_SEEK_SET, NULL); }
+};
+
+class CLimitedCachedInStream:
+ public IInStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<IInStream> _stream;
+ UInt64 _virtPos;
+ UInt64 _physPos;
+ UInt64 _size;
+ UInt64 _startOffset;
+
+ const Byte *_cache;
+ size_t _cacheSize;
+ size_t _cachePhyPos;
+
+
+ HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
+public:
+ CByteBuffer Buffer;
+
+ void SetStream(IInStream *stream) { _stream = stream; }
+ void SetCache(size_t cacheSize, size_t cachePos)
+ {
+ _cache = Buffer;
+ _cacheSize = cacheSize;
+ _cachePhyPos = cachePos;
+ }
+
+ HRESULT InitAndSeek(UInt64 startOffset, UInt64 size)
+ {
+ _startOffset = startOffset;
+ _physPos = startOffset;
+ _virtPos = 0;
+ _size = size;
+ return SeekToPhys();
+ }
+
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+
+ HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); }
+};
+
+class CTailOutStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ UInt64 _virtPos;
+ UInt64 _virtSize;
+public:
+ CMyComPtr<IOutStream> Stream;
+ UInt64 Offset;
+
+ virtual ~CTailOutStream() {}
+
+ MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStream)
+
+ void Init()
+ {
+ _virtPos = 0;
+ _virtSize = 0;
+ }
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(UInt64 newSize);
+};
+
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Common/LockedStream.cpp b/3rdparty/lzma/CPP/7zip/Common/LockedStream.cpp
index f05601cb6dc..ca39fb455d6 100644
--- a/3rdparty/lzma/CPP/7zip/Common/LockedStream.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/LockedStream.cpp
@@ -1,23 +1,3 @@
// LockedStream.cpp
#include "StdAfx.h"
-
-#include "LockedStream.h"
-
-HRESULT CLockedInStream::Read(UInt64 startPos, void *data, UInt32 size,
- UInt32 *processedSize)
-{
- NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
- RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL));
- return _stream->Read(data, size, processedSize);
-}
-
-STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
-{
- UInt32 realProcessedSize = 0;
- HRESULT result = _lockedInStream->Read(_pos, data, size, &realProcessedSize);
- _pos += realProcessedSize;
- if (processedSize != NULL)
- *processedSize = realProcessedSize;
- return result;
-}
diff --git a/3rdparty/lzma/CPP/7zip/Common/LockedStream.h b/3rdparty/lzma/CPP/7zip/Common/LockedStream.h
index 486e4220bc3..efebf197553 100644
--- a/3rdparty/lzma/CPP/7zip/Common/LockedStream.h
+++ b/3rdparty/lzma/CPP/7zip/Common/LockedStream.h
@@ -1,38 +1,6 @@
// LockedStream.h
-#ifndef __LOCKEDSTREAM_H
-#define __LOCKEDSTREAM_H
-
-#include "../../Windows/Synchronization.h"
-#include "../../Common/MyCom.h"
-#include "../IStream.h"
-
-class CLockedInStream
-{
- CMyComPtr<IInStream> _stream;
- NWindows::NSynchronization::CCriticalSection _criticalSection;
-public:
- void Init(IInStream *stream)
- { _stream = stream; }
- HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize);
-};
-
-class CLockedSequentialInStreamImp:
- public ISequentialInStream,
- public CMyUnknownImp
-{
- CLockedInStream *_lockedInStream;
- UInt64 _pos;
-public:
- void Init(CLockedInStream *lockedInStream, UInt64 startPos)
- {
- _lockedInStream = lockedInStream;
- _pos = startPos;
- }
-
- MY_UNKNOWN_IMP
-
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
-};
+#ifndef __LOCKED_STREAM_H
+#define __LOCKED_STREAM_H
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Common/MethodId.h b/3rdparty/lzma/CPP/7zip/Common/MethodId.h
index 54ebc9f7dae..28b615fcd3e 100644
--- a/3rdparty/lzma/CPP/7zip/Common/MethodId.h
+++ b/3rdparty/lzma/CPP/7zip/Common/MethodId.h
@@ -3,7 +3,7 @@
#ifndef __7Z_METHOD_ID_H
#define __7Z_METHOD_ID_H
-#include "../../Common/Types.h"
+#include "../../Common/MyTypes.h"
typedef UInt64 CMethodId;
diff --git a/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp b/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp
index e15a3cc827e..a5149ab5bb5 100644
--- a/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp
@@ -10,12 +10,12 @@ using namespace NWindows;
bool StringToBool(const UString &s, bool &res)
{
- if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0)
+ if (s.IsEmpty() || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON"))
{
res = true;
return true;
}
- if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0)
+ if ((s[0] == '-' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "OFF"))
{
res = false;
return true;
@@ -34,18 +34,12 @@ HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest)
return E_INVALIDARG;
}
-int ParseStringToUInt32(const UString &srcString, UInt32 &number)
+unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number)
{
const wchar_t *start = srcString;
const wchar_t *end;
- UInt64 number64 = ConvertStringToUInt64(start, &end);
- if (number64 > (UInt32)0xFFFFFFFF)
- {
- number = 0;
- return 0;
- }
- number = (UInt32)number64;
- return (int)(end - start);
+ number = ConvertStringToUInt32(start, &end);
+ return (unsigned)(end - start);
}
HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
@@ -66,7 +60,7 @@ HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &
if (name.IsEmpty())
return S_OK;
UInt32 v;
- if (ParseStringToUInt32(name, v) != name.Length())
+ if (ParseStringToUInt32(name, v) != name.Len())
return E_INVALIDARG;
resValue = v;
return S_OK;
@@ -96,61 +90,71 @@ HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 default
return ParsePropToUInt32(name, prop, numThreads);
}
-static HRESULT StringToDictSize(const UString &srcStringSpec, UInt32 &dicSize)
+
+static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp)
{
- UString srcString = srcStringSpec;
- srcString.MakeUpper();
- const wchar_t *start = srcString;
const wchar_t *end;
- UInt64 number = ConvertStringToUInt64(start, &end);
- int numDigits = (int)(end - start);
- if (numDigits == 0 || srcString.Length() > numDigits + 1)
+ UInt32 number = ConvertStringToUInt32(s, &end);
+ unsigned numDigits = (unsigned)(end - s);
+ if (numDigits == 0 || s.Len() > numDigits + 1)
return E_INVALIDARG;
- const unsigned kLogDictSizeLimit = 32;
- if (srcString.Length() == numDigits)
+
+ if (s.Len() == numDigits)
{
- if (number >= kLogDictSizeLimit)
+ if (number >= 64)
return E_INVALIDARG;
- dicSize = (UInt32)1 << (int)number;
+ if (number < 32)
+ destProp = (UInt32)((UInt32)1 << (unsigned)number);
+ else
+ destProp = (UInt64)((UInt64)1 << (unsigned)number);
return S_OK;
}
+
unsigned numBits;
- switch (srcString[numDigits])
+
+ switch (MyCharLower_Ascii(s[numDigits]))
{
- case 'B': numBits = 0; break;
- case 'K': numBits = 10; break;
- case 'M': numBits = 20; break;
- case 'G': numBits = 30; break;
+ case 'b': destProp = number; return S_OK;
+ case 'k': numBits = 10; break;
+ case 'm': numBits = 20; break;
+ case 'g': numBits = 30; break;
default: return E_INVALIDARG;
}
- if (number >= ((UInt64)1 << (kLogDictSizeLimit - numBits)))
- return E_INVALIDARG;
- dicSize = (UInt32)number << numBits;
+
+ if (number < ((UInt32)1 << (32 - numBits)))
+ destProp = (UInt32)(number << numBits);
+ else
+ destProp = (UInt64)((UInt64)number << numBits);
+
return S_OK;
}
-static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, UInt32 &resValue)
+
+static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVariant &destProp)
{
if (prop.vt == VT_UI4)
{
UInt32 v = prop.ulVal;
- if (v >= 32)
+ if (v >= 64)
return E_INVALIDARG;
- resValue = (UInt32)1 << v;
+ if (v < 32)
+ destProp = (UInt32)((UInt32)1 << (unsigned)v);
+ else
+ destProp = (UInt64)((UInt64)1 << (unsigned)v);
return S_OK;
}
if (prop.vt == VT_BSTR)
- return StringToDictSize(prop.bstrVal, resValue);
+ return StringToDictSize(prop.bstrVal, destProp);
return E_INVALIDARG;
}
+
void CProps::AddProp32(PROPID propid, UInt32 level)
{
- CProp prop;
+ CProp &prop = Props.AddNew();
prop.IsOptional = true;
prop.Id = propid;
prop.Value = (UInt32)level;
- Props.Add(prop);
}
class CCoderProps
@@ -191,7 +195,7 @@ void CCoderProps::AddProp(const CProp &prop)
HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const
{
CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0));
- for (int i = 0; i < Props.Size(); i++)
+ FOR_VECTOR (i, Props)
coderProps.AddProp(Props[i]);
if (dataSizeReduce)
{
@@ -226,34 +230,34 @@ int CMethodProps::GetLevel() const
struct CNameToPropID
{
VARTYPE VarType;
- const wchar_t *Name;
+ const char *Name;
};
static const CNameToPropID g_NameToPropID[] =
{
- { VT_UI4, L"" },
- { VT_UI4, L"d" },
- { VT_UI4, L"mem" },
- { VT_UI4, L"o" },
- { VT_UI4, L"c" },
- { VT_UI4, L"pb" },
- { VT_UI4, L"lc" },
- { VT_UI4, L"lp" },
- { VT_UI4, L"fb" },
- { VT_BSTR, L"mf" },
- { VT_UI4, L"mc" },
- { VT_UI4, L"pass" },
- { VT_UI4, L"a" },
- { VT_UI4, L"mt" },
- { VT_BOOL, L"eos" },
- { VT_UI4, L"x" },
- { VT_UI4, L"reduceSize" }
+ { VT_UI4, "" },
+ { VT_UI4, "d" },
+ { VT_UI4, "mem" },
+ { VT_UI4, "o" },
+ { VT_UI4, "c" },
+ { VT_UI4, "pb" },
+ { VT_UI4, "lc" },
+ { VT_UI4, "lp" },
+ { VT_UI4, "fb" },
+ { VT_BSTR, "mf" },
+ { VT_UI4, "mc" },
+ { VT_UI4, "pass" },
+ { VT_UI4, "a" },
+ { VT_UI4, "mt" },
+ { VT_BOOL, "eos" },
+ { VT_UI4, "x" },
+ { VT_UI4, "reduceSize" }
};
static int FindPropIdExact(const UString &name)
{
- for (unsigned i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
- if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)
+ for (unsigned i = 0; i < ARRAY_SIZE(g_NameToPropID); i++)
+ if (StringsAreEqualNoCase_Ascii(name, g_NameToPropID[i].Name))
return i;
return -1;
}
@@ -285,10 +289,10 @@ static void SplitParams(const UString &srcString, UStringVector &subStrings)
{
subStrings.Clear();
UString s;
- int len = srcString.Length();
+ unsigned len = srcString.Len();
if (len == 0)
return;
- for (int i = 0; i < len; i++)
+ for (unsigned i = 0; i < len; i++)
{
wchar_t c = srcString[i];
if (c == L':')
@@ -307,19 +311,19 @@ static void SplitParam(const UString &param, UString &name, UString &value)
int eqPos = param.Find(L'=');
if (eqPos >= 0)
{
- name = param.Left(eqPos);
- value = param.Mid(eqPos + 1);
+ name.SetFrom(param, eqPos);
+ value = param.Ptr(eqPos + 1);
return;
}
- int i;
- for (i = 0; i < param.Length(); i++)
+ unsigned i;
+ for (i = 0; i < param.Len(); i++)
{
wchar_t c = param[i];
if (c >= L'0' && c <= L'9')
break;
}
- name = param.Left(i);
- value = param.Mid(i);
+ name.SetFrom(param, i);
+ value = param.Ptr(i);
}
static bool IsLogSizeProp(PROPID propid)
@@ -340,15 +344,13 @@ HRESULT CMethodProps::SetParam(const UString &name, const UString &value)
int index = FindPropIdExact(name);
if (index < 0)
return E_INVALIDARG;
- const CNameToPropID &nameToPropID = g_NameToPropID[index];
+ const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index];
CProp prop;
prop.Id = index;
if (IsLogSizeProp(prop.Id))
{
- UInt32 dicSize;
- RINOK(StringToDictSize(value, dicSize));
- prop.Value = dicSize;
+ RINOK(StringToDictSize(value, prop.Value));
}
else
{
@@ -365,7 +367,7 @@ HRESULT CMethodProps::SetParam(const UString &name, const UString &value)
else if (!value.IsEmpty())
{
UInt32 number;
- if (ParseStringToUInt32(value, number) == value.Length())
+ if (ParseStringToUInt32(value, number) == value.Len())
propValue = number;
else
propValue = value;
@@ -381,7 +383,7 @@ HRESULT CMethodProps::ParseParamsFromString(const UString &srcString)
{
UStringVector params;
SplitParams(srcString, params);
- for (int i = 0; i < params.Size(); i++)
+ FOR_VECTOR (i, params)
{
const UString &param = params[i];
UString name, value;
@@ -393,7 +395,7 @@ HRESULT CMethodProps::ParseParamsFromString(const UString &srcString)
HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value)
{
- if (realName.Length() == 0)
+ if (realName.Len() == 0)
{
// [empty]=method
return E_INVALIDARG;
@@ -410,15 +412,13 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const
int index = FindPropIdExact(realName);
if (index < 0)
return E_INVALIDARG;
- const CNameToPropID &nameToPropID = g_NameToPropID[index];
+ const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index];
CProp prop;
prop.Id = index;
if (IsLogSizeProp(prop.Id))
{
- UInt32 dicSize;
- RINOK(PROPVARIANT_to_DictSize(value, dicSize));
- prop.Value = dicSize;
+ RINOK(PROPVARIANT_to_DictSize(value, prop.Value));
}
else
{
@@ -429,20 +429,30 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const
return S_OK;
}
+HRESULT COneMethodInfo::ParseMethodFromString(const UString &s)
+{
+ MethodName.Empty();
+ int splitPos = s.Find(L':');
+ {
+ UString temp = s;
+ if (splitPos >= 0)
+ temp.DeleteFrom(splitPos);
+ if (!temp.IsAscii())
+ return E_INVALIDARG;
+ MethodName.SetFromWStr_if_Ascii(temp);
+ }
+ if (splitPos < 0)
+ return S_OK;
+ PropsString = s.Ptr(splitPos + 1);
+ return ParseParamsFromString(PropsString);
+}
+
HRESULT COneMethodInfo::ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value)
{
- if (!realName.IsEmpty() && realName.CompareNoCase(L"m") != 0)
+ if (!realName.IsEmpty() && !StringsAreEqualNoCase_Ascii(realName, "m"))
return ParseParamsFromPROPVARIANT(realName, value);
// -m{N}=method
if (value.vt != VT_BSTR)
return E_INVALIDARG;
- const UString s = value.bstrVal;
- int splitPos = s.Find(':');
- if (splitPos < 0)
- {
- MethodName = s;
- return S_OK;
- }
- MethodName = s.Left(splitPos);
- return ParseParamsFromString(s.Mid(splitPos + 1));
+ return ParseMethodFromString(value.bstrVal);
}
diff --git a/3rdparty/lzma/CPP/7zip/Common/MethodProps.h b/3rdparty/lzma/CPP/7zip/Common/MethodProps.h
index 0bdddc6b711..765e425df6d 100644
--- a/3rdparty/lzma/CPP/7zip/Common/MethodProps.h
+++ b/3rdparty/lzma/CPP/7zip/Common/MethodProps.h
@@ -11,7 +11,7 @@
bool StringToBool(const UString &s, bool &res);
HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest);
-int ParseStringToUInt32(const UString &srcString, UInt32 &number);
+unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number);
HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
@@ -32,7 +32,7 @@ struct CProps
bool AreThereNonOptionalProps() const
{
- for (int i = 0; i < Props.Size(); i++)
+ FOR_VECTOR (i, Props)
if (!Props[i].IsOptional)
return true;
return false;
@@ -40,13 +40,12 @@ struct CProps
void AddProp32(PROPID propid, UInt32 level);
- void AddPropString(PROPID propid, const wchar_t *s)
+ void AddProp_Ascii(PROPID propid, const char *s)
{
- CProp prop;
+ CProp &prop = Props.AddNew();
prop.IsOptional = true;
prop.Id = propid;
prop.Value = s;
- Props.Add(prop);
}
HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const;
@@ -100,6 +99,14 @@ public:
return level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26));
}
+ bool Are_Lzma_Model_Props_Defined() const
+ {
+ if (FindProp(NCoderPropID::kPosStateBits) >= 0) return true;
+ if (FindProp(NCoderPropID::kLitContextBits) >= 0) return true;
+ if (FindProp(NCoderPropID::kLitPosBits) >= 0) return true;
+ return false;
+ }
+
UInt32 Get_Lzma_NumThreads(bool &fixedNumber) const
{
fixedNumber = false;
@@ -153,12 +160,12 @@ public:
return level >= 9 ? (192 << 20) : ((UInt32)1 << (level + 19));
}
- void AddLevelProp(UInt32 level)
+ void AddProp_Level(UInt32 level)
{
AddProp32(NCoderPropID::kLevel, level);
}
- void AddNumThreadsProp(UInt32 numThreads)
+ void AddProp_NumThreads(UInt32 numThreads)
{
AddProp32(NCoderPropID::kNumThreads, numThreads);
}
@@ -170,15 +177,18 @@ public:
class COneMethodInfo: public CMethodProps
{
public:
- UString MethodName;
+ AString MethodName;
+ UString PropsString;
void Clear()
{
CMethodProps::Clear();
MethodName.Empty();
+ PropsString.Empty();
}
bool IsEmpty() const { return MethodName.IsEmpty() && Props.IsEmpty(); }
HRESULT ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
+ HRESULT ParseMethodFromString(const UString &s);
};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp b/3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp
index c5e4e6da474..368d39b6514 100644
--- a/3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp
@@ -2,7 +2,8 @@
#include "StdAfx.h"
-#include "Common/Defs.h"
+#include "../../Common/Defs.h"
+
#include "OffsetStream.h"
HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset)
@@ -17,14 +18,17 @@ STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *proc
return _stream->Write(data, size, processedSize);
}
-STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin,
- UInt64 *newPosition)
+STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
UInt64 absoluteNewPosition;
if (seekOrigin == STREAM_SEEK_SET)
+ {
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
offset += _offset;
+ }
HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition);
- if (newPosition != NULL)
+ if (newPosition)
*newPosition = absoluteNewPosition - _offset;
return result;
}
diff --git a/3rdparty/lzma/CPP/7zip/Common/OffsetStream.h b/3rdparty/lzma/CPP/7zip/Common/OffsetStream.h
index de9d06dd028..9074a24e031 100644
--- a/3rdparty/lzma/CPP/7zip/Common/OffsetStream.h
+++ b/3rdparty/lzma/CPP/7zip/Common/OffsetStream.h
@@ -1,9 +1,10 @@
// OffsetStream.h
-#ifndef __OFFSETSTREAM_H
-#define __OFFSETSTREAM_H
+#ifndef __OFFSET_STREAM_H
+#define __OFFSET_STREAM_H
+
+#include "../../Common/MyCom.h"
-#include "Common/MyCom.h"
#include "../IStream.h"
class COffsetOutStream:
diff --git a/3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp b/3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp
index 2e5debd8335..4ba34a053b1 100644
--- a/3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp
@@ -6,34 +6,29 @@
#include "OutBuffer.h"
-bool COutBuffer::Create(UInt32 bufferSize)
+bool COutBuffer::Create(UInt32 bufSize) throw()
{
const UInt32 kMinBlockSize = 1;
- if (bufferSize < kMinBlockSize)
- bufferSize = kMinBlockSize;
- if (_buffer != 0 && _bufferSize == bufferSize)
+ if (bufSize < kMinBlockSize)
+ bufSize = kMinBlockSize;
+ if (_buf != 0 && _bufSize == bufSize)
return true;
Free();
- _bufferSize = bufferSize;
- _buffer = (Byte *)::MidAlloc(bufferSize);
- return (_buffer != 0);
+ _bufSize = bufSize;
+ _buf = (Byte *)::MidAlloc(bufSize);
+ return (_buf != 0);
}
-void COutBuffer::Free()
+void COutBuffer::Free() throw()
{
- ::MidFree(_buffer);
- _buffer = 0;
+ ::MidFree(_buf);
+ _buf = 0;
}
-void COutBuffer::SetStream(ISequentialOutStream *stream)
-{
- _stream = stream;
-}
-
-void COutBuffer::Init()
+void COutBuffer::Init() throw()
{
_streamPos = 0;
- _limitPos = _bufferSize;
+ _limitPos = _bufSize;
_pos = 0;
_processedSize = 0;
_overDict = false;
@@ -42,27 +37,27 @@ void COutBuffer::Init()
#endif
}
-UInt64 COutBuffer::GetProcessedSize() const
+UInt64 COutBuffer::GetProcessedSize() const throw()
{
UInt64 res = _processedSize + _pos - _streamPos;
if (_streamPos > _pos)
- res += _bufferSize;
+ res += _bufSize;
return res;
}
-HRESULT COutBuffer::FlushPart()
+HRESULT COutBuffer::FlushPart() throw()
{
- // _streamPos < _bufferSize
- UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
+ // _streamPos < _bufSize
+ UInt32 size = (_streamPos >= _pos) ? (_bufSize - _streamPos) : (_pos - _streamPos);
HRESULT result = S_OK;
#ifdef _NO_EXCEPTIONS
result = ErrorCode;
#endif
- if (_buffer2 != 0)
+ if (_buf2 != 0)
{
- memmove(_buffer2, _buffer + _streamPos, size);
- _buffer2 += size;
+ memcpy(_buf2, _buf + _streamPos, size);
+ _buf2 += size;
}
if (_stream != 0
@@ -72,30 +67,30 @@ HRESULT COutBuffer::FlushPart()
)
{
UInt32 processedSize = 0;
- result = _stream->Write(_buffer + _streamPos, size, &processedSize);
+ result = _stream->Write(_buf + _streamPos, size, &processedSize);
size = processedSize;
}
_streamPos += size;
- if (_streamPos == _bufferSize)
+ if (_streamPos == _bufSize)
_streamPos = 0;
- if (_pos == _bufferSize)
+ if (_pos == _bufSize)
{
_overDict = true;
_pos = 0;
}
- _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
+ _limitPos = (_streamPos > _pos) ? _streamPos : _bufSize;
_processedSize += size;
return result;
}
-HRESULT COutBuffer::Flush()
+HRESULT COutBuffer::Flush() throw()
{
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
return ErrorCode;
#endif
- while(_streamPos != _pos)
+ while (_streamPos != _pos)
{
HRESULT result = FlushPart();
if (result != S_OK)
diff --git a/3rdparty/lzma/CPP/7zip/Common/OutBuffer.h b/3rdparty/lzma/CPP/7zip/Common/OutBuffer.h
index 62e77caae46..3bdfb87c592 100644
--- a/3rdparty/lzma/CPP/7zip/Common/OutBuffer.h
+++ b/3rdparty/lzma/CPP/7zip/Common/OutBuffer.h
@@ -1,7 +1,7 @@
// OutBuffer.h
-#ifndef __OUTBUFFER_H
-#define __OUTBUFFER_H
+#ifndef __OUT_BUFFER_H
+#define __OUT_BUFFER_H
#include "../IStream.h"
#include "../../Common/MyCom.h"
@@ -17,39 +17,38 @@ struct COutBufferException: public CSystemException
class COutBuffer
{
protected:
- Byte *_buffer;
+ Byte *_buf;
UInt32 _pos;
UInt32 _limitPos;
UInt32 _streamPos;
- UInt32 _bufferSize;
- CMyComPtr<ISequentialOutStream> _stream;
+ UInt32 _bufSize;
+ ISequentialOutStream *_stream;
UInt64 _processedSize;
- Byte *_buffer2;
+ Byte *_buf2;
bool _overDict;
- HRESULT FlushPart();
+ HRESULT FlushPart() throw();
public:
#ifdef _NO_EXCEPTIONS
HRESULT ErrorCode;
#endif
- COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
+ COutBuffer(): _buf(0), _pos(0), _stream(0), _buf2(0) {}
~COutBuffer() { Free(); }
- bool Create(UInt32 bufferSize);
- void Free();
+ bool Create(UInt32 bufSize) throw();
+ void Free() throw();
- void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
- void SetStream(ISequentialOutStream *stream);
- void Init();
- HRESULT Flush();
+ void SetMemStream(Byte *buf) { _buf2 = buf; }
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void Init() throw();
+ HRESULT Flush() throw();
void FlushWithCheck();
- void ReleaseStream() { _stream.Release(); }
void WriteByte(Byte b)
{
- _buffer[_pos++] = b;
- if(_pos == _limitPos)
+ _buf[_pos++] = b;
+ if (_pos == _limitPos)
FlushWithCheck();
}
void WriteBytes(const void *data, size_t size)
@@ -58,7 +57,7 @@ public:
WriteByte(((const Byte *)data)[i]);
}
- UInt64 GetProcessedSize() const;
+ UInt64 GetProcessedSize() const throw();
};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp b/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp
index f24ff6b6fb8..41385ccb1cc 100644
--- a/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp
@@ -1,14 +1,16 @@
-// ProgressUtils.h
+// ProgressUtils.cpp
#include "StdAfx.h"
#include "ProgressUtils.h"
-CLocalProgress::CLocalProgress()
-{
- ProgressOffset = InSize = OutSize = 0;
- SendRatio = SendProgress = true;
-}
+CLocalProgress::CLocalProgress():
+ ProgressOffset(0),
+ InSize(0),
+ OutSize(0),
+ SendRatio(true),
+ SendProgress(true)
+ {}
void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain)
{
@@ -20,19 +22,26 @@ void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain)
STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
{
- UInt64 inSizeNew = InSize, outSizeNew = OutSize;
+ UInt64 inSize2 = InSize;
+ UInt64 outSize2 = OutSize;
+
if (inSize)
- inSizeNew += (*inSize);
+ inSize2 += (*inSize);
if (outSize)
- outSizeNew += (*outSize);
+ outSize2 += (*outSize);
+
if (SendRatio && _ratioProgress)
{
- RINOK(_ratioProgress->SetRatioInfo(&inSizeNew, &outSizeNew));
+ RINOK(_ratioProgress->SetRatioInfo(&inSize2, &outSize2));
}
- inSizeNew += ProgressOffset;
- outSizeNew += ProgressOffset;
+
if (SendProgress)
- return _progress->SetCompleted(_inSizeIsMain ? &inSizeNew : &outSizeNew);
+ {
+ inSize2 += ProgressOffset;
+ outSize2 += ProgressOffset;
+ return _progress->SetCompleted(_inSizeIsMain ? &inSize2 : &outSize2);
+ }
+
return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h b/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h
index bae5395c147..e94265ba715 100644
--- a/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h
+++ b/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h
@@ -1,7 +1,7 @@
// ProgressUtils.h
-#ifndef __PROGRESSUTILS_H
-#define __PROGRESSUTILS_H
+#ifndef __PROGRESS_UTILS_H
+#define __PROGRESS_UTILS_H
#include "../../Common/MyCom.h"
@@ -23,10 +23,11 @@ public:
bool SendProgress;
CLocalProgress();
+
void Init(IProgress *progress, bool inSizeIsMain);
HRESULT SetCur();
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ICompressProgressInfo)
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
diff --git a/3rdparty/lzma/CPP/7zip/Common/PropId.cpp b/3rdparty/lzma/CPP/7zip/Common/PropId.cpp
new file mode 100644
index 00000000000..11d20d55753
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Common/PropId.cpp
@@ -0,0 +1,108 @@
+// PropId.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/MyWindows.h"
+
+#include "../PropID.h"
+
+// VARTYPE
+const Byte k7z_PROPID_To_VARTYPE[kpid_NUM_DEFINED] =
+{
+ VT_EMPTY,
+ VT_UI4,
+ VT_UI4,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BOOL,
+ VT_UI8,
+ VT_UI8,
+ VT_UI4,
+ VT_FILETIME,
+ VT_FILETIME,
+ VT_FILETIME,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_UI4,
+ VT_UI4,
+ VT_BSTR,
+ VT_BOOL,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_UI8,
+ VT_BSTR,
+ VT_UI8,
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_BSTR, // or VT_UI8 kpidUnpackVer
+ VT_UI4, // or VT_UI8 kpidVolume
+ VT_BOOL,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI4,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_UI4, // kpidChecksum
+ VT_BSTR,
+ VT_UI8,
+ VT_BSTR, // or VT_UI8 kpidId
+ VT_BSTR,
+ VT_BSTR,
+ VT_UI4,
+ VT_UI4,
+ VT_BSTR,
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_UI4,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR, // kpidNtSecure
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BSTR, // SHA-1
+ VT_BSTR, // SHA-256
+ VT_BSTR,
+ VT_UI8,
+ VT_UI4,
+ VT_UI4,
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_UI8,
+ VT_UI8,
+ VT_BSTR, // kpidNtReparse
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_BOOL,
+ VT_BSTR,
+ VT_BSTR
+};
diff --git a/3rdparty/lzma/CPP/7zip/Common/RegisterArc.h b/3rdparty/lzma/CPP/7zip/Common/RegisterArc.h
index bc2a034fd53..3421ba1b164 100644
--- a/3rdparty/lzma/CPP/7zip/Common/RegisterArc.h
+++ b/3rdparty/lzma/CPP/7zip/Common/RegisterArc.h
@@ -5,28 +5,74 @@
#include "../Archive/IArchive.h"
-typedef IInArchive * (*CreateInArchiveP)();
-typedef IOutArchive * (*CreateOutArchiveP)();
-
struct CArcInfo
{
- const wchar_t *Name;
- const wchar_t *Ext;
- const wchar_t *AddExt;
- Byte ClassId;
- Byte Signature[16];
- int SignatureSize;
- bool KeepName;
- CreateInArchiveP CreateInArchive;
- CreateOutArchiveP CreateOutArchive;
+ UInt16 Flags;
+ Byte Id;
+ Byte SignatureSize;
+ UInt16 SignatureOffset;
+
+ const Byte *Signature;
+ const char *Name;
+ const char *Ext;
+ const char *AddExt;
+
+ Func_CreateInArchive CreateInArchive;
+ Func_CreateOutArchive CreateOutArchive;
+ Func_IsArc IsArc;
+
+ bool IsMultiSignature() const { return (Flags & NArcInfoFlags::kMultiSignature) != 0; }
};
-void RegisterArc(const CArcInfo *arcInfo);
+void RegisterArc(const CArcInfo *arcInfo) throw();
+
+
+#define IMP_CreateArcIn_2(c) \
+ static IInArchive *CreateArc() { return new c; }
+
+#define IMP_CreateArcIn IMP_CreateArcIn_2(CHandler())
+
+#ifdef EXTRACT_ONLY
+ #define IMP_CreateArcOut
+ #define CreateArcOut NULL
+#else
+ #define IMP_CreateArcOut static IOutArchive *CreateArcOut() { return new CHandler(); }
+#endif
+
+#define REGISTER_ARC_V(n, e, ae, id, sigSize, sig, offs, flags, crIn, crOut, isArc) \
+ static const CArcInfo g_ArcInfo = { flags, id, sigSize, offs, sig, n, e, ae, crIn, crOut, isArc } ; \
+
+#define REGISTER_ARC_R(n, e, ae, id, sigSize, sig, offs, flags, crIn, crOut, isArc) \
+ REGISTER_ARC_V(n, e, ae, id, sigSize, sig, offs, flags, crIn, crOut, isArc) \
+ struct CRegisterArc { CRegisterArc() { RegisterArc(&g_ArcInfo); }}; \
+ static CRegisterArc g_RegisterArc;
+
+
+#define REGISTER_ARC_I_CLS(cls, n, e, ae, id, sig, offs, flags, isArc) \
+ IMP_CreateArcIn_2(cls) \
+ REGISTER_ARC_R(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, CreateArc, NULL, isArc)
+
+#define REGISTER_ARC_I_CLS_NO_SIG(cls, n, e, ae, id, offs, flags, isArc) \
+ IMP_CreateArcIn_2(cls) \
+ REGISTER_ARC_R(n, e, ae, id, 0, NULL, offs, flags, CreateArc, NULL, isArc)
+
+#define REGISTER_ARC_I(n, e, ae, id, sig, offs, flags, isArc) \
+ REGISTER_ARC_I_CLS(CHandler(), n, e, ae, id, sig, offs, flags, isArc)
+
+#define REGISTER_ARC_I_NO_SIG(n, e, ae, id, offs, flags, isArc) \
+ REGISTER_ARC_I_CLS_NO_SIG(CHandler(), n, e, ae, id, offs, flags, isArc)
+
-#define REGISTER_ARC_NAME(x) CRegister ## x
+#define REGISTER_ARC_IO(n, e, ae, id, sig, offs, flags, isArc) \
+ IMP_CreateArcIn \
+ IMP_CreateArcOut \
+ REGISTER_ARC_R(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, CreateArc, CreateArcOut, isArc)
-#define REGISTER_ARC(x) struct REGISTER_ARC_NAME(x) { \
- REGISTER_ARC_NAME(x)() { RegisterArc(&g_ArcInfo); }}; \
- static REGISTER_ARC_NAME(x) g_RegisterArc;
+#define REGISTER_ARC_IO_DECREMENT_SIG(n, e, ae, id, sig, offs, flags, isArc) \
+ IMP_CreateArcIn \
+ IMP_CreateArcOut \
+ REGISTER_ARC_V(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, CreateArc, CreateArcOut, isArc) \
+ struct CRegisterArcDecSig { CRegisterArcDecSig() { sig[0]--; RegisterArc(&g_ArcInfo); }}; \
+ static CRegisterArcDecSig g_RegisterArc;
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h b/3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h
index 786b4a4ce90..7ddb7604b9a 100644
--- a/3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h
+++ b/3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h
@@ -1,33 +1,106 @@
// RegisterCodec.h
-#ifndef __REGISTERCODEC_H
-#define __REGISTERCODEC_H
+#ifndef __REGISTER_CODEC_H
+#define __REGISTER_CODEC_H
#include "../Common/MethodId.h"
+#include "../ICoder.h"
+
typedef void * (*CreateCodecP)();
+
struct CCodecInfo
{
CreateCodecP CreateDecoder;
CreateCodecP CreateEncoder;
CMethodId Id;
- const wchar_t *Name;
- UInt32 NumInStreams;
+ const char *Name;
+ UInt32 NumStreams;
bool IsFilter;
};
-void RegisterCodec(const CCodecInfo *codecInfo);
+void RegisterCodec(const CCodecInfo *codecInfo) throw();
+
+
+#define REGISTER_CODEC_CREATE_2(name, cls, i) static void *name() { return (void *)(i *)(new cls); }
+#define REGISTER_CODEC_CREATE(name, cls) REGISTER_CODEC_CREATE_2(name, cls, ICompressCoder)
#define REGISTER_CODEC_NAME(x) CRegisterCodec ## x
+#define REGISTER_CODEC_VAR static const CCodecInfo g_CodecInfo =
#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \
REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo); }}; \
static REGISTER_CODEC_NAME(x) g_RegisterCodec;
+
#define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x
+#define REGISTER_CODECS_VAR static const CCodecInfo g_CodecsInfo[] =
+
#define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \
- REGISTER_CODECS_NAME(x)() { for (int i = 0; i < sizeof(g_CodecsInfo) / sizeof(g_CodecsInfo[0]); i++) \
+ REGISTER_CODECS_NAME(x)() { for (unsigned i = 0; i < ARRAY_SIZE(g_CodecsInfo); i++) \
RegisterCodec(&g_CodecsInfo[i]); }}; \
static REGISTER_CODECS_NAME(x) g_RegisterCodecs;
+
+#define REGISTER_CODEC_2(x, crDec, crEnc, id, name) \
+ REGISTER_CODEC_VAR \
+ { crDec, crEnc, id, name, 1, false }; \
+ REGISTER_CODEC(x)
+
+
+#ifdef EXTRACT_ONLY
+ #define REGISTER_CODEC_E(x, clsDec, clsEnc, id, name) \
+ REGISTER_CODEC_CREATE(CreateDec, clsDec) \
+ REGISTER_CODEC_2(x, CreateDec, NULL, id, name)
+#else
+ #define REGISTER_CODEC_E(x, clsDec, clsEnc, id, name) \
+ REGISTER_CODEC_CREATE(CreateDec, clsDec) \
+ REGISTER_CODEC_CREATE(CreateEnc, clsEnc) \
+ REGISTER_CODEC_2(x, CreateDec, CreateEnc, id, name)
+#endif
+
+
+
+#define REGISTER_FILTER_CREATE(name, cls) REGISTER_CODEC_CREATE_2(name, cls, ICompressFilter)
+
+#define REGISTER_FILTER_ITEM(crDec, crEnc, id, name) \
+ { crDec, crEnc, id, name, 1, true }
+
+#define REGISTER_FILTER(x, crDec, crEnc, id, name) \
+ REGISTER_CODEC_VAR \
+ REGISTER_FILTER_ITEM(crDec, crEnc, id, name); \
+ REGISTER_CODEC(x)
+
+#ifdef EXTRACT_ONLY
+ #define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \
+ REGISTER_FILTER_CREATE(CreateDec, clsDec) \
+ REGISTER_FILTER(x, CreateDec, NULL, id, name)
+#else
+ #define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \
+ REGISTER_FILTER_CREATE(CreateDec, clsDec) \
+ REGISTER_FILTER_CREATE(CreateEnc, clsEnc) \
+ REGISTER_FILTER(x, CreateDec, CreateEnc, id, name)
+#endif
+
+
+
+struct CHasherInfo
+{
+ IHasher * (*CreateHasher)();
+ CMethodId Id;
+ const char *Name;
+ UInt32 DigestSize;
+};
+
+void RegisterHasher(const CHasherInfo *hasher) throw();
+
+#define REGISTER_HASHER_NAME(x) CRegHasher_ ## x
+
+#define REGISTER_HASHER(cls, id, name, size) \
+ STDMETHODIMP_(UInt32) cls::GetDigestSize() throw() { return size; } \
+ static IHasher *CreateHasherSpec() { return new cls(); } \
+ static const CHasherInfo g_HasherInfo = { CreateHasherSpec, id, name, size }; \
+ struct REGISTER_HASHER_NAME(cls) { REGISTER_HASHER_NAME(cls)() { RegisterHasher(&g_HasherInfo); }}; \
+ static REGISTER_HASHER_NAME(cls) g_RegisterHasher;
+
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Common/StdAfx.h b/3rdparty/lzma/CPP/7zip/Common/StdAfx.h
index ef555ec12ac..1cbd7feaeec 100644
--- a/3rdparty/lzma/CPP/7zip/Common/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/Common/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../Common/MyWindows.h"
-#include "../../Common/NewHandler.h"
+#include "../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp
index 7a4c0ed26ad..435440c6649 100644
--- a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp
@@ -12,7 +12,7 @@ class CBinderInStream:
{
CStreamBinder *_binder;
public:
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
~CBinderInStream() { _binder->CloseRead(); }
CBinderInStream(CStreamBinder *binder): _binder(binder) {}
@@ -27,7 +27,7 @@ class CBinderOutStream:
{
CStreamBinder *_binder;
public:
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
~CBinderOutStream() { _binder->CloseWrite(); }
CBinderOutStream(CStreamBinder *binder): _binder(binder) {}
@@ -40,26 +40,38 @@ STDMETHODIMP CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
WRes CStreamBinder::CreateEvents()
{
- RINOK(_canWrite_Event.Create(true));
+ RINOK(_canWrite_Event.Create());
RINOK(_canRead_Event.Create());
return _readingWasClosed_Event.Create();
}
void CStreamBinder::ReInit()
{
- _waitWrite = true;
+ _canWrite_Event.Reset();
_canRead_Event.Reset();
_readingWasClosed_Event.Reset();
+
+ // _readingWasClosed = false;
+ _readingWasClosed2 = false;
+
+ _waitWrite = true;
+ _bufSize = 0;
+ _buf = NULL;
ProcessedSize = 0;
+ // WritingWasCut = false;
}
void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream)
{
+ // _readingWasClosed = false;
+ _readingWasClosed2 = false;
+
_waitWrite = true;
_bufSize = 0;
_buf = NULL;
ProcessedSize = 0;
+ // WritingWasCut = false;
CBinderInStream *inStreamSpec = new CBinderInStream(this);
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
@@ -108,19 +120,37 @@ HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSiz
{
if (processedSize)
*processedSize = 0;
- if (size != 0)
+ if (size == 0)
+ return S_OK;
+
+ if (!_readingWasClosed2)
{
_buf = data;
_bufSize = size;
- _canWrite_Event.Reset();
_canRead_Event.Set();
+
+ /*
+ _canWrite_Event.Lock();
+ if (_readingWasClosed)
+ _readingWasClosed2 = true;
+ */
HANDLE events[2] = { _canWrite_Event, _readingWasClosed_Event };
DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
- if (waitResult != WAIT_OBJECT_0 + 0)
- return S_FALSE;
- if (processedSize)
- *processedSize = size;
+ if (waitResult >= WAIT_OBJECT_0 + 2)
+ return E_FAIL;
+
+ size -= _bufSize;
+ if (size != 0)
+ {
+ if (processedSize)
+ *processedSize = size;
+ return S_OK;
+ }
+ // if (waitResult == WAIT_OBJECT_0 + 1)
+ _readingWasClosed2 = true;
}
- return S_OK;
+
+ // WritingWasCut = true;
+ return k_My_HRESULT_WritingWasCut;
}
diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h
index f3fb53228dd..12088a94586 100644
--- a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h
+++ b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h
@@ -7,11 +7,27 @@
#include "../IStream.h"
+/*
+We don't use probably UNSAFE version:
+reader thread:
+ _canWrite_Event.Set();
+ _readingWasClosed = true
+ _canWrite_Event.Set();
+writer thread:
+ _canWrite_Event.Wait()
+ if (_readingWasClosed)
+Can second call of _canWrite_Event.Set() be executed without memory barrier, if event is already set?
+*/
+
class CStreamBinder
{
- NWindows::NSynchronization::CManualResetEvent _canWrite_Event;
+ NWindows::NSynchronization::CAutoResetEvent _canWrite_Event;
NWindows::NSynchronization::CManualResetEvent _canRead_Event;
NWindows::NSynchronization::CManualResetEvent _readingWasClosed_Event;
+
+ // bool _readingWasClosed;
+ bool _readingWasClosed2;
+ // bool WritingWasCut;
bool _waitWrite;
UInt32 _bufSize;
const void *_buf;
@@ -20,13 +36,23 @@ public:
WRes CreateEvents();
void CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream);
+
void ReInit();
+
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);
- void CloseRead() { _readingWasClosed_Event.Set(); }
+
+ void CloseRead()
+ {
+ _readingWasClosed_Event.Set();
+ // _readingWasClosed = true;
+ // _canWrite_Event.Set();
+ }
+
void CloseWrite()
{
- // _bufSize must be = 0
+ _buf = NULL;
+ _bufSize = 0;
_canRead_Event.Set();
}
};
diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp b/3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp
index 1b6b0af08ba..8136716d66f 100644
--- a/3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp
@@ -8,14 +8,49 @@
#include "StreamObjects.h"
+STDMETHODIMP CBufferInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+ if (size == 0)
+ return S_OK;
+ if (_pos >= Buf.Size())
+ return S_OK;
+ size_t rem = Buf.Size() - (size_t)_pos;
+ if (rem > size)
+ rem = (size_t)size;
+ memcpy(data, (const Byte *)Buf + (size_t)_pos, rem);
+ _pos += rem;
+ if (processedSize)
+ *processedSize = (UInt32)rem;
+ return S_OK;
+}
+
+STDMETHODIMP CBufferInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ switch (seekOrigin)
+ {
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _pos; break;
+ case STREAM_SEEK_END: offset += Buf.Size(); break;
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _pos = offset;
+ if (newPosition)
+ *newPosition = offset;
+ return S_OK;
+}
+
STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
if (size == 0)
return S_OK;
- if (_pos > _size)
- return E_FAIL;
+ if (_pos >= _size)
+ return S_OK;
size_t rem = _size - (size_t)_pos;
if (rem > size)
rem = (size_t)size;
@@ -28,26 +63,48 @@ STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET: _pos = offset; break;
- case STREAM_SEEK_CUR: _pos += offset; break;
- case STREAM_SEEK_END: _pos = _size + offset; break;
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _pos; break;
+ case STREAM_SEEK_END: offset += _size; break;
default: return STG_E_INVALIDFUNCTION;
}
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _pos = offset;
if (newPosition)
- *newPosition = _pos;
+ *newPosition = offset;
return S_OK;
}
-void CByteDynBuffer::Free()
+void Create_BufInStream_WithReference(const void *data, size_t size, IUnknown *ref, ISequentialInStream **stream)
+{
+ *stream = NULL;
+ CBufInStream *inStreamSpec = new CBufInStream;
+ CMyComPtr<ISequentialInStream> streamTemp = inStreamSpec;
+ inStreamSpec->Init((const Byte *)data, size, ref);
+ *stream = streamTemp.Detach();
+}
+
+void Create_BufInStream_WithNewBuffer(const void *data, size_t size, ISequentialInStream **stream)
+{
+ *stream = NULL;
+ CBufferInStream *inStreamSpec = new CBufferInStream;
+ CMyComPtr<ISequentialInStream> streamTemp = inStreamSpec;
+ inStreamSpec->Buf.CopyFrom((const Byte *)data, size);
+ inStreamSpec->Init();
+ *stream = streamTemp.Detach();
+}
+
+void CByteDynBuffer::Free() throw()
{
free(_buf);
_buf = 0;
_capacity = 0;
}
-bool CByteDynBuffer::EnsureCapacity(size_t cap)
+bool CByteDynBuffer::EnsureCapacity(size_t cap) throw()
{
if (cap <= _capacity)
return true;
@@ -79,8 +136,7 @@ Byte *CDynBufSeqOutStream::GetBufPtrForWriting(size_t addSize)
void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const
{
- dest.SetCapacity(_size);
- memcpy(dest, (const Byte *)_buffer, _size);
+ dest.CopyFrom((const Byte *)_buffer, _size);
}
STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
@@ -104,8 +160,11 @@ STDMETHODIMP CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *p
size_t rem = _size - _pos;
if (rem > size)
rem = (size_t)size;
- memcpy(_buffer + _pos, data, rem);
- _pos += rem;
+ if (rem != 0)
+ {
+ memcpy(_buffer + _pos, data, rem);
+ _pos += rem;
+ }
if (processedSize)
*processedSize = (UInt32)rem;
return (rem != 0 || size == 0) ? S_OK : E_FAIL;
@@ -123,7 +182,7 @@ STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size,
static const UInt64 kEmptyTag = (UInt64)(Int64)-1;
-void CCachedInStream::Free()
+void CCachedInStream::Free() throw()
{
MyFree(_tags);
_tags = 0;
@@ -131,7 +190,7 @@ void CCachedInStream::Free()
_data = 0;
}
-bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog)
+bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw()
{
unsigned sizeLog = blockSizeLog + numBlocksLog;
if (sizeLog >= sizeof(size_t) * 8)
@@ -157,7 +216,7 @@ bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog)
return true;
}
-void CCachedInStream::Init(UInt64 size)
+void CCachedInStream::Init(UInt64 size) throw()
{
_size = size;
_pos = 0;
@@ -172,8 +231,8 @@ STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
*processedSize = 0;
if (size == 0)
return S_OK;
- if (_pos > _size)
- return E_FAIL;
+ if (_pos >= _size)
+ return S_OK;
{
UInt64 rem = _size - _pos;
@@ -210,14 +269,17 @@ STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET: _pos = offset; break;
- case STREAM_SEEK_CUR: _pos = _pos + offset; break;
- case STREAM_SEEK_END: _pos = _size + offset; break;
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _pos; break;
+ case STREAM_SEEK_END: offset += _size; break;
default: return STG_E_INVALIDFUNCTION;
}
- if (newPosition != 0)
- *newPosition = _pos;
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _pos = offset;
+ if (newPosition)
+ *newPosition = offset;
return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamObjects.h b/3rdparty/lzma/CPP/7zip/Common/StreamObjects.h
index 8cd95c70075..e20e9bd80de 100644
--- a/3rdparty/lzma/CPP/7zip/Common/StreamObjects.h
+++ b/3rdparty/lzma/CPP/7zip/Common/StreamObjects.h
@@ -3,10 +3,27 @@
#ifndef __STREAM_OBJECTS_H
#define __STREAM_OBJECTS_H
-#include "../../Common/Buffer.h"
+#include "../../Common/MyBuffer.h"
#include "../../Common/MyCom.h"
+#include "../../Common/MyVector.h"
+
#include "../IStream.h"
+class CBufferInStream:
+ public IInStream,
+ public CMyUnknownImp
+{
+ UInt64 _pos;
+public:
+ CByteBuffer Buf;
+ void Init() { _pos = 0; }
+
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+};
+
struct CReferenceBuf:
public IUnknown,
public CMyUnknownImp
@@ -31,13 +48,18 @@ public:
_pos = 0;
_ref = ref;
}
- void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.GetCapacity(), ref); }
+ void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.Size(), ref); }
- MY_UNKNOWN_IMP1(IInStream)
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
+void Create_BufInStream_WithReference(const void *data, size_t size, IUnknown *ref, ISequentialInStream **stream);
+void Create_BufInStream_WithNewBuffer(const void *data, size_t size, ISequentialInStream **stream);
+inline void Create_BufInStream_WithNewBuffer(const CByteBuffer &buf, ISequentialInStream **stream)
+ { Create_BufInStream_WithNewBuffer(buf, buf.Size(), stream); }
+
class CByteDynBuffer
{
size_t _capacity;
@@ -46,11 +68,11 @@ public:
CByteDynBuffer(): _capacity(0), _buf(0) {};
// there is no copy constructor. So don't copy this object.
~CByteDynBuffer() { Free(); }
- void Free();
- size_t GetCapacity() const { return _capacity; }
- operator Byte*() const { return _buf; };
- operator const Byte*() const { return _buf; };
- bool EnsureCapacity(size_t capacity);
+ void Free() throw();
+ size_t GetCapacity() const { return _capacity; }
+ operator Byte*() const { return _buf; }
+ operator const Byte*() const { return _buf; }
+ bool EnsureCapacity(size_t capacity) throw();
};
class CDynBufSeqOutStream:
@@ -68,7 +90,7 @@ public:
Byte *GetBufPtrForWriting(size_t addSize);
void UpdateSize(size_t addSize) { _size += addSize; }
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
@@ -88,7 +110,7 @@ public:
}
size_t GetPos() const { return _pos; }
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
@@ -103,7 +125,7 @@ public:
void Init() { _size = 0; }
UInt64 GetSize() const { return _size; }
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
@@ -123,9 +145,9 @@ protected:
public:
CCachedInStream(): _tags(0), _data(0) {}
virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (release calls it) !!!
- void Free();
- bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog);
- void Init(UInt64 size);
+ void Free() throw();
+ bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw();
+ void Init(UInt64 size) throw();
MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp b/3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp
index 049e4aa1754..1402f420599 100644
--- a/3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp
@@ -6,7 +6,7 @@
static const UInt32 kBlockSize = ((UInt32)1 << 31);
-HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize)
+HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) throw()
{
size_t size = *processedSize;
*processedSize = 0;
@@ -25,21 +25,21 @@ HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSiz
return S_OK;
}
-HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size)
+HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw()
{
size_t processedSize = size;
RINOK(ReadStream(stream, data, &processedSize));
return (size == processedSize) ? S_OK : S_FALSE;
}
-HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size)
+HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw()
{
size_t processedSize = size;
RINOK(ReadStream(stream, data, &processedSize));
return (size == processedSize) ? S_OK : E_FAIL;
}
-HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size)
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw()
{
while (size != 0)
{
diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamUtils.h b/3rdparty/lzma/CPP/7zip/Common/StreamUtils.h
index f1cfd184842..ae914c004b0 100644
--- a/3rdparty/lzma/CPP/7zip/Common/StreamUtils.h
+++ b/3rdparty/lzma/CPP/7zip/Common/StreamUtils.h
@@ -1,13 +1,13 @@
// StreamUtils.h
-#ifndef __STREAMUTILS_H
-#define __STREAMUTILS_H
+#ifndef __STREAM_UTILS_H
+#define __STREAM_UTILS_H
#include "../IStream.h"
-HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *size);
-HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size);
-HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size);
-HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size);
+HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *size) throw();
+HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw();
+HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw();
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw();
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.cpp b/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.cpp
new file mode 100644
index 00000000000..8f754e177e8
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.cpp
@@ -0,0 +1,57 @@
+// UniqBlocks.cpp
+
+#include "StdAfx.h"
+
+#include <string.h>
+
+#include "UniqBlocks.h"
+
+unsigned CUniqBlocks::AddUniq(const Byte *data, size_t size)
+{
+ unsigned left = 0, right = Sorted.Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ unsigned index = Sorted[mid];
+ const CByteBuffer &buf = Bufs[index];
+ size_t sizeMid = buf.Size();
+ if (size < sizeMid)
+ right = mid;
+ else if (size > sizeMid)
+ left = mid + 1;
+ else
+ {
+ if (size == 0)
+ return index;
+ int cmp = memcmp(data, buf, size);
+ if (cmp == 0)
+ return index;
+ if (cmp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ }
+ unsigned index = Bufs.Size();
+ Sorted.Insert(left, index);
+ Bufs.AddNew().CopyFrom(data, size);
+ return index;
+}
+
+UInt64 CUniqBlocks::GetTotalSizeInBytes() const
+{
+ UInt64 size = 0;
+ FOR_VECTOR (i, Bufs)
+ size += Bufs[i].Size();
+ return size;
+}
+
+void CUniqBlocks::GetReverseMap()
+{
+ unsigned num = Sorted.Size();
+ BufIndexToSortedIndex.ClearAndSetSize(num);
+ unsigned *p = &BufIndexToSortedIndex[0];
+ const unsigned *sorted = &Sorted[0];
+ for (unsigned i = 0; i < num; i++)
+ p[sorted[i]] = i;
+}
diff --git a/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.h b/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.h
new file mode 100644
index 00000000000..a376024e3df
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.h
@@ -0,0 +1,26 @@
+// UniqBlocks.h
+
+#ifndef __UNIQ_BLOCKS_H
+#define __UNIQ_BLOCKS_H
+
+#include "../../Common/MyTypes.h"
+#include "../../Common/MyBuffer.h"
+#include "../../Common/MyVector.h"
+
+struct CUniqBlocks
+{
+ CObjectVector<CByteBuffer> Bufs;
+ CUIntVector Sorted;
+ CUIntVector BufIndexToSortedIndex;
+
+ unsigned AddUniq(const Byte *data, size_t size);
+ UInt64 GetTotalSizeInBytes() const;
+ void GetReverseMap();
+
+ bool IsOnlyEmpty() const
+ {
+ return (Bufs.Size() == 0 || Bufs.Size() == 1 && Bufs[0].Size() == 0);
+ }
+};
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.cpp b/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.cpp
index 684da5abfee..fd7ce7ef347 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.cpp
@@ -4,383 +4,655 @@
#include "../../../C/Alloc.h"
+#include "../Common/StreamUtils.h"
+
#include "Bcj2Coder.h"
namespace NCompress {
namespace NBcj2 {
-inline bool IsJcc(Byte b0, Byte b1) { return (b0 == 0x0F && (b1 & 0xF0) == 0x80); }
-inline bool IsJ(Byte b0, Byte b1) { return ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)); }
-inline unsigned GetIndex(Byte b0, Byte b1) { return ((b1 == 0xE8) ? b0 : ((b1 == 0xE9) ? 256 : 257)); }
-
-#ifndef EXTRACT_ONLY
-
-static const int kBufferSize = 1 << 17;
+CBaseCoder::CBaseCoder()
+{
+ for (int i = 0; i < BCJ2_NUM_STREAMS + 1; i++)
+ {
+ _bufs[i] = NULL;
+ _bufsCurSizes[i] = 0;
+ _bufsNewSizes[i] = (1 << 18);
+ }
+}
-static bool inline Test86MSByte(Byte b)
+CBaseCoder::~CBaseCoder()
{
- return (b == 0 || b == 0xFF);
+ for (int i = 0; i < BCJ2_NUM_STREAMS + 1; i++)
+ ::MidFree(_bufs[i]);
}
-bool CEncoder::Create()
+HRESULT CBaseCoder::Alloc(bool allocForOrig)
{
- if (!_mainStream.Create(1 << 18))
- return false;
- if (!_callStream.Create(1 << 18))
- return false;
- if (!_jumpStream.Create(1 << 18))
- return false;
- if (!_rangeEncoder.Create(1 << 20))
- return false;
- if (_buffer == 0)
+ unsigned num = allocForOrig ? BCJ2_NUM_STREAMS + 1 : BCJ2_NUM_STREAMS;
+ for (unsigned i = 0; i < num; i++)
{
- _buffer = (Byte *)MidAlloc(kBufferSize);
- if (_buffer == 0)
- return false;
+ UInt32 newSize = _bufsNewSizes[i];
+ const UInt32 kMinBufSize = 1;
+ if (newSize < kMinBufSize)
+ newSize = kMinBufSize;
+ if (!_bufs[i] || newSize != _bufsCurSizes[i])
+ {
+ if (_bufs[i])
+ {
+ ::MidFree(_bufs[i]);
+ _bufs[i] = 0;
+ }
+ _bufsCurSizes[i] = 0;
+ Byte *buf = (Byte *)::MidAlloc(newSize);
+ _bufs[i] = buf;
+ if (!buf)
+ return E_OUTOFMEMORY;
+ _bufsCurSizes[i] = newSize;
+ }
}
- return true;
+ return S_OK;
}
-CEncoder::~CEncoder()
-{
- ::MidFree(_buffer);
-}
-HRESULT CEncoder::Flush()
+
+#ifndef EXTRACT_ONLY
+
+CEncoder::CEncoder(): _relatLim(BCJ2_RELAT_LIMIT) {}
+CEncoder::~CEncoder() {}
+
+STDMETHODIMP CEncoder::SetInBufSize(UInt32, UInt32 size) { _bufsNewSizes[BCJ2_NUM_STREAMS] = size; return S_OK; }
+STDMETHODIMP CEncoder::SetOutBufSize(UInt32 streamIndex, UInt32 size) { _bufsNewSizes[streamIndex] = size; return S_OK; }
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
{
- RINOK(_mainStream.Flush());
- RINOK(_callStream.Flush());
- RINOK(_jumpStream.Flush());
- _rangeEncoder.FlushData();
- return _rangeEncoder.FlushStream();
+ UInt32 relatLim = BCJ2_RELAT_LIMIT;
+
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = props[i];
+ PROPID propID = propIDs[i];
+ if (propID >= NCoderPropID::kReduceSize)
+ continue;
+ switch (propID)
+ {
+ /*
+ case NCoderPropID::kDefaultProp:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 v = prop.ulVal;
+ if (v > 31)
+ return E_INVALIDARG;
+ relatLim = (UInt32)1 << v;
+ break;
+ }
+ */
+ case NCoderPropID::kDictionarySize:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ relatLim = prop.ulVal;
+ if (relatLim > ((UInt32)1 << 31))
+ return E_INVALIDARG;
+ break;
+ }
+
+ case NCoderPropID::kNumThreads:
+ continue;
+ case NCoderPropID::kLevel:
+ continue;
+
+ default: return E_INVALIDARG;
+ }
+ }
+
+ _relatLim = relatLim;
+
+ return S_OK;
}
-const UInt32 kDefaultLimit = (1 << 24);
-HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
- ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams,
+HRESULT CEncoder::CodeReal(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams,
+ ISequentialOutStream * const *outStreams, const UInt64 * const * /* outSizes */, UInt32 numOutStreams,
ICompressProgressInfo *progress)
{
- if (numInStreams != 1 || numOutStreams != 4)
+ if (numInStreams != 1 || numOutStreams != BCJ2_NUM_STREAMS)
return E_INVALIDARG;
- if (!Create())
- return E_OUTOFMEMORY;
+ RINOK(Alloc());
+
+ UInt32 fileSize_for_Conv = 0;
+ if (inSizes && inSizes[0])
+ {
+ UInt64 inSize = *inSizes[0];
+ if (inSize <= BCJ2_FileSize_MAX)
+ fileSize_for_Conv = (UInt32)inSize;
+ }
- bool sizeIsDefined = false;
- UInt64 inSize = 0;
- if (inSizes != NULL)
- if (inSizes[0] != NULL)
+ CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
+ inStreams[0]->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);
+
+ CBcj2Enc enc;
+
+ enc.src = _bufs[BCJ2_NUM_STREAMS];
+ enc.srcLim = enc.src;
+
+ {
+ for (int i = 0; i < BCJ2_NUM_STREAMS; i++)
{
- inSize = *inSizes[0];
- if (inSize <= kDefaultLimit)
- sizeIsDefined = true;
+ enc.bufs[i] = _bufs[i];
+ enc.lims[i] = _bufs[i] + _bufsCurSizes[i];
}
+ }
- CCoderReleaser releaser(this);
-
- ISequentialInStream *inStream = inStreams[0];
+ size_t numBytes_in_ReadBuf = 0;
+ UInt64 prevProgress = 0;
+ UInt64 totalStreamRead = 0; // size read from InputStream
+ UInt64 currentInPos = 0; // data that was processed, it doesn't include data in input buffer and data in enc.temp
+ UInt64 outSizeRc = 0;
- _mainStream.SetStream(outStreams[0]);
- _mainStream.Init();
- _callStream.SetStream(outStreams[1]);
- _callStream.Init();
- _jumpStream.SetStream(outStreams[2]);
- _jumpStream.Init();
- _rangeEncoder.SetStream(outStreams[3]);
- _rangeEncoder.Init();
- for (int i = 0; i < 256 + 2; i++)
- _statusEncoder[i].Init();
+ Bcj2Enc_Init(&enc);
- CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
- {
- inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);
- }
+ enc.fileIp = 0;
+ enc.fileSize = fileSize_for_Conv;
- UInt32 nowPos = 0;
- UInt64 nowPos64 = 0;
- UInt32 bufferPos = 0;
+ enc.relatLimit = _relatLim;
- Byte prevByte = 0;
+ enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE;
+ bool needSubSize = false;
UInt64 subStreamIndex = 0;
- UInt64 subStreamStartPos = 0;
- UInt64 subStreamEndPos = 0;
+ UInt64 subStreamStartPos = 0;
+ bool readWasFinished = false;
for (;;)
{
- UInt32 processedSize = 0;
- for (;;)
- {
- UInt32 size = kBufferSize - (bufferPos + processedSize);
- UInt32 processedSizeLoc;
- if (size == 0)
- break;
- RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc));
- if (processedSizeLoc == 0)
- break;
- processedSize += processedSizeLoc;
- }
- UInt32 endPos = bufferPos + processedSize;
-
- if (endPos < 5)
- {
- // change it
- for (bufferPos = 0; bufferPos < endPos; bufferPos++)
- {
- Byte b = _buffer[bufferPos];
- _mainStream.WriteByte(b);
- UInt32 index;
- if (b == 0xE8)
- index = prevByte;
- else if (b == 0xE9)
- index = 256;
- else if (IsJcc(prevByte, b))
- index = 257;
- else
- {
- prevByte = b;
- continue;
- }
- _statusEncoder[index].Encode(&_rangeEncoder, 0);
- prevByte = b;
- }
- return Flush();
- }
-
- bufferPos = 0;
-
- UInt32 limit = endPos - 5;
- while(bufferPos <= limit)
+ if (needSubSize && getSubStreamSize)
{
- Byte b = _buffer[bufferPos];
- _mainStream.WriteByte(b);
- if (!IsJ(prevByte, b))
+ enc.fileIp = 0;
+ enc.fileSize = fileSize_for_Conv;
+ enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE;
+
+ for (;;)
{
- bufferPos++;
- prevByte = b;
- continue;
- }
- Byte nextByte = _buffer[bufferPos + 4];
- UInt32 src =
- (UInt32(nextByte) << 24) |
- (UInt32(_buffer[bufferPos + 3]) << 16) |
- (UInt32(_buffer[bufferPos + 2]) << 8) |
- (_buffer[bufferPos + 1]);
- UInt32 dest = (nowPos + bufferPos + 5) + src;
- // if (Test86MSByte(nextByte))
- bool convert;
- if (getSubStreamSize != NULL)
- {
- UInt64 currentPos = (nowPos64 + bufferPos);
- while (subStreamEndPos < currentPos)
+ UInt64 subStreamSize = 0;
+ HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);
+ needSubSize = false;
+
+ if (result == S_OK)
{
- UInt64 subStreamSize;
- HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);
- if (result == S_OK)
+ UInt64 newEndPos = subStreamStartPos + subStreamSize;
+
+ bool isAccurateEnd = (newEndPos < totalStreamRead ||
+ (newEndPos <= totalStreamRead && readWasFinished));
+
+ if (newEndPos <= currentInPos && isAccurateEnd)
{
- subStreamStartPos = subStreamEndPos;
- subStreamEndPos += subStreamSize;
+ subStreamStartPos = newEndPos;
subStreamIndex++;
+ continue;
}
- else if (result == S_FALSE || result == E_NOTIMPL)
+
+ enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf;
+
+ if (isAccurateEnd)
{
- getSubStreamSize.Release();
- subStreamStartPos = 0;
- subStreamEndPos = subStreamStartPos - 1;
+ // data in enc.temp is possible here
+ size_t rem = (size_t)(totalStreamRead - newEndPos);
+
+ /* Pos_of(enc.src) <= old newEndPos <= newEndPos
+ in another case, it's fail in some code */
+ if ((size_t)(enc.srcLim - enc.src) < rem)
+ return E_FAIL;
+
+ enc.srcLim -= rem;
+ enc.finishMode = BCJ2_ENC_FINISH_MODE_END_BLOCK;
}
- else
- return result;
- }
- if (getSubStreamSize == NULL)
- {
- if (sizeIsDefined)
- convert = (dest < inSize);
- else
- convert = Test86MSByte(nextByte);
+
+ if (subStreamSize <= BCJ2_FileSize_MAX)
+ {
+ enc.fileIp = enc.ip + (UInt32)(subStreamStartPos - currentInPos);
+ enc.fileSize = (UInt32)subStreamSize;
+ }
+ break;
}
- else if (subStreamEndPos - subStreamStartPos > kDefaultLimit)
- convert = Test86MSByte(nextByte);
- else
+
+ if (result == S_FALSE)
+ break;
+ if (result == E_NOTIMPL)
{
- UInt64 dest64 = (currentPos + 5) + Int64(Int32(src));
- convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos);
+ getSubStreamSize.Release();
+ break;
}
+ return result;
}
- else if (sizeIsDefined)
- convert = (dest < inSize);
- else
- convert = Test86MSByte(nextByte);
- unsigned index = GetIndex(prevByte, b);
- if (convert)
+ }
+
+ if (readWasFinished && totalStreamRead - currentInPos == Bcj2Enc_Get_InputData_Size(&enc))
+ enc.finishMode = BCJ2_ENC_FINISH_MODE_END_STREAM;
+
+ Bcj2Enc_Encode(&enc);
+
+ currentInPos = totalStreamRead - numBytes_in_ReadBuf + (enc.src - _bufs[BCJ2_NUM_STREAMS]) - enc.tempPos;
+
+ if (Bcj2Enc_IsFinished(&enc))
+ break;
+
+ if (enc.state < BCJ2_NUM_STREAMS)
+ {
+ size_t curSize = enc.bufs[enc.state] - _bufs[enc.state];
+ // printf("Write stream = %2d %6d\n", enc.state, curSize);
+ RINOK(WriteStream(outStreams[enc.state], _bufs[enc.state], curSize));
+ if (enc.state == BCJ2_STREAM_RC)
+ outSizeRc += curSize;
+
+ enc.bufs[enc.state] = _bufs[enc.state];
+ enc.lims[enc.state] = _bufs[enc.state] + _bufsCurSizes[enc.state];
+ }
+ else if (enc.state != BCJ2_ENC_STATE_ORIG)
+ return E_FAIL;
+ else
+ {
+ needSubSize = true;
+
+ if (numBytes_in_ReadBuf != (size_t)(enc.src - _bufs[BCJ2_NUM_STREAMS]))
{
- _statusEncoder[index].Encode(&_rangeEncoder, 1);
- bufferPos += 5;
- COutBuffer &s = (b == 0xE8) ? _callStream : _jumpStream;
- for (int i = 24; i >= 0; i -= 8)
- s.WriteByte((Byte)(dest >> i));
- prevByte = nextByte;
+ enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf;
+ continue;
}
- else
+
+ if (readWasFinished)
+ continue;
+
+ numBytes_in_ReadBuf = 0;
+ enc.src = _bufs[BCJ2_NUM_STREAMS];
+ enc.srcLim = _bufs[BCJ2_NUM_STREAMS];
+
+ UInt32 curSize = _bufsCurSizes[BCJ2_NUM_STREAMS];
+ RINOK(inStreams[0]->Read(_bufs[BCJ2_NUM_STREAMS], curSize, &curSize));
+
+ // printf("Read %6d bytes\n", curSize);
+ if (curSize == 0)
{
- _statusEncoder[index].Encode(&_rangeEncoder, 0);
- bufferPos++;
- prevByte = b;
+ readWasFinished = true;
+ continue;
}
+
+ numBytes_in_ReadBuf = curSize;
+ totalStreamRead += numBytes_in_ReadBuf;
+ enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf;
}
- nowPos += bufferPos;
- nowPos64 += bufferPos;
- if (progress != NULL)
+ if (progress && currentInPos - prevProgress >= (1 << 20))
{
- /*
- const UInt64 compressedSize =
- _mainStream.GetProcessedSize() +
- _callStream.GetProcessedSize() +
- _jumpStream.GetProcessedSize() +
- _rangeEncoder.GetProcessedSize();
- */
- RINOK(progress->SetRatioInfo(&nowPos64, NULL));
+ UInt64 outSize2 = currentInPos + outSizeRc + enc.bufs[BCJ2_STREAM_RC] - enc.bufs[BCJ2_STREAM_RC];
+ prevProgress = currentInPos;
+ // printf("progress %8d, %8d\n", (int)inSize2, (int)outSize2);
+ RINOK(progress->SetRatioInfo(&currentInPos, &outSize2));
}
-
- UInt32 i = 0;
- while(bufferPos < endPos)
- _buffer[i++] = _buffer[bufferPos++];
- bufferPos = i;
}
+
+ for (int i = 0; i < BCJ2_NUM_STREAMS; i++)
+ {
+ RINOK(WriteStream(outStreams[i], _bufs[i], enc.bufs[i] - _bufs[i]));
+ }
+
+ // if (currentInPos != subStreamStartPos + subStreamSize) return E_FAIL;
+
+ return S_OK;
}
-STDMETHODIMP CEncoder::Code(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
- ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
+STDMETHODIMP CEncoder::Code(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams,
+ ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams,
ICompressProgressInfo *progress)
{
try
{
return CodeReal(inStreams, inSizes, numInStreams, outStreams, outSizes,numOutStreams, progress);
}
- catch(const COutBufferException &e) { return e.ErrorCode; }
- catch(...) { return S_FALSE; }
+ catch(...) { return E_FAIL; }
}
#endif
-STDMETHODIMP CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size) { _inBufSizes[streamIndex] = size; return S_OK; }
-STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; }
-CDecoder::CDecoder():
- _outBufSize(1 << 16)
+
+
+
+STDMETHODIMP CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size) { _bufsNewSizes[streamIndex] = size; return S_OK; }
+STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _bufsNewSizes[BCJ2_NUM_STREAMS] = size; return S_OK; }
+
+CDecoder::CDecoder(): _finishMode(false), _outSizeDefined(false), _outSize(0)
+{}
+
+STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
+{
+ _finishMode = (finishMode != 0);
+ return S_OK;
+}
+
+void CDecoder::InitCommon()
{
- _inBufSizes[0] = 1 << 20;
- _inBufSizes[1] = 1 << 20;
- _inBufSizes[2] = 1 << 20;
- _inBufSizes[3] = 1 << 20;
+ {
+ for (int i = 0; i < BCJ2_NUM_STREAMS; i++)
+ dec.lims[i] = dec.bufs[i] = _bufs[i];
+ }
+
+ {
+ for (int i = 0; i < BCJ2_NUM_STREAMS; i++)
+ {
+ _extraReadSizes[i] = 0;
+ _inStreamsProcessed[i] = 0;
+ _readRes[i] = S_OK;
+ }
+ }
+
+ Bcj2Dec_Init(&dec);
}
-HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams, const UInt64 ** /* inSizes */, UInt32 numInStreams,
- ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams,
+HRESULT CDecoder::Code(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams,
+ ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams,
ICompressProgressInfo *progress)
{
- if (numInStreams != 4 || numOutStreams != 1)
+ if (numInStreams != BCJ2_NUM_STREAMS || numOutStreams != 1)
return E_INVALIDARG;
- if (!_mainInStream.Create(_inBufSizes[0]))
- return E_OUTOFMEMORY;
- if (!_callStream.Create(_inBufSizes[1]))
- return E_OUTOFMEMORY;
- if (!_jumpStream.Create(_inBufSizes[2]))
- return E_OUTOFMEMORY;
- if (!_rangeDecoder.Create(_inBufSizes[3]))
- return E_OUTOFMEMORY;
- if (!_outStream.Create(_outBufSize))
- return E_OUTOFMEMORY;
-
- CCoderReleaser releaser(this);
-
- _mainInStream.SetStream(inStreams[0]);
- _callStream.SetStream(inStreams[1]);
- _jumpStream.SetStream(inStreams[2]);
- _rangeDecoder.SetStream(inStreams[3]);
- _outStream.SetStream(outStreams[0]);
-
- _mainInStream.Init();
- _callStream.Init();
- _jumpStream.Init();
- _rangeDecoder.Init();
- _outStream.Init();
-
- for (int i = 0; i < 256 + 2; i++)
- _statusDecoder[i].Init();
-
- Byte prevByte = 0;
- UInt32 processedBytes = 0;
+ RINOK(Alloc());
+
+ InitCommon();
+
+ dec.destLim = dec.dest = _bufs[BCJ2_NUM_STREAMS];
+
+ UInt64 outSizeProcessed = 0;
+ UInt64 prevProgress = 0;
+
+ HRESULT res = S_OK;
+
for (;;)
{
- if (processedBytes >= (1 << 20) && progress != NULL)
+ if (Bcj2Dec_Decode(&dec) != SZ_OK)
+ return S_FALSE;
+
+ if (dec.state < BCJ2_NUM_STREAMS)
{
- /*
- const UInt64 compressedSize =
- _mainInStream.GetProcessedSize() +
- _callStream.GetProcessedSize() +
- _jumpStream.GetProcessedSize() +
- _rangeDecoder.GetProcessedSize();
- */
- const UInt64 nowPos64 = _outStream.GetProcessedSize();
- RINOK(progress->SetRatioInfo(NULL, &nowPos64));
- processedBytes = 0;
+ size_t totalRead = _extraReadSizes[dec.state];
+ {
+ Byte *buf = _bufs[dec.state];
+ for (size_t i = 0; i < totalRead; i++)
+ buf[i] = dec.bufs[dec.state][i];
+ dec.lims[dec.state] =
+ dec.bufs[dec.state] = buf;
+ }
+
+ if (_readRes[dec.state] != S_OK)
+ {
+ res = _readRes[dec.state];
+ break;
+ }
+
+ do
+ {
+ UInt32 curSize = _bufsCurSizes[dec.state] - (UInt32)totalRead;
+ /*
+ we want to call Read even even if size is 0
+ if (inSizes && inSizes[dec.state])
+ {
+ UInt64 rem = *inSizes[dec.state] - _inStreamsProcessed[dec.state];
+ if (curSize > rem)
+ curSize = (UInt32)rem;
+ }
+ */
+
+ HRESULT res2 = inStreams[dec.state]->Read(_bufs[dec.state] + totalRead, curSize, &curSize);
+ _readRes[dec.state] = res2;
+ if (curSize == 0)
+ break;
+ _inStreamsProcessed[dec.state] += curSize;
+ totalRead += curSize;
+ if (res2 != S_OK)
+ break;
+ }
+ while (totalRead < 4 && BCJ2_IS_32BIT_STREAM(dec.state));
+
+ if (_readRes[dec.state] != S_OK)
+ res = _readRes[dec.state];
+
+ if (totalRead == 0)
+ break;
+
+ // res == S_OK;
+
+ if (BCJ2_IS_32BIT_STREAM(dec.state))
+ {
+ unsigned extraSize = ((unsigned)totalRead & 3);
+ _extraReadSizes[dec.state] = extraSize;
+ if (totalRead < 4)
+ {
+ res = (_readRes[dec.state] != S_OK) ? _readRes[dec.state] : S_FALSE;
+ break;
+ }
+ totalRead -= extraSize;
+ }
+
+ dec.lims[dec.state] = _bufs[dec.state] + totalRead;
}
- UInt32 i;
- Byte b = 0;
- const UInt32 kBurstSize = (1 << 18);
- for (i = 0; i < kBurstSize; i++)
+ else // if (dec.state <= BCJ2_STATE_ORIG)
{
- if (!_mainInStream.ReadByte(b))
- return Flush();
- _outStream.WriteByte(b);
- if (IsJ(prevByte, b))
- break;
- prevByte = b;
+ size_t curSize = dec.dest - _bufs[BCJ2_NUM_STREAMS];
+ if (curSize != 0)
+ {
+ outSizeProcessed += curSize;
+ RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize));
+ }
+ dec.dest = _bufs[BCJ2_NUM_STREAMS];
+ {
+ size_t rem = _bufsCurSizes[BCJ2_NUM_STREAMS];
+ if (outSizes && outSizes[0])
+ {
+ UInt64 outSize = *outSizes[0] - outSizeProcessed;
+ if (rem > outSize)
+ rem = (size_t)outSize;
+ }
+ dec.destLim = dec.dest + rem;
+ if (rem == 0)
+ break;
+ }
}
- processedBytes += i;
- if (i == kBurstSize)
- continue;
- unsigned index = GetIndex(prevByte, b);
- if (_statusDecoder[index].Decode(&_rangeDecoder) == 1)
+
+ if (progress)
{
- UInt32 src = 0;
- CInBuffer &s = (b == 0xE8) ? _callStream : _jumpStream;
- for (int i = 0; i < 4; i++)
+ UInt64 outSize2 = outSizeProcessed + (dec.dest - _bufs[BCJ2_NUM_STREAMS]);
+ if (outSize2 - prevProgress >= (1 << 22))
{
- Byte b0;
- if(!s.ReadByte(b0))
+ UInt64 inSize2 = outSize2 + _inStreamsProcessed[BCJ2_STREAM_RC] - (dec.lims[BCJ2_STREAM_RC] - dec.bufs[BCJ2_STREAM_RC]);
+ RINOK(progress->SetRatioInfo(&inSize2, &outSize2));
+ prevProgress = outSize2;
+ }
+ }
+ }
+
+ size_t curSize = dec.dest - _bufs[BCJ2_NUM_STREAMS];
+ if (curSize != 0)
+ {
+ outSizeProcessed += curSize;
+ RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize));
+ }
+
+ if (res != S_OK)
+ return res;
+
+ if (_finishMode)
+ {
+ if (!Bcj2Dec_IsFinished(&dec))
+ return S_FALSE;
+
+ // we still allow the cases when input streams are larger than required for decoding.
+ // so the case (dec.state == BCJ2_STATE_ORIG) is also allowed, if MAIN stream is larger than required.
+ if (dec.state != BCJ2_STREAM_MAIN &&
+ dec.state != BCJ2_DEC_STATE_ORIG)
+ return S_FALSE;
+
+ if (inSizes)
+ {
+ for (int i = 0; i < BCJ2_NUM_STREAMS; i++)
+ {
+ size_t rem = dec.lims[i] - dec.bufs[i] + _extraReadSizes[i];
+ /*
+ if (rem != 0)
+ return S_FALSE;
+ */
+ if (inSizes[i] && *inSizes[i] != _inStreamsProcessed[i] - rem)
return S_FALSE;
- src <<= 8;
- src |= ((UInt32)b0);
}
- UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ;
- _outStream.WriteByte((Byte)(dest));
- _outStream.WriteByte((Byte)(dest >> 8));
- _outStream.WriteByte((Byte)(dest >> 16));
- _outStream.WriteByte((Byte)(dest >> 24));
- prevByte = (Byte)(dest >> 24);
- processedBytes += 4;
}
- else
- prevByte = b;
}
+
+ return S_OK;
}
-STDMETHODIMP CDecoder::Code(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
- ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
- ICompressProgressInfo *progress)
+STDMETHODIMP CDecoder::SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream)
{
- try
+ inStreams[streamIndex] = inStream;
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::ReleaseInStream2(UInt32 streamIndex)
+{
+ inStreams[streamIndex].Release();
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+{
+ _outSizeDefined = (outSize != NULL);
+ _outSize = 0;
+ if (_outSizeDefined)
+ _outSize = *outSize;
+
+ _outSize_Processed = 0;
+
+ HRESULT res = Alloc(false);
+
+ InitCommon();
+ dec.destLim = dec.dest = NULL;
+
+ return res;
+}
+
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+
+ if (size == 0)
+ return S_OK;
+
+ UInt32 totalProcessed = 0;
+
+ if (_outSizeDefined)
{
- return CodeReal(inStreams, inSizes, numInStreams, outStreams, outSizes,numOutStreams, progress);
+ UInt64 rem = _outSize - _outSize_Processed;
+ if (size > rem)
+ size = (UInt32)rem;
+ }
+ dec.dest = (Byte *)data;
+ dec.destLim = (const Byte *)data + size;
+
+ HRESULT res = S_OK;
+
+ for (;;)
+ {
+ SRes sres = Bcj2Dec_Decode(&dec);
+ if (sres != SZ_OK)
+ return S_FALSE;
+
+ {
+ UInt32 curSize = (UInt32)(dec.dest - (Byte *)data);
+ if (curSize != 0)
+ {
+ totalProcessed += curSize;
+ if (processedSize)
+ *processedSize = totalProcessed;
+ data = (void *)((Byte *)data + curSize);
+ size -= curSize;
+ _outSize_Processed += curSize;
+ }
+ }
+
+ if (dec.state >= BCJ2_NUM_STREAMS)
+ break;
+
+ {
+ size_t totalRead = _extraReadSizes[dec.state];
+ {
+ Byte *buf = _bufs[dec.state];
+ for (size_t i = 0; i < totalRead; i++)
+ buf[i] = dec.bufs[dec.state][i];
+ dec.lims[dec.state] =
+ dec.bufs[dec.state] = buf;
+ }
+
+ if (_readRes[dec.state] != S_OK)
+ return _readRes[dec.state];
+
+ do
+ {
+ UInt32 curSize = _bufsCurSizes[dec.state] - (UInt32)totalRead;
+ HRESULT res2 = inStreams[dec.state]->Read(_bufs[dec.state] + totalRead, curSize, &curSize);
+ _readRes[dec.state] = res2;
+ if (curSize == 0)
+ break;
+ _inStreamsProcessed[dec.state] += curSize;
+ totalRead += curSize;
+ if (res2 != S_OK)
+ break;
+ }
+ while (totalRead < 4 && BCJ2_IS_32BIT_STREAM(dec.state));
+
+ if (totalRead == 0)
+ {
+ if (totalProcessed == 0)
+ res = _readRes[dec.state];
+ break;
+ }
+
+ if (BCJ2_IS_32BIT_STREAM(dec.state))
+ {
+ unsigned extraSize = ((unsigned)totalRead & 3);
+ _extraReadSizes[dec.state] = extraSize;
+ if (totalRead < 4)
+ {
+ if (totalProcessed != 0)
+ return S_OK;
+ return (_readRes[dec.state] != S_OK) ? _readRes[dec.state] : S_FALSE;
+ }
+ totalRead -= extraSize;
+ }
+
+ dec.lims[dec.state] = _bufs[dec.state] + totalRead;
+ }
+ }
+
+ if (_finishMode && _outSizeDefined && _outSize == _outSize_Processed)
+ {
+ if (!Bcj2Dec_IsFinished(&dec))
+ return S_FALSE;
+
+ if (dec.state != BCJ2_STREAM_MAIN &&
+ dec.state != BCJ2_DEC_STATE_ORIG)
+ return S_FALSE;
+
+ /*
+ for (int i = 0; i < BCJ2_NUM_STREAMS; i++)
+ if (dec.bufs[i] != dec.lims[i] || _extraReadSizes[i] != 0)
+ return S_FALSE;
+ */
}
- catch(const CInBufferException &e) { return e.ErrorCode; }
- catch(const COutBufferException &e) { return e.ErrorCode; }
- catch(...) { return S_FALSE; }
+
+ return res;
}
}}
diff --git a/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.h b/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.h
index 79a713f1711..627e505d184 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.h
+++ b/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.h
@@ -3,60 +3,57 @@
#ifndef __COMPRESS_BCJ2_CODER_H
#define __COMPRESS_BCJ2_CODER_H
+#include "../../../C/Bcj2.h"
+
#include "../../Common/MyCom.h"
#include "../ICoder.h"
-#include "RangeCoderBit.h"
-
namespace NCompress {
namespace NBcj2 {
-const int kNumMoveBits = 5;
+class CBaseCoder
+{
+protected:
+ Byte *_bufs[BCJ2_NUM_STREAMS + 1];
+ UInt32 _bufsCurSizes[BCJ2_NUM_STREAMS + 1];
+ UInt32 _bufsNewSizes[BCJ2_NUM_STREAMS + 1];
+
+ HRESULT Alloc(bool allocForOrig = true);
+public:
+ CBaseCoder();
+ ~CBaseCoder();
+};
+
#ifndef EXTRACT_ONLY
class CEncoder:
public ICompressCoder2,
- public CMyUnknownImp
+ public ICompressSetCoderProperties,
+ public ICompressSetBufSize,
+ public CMyUnknownImp,
+ public CBaseCoder
{
- Byte *_buffer;
- bool Create();
-
- COutBuffer _mainStream;
- COutBuffer _callStream;
- COutBuffer _jumpStream;
- NCompress::NRangeCoder::CEncoder _rangeEncoder;
- NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusEncoder[256 + 2];
+ UInt32 _relatLim;
- HRESULT Flush();
-public:
- void ReleaseStreams()
- {
- _mainStream.ReleaseStream();
- _callStream.ReleaseStream();
- _jumpStream.ReleaseStream();
- _rangeEncoder.ReleaseStream();
- }
-
- class CCoderReleaser
- {
- CEncoder *_coder;
- public:
- CCoderReleaser(CEncoder *coder): _coder(coder) {}
- ~CCoderReleaser() { _coder->ReleaseStreams(); }
- };
+ HRESULT CodeReal(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams,
+ ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
public:
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP3(ICompressCoder2, ICompressSetCoderProperties, ICompressSetBufSize)
- HRESULT CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
- ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
- ICompressProgressInfo *progress);
- STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
- ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
+ STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams,
+ ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams,
ICompressProgressInfo *progress);
- CEncoder(): _buffer(0) {};
+
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+
+ STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
+ STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
+
+ CEncoder();
~CEncoder();
};
@@ -64,49 +61,54 @@ public:
class CDecoder:
public ICompressCoder2,
+ public ICompressSetFinishMode,
+ public ICompressSetInStream2,
+ public ISequentialInStream,
+ public ICompressSetOutStreamSize,
public ICompressSetBufSize,
- public CMyUnknownImp
+ public CMyUnknownImp,
+ public CBaseCoder
{
- CInBuffer _mainInStream;
- CInBuffer _callStream;
- CInBuffer _jumpStream;
- NCompress::NRangeCoder::CDecoder _rangeDecoder;
- NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusDecoder[256 + 2];
+ unsigned _extraReadSizes[BCJ2_NUM_STREAMS];
+ UInt64 _inStreamsProcessed[BCJ2_NUM_STREAMS];
+ HRESULT _readRes[BCJ2_NUM_STREAMS];
+ CMyComPtr<ISequentialInStream> inStreams[BCJ2_NUM_STREAMS];
+
+ bool _finishMode;
+ bool _outSizeDefined;
+ UInt64 _outSize;
+ UInt64 _outSize_Processed;
+ CBcj2Dec dec;
+
+ void InitCommon();
+ // HRESULT ReadSpec();
+
+public:
+ MY_UNKNOWN_IMP6(
+ ICompressCoder2,
+ ICompressSetFinishMode,
+ ICompressSetInStream2,
+ ISequentialInStream,
+ ICompressSetOutStreamSize,
+ ICompressSetBufSize
+ );
+
+ STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams,
+ ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
- COutBuffer _outStream;
- UInt32 _inBufSizes[4];
- UInt32 _outBufSize;
+ STDMETHOD(SetFinishMode)(UInt32 finishMode);
-public:
- void ReleaseStreams()
- {
- _mainInStream.ReleaseStream();
- _callStream.ReleaseStream();
- _jumpStream.ReleaseStream();
- _rangeDecoder.ReleaseStream();
- _outStream.ReleaseStream();
- }
-
- HRESULT Flush() { return _outStream.Flush(); }
- class CCoderReleaser
- {
- CDecoder *_coder;
- public:
- CCoderReleaser(CDecoder *coder): _coder(coder) {}
- ~CCoderReleaser() { _coder->ReleaseStreams(); }
- };
+ STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream2)(UInt32 streamIndex);
-public:
- MY_UNKNOWN_IMP1(ICompressSetBufSize);
- HRESULT CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
- ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
- ICompressProgressInfo *progress);
- STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
- ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
- ICompressProgressInfo *progress);
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
+
CDecoder();
};
diff --git a/3rdparty/lzma/CPP/7zip/Compress/Bcj2Register.cpp b/3rdparty/lzma/CPP/7zip/Compress/Bcj2Register.cpp
index 8eb1e73609b..ef37ae0cba4 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/Bcj2Register.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/Bcj2Register.cpp
@@ -6,14 +6,14 @@
#include "Bcj2Coder.h"
-static void *CreateCodec() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CDecoder()); }
+REGISTER_CODEC_CREATE_2(CreateCodec, NCompress::NBcj2::CDecoder(), ICompressCoder2)
#ifndef EXTRACT_ONLY
-static void *CreateCodecOut() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CEncoder()); }
+REGISTER_CODEC_CREATE_2(CreateCodecOut, NCompress::NBcj2::CEncoder(), ICompressCoder2)
#else
-#define CreateCodecOut 0
+#define CreateCodecOut NULL
#endif
-static CCodecInfo g_CodecInfo =
- { CreateCodec, CreateCodecOut, 0x0303011B, L"BCJ2", 4, false };
+REGISTER_CODEC_VAR
+ { CreateCodec, CreateCodecOut, 0x303011B, "BCJ2", 4, false };
REGISTER_CODEC(BCJ2)
diff --git a/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.cpp
index 0e34ef48880..37815dceb17 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.cpp
@@ -4,12 +4,16 @@
#include "BcjCoder.h"
-UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size)
+STDMETHODIMP CBcjCoder::Init()
{
- return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 1);
+ _bufferPos = 0;
+ x86_Convert_Init(_prevMask);
+ return S_OK;
}
-UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size)
+STDMETHODIMP_(UInt32) CBcjCoder::Filter(Byte *data, UInt32 size)
{
- return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 0);
+ UInt32 processed = (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, _encode);
+ _bufferPos += processed;
+ return processed;
}
diff --git a/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.h b/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.h
index 0754bcd23cf..275fd4f2431 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.h
+++ b/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.h
@@ -5,15 +5,22 @@
#include "../../../C/Bra.h"
-#include "BranchCoder.h"
+#include "../../Common/MyCom.h"
-struct CBranch86
+#include "../ICoder.h"
+
+class CBcjCoder:
+ public ICompressFilter,
+ public CMyUnknownImp
{
+ UInt32 _bufferPos;
UInt32 _prevMask;
- void x86Init() { x86_Convert_Init(_prevMask); }
-};
+ int _encode;
+public:
+ MY_UNKNOWN_IMP;
+ INTERFACE_ICompressFilter(;)
-MyClassB(BCJ_x86, 0x01, 3, CBranch86 ,
- virtual void SubInit() { x86Init(); })
+ CBcjCoder(int encode): _bufferPos(0), _encode(encode) { x86_Convert_Init(_prevMask); }
+};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Compress/BcjRegister.cpp b/3rdparty/lzma/CPP/7zip/Compress/BcjRegister.cpp
index 648ad8e0363..83c6830fbc9 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/BcjRegister.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/BcjRegister.cpp
@@ -6,14 +6,7 @@
#include "BcjCoder.h"
-static void *CreateCodec() { return (void *)(ICompressFilter *)(new CBCJ_x86_Decoder()); }
-#ifndef EXTRACT_ONLY
-static void *CreateCodecOut() { return (void *)(ICompressFilter *)(new CBCJ_x86_Encoder()); }
-#else
-#define CreateCodecOut 0
-#endif
-
-static CCodecInfo g_CodecInfo =
- { CreateCodec, CreateCodecOut, 0x03030103, L"BCJ", 1, true };
-
-REGISTER_CODEC(BCJ)
+REGISTER_FILTER_E(BCJ,
+ CBcjCoder(false),
+ CBcjCoder(true),
+ 0x3030103, "BCJ")
diff --git a/3rdparty/lzma/CPP/7zip/Compress/BranchCoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/BranchCoder.cpp
deleted file mode 100644
index 431709526a0..00000000000
--- a/3rdparty/lzma/CPP/7zip/Compress/BranchCoder.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// BranchCoder.cpp
-
-#include "StdAfx.h"
-
-#include "BranchCoder.h"
-
-STDMETHODIMP CBranchConverter::Init()
-{
- _bufferPos = 0;
- SubInit();
- return S_OK;
-}
-
-STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size)
-{
- UInt32 processedSize = SubFilter(data, size);
- _bufferPos += processedSize;
- return processedSize;
-}
diff --git a/3rdparty/lzma/CPP/7zip/Compress/BranchCoder.h b/3rdparty/lzma/CPP/7zip/Compress/BranchCoder.h
deleted file mode 100644
index 0e3a5c4e101..00000000000
--- a/3rdparty/lzma/CPP/7zip/Compress/BranchCoder.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// BranchCoder.h
-
-#ifndef __COMPRESS_BRANCH_CODER_H
-#define __COMPRESS_BRANCH_CODER_H
-
-#include "../../Common/MyCom.h"
-
-#include "../ICoder.h"
-
-class CBranchConverter:
- public ICompressFilter,
- public CMyUnknownImp
-{
-protected:
- UInt32 _bufferPos;
- virtual void SubInit() {}
- virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0;
-public:
- MY_UNKNOWN_IMP;
- STDMETHOD(Init)();
- STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
-};
-
-#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \
- { public: UInt32 SubFilter(Byte *data, UInt32 size); };
-
-#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \
- { public: UInt32 SubFilter(Byte *data, UInt32 size); };
-
-#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
- { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
-
-#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
- { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
-
-#define MyClassA(Name, id, subId) \
-MyClassEncoderA(Name ## _Encoder) \
-MyClassDecoderA(Name ## _Decoder)
-
-#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \
-MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \
-MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT)
-
-#endif
diff --git a/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.cpp b/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.cpp
index 423b723ab0d..0bf39b79ca0 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.cpp
@@ -2,36 +2,17 @@
#include "StdAfx.h"
-#include "../../../C/Bra.h"
-
#include "BranchMisc.h"
-UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::ARM_Convert(data, size, _bufferPos, 1); }
-
-UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::ARM_Convert(data, size, _bufferPos, 0); }
-
-UInt32 CBC_ARMT_Encoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::ARMT_Convert(data, size, _bufferPos, 1); }
-
-UInt32 CBC_ARMT_Decoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::ARMT_Convert(data, size, _bufferPos, 0); }
-
-UInt32 CBC_PPC_Encoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::PPC_Convert(data, size, _bufferPos, 1); }
-
-UInt32 CBC_PPC_Decoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::PPC_Convert(data, size, _bufferPos, 0); }
-
-UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::SPARC_Convert(data, size, _bufferPos, 1); }
-
-UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::SPARC_Convert(data, size, _bufferPos, 0); }
-
-UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::IA64_Convert(data, size, _bufferPos, 1); }
-
-UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::IA64_Convert(data, size, _bufferPos, 0); }
+STDMETHODIMP CBranchCoder::Init()
+{
+ _bufferPos = 0;
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CBranchCoder::Filter(Byte *data, UInt32 size)
+{
+ UInt32 processed = (UInt32)BraFunc(data, size, _bufferPos, _encode);
+ _bufferPos += processed;
+ return processed;
+}
diff --git a/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.h b/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.h
index 81198b21c4f..bbb5add9c5d 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.h
+++ b/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.h
@@ -3,12 +3,28 @@
#ifndef __COMPRESS_BRANCH_MISC_H
#define __COMPRESS_BRANCH_MISC_H
-#include "BranchCoder.h"
+#include "../../Common/MyCom.h"
-MyClassA(BC_ARM, 0x05, 1)
-MyClassA(BC_ARMT, 0x07, 1)
-MyClassA(BC_PPC, 0x02, 5)
-MyClassA(BC_SPARC, 0x08, 5)
-MyClassA(BC_IA64, 0x04, 1)
+#include "../ICoder.h"
+
+EXTERN_C_BEGIN
+
+typedef SizeT (*Func_Bra)(Byte *data, SizeT size, UInt32 ip, int encoding);
+
+EXTERN_C_END
+
+class CBranchCoder:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+ UInt32 _bufferPos;
+ int _encode;
+ Func_Bra BraFunc;
+public:
+ MY_UNKNOWN_IMP;
+ INTERFACE_ICompressFilter(;)
+
+ CBranchCoder(Func_Bra bra, int encode): _bufferPos(0), _encode(encode), BraFunc(bra) {}
+};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Compress/BranchRegister.cpp b/3rdparty/lzma/CPP/7zip/Compress/BranchRegister.cpp
index 380828c6d80..e1fcff6dcd4 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/BranchRegister.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/BranchRegister.cpp
@@ -2,29 +2,35 @@
#include "StdAfx.h"
+#include "../../../C/Bra.h"
+
#include "../Common/RegisterCodec.h"
#include "BranchMisc.h"
-#define CREATE_CODEC(x) \
- static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## _Decoder); } \
- static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## _Encoder); }
+#define CREATE_BRA(n) \
+ REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CBranchCoder(n ## _Convert, false)) \
+ REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CBranchCoder(n ## _Convert, true)) \
-CREATE_CODEC(BC_PPC)
-CREATE_CODEC(BC_IA64)
-CREATE_CODEC(BC_ARM)
-CREATE_CODEC(BC_ARMT)
-CREATE_CODEC(BC_SPARC)
+CREATE_BRA(PPC)
+CREATE_BRA(IA64)
+CREATE_BRA(ARM)
+CREATE_BRA(ARMT)
+CREATE_BRA(SPARC)
-#define METHOD_ITEM(x, id1, id2, name) { CreateCodec ## x, CreateCodec ## x ## Out, 0x03030000 + (id1 * 256) + id2, name, 1, true }
+#define METHOD_ITEM(n, id, name) \
+ REGISTER_FILTER_ITEM( \
+ CreateBra_Decoder_ ## n, \
+ CreateBra_Encoder_ ## n, \
+ 0x3030000 + id, name)
-static CCodecInfo g_CodecsInfo[] =
+REGISTER_CODECS_VAR
{
- METHOD_ITEM(BC_PPC, 0x02, 0x05, L"PPC"),
- METHOD_ITEM(BC_IA64, 0x04, 1, L"IA64"),
- METHOD_ITEM(BC_ARM, 0x05, 1, L"ARM"),
- METHOD_ITEM(BC_ARMT, 0x07, 1, L"ARMT"),
- METHOD_ITEM(BC_SPARC, 0x08, 0x05, L"SPARC")
+ METHOD_ITEM(PPC, 0x205, "PPC"),
+ METHOD_ITEM(IA64, 0x401, "IA64"),
+ METHOD_ITEM(ARM, 0x501, "ARM"),
+ METHOD_ITEM(ARMT, 0x701, "ARMT"),
+ METHOD_ITEM(SPARC, 0x805, "SPARC")
};
REGISTER_CODECS(Branch)
diff --git a/3rdparty/lzma/CPP/7zip/Compress/ByteSwap.cpp b/3rdparty/lzma/CPP/7zip/Compress/ByteSwap.cpp
index 645b6ffcda2..f5620d6ce42 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/ByteSwap.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/ByteSwap.cpp
@@ -14,8 +14,7 @@ class CByteSwap2:
{
public:
MY_UNKNOWN_IMP
- STDMETHOD(Init)();
- STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+ INTERFACE_ICompressFilter(;)
};
class CByteSwap4:
@@ -24,8 +23,7 @@ class CByteSwap4:
{
public:
MY_UNKNOWN_IMP
- STDMETHOD(Init)();
- STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+ INTERFACE_ICompressFilter(;)
};
STDMETHODIMP CByteSwap2::Init() { return S_OK; }
@@ -33,14 +31,22 @@ STDMETHODIMP CByteSwap2::Init() { return S_OK; }
STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size)
{
const UInt32 kStep = 2;
- UInt32 i;
- for (i = 0; i + kStep <= size; i += kStep)
+ if (size < kStep)
+ return 0;
+ size &= ~(kStep - 1);
+
+ const Byte *end = data + (size_t)size;
+
+ do
{
- Byte b = data[i];
- data[i] = data[i + 1];
- data[i + 1] = b;
+ Byte b0 = data[0];
+ data[0] = data[1];
+ data[1] = b0;
+ data += kStep;
}
- return i;
+ while (data != end);
+
+ return size;
}
STDMETHODIMP CByteSwap4::Init() { return S_OK; }
@@ -48,26 +54,34 @@ STDMETHODIMP CByteSwap4::Init() { return S_OK; }
STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size)
{
const UInt32 kStep = 4;
- UInt32 i;
- for (i = 0; i + kStep <= size; i += kStep)
+ if (size < kStep)
+ return 0;
+ size &= ~(kStep - 1);
+
+ const Byte *end = data + (size_t)size;
+
+ do
{
- Byte b0 = data[i];
- Byte b1 = data[i + 1];
- data[i] = data[i + 3];
- data[i + 1] = data[i + 2];
- data[i + 2] = b1;
- data[i + 3] = b0;
+ Byte b0 = data[0];
+ Byte b1 = data[1];
+ data[0] = data[3];
+ data[1] = data[2];
+ data[2] = b1;
+ data[3] = b0;
+ data += kStep;
}
- return i;
+ while (data != end);
+
+ return size;
}
-static void *CreateCodec2() { return (void *)(ICompressFilter *)(new CByteSwap2); }
-static void *CreateCodec4() { return (void *)(ICompressFilter *)(new CByteSwap4); }
+REGISTER_FILTER_CREATE(CreateFilter2, CByteSwap2())
+REGISTER_FILTER_CREATE(CreateFilter4, CByteSwap4())
-static CCodecInfo g_CodecsInfo[] =
+REGISTER_CODECS_VAR
{
- { CreateCodec2, CreateCodec2, 0x020302, L"Swap2", 1, true },
- { CreateCodec4, CreateCodec4, 0x020304, L"Swap4", 1, true }
+ REGISTER_FILTER_ITEM(CreateFilter2, CreateFilter2, 0x20302, "Swap2"),
+ REGISTER_FILTER_ITEM(CreateFilter4, CreateFilter4, 0x20304, "Swap4")
};
REGISTER_CODECS(ByteSwap)
diff --git a/3rdparty/lzma/CPP/7zip/Compress/CodecExports.cpp b/3rdparty/lzma/CPP/7zip/Compress/CodecExports.cpp
index 4ff1c0fcb0a..99085040d07 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/CodecExports.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/CodecExports.cpp
@@ -2,110 +2,168 @@
#include "StdAfx.h"
+#include "../../../C/CpuArch.h"
+
#include "../../Common/ComTry.h"
+#include "../../Common/MyCom.h"
-#include "../../Windows/PropVariant.h"
+#include "../../Windows/Defs.h"
#include "../ICoder.h"
#include "../Common/RegisterCodec.h"
-extern unsigned int g_NumCodecs;
+extern unsigned g_NumCodecs;
extern const CCodecInfo *g_Codecs[];
-static const UInt16 kDecodeId = 0x2790;
-
-DEFINE_GUID(CLSID_CCodec,
-0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+extern unsigned g_NumHashers;
+extern const CHasherInfo *g_Hashers[];
-static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value)
+static void SetPropFromAscii(const char *s, PROPVARIANT *prop) throw()
{
- if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
- value->vt = VT_BSTR;
- return S_OK;
+ UINT len = (UINT)strlen(s);
+ BSTR dest = ::SysAllocStringLen(NULL, len);
+ if (dest)
+ {
+ for (UINT i = 0; i <= len; i++)
+ dest[i] = (Byte)s[i];
+ prop->bstrVal = dest;
+ prop->vt = VT_BSTR;
+ }
}
-static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
+static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) throw()
{
- return SetPropString((const char *)&guid, sizeof(GUID), value);
+ if ((value->bstrVal = ::SysAllocStringByteLen((const char *)&guid, sizeof(guid))) != NULL)
+ value->vt = VT_BSTR;
+ return S_OK;
}
-static HRESULT SetClassID(CMethodId id, bool encode, PROPVARIANT *value)
+static HRESULT MethodToClassID(UInt16 typeId, CMethodId id, PROPVARIANT *value) throw()
{
- GUID clsId = CLSID_CCodec;
- for (int i = 0; i < sizeof(id); i++, id >>= 8)
- clsId.Data4[i] = (Byte)(id & 0xFF);
- if (encode)
- clsId.Data3++;
+ GUID clsId;
+ clsId.Data1 = k_7zip_GUID_Data1;
+ clsId.Data2 = k_7zip_GUID_Data2;
+ clsId.Data3 = typeId;
+ SetUi64(clsId.Data4, id);
return SetPropGUID(clsId, value);
}
-static HRESULT FindCodecClassId(const GUID *clsID, UInt32 isCoder2, bool isFilter, bool &encode, int &index)
+static HRESULT FindCodecClassId(const GUID *clsid, bool isCoder2, bool isFilter, bool &encode, int &index) throw()
{
index = -1;
- if (clsID->Data1 != CLSID_CCodec.Data1 ||
- clsID->Data2 != CLSID_CCodec.Data2 ||
- (clsID->Data3 & ~1) != kDecodeId)
+ if (clsid->Data1 != k_7zip_GUID_Data1 ||
+ clsid->Data2 != k_7zip_GUID_Data2)
return S_OK;
- encode = (clsID->Data3 != kDecodeId);
- UInt64 id = 0;
- for (int j = 0; j < 8; j++)
- id |= ((UInt64)clsID->Data4[j]) << (8 * j);
+
+ encode = true;
+
+ if (clsid->Data3 == k_7zip_GUID_Data3_Decoder) encode = false;
+ else if (clsid->Data3 != k_7zip_GUID_Data3_Encoder) return S_OK;
+
+ UInt64 id = GetUi64(clsid->Data4);
+
for (unsigned i = 0; i < g_NumCodecs; i++)
{
const CCodecInfo &codec = *g_Codecs[i];
- if (id != codec.Id || encode && !codec.CreateEncoder || !encode && !codec.CreateDecoder)
+
+ if (id != codec.Id
+ || (encode ? !codec.CreateEncoder : !codec.CreateDecoder)
+ || (isFilter ? !codec.IsFilter : codec.IsFilter))
continue;
- if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter ||
- codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2)
+
+ if (codec.NumStreams == 1 ? isCoder2 : !isCoder2)
return E_NOINTERFACE;
+
index = i;
return S_OK;
}
+
return S_OK;
}
-STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject)
+static HRESULT CreateCoderMain(unsigned index, bool encode, void **coder)
{
COM_TRY_BEGIN
- *outObject = 0;
- bool isCoder = (*iid == IID_ICompressCoder) != 0;
- bool isCoder2 = (*iid == IID_ICompressCoder2) != 0;
- bool isFilter = (*iid == IID_ICompressFilter) != 0;
+
const CCodecInfo &codec = *g_Codecs[index];
- if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter ||
- codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2)
- return E_NOINTERFACE;
+
+ void *c;
if (encode)
- {
- if (!codec.CreateEncoder)
- return CLASS_E_CLASSNOTAVAILABLE;
- *outObject = codec.CreateEncoder();
- }
+ c = codec.CreateEncoder();
else
+ c = codec.CreateDecoder();
+
+ if (c)
{
- if (!codec.CreateDecoder)
- return CLASS_E_CLASSNOTAVAILABLE;
- *outObject = codec.CreateDecoder();
+ IUnknown *unk;
+ if (codec.IsFilter)
+ unk = (IUnknown *)(ICompressFilter *)c;
+ else if (codec.NumStreams != 1)
+ unk = (IUnknown *)(ICompressCoder2 *)c;
+ else
+ unk = (IUnknown *)(ICompressCoder *)c;
+ unk->AddRef();
+ *coder = c;
}
- if (isCoder)
- ((ICompressCoder *)*outObject)->AddRef();
- else if (isCoder2)
- ((ICompressCoder2 *)*outObject)->AddRef();
- else
- ((ICompressFilter *)*outObject)->AddRef();
return S_OK;
+
COM_TRY_END
}
+static HRESULT CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject)
+{
+ *outObject = NULL;
+
+ const CCodecInfo &codec = *g_Codecs[index];
+
+ if (encode ? !codec.CreateEncoder : !codec.CreateDecoder)
+ return CLASS_E_CLASSNOTAVAILABLE;
+
+ if (codec.IsFilter)
+ {
+ if (*iid != IID_ICompressFilter) return E_NOINTERFACE;
+ }
+ else if (codec.NumStreams != 1)
+ {
+ if (*iid != IID_ICompressCoder2) return E_NOINTERFACE;
+ }
+ else
+ {
+ if (*iid != IID_ICompressCoder) return E_NOINTERFACE;
+ }
+
+ return CreateCoderMain(index, encode, outObject);
+}
+
+STDAPI CreateDecoder(UInt32 index, const GUID *iid, void **outObject)
+{
+ return CreateCoder2(false, index, iid, outObject);
+}
+
+STDAPI CreateEncoder(UInt32 index, const GUID *iid, void **outObject)
+{
+ return CreateCoder2(true, index, iid, outObject);
+}
+
STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject)
{
- *outObject = 0;
+ *outObject = NULL;
+
+ bool isFilter = false;
+ bool isCoder2 = false;
bool isCoder = (*iid == IID_ICompressCoder) != 0;
- bool isCoder2 = (*iid == IID_ICompressCoder2) != 0;
- bool isFilter = (*iid == IID_ICompressFilter) != 0;
- if (!isCoder && !isCoder2 && !isFilter)
- return E_NOINTERFACE;
+ if (!isCoder)
+ {
+ isFilter = (*iid == IID_ICompressFilter) != 0;
+ if (!isFilter)
+ {
+ isCoder2 = (*iid == IID_ICompressCoder2) != 0;
+ if (!isCoder2)
+ return E_NOINTERFACE;
+ }
+ }
+
bool encode;
int codecIndex;
HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex);
@@ -113,42 +171,69 @@ STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject)
return res;
if (codecIndex < 0)
return CLASS_E_CLASSNOTAVAILABLE;
- return CreateCoder2(encode, codecIndex, iid, outObject);
-}
+ return CreateCoderMain(codecIndex, encode, outObject);
+}
+
STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)
{
::VariantClear((VARIANTARG *)value);
const CCodecInfo &codec = *g_Codecs[codecIndex];
- switch(propID)
+ switch (propID)
{
case NMethodPropID::kID:
- {
value->uhVal.QuadPart = (UInt64)codec.Id;
value->vt = VT_UI8;
break;
- }
case NMethodPropID::kName:
- if ((value->bstrVal = ::SysAllocString(codec.Name)) != 0)
- value->vt = VT_BSTR;
+ SetPropFromAscii(codec.Name, value);
break;
case NMethodPropID::kDecoder:
if (codec.CreateDecoder)
- return SetClassID(codec.Id, false, value);
+ return MethodToClassID(k_7zip_GUID_Data3_Decoder, codec.Id, value);
break;
case NMethodPropID::kEncoder:
if (codec.CreateEncoder)
- return SetClassID(codec.Id, true, value);
+ return MethodToClassID(k_7zip_GUID_Data3_Encoder, codec.Id, value);
break;
- case NMethodPropID::kInStreams:
- {
- if (codec.NumInStreams != 1)
+ case NMethodPropID::kDecoderIsAssigned:
+ value->vt = VT_BOOL;
+ value->boolVal = BoolToVARIANT_BOOL(codec.CreateDecoder != NULL);
+ break;
+ case NMethodPropID::kEncoderIsAssigned:
+ value->vt = VT_BOOL;
+ value->boolVal = BoolToVARIANT_BOOL(codec.CreateEncoder != NULL);
+ break;
+ case NMethodPropID::kPackStreams:
+ if (codec.NumStreams != 1)
{
value->vt = VT_UI4;
- value->ulVal = (ULONG)codec.NumInStreams;
+ value->ulVal = (ULONG)codec.NumStreams;
}
break;
- }
+ /*
+ case NMethodPropID::kIsFilter:
+ // if (codec.IsFilter)
+ {
+ value->vt = VT_BOOL;
+ value->boolVal = BoolToVARIANT_BOOL(codec.IsFilter);
+ }
+ break;
+ */
+ /*
+ case NMethodPropID::kDecoderFlags:
+ {
+ value->vt = VT_UI4;
+ value->ulVal = (ULONG)codec.DecoderFlags;
+ }
+ break;
+ case NMethodPropID::kEncoderFlags:
+ {
+ value->vt = VT_UI4;
+ value->ulVal = (ULONG)codec.EncoderFlags;
+ }
+ break;
+ */
}
return S_OK;
}
@@ -158,3 +243,102 @@ STDAPI GetNumberOfMethods(UINT32 *numCodecs)
*numCodecs = g_NumCodecs;
return S_OK;
}
+
+
+// ---------- Hashers ----------
+
+static int FindHasherClassId(const GUID *clsid) throw()
+{
+ if (clsid->Data1 != k_7zip_GUID_Data1 ||
+ clsid->Data2 != k_7zip_GUID_Data2 ||
+ clsid->Data3 != k_7zip_GUID_Data3_Hasher)
+ return -1;
+ UInt64 id = GetUi64(clsid->Data4);
+ for (unsigned i = 0; i < g_NumCodecs; i++)
+ if (id == g_Hashers[i]->Id)
+ return i;
+ return -1;
+}
+
+static HRESULT CreateHasher2(UInt32 index, IHasher **hasher)
+{
+ COM_TRY_BEGIN
+ *hasher = g_Hashers[index]->CreateHasher();
+ if (*hasher)
+ (*hasher)->AddRef();
+ return S_OK;
+ COM_TRY_END
+}
+
+STDAPI CreateHasher(const GUID *clsid, IHasher **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ int index = FindHasherClassId(clsid);
+ if (index < 0)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ return CreateHasher2(index, outObject);
+ COM_TRY_END
+}
+
+STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)
+{
+ ::VariantClear((VARIANTARG *)value);
+ const CHasherInfo &codec = *g_Hashers[codecIndex];
+ switch (propID)
+ {
+ case NMethodPropID::kID:
+ value->uhVal.QuadPart = (UInt64)codec.Id;
+ value->vt = VT_UI8;
+ break;
+ case NMethodPropID::kName:
+ SetPropFromAscii(codec.Name, value);
+ break;
+ case NMethodPropID::kEncoder:
+ if (codec.CreateHasher)
+ return MethodToClassID(k_7zip_GUID_Data3_Hasher, codec.Id, value);
+ break;
+ case NMethodPropID::kDigestSize:
+ value->ulVal = (ULONG)codec.DigestSize;
+ value->vt = VT_UI4;
+ break;
+ }
+ return S_OK;
+}
+
+class CHashers:
+ public IHashers,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(IHashers)
+
+ STDMETHOD_(UInt32, GetNumHashers)();
+ STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher);
+};
+
+STDAPI GetHashers(IHashers **hashers)
+{
+ COM_TRY_BEGIN
+ *hashers = new CHashers;
+ if (*hashers)
+ (*hashers)->AddRef();
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP_(UInt32) CHashers::GetNumHashers()
+{
+ return g_NumHashers;
+}
+
+STDMETHODIMP CHashers::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ return ::GetHasherProp(index, propID, value);
+}
+
+STDMETHODIMP CHashers::CreateHasher(UInt32 index, IHasher **hasher)
+{
+ return ::CreateHasher2(index, hasher);
+}
diff --git a/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp
index f71692a7781..ac6ab2e718a 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp
@@ -4,17 +4,15 @@
#include "../../../C/Alloc.h"
-#include "../Common/StreamUtils.h"
-
#include "CopyCoder.h"
namespace NCompress {
-static const UInt32 kBufferSize = 1 << 17;
+static const UInt32 kBufSize = 1 << 17;
CCopyCoder::~CCopyCoder()
{
- ::MidFree(_buffer);
+ ::MidFree(_buf);
}
STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
@@ -22,36 +20,78 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
const UInt64 * /* inSize */, const UInt64 *outSize,
ICompressProgressInfo *progress)
{
- if (_buffer == 0)
+ if (!_buf)
{
- _buffer = (Byte *)::MidAlloc(kBufferSize);
- if (_buffer == 0)
+ _buf = (Byte *)::MidAlloc(kBufSize);
+ if (!_buf)
return E_OUTOFMEMORY;
}
TotalSize = 0;
+
for (;;)
{
- UInt32 size = kBufferSize;
- if (outSize != 0)
- if (size > *outSize - TotalSize)
- size = (UInt32)(*outSize - TotalSize);
- RINOK(inStream->Read(_buffer, size, &size));
+ UInt32 size = kBufSize;
+ if (outSize && size > *outSize - TotalSize)
+ size = (UInt32)(*outSize - TotalSize);
+ if (size == 0)
+ return S_OK;
+
+ HRESULT readRes = inStream->Read(_buf, size, &size);
+
if (size == 0)
- break;
+ return readRes;
+
if (outStream)
{
- RINOK(WriteStream(outStream, _buffer, size));
+ UInt32 pos = 0;
+ do
+ {
+ UInt32 curSize = size - pos;
+ HRESULT res = outStream->Write(_buf + pos, curSize, &curSize);
+ pos += curSize;
+ TotalSize += curSize;
+ RINOK(res);
+ if (curSize == 0)
+ return E_FAIL;
+ }
+ while (pos < size);
}
- TotalSize += size;
- if (progress != NULL)
+ else
+ TotalSize += size;
+
+ RINOK(readRes);
+
+ if (progress)
{
RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
}
}
+}
+
+STDMETHODIMP CCopyCoder::SetInStream(ISequentialInStream *inStream)
+{
+ _inStream = inStream;
+ TotalSize = 0;
return S_OK;
}
+STDMETHODIMP CCopyCoder::ReleaseInStream()
+{
+ _inStream.Release();
+ return S_OK;
+}
+
+STDMETHODIMP CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize = 0;
+ HRESULT res = _inStream->Read(data, size, &realProcessedSize);
+ TotalSize += realProcessedSize;
+ if (processedSize)
+ *processedSize = realProcessedSize;
+ return res;
+}
+
STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value)
{
*value = TotalSize;
@@ -60,8 +100,16 @@ STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value)
HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
{
- CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ CMyComPtr<ICompressCoder> copyCoder = new CCopyCoder;
return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
}
+HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress)
+{
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+ RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress));
+ return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL;
+}
+
}
diff --git a/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.h b/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.h
index c5445ccf8f2..a21c0988a91 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.h
+++ b/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.h
@@ -11,23 +11,35 @@ namespace NCompress {
class CCopyCoder:
public ICompressCoder,
+ public ICompressSetInStream,
+ public ISequentialInStream,
public ICompressGetInStreamProcessedSize,
public CMyUnknownImp
{
- Byte *_buffer;
+ Byte *_buf;
+ CMyComPtr<ISequentialInStream> _inStream;
public:
UInt64 TotalSize;
- CCopyCoder(): TotalSize(0), _buffer(0) {};
+
+ CCopyCoder(): _buf(0), TotalSize(0) {};
~CCopyCoder();
- MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
+ MY_UNKNOWN_IMP4(
+ ICompressCoder,
+ ICompressSetInStream,
+ ISequentialInStream,
+ ICompressGetInStreamProcessedSize)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
};
HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
+HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress);
}
diff --git a/3rdparty/lzma/CPP/7zip/Compress/CopyRegister.cpp b/3rdparty/lzma/CPP/7zip/Compress/CopyRegister.cpp
index efb9b9e954f..703c52ca6e0 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/CopyRegister.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/CopyRegister.cpp
@@ -6,9 +6,6 @@
#include "CopyCoder.h"
-static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::CCopyCoder); }
+REGISTER_CODEC_CREATE(CreateCodec, NCompress::CCopyCoder())
-static CCodecInfo g_CodecInfo =
-{ CreateCodec, CreateCodec, 0x00, L"Copy", 1, false };
-
-REGISTER_CODEC(Copy)
+REGISTER_CODEC_2(Copy, CreateCodec, CreateCodec, 0, "Copy")
diff --git a/3rdparty/lzma/CPP/7zip/Compress/DeltaFilter.cpp b/3rdparty/lzma/CPP/7zip/Compress/DeltaFilter.cpp
index d8378a60e41..d90f62f59f4 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/DeltaFilter.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/DeltaFilter.cpp
@@ -4,18 +4,24 @@
#include "../../../C/Delta.h"
-#include "../Common/RegisterCodec.h"
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
-#include "BranchCoder.h"
+#include "../Common/RegisterCodec.h"
struct CDelta
{
unsigned _delta;
Byte _state[DELTA_STATE_SIZE];
+
CDelta(): _delta(1) {}
void DeltaInit() { Delta_Init(_state); }
};
+
+#ifndef EXTRACT_ONLY
+
class CDeltaEncoder:
public ICompressFilter,
public ICompressSetCoderProperties,
@@ -25,25 +31,11 @@ class CDeltaEncoder:
{
public:
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties)
- STDMETHOD(Init)();
- STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+ INTERFACE_ICompressFilter(;)
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
};
-class CDeltaDecoder:
- public ICompressFilter,
- public ICompressSetDecoderProperties2,
- CDelta,
- public CMyUnknownImp
-{
-public:
- MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
- STDMETHOD(Init)();
- STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
- STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
-};
-
STDMETHODIMP CDeltaEncoder::Init()
{
DeltaInit();
@@ -89,6 +81,21 @@ STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream
return outStream->Write(&prop, 1, NULL);
}
+#endif
+
+
+class CDeltaDecoder:
+ public ICompressFilter,
+ public ICompressSetDecoderProperties2,
+ CDelta,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
+ INTERFACE_ICompressFilter(;)
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
STDMETHODIMP CDeltaDecoder::Init()
{
DeltaInit();
@@ -109,17 +116,8 @@ STDMETHODIMP CDeltaDecoder::SetDecoderProperties2(const Byte *props, UInt32 size
return S_OK;
}
-#define CREATE_CODEC(x) \
- static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## Decoder); } \
- static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## Encoder); }
-
-CREATE_CODEC(Delta)
-
-#define METHOD_ITEM(x, id, name) { CreateCodec ## x, CreateCodec ## x ## Out, id, name, 1, true }
-
-static CCodecInfo g_CodecsInfo[] =
-{
- METHOD_ITEM(Delta, 3, L"Delta")
-};
-REGISTER_CODECS(Delta)
+REGISTER_FILTER_E(Delta,
+ CDeltaDecoder(),
+ CDeltaEncoder(),
+ 3, "Delta")
diff --git a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.cpp
index 322015e294e..1a378bbe3a1 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.cpp
@@ -10,7 +10,7 @@
static HRESULT SResToHRESULT(SRes res)
{
- switch(res)
+ switch (res)
{
case SZ_OK: return S_OK;
case SZ_ERROR_MEM: return E_OUTOFMEMORY;
@@ -24,32 +24,40 @@ static HRESULT SResToHRESULT(SRes res)
namespace NCompress {
namespace NLzma2 {
-static const UInt32 kInBufSize = 1 << 20;
-
-CDecoder::CDecoder(): _inBuf(0), _outSizeDefined(false)
+CDecoder::CDecoder():
+ _inBuf(NULL),
+ _inBufSize(0),
+ _inBufSizeNew(1 << 20),
+ _outStepSize(1 << 22),
+ _outSizeDefined(false),
+ _finishMode(false)
{
Lzma2Dec_Construct(&_state);
}
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; }
+STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStepSize = size; return S_OK; }
CDecoder::~CDecoder()
{
Lzma2Dec_Free(&_state, &g_Alloc);
- MyFree(_inBuf);
+ MidFree(_inBuf);
}
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
{
- if (size != 1) return SZ_ERROR_UNSUPPORTED;
+ if (size != 1)
+ return E_NOTIMPL;
+
RINOK(SResToHRESULT(Lzma2Dec_Allocate(&_state, prop[0], &g_Alloc)));
- if (_inBuf == 0)
+ if (!_inBuf || _inBufSize != _inBufSizeNew)
{
- _inBuf = (Byte *)MyAlloc(kInBufSize);
- if (_inBuf == 0)
+ MidFree(_inBuf);
+ _inBufSize = 0;
+ _inBuf = (Byte *)MidAlloc(_inBufSizeNew);
+ if (!_inBuf)
return E_OUTOFMEMORY;
+ _inBufSize = _inBufSizeNew;
}
return S_OK;
@@ -62,6 +70,7 @@ STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
_outSizeDefined = (outSize != NULL);
+ _outSize = 0;
if (_outSizeDefined)
_outSize = *outSize;
@@ -72,39 +81,55 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
return S_OK;
}
+STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
+{
+ _finishMode = (finishMode != 0);
+ return S_OK;
+}
+
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 * /* inSize */,
+ ISequentialOutStream *outStream, const UInt64 *inSize,
const UInt64 *outSize, ICompressProgressInfo *progress)
{
- if (_inBuf == 0)
+ 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;
+
+ SizeT next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ?
+ _state.decoder.dicBufSize :
+ _state.decoder.dicPos + step;
+
+ HRESULT hres = S_OK;
+
for (;;)
{
if (_inPos == _inSize)
{
_inPos = _inSize = 0;
- RINOK(inStream->Read(_inBuf, kInBufSize, &_inSize));
+ hres = inStream->Read(_inBuf, _inBufSize, &_inSize);
+ if (hres != S_OK)
+ break;
}
SizeT dicPos = _state.decoder.dicPos;
- SizeT curSize = _state.decoder.dicBufSize - dicPos;
- const UInt32 kStepSize = ((UInt32)1 << 22);
- if (curSize > kStepSize)
- curSize = (SizeT)kStepSize;
-
+ SizeT curSize = next - dicPos;
+
ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
if (_outSizeDefined)
{
const UInt64 rem = _outSize - _outSizeProcessed;
- if (rem < curSize)
+ if (curSize >= rem)
{
curSize = (SizeT)rem;
- /*
- // finishMode = LZMA_FINISH_END;
- we can't use LZMA_FINISH_END here to allow partial decoding
- */
+ if (_finishMode)
+ finishMode = LZMA_FINISH_END;
}
}
@@ -117,71 +142,123 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
SizeT outSizeProcessed = _state.decoder.dicPos - dicPos;
_outSizeProcessed += outSizeProcessed;
- bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0);
- bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize);
+ bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0
+ || status == LZMA_STATUS_FINISHED_WITH_MARK);
+ bool outFinished = (_outSizeDefined && _outSizeProcessed >= _outSize);
- if (res != 0 || _state.decoder.dicPos == _state.decoder.dicBufSize || finished || stopDecoding)
+ if (res != 0
+ || _state.decoder.dicPos >= next
+ || finished
+ || outFinished)
{
- HRESULT res2 = WriteStream(outStream, _state.decoder.dic, _state.decoder.dicPos);
+ HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos);
+
+ if (_state.decoder.dicPos == _state.decoder.dicBufSize)
+ _state.decoder.dicPos = 0;
+
+ wrPos = _state.decoder.dicPos;
+
+ next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ?
+ _state.decoder.dicBufSize :
+ _state.decoder.dicPos + step;
+
if (res != 0)
return S_FALSE;
RINOK(res2);
- if (stopDecoding)
- return S_OK;
+
if (finished)
- return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE);
- }
- if (_state.decoder.dicPos == _state.decoder.dicBufSize)
- _state.decoder.dicPos = 0;
+ {
+ 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;
+ }
- if (progress != NULL)
+ if (outFinished && finishMode == LZMA_FINISH_ANY)
+ return S_OK;
+ }
+
+ if (progress)
{
RINOK(progress->SetRatioInfo(&_inSizeProcessed, &_outSizeProcessed));
}
}
+
+ HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos);
+ if (hres != S_OK)
+ return hres;
+ return res2;
}
#ifndef NO_READ_FROM_CODER
STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
+ UInt32 totalProcessed = 0;
+
if (processedSize)
*processedSize = 0;
- do
+
+ for (;;)
{
if (_inPos == _inSize)
{
_inPos = _inSize = 0;
- RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize));
+ RINOK(_inStream->Read(_inBuf, _inBufSize, &_inSize));
}
{
- SizeT inProcessed = _inSize - _inPos;
-
+ ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
if (_outSizeDefined)
{
const UInt64 rem = _outSize - _outSizeProcessed;
- if (rem < size)
+ if (rem <= size)
+ {
size = (UInt32)rem;
+ if (_finishMode)
+ finishMode = LZMA_FINISH_END;
+ }
}
SizeT outProcessed = size;
+ SizeT inProcessed = _inSize - _inPos;
+
ELzmaStatus status;
SRes res = Lzma2Dec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,
- _inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status);
+ _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 += (UInt32)outProcessed;
- RINOK(SResToHRESULT(res));
+ *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;
+ }
}
}
- while (size != 0);
- return S_OK;
}
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.h b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.h
index fd7ca2f3946..a87912fb596 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.h
+++ b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.h
@@ -15,7 +15,9 @@ namespace NLzma2 {
class CDecoder:
public ICompressCoder,
public ICompressSetDecoderProperties2,
+ public ICompressSetFinishMode,
public ICompressGetInStreamProcessedSize,
+ public ICompressSetBufSize,
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
public ICompressSetOutStreamSize,
@@ -27,36 +29,49 @@ class CDecoder:
Byte *_inBuf;
UInt32 _inPos;
UInt32 _inSize;
- CLzma2Dec _state;
+
+ bool _finishMode;
bool _outSizeDefined;
UInt64 _outSize;
+
UInt64 _inSizeProcessed;
UInt64 _outSizeProcessed;
+
+ UInt32 _inBufSize;
+ UInt32 _inBufSizeNew;
+ UInt32 _outStepSize;
+
+ 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_UNKNOWN_IMP5(
- ICompressSetDecoderProperties2,
- ICompressGetInStreamProcessedSize,
- ICompressSetInStream,
- ICompressSetOutStreamSize,
- ISequentialInStream)
- #else
- MY_UNKNOWN_IMP2(
- ICompressSetDecoderProperties2,
- ICompressGetInStreamProcessedSize)
+ 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(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 NO_READ_FROM_CODER
diff --git a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.cpp
index 5e4c71bea46..06a11f10eae 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.cpp
@@ -19,14 +19,6 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep);
namespace NLzma2 {
-static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }
-static void SzBigFree(void *, void *address) { BigFree(address); }
-static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
-
-static void *SzAlloc(void *, size_t size) { return MyAlloc(size); }
-static void SzFree(void *, void *address) { MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
CEncoder::CEncoder()
{
_encoder = 0;
@@ -46,7 +38,20 @@ HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzm
switch (propID)
{
case NCoderPropID::kBlockSize:
- if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.blockSize = prop.ulVal; break;
+ {
+ 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;
+ }
+ else
+ return E_INVALIDARG;
+ break;
+ }
case NCoderPropID::kNumThreads:
if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break;
default:
diff --git a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Register.cpp b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Register.cpp
index cace871eff2..d684d9d02f0 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Register.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Register.cpp
@@ -6,15 +6,12 @@
#include "Lzma2Decoder.h"
-static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NLzma2::CDecoder); }
#ifndef EXTRACT_ONLY
#include "Lzma2Encoder.h"
-static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NLzma2::CEncoder); }
-#else
-#define CreateCodecOut 0
#endif
-static CCodecInfo g_CodecInfo =
- { CreateCodec, CreateCodecOut, 0x21, L"LZMA2", 1, false };
-
-REGISTER_CODEC(LZMA2)
+REGISTER_CODEC_E(LZMA2,
+ NCompress::NLzma2::CDecoder(),
+ NCompress::NLzma2::CEncoder(),
+ 0x21,
+ "LZMA2")
diff --git a/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.cpp
index b7c260bd9e0..9002678ae08 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.cpp
@@ -10,7 +10,7 @@
static HRESULT SResToHRESULT(SRes res)
{
- switch(res)
+ switch (res)
{
case SZ_OK: return S_OK;
case SZ_ERROR_MEM: return E_OUTOFMEMORY;
@@ -25,19 +25,16 @@ namespace NCompress {
namespace NLzma {
CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false),
- _inBufSize(1 << 20),
- _outBufSize(1 << 22),
- FinishStream(false)
+ _inBufSize(1 << 20),
+ _outBufSize(1 << 22),
+ FinishStream(false),
+ NeedMoreInput(false)
{
_inSizeProcessed = 0;
_inPos = _inSize = 0;
LzmaDec_Construct(&_state);
}
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
CDecoder::~CDecoder()
{
LzmaDec_Free(&_state, &g_Alloc);
@@ -81,10 +78,17 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
_inSizeProcessed = 0;
_inPos = _inSize = 0;
+ NeedMoreInput = false;
SetOutStreamSizeResume(outSize);
return S_OK;
}
+STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
+{
+ FinishStream = (finishMode != 0);
+ return S_OK;
+}
+
HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
{
if (_inBuf == 0 || !_propsWereSet)
@@ -144,9 +148,21 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
return S_FALSE;
RINOK(res2);
if (stopDecoding)
+ {
+ if (status == LZMA_STATUS_NEEDS_MORE_INPUT)
+ NeedMoreInput = true;
+ if (FinishStream &&
+ status != LZMA_STATUS_FINISHED_WITH_MARK &&
+ status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
+ 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 (progress)
{
diff --git a/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.h b/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.h
index d28a4634bc6..f1f839a4f1b 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.h
+++ b/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.h
@@ -14,6 +14,7 @@ namespace NLzma {
class CDecoder:
public ICompressCoder,
public ICompressSetDecoderProperties2,
+ public ICompressSetFinishMode,
public ICompressSetBufSize,
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
@@ -45,6 +46,7 @@ class CDecoder:
public:
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize)
#ifndef NO_READ_FROM_CODER
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
@@ -57,6 +59,7 @@ public:
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(SetOutStreamSize)(const UInt64 *outSize);
STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
@@ -73,10 +76,14 @@ public:
#endif
- bool FinishStream;
+ 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
CDecoder();
virtual ~CDecoder();
+
+ UInt64 GetOutputProcessedSize() const { return _outSizeProcessed; }
};
}}
diff --git a/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.cpp
index 80e12f181dd..0a7e294d4f9 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.cpp
@@ -12,29 +12,21 @@
namespace NCompress {
namespace NLzma {
-static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }
-static void SzBigFree(void *, void *address) { BigFree(address); }
-static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
-
-static void *SzAlloc(void *, size_t size) { return MyAlloc(size); }
-static void SzFree(void *, void *address) { MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
CEncoder::CEncoder()
{
- _encoder = 0;
+ _encoder = NULL;
_encoder = LzmaEnc_Create(&g_Alloc);
- if (_encoder == 0)
+ if (!_encoder)
throw 1;
}
CEncoder::~CEncoder()
{
- if (_encoder != 0)
+ if (_encoder)
LzmaEnc_Destroy(_encoder, &g_Alloc, &g_BigAlloc);
}
-inline wchar_t GetUpperChar(wchar_t c)
+static inline wchar_t GetUpperChar(wchar_t c)
{
if (c >= 'a' && c <= 'z')
c -= 0x20;
@@ -51,22 +43,21 @@ static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes)
int numHashBytesLoc = (int)(*s++ - L'0');
if (numHashBytesLoc < 4 || numHashBytesLoc > 4)
return 0;
- if (*s++ != 0)
+ if (*s != 0)
return 0;
*btMode = 0;
*numHashBytes = numHashBytesLoc;
return 1;
}
+
if (c != L'B')
return 0;
-
if (GetUpperChar(*s++) != L'T')
return 0;
int numHashBytesLoc = (int)(*s++ - L'0');
if (numHashBytesLoc < 2 || numHashBytesLoc > 4)
return 0;
- c = GetUpperChar(*s++);
- if (c != L'\0')
+ if (*s != 0)
return 0;
*btMode = 1;
*numHashBytes = numHashBytesLoc;
@@ -87,8 +78,8 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
return S_OK;
if (propID == NCoderPropID::kReduceSize)
{
- if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1)
- ep.reduceSize = (UInt32)prop.uhVal.QuadPart;
+ if (prop.vt == VT_UI8)
+ ep.reduceSize = prop.uhVal.QuadPart;
return S_OK;
}
if (prop.vt != VT_UI4)
@@ -124,7 +115,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
switch (propID)
{
case NCoderPropID::kEndMarker:
- if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal == VARIANT_TRUE); break;
+ if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal != VARIANT_FALSE); break;
default:
RINOK(SetLzmaProp(propID, prop, props));
}
@@ -148,6 +139,7 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
CCompressProgressWrap progressWrap(progress);
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)
@@ -156,5 +148,5 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
return progressWrap.Res;
return SResToHRESULT(res);
}
-
+
}}
diff --git a/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.h b/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.h
index 904c0002c48..3ed067f14d3 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.h
+++ b/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.h
@@ -19,6 +19,7 @@ class CEncoder:
public CMyUnknownImp
{
CLzmaEncHandle _encoder;
+ UInt64 _inputProcessed;
public:
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties)
@@ -29,6 +30,7 @@ public:
CEncoder();
virtual ~CEncoder();
+ UInt64 GetInputProcessedSize() const { return _inputProcessed; }
};
}}
diff --git a/3rdparty/lzma/CPP/7zip/Compress/LzmaRegister.cpp b/3rdparty/lzma/CPP/7zip/Compress/LzmaRegister.cpp
index 96ed0baed06..c12416f2cd3 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/LzmaRegister.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/LzmaRegister.cpp
@@ -6,15 +6,12 @@
#include "LzmaDecoder.h"
-static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NLzma::CDecoder); }
#ifndef EXTRACT_ONLY
#include "LzmaEncoder.h"
-static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NLzma::CEncoder); }
-#else
-#define CreateCodecOut 0
#endif
-static CCodecInfo g_CodecInfo =
- { CreateCodec, CreateCodecOut, 0x030101, L"LZMA", 1, false };
-
-REGISTER_CODEC(LZMA)
+REGISTER_CODEC_E(LZMA,
+ NCompress::NLzma::CDecoder(),
+ NCompress::NLzma::CEncoder(),
+ 0x30101,
+ "LZMA")
diff --git a/3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.cpp
index c02f44f1666..c868730ea00 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.cpp
@@ -23,10 +23,6 @@ enum
kStatus_Error
};
-static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }
-static void SzBigFree(void *, void *address) { BigFree(address); }
-static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
-
CDecoder::~CDecoder()
{
::MidFree(_outBuf);
@@ -53,7 +49,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)
HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size)
{
- switch(_status)
+ switch (_status)
{
case kStatus_Finished: return S_OK;
case kStatus_Error: return S_FALSE;
diff --git a/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp
index 5bf83529383..00ea9668b00 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp
@@ -14,10 +14,6 @@ namespace NPpmd {
static const UInt32 kBufSize = (1 << 20);
-static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }
-static void SzBigFree(void *, void *address) { BigFree(address); }
-static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
-
static const Byte kOrders[10] = { 3, 4, 4, 5, 5, 6, 8, 16, 24, 32 };
void CEncProps::Normalize(int level)
@@ -40,7 +36,7 @@ void CEncProps::Normalize(int level)
}
}
}
- if (Order == -1) Order = kOrders[level];
+ if (Order == -1) Order = kOrders[(unsigned)level];
}
CEncoder::CEncoder():
diff --git a/3rdparty/lzma/CPP/7zip/Compress/PpmdRegister.cpp b/3rdparty/lzma/CPP/7zip/Compress/PpmdRegister.cpp
index 9f59fcdd39a..17f84bd03b9 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/PpmdRegister.cpp
+++ b/3rdparty/lzma/CPP/7zip/Compress/PpmdRegister.cpp
@@ -1,5 +1,4 @@
// PpmdRegister.cpp
-// 2009-05-30 : Igor Pavlov : Public domain
#include "StdAfx.h"
@@ -7,15 +6,12 @@
#include "PpmdDecoder.h"
-static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NPpmd::CDecoder); }
#ifndef EXTRACT_ONLY
#include "PpmdEncoder.h"
-static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NPpmd::CEncoder); }
-#else
-#define CreateCodecOut 0
#endif
-static CCodecInfo g_CodecInfo =
- { CreateCodec, CreateCodecOut, 0x030401, L"PPMD", 1, false };
-
-REGISTER_CODEC(PPMD)
+REGISTER_CODEC_E(PPMD,
+ NCompress::NPpmd::CDecoder(),
+ NCompress::NPpmd::CEncoder(),
+ 0x30401,
+ "PPMD")
diff --git a/3rdparty/lzma/CPP/7zip/Compress/RangeCoder.h b/3rdparty/lzma/CPP/7zip/Compress/RangeCoder.h
deleted file mode 100644
index 1eb2a6d470e..00000000000
--- a/3rdparty/lzma/CPP/7zip/Compress/RangeCoder.h
+++ /dev/null
@@ -1,205 +0,0 @@
-// Compress/RangeCoder.h
-// 2009-05-30 : Igor Pavlov : Public domain
-
-#ifndef __COMPRESS_RANGE_CODER_H
-#define __COMPRESS_RANGE_CODER_H
-
-#include "../Common/InBuffer.h"
-#include "../Common/OutBuffer.h"
-
-namespace NCompress {
-namespace NRangeCoder {
-
-const int kNumTopBits = 24;
-const UInt32 kTopValue = (1 << kNumTopBits);
-
-class CEncoder
-{
- UInt32 _cacheSize;
- Byte _cache;
-public:
- UInt64 Low;
- UInt32 Range;
- COutBuffer Stream;
- bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
-
- void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
- void Init()
- {
- Stream.Init();
- Low = 0;
- Range = 0xFFFFFFFF;
- _cacheSize = 1;
- _cache = 0;
- }
-
- void FlushData()
- {
- // Low += 1;
- for(int i = 0; i < 5; i++)
- ShiftLow();
- }
-
- HRESULT FlushStream() { return Stream.Flush(); }
-
- void ReleaseStream() { Stream.ReleaseStream(); }
-
- void Encode(UInt32 start, UInt32 size, UInt32 total)
- {
- Low += start * (Range /= total);
- Range *= size;
- while (Range < kTopValue)
- {
- Range <<= 8;
- ShiftLow();
- }
- }
-
- void ShiftLow()
- {
- if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
- {
- Byte temp = _cache;
- do
- {
- Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
- temp = 0xFF;
- }
- while(--_cacheSize != 0);
- _cache = (Byte)((UInt32)Low >> 24);
- }
- _cacheSize++;
- Low = (UInt32)Low << 8;
- }
-
- void EncodeDirectBits(UInt32 value, int numBits)
- {
- for (numBits--; numBits >= 0; numBits--)
- {
- Range >>= 1;
- Low += Range & (0 - ((value >> numBits) & 1));
- if (Range < kTopValue)
- {
- Range <<= 8;
- ShiftLow();
- }
- }
- }
-
- void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
- {
- UInt32 newBound = (Range >> numTotalBits) * size0;
- if (symbol == 0)
- Range = newBound;
- else
- {
- Low += newBound;
- Range -= newBound;
- }
- while (Range < kTopValue)
- {
- Range <<= 8;
- ShiftLow();
- }
- }
-
- UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
-};
-
-class CDecoder
-{
-public:
- CInBuffer Stream;
- UInt32 Range;
- UInt32 Code;
- bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
-
- void Normalize()
- {
- while (Range < kTopValue)
- {
- Code = (Code << 8) | Stream.ReadByte();
- Range <<= 8;
- }
- }
-
- void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
- void Init()
- {
- Stream.Init();
- Code = 0;
- Range = 0xFFFFFFFF;
- for(int i = 0; i < 5; i++)
- Code = (Code << 8) | Stream.ReadByte();
- }
-
- void ReleaseStream() { Stream.ReleaseStream(); }
-
- UInt32 GetThreshold(UInt32 total)
- {
- return (Code) / ( Range /= total);
- }
-
- void Decode(UInt32 start, UInt32 size)
- {
- Code -= start * Range;
- Range *= size;
- Normalize();
- }
-
- UInt32 DecodeDirectBits(int numTotalBits)
- {
- UInt32 range = Range;
- UInt32 code = Code;
- UInt32 result = 0;
- for (int i = numTotalBits; i != 0; i--)
- {
- range >>= 1;
- /*
- result <<= 1;
- if (code >= range)
- {
- code -= range;
- result |= 1;
- }
- */
- UInt32 t = (code - range) >> 31;
- code -= range & (t - 1);
- result = (result << 1) | (1 - t);
-
- if (range < kTopValue)
- {
- code = (code << 8) | Stream.ReadByte();
- range <<= 8;
- }
- }
- Range = range;
- Code = code;
- return result;
- }
-
- UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
- {
- UInt32 newBound = (Range >> numTotalBits) * size0;
- UInt32 symbol;
- if (Code < newBound)
- {
- symbol = 0;
- Range = newBound;
- }
- else
- {
- symbol = 1;
- Code -= newBound;
- Range -= newBound;
- }
- Normalize();
- return symbol;
- }
-
- UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
-};
-
-}}
-
-#endif
diff --git a/3rdparty/lzma/CPP/7zip/Compress/RangeCoderBit.h b/3rdparty/lzma/CPP/7zip/Compress/RangeCoderBit.h
deleted file mode 100644
index b5a1830d678..00000000000
--- a/3rdparty/lzma/CPP/7zip/Compress/RangeCoderBit.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Compress/RangeCoderBit.h
-// 2009-05-30 : Igor Pavlov : Public domain
-
-#ifndef __COMPRESS_RANGE_CODER_BIT_H
-#define __COMPRESS_RANGE_CODER_BIT_H
-
-#include "RangeCoder.h"
-
-namespace NCompress {
-namespace NRangeCoder {
-
-const int kNumBitModelTotalBits = 11;
-const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
-
-const int kNumMoveReducingBits = 4;
-
-const int kNumBitPriceShiftBits = 4;
-const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
-
-extern UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
-
-template <int numMoveBits>
-class CBitModel
-{
-public:
- UInt32 Prob;
- void UpdateModel(UInt32 symbol)
- {
- /*
- Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
- Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
- */
- if (symbol == 0)
- Prob += (kBitModelTotal - Prob) >> numMoveBits;
- else
- Prob -= (Prob) >> numMoveBits;
- }
-public:
- void Init() { Prob = kBitModelTotal / 2; }
-};
-
-template <int numMoveBits>
-class CBitEncoder: public CBitModel<numMoveBits>
-{
-public:
- void Encode(CEncoder *encoder, UInt32 symbol)
- {
- /*
- encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
- this->UpdateModel(symbol);
- */
- UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
- if (symbol == 0)
- {
- encoder->Range = newBound;
- this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
- }
- else
- {
- encoder->Low += newBound;
- encoder->Range -= newBound;
- this->Prob -= (this->Prob) >> numMoveBits;
- }
- if (encoder->Range < kTopValue)
- {
- encoder->Range <<= 8;
- encoder->ShiftLow();
- }
- }
- UInt32 GetPrice(UInt32 symbol) const
- {
- return ProbPrices[(this->Prob ^ ((-(int)symbol)) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
- }
- UInt32 GetPrice0() const { return ProbPrices[this->Prob >> kNumMoveReducingBits]; }
- UInt32 GetPrice1() const { return ProbPrices[(this->Prob ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]; }
-};
-
-
-template <int numMoveBits>
-class CBitDecoder: public CBitModel<numMoveBits>
-{
-public:
- UInt32 Decode(CDecoder *decoder)
- {
- UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
- if (decoder->Code < newBound)
- {
- decoder->Range = newBound;
- this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
- if (decoder->Range < kTopValue)
- {
- decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
- decoder->Range <<= 8;
- }
- return 0;
- }
- else
- {
- decoder->Range -= newBound;
- decoder->Code -= newBound;
- this->Prob -= (this->Prob) >> numMoveBits;
- if (decoder->Range < kTopValue)
- {
- decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
- decoder->Range <<= 8;
- }
- return 1;
- }
- }
-};
-
-}}
-
-#endif
diff --git a/3rdparty/lzma/CPP/7zip/Compress/StdAfx.h b/3rdparty/lzma/CPP/7zip/Compress/StdAfx.h
index 99a8aa46d36..1cbd7feaeec 100644
--- a/3rdparty/lzma/CPP/7zip/Compress/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/Compress/StdAfx.h
@@ -3,6 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../Common/MyWindows.h"
+#include "../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Crc.mak b/3rdparty/lzma/CPP/7zip/Crc.mak
index 7f2552c1708..f2b0874cb45 100644
--- a/3rdparty/lzma/CPP/7zip/Crc.mak
+++ b/3rdparty/lzma/CPP/7zip/Crc.mak
@@ -1,6 +1,6 @@
C_OBJS = $(C_OBJS) \
$O\7zCrc.obj
-!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS"
+!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM"
C_OBJS = $(C_OBJS) \
!ELSE
ASM_OBJS = $(ASM_OBJS) \
diff --git a/3rdparty/lzma/CPP/7zip/Crc64.mak b/3rdparty/lzma/CPP/7zip/Crc64.mak
new file mode 100644
index 00000000000..57301c22345
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Crc64.mak
@@ -0,0 +1,8 @@
+C_OBJS = $(C_OBJS) \
+ $O\XzCrc64.obj
+!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM"
+C_OBJS = $(C_OBJS) \
+!ELSE
+ASM_OBJS = $(ASM_OBJS) \
+!ENDIF
+ $O\XzCrc64Opt.obj
diff --git a/3rdparty/lzma/CPP/7zip/Crypto/7zAes.cpp b/3rdparty/lzma/CPP/7zip/Crypto/7zAes.cpp
new file mode 100644
index 00000000000..d33b562a3f6
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Crypto/7zAes.cpp
@@ -0,0 +1,280 @@
+// 7zAes.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Sha256.h"
+
+#include "../../Common/ComTry.h"
+
+#ifndef _7ZIP_ST
+#include "../../Windows/Synchronization.h"
+#endif
+
+#include "../Common/StreamUtils.h"
+
+#include "7zAes.h"
+#include "MyAes.h"
+
+#ifndef EXTRACT_ONLY
+#include "RandGen.h"
+#endif
+
+namespace NCrypto {
+namespace N7z {
+
+static const unsigned k_NumCyclesPower_Supported_MAX = 24;
+
+bool CKeyInfo::IsEqualTo(const CKeyInfo &a) const
+{
+ if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower)
+ return false;
+ for (unsigned i = 0; i < SaltSize; i++)
+ if (Salt[i] != a.Salt[i])
+ return false;
+ return (Password == a.Password);
+}
+
+void CKeyInfo::CalcKey()
+{
+ if (NumCyclesPower == 0x3F)
+ {
+ unsigned pos;
+ for (pos = 0; pos < SaltSize; pos++)
+ Key[pos] = Salt[pos];
+ for (unsigned i = 0; i < Password.Size() && pos < kKeySize; i++)
+ Key[pos++] = Password[i];
+ for (; pos < kKeySize; pos++)
+ Key[pos] = 0;
+ }
+ else
+ {
+ size_t bufSize = 8 + SaltSize + Password.Size();
+ CObjArray<Byte> buf(bufSize);
+ memcpy(buf, Salt, SaltSize);
+ memcpy(buf + SaltSize, Password, Password.Size());
+
+ CSha256 sha;
+ Sha256_Init(&sha);
+
+ Byte *ctr = buf + SaltSize + Password.Size();
+
+ for (unsigned i = 0; i < 8; i++)
+ ctr[i] = 0;
+
+ UInt64 numRounds = (UInt64)1 << NumCyclesPower;
+
+ do
+ {
+ Sha256_Update(&sha, buf, bufSize);
+ for (unsigned i = 0; i < 8; i++)
+ if (++(ctr[i]) != 0)
+ break;
+ }
+ while (--numRounds != 0);
+
+ Sha256_Final(&sha, Key);
+ }
+}
+
+bool CKeyInfoCache::GetKey(CKeyInfo &key)
+{
+ FOR_VECTOR (i, Keys)
+ {
+ const CKeyInfo &cached = Keys[i];
+ if (key.IsEqualTo(cached))
+ {
+ for (unsigned j = 0; j < kKeySize; j++)
+ key.Key[j] = cached.Key[j];
+ if (i != 0)
+ Keys.MoveToFront(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+void CKeyInfoCache::FindAndAdd(const CKeyInfo &key)
+{
+ FOR_VECTOR (i, Keys)
+ {
+ const CKeyInfo &cached = Keys[i];
+ if (key.IsEqualTo(cached))
+ {
+ if (i != 0)
+ Keys.MoveToFront(i);
+ return;
+ }
+ }
+ Add(key);
+}
+
+void CKeyInfoCache::Add(const CKeyInfo &key)
+{
+ if (Keys.Size() >= Size)
+ Keys.DeleteBack();
+ Keys.Insert(0, key);
+}
+
+static CKeyInfoCache g_GlobalKeyCache(32);
+
+#ifndef _7ZIP_ST
+ static NWindows::NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection;
+ #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection);
+#else
+ #define MT_LOCK
+#endif
+
+CBase::CBase():
+ _cachedKeys(16),
+ _ivSize(0)
+{
+ for (unsigned i = 0; i < sizeof(_iv); i++)
+ _iv[i] = 0;
+}
+
+void CBase::PrepareKey()
+{
+ // BCJ2 threads use same password. So we use long lock.
+ MT_LOCK
+
+ bool finded = false;
+ if (!_cachedKeys.GetKey(_key))
+ {
+ finded = g_GlobalKeyCache.GetKey(_key);
+ if (!finded)
+ _key.CalcKey();
+ _cachedKeys.Add(_key);
+ }
+ if (!finded)
+ g_GlobalKeyCache.FindAndAdd(_key);
+}
+
+#ifndef EXTRACT_ONLY
+
+/*
+STDMETHODIMP CEncoder::ResetSalt()
+{
+ _key.SaltSize = 4;
+ g_RandomGenerator.Generate(_key.Salt, _key.SaltSize);
+ return S_OK;
+}
+*/
+
+STDMETHODIMP CEncoder::ResetInitVector()
+{
+ for (unsigned i = 0; i < sizeof(_iv); i++)
+ _iv[i] = 0;
+ _ivSize = 8;
+ g_RandomGenerator.Generate(_iv, _ivSize);
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ Byte props[2 + sizeof(_key.Salt) + sizeof(_iv)];
+ unsigned propsSize = 1;
+
+ props[0] = (Byte)(_key.NumCyclesPower
+ | (_key.SaltSize == 0 ? 0 : (1 << 7))
+ | (_ivSize == 0 ? 0 : (1 << 6)));
+
+ if (_key.SaltSize != 0 || _ivSize != 0)
+ {
+ props[1] = (Byte)(
+ ((_key.SaltSize == 0 ? 0 : _key.SaltSize - 1) << 4)
+ | (_ivSize == 0 ? 0 : _ivSize - 1));
+ memcpy(props + 2, _key.Salt, _key.SaltSize);
+ propsSize = 2 + _key.SaltSize;
+ memcpy(props + propsSize, _iv, _ivSize);
+ propsSize += _ivSize;
+ }
+
+ return WriteStream(outStream, props, propsSize);
+}
+
+CEncoder::CEncoder()
+{
+ // _key.SaltSize = 4; g_RandomGenerator.Generate(_key.Salt, _key.SaltSize);
+ // _key.NumCyclesPower = 0x3F;
+ _key.NumCyclesPower = 19;
+ _aesFilter = new CAesCbcEncoder(kKeySize);
+}
+
+#endif
+
+CDecoder::CDecoder()
+{
+ _aesFilter = new CAesCbcDecoder(kKeySize);
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ _key.ClearProps();
+
+ _ivSize = 0;
+ unsigned i;
+ for (i = 0; i < sizeof(_iv); i++)
+ _iv[i] = 0;
+
+ if (size == 0)
+ return S_OK;
+
+ Byte b0 = data[0];
+
+ _key.NumCyclesPower = b0 & 0x3F;
+ if ((b0 & 0xC0) == 0)
+ return size == 1 ? S_OK : E_INVALIDARG;
+
+ if (size <= 1)
+ return E_INVALIDARG;
+
+ Byte b1 = data[1];
+
+ unsigned saltSize = ((b0 >> 7) & 1) + (b1 >> 4);
+ unsigned ivSize = ((b0 >> 6) & 1) + (b1 & 0x0F);
+
+ if (size != 2 + saltSize + ivSize)
+ return E_INVALIDARG;
+ _key.SaltSize = saltSize;
+ data += 2;
+ for (i = 0; i < saltSize; i++)
+ _key.Salt[i] = *data++;
+ for (i = 0; i < ivSize; i++)
+ _iv[i] = *data++;
+ return (_key.NumCyclesPower <= k_NumCyclesPower_Supported_MAX
+ || _key.NumCyclesPower == 0x3F) ? S_OK : E_NOTIMPL;
+}
+
+
+STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ COM_TRY_BEGIN
+
+ _key.Password.CopyFrom(data, (size_t)size);
+ return S_OK;
+
+ COM_TRY_END
+}
+
+STDMETHODIMP CBaseCoder::Init()
+{
+ COM_TRY_BEGIN
+
+ PrepareKey();
+ CMyComPtr<ICryptoProperties> cp;
+ RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));
+ if (!cp)
+ return E_FAIL;
+ RINOK(cp->SetKey(_key.Key, kKeySize));
+ RINOK(cp->SetInitVector(_iv, sizeof(_iv)));
+ return _aesFilter->Init();
+
+ COM_TRY_END
+}
+
+STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size)
+{
+ return _aesFilter->Filter(data, size);
+}
+
+}}
diff --git a/3rdparty/lzma/CPP/7zip/Crypto/7zAes.h b/3rdparty/lzma/CPP/7zip/Crypto/7zAes.h
new file mode 100644
index 00000000000..4bd7d2911cc
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Crypto/7zAes.h
@@ -0,0 +1,116 @@
+// 7zAes.h
+
+#ifndef __CRYPTO_7Z_AES_H
+#define __CRYPTO_7Z_AES_H
+
+#include "../../Common/MyBuffer.h"
+#include "../../Common/MyCom.h"
+#include "../../Common/MyVector.h"
+
+#include "../ICoder.h"
+#include "../IPassword.h"
+
+namespace NCrypto {
+namespace N7z {
+
+const unsigned kKeySize = 32;
+const unsigned kSaltSizeMax = 16;
+const unsigned kIvSizeMax = 16; // AES_BLOCK_SIZE;
+
+class CKeyInfo
+{
+public:
+ unsigned NumCyclesPower;
+ unsigned SaltSize;
+ Byte Salt[kSaltSizeMax];
+ CByteBuffer Password;
+ Byte Key[kKeySize];
+
+ bool IsEqualTo(const CKeyInfo &a) const;
+ void CalcKey();
+
+ CKeyInfo() { ClearProps(); }
+ void ClearProps()
+ {
+ NumCyclesPower = 0;
+ SaltSize = 0;
+ for (unsigned i = 0; i < sizeof(Salt); i++)
+ Salt[i] = 0;
+ }
+};
+
+class CKeyInfoCache
+{
+ unsigned Size;
+ CObjectVector<CKeyInfo> Keys;
+public:
+ CKeyInfoCache(unsigned size): Size(size) {}
+ bool GetKey(CKeyInfo &key);
+ void Add(const CKeyInfo &key);
+ void FindAndAdd(const CKeyInfo &key);
+};
+
+class CBase
+{
+ CKeyInfoCache _cachedKeys;
+protected:
+ CKeyInfo _key;
+ Byte _iv[kIvSizeMax];
+ unsigned _ivSize;
+
+ void PrepareKey();
+ CBase();
+};
+
+class CBaseCoder:
+ public ICompressFilter,
+ public ICryptoSetPassword,
+ public CMyUnknownImp,
+ public CBase
+{
+protected:
+ CMyComPtr<ICompressFilter> _aesFilter;
+
+public:
+ INTERFACE_ICompressFilter(;)
+
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+};
+
+#ifndef EXTRACT_ONLY
+
+class CEncoder:
+ public CBaseCoder,
+ public ICompressWriteCoderProperties,
+ // public ICryptoResetSalt,
+ public ICryptoResetInitVector
+{
+public:
+ MY_UNKNOWN_IMP3(
+ ICryptoSetPassword,
+ ICompressWriteCoderProperties,
+ // ICryptoResetSalt,
+ ICryptoResetInitVector)
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ // STDMETHOD(ResetSalt)();
+ STDMETHOD(ResetInitVector)();
+ CEncoder();
+};
+
+#endif
+
+class CDecoder:
+ public CBaseCoder,
+ public ICompressSetDecoderProperties2
+{
+public:
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICompressSetDecoderProperties2)
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+ CDecoder();
+};
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/Crypto/7zAesRegister.cpp b/3rdparty/lzma/CPP/7zip/Crypto/7zAesRegister.cpp
new file mode 100644
index 00000000000..f1916cb15f1
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Crypto/7zAesRegister.cpp
@@ -0,0 +1,12 @@
+// 7zAesRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/RegisterCodec.h"
+
+#include "7zAes.h"
+
+REGISTER_FILTER_E(7zAES,
+ NCrypto::N7z::CDecoder(),
+ NCrypto::N7z::CEncoder(),
+ 0x6F10701, "7zAES")
diff --git a/3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp b/3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp
new file mode 100644
index 00000000000..52eaab7ae2c
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp
@@ -0,0 +1,112 @@
+// Crypto/MyAes.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/CpuArch.h"
+
+#include "MyAes.h"
+
+namespace NCrypto {
+
+static struct CAesTabInit { CAesTabInit() { AesGenTables();} } g_AesTabInit;
+
+CAesCbcCoder::CAesCbcCoder(bool encodeMode, unsigned keySize):
+ _keySize(keySize),
+ _keyIsSet(false),
+ _encodeMode(encodeMode)
+{
+ _offset = ((0 - (unsigned)(ptrdiff_t)_aes) & 0xF) / sizeof(UInt32);
+ memset(_iv, 0, AES_BLOCK_SIZE);
+ SetFunctions(0);
+}
+
+STDMETHODIMP CAesCbcCoder::Init()
+{
+ AesCbc_Init(_aes + _offset, _iv);
+ return _keyIsSet ? S_OK : E_FAIL;
+}
+
+STDMETHODIMP_(UInt32) CAesCbcCoder::Filter(Byte *data, UInt32 size)
+{
+ if (!_keyIsSet)
+ return 0;
+ if (size == 0)
+ return 0;
+ if (size < AES_BLOCK_SIZE)
+ return AES_BLOCK_SIZE;
+ size >>= 4;
+ _codeFunc(_aes + _offset, data, size);
+ return size << 4;
+}
+
+STDMETHODIMP CAesCbcCoder::SetKey(const Byte *data, UInt32 size)
+{
+ if ((size & 0x7) != 0 || size < 16 || size > 32)
+ return E_INVALIDARG;
+ if (_keySize != 0 && size != _keySize)
+ return E_INVALIDARG;
+ AES_SET_KEY_FUNC setKeyFunc = _encodeMode ? Aes_SetKey_Enc : Aes_SetKey_Dec;
+ setKeyFunc(_aes + _offset + 4, data, size);
+ _keyIsSet = true;
+ return S_OK;
+}
+
+STDMETHODIMP CAesCbcCoder::SetInitVector(const Byte *data, UInt32 size)
+{
+ if (size != AES_BLOCK_SIZE)
+ return E_INVALIDARG;
+ memcpy(_iv, data, size);
+ CAesCbcCoder::Init(); // don't call virtual function here !!!
+ return S_OK;
+}
+
+EXTERN_C_BEGIN
+
+void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks);
+
+void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
+
+EXTERN_C_END
+
+bool CAesCbcCoder::SetFunctions(UInt32 algo)
+{
+ _codeFunc = _encodeMode ?
+ g_AesCbc_Encode :
+ g_AesCbc_Decode;
+ if (algo == 1)
+ {
+ _codeFunc = _encodeMode ?
+ AesCbc_Encode:
+ AesCbc_Decode;
+ }
+ if (algo == 2)
+ {
+ #ifdef MY_CPU_X86_OR_AMD64
+ if (g_AesCbc_Encode != AesCbc_Encode_Intel)
+ #endif
+ return false;
+ }
+ return true;
+}
+
+STDMETHODIMP CAesCbcCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ if (propIDs[i] == NCoderPropID::kDefaultProp)
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ if (!SetFunctions(prop.ulVal))
+ return E_NOTIMPL;
+ }
+ }
+ return S_OK;
+}
+
+}
diff --git a/3rdparty/lzma/CPP/7zip/Crypto/MyAes.h b/3rdparty/lzma/CPP/7zip/Crypto/MyAes.h
new file mode 100644
index 00000000000..289935ebc36
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Crypto/MyAes.h
@@ -0,0 +1,55 @@
+// Crypto/MyAes.h
+
+#ifndef __CRYPTO_MY_AES_H
+#define __CRYPTO_MY_AES_H
+
+#include "../../../C/Aes.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+namespace NCrypto {
+
+class CAesCbcCoder:
+ public ICompressFilter,
+ public ICryptoProperties,
+ public ICompressSetCoderProperties,
+ public CMyUnknownImp
+{
+ AES_CODE_FUNC _codeFunc;
+ unsigned _offset;
+ unsigned _keySize;
+ bool _keyIsSet;
+ bool _encodeMode;
+ UInt32 _aes[AES_NUM_IVMRK_WORDS + 3];
+ Byte _iv[AES_BLOCK_SIZE];
+
+ bool SetFunctions(UInt32 algo);
+
+public:
+ CAesCbcCoder(bool encodeMode, unsigned keySize);
+
+ MY_UNKNOWN_IMP2(ICryptoProperties, ICompressSetCoderProperties)
+
+ INTERFACE_ICompressFilter(;)
+
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size);
+ STDMETHOD(SetInitVector)(const Byte *data, UInt32 size);
+
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+};
+
+struct CAesCbcEncoder: public CAesCbcCoder
+{
+ CAesCbcEncoder(unsigned keySize = 0): CAesCbcCoder(true, keySize) {}
+};
+
+struct CAesCbcDecoder: public CAesCbcCoder
+{
+ CAesCbcDecoder(unsigned keySize = 0): CAesCbcCoder(false, keySize) {}
+};
+
+}
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/Crypto/MyAesReg.cpp b/3rdparty/lzma/CPP/7zip/Crypto/MyAesReg.cpp
new file mode 100644
index 00000000000..34035da6888
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Crypto/MyAesReg.cpp
@@ -0,0 +1,12 @@
+// MyAesReg.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/RegisterCodec.h"
+
+#include "MyAes.h"
+
+REGISTER_FILTER_E(AES256CBC,
+ NCrypto::CAesCbcDecoder(32),
+ NCrypto::CAesCbcEncoder(32),
+ 0x6F00181, "AES256CBC")
diff --git a/3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp b/3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp
new file mode 100644
index 00000000000..408f73f1686
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp
@@ -0,0 +1,124 @@
+// RandGen.cpp
+
+#include "StdAfx.h"
+
+#ifndef _7ZIP_ST
+#include "../../Windows/Synchronization.h"
+#endif
+
+#include "RandGen.h"
+
+#ifndef _WIN32
+#include <unistd.h>
+#define USE_POSIX_TIME
+#define USE_POSIX_TIME2
+#endif
+
+#ifdef USE_POSIX_TIME
+#include <time.h>
+#ifdef USE_POSIX_TIME2
+#include <sys/time.h>
+#endif
+#endif
+
+// This is not very good random number generator.
+// Please use it only for salt.
+// First generated data block depends from timer and processID.
+// Other generated data blocks depend from previous state
+// Maybe it's possible to restore original timer value from generated value.
+
+#define HASH_UPD(x) Sha256_Update(&hash, (const Byte *)&x, sizeof(x));
+
+void CRandomGenerator::Init()
+{
+ CSha256 hash;
+ Sha256_Init(&hash);
+
+ #ifdef _WIN32
+ DWORD w = ::GetCurrentProcessId();
+ HASH_UPD(w);
+ w = ::GetCurrentThreadId();
+ HASH_UPD(w);
+ #else
+ pid_t pid = getpid();
+ HASH_UPD(pid);
+ pid = getppid();
+ HASH_UPD(pid);
+ #endif
+
+ for (unsigned i = 0; i <
+ #ifdef _DEBUG
+ 2;
+ #else
+ 1000;
+ #endif
+ i++)
+ {
+ #ifdef _WIN32
+ LARGE_INTEGER v;
+ if (::QueryPerformanceCounter(&v))
+ HASH_UPD(v.QuadPart);
+ #endif
+
+ #ifdef USE_POSIX_TIME
+ #ifdef USE_POSIX_TIME2
+ timeval v;
+ if (gettimeofday(&v, 0) == 0)
+ {
+ HASH_UPD(v.tv_sec);
+ HASH_UPD(v.tv_usec);
+ }
+ #endif
+ time_t v2 = time(NULL);
+ HASH_UPD(v2);
+ #endif
+
+ #ifdef _WIN32
+ DWORD tickCount = ::GetTickCount();
+ HASH_UPD(tickCount);
+ #endif
+
+ for (unsigned j = 0; j < 100; j++)
+ {
+ Sha256_Final(&hash, _buff);
+ Sha256_Init(&hash);
+ Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
+ }
+ }
+ Sha256_Final(&hash, _buff);
+ _needInit = false;
+}
+
+#ifndef _7ZIP_ST
+ static NWindows::NSynchronization::CCriticalSection g_CriticalSection;
+ #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+#else
+ #define MT_LOCK
+#endif
+
+void CRandomGenerator::Generate(Byte *data, unsigned size)
+{
+ MT_LOCK
+
+ if (_needInit)
+ Init();
+ while (size != 0)
+ {
+ CSha256 hash;
+
+ Sha256_Init(&hash);
+ Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
+ Sha256_Final(&hash, _buff);
+
+ Sha256_Init(&hash);
+ UInt32 salt = 0xF672ABD1;
+ HASH_UPD(salt);
+ Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
+ Byte buff[SHA256_DIGEST_SIZE];
+ Sha256_Final(&hash, buff);
+ for (unsigned i = 0; i < SHA256_DIGEST_SIZE && size != 0; i++, size--)
+ *data++ = buff[i];
+ }
+}
+
+CRandomGenerator g_RandomGenerator;
diff --git a/3rdparty/lzma/CPP/7zip/Crypto/RandGen.h b/3rdparty/lzma/CPP/7zip/Crypto/RandGen.h
new file mode 100644
index 00000000000..cfdcd60d012
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Crypto/RandGen.h
@@ -0,0 +1,21 @@
+// RandGen.h
+
+#ifndef __CRYPTO_RAND_GEN_H
+#define __CRYPTO_RAND_GEN_H
+
+#include "../../../C/Sha256.h"
+
+class CRandomGenerator
+{
+ Byte _buff[SHA256_DIGEST_SIZE];
+ bool _needInit;
+
+ void Init();
+public:
+ CRandomGenerator(): _needInit(true) {};
+ void Generate(Byte *data, unsigned size);
+};
+
+extern CRandomGenerator g_RandomGenerator;
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/Crypto/StdAfx.h b/3rdparty/lzma/CPP/7zip/Crypto/StdAfx.h
new file mode 100644
index 00000000000..1cbd7feaeec
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/Crypto/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../Common/Common.h"
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/GuiCommon.rc b/3rdparty/lzma/CPP/7zip/GuiCommon.rc
new file mode 100644
index 00000000000..6b26ddd85c9
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/GuiCommon.rc
@@ -0,0 +1,81 @@
+#include <windows.h>
+
+// #include <winnt.h>
+// #include <WinUser.h>
+
+// for Windows CE:
+#include <CommCtrl.h>
+
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+#undef m
+#undef bxs
+#undef bys
+#undef bxsDots
+#undef y
+#undef xc
+#undef yc
+#undef xs
+#undef ys
+#undef bx
+#undef bx1
+#undef bx2
+#undef bx3
+#undef by
+#undef by1
+#undef by2
+#undef by3
+#undef gSpace
+#undef gSize
+#undef marg2
+#undef marg3
+
+#undef MY_DIALOG
+#undef MY_RESIZE_DIALOG
+#undef MY_PAGE
+
+#define m 8
+#define bxs 64
+#define bys 16
+#define bxsDots 20
+
+#define xs (xc + m + m)
+#define ys (yc + m + m)
+
+#define bx1 (xs - m - bxs)
+#define bx2 (bx1 - m - bxs)
+#define bx3 (bx2 - m - bxs)
+#define bx bx1
+
+#define by1 (ys - m - bys)
+#define by2 (by1 - m - bys)
+#define by by1
+
+
+#define MY_MODAL_DIALOG_STYLE STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+
+#define MY_MODAL_RESIZE_DIALOG_STYLE MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX | WS_THICKFRAME
+
+#define MY_PAGE_STYLE STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
+
+#define MY_FONT FONT 8, "MS Shell Dlg"
+
+#define SMALL_PAGE_SIZE_X 120
+
+// #define MY_DIALOG DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT
+// #define MY_RESIZE_DIALOG DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT
+#define MY_PAGE DIALOG 0, 0, xs, ys MY_PAGE_STYLE MY_FONT
+
+#define OK_CANCEL \
+ DEFPUSHBUTTON "OK", IDOK, bx2, by, bxs, bys \
+ PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
+
+
+#define MY_COMBO CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+#define MY_COMBO_SORTED MY_COMBO | CBS_SORT
+#define MY_COMBO_WITH_EDIT CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+
+#define MY_CHECKBOX "Button", BS_AUTOCHECKBOX | WS_TABSTOP
+
+#define MY_TEXT_NOPREFIX 8, SS_NOPREFIX
diff --git a/3rdparty/lzma/CPP/7zip/Guid.txt b/3rdparty/lzma/CPP/7zip/Guid.txt
index 0db316a5d8e..7edab6ead87 100644
--- a/3rdparty/lzma/CPP/7zip/Guid.txt
+++ b/3rdparty/lzma/CPP/7zip/Guid.txt
@@ -3,17 +3,25 @@
00 IProgress.h
05 IProgress
+ // 050002 IProgress2
01 IFolderArchive.h
- 05 IArchiveFolder
+ // 05 IArchiveFolder // old
// 06 IInFolderArchive // old
07 IFileExtractCallback.h::IFolderArchiveExtractCallback
- 0A IOutFolderArchive
+ 08 IFileExtractCallback.h::IFolderArchiveExtractCallback2
+ // 0A IOutFolderArchive
0B IFolderArchiveUpdateCallback
0C Agent.h::IArchiveFolderInternal
- 0D
+ 0D IArchiveFolder
0E IInFolderArchive
+ 0F IOutFolderArchive
+ 10 IFolderArchiveUpdateCallback2
+ 11 IFolderScanProgress
+
+ 20 IFileExtractCallback.h::IGetProp
+ 30 IFileExtractCallback.h::IFolderExtractToStreamCallback
03 IStream.h
@@ -22,7 +30,9 @@
03 IInStream
04 IOutStream
06 IStreamGetSize
- 07 IOutStreamFlush
+ 07 IOutStreamFinish
+ 08 IStreamGetProps
+ 09 IStreamGetProps2
04 ICoder.h
@@ -36,12 +46,20 @@
23 ICompressWriteCoderProperties
24 ICompressGetInStreamProcessedSize
25 ICompressSetCoderMt
+ 26 ICompressSetFinishMode
+
30 ICompressGetSubStreamSize
31 ICompressSetInStream
32 ICompressSetOutStream
- 33 ICompressSetInStreamSize
+// 33 ICompressSetInStreamSize
34 ICompressSetOutStreamSize
35 ICompressSetBufSize
+ 36 ICompressInitEncoder
+ 37 ICompressSetInStream2
+// 38 ICompressSetOutStream2
+// 39 SetInStreamSize2
+// 3A SetOutStreamSize2
+
40 ICompressFilter
60 ICompressCodecsInfo
61 ISetCompressCodecsInfo
@@ -50,6 +68,8 @@
8C ICryptoResetInitVector
90 ICryptoSetPassword
A0 ICryptoSetCRC
+ C0 IHasher
+ C1 IHashers
05 IPassword.h
@@ -61,17 +81,26 @@
06 IArchive.h
03 ISetProperties
+ 04 IArchiveKeepModeForNextOpen
+ 05 IArchiveAllowTail
10 IArchiveOpenCallback
+
20 IArchiveExtractCallback
+ 21 IArchiveExtractCallbackMessage
+
30 IArchiveOpenVolumeCallback
40 IInArchiveGetStream
50 IArchiveOpenSetSubArchiveName
60 IInArchive
61 IArchiveOpenSeq
+ 70 IArchiveGetRawProps
+ 71 IArchiveGetRootProps
80 IArchiveUpdateCallback
82 IArchiveUpdateCallback2
+ 83 IArchiveUpdateCallbackFile
+
A0 IOutArchive
@@ -96,7 +125,12 @@
0F
10 IFolderArcProps
11 IGetFolderArcProps
- 12 IFolderOperations
+ 12 // IFolderOperations
+ 13 IFolderOperations
+ 14 IFolderCalcItemFullSize
+ 15 IFolderCompare
+ 16 IFolderGetItemName
+ 17 IFolderAltStreams
09 IFolder.h :: FOLDER_MANAGER_INTERFACE
@@ -129,6 +163,14 @@ Handler GUIDs:
0C xz
0D ppmd
+ C7 Ext
+ C8 VMDK
+ C9 VDI
+ CA Qcow
+ CB GPT
+ CC Rar5
+ CD IHex
+ CE Hxs
CF TE
D0 UEFIc
D1 UEFIs
@@ -163,12 +205,12 @@ Handler GUIDs:
EE Tar
EF GZip
-{23170F69-40C1-278A-1000-000100030000} CAgentArchiveHandle
{23170F69-40C1-278A-1000-000100020000} ContextMenu.h::CZipContextMenu
-{23170F69-40C1-278B- old codecs clsids
-
-{23170F69-40C1-278D-1000-000100020000} OptionsDialog.h::CLSID_CSevenZipOptions
+// {23170F69-40C1-278A-1000-000100030000} // CAgentArchiveHandler
+// {23170F69-40C1-278B- old codecs clsids
+// {23170F69-40C1-278D-1000-000100020000} OptionsDialog.h::CLSID_CSevenZipOptions
{23170F69-40C1-2790-id} Codec Decoders
{23170F69-40C1-2791-id} Codec Encoders
+{23170F69-40C1-2792-id} Hashers
diff --git a/3rdparty/lzma/CPP/7zip/ICoder.h b/3rdparty/lzma/CPP/7zip/ICoder.h
index b43997d430f..75db9399379 100644
--- a/3rdparty/lzma/CPP/7zip/ICoder.h
+++ b/3rdparty/lzma/CPP/7zip/ICoder.h
@@ -10,6 +10,15 @@
CODER_INTERFACE(ICompressProgressInfo, 0x04)
{
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE;
+
+ /* (inSize) can be NULL, if unknown
+ (outSize) can be NULL, if unknown
+
+ returns:
+ S_OK
+ E_ABORT : Break by user
+ another error codes
+ */
};
CODER_INTERFACE(ICompressCoder, 0x05)
@@ -21,11 +30,75 @@ CODER_INTERFACE(ICompressCoder, 0x05)
CODER_INTERFACE(ICompressCoder2, 0x18)
{
- STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
- ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
+ STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams,
+ ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams,
ICompressProgressInfo *progress) PURE;
};
+/*
+ ICompressCoder::Code
+ ICompressCoder2::Code
+
+ returns:
+ S_OK : OK
+ S_FALSE : data error (for decoders)
+ E_OUTOFMEMORY : memory allocation error
+ another error code : some error. For example, it can be error code received from inStream or outStream function.
+
+ Parameters:
+ (inStream != NULL)
+ (outStream != NULL)
+
+ if (inSize != NULL)
+ {
+ Encoders in 7-Zip ignore (inSize).
+ Decoder can use (*inSize) to check that stream was decoded correctly.
+ Some decoder in 7-Zip check it, if (full_decoding mode was set via ICompressSetFinishMode)
+ }
+
+ If it's required to limit the reading from input stream (inStream), it can
+ be done with ISequentialInStream implementation.
+
+ if (outSize != NULL)
+ {
+ Encoders in 7-Zip ignore (outSize).
+ Decoder unpacks no more than (*outSize) bytes.
+ }
+
+ (progress == NULL) is allowed.
+
+
+ Decoding with Code() function
+ -----------------------------
+
+ You can request some interfaces before decoding
+ - ICompressSetDecoderProperties2
+ - ICompressSetFinishMode
+
+ If you need to decode full stream:
+ {
+ 1) try to set full_decoding mode with ICompressSetFinishMode::SetFinishMode(1);
+ 2) call the Code() function with specified (inSize) and (outSize), if these sizes are known.
+ }
+
+ If you need to decode only part of stream:
+ {
+ 1) try to set partial_decoding mode with ICompressSetFinishMode::SetFinishMode(0);
+ 2) Call the Code() function with specified (inSize = NULL) and specified (outSize).
+ }
+
+ Encoding with Code() function
+ -----------------------------
+
+ You can request some interfaces :
+ - ICompressSetCoderProperties - use it before encoding to set properties
+ - ICompressWriteCoderProperties - use it before or after encoding to request encoded properties.
+
+ ICompressCoder2 is used when (numInStreams != 1 || numOutStreams != 1)
+ The rules are similar to ICompressCoder rules
+*/
+
+
namespace NCoderPropID
{
enum EEnum
@@ -64,6 +137,12 @@ CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
{
+ /* returns:
+ S_OK
+ E_NOTIMP : unsupported properties
+ E_INVALIDARG : incorrect (or unsupported) properties
+ E_OUTOFMEMORY : memory allocation error
+ */
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
};
@@ -82,9 +161,34 @@ CODER_INTERFACE(ICompressSetCoderMt, 0x25)
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;
};
+CODER_INTERFACE(ICompressSetFinishMode, 0x26)
+{
+ STDMETHOD(SetFinishMode)(UInt32 finishMode) PURE;
+
+ /* finishMode:
+ 0 : partial decoding is allowed. It's default mode for ICompressCoder::Code(), if (outSize) is defined.
+ 1 : full decoding. The stream must be finished at the end of decoding. */
+};
+
+
CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
{
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
+
+ /* returns:
+ S_OK : (*value) contains the size or estimated size (can be incorrect size)
+ S_FALSE : size is undefined
+ E_NOTIMP : the feature is not implemented
+
+ Let's (read_size) is size of data that was already read by ISequentialInStream::Read().
+ The caller should call GetSubStreamSize() after each Read() and check sizes:
+ if (start_of_subStream + *value < read_size)
+ {
+ // (*value) is correct, and it's allowed to call GetSubStreamSize() for next subStream:
+ start_of_subStream += *value;
+ subStream++;
+ }
+ */
};
CODER_INTERFACE(ICompressSetInStream, 0x31)
@@ -99,14 +203,21 @@ CODER_INTERFACE(ICompressSetOutStream, 0x32)
STDMETHOD(ReleaseOutStream)() PURE;
};
+/*
CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
{
STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
};
+*/
CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
{
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
+
+ /* That function initializes decoder structures.
+ Call this function only for stream version of decoder.
+ if (outSize == NULL), then output size is unknown
+ if (outSize != NULL), then the decoder must stop decoding after (*outSize) bytes. */
};
CODER_INTERFACE(ICompressSetBufSize, 0x35)
@@ -115,25 +226,62 @@ CODER_INTERFACE(ICompressSetBufSize, 0x35)
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size) PURE;
};
+CODER_INTERFACE(ICompressInitEncoder, 0x36)
+{
+ STDMETHOD(InitEncoder)() PURE;
+
+ /* That function initializes encoder structures.
+ Call this function only for stream version of encoder. */
+};
+
+CODER_INTERFACE(ICompressSetInStream2, 0x37)
+{
+ STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream) PURE;
+ STDMETHOD(ReleaseInStream2)(UInt32 streamIndex) PURE;
+};
+
+/*
+CODER_INTERFACE(ICompressSetOutStream2, 0x38)
+{
+ STDMETHOD(SetOutStream2)(UInt32 streamIndex, ISequentialOutStream *outStream) PURE;
+ STDMETHOD(ReleaseOutStream2)(UInt32 streamIndex) PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStreamSize2, 0x39)
+{
+ STDMETHOD(SetInStreamSize2)(UInt32 streamIndex, const UInt64 *inSize) PURE;
+};
+*/
+
+
+/*
+ ICompressFilter
+ Filter() converts as most as possible bytes
+ returns: (outSize):
+ if (outSize <= size) : Filter have converted outSize bytes
+ if (outSize > size) : Filter have not converted anything.
+ and it needs at least outSize bytes to convert one block
+ (it's for crypto block algorithms).
+*/
+
+#define INTERFACE_ICompressFilter(x) \
+ STDMETHOD(Init)() x; \
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) x; \
+
CODER_INTERFACE(ICompressFilter, 0x40)
{
- STDMETHOD(Init)() PURE;
- STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE;
- // Filter converts as most as possible bytes
- // Filter return outSize (UInt32)
- // if (outSize <= size): Filter have converted outSize bytes
- // if (outSize > size): Filter have not converted anything.
- // and it needs at least outSize bytes to convert one block
- // (it's for crypto block algorithms).
+ INTERFACE_ICompressFilter(PURE);
};
+
CODER_INTERFACE(ICompressCodecsInfo, 0x60)
{
- STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods) PURE;
+ STDMETHOD(GetNumMethods)(UInt32 *numMethods) PURE;
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder) PURE;
STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder) PURE;
};
+
CODER_INTERFACE(ISetCompressCodecsInfo, 0x61)
{
STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo) PURE;
@@ -155,6 +303,10 @@ CODER_INTERFACE(ICryptoResetSalt, 0x88)
CODER_INTERFACE(ICryptoResetInitVector, 0x8C)
{
STDMETHOD(ResetInitVector)() PURE;
+
+ /* Call ResetInitVector() only for encoding.
+ Call ResetInitVector() before encoding and before WriteCoderProperties().
+ Crypto encoder can create random IV in that function. */
};
CODER_INTERFACE(ICryptoSetPassword, 0x90)
@@ -167,8 +319,7 @@ CODER_INTERFACE(ICryptoSetCRC, 0xA0)
STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
};
-//////////////////////
-// It's for DLL file
+
namespace NMethodPropID
{
enum EEnum
@@ -177,12 +328,44 @@ namespace NMethodPropID
kName,
kDecoder,
kEncoder,
- kInStreams,
- kOutStreams,
+ kPackStreams,
+ kUnpackStreams,
kDescription,
kDecoderIsAssigned,
- kEncoderIsAssigned
+ kEncoderIsAssigned,
+ kDigestSize
};
}
+
+#define INTERFACE_IHasher(x) \
+ STDMETHOD_(void, Init)() throw() x; \
+ STDMETHOD_(void, Update)(const void *data, UInt32 size) throw() x; \
+ STDMETHOD_(void, Final)(Byte *digest) throw() x; \
+ STDMETHOD_(UInt32, GetDigestSize)() throw() x; \
+
+CODER_INTERFACE(IHasher, 0xC0)
+{
+ INTERFACE_IHasher(PURE)
+};
+
+CODER_INTERFACE(IHashers, 0xC1)
+{
+ STDMETHOD_(UInt32, GetNumHashers)() PURE;
+ STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher) PURE;
+};
+
+extern "C"
+{
+ typedef HRESULT (WINAPI *Func_GetNumberOfMethods)(UInt32 *numMethods);
+ typedef HRESULT (WINAPI *Func_GetMethodProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ typedef HRESULT (WINAPI *Func_CreateDecoder)(UInt32 index, const GUID *iid, void **outObject);
+ typedef HRESULT (WINAPI *Func_CreateEncoder)(UInt32 index, const GUID *iid, void **outObject);
+
+ typedef HRESULT (WINAPI *Func_GetHashers)(IHashers **hashers);
+
+ typedef HRESULT (WINAPI *Func_SetCodecs)(ICompressCodecsInfo *compressCodecsInfo);
+}
+
#endif
diff --git a/3rdparty/lzma/CPP/7zip/IDecl.h b/3rdparty/lzma/CPP/7zip/IDecl.h
index 8316eb3ac68..077ef0ee3f5 100644
--- a/3rdparty/lzma/CPP/7zip/IDecl.h
+++ b/3rdparty/lzma/CPP/7zip/IDecl.h
@@ -5,10 +5,23 @@
#include "../Common/MyUnknown.h"
+#define k_7zip_GUID_Data1 0x23170F69
+#define k_7zip_GUID_Data2 0x40C1
+
+#define k_7zip_GUID_Data3_Common 0x278A
+
+#define k_7zip_GUID_Data3_Decoder 0x2790
+#define k_7zip_GUID_Data3_Encoder 0x2791
+#define k_7zip_GUID_Data3_Hasher 0x2792
+
+
#define DECL_INTERFACE_SUB(i, base, groupId, subId) \
-DEFINE_GUID(IID_ ## i, \
-0x23170F69, 0x40C1, 0x278A, 0, 0, 0, (groupId), 0, (subId), 0, 0); \
-struct i: public base
+ DEFINE_GUID(IID_ ## i, \
+ k_7zip_GUID_Data1, \
+ k_7zip_GUID_Data2, \
+ k_7zip_GUID_Data3_Common, \
+ 0, 0, 0, (groupId), 0, (subId), 0, 0); \
+ struct i: public base
#define DECL_INTERFACE(i, groupId, subId) DECL_INTERFACE_SUB(i, IUnknown, groupId, subId)
diff --git a/3rdparty/lzma/CPP/7zip/IPassword.h b/3rdparty/lzma/CPP/7zip/IPassword.h
index 3ca7b090e93..7ea45537e65 100644
--- a/3rdparty/lzma/CPP/7zip/IPassword.h
+++ b/3rdparty/lzma/CPP/7zip/IPassword.h
@@ -3,8 +3,8 @@
#ifndef __IPASSWORD_H
#define __IPASSWORD_H
+#include "../Common/MyTypes.h"
#include "../Common/MyUnknown.h"
-#include "../Common/Types.h"
#include "IDecl.h"
@@ -21,4 +21,3 @@ PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11)
};
#endif
-
diff --git a/3rdparty/lzma/CPP/7zip/IProgress.h b/3rdparty/lzma/CPP/7zip/IProgress.h
index d6093f17330..fac951eca48 100644
--- a/3rdparty/lzma/CPP/7zip/IProgress.h
+++ b/3rdparty/lzma/CPP/7zip/IProgress.h
@@ -1,10 +1,9 @@
-// Interface/IProgress.h
+// IProgress.h
#ifndef __IPROGRESS_H
#define __IPROGRESS_H
-#include "../Common/MyUnknown.h"
-#include "../Common/Types.h"
+#include "../Common/MyTypes.h"
#include "IDecl.h"
@@ -17,17 +16,4 @@ DECL_INTERFACE(IProgress, 0, 5)
INTERFACE_IProgress(PURE)
};
-/*
-// {23170F69-40C1-278A-0000-000000050002}
-DEFINE_GUID(IID_IProgress2,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050002")
-IProgress2: public IUnknown
-{
-public:
- STDMETHOD(SetTotal)(const UInt64 *total) PURE;
- STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE;
-};
-*/
-
#endif
diff --git a/3rdparty/lzma/CPP/7zip/IStream.h b/3rdparty/lzma/CPP/7zip/IStream.h
index 165e8baadda..9a0bcbf3d72 100644
--- a/3rdparty/lzma/CPP/7zip/IStream.h
+++ b/3rdparty/lzma/CPP/7zip/IStream.h
@@ -3,8 +3,8 @@
#ifndef __ISTREAM_H
#define __ISTREAM_H
-#include "../Common/MyUnknown.h"
-#include "../Common/Types.h"
+#include "../Common/MyTypes.h"
+#include "../Common/MyWindows.h"
#include "IDecl.h"
@@ -14,26 +14,71 @@
STREAM_INTERFACE(ISequentialInStream, 0x01)
{
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;
+
/*
- Out: if size != 0, return_value = S_OK and (*processedSize == 0),
- then there are no more bytes in stream.
- if (size > 0) && there are bytes in stream,
- this function must read at least 1 byte.
- This function is allowed to read less than number of remaining bytes in stream.
- You must call Read function in loop, if you need exact amount of data
+ The requirement for caller: (processedSize != NULL).
+ The callee can allow (processedSize == NULL) for compatibility reasons.
+
+ if (size == 0), this function returns S_OK and (*processedSize) is set to 0.
+
+ if (size != 0)
+ {
+ Partial read is allowed: (*processedSize <= avail_size && *processedSize <= size),
+ where (avail_size) is the size of remaining bytes in stream.
+ If (avail_size != 0), this function must read at least 1 byte: (*processedSize > 0).
+ You must call Read() in loop, if you need to read exact amount of data.
+ }
+
+ If seek pointer before Read() call was changed to position past the end of stream:
+ if (seek_pointer >= stream_size), this function returns S_OK and (*processedSize) is set to 0.
+
+ ERROR CASES:
+ If the function returns error code, then (*processedSize) is size of
+ data written to (data) buffer (it can be data before error or data with errors).
+ The recommended way for callee to work with reading errors:
+ 1) write part of data before error to (data) buffer and return S_OK.
+ 2) return error code for further calls of Read().
*/
};
STREAM_INTERFACE(ISequentialOutStream, 0x02)
{
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE;
+
/*
- if (size > 0) this function must write at least 1 byte.
- This function is allowed to write less than "size".
- You must call Write function in loop, if you need to write exact amount of data
+ The requirement for caller: (processedSize != NULL).
+ The callee can allow (processedSize == NULL) for compatibility reasons.
+
+ if (size != 0)
+ {
+ Partial write is allowed: (*processedSize <= size),
+ but this function must write at least 1 byte: (*processedSize > 0).
+ You must call Write() in loop, if you need to write exact amount of data.
+ }
+
+ ERROR CASES:
+ If the function returns error code, then (*processedSize) is size of
+ data written from (data) buffer.
*/
};
+#ifdef __HRESULT_FROM_WIN32
+#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK)
+#else
+#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK)
+#endif
+
+/* Seek() Function
+ If you seek before the beginning of the stream, Seek() function returns error code:
+ Recommended error code is __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK).
+ or STG_E_INVALIDFUNCTION
+
+ It is allowed to seek past the end of the stream.
+
+
+ if Seek() returns error, then the value of *newPosition is undefined.
+*/
+
STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
{
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
@@ -50,9 +95,33 @@ STREAM_INTERFACE(IStreamGetSize, 0x06)
STDMETHOD(GetSize)(UInt64 *size) PURE;
};
-STREAM_INTERFACE(IOutStreamFlush, 0x07)
+STREAM_INTERFACE(IOutStreamFinish, 0x07)
+{
+ STDMETHOD(OutStreamFinish)() PURE;
+};
+
+
+STREAM_INTERFACE(IStreamGetProps, 0x08)
+{
+ STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib) PURE;
+};
+
+struct CStreamFileProps
+{
+ UInt64 Size;
+ UInt64 VolID;
+ UInt64 FileID_Low;
+ UInt64 FileID_High;
+ UInt32 NumLinks;
+ UInt32 Attrib;
+ FILETIME CTime;
+ FILETIME ATime;
+ FILETIME MTime;
+};
+
+STREAM_INTERFACE(IStreamGetProps2, 0x09)
{
- STDMETHOD(Flush)() PURE;
+ STDMETHOD(GetProps2)(CStreamFileProps *props) PURE;
};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/MyVersion.h b/3rdparty/lzma/CPP/7zip/MyVersion.h
index 2e657393d80..8f52a1261a4 100644
--- a/3rdparty/lzma/CPP/7zip/MyVersion.h
+++ b/3rdparty/lzma/CPP/7zip/MyVersion.h
@@ -1,6 +1,2 @@
-#include "..\..\C\7zVersion.h"
-
-#undef MY_COPYRIGHT
-#undef MY_VERSION_COPYRIGHT_DATE
-#define MY_COPYRIGHT "Copyright (c) 1999-2011 Igor Pavlov"
-#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
+#define USE_COPYRIGHT_CR
+#include "../../C/7zVersion.h"
diff --git a/3rdparty/lzma/CPP/7zip/PropID.h b/3rdparty/lzma/CPP/7zip/PropID.h
index 8f888526311..1822f402b9f 100644
--- a/3rdparty/lzma/CPP/7zip/PropID.h
+++ b/3rdparty/lzma/CPP/7zip/PropID.h
@@ -1,13 +1,15 @@
// PropID.h
-#ifndef __7ZIP_PROPID_H
-#define __7ZIP_PROPID_H
+#ifndef __7ZIP_PROP_ID_H
+#define __7ZIP_PROP_ID_H
+
+#include "../Common/MyTypes.h"
enum
{
kpidNoProperty = 0,
- kpidMainSubfile = 1,
- kpidHandlerItemIndex = 2,
+ kpidMainSubfile,
+ kpidHandlerItemIndex,
kpidPath,
kpidName,
kpidExtension,
@@ -59,18 +61,67 @@ enum
kpidCreatorApp,
kpidSectorSize,
kpidPosixAttrib,
- kpidLink,
+ kpidSymLink,
kpidError,
-
- kpidTotalSize = 0x1100,
+ kpidTotalSize,
kpidFreeSpace,
kpidClusterSize,
kpidVolumeName,
-
- kpidLocalName = 0x1200,
+ kpidLocalName,
kpidProvider,
+ kpidNtSecure,
+ kpidIsAltStream,
+ kpidIsAux,
+ kpidIsDeleted,
+ kpidIsTree,
+ kpidSha1,
+ kpidSha256,
+ kpidErrorType,
+ kpidNumErrors,
+ kpidErrorFlags,
+ kpidWarningFlags,
+ kpidWarning,
+ kpidNumStreams,
+ kpidNumAltStreams,
+ kpidAltStreamsSize,
+ kpidVirtualSize,
+ kpidUnpackSize,
+ kpidTotalPhySize,
+ kpidVolumeIndex,
+ kpidSubType,
+ kpidShortComment,
+ kpidCodePage,
+ kpidIsNotArcType,
+ kpidPhySizeCantBeDetected,
+ kpidZerosTailIsAllowed,
+ kpidTailSize,
+ kpidEmbeddedStubSize,
+ kpidNtReparse,
+ kpidHardLink,
+ kpidINode,
+ kpidStreamId,
+ kpidReadOnly,
+ kpidOutName,
+ kpidCopyLink,
+
+ kpid_NUM_DEFINED,
kpidUserDefined = 0x10000
};
+extern const Byte k7z_PROPID_To_VARTYPE[kpid_NUM_DEFINED]; // VARTYPE
+
+const UInt32 kpv_ErrorFlags_IsNotArc = 1 << 0;
+const UInt32 kpv_ErrorFlags_HeadersError = 1 << 1;
+const UInt32 kpv_ErrorFlags_EncryptedHeadersError = 1 << 2;
+const UInt32 kpv_ErrorFlags_UnavailableStart = 1 << 3;
+const UInt32 kpv_ErrorFlags_UnconfirmedStart = 1 << 4;
+const UInt32 kpv_ErrorFlags_UnexpectedEnd = 1 << 5;
+const UInt32 kpv_ErrorFlags_DataAfterEnd = 1 << 6;
+const UInt32 kpv_ErrorFlags_UnsupportedMethod = 1 << 7;
+const UInt32 kpv_ErrorFlags_UnsupportedFeature = 1 << 8;
+const UInt32 kpv_ErrorFlags_DataError = 1 << 9;
+const UInt32 kpv_ErrorFlags_CrcError = 1 << 10;
+// const UInt32 kpv_ErrorFlags_Unsupported = 1 << 11;
+
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.cpp b/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.cpp
index d181843d178..55650cfa0fe 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.cpp
@@ -2,39 +2,54 @@
#include "StdAfx.h"
-#include "Common/IntToString.h"
-#include "Common/MyInitGuid.h"
-#include "Common/StringConvert.h"
-
-#include "Windows/DLL.h"
-#include "Windows/FileDir.h"
-#include "Windows/FileFind.h"
-#include "Windows/FileName.h"
-#include "Windows/NtCheck.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
+#include <stdio.h>
+
+#include "../../../Common/MyWindows.h"
+
+#include "../../../Common/Defs.h"
+#include "../../../Common/MyInitGuid.h"
+
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
+
+#include "../../../Windows/DLL.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/NtCheck.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/PropVariantConv.h"
#include "../../Common/FileStreams.h"
#include "../../Archive/IArchive.h"
#include "../../IPassword.h"
-#include "../../MyVersion.h"
+#include "../../../../C/7zVersion.h"
#ifdef _WIN32
HINSTANCE g_hInstance = 0;
#endif
+// Tou can find the list of all GUIDs in Guid.txt file.
// use another CLSIDs, if you want to support other formats (zip, rar, ...).
// {23170F69-40C1-278A-1000-000110070000}
+
DEFINE_GUID(CLSID_CFormat7z,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
+DEFINE_GUID(CLSID_CFormatXz,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0C, 0x00, 0x00);
+
+#define CLSID_Format CLSID_CFormat7z
+// #define CLSID_Format CLSID_CFormatXz
using namespace NWindows;
+using namespace NFile;
+using namespace NDir;
#define kDllName "7z.dll"
-static const char *kCopyrightString = "\n" MY_7ZIP_VERSION
+static const char *kCopyrightString = "\n7-Zip " MY_VERSION
" (" kDllName " client) "
MY_COPYRIGHT " " MY_DATE "\n";
@@ -46,12 +61,6 @@ static const char *kHelpString =
" Client7z.exe x archive.7z : eXtract files from archive.7z\n";
-typedef UINT32 (WINAPI * CreateObjectFunc)(
- const GUID *clsID,
- const GUID *interfaceID,
- void **outObject);
-
-
static AString FStringToConsoleString(const FString &s)
{
return GetOemString(fs2us(s));
@@ -177,7 +186,11 @@ static const char *kSkippingString = "Skipping ";
static const char *kUnsupportedMethod = "Unsupported Method";
static const char *kCRCFailed = "CRC Failed";
static const char *kDataError = "Data Error";
-static const char *kUnknownError = "Unknown 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,
@@ -232,7 +245,7 @@ void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const FString &di
NumErrors = 0;
_archiveHandler = archiveHandler;
_directoryPath = directoryPath;
- NFile::NName::NormalizeDirPathPrefix(_directoryPath);
+ NName::NormalizeDirPathPrefix(_directoryPath);
}
STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 /* size */)
@@ -296,7 +309,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
NCOM::CPropVariant prop;
RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));
_processedFileInfo.MTimeDefined = false;
- switch(prop.vt)
+ switch (prop.vt)
{
case VT_EMPTY:
// _processedFileInfo.MTime = _utcMTimeDefault;
@@ -314,18 +327,16 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
// Get Size
NCOM::CPropVariant prop;
RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));
- bool newFileSizeDefined = (prop.vt != VT_EMPTY);
UInt64 newFileSize;
- if (newFileSizeDefined)
- newFileSize = ConvertPropVariantToUInt64(prop);
+ /* bool newFileSizeDefined = */ ConvertPropVariantToUInt64(prop, newFileSize);
}
{
// Create folders for file
- int slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR);
+ int slashPos = _filePath.ReverseFind_PathSepar();
if (slashPos >= 0)
- NFile::NDirectory::CreateComplexDirectory(_directoryPath + us2fs(_filePath.Left(slashPos)));
+ CreateComplexDir(_directoryPath + us2fs(_filePath.Left(slashPos)));
}
FString fullProcessedPath = _directoryPath + us2fs(_filePath);
@@ -333,14 +344,14 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
if (_processedFileInfo.isDir)
{
- NFile::NDirectory::CreateComplexDirectory(fullProcessedPath);
+ CreateComplexDir(fullProcessedPath);
}
else
{
- NFile::NFind::CFileInfo fi;
+ NFind::CFileInfo fi;
if (fi.Find(fullProcessedPath))
{
- if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
+ if (!DeleteFileAlways(fullProcessedPath))
{
PrintError("Can not delete output file", fullProcessedPath);
return E_ABORT;
@@ -379,32 +390,58 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
{
- switch(operationResult)
+ switch (operationResult)
{
case NArchive::NExtract::NOperationResult::kOK:
break;
default:
{
NumErrors++;
- PrintString(" ");
- switch(operationResult)
+ PrintString(" : ");
+ const char *s = NULL;
+ switch (operationResult)
{
- case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
- PrintString(kUnsupportedMethod);
+ case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
+ s = kUnsupportedMethod;
break;
case NArchive::NExtract::NOperationResult::kCRCError:
- PrintString(kCRCFailed);
+ s = kCRCFailed;
break;
case NArchive::NExtract::NOperationResult::kDataError:
- PrintString(kDataError);
+ s = kDataError;
+ break;
+ case NArchive::NExtract::NOperationResult::kUnavailable:
+ s = kUnavailableData;
+ break;
+ case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
+ s = kUnexpectedEnd;
+ break;
+ case NArchive::NExtract::NOperationResult::kDataAfterEnd:
+ s = kDataAfterEnd;
+ break;
+ case NArchive::NExtract::NOperationResult::kIsNotArc:
+ s = kIsNotArc;
+ break;
+ case NArchive::NExtract::NOperationResult::kHeadersError:
+ s = kHeadersError;
break;
- default:
- PrintString(kUnknownError);
+ }
+ if (s)
+ {
+ PrintString("Error : ");
+ PrintString(s);
+ }
+ else
+ {
+ char temp[16];
+ ConvertUInt32ToString(operationResult, temp);
+ PrintString("Error #");
+ PrintString(temp);
}
}
}
- if (_outFileStream != NULL)
+ if (_outFileStream)
{
if (_processedFileInfo.MTimeDefined)
_outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
@@ -412,7 +449,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
}
_outFileStream.Release();
if (_extractMode && _processedFileInfo.AttribDefined)
- NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attrib);
+ SetFileAttrib(_diskFilePath, _processedFileInfo.Attrib);
PrintNewLine();
return S_OK;
}
@@ -462,7 +499,6 @@ public:
STDMETHOD(SetCompleted)(const UInt64 *completeValue);
// IUpdateCallback2
- STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);
STDMETHOD(GetUpdateItemInfo)(UInt32 index,
Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
@@ -514,21 +550,15 @@ STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValu
return S_OK;
}
-
-STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG ** /* enumerator */)
-{
- return E_NOTIMPL;
-}
-
STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */,
Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
{
- if (newData != NULL)
+ if (newData)
*newData = BoolToInt(true);
- if (newProperties != NULL)
+ if (newProperties)
*newProperties = BoolToInt(true);
- if (indexInArchive != NULL)
- *indexInArchive = (UInt32)-1;
+ if (indexInArchive)
+ *indexInArchive = (UInt32)(Int32)-1;
return S_OK;
}
@@ -545,7 +575,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
{
const CDirItem &dirItem = (*DirItems)[index];
- switch(propID)
+ switch (propID)
{
case kpidPath: prop = dirItem.Name; break;
case kpidIsDir: prop = dirItem.isDir(); break;
@@ -632,8 +662,8 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOu
wchar_t temp[16];
ConvertUInt32ToString(index + 1, temp);
UString res = temp;
- while (res.Length() < 2)
- res = UString(L'0') + res;
+ while (res.Len() < 2)
+ res.InsertAtFront(L'0');
UString fileName = VolName;
fileName += L'.';
fileName += res;
@@ -663,7 +693,7 @@ STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDef
return StringToBstr(Password, password);
}
-//////////////////////////////////////////////////////////////////////////
+
// Main function
#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1;
@@ -679,14 +709,16 @@ int MY_CDECL main(int numArgs, const char *args[])
PrintStringLn(kHelpString);
return 1;
}
+
NDLL::CLibrary lib;
if (!lib.Load(NDLL::GetModuleDirPrefix() + FTEXT(kDllName)))
{
PrintError("Can not load 7-zip library");
return 1;
}
- CreateObjectFunc createObjectFunc = (CreateObjectFunc)lib.GetProc("CreateObject");
- if (createObjectFunc == 0)
+
+ Func_CreateObject createObjectFunc = (Func_CreateObject)lib.GetProc("CreateObject");
+ if (!createObjectFunc)
{
PrintError("Can not get CreateObject");
return 1;
@@ -695,15 +727,17 @@ int MY_CDECL main(int numArgs, const char *args[])
char c;
{
AString command = args[1];
- if (command.Length() != 1)
+ if (command.Len() != 1)
{
PrintError("incorrect command");
return 1;
}
- c = (char)MyCharUpper(command[0]);
+ c = (char)MyCharLower_Ascii(command[0]);
}
+
FString archiveName = CmdStringToFString(args[2]);
- if (c == 'A')
+
+ if (c == 'a')
{
// create archive command
if (numArgs < 4)
@@ -712,28 +746,31 @@ int MY_CDECL main(int numArgs, const char *args[])
return 1;
}
CObjectVector<CDirItem> dirItems;
- int i;
- for (i = 3; i < numArgs; i++)
{
- CDirItem di;
- FString name = CmdStringToFString(args[i]);
-
- NFile::NFind::CFileInfo fi;
- if (!fi.Find(name))
+ int i;
+ for (i = 3; i < numArgs; i++)
{
- PrintError("Can't find file", name);
- return 1;
+ CDirItem di;
+ FString name = CmdStringToFString(args[i]);
+
+ NFind::CFileInfo fi;
+ if (!fi.Find(name))
+ {
+ PrintError("Can't find file", name);
+ return 1;
+ }
+
+ di.Attrib = fi.Attrib;
+ di.Size = fi.Size;
+ di.CTime = fi.CTime;
+ di.ATime = fi.ATime;
+ di.MTime = fi.MTime;
+ di.Name = fs2us(name);
+ di.FullPath = name;
+ dirItems.Add(di);
}
-
- di.Attrib = fi.Attrib;
- di.Size = fi.Size;
- di.CTime = fi.CTime;
- di.ATime = fi.ATime;
- di.MTime = fi.MTime;
- di.Name = fs2us(name);
- di.FullPath = name;
- dirItems.Add(di);
}
+
COutFileStream *outFileStreamSpec = new COutFileStream;
CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
if (!outFileStreamSpec->Create(archiveName, false))
@@ -743,7 +780,7 @@ int MY_CDECL main(int numArgs, const char *args[])
}
CMyComPtr<IOutArchive> outArchive;
- if (createObjectFunc(&CLSID_CFormat7z, &IID_IOutArchive, (void **)&outArchive) != S_OK)
+ if (createObjectFunc(&CLSID_Format, &IID_IOutArchive, (void **)&outArchive) != S_OK)
{
PrintError("Can not get class object");
return 1;
@@ -762,7 +799,7 @@ int MY_CDECL main(int numArgs, const char *args[])
L"s",
L"x"
};
- const int kNumProps = sizeof(names) / sizeof(names[0]);
+ const unsigned kNumProps = ARRAY_SIZE(names);
NCOM::CPropVariant values[kNumProps] =
{
false, // solid mode OFF
@@ -780,17 +817,21 @@ int MY_CDECL main(int numArgs, const char *args[])
*/
HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback);
+
updateCallbackSpec->Finilize();
+
if (result != S_OK)
{
PrintError("Update Error");
return 1;
}
- for (i = 0; i < updateCallbackSpec->FailedFiles.Size(); i++)
+
+ FOR_VECTOR (i, updateCallbackSpec->FailedFiles)
{
PrintNewLine();
PrintError("Error for file", updateCallbackSpec->FailedFiles[i]);
}
+
if (updateCallbackSpec->FailedFiles.Size() != 0)
return 1;
}
@@ -803,9 +844,10 @@ int MY_CDECL main(int numArgs, const char *args[])
}
bool listCommand;
- if (c == 'L')
+
+ if (c == 'l')
listCommand = true;
- else if (c == 'X')
+ else if (c == 'x')
listCommand = false;
else
{
@@ -814,7 +856,7 @@ int MY_CDECL main(int numArgs, const char *args[])
}
CMyComPtr<IInArchive> archive;
- if (createObjectFunc(&CLSID_CFormat7z, &IID_IInArchive, (void **)&archive) != S_OK)
+ if (createObjectFunc(&CLSID_Format, &IID_IInArchive, (void **)&archive) != S_OK)
{
PrintError("Can not get class object");
return 1;
@@ -836,7 +878,8 @@ int MY_CDECL main(int numArgs, const char *args[])
// openCallbackSpec->PasswordIsDefined = true;
// openCallbackSpec->Password = L"1";
- if (archive->Open(file, 0, openCallback) != S_OK)
+ const UInt64 scanSize = 1 << 23;
+ if (archive->Open(file, &scanSize, openCallback) != S_OK)
{
PrintError("Can not open file as archive", archiveName);
return 1;
@@ -854,7 +897,8 @@ int MY_CDECL main(int numArgs, const char *args[])
// Get uncompressed size of file
NCOM::CPropVariant prop;
archive->GetProperty(i, kpidSize, &prop);
- UString s = ConvertPropVariantToString(prop);
+ char s[32];
+ ConvertPropVariantToShortString(prop, s);
PrintString(s);
PrintString(" ");
}
@@ -862,8 +906,10 @@ int MY_CDECL main(int numArgs, const char *args[])
// Get name of file
NCOM::CPropVariant prop;
archive->GetProperty(i, kpidPath, &prop);
- UString s = ConvertPropVariantToString(prop);
- PrintString(s);
+ if (prop.vt == VT_BSTR)
+ PrintString(prop.bstrVal);
+ else if (prop.vt != VT_EMPTY)
+ PrintString("ERROR!");
}
PrintNewLine();
}
@@ -877,7 +923,27 @@ int MY_CDECL main(int numArgs, const char *args[])
extractCallbackSpec->PasswordIsDefined = false;
// extractCallbackSpec->PasswordIsDefined = true;
// extractCallbackSpec->Password = L"1";
+
+ /*
+ const wchar_t *names[] =
+ {
+ L"mt",
+ L"mtf"
+ };
+ const unsigned kNumProps = sizeof(names) / sizeof(names[0]);
+ NCOM::CPropVariant values[kNumProps] =
+ {
+ (UInt32)1,
+ false
+ };
+ CMyComPtr<ISetProperties> setProperties;
+ archive->QueryInterface(IID_ISetProperties, (void **)&setProperties);
+ if (setProperties)
+ setProperties->SetProperties(names, values, kNumProps);
+ */
+
HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback);
+
if (result != S_OK)
{
PrintError("Extract Error");
@@ -885,5 +951,6 @@ int MY_CDECL main(int numArgs, const char *args[])
}
}
}
+
return 0;
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.dsp b/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.dsp
index 542e2852534..8ad7fb133dd 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.dsp
+++ b/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.dsp
@@ -39,9 +39,10 @@ RSC=rc.exe
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -49,7 +50,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zcl.exe"
!ELSEIF "$(CFG)" == "Client7z - Win32 Debug"
@@ -65,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 /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /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 BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
@@ -73,7 +74,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zcl.exe" /pdbtype:sept
!ENDIF
@@ -86,6 +87,10 @@ LINK32=link.exe
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
@@ -147,11 +152,11 @@ SOURCE=..\..\..\Windows\PropVariant.h
# End Source File
# Begin Source File
-SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+SOURCE=..\..\..\Windows\PropVariantConv.cpp
# End Source File
# Begin Source File
-SOURCE=..\..\..\Windows\PropVariantConversions.h
+SOURCE=..\..\..\Windows\PropVariantConv.h
# End Source File
# End Group
# Begin Group "Common"
@@ -222,5 +227,9 @@ SOURCE=..\..\Common\FileStreams.h
SOURCE=.\Client7z.cpp
# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Sort.h
+# End Source File
# End Target
# End Project
diff --git a/3rdparty/lzma/CPP/7zip/UI/Client7z/StdAfx.h b/3rdparty/lzma/CPP/7zip/UI/Client7z/StdAfx.h
index b23436e93e4..2854ff3e935 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Client7z/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Client7z/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include <windows.h>
-#include <stdio.h>
+#include "../../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Client7z/makefile b/3rdparty/lzma/CPP/7zip/UI/Client7z/makefile
index 0ff8e72f345..99a6d494778 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Client7z/makefile
+++ b/3rdparty/lzma/CPP/7zip/UI/Client7z/makefile
@@ -1,8 +1,7 @@
-PROG = 7z.exe
+PROG = 7zcl.exe
MY_CONSOLE = 1
-CFLAGS = $(CFLAGS) -I ../../../
-CONSOLE_OBJS = \
+CURRENT_OBJS = \
$O\Client7z.obj \
COMMON_OBJS = \
@@ -21,25 +20,9 @@ WIN_OBJS = \
$O\FileIO.obj \
$O\FileName.obj \
$O\PropVariant.obj \
- $O\PropVariantConversions.obj \
+ $O\PropVariantConv.obj \
7ZIP_COMMON_OBJS = \
$O\FileStreams.obj \
-OBJS = \
- $O\StdAfx.obj \
- $(CONSOLE_OBJS) \
- $(COMMON_OBJS) \
- $(WIN_OBJS) \
- $(7ZIP_COMMON_OBJS) \
-
-!include "../../../Build.mak"
-
-$(CONSOLE_OBJS): $(*B).cpp
- $(COMPL)
-$(COMMON_OBJS): ../../../Common/$(*B).cpp
- $(COMPL)
-$(WIN_OBJS): ../../../Windows/$(*B).cpp
- $(COMPL)
-$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
- $(COMPL)
+!include "../../7zip.mak"
diff --git a/3rdparty/lzma/CPP/7zip/UI/Client7z/resource.rc b/3rdparty/lzma/CPP/7zip/UI/Client7z/resource.rc
new file mode 100644
index 00000000000..a09bb0441ca
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/Client7z/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_APP("7-Zip client", "7zcl")
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
index 85ec17b42c9..1bd202edbcd 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -1,6 +1,8 @@
// ArchiveCommandLine.cpp
#include "StdAfx.h"
+#undef printf
+#undef sprintf
#ifdef _WIN32
#ifndef UNDER_CE
@@ -9,15 +11,15 @@
#endif
#include <stdio.h>
-#include "Common/ListFileUtils.h"
-#include "Common/StringConvert.h"
-#include "Common/StringToInt.h"
+#include "../../../Common/ListFileUtils.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/StringToInt.h"
-#include "Windows/FileDir.h"
-#include "Windows/FileName.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileName.h"
#ifdef _WIN32
-#include "Windows/FileMapping.h"
-#include "Windows/Synchronization.h"
+#include "../../../Windows/FileMapping.h"
+#include "../../../Windows/Synchronization.h"
#endif
#include "ArchiveCommandLine.h"
@@ -48,6 +50,25 @@ using namespace NCommandLineParser;
using namespace NWindows;
using namespace NFile;
+static bool StringToUInt32(const wchar_t *s, UInt32 &v)
+{
+ if (*s == 0)
+ return false;
+ const wchar_t *end;
+ v = ConvertStringToUInt32(s, &end);
+ 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;
namespace NKey {
@@ -56,49 +77,98 @@ enum Enum
kHelp1 = 0,
kHelp2,
kHelp3,
+
kDisableHeaders,
kDisablePercents,
- kArchiveType,
+ kShowTime,
+ kLogLevel,
+
+ kOutStream,
+ kErrStream,
+ kPercentStream,
+
kYes,
- #ifndef _NO_CRYPTO
- kPassword,
- #endif
+
+ kShowDialog,
+ kOverwrite,
+
+ kArchiveType,
+ kExcludedArcType,
+
kProperty,
kOutputDir,
kWorkingDir,
+
kInclude,
kExclude,
kArInclude,
kArExclude,
kNoArName,
+
kUpdate,
kVolume,
kRecursed,
+
+ kAffinity,
kSfx,
+ kEmail,
+ kHash,
+
kStdIn,
kStdOut,
- kOverwrite,
- kEmail,
- kShowDialog,
+
kLargePages,
kListfileCharSet,
kConsoleCharSet,
kTechMode,
+
kShareForWrite,
kCaseSensitive,
- kCalcCrc
+ kArcNameMode,
+
+ kDisableWildcardParsing,
+ kElimDup,
+ kFullPathMode,
+
+ kHardLinks,
+ kSymLinks,
+ kNtSecurity,
+ kAltStreams,
+ kReplaceColonForAltStream,
+ kWriteToAltStreamIfColon,
+
+ kDeleteAfterCompressing,
+ kSetArcMTime
+
+ #ifndef _NO_CRYPTO
+ , kPassword
+ #endif
};
}
-static const wchar_t kRecursedIDChar = 'R';
-static const wchar_t *kRecursedPostCharSet = L"0-";
+static const wchar_t kRecursedIDChar = 'r';
+static const char *kRecursedPostCharSet = "0-";
+
+static const char *k_ArcNameMode_PostCharSet = "sea";
+
+static const char *k_Stream_PostCharSet = "012";
+
+static inline const EArcNameMode ParseArcNameMode(int postCharIndex)
+{
+ switch (postCharIndex)
+ {
+ case 1: return k_ArcNameMode_Exact;
+ case 2: return k_ArcNameMode_Add;
+ default: return k_ArcNameMode_Smart;
+ }
+}
namespace NRecursedPostCharIndex {
enum EEnum
{
- kWildCardRecursionOnly = 0,
+ kWildcardRecursionOnly = 0,
kNoRecursion = 1
};
}
@@ -110,135 +180,143 @@ 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 wchar_t *kOverwritePostCharSet = L"asut";
+static const char *kOverwritePostCharSet = "asut";
-NExtract::NOverwriteMode::EEnum k_OverwriteModes[] =
+static const NExtract::NOverwriteMode::EEnum k_OverwriteModes[] =
{
- NExtract::NOverwriteMode::kWithoutPrompt,
- NExtract::NOverwriteMode::kSkipExisting,
- NExtract::NOverwriteMode::kAutoRename,
- NExtract::NOverwriteMode::kAutoRenameExisting
+ NExtract::NOverwriteMode::kOverwrite,
+ NExtract::NOverwriteMode::kSkip,
+ NExtract::NOverwriteMode::kRename,
+ NExtract::NOverwriteMode::kRenameExisting
};
static const CSwitchForm kSwitchForms[] =
- {
- { L"?", NSwitchType::kSimple, false },
- { L"H", NSwitchType::kSimple, false },
- { L"-HELP", NSwitchType::kSimple, false },
- { L"BA", NSwitchType::kSimple, false },
- { L"BD", NSwitchType::kSimple, false },
- { L"T", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"Y", NSwitchType::kSimple, false },
- #ifndef _NO_CRYPTO
- { L"P", NSwitchType::kUnLimitedPostString, false, 0 },
- #endif
- { L"M", NSwitchType::kUnLimitedPostString, true, 1 },
- { L"O", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"W", NSwitchType::kUnLimitedPostString, false, 0 },
- { L"I", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
- { L"X", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
- { L"AI", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
- { L"AX", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
- { L"AN", NSwitchType::kSimple, false },
- { L"U", NSwitchType::kUnLimitedPostString, true, 1},
- { L"V", NSwitchType::kUnLimitedPostString, true, 1},
- { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet },
- { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 },
- { L"SI", NSwitchType::kUnLimitedPostString, false, 0 },
- { L"SO", NSwitchType::kSimple, false, 0 },
- { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet},
- { L"SEML", NSwitchType::kUnLimitedPostString, false, 0},
- { L"AD", NSwitchType::kSimple, false },
- { L"SLP", NSwitchType::kUnLimitedPostString, false, 0},
- { L"SCS", NSwitchType::kUnLimitedPostString, false, 0},
- { L"SCC", NSwitchType::kUnLimitedPostString, false, 0},
- { L"SLT", NSwitchType::kSimple, false },
- { L"SSW", NSwitchType::kSimple, false },
- { L"SSC", NSwitchType::kPostChar, false, 0, 0, L"-" },
- { L"SCRC", NSwitchType::kSimple, false }
- };
+{
+ { "?" },
+ { "h" },
+ { "-help" },
+
+ { "ba" },
+ { "bd" },
+ { "bt" },
+ { "bb", NSwitchType::kString, false, 0 },
+
+ { "bso", NSwitchType::kChar, false, 1, k_Stream_PostCharSet },
+ { "bse", NSwitchType::kChar, false, 1, k_Stream_PostCharSet },
+ { "bsp", NSwitchType::kChar, false, 1, k_Stream_PostCharSet },
+
+ { "y" },
+
+ { "ad" },
+ { "ao", NSwitchType::kChar, false, 1, kOverwritePostCharSet},
-static const CCommandForm g_CommandForms[] =
-{
- { L"A", false },
- { L"U", false },
- { L"D", false },
- { L"T", false },
- { L"E", false },
- { L"X", false },
- { L"L", false },
- { L"B", false },
- { L"I", false }
-};
+ { "t", NSwitchType::kString, false, 1 },
+ { "stx", NSwitchType::kString, true, 1 },
+
+ { "m", NSwitchType::kString, true, 1 },
+ { "o", NSwitchType::kString, false, 1 },
+ { "w", NSwitchType::kString },
+
+ { "i", NSwitchType::kString, true, kSomeCludePostStringMinSize},
+ { "x", NSwitchType::kString, true, kSomeCludePostStringMinSize},
+ { "ai", NSwitchType::kString, true, kSomeCludePostStringMinSize},
+ { "ax", NSwitchType::kString, true, kSomeCludePostStringMinSize},
+ { "an" },
+
+ { "u", NSwitchType::kString, true, 1},
+ { "v", NSwitchType::kString, true, 1},
+ { "r", NSwitchType::kChar, false, 0, kRecursedPostCharSet },
+
+ { "stm", NSwitchType::kString },
+ { "sfx", NSwitchType::kString },
+ { "seml", NSwitchType::kString, false, 0},
+ { "scrc", NSwitchType::kString, true, 0 },
+
+ { "si", NSwitchType::kString },
+ { "so" },
-static const int kNumCommandForms = sizeof(g_CommandForms) / sizeof(g_CommandForms[0]);
+ { "slp", NSwitchType::kMinus },
+ { "scs", NSwitchType::kString },
+ { "scc", NSwitchType::kString },
+ { "slt" },
-static const wchar_t *kUniversalWildcard = L"*";
-static const int kMinNonSwitchWords = 1;
-static const int kCommandIndex = 0;
+ { "ssw" },
+ { "ssc", NSwitchType::kMinus },
+ { "sa", NSwitchType::kChar, false, 1, k_ArcNameMode_PostCharSet },
+
+ { "spd" },
+ { "spe", NSwitchType::kMinus },
+ { "spf", NSwitchType::kString, false, 0 },
+
+ { "snh", NSwitchType::kMinus },
+ { "snl", NSwitchType::kMinus },
+ { "sni" },
+ { "sns", NSwitchType::kMinus },
+ { "snr" },
+ { "snc" },
+
+ { "sdel" },
+ { "stl" }
+
+ #ifndef _NO_CRYPTO
+ , { "p", NSwitchType::kString }
+ #endif
+};
-// ---------------------------
-// exception messages
+static const wchar_t *kUniversalWildcard = L"*";
+static const unsigned kMinNonSwitchWords = 1;
+static const unsigned kCommandIndex = 0;
-static const char *kUserErrorMessage = "Incorrect command line";
+// 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 *kIncorrectWildCardInListFile = "Incorrect wildcard in listfile";
-static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line";
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 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 void ThrowException(const char *errorMessage)
+bool CArcCommand::IsFromExtractGroup() const
{
- throw CArchiveCommandLineException(errorMessage);
-}
-
-static void ThrowUserErrorException()
-{
- ThrowException(kUserErrorMessage);
-}
-
-// ---------------------------
-
-bool CArchiveCommand::IsFromExtractGroup() const
-{
- switch(CommandType)
+ switch (CommandType)
{
case NCommandType::kTest:
case NCommandType::kExtract:
- case NCommandType::kFullExtract:
+ case NCommandType::kExtractFull:
return true;
- default:
- return false;
}
+ return false;
}
-NExtract::NPathMode::EEnum CArchiveCommand::GetPathMode() const
+NExtract::NPathMode::EEnum CArcCommand::GetPathMode() const
{
- switch(CommandType)
+ switch (CommandType)
{
case NCommandType::kTest:
- case NCommandType::kFullExtract:
- return NExtract::NPathMode::kFullPathnames;
- default:
- return NExtract::NPathMode::kNoPathnames;
+ case NCommandType::kExtractFull:
+ return NExtract::NPathMode::kFullPaths;
}
+ return NExtract::NPathMode::kNoPaths;
}
-bool CArchiveCommand::IsFromUpdateGroup() const
+bool CArcCommand::IsFromUpdateGroup() const
{
- return (CommandType == NCommandType::kAdd ||
- CommandType == NCommandType::kUpdate ||
- CommandType == NCommandType::kDelete);
+ switch (CommandType)
+ {
+ case NCommandType::kAdd:
+ case NCommandType::kUpdate:
+ case NCommandType::kDelete:
+ case NCommandType::kRename:
+ return true;
+ }
+ return false;
}
static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
{
switch (index)
{
- case NRecursedPostCharIndex::kWildCardRecursionOnly:
- return NRecursedType::kWildCardOnlyRecursed;
+ case NRecursedPostCharIndex::kWildcardRecursionOnly:
+ return NRecursedType::kWildcardOnlyRecursed;
case NRecursedPostCharIndex::kNoRecursion:
return NRecursedType::kNonRecursed;
default:
@@ -246,170 +324,281 @@ static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
}
}
-static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command)
+static const char *g_Commands = "audtexlbih";
+
+static bool ParseArchiveCommand(const UString &commandString, CArcCommand &command)
{
- UString commandStringUpper = commandString;
- commandStringUpper.MakeUpper();
- UString postString;
- int commandIndex = ParseCommand(kNumCommandForms, g_CommandForms, commandStringUpper,
- postString) ;
- if (commandIndex < 0)
- return false;
- command.CommandType = (NCommandType::EEnum)commandIndex;
- return true;
+ UString s = commandString;
+ s.MakeLower_Ascii();
+ if (s.Len() == 1)
+ {
+ if (s[0] > 0x7F)
+ return false;
+ int index = FindCharPosInString(g_Commands, (char)s[0]);
+ if (index < 0)
+ return false;
+ command.CommandType = (NCommandType::EEnum)index;
+ return true;
+ }
+ if (s.Len() == 2 && s[0] == 'r' && s[1] == 'n')
+ {
+ command.CommandType = (NCommandType::kRename);
+ return true;
+ }
+ return false;
}
// ------------------------------------------------------------------
// filenames functions
-static void AddNameToCensor(NWildcard::CCensor &wildcardCensor,
- const UString &name, bool include, NRecursedType::EEnum type)
+static void AddNameToCensor(NWildcard::CCensor &censor,
+ const UString &name, bool include, NRecursedType::EEnum type, bool wildcardMatching)
{
bool recursed = false;
switch (type)
{
- case NRecursedType::kWildCardOnlyRecursed:
- recursed = DoesNameContainWildCard(name);
+ case NRecursedType::kWildcardOnlyRecursed:
+ recursed = DoesNameContainWildcard(name);
break;
case NRecursedType::kRecursed:
recursed = true;
break;
}
- wildcardCensor.AddItem(include, name, recursed);
+ censor.AddPreItem(include, name, recursed, wildcardMatching);
}
-static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor,
- LPCWSTR fileName, bool include, NRecursedType::EEnum type, UINT codePage)
+static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs,
+ const UString &oldName, const UString &newName, NRecursedType::EEnum type,
+ bool wildcardMatching)
+{
+ CRenamePair &pair = renamePairs->AddNew();
+ pair.OldName = oldName;
+ pair.NewName = newName;
+ pair.RecursedType = type;
+ pair.WildcardParsing = wildcardMatching;
+
+ if (!pair.Prepare())
+ {
+ UString val;
+ val += pair.OldName;
+ val.Add_LF();
+ val += pair.NewName;
+ val.Add_LF();
+ if (type == NRecursedType::kRecursed)
+ val.AddAscii("-r");
+ else if (type == NRecursedType::kRecursed)
+ val.AddAscii("-r0");
+ throw CArcCmdLineException("Unsupported rename command:", val);
+ }
+}
+
+static void AddToCensorFromListFile(
+ CObjectVector<CRenamePair> *renamePairs,
+ NWildcard::CCensor &censor,
+ LPCWSTR fileName, bool include, NRecursedType::EEnum type, bool wildcardMatching, Int32 codePage)
{
UStringVector names;
if (!NFind::DoesFileExist(us2fs(fileName)))
- throw kCannotFindListFile;
+ throw CArcCmdLineException(kCannotFindListFile, fileName);
if (!ReadNamesFromListFile(us2fs(fileName), names, codePage))
- throw kIncorrectListFile;
- for (int i = 0; i < names.Size(); i++)
- AddNameToCensor(wildcardCensor, names[i], include, type);
+ throw CArcCmdLineException(kIncorrectListFile, fileName);
+ if (renamePairs)
+ {
+ if ((names.Size() & 1) != 0)
+ throw CArcCmdLineException(kIncorrectListFile, fileName);
+ for (unsigned i = 0; i < names.Size(); i += 2)
+ {
+ // change type !!!!
+ AddRenamePair(renamePairs, names[i], names[i + 1], type, wildcardMatching);
+ }
+ }
+ else
+ FOR_VECTOR (i, names)
+ AddNameToCensor(censor, names[i], include, type, wildcardMatching);
}
static void AddToCensorFromNonSwitchesStrings(
- int startIndex,
- NWildcard::CCensor &wildcardCensor,
+ CObjectVector<CRenamePair> *renamePairs,
+ unsigned startIndex,
+ NWildcard::CCensor &censor,
const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,
- bool thereAreSwitchIncludes, UINT codePage)
+ bool wildcardMatching,
+ bool thereAreSwitchIncludes, Int32 codePage)
{
- if (nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes))
- AddNameToCensor(wildcardCensor, kUniversalWildcard, true, type);
- for (int i = startIndex; i < nonSwitchStrings.Size(); i++)
+ if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes)
+ AddNameToCensor(censor, kUniversalWildcard, true, type,
+ true // wildcardMatching
+ );
+
+ int oldIndex = -1;
+
+ for (unsigned i = startIndex; i < nonSwitchStrings.Size(); i++)
{
const UString &s = nonSwitchStrings[i];
if (s.IsEmpty())
- throw kEmptyFilePath;
+ throw CArcCmdLineException(kEmptyFilePath);
if (s[0] == kFileListID)
- AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage);
- else
- AddNameToCensor(wildcardCensor, s, true, type);
- }
-}
-
-#ifdef _WIN32
-static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor,
- const UString &switchParam, bool include,
- NRecursedType::EEnum commonRecursedType)
-{
- int splitPos = switchParam.Find(L':');
- if (splitPos < 0)
- ThrowUserErrorException();
- UString mappingName = switchParam.Left(splitPos);
-
- UString switchParam2 = switchParam.Mid(splitPos + 1);
- splitPos = switchParam2.Find(L':');
- if (splitPos < 0)
- ThrowUserErrorException();
-
- UString mappingSize = switchParam2.Left(splitPos);
- UString eventName = switchParam2.Mid(splitPos + 1);
-
- UInt64 dataSize64 = ConvertStringToUInt64(mappingSize, NULL);
- UInt32 dataSize = (UInt32)dataSize64;
- {
- CFileMapping fileMapping;
- if (fileMapping.Open(FILE_MAP_READ, GetSystemString(mappingName)) != 0)
- ThrowException("Can not open mapping");
- LPVOID data = fileMapping.Map(FILE_MAP_READ, 0, dataSize);
- if (data == NULL)
- ThrowException("MapViewOfFile error");
- try
+ AddToCensorFromListFile(renamePairs, censor, s.Ptr(1), true, type, wildcardMatching, codePage);
+ else if (renamePairs)
{
- const wchar_t *curData = (const wchar_t *)data;
- if (*curData != 0)
- ThrowException("Incorrect mapping data");
- UInt32 numChars = dataSize / sizeof(wchar_t);
- UString name;
- for (UInt32 i = 1; i < numChars; i++)
+ if (oldIndex == -1)
+ oldIndex = i;
+ else
{
- wchar_t c = curData[i];
- if (c == L'\0')
- {
- AddNameToCensor(wildcardCensor, name, include, commonRecursedType);
- name.Empty();
- }
- else
- name += c;
+ // NRecursedType::EEnum type is used for global wildcard (-i! switches)
+ AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, NRecursedType::kNonRecursed, wildcardMatching);
+ // AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, type);
+ oldIndex = -1;
}
- if (!name.IsEmpty())
- ThrowException("data error");
}
- catch(...)
- {
- UnmapViewOfFile(data);
- throw;
- }
- UnmapViewOfFile(data);
+ else
+ AddNameToCensor(censor, s, true, type, wildcardMatching);
}
+ if (oldIndex != -1)
+ {
+ throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[oldIndex]);
+ }
+}
+
+#ifdef _WIN32
+
+struct CEventSetEnd
+{
+ UString Name;
+
+ CEventSetEnd(const wchar_t *name): Name(name) {}
+ ~CEventSetEnd()
{
NSynchronization::CManualResetEvent event;
- if (event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName)) == S_OK)
+ if (event.Open(EVENT_MODIFY_STATE, false, GetSystemString(Name)) == 0)
event.Set();
}
+};
+
+const char *k_IncorrectMapCommand = "Incorrect Map command";
+
+static const char *ParseMapWithPaths(
+ NWildcard::CCensor &censor,
+ const UString &s2, bool include,
+ NRecursedType::EEnum commonRecursedType,
+ bool wildcardMatching)
+{
+ UString s = s2;
+ int pos = s.Find(L':');
+ if (pos < 0)
+ return k_IncorrectMapCommand;
+ int pos2 = s.Find(L':', pos + 1);
+ if (pos2 < 0)
+ return k_IncorrectMapCommand;
+
+ CEventSetEnd eventSetEnd((const wchar_t *)s + ((unsigned)pos2 + 1));
+ s.DeleteFrom(pos2);
+ UInt32 size;
+ if (!StringToUInt32(s.Ptr(pos + 1), size)
+ || size < sizeof(wchar_t)
+ || size > ((UInt32)1 << 31)
+ || size % sizeof(wchar_t) != 0)
+ return "Unsupported Map data size";
+
+ s.DeleteFrom(pos);
+ CFileMapping map;
+ if (map.Open(FILE_MAP_READ, GetSystemString(s)) != 0)
+ return "Can not open mapping";
+ LPVOID data = map.Map(FILE_MAP_READ, 0, size);
+ if (!data)
+ return "MapViewOfFile error";
+ CFileUnmapper unmapper(data);
+
+ UString name;
+ const wchar_t *p = (const wchar_t *)data;
+ if (*p != 0) // data format marker
+ return "Unsupported Map data";
+ UInt32 numChars = size / sizeof(wchar_t);
+ for (UInt32 i = 1; i < numChars; i++)
+ {
+ wchar_t c = p[i];
+ if (c == 0)
+ {
+ // MessageBoxW(0, name, L"7-Zip", 0);
+ AddNameToCensor(censor, name, include, commonRecursedType, wildcardMatching);
+ name.Empty();
+ }
+ else
+ name += c;
+ }
+ if (!name.IsEmpty())
+ return "Map data error";
+
+ return NULL;
}
+
#endif
-static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
+static void AddSwitchWildcardsToCensor(
+ NWildcard::CCensor &censor,
const UStringVector &strings, bool include,
- NRecursedType::EEnum commonRecursedType, UINT codePage)
+ NRecursedType::EEnum commonRecursedType,
+ bool wildcardMatching,
+ Int32 codePage)
{
- for (int i = 0; i < strings.Size(); i++)
+ const char *errorMessage = NULL;
+ unsigned i;
+ for (i = 0; i < strings.Size(); i++)
{
const UString &name = strings[i];
NRecursedType::EEnum recursedType;
- int pos = 0;
- if (name.Length() < kSomeCludePostStringMinSize)
- ThrowUserErrorException();
- if (::MyCharUpper(name[pos]) == kRecursedIDChar)
+ unsigned pos = 0;
+
+ if (name.Len() < kSomeCludePostStringMinSize)
+ {
+ errorMessage = "Too short switch";
+ break;
+ }
+
+ if (::MyCharLower_Ascii(name[pos]) == kRecursedIDChar)
{
pos++;
- int index = UString(kRecursedPostCharSet).Find(name[pos]);
+ wchar_t c = name[pos];
+ int index = -1;
+ if (c <= 0x7F)
+ index = FindCharPosInString(kRecursedPostCharSet, (char)c);
recursedType = GetRecursedTypeFromIndex(index);
if (index >= 0)
pos++;
}
else
recursedType = commonRecursedType;
- if (name.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize)
- ThrowUserErrorException();
- UString tail = name.Mid(pos + 1);
+
+ if (name.Len() < pos + kSomeCludeAfterRecursedPostStringMinSize)
+ {
+ errorMessage = "Too short switch";
+ break;
+ }
+
+ UString tail = name.Ptr(pos + 1);
+
if (name[pos] == kImmediateNameID)
- AddNameToCensor(wildcardCensor, tail, include, recursedType);
+ AddNameToCensor(censor, tail, include, recursedType, wildcardMatching);
else if (name[pos] == kFileListID)
- AddToCensorFromListFile(wildcardCensor, tail, include, recursedType, codePage);
+ AddToCensorFromListFile(NULL, censor, tail, include, recursedType, wildcardMatching, codePage);
#ifdef _WIN32
else if (name[pos] == kMapNameID)
- ParseMapWithPaths(wildcardCensor, tail, include, recursedType);
+ {
+ errorMessage = ParseMapWithPaths(censor, tail, include, recursedType, wildcardMatching);
+ if (errorMessage)
+ break;
+ }
#endif
else
- ThrowUserErrorException();
+ {
+ errorMessage = "Incorrect wildcard type marker";
+ break;
+ }
}
+ if (i != strings.Size())
+ throw CArcCmdLineException(errorMessage, strings[i]);
}
#ifdef _WIN32
@@ -418,20 +607,27 @@ static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
static void ConvertToLongName(const UString &prefix, UString &name)
{
- if (name.IsEmpty() || DoesNameContainWildCard(name))
+ if (name.IsEmpty() || DoesNameContainWildcard(name))
return;
NFind::CFileInfo fi;
- if (fi.Find(us2fs(prefix + name)))
+ 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 (int i = 0; i < items.Size(); i++)
+ 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());
}
}
@@ -440,17 +636,22 @@ static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &no
{
ConvertToLongNames(prefix, node.IncludeItems);
ConvertToLongNames(prefix, node.ExcludeItems);
- int i;
+ unsigned i;
for (i = 0; i < node.SubNodes.Size(); i++)
- ConvertToLongName(prefix, node.SubNodes[i].Name);
+ {
+ 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 (int j = i + 1; j < node.SubNodes.Size();)
+ for (unsigned j = i + 1; j < node.SubNodes.Size();)
{
const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
- if (nextNode1.Name.CompareNoCase(nextNode2.Name) == 0)
+ if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name))
{
nextNode1.IncludeItems += nextNode2.IncludeItems;
nextNode1.ExcludeItems += nextNode2.ExcludeItems;
@@ -467,9 +668,9 @@ static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &no
}
}
-static void ConvertToLongNames(NWildcard::CCensor &censor)
+void ConvertToLongNames(NWildcard::CCensor &censor)
{
- for (int i = 0; i < censor.Pairs.Size(); i++)
+ FOR_VECTOR (i, censor.Pairs)
{
NWildcard::CPair &pair = censor.Pairs[i];
ConvertToLongNames(pair.Prefix, pair.Head);
@@ -478,9 +679,10 @@ static void ConvertToLongNames(NWildcard::CCensor &censor)
#endif
+/*
static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
{
- switch(i)
+ switch (i)
{
case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore;
case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy;
@@ -489,36 +691,37 @@ static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
}
throw 98111603;
}
+*/
-const UString kUpdatePairStateIDSet = L"PQRXYZW";
-const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
-
-const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress, Create Anti
+static const wchar_t *kUpdatePairStateIDSet = L"pqrxyzw";
+static const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
-const wchar_t *kUpdateIgnoreItselfPostStringID = L"-";
-const wchar_t kUpdateNewArchivePostCharID = '!';
+static const unsigned kNumUpdatePairActions = 4;
+static const char *kUpdateIgnoreItselfPostStringID = "-";
+static const wchar_t kUpdateNewArchivePostCharID = '!';
static bool ParseUpdateCommandString2(const UString &command,
NUpdateArchive::CActionSet &actionSet, UString &postString)
{
- for (int i = 0; i < command.Length();)
+ for (unsigned i = 0; i < command.Len();)
{
- wchar_t c = MyCharUpper(command[i]);
- int statePos = kUpdatePairStateIDSet.Find(c);
+ wchar_t c = MyCharLower_Ascii(command[i]);
+ int statePos = FindCharPosInString(kUpdatePairStateIDSet, c);
if (statePos < 0)
{
- postString = command.Mid(i);
+ postString = command.Ptr(i);
return true;
}
i++;
- if (i >= command.Length())
+ if (i >= command.Len())
return false;
- int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i]));
- if (actionPos < 0)
+ c = command[i];
+ if (c < '0' || c >= '0' + kNumUpdatePairActions)
return false;
- actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos);
- if (kUpdatePairStateNotSupportedActions[statePos] == actionPos)
+ unsigned actionPos = c - '0';
+ actionSet.StateActions[(unsigned)statePos] = (NUpdateArchive::NPairAction::EEnum)(actionPos);
+ if (kUpdatePairStateNotSupportedActions[(unsigned)statePos] == (int)actionPos)
return false;
i++;
}
@@ -530,10 +733,12 @@ static void ParseUpdateCommandString(CUpdateOptions &options,
const UStringVector &updatePostStrings,
const NUpdateArchive::CActionSet &defaultActionSet)
{
- for (int i = 0; i < updatePostStrings.Size(); i++)
+ const char *errorMessage = "incorrect update switch command";
+ unsigned i;
+ for (i = 0; i < updatePostStrings.Size(); i++)
{
const UString &updateString = updatePostStrings[i];
- if (updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0)
+ if (updateString.IsEqualTo(kUpdateIgnoreItselfPostStringID))
{
if (options.UpdateArchiveItself)
{
@@ -547,7 +752,7 @@ static void ParseUpdateCommandString(CUpdateOptions &options,
UString postString;
if (!ParseUpdateCommandString2(updateString, actionSet, postString))
- ThrowUserErrorException();
+ break;
if (postString.IsEmpty())
{
if (options.UpdateArchiveItself)
@@ -555,64 +760,23 @@ static void ParseUpdateCommandString(CUpdateOptions &options,
}
else
{
- if (MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID)
- ThrowUserErrorException();
+ if (postString[0] != kUpdateNewArchivePostCharID)
+ break;
CUpdateArchiveCommand uc;
- UString archivePath = postString.Mid(1);
+ UString archivePath = postString.Ptr(1);
if (archivePath.IsEmpty())
- ThrowUserErrorException();
+ break;
uc.UserArchivePath = archivePath;
uc.ActionSet = actionSet;
options.Commands.Add(uc);
}
}
}
+ if (i != updatePostStrings.Size())
+ throw CArcCmdLineException(errorMessage, updatePostStrings[i]);
}
-static const char kByteSymbol = 'B';
-static const char kKiloSymbol = 'K';
-static const char kMegaSymbol = 'M';
-static const char kGigaSymbol = 'G';
-
-static bool ParseComplexSize(const UString &src, UInt64 &result)
-{
- UString s = src;
- s.MakeUpper();
-
- const wchar_t *start = s;
- const wchar_t *end;
- UInt64 number = ConvertStringToUInt64(start, &end);
- int numDigits = (int)(end - start);
- if (numDigits == 0 || s.Length() > numDigits + 1)
- return false;
- if (s.Length() == numDigits)
- {
- result = number;
- return true;
- }
- int numBits;
- switch (s[numDigits])
- {
- case kByteSymbol:
- result = number;
- return true;
- case kKiloSymbol:
- numBits = 10;
- break;
- case kMegaSymbol:
- numBits = 20;
- break;
- case kGigaSymbol:
- numBits = 30;
- break;
- default:
- return false;
- }
- if (number >= ((UInt64)1 << (64 - numBits)))
- return false;
- result = number << numBits;
- return true;
-}
+bool ParseComplexSize(const wchar_t *s, UInt64 &result);
static void SetAddCommandOptions(
NCommandType::EEnum commandType,
@@ -620,16 +784,16 @@ static void SetAddCommandOptions(
CUpdateOptions &options)
{
NUpdateArchive::CActionSet defaultActionSet;
- switch(commandType)
+ switch (commandType)
{
case NCommandType::kAdd:
- defaultActionSet = NUpdateArchive::kAddActionSet;
+ defaultActionSet = NUpdateArchive::k_ActionSet_Add;
break;
case NCommandType::kDelete:
- defaultActionSet = NUpdateArchive::kDeleteActionSet;
+ defaultActionSet = NUpdateArchive::k_ActionSet_Delete;
break;
default:
- defaultActionSet = NUpdateArchive::kUpdateActionSet;
+ defaultActionSet = NUpdateArchive::k_ActionSet_Update;
}
options.UpdateArchiveItself = true;
@@ -645,7 +809,7 @@ static void SetAddCommandOptions(
{
const UString &postString = parser[NKey::kWorkingDir].PostStrings[0];
if (postString.IsEmpty())
- NDirectory::MyGetTempPath(options.WorkingDir);
+ NDir::MyGetTempPath(options.WorkingDir);
else
options.WorkingDir = us2fs(postString);
}
@@ -656,11 +820,11 @@ static void SetAddCommandOptions(
if (parser[NKey::kVolume].ThereIs)
{
const UStringVector &sv = parser[NKey::kVolume].PostStrings;
- for (int i = 0; i < sv.Size(); i++)
+ FOR_VECTOR (i, sv)
{
UInt64 size;
- if (!ParseComplexSize(sv[i], size))
- ThrowException("Incorrect volume size");
+ if (!ParseComplexSize(sv[i], size) || size == 0)
+ throw CArcCmdLineException("Incorrect volume size:", sv[i]);
options.VolumesSizes.Add(size);
}
}
@@ -670,116 +834,175 @@ static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &pr
{
if (parser[NKey::kProperty].ThereIs)
{
- for (int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
+ FOR_VECTOR (i, parser[NKey::kProperty].PostStrings)
{
- CProperty property;
- const UString &postString = parser[NKey::kProperty].PostStrings[i];
- int index = postString.Find(L'=');
- if (index < 0)
- property.Name = postString;
- else
+ CProperty prop;
+ prop.Name = parser[NKey::kProperty].PostStrings[i];
+ int index = prop.Name.Find(L'=');
+ if (index >= 0)
{
- property.Name = postString.Left(index);
- property.Value = postString.Mid(index + 1);
+ prop.Value = prop.Name.Ptr(index + 1);
+ prop.Name.DeleteFrom(index);
}
- properties.Add(property);
+ properties.Add(prop);
}
}
}
-CArchiveCommandLineParser::CArchiveCommandLineParser():
- parser(sizeof(kSwitchForms) / sizeof(kSwitchForms[0])) {}
+CArcCmdLineParser::CArcCmdLineParser(): parser(ARRAY_SIZE(kSwitchForms)) {}
-void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings,
- CArchiveCommandLineOptions &options)
+static inline void SetStreamMode(const CSwitchResult &sw, unsigned &res)
{
- try
- {
- parser.ParseStrings(kSwitchForms, commandStrings);
- }
- catch(...)
- {
- ThrowUserErrorException();
- }
+ if (sw.ThereIs)
+ res = sw.PostCharIndex;
+}
+
+void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
+ CArcCmdLineOptions &options)
+{
+ if (!parser.ParseStrings(kSwitchForms, commandStrings))
+ throw CArcCmdLineException(parser.ErrorMessage, parser.ErrorLine);
options.IsInTerminal = MY_IS_TERMINAL(stdin);
options.IsStdOutTerminal = MY_IS_TERMINAL(stdout);
options.IsStdErrTerminal = MY_IS_TERMINAL(stderr);
+
+ options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs || parser[NKey::kHelp3].ThereIs;
+
options.StdInMode = parser[NKey::kStdIn].ThereIs;
options.StdOutMode = parser[NKey::kStdOut].ThereIs;
options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs;
- options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs || parser[NKey::kHelp3].ThereIs;
+ options.TechMode = parser[NKey::kTechMode].ThereIs;
+ options.ShowTime = parser[NKey::kShowTime].ThereIs;
+
+ if (parser[NKey::kDisablePercents].ThereIs
+ || options.StdOutMode
+ || !options.IsStdOutTerminal)
+ options.Number_for_Percents = k_OutStream_disabled;
+
+ if (options.StdOutMode)
+ options.Number_for_Out = k_OutStream_disabled;
+
+ SetStreamMode(parser[NKey::kOutStream], options.Number_for_Out);
+ SetStreamMode(parser[NKey::kErrStream], options.Number_for_Errors);
+ SetStreamMode(parser[NKey::kPercentStream], options.Number_for_Percents);
+
+ if (parser[NKey::kLogLevel].ThereIs)
+ {
+ const UString &s = parser[NKey::kLogLevel].PostStrings[0];
+ if (s.IsEmpty())
+ options.LogLevel = 1;
+ else
+ {
+ UInt32 v;
+ if (!StringToUInt32(s, v))
+ throw CArcCmdLineException("Unsupported switch postfix -bb", s);
+ options.LogLevel = (unsigned)v;
+ }
+ }
+
+ if (parser[NKey::kCaseSensitive].ThereIs)
+ {
+ g_CaseSensitive = !parser[NKey::kCaseSensitive].WithMinus;
+ options.CaseSensitiveChange = true;
+ options.CaseSensitive = g_CaseSensitive;
+ }
- #ifdef _WIN32
options.LargePages = false;
if (parser[NKey::kLargePages].ThereIs)
+ options.LargePages = !parser[NKey::kLargePages].WithMinus;
+
+
+ #ifndef UNDER_CE
+
+ if (parser[NKey::kAffinity].ThereIs)
{
- const UString &postString = parser[NKey::kLargePages].PostStrings.Front();
- if (postString.IsEmpty())
- options.LargePages = true;
+ const UString &s = parser[NKey::kAffinity].PostStrings[0];
+ if (!s.IsEmpty())
+ {
+ UInt32 v = 0;
+ AString a;
+ a.SetFromWStr_if_Ascii(s);
+ if (!a.IsEmpty())
+ {
+ const char *end;
+ v = ConvertHexStringToUInt32(a, &end);
+ if (*end != 0)
+ a.Empty();
+ }
+ if (a.IsEmpty())
+ throw CArcCmdLineException("Unsupported switch postfix -stm", s);
+
+ #ifdef _WIN32
+ SetProcessAffinityMask(GetCurrentProcess(), v);
+ #endif
+ }
}
+
#endif
}
struct CCodePagePair
{
- const wchar_t *Name;
- UINT CodePage;
+ const char *Name;
+ Int32 CodePage;
};
-static CCodePagePair g_CodePagePairs[] =
+static const unsigned kNumByteOnlyCodePages = 3;
+
+static const CCodePagePair g_CodePagePairs[] =
{
- { L"UTF-8", CP_UTF8 },
- { L"WIN", CP_ACP },
- { L"DOS", CP_OEMCP }
+ { "utf-8", CP_UTF8 },
+ { "win", CP_ACP },
+ { "dos", CP_OEMCP },
+ { "utf-16le", MY__CP_UTF16 },
+ { "utf-16be", MY__CP_UTF16BE }
};
-static int FindCharset(const NCommandLineParser::CParser &parser, int keyIndex, int defaultVal)
+static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned keyIndex,
+ bool byteOnlyCodePages, Int32 defaultVal)
{
if (!parser[keyIndex].ThereIs)
return defaultVal;
UString name = parser[keyIndex].PostStrings.Back();
- name.MakeUpper();
- int i;
- for (i = 0; i < sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]); i++)
+ UInt32 v;
+ if (StringToUInt32(name, v))
+ if (v < ((UInt32)1 << 16))
+ return (Int32)v;
+ name.MakeLower_Ascii();
+ unsigned num = byteOnlyCodePages ? kNumByteOnlyCodePages : ARRAY_SIZE(g_CodePagePairs);
+ for (unsigned i = 0;; i++)
{
+ if (i == num) // to disable warnings from different compilers
+ throw CArcCmdLineException("Unsupported charset:", name);
const CCodePagePair &pair = g_CodePagePairs[i];
- if (name.Compare(pair.Name) == 0)
+ if (name.IsEqualTo(pair.Name))
return pair.CodePage;
}
- if (i == sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]))
- ThrowUserErrorException();
- return -1;
}
-static bool ConvertStringToUInt32(const wchar_t *s, UInt32 &v)
-{
- const wchar_t *end;
- UInt64 number = ConvertStringToUInt64(s, &end);
- if (*end != 0)
- return false;
- if (number > (UInt32)0xFFFFFFFF)
- return false;
- v = (UInt32)number;
- return true;
-}
-
-void EnumerateDirItemsAndSort(NWildcard::CCensor &wildcardCensor,
+HRESULT EnumerateDirItemsAndSort(
+ NWildcard::CCensor &censor,
+ NWildcard::ECensorPathMode censorPathMode,
+ const UString &addPathPrefix,
UStringVector &sortedPaths,
- UStringVector &sortedFullPaths)
+ UStringVector &sortedFullPaths,
+ CDirItemsStat &st,
+ IDirItemsCallback *callback)
{
- UStringVector paths;
+ FStringVector paths;
+
{
CDirItems dirItems;
+ dirItems.Callback = callback;
{
- FStringVector errorPaths;
- CRecordVector<DWORD> errorCodes;
- HRESULT res = EnumerateItems(wildcardCensor, dirItems, NULL, errorPaths, errorCodes);
- if (res != S_OK || errorPaths.Size() > 0)
- throw "cannot find archive";
+ HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems);
+ st = dirItems.Stat;
+ RINOK(res);
}
- for (int i = 0; i < dirItems.Items.Size(); i++)
+
+ FOR_VECTOR (i, dirItems.Items)
{
const CDirItem &dirItem = dirItems.Items[i];
if (!dirItem.IsDir())
@@ -788,44 +1011,76 @@ void EnumerateDirItemsAndSort(NWildcard::CCensor &wildcardCensor,
}
if (paths.Size() == 0)
- throw "there is no such archive";
+ throw CArcCmdLineException(kCannotFindArchive);
UStringVector fullPaths;
- int i;
+ unsigned i;
+
for (i = 0; i < paths.Size(); i++)
{
FString fullPath;
- NFile::NDirectory::MyGetFullPathName(us2fs(paths[i]), fullPath);
+ NFile::NDir::MyGetFullPathName(paths[i], fullPath);
fullPaths.Add(fs2us(fullPath));
}
- CIntVector indices;
+
+ CUIntVector indices;
SortFileNames(fullPaths, indices);
- sortedPaths.Reserve(indices.Size());
- sortedFullPaths.Reserve(indices.Size());
+ sortedPaths.ClearAndReserve(indices.Size());
+ sortedFullPaths.ClearAndReserve(indices.Size());
+
for (i = 0; i < indices.Size(); i++)
{
- int index = indices[i];
- sortedPaths.Add(paths[index]);
- sortedFullPaths.Add(fullPaths[index]);
+ 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;
}
-void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
+static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp)
+{
+ bp.Def = parser[switchID].ThereIs;
+ if (bp.Def)
+ bp.Val = !parser[switchID].WithMinus;
+}
+
+void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
{
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
- int numNonSwitchStrings = nonSwitchStrings.Size();
+ unsigned numNonSwitchStrings = nonSwitchStrings.Size();
if (numNonSwitchStrings < kMinNonSwitchWords)
- ThrowUserErrorException();
+ throw CArcCmdLineException("The command must be spcified");
if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command))
- ThrowUserErrorException();
+ throw CArcCmdLineException("Unsupported command:", nonSwitchStrings[kCommandIndex]);
- options.TechMode = parser[NKey::kTechMode].ThereIs;
- options.CalcCrc = parser[NKey::kCalcCrc].ThereIs;
-
- if (parser[NKey::kCaseSensitive].ThereIs)
- g_CaseSensitive = (parser[NKey::kCaseSensitive].PostCharIndex < 0);
+ if (parser[NKey::kHash].ThereIs)
+ options.HashMethods = parser[NKey::kHash].PostStrings;
+
+ if (parser[NKey::kElimDup].ThereIs)
+ {
+ options.ExtractOptions.ElimDup.Def = true;
+ options.ExtractOptions.ElimDup.Val = !parser[NKey::kElimDup].WithMinus;
+ }
+
+ NWildcard::ECensorPathMode censorPathMode = NWildcard::k_RelatPath;
+ bool fullPathMode = parser[NKey::kFullPathMode].ThereIs;
+ if (fullPathMode)
+ {
+ censorPathMode = NWildcard::k_AbsPath;
+ const UString &s = parser[NKey::kFullPathMode].PostStrings[0];
+ if (!s.IsEmpty())
+ {
+ if (s == L"2")
+ censorPathMode = NWildcard::k_FullPath;
+ else
+ throw CArcCmdLineException("Unsupported -spf:", s);
+ }
+ }
NRecursedType::EEnum recursedType;
if (parser[NKey::kRecursed].ThereIs)
@@ -833,43 +1088,58 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
else
recursedType = NRecursedType::kNonRecursed;
- g_CodePage = FindCharset(parser, NKey::kConsoleCharSet, -1);
- UINT codePage = FindCharset(parser, NKey::kListfileCharSet, CP_UTF8);
+ bool wildcardMatching = true;
+ if (parser[NKey::kDisableWildcardParsing].ThereIs)
+ wildcardMatching = false;
+
+ g_CodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1);
+ Int32 codePage = FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8);
bool thereAreSwitchIncludes = false;
+
if (parser[NKey::kInclude].ThereIs)
{
thereAreSwitchIncludes = true;
- AddSwitchWildCardsToCensor(options.WildcardCensor,
- parser[NKey::kInclude].PostStrings, true, recursedType, codePage);
+ AddSwitchWildcardsToCensor(options.Censor,
+ parser[NKey::kInclude].PostStrings, true, recursedType, wildcardMatching, codePage);
}
+
if (parser[NKey::kExclude].ThereIs)
- AddSwitchWildCardsToCensor(options.WildcardCensor,
- parser[NKey::kExclude].PostStrings, false, recursedType, codePage);
+ AddSwitchWildcardsToCensor(options.Censor,
+ parser[NKey::kExclude].PostStrings, false, recursedType, wildcardMatching, codePage);
- int curCommandIndex = kCommandIndex + 1;
+ unsigned curCommandIndex = kCommandIndex + 1;
bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs &&
options.Command.CommandType != NCommandType::kBenchmark &&
- options.Command.CommandType != NCommandType::kInfo;
+ options.Command.CommandType != NCommandType::kInfo &&
+ options.Command.CommandType != NCommandType::kHash;
bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList;
+ bool isRename = options.Command.CommandType == NCommandType::kRename;
- if (isExtractOrList && options.StdInMode)
+ if ((isExtractOrList || isRename) && options.StdInMode)
thereIsArchiveName = false;
+ if (parser[NKey::kArcNameMode].ThereIs)
+ options.UpdateOptions.ArcNameMode = ParseArcNameMode(parser[NKey::kArcNameMode].PostCharIndex);
+
if (thereIsArchiveName)
{
if (curCommandIndex >= numNonSwitchStrings)
- ThrowUserErrorException();
+ throw CArcCmdLineException("Cannot find archive name");
options.ArchiveName = nonSwitchStrings[curCommandIndex++];
if (options.ArchiveName.IsEmpty())
- ThrowUserErrorException();
+ throw CArcCmdLineException("Archive name cannot by empty");
+ #ifdef _WIN32
+ // options.ArchiveName.Replace(L'/', WCHAR_PATH_SEPARATOR);
+ #endif
}
- AddToCensorFromNonSwitchesStrings(
- curCommandIndex, options.WildcardCensor,
- nonSwitchStrings, recursedType, thereAreSwitchIncludes, codePage);
+ AddToCensorFromNonSwitchesStrings(isRename ? &options.UpdateOptions.RenamePairs : NULL,
+ curCommandIndex, options.Censor,
+ nonSwitchStrings, recursedType, wildcardMatching,
+ thereAreSwitchIncludes, codePage);
options.YesToAll = parser[NKey::kYes].ThereIs;
@@ -885,63 +1155,126 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
if (parser[NKey::kArchiveType].ThereIs)
options.ArcType = parser[NKey::kArchiveType].PostStrings[0];
+ options.ExcludedArcTypes = parser[NKey::kExcludedArcType].PostStrings;
+
SetMethodOptions(parser, options.Properties);
+ if (parser[NKey::kNtSecurity].ThereIs) options.NtSecurity.SetTrueTrue();
+
+ SetBoolPair(parser, NKey::kAltStreams, options.AltStreams);
+ SetBoolPair(parser, NKey::kHardLinks, options.HardLinks);
+ SetBoolPair(parser, NKey::kSymLinks, options.SymLinks);
+
if (isExtractOrList)
{
- if (!options.WildcardCensor.AllAreRelative())
- ThrowException("Cannot use absolute pathnames for this command");
+ CExtractOptionsBase &eo = options.ExtractOptions;
+
+ {
+ CExtractNtOptions &nt = eo.NtOptions;
+ nt.NtSecurity = options.NtSecurity;
+
+ nt.AltStreams = options.AltStreams;
+ if (!options.AltStreams.Def)
+ nt.AltStreams.Val = true;
+
+ nt.HardLinks = options.HardLinks;
+ if (!options.HardLinks.Def)
+ nt.HardLinks.Val = true;
- NWildcard::CCensor archiveWildcardCensor;
+ nt.SymLinks = options.SymLinks;
+ if (!options.SymLinks.Def)
+ nt.SymLinks.Val = true;
+
+ nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs;
+ nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs;
+ }
+
+ options.Censor.AddPathsToCensor(NWildcard::k_AbsPath);
+ options.Censor.ExtendExclude();
+
+ // are there paths that look as non-relative (!Prefix.IsEmpty())
+ if (!options.Censor.AllAreRelative())
+ throw CArcCmdLineException("Cannot use absolute pathnames for this command");
+
+ NWildcard::CCensor &arcCensor = options.arcCensor;
if (parser[NKey::kArInclude].ThereIs)
- AddSwitchWildCardsToCensor(archiveWildcardCensor,
- parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, codePage);
+ AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, wildcardMatching, codePage);
if (parser[NKey::kArExclude].ThereIs)
- AddSwitchWildCardsToCensor(archiveWildcardCensor,
- parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, codePage);
+ AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, wildcardMatching, codePage);
if (thereIsArchiveName)
- AddNameToCensor(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);
+ AddNameToCensor(arcCensor, options.ArchiveName, true, NRecursedType::kNonRecursed, wildcardMatching);
+
+ arcCensor.AddPathsToCensor(NWildcard::k_RelatPath);
#ifdef _WIN32
- ConvertToLongNames(archiveWildcardCensor);
+ ConvertToLongNames(arcCensor);
#endif
- archiveWildcardCensor.ExtendExclude();
+ arcCensor.ExtendExclude();
if (options.StdInMode)
- {
- UString arcName = parser[NKey::kStdIn].PostStrings.Front();
- options.ArchivePathsSorted.Add(arcName);
- options.ArchivePathsFullSorted.Add(arcName);
- }
- else
- {
- EnumerateDirItemsAndSort(archiveWildcardCensor,
- options.ArchivePathsSorted,
- options.ArchivePathsFullSorted);
- }
+ options.ArcName_for_StdInMode = parser[NKey::kStdIn].PostStrings.Front();
if (isExtractGroupCommand)
{
- if (options.StdOutMode && options.IsStdOutTerminal && options.IsStdErrTerminal)
- throw kSameTerminalError;
+ if (options.StdOutMode)
+ {
+ if (
+ options.Number_for_Percents == k_OutStream_stdout
+ // || options.Number_for_Out == k_OutStream_stdout
+ // || options.Number_for_Errors == k_OutStream_stdout
+ ||
+ (
+ (options.IsStdOutTerminal && options.IsStdErrTerminal)
+ &&
+ (
+ options.Number_for_Percents != k_OutStream_disabled
+ // || options.Number_for_Out != k_OutStream_disabled
+ // || options.Number_for_Errors != k_OutStream_disabled
+ )
+ )
+ )
+ throw CArcCmdLineException(kSameTerminalError);
+ }
+
if (parser[NKey::kOutputDir].ThereIs)
{
- options.OutputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]);
- NFile::NName::NormalizeDirPathPrefix(options.OutputDir);
+ eo.OutputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]);
+ NFile::NName::NormalizeDirPathPrefix(eo.OutputDir);
}
- options.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
+ eo.OverwriteMode = NExtract::NOverwriteMode::kAsk;
if (parser[NKey::kOverwrite].ThereIs)
- options.OverwriteMode = k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex];
+ {
+ eo.OverwriteMode = k_OverwriteModes[(unsigned)parser[NKey::kOverwrite].PostCharIndex];
+ eo.OverwriteMode_Force = true;
+ }
else if (options.YesToAll)
- options.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
+ {
+ eo.OverwriteMode = NExtract::NOverwriteMode::kOverwrite;
+ eo.OverwriteMode_Force = true;
+ }
+ }
+
+ eo.PathMode = options.Command.GetPathMode();
+ if (censorPathMode == NWildcard::k_AbsPath)
+ {
+ eo.PathMode = NExtract::NPathMode::kAbsPaths;
+ eo.PathMode_Force = true;
+ }
+ else if (censorPathMode == NWildcard::k_FullPath)
+ {
+ eo.PathMode = NExtract::NPathMode::kFullPaths;
+ eo.PathMode_Force = true;
}
}
else if (options.Command.IsFromUpdateGroup())
{
+ if (parser[NKey::kArInclude].ThereIs)
+ throw CArcCmdLineException("-ai switch is not supported for this command");
+
CUpdateOptions &updateOptions = options.UpdateOptions;
SetAddCommandOptions(options.Command.CommandType, parser, updateOptions);
@@ -951,20 +1284,18 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
if (parser[NKey::kShareForWrite].ThereIs)
updateOptions.OpenShareForWrite = true;
- options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs;
+ updateOptions.PathMode = censorPathMode;
- if (options.EnablePercents)
- {
- if ((options.StdOutMode && !options.IsStdErrTerminal) ||
- (!options.StdOutMode && !options.IsStdOutTerminal))
- options.EnablePercents = false;
- }
+ updateOptions.AltStreams = options.AltStreams;
+ updateOptions.NtSecurity = options.NtSecurity;
+ updateOptions.HardLinks = options.HardLinks;
+ updateOptions.SymLinks = options.SymLinks;
updateOptions.EMailMode = parser[NKey::kEmail].ThereIs;
if (updateOptions.EMailMode)
{
updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front();
- if (updateOptions.EMailAddress.Length() > 0)
+ if (updateOptions.EMailAddress.Len() > 0)
if (updateOptions.EMailAddress[0] == L'.')
{
updateOptions.EMailRemoveAfter = true;
@@ -975,30 +1306,56 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
updateOptions.StdOutMode = options.StdOutMode;
updateOptions.StdInMode = options.StdInMode;
+ updateOptions.DeleteAfterCompressing = parser[NKey::kDeleteAfterCompressing].ThereIs;
+ updateOptions.SetArcMTime = parser[NKey::kSetArcMTime].ThereIs;
+
if (updateOptions.StdOutMode && updateOptions.EMailMode)
- throw "stdout mode and email mode cannot be combined";
- if (updateOptions.StdOutMode && options.IsStdOutTerminal)
- throw kTerminalOutError;
+ throw CArcCmdLineException("stdout mode and email mode cannot be combined");
+
+ if (updateOptions.StdOutMode)
+ {
+ if (options.IsStdOutTerminal)
+ throw CArcCmdLineException(kTerminalOutError);
+
+ if (options.Number_for_Percents == k_OutStream_stdout
+ || options.Number_for_Out == k_OutStream_stdout
+ || options.Number_for_Errors == k_OutStream_stdout)
+ throw CArcCmdLineException(kSameTerminalError);
+ }
+
if (updateOptions.StdInMode)
updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front();
- #ifdef _WIN32
- ConvertToLongNames(options.WildcardCensor);
- #endif
+ if (options.Command.CommandType == NCommandType::kRename)
+ if (updateOptions.Commands.Size() != 1)
+ throw CArcCmdLineException("Only one archive can be created with rename command");
}
else if (options.Command.CommandType == NCommandType::kBenchmark)
{
options.NumIterations = 1;
if (curCommandIndex < numNonSwitchStrings)
{
- if (!ConvertStringToUInt32(nonSwitchStrings[curCommandIndex++], options.NumIterations))
- ThrowUserErrorException();
+ if (!StringToUInt32(nonSwitchStrings[curCommandIndex], options.NumIterations))
+ throw CArcCmdLineException("Incorrect Number of benmchmark iterations", nonSwitchStrings[curCommandIndex]);
+ curCommandIndex++;
}
}
+ else if (options.Command.CommandType == NCommandType::kHash)
+ {
+ options.Censor.AddPathsToCensor(censorPathMode);
+ options.Censor.ExtendExclude();
+
+ CHashOptions &hashOptions = options.HashOptions;
+ hashOptions.PathMode = censorPathMode;
+ hashOptions.Methods = options.HashMethods;
+ if (parser[NKey::kShareForWrite].ThereIs)
+ hashOptions.OpenShareForWrite = true;
+ hashOptions.StdInMode = options.StdInMode;
+ hashOptions.AltStreamsMode = options.AltStreams.Val;
+ }
else if (options.Command.CommandType == NCommandType::kInfo)
{
}
else
- ThrowUserErrorException();
- options.WildcardCensor.ExtendExclude();
+ throw 20150919;
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h
index 96646d605cf..a345505cb84 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h
@@ -3,15 +3,16 @@
#ifndef __ARCHIVE_COMMAND_LINE_H
#define __ARCHIVE_COMMAND_LINE_H
-#include "Common/CommandLineParser.h"
-#include "Common/Wildcard.h"
+#include "../../../Common/CommandLineParser.h"
+#include "../../../Common/Wildcard.h"
#include "Extract.h"
+#include "HashCalc.h"
#include "Update.h"
-struct CArchiveCommandLineException: public AString
+struct CArcCmdLineException: public UString
{
- CArchiveCommandLineException(const char *errorMessage): AString(errorMessage) {}
+ CArcCmdLineException(const char *a, const wchar_t *u = NULL);
};
namespace NCommandType { enum EEnum
@@ -21,35 +22,38 @@ namespace NCommandType { enum EEnum
kDelete,
kTest,
kExtract,
- kFullExtract,
+ kExtractFull,
kList,
kBenchmark,
- kInfo
+ kInfo,
+ kHash,
+ kRename
};}
-namespace NRecursedType { enum EEnum
-{
- kRecursed,
- kWildCardOnlyRecursed,
- kNonRecursed
-};}
-
-struct CArchiveCommand
+struct CArcCommand
{
NCommandType::EEnum CommandType;
+
bool IsFromExtractGroup() const;
bool IsFromUpdateGroup() const;
- bool IsTestMode() const { return CommandType == NCommandType::kTest; }
+ bool IsTestCommand() const { return CommandType == NCommandType::kTest; }
NExtract::NPathMode::EEnum GetPathMode() const;
};
-struct CArchiveCommandLineOptions
+enum
+{
+ k_OutStream_disabled = 0,
+ k_OutStream_stdout = 1,
+ k_OutStream_stderr = 2
+};
+
+struct CArcCmdLineOptions
{
bool HelpMode;
- #ifdef _WIN32
bool LargePages;
- #endif
+ bool CaseSensitiveChange;
+ bool CaseSensitive;
bool IsInTerminal;
bool IsStdOutTerminal;
@@ -60,10 +64,9 @@ struct CArchiveCommandLineOptions
bool YesToAll;
bool ShowDialog;
- // NWildcard::CCensor ArchiveWildcardCensor;
- NWildcard::CCensor WildcardCensor;
+ NWildcard::CCensor Censor;
- CArchiveCommand Command;
+ CArcCommand Command;
UString ArchiveName;
#ifndef _NO_CRYPTO
@@ -72,36 +75,73 @@ struct CArchiveCommandLineOptions
#endif
bool TechMode;
- // Extract
- bool CalcCrc;
+ bool ShowTime;
+
+ UStringVector HashMethods;
+
bool AppendName;
- FString OutputDir;
- NExtract::NOverwriteMode::EEnum OverwriteMode;
- UStringVector ArchivePathsSorted;
- UStringVector ArchivePathsFullSorted;
+ // UStringVector ArchivePathsSorted;
+ // UStringVector ArchivePathsFullSorted;
+ NWildcard::CCensor arcCensor;
+ UString ArcName_for_StdInMode;
+
CObjectVector<CProperty> Properties;
+ CExtractOptionsBase ExtractOptions;
+
+ CBoolPair NtSecurity;
+ CBoolPair AltStreams;
+ CBoolPair HardLinks;
+ CBoolPair SymLinks;
+
CUpdateOptions UpdateOptions;
+ CHashOptions HashOptions;
UString ArcType;
- bool EnablePercents;
+ UStringVector ExcludedArcTypes;
+
+ unsigned Number_for_Out;
+ unsigned Number_for_Errors;
+ unsigned Number_for_Percents;
+ unsigned LogLevel;
+
+ // bool IsOutAllowed() const { return Number_for_Out != k_OutStream_disabled; }
// Benchmark
UInt32 NumIterations;
- CArchiveCommandLineOptions(): StdInMode(false), StdOutMode(false) {};
+ CArcCmdLineOptions():
+ LargePages(false),
+ CaseSensitiveChange(false),
+ CaseSensitive(false),
+
+ StdInMode(false),
+ StdOutMode(false),
+
+ Number_for_Out(k_OutStream_stdout),
+ Number_for_Errors(k_OutStream_stderr),
+ Number_for_Percents(k_OutStream_stdout),
+
+ LogLevel(0)
+ {
+ };
};
-class CArchiveCommandLineParser
+class CArcCmdLineParser
{
NCommandLineParser::CParser parser;
public:
- CArchiveCommandLineParser();
- void Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options);
- void Parse2(CArchiveCommandLineOptions &options);
+ CArcCmdLineParser();
+ void Parse1(const UStringVector &commandStrings, CArcCmdLineOptions &options);
+ void Parse2(CArcCmdLineOptions &options);
};
-void EnumerateDirItemsAndSort(NWildcard::CCensor &wildcardCensor,
+HRESULT EnumerateDirItemsAndSort(
+ NWildcard::CCensor &censor,
+ NWildcard::ECensorPathMode pathMode,
+ const UString &addPathPrefix,
UStringVector &sortedPaths,
- UStringVector &sortedFullPaths);
+ UStringVector &sortedFullPaths,
+ CDirItemsStat &st,
+ IDirItemsCallback *callback);
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
index 9c9c042291d..62da5e9fad4 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
@@ -2,63 +2,273 @@
#include "StdAfx.h"
-#include "Common/ComTry.h"
-#include "Common/StringConvert.h"
-#include "Common/Wildcard.h"
+#undef sprintf
+#undef printf
-#include "Windows/FileDir.h"
-#include "Windows/FileFind.h"
-#include "Windows/FileName.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
+#include "../../../../C/Alloc.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/ErrorMsg.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/PropVariantConv.h"
+
+#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
+#define _USE_SECURITY_CODE
+#include "../../../Windows/SecurityUtils.h"
+#endif
#include "../../Common/FilePathAutoRename.h"
+// #include "../../Common/StreamUtils.h"
#include "../Common/ExtractingFilePath.h"
+#include "../Common/PropIDUtils.h"
#include "ArchiveExtractCallback.h"
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";
+
+
+#ifndef _SFX
+
+STDMETHODIMP COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ HRESULT result = S_OK;
+ if (_stream)
+ result = _stream->Write(data, size, &size);
+ if (_calculate)
+ _hash->Update(data, size);
+ _size += size;
+ if (processedSize)
+ *processedSize = size;
+ return result;
+}
+
+#endif
+
+#ifdef _USE_SECURITY_CODE
+bool InitLocalPrivileges()
+{
+ NSecurity::CAccessToken token;
+ if (!token.OpenProcessToken(GetCurrentProcess(),
+ TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES))
+ return false;
+
+ TOKEN_PRIVILEGES tp;
+
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ if (!::LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &tp.Privileges[0].Luid))
+ return false;
+ if (!token.AdjustPrivileges(&tp))
+ return false;
+ return (GetLastError() == ERROR_SUCCESS);
+}
+#endif
+
+#ifdef SUPPORT_LINKS
+
+int CHardLinkNode::Compare(const CHardLinkNode &a) const
+{
+ if (StreamId < a.StreamId) return -1;
+ if (StreamId > a.StreamId) return 1;
+ return MyCompare(INode, a.INode);
+}
+
+static HRESULT Archive_Get_HardLinkNode(IInArchive *archive, UInt32 index, CHardLinkNode &h, bool &defined)
+{
+ h.INode = 0;
+ h.StreamId = (UInt64)(Int64)-1;
+ defined = false;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidINode, &prop));
+ if (!ConvertPropVariantToUInt64(prop, h.INode))
+ return S_OK;
+ }
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidStreamId, &prop));
+ ConvertPropVariantToUInt64(prop, h.StreamId);
+ }
+ defined = true;
+ return S_OK;
+}
+
+
+HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *realIndices)
+{
+ _hardLinks.Clear();
+
+ if (!_arc->Ask_INode)
+ return S_OK;
+
+ IInArchive *archive = _arc->Archive;
+ CRecordVector<CHardLinkNode> &hardIDs = _hardLinks.IDs;
+
+ {
+ UInt32 numItems;
+ if (realIndices)
+ numItems = realIndices->Size();
+ else
+ {
+ RINOK(archive->GetNumberOfItems(&numItems));
+ }
+
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ CHardLinkNode h;
+ bool defined;
+ UInt32 realIndex = realIndices ? (*realIndices)[i] : i;
+
+ RINOK(Archive_Get_HardLinkNode(archive, realIndex, h, defined));
+ if (defined)
+ {
+ bool isAltStream = false;
+ RINOK(Archive_IsItem_AltStream(archive, realIndex, isAltStream));
+ if (!isAltStream)
+ hardIDs.Add(h);
+ }
+ }
+ }
+
+ hardIDs.Sort2();
+
+ {
+ // wee keep only items that have 2 or more items
+ unsigned k = 0;
+ unsigned numSame = 1;
+ for (unsigned i = 1; i < hardIDs.Size(); i++)
+ {
+ if (hardIDs[i].Compare(hardIDs[i - 1]) != 0)
+ numSame = 1;
+ else if (++numSame == 2)
+ {
+ if (i - 1 != k)
+ hardIDs[k] = hardIDs[i - 1];
+ k++;
+ }
+ }
+ hardIDs.DeleteFrom(k);
+ }
+
+ _hardLinks.PrepareLinks();
+ return S_OK;
+}
-static const char *kCantAutoRename = "ERROR: Can not create file with auto name";
-static const char *kCantRenameFile = "ERROR: Can not rename existing file ";
-static const char *kCantDeleteOutputFile = "ERROR: Can not delete output file ";
+#endif
+
+CArchiveExtractCallback::CArchiveExtractCallback():
+ WriteCTime(true),
+ WriteATime(true),
+ WriteMTime(true),
+ _multiArchives(false)
+{
+ LocalProgressSpec = new CLocalProgress();
+ _localProgress = LocalProgressSpec;
+
+ #ifdef _USE_SECURITY_CODE
+ _saclEnabled = InitLocalPrivileges();
+ #endif
+}
void CArchiveExtractCallback::Init(
+ const CExtractNtOptions &ntOptions,
const NWildcard::CCensorNode *wildcardCensor,
const CArc *arc,
IFolderArchiveExtractCallback *extractCallback2,
- bool stdOutMode, bool testMode, bool crcMode,
+ bool stdOutMode, bool testMode,
const FString &directoryPath,
- const UStringVector &removePathParts,
+ const UStringVector &removePathParts, bool removePartsForAltStreams,
UInt64 packSize)
{
+ _extractedFolderPaths.Clear();
+ _extractedFolderIndices.Clear();
+
+ #ifdef SUPPORT_LINKS
+ _hardLinks.Clear();
+ #endif
+
+ #ifdef SUPPORT_ALT_STREAMS
+ _renamedFiles.Clear();
+ #endif
+
+ _ntOptions = ntOptions;
_wildcardCensor = wildcardCensor;
_stdOutMode = stdOutMode;
_testMode = testMode;
- _crcMode = crcMode;
- _unpTotal = 1;
+
+ // _progressTotal = 0;
+ // _progressTotal_Defined = false;
+
_packTotal = packSize;
+ _progressTotal = packSize;
+ _progressTotal_Defined = true;
_extractCallback2 = extractCallback2;
_compressProgress.Release();
_extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);
+ _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage, &_callbackMessage);
+ _extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2);
+
+ #ifndef _SFX
+
+ _extractCallback2.QueryInterface(IID_IFolderExtractToStreamCallback, &ExtractToStreamCallback);
+ if (ExtractToStreamCallback)
+ {
+ Int32 useStreams = 0;
+ if (ExtractToStreamCallback->UseExtractToStream(&useStreams) != S_OK)
+ useStreams = 0;
+ if (useStreams == 0)
+ ExtractToStreamCallback.Release();
+ }
+
+ #endif
LocalProgressSpec->Init(extractCallback2, true);
LocalProgressSpec->SendProgress = false;
-
_removePathParts = removePathParts;
+ _removePartsForAltStreams = removePartsForAltStreams;
+
+ #ifndef _SFX
+ _baseParentFolder = (UInt32)(Int32)-1;
+ _use_baseParentFolder_mode = false;
+ #endif
+
_arc = arc;
- _directoryPath = directoryPath;
- NFile::NName::NormalizeDirPathPrefix(_directoryPath);
+ _dirPathPrefix = directoryPath;
+ _dirPathPrefix_Full = directoryPath;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (!NName::IsAltPathPrefix(_dirPathPrefix))
+ #endif
+ {
+ NName::NormalizeDirPathPrefix(_dirPathPrefix);
+ NDir::MyGetFullPathName(directoryPath, _dirPathPrefix_Full);
+ NName::NormalizeDirPathPrefix(_dirPathPrefix_Full);
+ }
}
STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size)
{
COM_TRY_BEGIN
- _unpTotal = size;
+ _progressTotal = size;
+ _progressTotal_Defined = true;
if (!_multiArchives && _extractCallback2)
return _extractCallback2->SetTotal(size);
return S_OK;
@@ -87,18 +297,20 @@ static UInt64 MyMultDiv64(UInt64 unpCur, UInt64 unpTotal, UInt64 packTotal)
STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)
{
COM_TRY_BEGIN
+
if (!_extractCallback2)
return S_OK;
+ UInt64 packCur;
if (_multiArchives)
{
- if (completeValue != NULL)
- {
- UInt64 packCur = LocalProgressSpec->InSize + MyMultDiv64(*completeValue, _unpTotal, _packTotal);
- return _extractCallback2->SetCompleted(&packCur);
- }
+ packCur = LocalProgressSpec->InSize;
+ if (completeValue && _progressTotal_Defined)
+ packCur += MyMultDiv64(*completeValue, _progressTotal, _packTotal);
+ completeValue = &packCur;
}
return _extractCallback2->SetCompleted(completeValue);
+
COM_TRY_END
}
@@ -111,13 +323,39 @@ STDMETHODIMP CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const U
void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath)
{
- fullPath = _directoryPath;
- for (int i = 0; i < dirPathParts.Size(); i++)
+ bool isAbsPath = false;
+
+ if (!dirPathParts.IsEmpty())
+ {
+ const UString &s = dirPathParts[0];
+ if (s.IsEmpty())
+ isAbsPath = true;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ else
+ {
+ if (NName::IsDrivePath2(s))
+ isAbsPath = true;
+ }
+ #endif
+ }
+
+ if (_pathMode == NExtract::NPathMode::kAbsPaths && isAbsPath)
+ fullPath.Empty();
+ else
+ fullPath = _dirPathPrefix;
+
+ FOR_VECTOR (i, dirPathParts)
{
- if (i > 0)
- fullPath += FCHAR_PATH_SEPARATOR;
- fullPath += us2fs(dirPathParts[i]);
- NFile::NDirectory::MyCreateDirectory(fullPath);
+ if (i != 0)
+ fullPath.Add_PathSepar();
+ const UString &s = dirPathParts[i];
+ fullPath += us2fs(s);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (_pathMode == NExtract::NPathMode::kAbsPaths)
+ if (i == 0 && s.Len() == 2 && NName::IsDrivePath2(s))
+ continue;
+ #endif
+ CreateDir(fullPath);
}
}
@@ -141,31 +379,272 @@ HRESULT CArchiveExtractCallback::GetUnpackSize()
return _arc->GetItemSize(_index, _curSize, _curSizeDefined);
}
+static void AddPathToMessage(UString &s, const FString &path)
+{
+ s.AddAscii(" : ");
+ s += fs2us(path);
+}
+
HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FString &path)
{
- return _extractCallback2->MessageError(GetUnicodeString(message) + fs2us(path));
+ UString s;
+ s.AddAscii(message);
+ AddPathToMessage(s, path);
+ return _extractCallback2->MessageError(s);
+}
+
+HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path)
+{
+ DWORD errorCode = GetLastError();
+ UString s;
+ s.AddAscii(message);
+ if (errorCode != 0)
+ {
+ s.AddAscii(" : ");
+ s += NError::MyFormatMessage(errorCode);
+ }
+ AddPathToMessage(s, path);
+ return _extractCallback2->MessageError(s);
+}
+
+HRESULT CArchiveExtractCallback::SendMessageError2(const char *message, const FString &path1, const FString &path2)
+{
+ UString s;
+ s.AddAscii(message);
+ AddPathToMessage(s, path1);
+ AddPathToMessage(s, path2);
+ return _extractCallback2->MessageError(s);
+}
+
+#ifndef _SFX
+
+STDMETHODIMP CGetProp::GetProp(PROPID propID, PROPVARIANT *value)
+{
+ /*
+ if (propID == kpidName)
+ {
+ COM_TRY_BEGIN
+ NCOM::CPropVariant prop = Name;
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+ }
+ */
+ return Arc->Archive->GetProperty(IndexInArc, propID, value);
+}
+
+#endif
+
+
+#ifdef SUPPORT_LINKS
+
+static UString GetDirPrefixOf(const UString &src)
+{
+ UString s = src;
+ if (!s.IsEmpty())
+ {
+ if (IsPathSepar(s.Back()))
+ s.DeleteBack();
+ int pos = s.ReverseFind_PathSepar();
+ s.DeleteFrom(pos + 1);
+ }
+ return s;
+}
+
+#endif
+
+
+bool IsSafePath(const UString &path)
+{
+ if (NName::IsAbsolutePath(path))
+ return false;
+
+ UStringVector parts;
+ SplitPathToParts(path, parts);
+ unsigned level = 0;
+
+ FOR_VECTOR (i, parts)
+ {
+ const UString &s = parts[i];
+ if (s.IsEmpty())
+ {
+ if (i == 0)
+ return false;
+ continue;
+ }
+ if (s == L".")
+ continue;
+ if (s == L"..")
+ {
+ if (level == 0)
+ return false;
+ level--;
+ }
+ else
+ level++;
+ }
+
+ return level > 0;
+}
+
+
+bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include)
+{
+ bool found = false;
+
+ if (node.CheckPathVect(item.PathParts, !item.MainIsDir, include))
+ {
+ if (!include)
+ return true;
+
+ #ifdef SUPPORT_ALT_STREAMS
+ if (!item.IsAltStream)
+ return true;
+ #endif
+
+ found = true;
+ }
+
+ #ifdef SUPPORT_ALT_STREAMS
+
+ if (!item.IsAltStream)
+ return false;
+
+ UStringVector pathParts2 = item.PathParts;
+ if (pathParts2.IsEmpty())
+ pathParts2.AddNew();
+ UString &back = pathParts2.Back();
+ back += L':';
+ back += item.AltStreamName;
+ bool include2;
+
+ if (node.CheckPathVect(pathParts2,
+ true, // isFile,
+ include2))
+ {
+ include = include2;
+ return true;
+ }
+
+ #endif
+
+ return found;
+}
+
+bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item)
+{
+ bool include;
+ if (CensorNode_CheckPath2(node, item, include))
+ return include;
+ return false;
+}
+
+static FString MakePath_from_2_Parts(const FString &prefix, const FString &path)
+{
+ FString s = prefix;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (!path.IsEmpty() && path[0] == ':' && !prefix.IsEmpty() && IsPathSepar(prefix.Back()))
+ {
+ if (!NName::IsDriveRootPath_SuperAllowed(prefix))
+ s.DeleteBack();
+ }
+ #endif
+ s += path;
+ return s;
}
+
+/*
+#ifdef SUPPORT_LINKS
+
+struct CTempMidBuffer
+{
+ void *Buf;
+
+ CTempMidBuffer(size_t size): Buf(NULL) { Buf = ::MidAlloc(size); }
+ ~CTempMidBuffer() { ::MidFree(Buf); }
+};
+
+HRESULT CArchiveExtractCallback::MyCopyFile(ISequentialOutStream *outStream)
+{
+ const size_t kBufSize = 1 << 16;
+ CTempMidBuffer buf(kBufSize);
+ if (!buf.Buf)
+ return E_OUTOFMEMORY;
+
+ NIO::CInFile inFile;
+ NIO::COutFile outFile;
+
+ if (!inFile.Open(_CopyFile_Path))
+ return SendMessageError_with_LastError("Open error", _CopyFile_Path);
+
+ for (;;)
+ {
+ UInt32 num;
+
+ if (!inFile.Read(buf.Buf, kBufSize, num))
+ return SendMessageError_with_LastError("Read error", _CopyFile_Path);
+
+ if (num == 0)
+ return S_OK;
+
+
+ RINOK(WriteStream(outStream, buf.Buf, num));
+ }
+}
+
+#endif
+*/
+
STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
{
COM_TRY_BEGIN
- _crcStream.Release();
- *outStream = 0;
+
+ *outStream = NULL;
+
+ #ifndef _SFX
+ if (_hashStream)
+ _hashStreamSpec->ReleaseStream();
+ _hashStreamWasUsed = false;
+ #endif
+
_outFileStream.Release();
_encrypted = false;
+ _position = 0;
_isSplit = false;
+
_curSize = 0;
_curSizeDefined = false;
_index = index;
- UString fullPath;
+ _diskFilePath.Empty();
+
+ // _fi.Clear();
+
+ #ifdef SUPPORT_LINKS
+ // _CopyFile_Path.Empty();
+ linkPath.Empty();
+ #endif
IInArchive *archive = _arc->Archive;
- RINOK(_arc->GetItemPath(index, fullPath));
- RINOK(IsArchiveItemFolder(archive, index, _fi.IsDir));
- _filePath = fullPath;
+ #ifndef _SFX
+ _item._use_baseParentFolder_mode = _use_baseParentFolder_mode;
+ if (_use_baseParentFolder_mode)
+ {
+ _item._baseParentFolder = _baseParentFolder;
+ if (_pathMode == NExtract::NPathMode::kFullPaths ||
+ _pathMode == NExtract::NPathMode::kAbsPaths)
+ _item._baseParentFolder = -1;
+ }
+ #endif
+
+ #ifdef SUPPORT_ALT_STREAMS
+ _item.WriteToAltStreamIfColon = _ntOptions.WriteToAltStreamIfColon;
+ #endif
+
+ RINOK(_arc->GetItem(index, _item));
{
NCOM::CPropVariant prop;
@@ -178,26 +657,303 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
_isSplit = true;
}
}
+
+ #ifdef SUPPORT_LINKS
+
+ // bool isCopyLink = false;
+ bool isHardLink = false;
+ bool isJunction = false;
+ bool isRelative = false;
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidHardLink, &prop));
+ if (prop.vt == VT_BSTR)
+ {
+ isHardLink = true;
+ // isCopyLink = false;
+ isRelative = false; // RAR5, TAR: hard links are from root folder of archive
+ linkPath.SetFromBstr(prop.bstrVal);
+ }
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ }
+
+ /*
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidCopyLink, &prop));
+ if (prop.vt == VT_BSTR)
+ {
+ isHardLink = false;
+ isCopyLink = true;
+ isRelative = false; // RAR5: copy links are from root folder of archive
+ linkPath.SetFromBstr(prop.bstrVal);
+ }
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ }
+ */
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidSymLink, &prop));
+ if (prop.vt == VT_BSTR)
+ {
+ isHardLink = false;
+ // isCopyLink = false;
+ isRelative = true; // RAR5, TAR: symbolic links can be relative
+ linkPath.SetFromBstr(prop.bstrVal);
+ }
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ }
+
+
+ bool isOkReparse = false;
+
+ if (linkPath.IsEmpty() && _arc->GetRawProps)
+ {
+ const void *data;
+ UInt32 dataSize;
+ UInt32 propType;
- RINOK(GetArchiveItemBoolProp(archive, index, kpidEncrypted, _encrypted));
+ _arc->GetRawProps->GetRawProp(_index, kpidNtReparse, &data, &dataSize, &propType);
+
+ if (dataSize != 0)
+ {
+ if (propType != NPropDataType::kRaw)
+ return E_FAIL;
+ UString s;
+ CReparseAttr reparse;
+ isOkReparse = reparse.Parse((const Byte *)data, dataSize);
+ if (isOkReparse)
+ {
+ isHardLink = false;
+ // isCopyLink = false;
+ linkPath = reparse.GetPath();
+ isJunction = reparse.IsMountPoint();
+ isRelative = reparse.IsRelative();
+ #ifndef _WIN32
+ linkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR);
+ #endif
+ }
+ }
+ }
+
+ if (!linkPath.IsEmpty())
+ {
+ #ifdef _WIN32
+ linkPath.Replace(L'/', WCHAR_PATH_SEPARATOR);
+ #endif
+
+ // rar5 uses "\??\" prefix for absolute links
+ if (linkPath.IsPrefixedBy(WSTRING_PATH_SEPARATOR L"??" WSTRING_PATH_SEPARATOR))
+ {
+ isRelative = false;
+ linkPath.DeleteFrontal(4);
+ }
+
+ for (;;)
+ // while (NName::IsAbsolutePath(linkPath))
+ {
+ unsigned n = NName::GetRootPrefixSize(linkPath);
+ if (n == 0)
+ break;
+ isRelative = false;
+ linkPath.DeleteFrontal(n);
+ }
+ }
+
+ if (!linkPath.IsEmpty() && !isRelative && _removePathParts.Size() != 0)
+ {
+ UStringVector pathParts;
+ SplitPathToParts(linkPath, pathParts);
+ bool badPrefix = false;
+ FOR_VECTOR (i, _removePathParts)
+ {
+ if (CompareFileNames(_removePathParts[i], pathParts[i]) != 0)
+ {
+ badPrefix = true;
+ break;
+ }
+ }
+ if (!badPrefix)
+ pathParts.DeleteFrontal(_removePathParts.Size());
+ linkPath = MakePathFromParts(pathParts);
+ }
+
+ #endif
+
+ RINOK(Archive_GetItemBoolProp(archive, index, kpidEncrypted, _encrypted));
RINOK(GetUnpackSize());
+ #ifdef SUPPORT_ALT_STREAMS
+
+ if (!_ntOptions.AltStreams.Val && _item.IsAltStream)
+ return S_OK;
+
+ #endif
+
+
+ UStringVector &pathParts = _item.PathParts;
+
if (_wildcardCensor)
{
- if (!_wildcardCensor->CheckPath(fullPath, !_fi.IsDir))
+ if (!CensorNode_CheckPath(*_wildcardCensor, _item))
return S_OK;
}
- if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
+ #ifndef _SFX
+ if (_use_baseParentFolder_mode)
{
- if (_stdOutMode)
+ if (!pathParts.IsEmpty())
{
- CMyComPtr<ISequentialOutStream> outStreamLoc = new CStdOutFileStream;
- *outStream = outStreamLoc.Detach();
- return S_OK;
+ unsigned numRemovePathParts = 0;
+
+ #ifdef SUPPORT_ALT_STREAMS
+ if (_pathMode == NExtract::NPathMode::kNoPathsAlt && _item.IsAltStream)
+ numRemovePathParts = pathParts.Size();
+ else
+ #endif
+ if (_pathMode == NExtract::NPathMode::kNoPaths ||
+ _pathMode == NExtract::NPathMode::kNoPathsAlt)
+ numRemovePathParts = pathParts.Size() - 1;
+ pathParts.DeleteFrontal(numRemovePathParts);
+ }
+ }
+ else
+ #endif
+ {
+ if (pathParts.IsEmpty())
+ {
+ if (_item.IsDir)
+ return S_OK;
+ /*
+ #ifdef SUPPORT_ALT_STREAMS
+ if (!_item.IsAltStream)
+ #endif
+ return E_FAIL;
+ */
}
+ unsigned numRemovePathParts = 0;
+
+ switch (_pathMode)
+ {
+ case NExtract::NPathMode::kFullPaths:
+ case NExtract::NPathMode::kCurPaths:
+ {
+ if (_removePathParts.IsEmpty())
+ break;
+ bool badPrefix = false;
+
+ if (pathParts.Size() < _removePathParts.Size())
+ badPrefix = true;
+ else
+ {
+ if (pathParts.Size() == _removePathParts.Size())
+ {
+ if (_removePartsForAltStreams)
+ {
+ #ifdef SUPPORT_ALT_STREAMS
+ if (!_item.IsAltStream)
+ #endif
+ badPrefix = true;
+ }
+ else
+ {
+ if (!_item.MainIsDir)
+ badPrefix = true;
+ }
+ }
+
+ if (!badPrefix)
+ FOR_VECTOR (i, _removePathParts)
+ {
+ if (CompareFileNames(_removePathParts[i], pathParts[i]) != 0)
+ {
+ badPrefix = true;
+ break;
+ }
+ }
+ }
+
+ if (badPrefix)
+ {
+ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
+ return E_FAIL;
+ }
+ else
+ numRemovePathParts = _removePathParts.Size();
+ break;
+ }
+
+ case NExtract::NPathMode::kNoPaths:
+ {
+ if (!pathParts.IsEmpty())
+ numRemovePathParts = pathParts.Size() - 1;
+ break;
+ }
+ case NExtract::NPathMode::kNoPathsAlt:
+ {
+ #ifdef SUPPORT_ALT_STREAMS
+ if (_item.IsAltStream)
+ numRemovePathParts = pathParts.Size();
+ else
+ #endif
+ if (!pathParts.IsEmpty())
+ numRemovePathParts = pathParts.Size() - 1;
+ break;
+ }
+ /*
+ case NExtract::NPathMode::kFullPaths:
+ case NExtract::NPathMode::kAbsPaths:
+ break;
+ */
+ }
+
+ pathParts.DeleteFrontal(numRemovePathParts);
+ }
+
+ #ifndef _SFX
+
+ if (ExtractToStreamCallback)
+ {
+ if (!GetProp)
+ {
+ GetProp_Spec = new CGetProp;
+ GetProp = GetProp_Spec;
+ }
+ GetProp_Spec->Arc = _arc;
+ GetProp_Spec->IndexInArc = index;
+ UString name = MakePathFromParts(pathParts);
+
+ #ifdef SUPPORT_ALT_STREAMS
+ if (_item.IsAltStream)
+ {
+ if (!pathParts.IsEmpty() || (!_removePartsForAltStreams && _pathMode != NExtract::NPathMode::kNoPathsAlt))
+ name += L':';
+ name += _item.AltStreamName;
+ }
+ #endif
+
+ return ExtractToStreamCallback->GetStream7(name, BoolToInt(_item.IsDir), outStream, askExtractMode, GetProp);
+ }
+
+ #endif
+
+ CMyComPtr<ISequentialOutStream> outStreamLoc;
+
+if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
+{
+ if (_stdOutMode)
+ {
+ outStreamLoc = new CStdOutFileStream;
+ }
+ else
+ {
{
NCOM::CPropVariant prop;
RINOK(archive->GetProperty(index, kpidAttrib, &prop));
@@ -219,38 +975,44 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
bool isAnti = false;
RINOK(_arc->IsItemAnti(index, isAnti));
- UStringVector pathParts;
- SplitPathToParts(fullPath, pathParts);
+ #ifdef SUPPORT_ALT_STREAMS
+ if (!_item.IsAltStream
+ || !pathParts.IsEmpty()
+ || !(_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt))
+ #endif
+ Correct_FsPath(_pathMode == NExtract::NPathMode::kAbsPaths, pathParts, _item.MainIsDir);
+
+ #ifdef SUPPORT_ALT_STREAMS
- if (pathParts.IsEmpty())
- return E_FAIL;
- int numRemovePathParts = 0;
- switch(_pathMode)
+ if (_item.IsAltStream)
{
- case NExtract::NPathMode::kFullPathnames:
- break;
- case NExtract::NPathMode::kCurrentPathnames:
- {
- numRemovePathParts = _removePathParts.Size();
- if (pathParts.Size() <= numRemovePathParts)
- return E_FAIL;
- for (int i = 0; i < numRemovePathParts; i++)
- if (_removePathParts[i].CompareNoCase(pathParts[i]) != 0)
- return E_FAIL;
- break;
- }
- case NExtract::NPathMode::kNoPathnames:
+ UString s = _item.AltStreamName;
+ Correct_AltStream_Name(s);
+ bool needColon = true;
+
+ if (pathParts.IsEmpty())
{
- numRemovePathParts = pathParts.Size() - 1;
- break;
+ pathParts.AddNew();
+ if (_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt)
+ needColon = false;
}
+ else if (_pathMode == NExtract::NPathMode::kAbsPaths &&
+ NWildcard::GetNumPrefixParts_if_DrivePath(pathParts) == pathParts.Size())
+ pathParts.AddNew();
+
+ UString &name = pathParts.Back();
+ if (needColon)
+ name += (wchar_t)(_ntOptions.ReplaceColonForAltStream ? L'_' : L':');
+ name += s;
}
- pathParts.Delete(0, numRemovePathParts);
- MakeCorrectPath(pathParts);
- UString processedPath = MakePathNameFromParts(pathParts);
+
+ #endif
+
+ UString processedPath = MakePathFromParts(pathParts);
+
if (!isAnti)
{
- if (!_fi.IsDir)
+ if (!_item.IsDir)
{
if (!pathParts.IsEmpty())
pathParts.DeleteBack();
@@ -260,74 +1022,103 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
{
FString fullPathNew;
CreateComplexDirectory(pathParts, fullPathNew);
- if (_fi.IsDir)
- NFile::NDirectory::SetDirTime(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));
+ }
}
}
- FString fullProcessedPath = _directoryPath + us2fs(processedPath);
+ FString fullProcessedPath = us2fs(processedPath);
+ if (_pathMode != NExtract::NPathMode::kAbsPaths
+ || !NName::IsAbsolutePath(processedPath))
+ {
+ fullProcessedPath = MakePath_from_2_Parts(_dirPathPrefix, fullProcessedPath);
+ }
- if (_fi.IsDir)
+ #ifdef SUPPORT_ALT_STREAMS
+
+ if (_item.IsAltStream && _item.ParentIndex != (UInt32)(Int32)-1)
+ {
+ CIndexToPathPair pair(_item.ParentIndex);
+ int renIndex = _renamedFiles.FindInSorted(pair);
+ if (renIndex >= 0)
+ {
+ const CIndexToPathPair &pair = _renamedFiles[renIndex];
+ fullProcessedPath = pair.Path;
+ fullProcessedPath += (FChar)':';
+ UString s = _item.AltStreamName;
+ Correct_AltStream_Name(s);
+ fullProcessedPath += us2fs(s);
+ }
+ }
+
+ #endif
+
+ bool isRenamed = false;
+
+ if (_item.IsDir)
{
_diskFilePath = fullProcessedPath;
if (isAnti)
- NFile::NDirectory::MyRemoveDirectory(_diskFilePath);
- return S_OK;
+ RemoveDir(_diskFilePath);
+ #ifdef SUPPORT_LINKS
+ if (linkPath.IsEmpty())
+ #endif
+ return S_OK;
}
-
- if (!_isSplit)
+ else if (!_isSplit)
{
- NFile::NFind::CFileInfo fileInfo;
+
+ // ----- Is file (not split) -----
+ NFind::CFileInfo fileInfo;
if (fileInfo.Find(fullProcessedPath))
{
- switch(_overwriteMode)
+ switch (_overwriteMode)
{
- case NExtract::NOverwriteMode::kSkipExisting:
+ case NExtract::NOverwriteMode::kSkip:
return S_OK;
- case NExtract::NOverwriteMode::kAskBefore:
+ case NExtract::NOverwriteMode::kAsk:
{
- Int32 overwiteResult;
+ int slashPos = fullProcessedPath.ReverseFind_PathSepar();
+ FString realFullProcessedPath = fullProcessedPath.Left(slashPos + 1) + fileInfo.Name;
+
+ Int32 overwriteResult;
RINOK(_extractCallback2->AskOverwrite(
- fs2us(fullProcessedPath), &fileInfo.MTime, &fileInfo.Size, fullPath,
+ fs2us(realFullProcessedPath), &fileInfo.MTime, &fileInfo.Size, _item.Path,
_fi.MTimeDefined ? &_fi.MTime : NULL,
_curSizeDefined ? &_curSize : NULL,
- &overwiteResult))
+ &overwriteResult))
- switch(overwiteResult)
+ switch (overwriteResult)
{
- case NOverwriteAnswer::kCancel:
- return E_ABORT;
- case NOverwriteAnswer::kNo:
- return S_OK;
- case NOverwriteAnswer::kNoToAll:
- _overwriteMode = NExtract::NOverwriteMode::kSkipExisting;
- return S_OK;
- case NOverwriteAnswer::kYesToAll:
- _overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
- break;
- case NOverwriteAnswer::kYes:
- break;
- case NOverwriteAnswer::kAutoRename:
- _overwriteMode = NExtract::NOverwriteMode::kAutoRename;
- break;
+ case NOverwriteAnswer::kCancel: return E_ABORT;
+ case NOverwriteAnswer::kNo: return S_OK;
+ case NOverwriteAnswer::kNoToAll: _overwriteMode = NExtract::NOverwriteMode::kSkip; return S_OK;
+ case NOverwriteAnswer::kYes: break;
+ case NOverwriteAnswer::kYesToAll: _overwriteMode = NExtract::NOverwriteMode::kOverwrite; break;
+ case NOverwriteAnswer::kAutoRename: _overwriteMode = NExtract::NOverwriteMode::kRename; break;
default:
return E_FAIL;
}
}
}
- if (_overwriteMode == NExtract::NOverwriteMode::kAutoRename)
+ if (_overwriteMode == NExtract::NOverwriteMode::kRename)
{
if (!AutoRenamePath(fullProcessedPath))
{
RINOK(SendMessageError(kCantAutoRename, fullProcessedPath));
return E_FAIL;
}
+ isRenamed = true;
}
- else if (_overwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting)
+ else if (_overwriteMode == NExtract::NOverwriteMode::kRenameExisting)
{
FString existPath = fullProcessedPath;
if (!AutoRenamePath(existPath))
@@ -335,65 +1126,290 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
RINOK(SendMessageError(kCantAutoRename, fullProcessedPath));
return E_FAIL;
}
- if (!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath))
+ // MyMoveFile can raname folders. So it's OK to use it for folders too
+ if (!MyMoveFile(fullProcessedPath, existPath))
{
- RINOK(SendMessageError(kCantRenameFile, fullProcessedPath));
+ RINOK(SendMessageError2(kCantRenameFile, existPath, fullProcessedPath));
return E_FAIL;
}
}
else
- if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
+ {
+ if (fileInfo.IsDir())
{
- RINOK(SendMessageError(kCantDeleteOutputFile, fullProcessedPath));
- return S_OK;
- // return E_FAIL;
+ // do we need to delete all files in folder?
+ if (!RemoveDir(fullProcessedPath))
+ {
+ RINOK(SendMessageError_with_LastError(kCantDeleteOutputDir, fullProcessedPath));
+ return S_OK;
+ }
}
+ else
+ {
+ bool needDelete = true;
+ if (needDelete)
+ {
+ if (!DeleteFileAlways(fullProcessedPath))
+ {
+ RINOK(SendMessageError_with_LastError(kCantDeleteOutputFile, fullProcessedPath));
+ return S_OK;
+ // return E_FAIL;
+ }
+ }
+ }
+ }
}
+ else // not Find(fullProcessedPath)
+ {
+ // we need to clear READ-ONLY of parent before creating alt stream
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ int colonPos = NName::FindAltStreamColon(fullProcessedPath);
+ if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0)
+ {
+ FString parentFsPath = fullProcessedPath;
+ parentFsPath.DeleteFrom(colonPos);
+ NFind::CFileInfo parentFi;
+ if (parentFi.Find(parentFsPath))
+ {
+ if (parentFi.IsReadOnly())
+ SetFileAttrib(parentFsPath, parentFi.Attrib & ~FILE_ATTRIBUTE_READONLY);
+ }
+ }
+ #endif
+ }
+ // ----- END of code for Is file (not split) -----
+
}
+ _diskFilePath = fullProcessedPath;
+
+
if (!isAnti)
{
- _outFileStreamSpec = new COutFileStream;
- CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
- if (!_outFileStreamSpec->Open(fullProcessedPath, _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS))
+ #ifdef SUPPORT_LINKS
+
+ if (!linkPath.IsEmpty())
{
- // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
+ #ifndef UNDER_CE
+
+ UString relatPath;
+ if (isRelative)
+ relatPath = GetDirPrefixOf(_item.Path);
+ relatPath += linkPath;
+
+ if (!IsSafePath(relatPath))
{
- RINOK(SendMessageError("can not open output file ", fullProcessedPath));
- return S_OK;
+ RINOK(SendMessageError("Dangerous link path was ignored", us2fs(relatPath)));
+ }
+ else
+ {
+ FString existPath;
+ if (isHardLink /* || isCopyLink */ || !isRelative)
+ {
+ if (!NName::GetFullPath(_dirPathPrefix_Full, us2fs(relatPath), existPath))
+ {
+ RINOK(SendMessageError("Incorrect path", us2fs(relatPath)));
+ }
+ }
+ else
+ {
+ existPath = us2fs(linkPath);
+ }
+
+ if (!existPath.IsEmpty())
+ {
+ if (isHardLink /* || isCopyLink */)
+ {
+ // if (isHardLink)
+ {
+ if (!MyCreateHardLink(fullProcessedPath, existPath))
+ {
+ RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, existPath));
+ // return S_OK;
+ }
+ }
+ /*
+ else
+ {
+ NFind::CFileInfo fi;
+ if (!fi.Find(existPath))
+ {
+ RINOK(SendMessageError2("Can not find the file for copying", existPath, fullProcessedPath));
+ }
+ else
+ {
+ if (_curSizeDefined && _curSize == fi.Size)
+ _CopyFile_Path = existPath;
+ else
+ {
+ RINOK(SendMessageError2("File size collision for file copying", existPath, fullProcessedPath));
+ }
+
+ // RINOK(MyCopyFile(existPath, fullProcessedPath));
+ }
+ }
+ */
+ }
+ else if (_ntOptions.SymLinks.Val)
+ {
+ // bool isSymLink = true; // = false for junction
+ if (_item.IsDir && !isRelative)
+ {
+ // if it's before Vista we use Junction Point
+ // isJunction = true;
+ // convertToAbs = true;
+ }
+
+ CByteBuffer data;
+ if (FillLinkData(data, fs2us(existPath), !isJunction))
+ {
+ CReparseAttr attr;
+ if (!attr.Parse(data, data.Size()))
+ {
+ RINOK(SendMessageError("Internal error for symbolic link file", us2fs(_item.Path)));
+ // return E_FAIL;
+ }
+ else
+ if (!NFile::NIO::SetReparseData(fullProcessedPath, _item.IsDir, data, (DWORD)data.Size()))
+ {
+ RINOK(SendMessageError_with_LastError("Can not create symbolic link", fullProcessedPath));
+ }
+ }
+ }
+ }
}
+
+ #endif
}
- if (_isSplit)
+
+ if (linkPath.IsEmpty() /* || !_CopyFile_Path.IsEmpty() */)
+ #endif // SUPPORT_LINKS
{
- RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL));
+ bool needWriteFile = true;
+
+ #ifdef SUPPORT_LINKS
+ if (!_hardLinks.IDs.IsEmpty() && !_item.IsAltStream)
+ {
+ CHardLinkNode h;
+ bool defined;
+ RINOK(Archive_Get_HardLinkNode(archive, index, h, defined));
+ if (defined)
+ {
+ {
+ int linkIndex = _hardLinks.IDs.FindInSorted2(h);
+ if (linkIndex >= 0)
+ {
+ FString &hl = _hardLinks.Links[linkIndex];
+ if (hl.IsEmpty())
+ hl = fullProcessedPath;
+ else
+ {
+ if (!MyCreateHardLink(fullProcessedPath, hl))
+ {
+ RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, hl));
+ return S_OK;
+ }
+ needWriteFile = false;
+ }
+ }
+ }
+ }
+ }
+ #endif
+
+ if (needWriteFile)
+ {
+ _outFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+ if (!_outFileStreamSpec->Open(fullProcessedPath, _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS))
+ {
+ // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
+ {
+ RINOK(SendMessageError_with_LastError("Can not open output file", fullProcessedPath));
+ return S_OK;
+ }
+ }
+
+
+ #ifdef SUPPORT_ALT_STREAMS
+ if (isRenamed && !_item.IsAltStream)
+ {
+ CIndexToPathPair pair(index, fullProcessedPath);
+ unsigned oldSize = _renamedFiles.Size();
+ unsigned insertIndex = _renamedFiles.AddToUniqueSorted(pair);
+ if (oldSize == _renamedFiles.Size())
+ _renamedFiles[insertIndex].Path = fullProcessedPath;
+ }
+ #endif
+
+ if (_isSplit)
+ {
+ RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL));
+ }
+
+ _outFileStream = outStreamLoc;
+ }
}
- _outFileStream = outStreamLoc;
- *outStream = outStreamLoc.Detach();
}
- _diskFilePath = fullProcessedPath;
+
+ outStreamLoc = _outFileStream;
}
- else
+}
+
+ #ifndef _SFX
+
+ if (_hashStream)
{
- *outStream = NULL;
+ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract ||
+ askExtractMode == NArchive::NExtract::NAskMode::kTest)
+ {
+ _hashStreamSpec->SetStream(outStreamLoc);
+ outStreamLoc = _hashStream;
+ _hashStreamSpec->Init(true);
+ _hashStreamWasUsed = true;
+ }
}
- if (_crcMode)
+
+ #endif
+
+
+ if (outStreamLoc)
{
- _crcStreamSpec = new COutStreamWithCRC;
- _crcStream = _crcStreamSpec;
- CMyComPtr<ISequentialOutStream> crcStream = _crcStreamSpec;
- _crcStreamSpec->SetStream(*outStream);
- if (*outStream)
- (*outStream)->Release();
- *outStream = crcStream.Detach();
- _crcStreamSpec->Init(true);
+ /*
+ #ifdef SUPPORT_LINKS
+
+ if (!_CopyFile_Path.IsEmpty())
+ {
+ RINOK(PrepareOperation(askExtractMode));
+ RINOK(MyCopyFile(outStreamLoc));
+ return SetOperationResult(NArchive::NExtract::NOperationResult::kOK);
+ }
+
+ if (isCopyLink && _testMode)
+ return S_OK;
+
+ #endif
+ */
+
+ *outStream = outStreamLoc.Detach();
}
+
return S_OK;
+
COM_TRY_END
}
+
STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
{
COM_TRY_BEGIN
+
+ #ifndef _SFX
+ if (ExtractToStreamCallback)
+ return ExtractToStreamCallback->PrepareOperation7(askExtractMode);
+ #endif
+
_extractMode = false;
+
switch (askExtractMode)
{
case NArchive::NExtract::NAskMode::kExtract:
@@ -403,32 +1419,42 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
_extractMode = true;
break;
};
- return _extractCallback2->PrepareOperation(_filePath, _fi.IsDir,
+
+ return _extractCallback2->PrepareOperation(_item.Path, BoolToInt(_item.IsDir),
askExtractMode, _isSplit ? &_position: 0);
+
COM_TRY_END
}
-STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
+
+STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes)
{
COM_TRY_BEGIN
- switch(operationResult)
- {
- case NArchive::NExtract::NOperationResult::kOK:
- case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
- case NArchive::NExtract::NOperationResult::kCRCError:
- case NArchive::NExtract::NOperationResult::kDataError:
- break;
- default:
- _outFileStream.Release();
- return E_FAIL;
- }
- if (_crcStream)
+
+ #ifndef _SFX
+ if (ExtractToStreamCallback)
+ return ExtractToStreamCallback->SetOperationResult7(opRes, BoolToInt(_encrypted));
+ #endif
+
+ #ifndef _SFX
+
+ if (_hashStreamWasUsed)
{
- CrcSum += _crcStreamSpec->GetCRC();
- _curSize = _crcStreamSpec->GetSize();
+ _hashStreamSpec->_hash->Final(_item.IsDir,
+ #ifdef SUPPORT_ALT_STREAMS
+ _item.IsAltStream
+ #else
+ false
+ #endif
+ , _item.Path);
+ _curSize = _hashStreamSpec->GetSize();
_curSizeDefined = true;
- _crcStream.Release();
+ _hashStreamSpec->ReleaseStream();
+ _hashStreamWasUsed = false;
}
+
+ #endif
+
if (_outFileStream)
{
_outFileStreamSpec->SetTime(
@@ -440,36 +1466,92 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
RINOK(_outFileStreamSpec->Close());
_outFileStream.Release();
}
+
+ #ifdef _USE_SECURITY_CODE
+ if (!_stdOutMode && _extractMode && _ntOptions.NtSecurity.Val && _arc->GetRawProps)
+ {
+ const void *data;
+ UInt32 dataSize;
+ UInt32 propType;
+ _arc->GetRawProps->GetRawProp(_index, kpidNtSecure, &data, &dataSize, &propType);
+ if (dataSize != 0)
+ {
+ if (propType != NPropDataType::kRaw)
+ return E_FAIL;
+ if (CheckNtSecure((const Byte *)data, dataSize))
+ {
+ SECURITY_INFORMATION securInfo = DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION;
+ if (_saclEnabled)
+ securInfo |= SACL_SECURITY_INFORMATION;
+ ::SetFileSecurityW(fs2us(_diskFilePath), securInfo, (PSECURITY_DESCRIPTOR)(void *)data);
+ }
+ }
+ }
+ #endif
+
if (!_curSizeDefined)
GetUnpackSize();
+
if (_curSizeDefined)
- UnpackSize += _curSize;
- if (_fi.IsDir)
+ {
+ #ifdef SUPPORT_ALT_STREAMS
+ if (_item.IsAltStream)
+ AltStreams_UnpackSize += _curSize;
+ else
+ #endif
+ UnpackSize += _curSize;
+ }
+
+ if (_item.IsDir)
NumFolders++;
+ #ifdef SUPPORT_ALT_STREAMS
+ else if (_item.IsAltStream)
+ NumAltStreams++;
+ #endif
else
NumFiles++;
- if (_extractMode && _fi.AttribDefined)
- NFile::NDirectory::MySetFileAttributes(_diskFilePath, _fi.Attrib);
- RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted));
+ if (!_stdOutMode && _extractMode && _fi.AttribDefined)
+ SetFileAttrib(_diskFilePath, _fi.Attrib);
+
+ RINOK(_extractCallback2->SetOperationResult(opRes, BoolToInt(_encrypted)));
+
return S_OK;
+
COM_TRY_END
}
-/*
-STDMETHODIMP CArchiveExtractCallback::GetInStream(
- const wchar_t *name, ISequentialInStream **inStream)
+STDMETHODIMP CArchiveExtractCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)
{
- COM_TRY_BEGIN
- CInFileStream *inFile = new CInFileStream;
- CMyComPtr<ISequentialInStream> inStreamTemp = inFile;
- if (!inFile->Open(_srcDirectoryPrefix + name))
- return ::GetLastError();
- *inStream = inStreamTemp.Detach();
+ if (_folderArchiveExtractCallback2)
+ {
+ bool isEncrypted = false;
+ wchar_t temp[16];
+ UString s2;
+ const wchar_t *s = NULL;
+
+ if (indexType == NArchive::NEventIndexType::kInArcIndex && index != (UInt32)(Int32)-1)
+ {
+ CReadArcItem item;
+ RINOK(_arc->GetItem(index, item));
+ s2 = item.Path;
+ s = s2;
+ RINOK(Archive_GetItemBoolProp(_arc->Archive, index, kpidEncrypted, isEncrypted));
+ }
+ else
+ {
+ temp[0] = '#';
+ ConvertUInt32ToString(index, temp + 1);
+ s = temp;
+ // if (indexType == NArchive::NEventIndexType::kBlockIndex) {}
+ }
+
+ return _folderArchiveExtractCallback2->ReportExtractResult(opRes, isEncrypted, s);
+ }
+
return S_OK;
- COM_TRY_END
}
-*/
+
STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
{
@@ -482,3 +1564,73 @@ STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
return _cryptoGetTextPassword->CryptoGetTextPassword(password);
COM_TRY_END
}
+
+
+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)
+{
+ for (unsigned numSlashes = 0;;)
+ {
+ FChar c = *s++;
+ if (c == 0)
+ return numSlashes;
+ if (IS_PATH_SEPAR(c))
+ numSlashes++;
+ }
+}
+
+HRESULT CArchiveExtractCallback::SetDirsTimes()
+{
+ CRecordVector<CExtrRefSortPair> pairs;
+ pairs.ClearAndSetSize(_extractedFolderPaths.Size());
+ unsigned i;
+
+ for (i = 0; i < _extractedFolderPaths.Size(); i++)
+ {
+ CExtrRefSortPair &pair = pairs[i];
+ pair.Index = i;
+ pair.Len = GetNumSlashes(_extractedFolderPaths[i]);
+ }
+
+ 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));
+ }
+ return S_OK;
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h
index cee7c5b6180..7d4155fe2e7 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h
@@ -3,8 +3,8 @@
#ifndef __ARCHIVE_EXTRACT_CALLBACK_H
#define __ARCHIVE_EXTRACT_CALLBACK_H
-#include "Common/MyCom.h"
-#include "Common/Wildcard.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Common/Wildcard.h"
#include "../../IPassword.h"
@@ -13,30 +13,167 @@
#include "../../Archive/IArchive.h"
-#include "../../Archive/Common/OutStreamWithCRC.h"
-
#include "ExtractMode.h"
#include "IFileExtractCallback.h"
#include "OpenArchive.h"
+#include "HashCalc.h"
+
+#ifndef _SFX
+
+class COutStreamWithHash:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _size;
+ bool _calculate;
+public:
+ IHashCalc *_hash;
+
+ MY_UNKNOWN_IMP
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void ReleaseStream() { _stream.Release(); }
+ void Init(bool calculate = true)
+ {
+ InitCRC();
+ _size = 0;
+ _calculate = calculate;
+ }
+ void EnableCalc(bool calculate) { _calculate = calculate; }
+ void InitCRC() { _hash->InitForNewFile(); }
+ UInt64 GetSize() const { return _size; }
+};
+
+#endif
+
+struct CExtractNtOptions
+{
+ CBoolPair NtSecurity;
+ CBoolPair SymLinks;
+ CBoolPair HardLinks;
+ CBoolPair AltStreams;
+ bool ReplaceColonForAltStream;
+ bool WriteToAltStreamIfColon;
+
+ CExtractNtOptions():
+ ReplaceColonForAltStream(false),
+ WriteToAltStreamIfColon(false)
+ {
+ SymLinks.Val = true;
+ HardLinks.Val = true;
+ AltStreams.Val = true;
+ }
+};
+
+#ifndef _SFX
+
+class CGetProp:
+ public IGetProp,
+ public CMyUnknownImp
+{
+public:
+ const CArc *Arc;
+ UInt32 IndexInArc;
+ // UString Name; // relative path
+
+ MY_UNKNOWN_IMP1(IGetProp)
+ INTERFACE_IGetProp(;)
+};
+
+#endif
+
+#ifndef _SFX
+#ifndef UNDER_CE
+
+#define SUPPORT_LINKS
+
+#endif
+#endif
+
+
+#ifdef SUPPORT_LINKS
+
+struct CHardLinkNode
+{
+ UInt64 StreamId;
+ UInt64 INode;
+
+ int Compare(const CHardLinkNode &a) const;
+};
+
+class CHardLinks
+{
+public:
+ CRecordVector<CHardLinkNode> IDs;
+ CObjectVector<FString> Links;
+
+ void Clear()
+ {
+ IDs.Clear();
+ Links.Clear();
+ }
+
+ void PrepareLinks()
+ {
+ while (Links.Size() < IDs.Size())
+ Links.AddNew();
+ }
+};
+
+#endif
+
+#ifdef SUPPORT_ALT_STREAMS
+
+struct CIndexToPathPair
+{
+ UInt32 Index;
+ FString Path;
+
+ CIndexToPathPair(UInt32 index): Index(index) {}
+ CIndexToPathPair(UInt32 index, const FString &path): Index(index), Path(path) {}
+
+ int Compare(const CIndexToPathPair &pair) const
+ {
+ return MyCompare(Index, pair.Index);
+ }
+};
+
+#endif
+
class CArchiveExtractCallback:
public IArchiveExtractCallback,
- // public IArchiveVolumeExtractCallback,
+ public IArchiveExtractCallbackMessage,
public ICryptoGetTextPassword,
public ICompressProgressInfo,
public CMyUnknownImp
{
const CArc *_arc;
- const NWildcard::CCensorNode *_wildcardCensor;
+ CExtractNtOptions _ntOptions;
+
+ const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin)
CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
CMyComPtr<ICompressProgressInfo> _compressProgress;
CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
- FString _directoryPath;
+ CMyComPtr<IArchiveExtractCallbackMessage> _callbackMessage;
+ CMyComPtr<IFolderArchiveExtractCallback2> _folderArchiveExtractCallback2;
+
+ FString _dirPathPrefix;
+ FString _dirPathPrefix_Full;
NExtract::NPathMode::EEnum _pathMode;
NExtract::NOverwriteMode::EEnum _overwriteMode;
+ #ifndef _SFX
+
+ CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
+ CGetProp *GetProp_Spec;
+ CMyComPtr<IGetProp> GetProp;
+
+ #endif
+
+ CReadArcItem _item;
FString _diskFilePath;
- UString _filePath;
UInt64 _position;
bool _isSplit;
@@ -59,8 +196,6 @@ class CArchiveExtractCallback:
bool ATimeDefined;
bool MTimeDefined;
bool AttribDefined;
-
- bool IsDir;
} _fi;
UInt32 _index;
@@ -69,25 +204,46 @@ class CArchiveExtractCallback:
COutFileStream *_outFileStreamSpec;
CMyComPtr<ISequentialOutStream> _outFileStream;
- COutStreamWithCRC *_crcStreamSpec;
- CMyComPtr<ISequentialOutStream> _crcStream;
+ #ifndef _SFX
+
+ COutStreamWithHash *_hashStreamSpec;
+ CMyComPtr<ISequentialOutStream> _hashStream;
+ bool _hashStreamWasUsed;
+
+ #endif
+ bool _removePartsForAltStreams;
UStringVector _removePathParts;
+
+ #ifndef _SFX
+ bool _use_baseParentFolder_mode;
+ UInt32 _baseParentFolder;
+ #endif
bool _stdOutMode;
bool _testMode;
- bool _crcMode;
bool _multiArchives;
CMyComPtr<ICompressProgressInfo> _localProgress;
UInt64 _packTotal;
- UInt64 _unpTotal;
+
+ UInt64 _progressTotal;
+ bool _progressTotal_Defined;
+
+ FStringVector _extractedFolderPaths;
+ CRecordVector<UInt32> _extractedFolderIndices;
+
+ #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 GetUnpackSize();
HRESULT SendMessageError(const char *message, const FString &path);
+ HRESULT SendMessageError_with_LastError(const char *message, const FString &path);
+ HRESULT SendMessageError2(const char *message, const FString &path1, const FString &path2);
public:
@@ -95,30 +251,20 @@ public:
UInt64 NumFolders;
UInt64 NumFiles;
+ UInt64 NumAltStreams;
UInt64 UnpackSize;
- UInt32 CrcSum;
+ UInt64 AltStreams_UnpackSize;
- MY_UNKNOWN_IMP2(ICryptoGetTextPassword, ICompressProgressInfo)
- // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)
+ MY_UNKNOWN_IMP3(IArchiveExtractCallbackMessage, ICryptoGetTextPassword, ICompressProgressInfo)
INTERFACE_IArchiveExtractCallback(;)
+ INTERFACE_IArchiveExtractCallbackMessage(;)
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
- // IArchiveVolumeExtractCallback
- // STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream);
-
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
- CArchiveExtractCallback():
- WriteCTime(true),
- WriteATime(true),
- WriteMTime(true),
- _multiArchives(false)
- {
- LocalProgressSpec = new CLocalProgress();
- _localProgress = LocalProgressSpec;
- }
+ CArchiveExtractCallback();
void InitForMulti(bool multiArchives,
NExtract::NPathMode::EEnum pathMode,
@@ -127,19 +273,66 @@ public:
_multiArchives = multiArchives;
_pathMode = pathMode;
_overwriteMode = overwriteMode;
- NumFolders = NumFiles = UnpackSize = 0;
- CrcSum = 0;
+ NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0;
+ }
+
+ #ifndef _SFX
+
+ void SetHashMethods(IHashCalc *hash)
+ {
+ if (!hash)
+ return;
+ _hashStreamSpec = new COutStreamWithHash;
+ _hashStream = _hashStreamSpec;
+ _hashStreamSpec->_hash = hash;
}
+ #endif
+
void Init(
+ const CExtractNtOptions &ntOptions,
const NWildcard::CCensorNode *wildcardCensor,
const CArc *arc,
IFolderArchiveExtractCallback *extractCallback2,
- bool stdOutMode, bool testMode, bool crcMode,
+ bool stdOutMode, bool testMode,
const FString &directoryPath,
- const UStringVector &removePathParts,
+ const UStringVector &removePathParts, bool removePartsForAltStreams,
UInt64 packSize);
+
+ #ifdef SUPPORT_LINKS
+
+private:
+ CHardLinks _hardLinks;
+ UString linkPath;
+
+ // FString _CopyFile_Path;
+ // HRESULT MyCopyFile(ISequentialOutStream *outStream);
+
+public:
+ // call PrepareHardLinks() after Init()
+ HRESULT PrepareHardLinks(const CRecordVector<UInt32> *realIndices); // NULL means all items
+
+ #endif
+
+
+ #ifdef SUPPORT_ALT_STREAMS
+ CObjectVector<CIndexToPathPair> _renamedFiles;
+ #endif
+
+ // call it after Init()
+
+ #ifndef _SFX
+ void SetBaseParentFolderIndex(UInt32 indexInArc)
+ {
+ _baseParentFolder = indexInArc;
+ _use_baseParentFolder_mode = true;
+ }
+ #endif
+
+ HRESULT SetDirsTimes();
};
+bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
+
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.cpp
index 17947dcef43..06d2ab80895 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.cpp
@@ -2,53 +2,77 @@
#include "StdAfx.h"
-#include "Windows/FileDir.h"
-#include "Windows/FileFind.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileName.h"
#include "ExtractingFilePath.h"
+#include "ArchiveName.h"
using namespace NWindows;
+using namespace NFile;
-static FString CreateArchiveName2(const FString &srcName, bool fromPrev, bool keepName)
+UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
+{
+ FString resultName = fi.Name;
+ if (!fi.IsDir() && !keepName)
+ {
+ int dotPos = resultName.ReverseFind_Dot();
+ if (dotPos > 0)
+ {
+ FString archiveName2 = resultName.Left(dotPos);
+ if (archiveName2.ReverseFind_Dot() < 0)
+ resultName = archiveName2;
+ }
+ }
+ return Get_Correct_FsFile_Name(fs2us(resultName));
+}
+
+static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepName)
{
FString resultName = FTEXT("Archive");
if (fromPrev)
{
FString dirPrefix;
- if (NFile::NDirectory::GetOnlyDirPrefix(srcName, dirPrefix))
+ if (NDir::GetOnlyDirPrefix(path, dirPrefix))
{
- if (dirPrefix.Length() > 0)
- if (dirPrefix.Back() == FCHAR_PATH_SEPARATOR)
+ if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back()))
+ {
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (NName::IsDriveRootPath_SuperAllowed(dirPrefix))
+ resultName = dirPrefix[dirPrefix.Len() - 3]; // only letter
+ else
+ #endif
{
dirPrefix.DeleteBack();
- NFile::NFind::CFileInfo fileInfo;
- if (fileInfo.Find(dirPrefix))
- resultName = fileInfo.Name;
+ NFind::CFileInfo fi;
+ if (fi.Find(dirPrefix))
+ resultName = fi.Name;
}
+ }
}
}
else
{
- NFile::NFind::CFileInfo fileInfo;
- if (!fileInfo.Find(srcName))
- // return resultName;
- return srcName;
- resultName = fileInfo.Name;
- if (!fileInfo.IsDir() && !keepName)
+ NFind::CFileInfo fi;
+ if (fi.Find(path))
{
- int dotPos = resultName.ReverseFind('.');
- if (dotPos > 0)
+ resultName = fi.Name;
+ if (!fi.IsDir() && !keepName)
{
- FString archiveName2 = resultName.Left(dotPos);
- if (archiveName2.ReverseFind(FTEXT('.')) < 0)
- resultName = archiveName2;
+ int dotPos = resultName.ReverseFind_Dot();
+ if (dotPos > 0)
+ {
+ FString name2 = resultName.Left(dotPos);
+ if (name2.ReverseFind_Dot() < 0)
+ resultName = name2;
+ }
}
}
}
return resultName;
}
-UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)
+UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName)
{
- return GetCorrectFsPath(fs2us(CreateArchiveName2(us2fs(srcName), fromPrev, keepName)));
+ return Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(path), fromPrev, keepName)));
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.h b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.h
index 9513fb2ba8b..ec2f1e8d1d9 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.h
@@ -1,10 +1,13 @@
// ArchiveName.h
-#ifndef __ARCHIVENAME_H
-#define __ARCHIVENAME_H
+#ifndef __ARCHIVE_NAME_H
+#define __ARCHIVE_NAME_H
-#include "Common/MyString.h"
+#include "../../../Common/MyString.h"
-UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName);
+#include "../../../Windows/FileFind.h"
+
+UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName);
+UString CreateArchiveName(const NWindows::NFile::NFind::CFileInfo &fileInfo, bool keepName);
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
index be20940c033..359835d3c2c 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
@@ -2,9 +2,10 @@
#include "StdAfx.h"
-#include "Common/ComTry.h"
+#include "../../../Common/ComTry.h"
-#include "Windows/PropVariant.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/PropVariant.h"
#include "../../Common/FileStreams.h"
@@ -39,12 +40,12 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
COM_TRY_BEGIN
NCOM::CPropVariant prop;
if (_subArchiveMode)
- switch(propID)
+ switch (propID)
{
case kpidName: prop = _subArchiveName; break;
}
else
- switch(propID)
+ switch (propID)
{
case kpidName: prop = _fileInfo.Name; break;
case kpidIsDir: prop = _fileInfo.IsDir(); break;
@@ -59,41 +60,54 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
COM_TRY_END
}
-int COpenCallbackImp::FindName(const UString &name)
-{
- for (int i = 0; i < FileNames.Size(); i++)
- if (name.CompareNoCase(FileNames[i]) == 0)
- return i;
- return -1;
-}
-
struct CInFileStreamVol: public CInFileStream
{
- UString Name;
+ int FileNameIndex;
COpenCallbackImp *OpenCallbackImp;
CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
+
~CInFileStreamVol()
{
if (OpenCallbackRef)
- {
- int index = OpenCallbackImp->FindName(Name);
- if (index >= 0)
- OpenCallbackImp->FileNames.Delete(index);
- }
+ OpenCallbackImp->FileNames_WasUsed[FileNameIndex] = false;
}
};
+
+// from ArchiveExtractCallback.cpp
+bool IsSafePath(const UString &path);
+
STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)
{
COM_TRY_BEGIN
+ *inStream = NULL;
+
if (_subArchiveMode)
return S_FALSE;
if (Callback)
{
RINOK(Callback->Open_CheckBreak());
}
- *inStream = NULL;
- FString fullPath = _folderPrefix + us2fs(name);
+
+ UString name2 = name;
+
+
+ #ifndef _SFX
+
+ #ifdef _WIN32
+ name2.Replace(L'/', WCHAR_PATH_SEPARATOR);
+ #endif
+
+ // if (!allowAbsVolPaths)
+ if (!IsSafePath(name2))
+ return S_FALSE;
+
+ #endif
+
+
+ FString fullPath;
+ if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name2), fullPath))
+ return S_FALSE;
if (!_fileInfo.Find(fullPath))
return S_FALSE;
if (_fileInfo.IsDir())
@@ -101,13 +115,20 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre
CInFileStreamVol *inFile = new CInFileStreamVol;
CMyComPtr<IInStream> inStreamTemp = inFile;
if (!inFile->Open(fullPath))
- return ::GetLastError();
- *inStream = inStreamTemp.Detach();
- inFile->Name = name;
+ {
+ DWORD lastError = ::GetLastError();
+ if (lastError == 0)
+ return E_FAIL;
+ return HRESULT_FROM_WIN32(lastError);
+ }
+
+ FileSizes.Add(_fileInfo.Size);
+ FileNames.Add(name2);
+ inFile->FileNameIndex = FileNames_WasUsed.Add(true);
inFile->OpenCallbackImp = this;
inFile->OpenCallbackRef = this;
- FileNames.Add(name);
- TotalSize += _fileInfo.Size;
+ // TotalSize += _fileInfo.Size;
+ *inStream = inStreamTemp.Detach();
return S_OK;
COM_TRY_END
}
@@ -125,6 +146,7 @@ STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
}
if (!Callback)
return E_NOTIMPL;
+ PasswordWasAsked = true;
return Callback->Open_CryptoGetTextPassword(password);
COM_TRY_END
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h
index afada4a6352..e9575f56123 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h
@@ -3,10 +3,9 @@
#ifndef __ARCHIVE_OPEN_CALLBACK_H
#define __ARCHIVE_OPEN_CALLBACK_H
-#include "Common/MyCom.h"
-#include "Common/MyString.h"
+#include "../../../Common/MyCom.h"
-#include "Windows/FileFind.h"
+#include "../../../Windows/FileFind.h"
#ifndef _NO_CRYPTO
#include "../../IPassword.h"
@@ -21,9 +20,9 @@
#define INTERFACE_IOpenCallbackUI_Crypto(x) \
virtual HRESULT Open_CryptoGetTextPassword(BSTR *password) x; \
- virtual HRESULT Open_GetPasswordIfAny(UString &password) x; \
- virtual bool Open_WasPasswordAsked() x; \
- virtual void Open_ClearPasswordWasAskedFlag() x; \
+ /* virtual HRESULT Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) x; */ \
+ /* virtual bool Open_WasPasswordAsked() x; */ \
+ /* virtual void Open_Clear_PasswordWasAsked_Flag() x; */ \
#endif
@@ -31,6 +30,7 @@
virtual HRESULT Open_CheckBreak() x; \
virtual HRESULT Open_SetTotal(const UInt64 *files, const UInt64 *bytes) x; \
virtual HRESULT Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) x; \
+ virtual HRESULT Open_Finished() x; \
INTERFACE_IOpenCallbackUI_Crypto(x)
struct IOpenCallbackUI
@@ -48,18 +48,13 @@ class COpenCallbackImp:
public CMyUnknownImp
{
public:
+ MY_QUERYINTERFACE_BEGIN2(IArchiveOpenVolumeCallback)
+ MY_QUERYINTERFACE_ENTRY(IArchiveOpenSetSubArchiveName)
#ifndef _NO_CRYPTO
- MY_UNKNOWN_IMP3(
- IArchiveOpenVolumeCallback,
- ICryptoGetTextPassword,
- IArchiveOpenSetSubArchiveName
- )
- #else
- MY_UNKNOWN_IMP2(
- IArchiveOpenVolumeCallback,
- IArchiveOpenSetSubArchiveName
- )
+ MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword)
#endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
INTERFACE_IArchiveOpenCallback(;)
INTERFACE_IArchiveOpenVolumeCallback(;)
@@ -72,8 +67,8 @@ public:
{
_subArchiveMode = true;
_subArchiveName = name;
- TotalSize = 0;
- return S_OK;
+ // TotalSize = 0;
+ return S_OK;
}
private:
@@ -81,23 +76,37 @@ private:
NWindows::NFile::NFind::CFileInfo _fileInfo;
bool _subArchiveMode;
UString _subArchiveName;
+
public:
UStringVector FileNames;
+ CBoolVector FileNames_WasUsed;
+ CRecordVector<UInt64> FileSizes;
+
+ bool PasswordWasAsked;
+
IOpenCallbackUI *Callback;
CMyComPtr<IArchiveOpenCallback> ReOpenCallback;
- UInt64 TotalSize;
+ // UInt64 TotalSize;
- COpenCallbackImp(): Callback(NULL) {}
+ COpenCallbackImp(): Callback(NULL), _subArchiveMode(false) {}
+
void Init(const FString &folderPrefix, const FString &fileName)
{
_folderPrefix = folderPrefix;
if (!_fileInfo.Find(_folderPrefix + fileName))
- throw 1;
+ throw 20121118;
FileNames.Clear();
+ FileNames_WasUsed.Clear();
+ FileSizes.Clear();
_subArchiveMode = false;
- TotalSize = 0;
+ // TotalSize = 0;
+ PasswordWasAsked = false;
+ }
+
+ bool SetSecondFileInfo(CFSTR newName)
+ {
+ return _fileInfo.Find(newName) && !_fileInfo.IsDir();
}
- int FindName(const UString &name);
};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp
index 5adfcc20552..fb69b544414 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include <stdio.h>
+
#ifndef _WIN32
#define USE_POSIX_TIME
#define USE_POSIX_TIME2
@@ -28,39 +30,65 @@
#include "../../../../C/7zCrc.h"
#include "../../../../C/Alloc.h"
+#include "../../../../C/CpuArch.h"
-#if !defined(_7ZIP_ST) || defined(_WIN32)
#include "../../../Windows/System.h"
-#endif
#ifndef _7ZIP_ST
#include "../../../Windows/Synchronization.h"
#include "../../../Windows/Thread.h"
#endif
+#if defined(_WIN32) || defined(UNIX_USE_WIN_FILE)
+#define USE_WIN_FILE
+#endif
+
+#ifdef USE_WIN_FILE
+#include "../../../Windows/FileIO.h"
+#endif
+
+
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
#include "../../Common/MethodProps.h"
+#include "../../Common/StreamUtils.h"
#include "Bench.h"
using namespace NWindows;
-static const UInt64 kUncompressMinBlockSize =
-#ifdef UNDER_CE
-(UInt64)1 << 30;
-#else
-(UInt64)1 << 33;
-#endif
+static const UInt32 k_LZMA = 0x030101;
-static const UInt32 kCrcBlockSize =
-#ifdef UNDER_CE
-1 << 25;
-#else
-1 << 30;
-#endif
+static const UInt64 kComplexInCommands = (UInt64)1 <<
+ #ifdef UNDER_CE
+ 31;
+ #else
+ 34;
+ #endif
+
+static const UInt32 kComplexInSeconds = 4;
+
+static void SetComplexCommands(UInt32 complexInSeconds,
+ bool isSpecifiedFreq, UInt64 cpuFreq, UInt64 &complexInCommands)
+{
+ complexInCommands = kComplexInCommands;
+ const UInt64 kMinFreq = (UInt64)1000000 * 4;
+ const UInt64 kMaxFreq = (UInt64)1000000 * 20000;
+ if (cpuFreq < kMinFreq && !isSpecifiedFreq)
+ cpuFreq = kMinFreq;
+ if (cpuFreq < kMaxFreq || isSpecifiedFreq)
+ {
+ if (complexInSeconds != 0)
+ complexInCommands = complexInSeconds * cpuFreq;
+ else
+ complexInCommands = cpuFreq >> 2;
+ }
+}
+
+static const unsigned kNumHashDictBits = 17;
+static const UInt32 kFilterUnpackSize = (48 << 10);
static const unsigned kOldLzmaDictBits = 30;
@@ -83,79 +111,154 @@ public:
}
};
-class CBenchBuffer
+
+static const unsigned kBufferAlignment = 1 << 4;
+
+struct CBenchBuffer
{
-public:
size_t BufferSize;
+
+ #ifdef _WIN32
+
Byte *Buffer;
- CBenchBuffer(): Buffer(0) {}
- virtual ~CBenchBuffer() { Free(); }
- void Free()
+
+ CBenchBuffer(): BufferSize(0), Buffer(NULL) {}
+ ~CBenchBuffer() { ::MidFree(Buffer); }
+
+ void AllocAlignedMask(size_t size, size_t)
{
::MidFree(Buffer);
- Buffer = 0;
+ BufferSize = 0;
+ Buffer = (Byte *)::MidAlloc(size);
+ if (Buffer)
+ BufferSize = size;
}
- bool Alloc(size_t bufferSize)
+
+ #else
+
+ Byte *Buffer;
+ Byte *_bufBase;
+
+ CBenchBuffer(): BufferSize(0), Buffer(NULL), _bufBase(NULL){}
+ ~CBenchBuffer() { ::MidFree(_bufBase); }
+
+ void AllocAlignedMask(size_t size, size_t alignMask)
{
- if (Buffer != 0 && BufferSize == bufferSize)
+ ::MidFree(_bufBase);
+ Buffer = NULL;
+ BufferSize = 0;
+ _bufBase = (Byte *)::MidAlloc(size + alignMask);
+
+ if (_bufBase)
+ {
+ // Buffer = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask);
+ Buffer = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask);
+ BufferSize = size;
+ }
+ }
+
+ #endif
+
+ bool Alloc(size_t size)
+ {
+ if (Buffer && BufferSize == size)
return true;
- Free();
- Buffer = (Byte *)::MidAlloc(bufferSize);
- BufferSize = bufferSize;
- return (Buffer != 0);
+ AllocAlignedMask(size, kBufferAlignment - 1);
+ return (Buffer != NULL || size == 0);
}
};
+
class CBenchRandomGenerator: public CBenchBuffer
{
- CBaseRandomGenerator *RG;
-public:
- void Set(CBaseRandomGenerator *rg) { RG = rg; }
- UInt32 GetVal(UInt32 &res, unsigned numBits)
+ static UInt32 GetVal(UInt32 &res, unsigned numBits)
{
UInt32 val = res & (((UInt32)1 << numBits) - 1);
res >>= numBits;
return val;
}
- UInt32 GetLen(UInt32 &res)
+
+ static UInt32 GetLen(UInt32 &r)
{
- UInt32 len = GetVal(res, 2);
- return GetVal(res, 1 + len);
+ UInt32 len = GetVal(r, 2);
+ return GetVal(r, 1 + len);
}
- void Generate(unsigned dictBits)
+
+public:
+
+ void GenerateSimpleRandom(CBaseRandomGenerator *_RG_)
+ {
+ CBaseRandomGenerator rg = *_RG_;
+ const size_t bufSize = BufferSize;
+ Byte *buf = Buffer;
+ for (size_t i = 0; i < bufSize; i++)
+ buf[i] = (Byte)rg.GetRnd();
+ *_RG_ = rg;
+ }
+
+ void GenerateLz(unsigned dictBits, CBaseRandomGenerator *_RG_)
{
+ CBaseRandomGenerator rg = *_RG_;
UInt32 pos = 0;
UInt32 rep0 = 1;
- while (pos < BufferSize)
+ const size_t bufSize = BufferSize;
+ Byte *buf = Buffer;
+ unsigned posBits = 1;
+
+ while (pos < bufSize)
{
- UInt32 res = RG->GetRnd();
- res >>= 1;
- if (GetVal(res, 1) == 0 || pos < 1024)
- Buffer[pos++] = (Byte)(res & 0xFF);
+ UInt32 r = rg.GetRnd();
+ if (GetVal(r, 1) == 0 || pos < 1024)
+ buf[pos++] = (Byte)(r & 0xFF);
else
{
UInt32 len;
- len = 1 + GetLen(res);
- if (GetVal(res, 3) != 0)
+ len = 1 + GetLen(r);
+
+ if (GetVal(r, 3) != 0)
{
- len += GetLen(res);
- do
+ len += GetLen(r);
+
+ while (((UInt32)1 << posBits) < pos)
+ posBits++;
+
+ unsigned numBitsMax = dictBits;
+ if (numBitsMax > posBits)
+ numBitsMax = posBits;
+
+ const unsigned kAddBits = 6;
+ unsigned numLogBits = 5;
+ if (numBitsMax <= (1 << 4) - 1 + kAddBits)
+ numLogBits = 4;
+
+ for (;;)
{
- UInt32 ppp = GetVal(res, 5) + 6;
- res = RG->GetRnd();
- if (ppp > dictBits)
+ UInt32 ppp = GetVal(r, numLogBits) + kAddBits;
+ r = rg.GetRnd();
+ if (ppp > numBitsMax)
continue;
- rep0 = /* (1 << ppp) +*/ GetVal(res, ppp);
- res = RG->GetRnd();
+ rep0 = GetVal(r, ppp);
+ if (rep0 < pos)
+ break;
+ r = rg.GetRnd();
}
- while (rep0 >= pos);
rep0++;
}
- for (UInt32 i = 0; i < len && pos < BufferSize; i++, pos++)
- Buffer[pos] = Buffer[pos - rep0];
+ {
+ UInt32 rem = (UInt32)bufSize - pos;
+ if (len > rem)
+ len = rem;
+ }
+ Byte *dest = buf + pos;
+ const Byte *src = dest - rep0;
+ pos += len;
+ for (UInt32 i = 0; i < len; i++)
+ *dest++ = *src++;
}
}
+
+ *_RG_ = rg;
}
};
@@ -189,7 +292,7 @@ STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processed
for (UInt32 i = 0; i < size; i++)
((Byte *)data)[i] = Data[Pos + i];
Pos += size;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = size;
return S_OK;
}
@@ -201,13 +304,23 @@ class CBenchmarkOutStream:
{
// bool _overflow;
public:
- UInt32 Pos;
+ size_t Pos;
+ bool RealCopy;
+ bool CalcCrc;
+ UInt32 Crc;
+
// CBenchmarkOutStream(): _overflow(false) {}
- void Init()
+ void Init(bool realCopy, bool calcCrc)
{
+ Crc = CRC_INIT_VAL;
+ RealCopy = realCopy;
+ CalcCrc = calcCrc;
// _overflow = false;
Pos = 0;
}
+
+ // void Print() { printf("\n%8d %8d\n", (unsigned)BufferSize, (unsigned)Pos); }
+
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
@@ -217,9 +330,15 @@ STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *p
size_t curSize = BufferSize - Pos;
if (curSize > size)
curSize = size;
- memcpy(Buffer + Pos, data, curSize);
- Pos += (UInt32)curSize;
- if(processedSize != NULL)
+ if (curSize != 0)
+ {
+ if (RealCopy)
+ memcpy(Buffer + Pos, data, curSize);
+ if (CalcCrc)
+ Crc = CrcUpdate(Crc, data, curSize);
+ Pos += curSize;
+ }
+ if (processedSize)
*processedSize = (UInt32)curSize;
if (curSize != size)
{
@@ -234,16 +353,20 @@ class CCrcOutStream:
public CMyUnknownImp
{
public:
+ bool CalcCrc;
UInt32 Crc;
MY_UNKNOWN_IMP
+
+ CCrcOutStream(): CalcCrc(true) {};
void Init() { Crc = CRC_INIT_VAL; }
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- Crc = CrcUpdate(Crc, data, size);
- if (processedSize != NULL)
+ if (CalcCrc)
+ Crc = CrcUpdate(Crc, data, size);
+ if (processedSize)
*processedSize = size;
return S_OK;
}
@@ -369,25 +492,16 @@ public:
}
};
-class CBenchProgressInfo:
- public ICompressProgressInfo,
- public CMyUnknownImp
+struct CBenchInfoCalc
{
-public:
- CBenchProgressStatus *Status;
CBenchInfo BenchInfo;
CUserTime UserTime;
- HRESULT Res;
- IBenchCallback *Callback;
- CBenchProgressInfo(): Callback(0) {}
void SetStartTime();
void SetFinishTime(CBenchInfo &dest);
- MY_UNKNOWN_IMP
- STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
-void CBenchProgressInfo::SetStartTime()
+void CBenchInfoCalc::SetStartTime()
{
BenchInfo.GlobalFreq = GetFreq();
BenchInfo.UserFreq = GetUserFreq();
@@ -396,13 +510,28 @@ void CBenchProgressInfo::SetStartTime()
UserTime.Init();
}
-void CBenchProgressInfo::SetFinishTime(CBenchInfo &dest)
+void CBenchInfoCalc::SetFinishTime(CBenchInfo &dest)
{
dest = BenchInfo;
dest.GlobalTime = ::GetTimeCount() - BenchInfo.GlobalTime;
dest.UserTime = UserTime.GetUserTime();
}
+class CBenchProgressInfo:
+ public ICompressProgressInfo,
+ public CMyUnknownImp,
+ public CBenchInfoCalc
+{
+public:
+ CBenchProgressStatus *Status;
+ HRESULT Res;
+ IBenchCallback *Callback;
+
+ CBenchProgressInfo(): Callback(0) {}
+ MY_UNKNOWN_IMP
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
{
HRESULT res = Status->GetResult();
@@ -414,8 +543,8 @@ STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64
SetFinishTime(info);
if (Status->EncodeMode)
{
- info.UnpackSize = *inSize;
- info.PackSize = *outSize;
+ info.UnpackSize = BenchInfo.UnpackSize + *inSize;
+ info.PackSize = BenchInfo.PackSize + *outSize;
res = Callback->SetEncodeResult(info, false);
}
else
@@ -429,11 +558,11 @@ STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64
return res;
}
-static const int kSubBits = 8;
+static const unsigned kSubBits = 8;
static UInt32 GetLogSize(UInt32 size)
{
- for (int i = kSubBits; i < 32; i++)
+ for (unsigned i = kSubBits; i < 32; i++)
for (UInt32 j = 0; j < (1 << kSubBits); j++)
if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))
return (i << kSubBits) + j;
@@ -488,6 +617,11 @@ static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
return value * freq / elTime;
}
+UInt64 CBenchInfo::GetSpeed(UInt64 numCommands) const
+{
+ return MyMultDiv64(numCommands, GlobalTime, GlobalFreq);
+}
+
struct CBenchProps
{
bool LzmaRatingMode;
@@ -499,19 +633,25 @@ struct CBenchProps
CBenchProps(): LzmaRatingMode(false) {}
void SetLzmaCompexity();
+ UInt64 GeComprCommands(UInt64 unpackSize)
+ {
+ return unpackSize * EncComplex;
+ }
+
UInt64 GeDecomprCommands(UInt64 packSize, UInt64 unpackSize)
{
return (packSize * DecComplexCompr + unpackSize * DecComplexUnc);
}
UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
- UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations);
+ UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations);
};
void CBenchProps::SetLzmaCompexity()
{
+ EncComplex = 1200;
DecComplexUnc = 4;
- DecComplexCompr = 200;
+ DecComplexCompr = 190;
LzmaRatingMode = true;
}
@@ -529,7 +669,7 @@ UInt64 CBenchProps::GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt6
return MyMultDiv64(numCommands, elapsedTime, freq);
}
-UInt64 CBenchProps::GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations)
+UInt64 CBenchProps::GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations)
{
UInt64 numCommands = (inSize * DecComplexCompr + outSize * DecComplexUnc) * numIterations;
return MyMultDiv64(numCommands, elapsedTime, freq);
@@ -542,7 +682,7 @@ UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt6
return props.GetCompressRating(dictSize, elapsedTime, freq, size);
}
-UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations)
+UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations)
{
CBenchProps props;
props.SetLzmaCompexity();
@@ -557,67 +697,103 @@ struct CEncoderInfo
NWindows::CThread thread[2];
UInt32 NumDecoderSubThreads;
#endif
- CMyComPtr<ICompressCoder> encoder;
+ CMyComPtr<ICompressCoder> _encoder;
+ CMyComPtr<ICompressFilter> _encoderFilter;
CBenchProgressInfo *progressInfoSpec[2];
CMyComPtr<ICompressProgressInfo> progressInfo[2];
- UInt32 NumIterations;
+ UInt64 NumIterations;
+
#ifdef USE_ALLOCA
size_t AllocaSize;
#endif
+ Byte _key[32];
+ Byte _iv[16];
+ Byte _psw[16];
+ bool CheckCrc_Enc;
+ bool CheckCrc_Dec;
+
struct CDecoderInfo
{
CEncoderInfo *Encoder;
UInt32 DecoderIndex;
+ bool CallbackMode;
+
#ifdef USE_ALLOCA
size_t AllocaSize;
#endif
- bool CallbackMode;
};
CDecoderInfo decodersInfo[2];
- CMyComPtr<ICompressCoder> decoders[2];
+ CMyComPtr<ICompressCoder> _decoders[2];
+ CMyComPtr<ICompressFilter> _decoderFilter;
+
HRESULT Results[2];
CBenchmarkOutStream *outStreamSpec;
CMyComPtr<ISequentialOutStream> outStream;
IBenchCallback *callback;
IBenchPrintCallback *printCallback;
UInt32 crc;
- UInt32 kBufferSize;
- UInt32 compressedSize;
+ size_t kBufferSize;
+ size_t compressedSize;
+ const Byte *uncompressedDataPtr;
+
+ const Byte *fileData;
CBenchRandomGenerator rg;
+
+ CBenchBuffer rgCopy; // it must be 16-byte aligned !!!
CBenchmarkOutStream *propStreamSpec;
CMyComPtr<ISequentialOutStream> propStream;
+
+ // for decode
+ COneMethodInfo _method;
+ size_t _uncompressedDataSize;
+
HRESULT Init(
const COneMethodInfo &method,
- UInt32 uncompressedDataSize,
unsigned generateDictBits,
CBaseRandomGenerator *rg);
HRESULT Encode();
HRESULT Decode(UInt32 decoderIndex);
- CEncoderInfo(): outStreamSpec(0), callback(0), printCallback(0), propStreamSpec(0) {}
+ CEncoderInfo():
+ fileData(NULL),
+ CheckCrc_Enc(true),
+ CheckCrc_Dec(true),
+ outStreamSpec(0), callback(0), printCallback(0), propStreamSpec(0) {}
#ifndef _7ZIP_ST
+
static THREAD_FUNC_DECL EncodeThreadFunction(void *param)
{
+ HRESULT res;
CEncoderInfo *encoder = (CEncoderInfo *)param;
- #ifdef USE_ALLOCA
- alloca(encoder->AllocaSize);
- #endif
- HRESULT res = encoder->Encode();
- encoder->Results[0] = res;
+ try
+ {
+ #ifdef USE_ALLOCA
+ alloca(encoder->AllocaSize);
+ #endif
+
+ res = encoder->Encode();
+ encoder->Results[0] = res;
+ }
+ catch(...)
+ {
+ res = E_FAIL;
+ }
if (res != S_OK)
encoder->progressInfoSpec[0]->Status->SetResult(res);
-
return 0;
}
+
static THREAD_FUNC_DECL DecodeThreadFunction(void *param)
{
CDecoderInfo *decoder = (CDecoderInfo *)param;
+
#ifdef USE_ALLOCA
alloca(decoder->AllocaSize);
#endif
+
CEncoderInfo *encoder = decoder->Encoder;
encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex);
return 0;
@@ -628,7 +804,7 @@ struct CEncoderInfo
return thread[0].Create(EncodeThreadFunction, this);
}
- HRESULT CreateDecoderThread(int index, bool callbackMode
+ HRESULT CreateDecoderThread(unsigned index, bool callbackMode
#ifdef USE_ALLOCA
, size_t allocaSize
#endif
@@ -637,30 +813,57 @@ struct CEncoderInfo
CDecoderInfo &decoder = decodersInfo[index];
decoder.DecoderIndex = index;
decoder.Encoder = this;
+
#ifdef USE_ALLOCA
decoder.AllocaSize = allocaSize;
#endif
+
decoder.CallbackMode = callbackMode;
return thread[index].Create(DecodeThreadFunction, &decoder);
}
+
#endif
};
-static const UInt32 k_LZMA = 0x030101;
HRESULT CEncoderInfo::Init(
const COneMethodInfo &method,
- UInt32 uncompressedDataSize,
unsigned generateDictBits,
CBaseRandomGenerator *rgLoc)
{
- rg.Set(rgLoc);
- kBufferSize = uncompressedDataSize;
- UInt32 kCompressedBufferSize = (kBufferSize - kBufferSize / 4) + kCompressedAdditionalSize;
- if (!rg.Alloc(kBufferSize))
- return E_OUTOFMEMORY;
- rg.Generate(generateDictBits);
- crc = CrcCalc(rg.Buffer, rg.BufferSize);
+ // we need extra space, if input data is already compressed
+ const size_t kCompressedBufferSize =
+ kCompressedAdditionalSize +
+ kBufferSize + kBufferSize / 16;
+ // kBufferSize / 2;
+
+ if (kCompressedBufferSize < kBufferSize)
+ return E_FAIL;
+
+ uncompressedDataPtr = fileData;
+
+ if (!fileData)
+ {
+ if (!rg.Alloc(kBufferSize))
+ return E_OUTOFMEMORY;
+
+ // DWORD ttt = GetTickCount();
+ if (generateDictBits == 0)
+ rg.GenerateSimpleRandom(rgLoc);
+ else
+ rg.GenerateLz(generateDictBits, rgLoc);
+ // printf("\n%d\n ", GetTickCount() - ttt);
+
+ crc = CrcCalc(rg.Buffer, rg.BufferSize);
+ uncompressedDataPtr = rg.Buffer;
+ }
+
+ if (_encoderFilter)
+ {
+ if (!rgCopy.Alloc(kBufferSize))
+ return E_OUTOFMEMORY;
+ }
+
outStreamSpec = new CBenchmarkOutStream;
if (!outStreamSpec->Alloc(kCompressedBufferSize))
@@ -676,54 +879,174 @@ HRESULT CEncoderInfo::Init(
}
if (!propStreamSpec->Alloc(kMaxLzmaPropSize))
return E_OUTOFMEMORY;
- propStreamSpec->Init();
+ propStreamSpec->Init(true, false);
+ CMyComPtr<IUnknown> coder;
+ if (_encoderFilter)
+ coder = _encoderFilter;
+ else
+ coder = _encoder;
{
CMyComPtr<ICompressSetCoderProperties> scp;
- encoder.QueryInterface(IID_ICompressSetCoderProperties, &scp);
+ coder.QueryInterface(IID_ICompressSetCoderProperties, &scp);
if (scp)
{
- UInt64 reduceSize = uncompressedDataSize;
+ UInt64 reduceSize = kBufferSize;
RINOK(method.SetCoderProps(scp, &reduceSize));
}
else
{
if (method.AreThereNonOptionalProps())
- return E_FAIL;
+ return E_INVALIDARG;
}
CMyComPtr<ICompressWriteCoderProperties> writeCoderProps;
- encoder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProps);
+ coder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProps);
if (writeCoderProps)
{
RINOK(writeCoderProps->WriteCoderProperties(propStream));
}
+
+ {
+ CMyComPtr<ICryptoSetPassword> sp;
+ coder.QueryInterface(IID_ICryptoSetPassword, &sp);
+ if (sp)
+ {
+ RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw)));
+
+ // we must call encoding one time to calculate password key for key cache.
+ // it must be after WriteCoderProperties!
+ CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+ Byte temp[16];
+ memset(temp, 0, sizeof(temp));
+ inStreamSpec->Init(temp, sizeof(temp));
+
+ CCrcOutStream *outStreamSpec = new CCrcOutStream;
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ outStreamSpec->Init();
+
+ if (_encoderFilter)
+ {
+ _encoderFilter->Init();
+ _encoderFilter->Filter(temp, sizeof(temp));
+ }
+ else
+ {
+ RINOK(_encoder->Code(inStream, outStream, 0, 0, NULL));
+ }
+ }
+ }
}
+
return S_OK;
}
+
+static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size)
+{
+ while (size != 0)
+ {
+ UInt32 cur = (UInt32)1 << 31;
+ if (cur > size)
+ cur = (UInt32)size;
+ UInt32 processed = filter->Filter(data, cur);
+ data += processed;
+ // if (processed > size) (in AES filter), we must fill last block with zeros.
+ // but it is not important for benchmark. So we just copy that data without filtering.
+ if (processed > size || processed == 0)
+ break;
+ size -= processed;
+ }
+}
+
+
HRESULT CEncoderInfo::Encode()
{
+ CBenchInfo &bi = progressInfoSpec[0]->BenchInfo;
+ bi.UnpackSize = 0;
+ bi.PackSize = 0;
+ CMyComPtr<ICryptoProperties> cp;
+ CMyComPtr<IUnknown> coder;
+ if (_encoderFilter)
+ coder = _encoderFilter;
+ else
+ coder = _encoder;
+ coder.QueryInterface(IID_ICryptoProperties, &cp);
CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
- inStreamSpec->Init(rg.Buffer, rg.BufferSize);
- outStreamSpec->Init();
+ UInt64 prev = 0;
- RINOK(encoder->Code(inStream, outStream, 0, 0, progressInfo[0]));
- compressedSize = outStreamSpec->Pos;
- encoder.Release();
+ UInt32 crcPrev = 0;
+
+ if (cp)
+ {
+ RINOK(cp->SetKey(_key, sizeof(_key)));
+ RINOK(cp->SetInitVector(_iv, sizeof(_iv)));
+ }
+
+ for (UInt64 i = 0; i < NumIterations; i++)
+ {
+ if (printCallback && bi.UnpackSize - prev > (1 << 20))
+ {
+ RINOK(printCallback->CheckBreak());
+ prev = bi.UnpackSize;
+ }
+
+ bool isLast = (i == NumIterations - 1);
+ bool calcCrc = ((isLast || (i & 0x7F) == 0 || CheckCrc_Enc) && NumIterations != 1);
+ outStreamSpec->Init(isLast, calcCrc);
+
+ if (_encoderFilter)
+ {
+ memcpy(rgCopy.Buffer, uncompressedDataPtr, kBufferSize);
+ _encoderFilter->Init();
+ My_FilterBench(_encoderFilter, rgCopy.Buffer, kBufferSize);
+ RINOK(WriteStream(outStream, rgCopy.Buffer, kBufferSize));
+ }
+ else
+ {
+ inStreamSpec->Init(uncompressedDataPtr, kBufferSize);
+ RINOK(_encoder->Code(inStream, outStream, NULL, NULL, progressInfo[0]));
+ }
+
+ // outStreamSpec->Print();
+
+ UInt32 crcNew = CRC_GET_DIGEST(outStreamSpec->Crc);
+ if (i == 0)
+ crcPrev = crcNew;
+ else if (calcCrc && crcPrev != crcNew)
+ return E_FAIL;
+
+ compressedSize = outStreamSpec->Pos;
+ bi.UnpackSize += kBufferSize;
+ bi.PackSize += compressedSize;
+ }
+
+ _encoder.Release();
+ _encoderFilter.Release();
return S_OK;
}
+
HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
{
CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
- CMyComPtr<ICompressCoder> &decoder = decoders[decoderIndex];
+ CMyComPtr<ICompressCoder> &decoder = _decoders[decoderIndex];
+ CMyComPtr<IUnknown> coder;
+ if (_decoderFilter)
+ {
+ if (decoderIndex != 0)
+ return E_FAIL;
+ coder = _decoderFilter;
+ }
+ else
+ coder = decoder;
CMyComPtr<ICompressSetDecoderProperties2> setDecProps;
- decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecProps);
+ coder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecProps);
if (!setDecProps && propStreamSpec->Pos != 0)
return E_FAIL;
@@ -737,7 +1060,7 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
#ifndef _7ZIP_ST
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
- decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+ coder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads));
@@ -745,30 +1068,79 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
}
#endif
- for (UInt32 j = 0; j < NumIterations; j++)
+ CMyComPtr<ICompressSetCoderProperties> scp;
+ coder.QueryInterface(IID_ICompressSetCoderProperties, &scp);
+ if (scp)
{
- if (printCallback)
+ UInt64 reduceSize = _uncompressedDataSize;
+ RINOK(_method.SetCoderProps(scp, &reduceSize));
+ }
+
+ CMyComPtr<ICryptoProperties> cp;
+ coder.QueryInterface(IID_ICryptoProperties, &cp);
+
+ if (setDecProps)
+ {
+ RINOK(setDecProps->SetDecoderProperties2(propStreamSpec->Buffer, (UInt32)propStreamSpec->Pos));
+ }
+
+ {
+ CMyComPtr<ICryptoSetPassword> sp;
+ coder.QueryInterface(IID_ICryptoSetPassword, &sp);
+ if (sp)
+ {
+ RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw)));
+ }
+ }
+
+ UInt64 prev = 0;
+
+ if (cp)
+ {
+ RINOK(cp->SetKey(_key, sizeof(_key)));
+ RINOK(cp->SetInitVector(_iv, sizeof(_iv)));
+ }
+
+ for (UInt64 i = 0; i < NumIterations; i++)
+ {
+ if (printCallback && pi->BenchInfo.UnpackSize - prev > (1 << 20))
{
RINOK(printCallback->CheckBreak());
+ prev = pi->BenchInfo.UnpackSize;
}
+
inStreamSpec->Init(outStreamSpec->Buffer, compressedSize);
crcOutStreamSpec->Init();
- if (setDecProps)
+ UInt64 outSize = kBufferSize;
+ crcOutStreamSpec->CalcCrc = ((i & 0x7F) == 0 || CheckCrc_Dec);
+
+ if (_decoderFilter)
{
- RINOK(setDecProps->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos));
+ if (compressedSize > rgCopy.BufferSize)
+ return E_FAIL;
+ memcpy(rgCopy.Buffer, outStreamSpec->Buffer, compressedSize);
+ _decoderFilter->Init();
+ My_FilterBench(_decoderFilter, rgCopy.Buffer, compressedSize);
+ RINOK(WriteStream(crcOutStream, rgCopy.Buffer, compressedSize));
}
- UInt64 outSize = kBufferSize;
- RINOK(decoder->Code(inStream, crcOutStream, 0, &outSize, progressInfo[decoderIndex]));
- if (CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc)
+ else
+ {
+ RINOK(decoder->Code(inStream, crcOutStream, 0, &outSize, progressInfo[decoderIndex]));
+ }
+
+ if (crcOutStreamSpec->CalcCrc && CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc)
return S_FALSE;
pi->BenchInfo.UnpackSize += kBufferSize;
pi->BenchInfo.PackSize += compressedSize;
}
+
decoder.Release();
+ _decoderFilter.Release();
return S_OK;
}
+
static const UInt32 kNumThreadsMax = (1 << 12);
struct CBenchEncoders
@@ -778,25 +1150,46 @@ struct CBenchEncoders
~CBenchEncoders() { delete []encoders; }
};
+
+static UInt64 GetNumIterations(UInt64 numCommands, UInt64 complexInCommands)
+{
+ if (numCommands < (1 << 4))
+ numCommands = (1 << 4);
+ UInt64 res = complexInCommands / numCommands;
+ return (res == 0 ? 1 : res);
+}
+
+
static HRESULT MethodBench(
DECL_EXTERNAL_CODECS_LOC_VARS
- bool oldLzmaBenchMode,
- UInt32 numThreads,
+ UInt64 complexInCommands,
+ bool
+ #ifndef _7ZIP_ST
+ oldLzmaBenchMode
+ #endif
+ ,
+ UInt32
+ #ifndef _7ZIP_ST
+ numThreads
+ #endif
+ ,
const COneMethodInfo &method2,
- UInt32 uncompressedDataSize,
+ size_t uncompressedDataSize,
+ const Byte *fileData,
unsigned generateDictBits,
+
IBenchPrintCallback *printCallback,
IBenchCallback *callback,
CBenchProps *benchProps)
{
COneMethodInfo method = method2;
UInt64 methodId;
- UInt32 numInStreams, numOutStreams;
+ UInt32 numStreams;
if (!FindMethod(
EXTERNAL_CODECS_LOC_VARS
- method.MethodName, methodId, numInStreams, numOutStreams))
+ method.MethodName, methodId, numStreams))
return E_NOTIMPL;
- if (numInStreams != 1 || numOutStreams != 1)
+ if (numStreams != 1)
return E_INVALIDARG;
UInt32 numEncoderThreads = 1;
@@ -810,7 +1203,7 @@ static HRESULT MethodBench(
bool fixedNumber;
UInt32 numLzmaThreads = method.Get_Lzma_NumThreads(fixedNumber);
if (!fixedNumber && numThreads == 1)
- method.AddNumThreadsProp(1);
+ method.AddProp_NumThreads(1);
if (numThreads > 1 && numLzmaThreads > 1)
{
numEncoderThreads = numThreads / 2;
@@ -819,35 +1212,60 @@ static HRESULT MethodBench(
}
#endif
- if (numThreads < 1 || numEncoderThreads > kNumThreadsMax)
- return E_INVALIDARG;
-
CBenchEncoders encodersSpec(numEncoderThreads);
CEncoderInfo *encoders = encodersSpec.encoders;
UInt32 i;
+
for (i = 0; i < numEncoderThreads; i++)
{
CEncoderInfo &encoder = encoders[i];
encoder.callback = (i == 0) ? callback : 0;
encoder.printCallback = printCallback;
- RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, encoder.encoder, true));
- if (!encoder.encoder)
- return E_NOTIMPL;
+ {
+ CCreatedCoder cod;
+ RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, true, encoder._encoderFilter, cod));
+ encoder._encoder = cod.Coder;
+ if (!encoder._encoder && !encoder._encoderFilter)
+ return E_NOTIMPL;
+ }
+
+ encoder.CheckCrc_Enc = (benchProps->EncComplex) > 30 ;
+ encoder.CheckCrc_Dec = (benchProps->DecComplexCompr + benchProps->DecComplexUnc) > 30 ;
+
+ memset(encoder._iv, 0, sizeof(encoder._iv));
+ memset(encoder._key, 0, sizeof(encoder._key));
+ memset(encoder._psw, 0, sizeof(encoder._psw));
+
for (UInt32 j = 0; j < numSubDecoderThreads; j++)
{
- RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, encoder.decoders[j], false));
- if (!encoder.decoders[j])
+ CCreatedCoder cod;
+ CMyComPtr<ICompressCoder> &decoder = encoder._decoders[j];
+ RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod));
+ decoder = cod.Coder;
+ if (!encoder._decoderFilter && !decoder)
return E_NOTIMPL;
}
}
CBaseRandomGenerator rg;
rg.Init();
+
+ UInt32 crc = 0;
+ if (fileData)
+ crc = CrcCalc(fileData, uncompressedDataSize);
+
for (i = 0; i < numEncoderThreads; i++)
{
- RINOK(encoders[i].Init(method, uncompressedDataSize, generateDictBits, &rg));
+ CEncoderInfo &encoder = encoders[i];
+ encoder._method = method;
+ encoder._uncompressedDataSize = uncompressedDataSize;
+ encoder.kBufferSize = uncompressedDataSize;
+ encoder.fileData = fileData;
+ encoder.crc = crc;
+
+ RINOK(encoders[i].Init(method, generateDictBits, &rg));
}
CBenchProgressStatus status;
@@ -857,11 +1275,16 @@ static HRESULT MethodBench(
for (i = 0; i < numEncoderThreads; i++)
{
CEncoderInfo &encoder = encoders[i];
+ encoder.NumIterations = GetNumIterations(benchProps->GeComprCommands(uncompressedDataSize), complexInCommands);
+
for (int j = 0; j < 2; j++)
{
- encoder.progressInfo[j] = encoder.progressInfoSpec[j] = new CBenchProgressInfo;
- encoder.progressInfoSpec[j]->Status = &status;
+ CBenchProgressInfo *spec = new CBenchProgressInfo;
+ encoder.progressInfoSpec[j] = spec;
+ encoder.progressInfo[j] = spec;
+ spec->Status = &status;
}
+
if (i == 0)
{
CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
@@ -876,6 +1299,7 @@ static HRESULT MethodBench(
#ifdef USE_ALLOCA
encoder.AllocaSize = (i * 16 * 21) & 0x7FF;
#endif
+
RINOK(encoder.CreateEncoderThread())
}
else
@@ -884,6 +1308,7 @@ static HRESULT MethodBench(
RINOK(encoder.Encode());
}
}
+
#ifndef _7ZIP_ST
if (numEncoderThreads > 1)
for (i = 0; i < numEncoderThreads; i++)
@@ -897,13 +1322,15 @@ static HRESULT MethodBench(
encoders[0].progressInfoSpec[0]->SetFinishTime(info);
info.UnpackSize = 0;
info.PackSize = 0;
- info.NumIterations = 1; // progressInfoSpec->NumIterations;
+ info.NumIterations = encoders[0].NumIterations;
+
for (i = 0; i < numEncoderThreads; i++)
{
CEncoderInfo &encoder = encoders[i];
info.UnpackSize += encoder.kBufferSize;
info.PackSize += encoder.compressedSize;
}
+
RINOK(callback->SetEncodeResult(info, true));
@@ -911,14 +1338,14 @@ static HRESULT MethodBench(
status.EncodeMode = false;
UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads;
+
for (i = 0; i < numEncoderThreads; i++)
{
CEncoderInfo &encoder = encoders[i];
if (i == 0)
{
- encoder.NumIterations = (UInt32)(1 + kUncompressMinBlockSize /
- benchProps->GeDecomprCommands(encoder.compressedSize, encoder.kBufferSize));
+ encoder.NumIterations = GetNumIterations(benchProps->GeDecomprCommands(encoder.compressedSize, encoder.kBufferSize), complexInCommands);
CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
bpi->Callback = callback;
bpi->BenchInfo.NumIterations = numDecoderThreads;
@@ -950,6 +1377,7 @@ static HRESULT MethodBench(
RINOK(encoder.Decode(0));
}
}
+
#ifndef _7ZIP_ST
HRESULT res = S_OK;
if (numDecoderThreads > 1)
@@ -963,8 +1391,10 @@ static HRESULT MethodBench(
}
RINOK(res);
#endif
+
RINOK(status.Res);
encoders[0].progressInfoSpec[0]->SetFinishTime(info);
+
#ifndef _7ZIP_ST
#ifdef UNDER_CE
if (numDecoderThreads > 1)
@@ -977,22 +1407,26 @@ static HRESULT MethodBench(
}
#endif
#endif
+
info.UnpackSize = 0;
info.PackSize = 0;
info.NumIterations = numSubDecoderThreads * encoders[0].NumIterations;
+
for (i = 0; i < numEncoderThreads; i++)
{
CEncoderInfo &encoder = encoders[i];
info.UnpackSize += encoder.kBufferSize;
info.PackSize += encoder.compressedSize;
}
+
RINOK(callback->SetDecodeResult(info, false));
RINOK(callback->SetDecodeResult(info, true));
+
return S_OK;
}
-inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary)
+static inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary)
{
UInt32 hs = dictionary - 1;
hs |= (hs >> 1);
@@ -1008,33 +1442,142 @@ inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary)
(1 << 20) + (multiThread ? (6 << 20) : 0);
}
-UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary)
+UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary, bool totalBench)
{
const UInt32 kBufferSize = dictionary;
- const UInt32 kCompressedBufferSize = (kBufferSize / 2);
- UInt32 numSubThreads = (numThreads > 1) ? 2 : 1;
- UInt32 numBigThreads = numThreads / numSubThreads;
- return (kBufferSize + kCompressedBufferSize +
- GetLZMAUsage((numThreads > 1), dictionary) + (2 << 20)) * numBigThreads;
+ const UInt32 kCompressedBufferSize = kBufferSize; // / 2;
+ bool lzmaMt = (totalBench || numThreads > 1);
+ UInt32 numBigThreads = numThreads;
+ if (!totalBench && lzmaMt)
+ numBigThreads /= 2;
+ return ((UInt64)kBufferSize + kCompressedBufferSize +
+ GetLZMAUsage(lzmaMt, dictionary) + (2 << 20)) * numBigThreads;
}
-static bool CrcBig(const void *data, UInt32 size, UInt32 numCycles, UInt32 crcBase)
+static HRESULT CrcBig(const void *data, UInt32 size, UInt64 numIterations,
+ const UInt32 *checkSum, IHasher *hf,
+ IBenchPrintCallback *callback)
{
- for (UInt32 i = 0; i < numCycles; i++)
- if (CrcCalc(data, size) != crcBase)
- return false;
- return true;
+ Byte hash[64];
+ UInt64 i;
+ for (i = 0; i < sizeof(hash); i++)
+ hash[i] = 0;
+ for (i = 0; i < numIterations; i++)
+ {
+ if (callback && (i & 0xFF) == 0)
+ {
+ RINOK(callback->CheckBreak());
+ }
+ hf->Init();
+ hf->Update(data, size);
+ hf->Final(hash);
+ UInt32 hashSize = hf->GetDigestSize();
+ if (hashSize > sizeof(hash))
+ return S_FALSE;
+ UInt32 sum = 0;
+ for (UInt32 j = 0; j < hashSize; j += 4)
+ sum ^= GetUi32(hash + j);
+ if (checkSum && sum != *checkSum)
+ {
+ return S_FALSE;
+ }
+ }
+ return S_OK;
+}
+
+UInt32 g_BenchCpuFreqTemp = 1;
+
+#define YY1 sum += val; sum ^= val;
+#define YY3 YY1 YY1 YY1 YY1
+#define YY5 YY3 YY3 YY3 YY3
+#define YY7 YY5 YY5 YY5 YY5
+static const UInt32 kNumFreqCommands = 128;
+
+EXTERN_C_BEGIN
+
+static UInt32 CountCpuFreq(UInt32 sum, UInt32 num, UInt32 val)
+{
+ for (UInt32 i = 0; i < num; i++)
+ {
+ YY7
+ }
+ return sum;
}
+EXTERN_C_END
+
+
#ifndef _7ZIP_ST
+
+struct CFreqInfo
+{
+ NWindows::CThread Thread;
+ IBenchPrintCallback *Callback;
+ HRESULT CallbackRes;
+ UInt32 ValRes;
+ UInt32 Size;
+ UInt64 NumIterations;
+
+ void Wait()
+ {
+ Thread.Wait();
+ Thread.Close();
+ }
+};
+
+static THREAD_FUNC_DECL FreqThreadFunction(void *param)
+{
+ CFreqInfo *p = (CFreqInfo *)param;
+
+ UInt32 sum = g_BenchCpuFreqTemp;
+ for (UInt64 k = p->NumIterations; k > 0; k--)
+ {
+ p->CallbackRes = p->Callback->CheckBreak();
+ if (p->CallbackRes != S_OK)
+ return 0;
+ sum = CountCpuFreq(sum, p->Size, g_BenchCpuFreqTemp);
+ }
+ p->ValRes = sum;
+ return 0;
+}
+
+struct CFreqThreads
+{
+ CFreqInfo *Items;
+ UInt32 NumThreads;
+
+ CFreqThreads(): Items(0), NumThreads(0) {}
+ void WaitAll()
+ {
+ for (UInt32 i = 0; i < NumThreads; i++)
+ Items[i].Wait();
+ NumThreads = 0;
+ }
+ ~CFreqThreads()
+ {
+ WaitAll();
+ delete []Items;
+ }
+};
+
struct CCrcInfo
{
NWindows::CThread Thread;
+ IBenchPrintCallback *Callback;
+ HRESULT CallbackRes;
+
const Byte *Data;
UInt32 Size;
- UInt32 NumCycles;
- UInt32 Crc;
- bool Res;
+ UInt64 NumIterations;
+ bool CheckSumDefined;
+ UInt32 CheckSum;
+ CMyComPtr<IHasher> Hasher;
+ HRESULT Res;
+
+ #ifdef USE_ALLOCA
+ size_t AllocaSize;
+ #endif
+
void Wait()
{
Thread.Wait();
@@ -1045,14 +1588,22 @@ struct CCrcInfo
static THREAD_FUNC_DECL CrcThreadFunction(void *param)
{
CCrcInfo *p = (CCrcInfo *)param;
- p->Res = CrcBig(p->Data, p->Size, p->NumCycles, p->Crc);
+
+ #ifdef USE_ALLOCA
+ alloca(p->AllocaSize);
+ #endif
+
+ p->Res = CrcBig(p->Data, p->Size, p->NumIterations,
+ p->CheckSumDefined ? &p->CheckSum : NULL, p->Hasher,
+ p->Callback);
return 0;
}
struct CCrcThreads
{
- UInt32 NumThreads;
CCrcInfo *Items;
+ UInt32 NumThreads;
+
CCrcThreads(): Items(0), NumThreads(0) {}
void WaitAll()
{
@@ -1066,6 +1617,7 @@ struct CCrcThreads
delete []Items;
}
};
+
#endif
static UInt32 CrcCalc1(const Byte *buf, UInt32 size)
@@ -1112,127 +1664,89 @@ bool CrcInternalTest()
return true;
}
-static HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed)
+struct CBenchMethod
{
- if (numThreads == 0)
- numThreads = 1;
+ unsigned Weight;
+ unsigned DictBits;
+ UInt32 EncComplex;
+ UInt32 DecComplexCompr;
+ UInt32 DecComplexUnc;
+ const char *Name;
+};
- CBenchBuffer buffer;
- size_t totalSize = (size_t)bufferSize * numThreads;
- if (totalSize / numThreads != bufferSize)
- return E_OUTOFMEMORY;
- if (!buffer.Alloc(totalSize))
- return E_OUTOFMEMORY;
+static const CBenchMethod g_Bench[] =
+{
+ { 40, 17, 357, 145, 20, "LZMA:x1" },
+ { 80, 24, 1220, 145, 20, "LZMA:x5:mt1" },
+ { 80, 24, 1220, 145, 20, "LZMA:x5:mt2" },
- Byte *buf = buffer.Buffer;
- CBaseRandomGenerator RG;
- UInt32 numCycles = (kCrcBlockSize) / ((bufferSize >> 2) + 1) + 1;
+ { 10, 16, 124, 40, 14, "Deflate:x1" },
+ { 20, 16, 376, 40, 14, "Deflate:x5" },
+ { 10, 16, 1082, 40, 14, "Deflate:x7" },
+ { 10, 17, 422, 40, 14, "Deflate64:x5" },
- UInt64 timeVal;
- #ifndef _7ZIP_ST
- CCrcThreads threads;
- if (numThreads > 1)
- {
- threads.Items = new CCrcInfo[numThreads];
- UInt32 i;
- for (i = 0; i < numThreads; i++)
- {
- CCrcInfo &info = threads.Items[i];
- Byte *data = buf + (size_t)bufferSize * i;
- info.Data = data;
- info.NumCycles = numCycles;
- info.Size = bufferSize;
- info.Crc = RandGenCrc(data, bufferSize, RG);
- }
- timeVal = GetTimeCount();
- for (i = 0; i < numThreads; i++)
- {
- CCrcInfo &info = threads.Items[i];
- RINOK(info.Thread.Create(CrcThreadFunction, &info));
- threads.NumThreads++;
- }
- threads.WaitAll();
- for (i = 0; i < numThreads; i++)
- if (!threads.Items[i].Res)
- return S_FALSE;
- }
- else
- #endif
- {
- UInt32 crc = RandGenCrc(buf, bufferSize, RG);
- timeVal = GetTimeCount();
- if (!CrcBig(buf, bufferSize, numCycles, crc))
- return S_FALSE;
- }
- timeVal = GetTimeCount() - timeVal;
- if (timeVal == 0)
- timeVal = 1;
+ { 10, 15, 590, 69, 69, "BZip2:x1" },
+ { 20, 19, 815, 122, 122, "BZip2:x5" },
+ { 10, 19, 815, 122, 122, "BZip2:x5:mt2" },
+ { 10, 19, 2530, 122, 122, "BZip2:x7" },
- UInt64 size = (UInt64)numCycles * totalSize;
- speed = MyMultDiv64(size, timeVal, GetFreq());
- return S_OK;
-}
+ { 10, 18, 1010, 0, 1150, "PPMD:x1" },
+ { 10, 22, 1655, 0, 1830, "PPMD:x5" },
-struct CBenchMethod
+ { 2, 0, 6, 0, 6, "Delta:4" },
+ { 2, 0, 4, 0, 4, "BCJ" },
+
+ { 10, 0, 24, 0, 24, "AES256CBC:1" },
+ { 2, 0, 8, 0, 2, "AES256CBC:2" }
+};
+
+struct CBenchHash
{
- unsigned dictBits;
- UInt32 EncComplex;
- UInt32 DecComplexCompr;
- UInt32 DecComplexUnc;
+ unsigned Weight;
+ UInt32 Complex;
+ UInt32 CheckSum;
const char *Name;
};
-static const CBenchMethod g_Bench[] =
+static const CBenchHash g_Hash[] =
{
- { 17, 340, 155, 20, "LZMA:x1" },
- { 24, 1182, 155, 20, "LZMA:x5:mt1" },
- { 24, 1182, 155, 20, "LZMA:x5:mt2" },
- { 16, 124, 47, 14, "Deflate:x1" },
- { 16, 376, 47, 14, "Deflate:x5" },
- { 16, 1084, 47, 14, "Deflate:x7" },
- { 17, 420, 47, 14, "Deflate64:x5" },
- { 15, 590, 69, 70, "BZip2:x1" },
- { 19, 792, 119, 119, "BZip2:x5" },
- #ifndef UNDER_CE
- { 19, 792, 119, 119, "BZip2:x5:mt2" },
- #endif
- { 19, 2500, 118, 118, "BZip2:x7" },
- { 18, 1010, 0, 1155, "PPMD:x1" },
- { 22, 1650, 0, 1830, "PPMD:x5" }
+ { 1, 1820, 0x8F8FEDAB, "CRC32:1" },
+ { 10, 558, 0x8F8FEDAB, "CRC32:4" },
+ { 10, 339, 0x8F8FEDAB, "CRC32:8" },
+ { 10, 512, 0xDF1C17CC, "CRC64" },
+ { 10, 5100, 0x2D79FF2E, "SHA256" },
+ { 10, 2340, 0x4C25132B, "SHA1" },
+ { 2, 5500, 0xE084E913, "BLAKE2sp" }
};
struct CTotalBenchRes
{
- UInt64 NumIterations;
+ // UInt64 NumIterations1; // for Usage
+ UInt64 NumIterations2; // for Rating / RPU
+
UInt64 Rating;
UInt64 Usage;
UInt64 RPU;
- void Init() { NumIterations = 0; Rating = 0; Usage = 0; RPU = 0; }
- void Normalize()
- {
- if (NumIterations == 0)
- return;
- Rating /= NumIterations;
- Usage /= NumIterations;
- RPU /= NumIterations;
- NumIterations = 1;
- }
- void SetMid(const CTotalBenchRes &r1, const CTotalBenchRes &r2)
+
+ void Init() { /* NumIterations1 = 0; */ NumIterations2 = 0; Rating = 0; Usage = 0; RPU = 0; }
+
+ void SetSum(const CTotalBenchRes &r1, const CTotalBenchRes &r2)
{
- Rating = (r1.Rating + r2.Rating) / 2;
- Usage = (r1.Usage + r2.Usage) / 2;
- RPU = (r1.RPU + r2.RPU) / 2;
- NumIterations = (r1.NumIterations + r2.NumIterations) / 2;
+ Rating = (r1.Rating + r2.Rating);
+ Usage = (r1.Usage + r2.Usage);
+ RPU = (r1.RPU + r2.RPU);
+ // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1);
+ NumIterations2 = (r1.NumIterations2 + r2.NumIterations2);
}
};
-static void PrintNumber(IBenchPrintCallback &f, UInt64 value, int size, bool withSpace = true)
+static void PrintNumber(IBenchPrintCallback &f, UInt64 value, int size)
{
char s[128];
int startPos = (int)sizeof(s) - 32;
memset(s, ' ', startPos);
ConvertUInt64ToString(value, s + startPos);
- if (withSpace)
+ // if (withSpace)
{
startPos--;
size++;
@@ -1247,45 +1761,115 @@ static void PrintNumber(IBenchPrintCallback &f, UInt64 value, int size, bool wit
f.Print(s + startPos);
}
-static void PrintRating(IBenchPrintCallback &f, UInt64 rating)
+static const int kFieldSize_Name = 12;
+static const int kFieldSize_SmallName = 4;
+static const int kFieldSize_Speed = 9;
+static const int kFieldSize_Usage = 5;
+static const int kFieldSize_RU = 6;
+static const int kFieldSize_Rating = 6;
+static const int kFieldSize_EU = 5;
+static const int kFieldSize_Effec = 5;
+
+static const int kFieldSize_TotalSize = 4 + kFieldSize_Speed + kFieldSize_Usage + kFieldSize_RU + kFieldSize_Rating;
+static const int kFieldSize_EUAndEffec = 2 + kFieldSize_EU + kFieldSize_Effec;
+
+
+static void PrintRating(IBenchPrintCallback &f, UInt64 rating, int size)
{
- PrintNumber(f, rating / 1000000, 6);
+ PrintNumber(f, (rating + 500000) / 1000000, size);
}
-static void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt64 rating)
+
+static void PrintPercents(IBenchPrintCallback &f, UInt64 val, UInt64 divider, int size)
{
- PrintNumber(f, (usage + 5000) / 10000, 5);
- PrintRating(f, rpu);
- PrintRating(f, rating);
+ PrintNumber(f, (val * 100 + divider / 2) / divider, size);
}
-static void PrintResults(IBenchPrintCallback &f, const CBenchInfo &info, UInt64 rating, CTotalBenchRes &res)
+static void PrintChars(IBenchPrintCallback &f, char c, unsigned size)
{
- UInt64 speed = MyMultDiv64(info.UnpackSize, info.GlobalTime, info.GlobalFreq);
- PrintNumber(f, speed / 1024, 7);
+ char s[256];
+ memset(s, (Byte)c, size);
+ s[size] = 0;
+ f.Print(s);
+}
+
+static void PrintSpaces(IBenchPrintCallback &f, unsigned size)
+{
+ PrintChars(f, ' ', size);
+}
+
+static void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt64 rating, bool showFreq, UInt64 cpuFreq)
+{
+ PrintNumber(f, (usage + 5000) / 10000, kFieldSize_Usage);
+ PrintRating(f, rpu, kFieldSize_RU);
+ PrintRating(f, rating, kFieldSize_Rating);
+ if (showFreq)
+ {
+ if (cpuFreq == 0)
+ PrintSpaces(f, kFieldSize_EUAndEffec);
+ else
+ {
+ UInt64 ddd = cpuFreq * usage / 100;
+ if (ddd == 0)
+ ddd = 1;
+ PrintPercents(f, (rating * 10000), ddd, kFieldSize_EU);
+ PrintPercents(f, rating, cpuFreq, kFieldSize_Effec);
+ }
+ }
+}
+
+static void PrintResults(IBenchPrintCallback *f,
+ const CBenchInfo &info,
+ unsigned weight,
+ UInt64 rating,
+ bool showFreq, UInt64 cpuFreq,
+ CTotalBenchRes *res)
+{
+ UInt64 speed = info.GetSpeed(info.UnpackSize * info.NumIterations);
+ if (f)
+ {
+ if (speed != 0)
+ PrintNumber(*f, speed / 1024, kFieldSize_Speed);
+ else
+ PrintSpaces(*f, 1 + kFieldSize_Speed);
+ }
UInt64 usage = info.GetUsage();
UInt64 rpu = info.GetRatingPerUsage(rating);
- PrintResults(f, usage, rpu, rating);
- res.NumIterations++;
- res.RPU += rpu;
- res.Rating += rating;
- res.Usage += usage;
+ if (f)
+ {
+ PrintResults(*f, usage, rpu, rating, showFreq, cpuFreq);
+ }
+
+ if (res)
+ {
+ // res->NumIterations1++;
+ res->NumIterations2 += weight;
+ res->RPU += (rpu * weight);
+ res->Rating += (rating * weight);
+ res->Usage += (usage * weight);
+ }
}
-static void PrintTotals(IBenchPrintCallback &f, const CTotalBenchRes &res)
+static void PrintTotals(IBenchPrintCallback &f, bool showFreq, UInt64 cpuFreq, const CTotalBenchRes &res)
{
- f.Print(" ");
- PrintResults(f, res.Usage, res.RPU, res.Rating);
+ PrintSpaces(f, 1 + kFieldSize_Speed);
+ // UInt64 numIterations1 = res.NumIterations1; if (numIterations1 == 0) numIterations1 = 1;
+ UInt64 numIterations2 = res.NumIterations2; if (numIterations2 == 0) numIterations2 = 1;
+ PrintResults(f, res.Usage / numIterations2, res.RPU / numIterations2, res.Rating / numIterations2, showFreq, cpuFreq);
}
-static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString, UInt64 size, const char *threadsString, UInt32 numThreads)
+static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
+ bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads)
{
f.Print("RAM ");
f.Print(sizeString);
- PrintNumber(f, (size >> 20), 5, true);
+ if (size_Defined)
+ PrintNumber(f, (size >> 20), 6);
+ else
+ f.Print(" ?");
f.Print(" MB, # ");
f.Print(threadsString);
- PrintNumber(f, numThreads, 3, true);
+ PrintNumber(f, numThreads, 3);
f.NewLine();
}
@@ -1297,41 +1881,74 @@ struct CBenchCallbackToPrint: public IBenchCallback
IBenchPrintCallback *_file;
UInt32 DictSize;
+ bool Use2Columns;
+ int NameFieldSize;
+
+ bool ShowFreq;
+ UInt64 CpuFreq;
+
+ unsigned EncodeWeight;
+ unsigned DecodeWeight;
+
+ CBenchCallbackToPrint():
+ Use2Columns(false),
+ NameFieldSize(0),
+ ShowFreq(false),
+ CpuFreq(0),
+ EncodeWeight(1),
+ DecodeWeight(1)
+ {}
+
void Init() { EncodeRes.Init(); DecodeRes.Init(); }
- void Normalize() { EncodeRes.Normalize(); DecodeRes.Normalize(); }
+ void Print(const char *s);
+ void NewLine();
+
+ HRESULT SetFreq(bool showFreq, UInt64 cpuFreq);
HRESULT SetEncodeResult(const CBenchInfo &info, bool final);
HRESULT SetDecodeResult(const CBenchInfo &info, bool final);
- void Print(const char *string);
- void NewLine();
- void PrintLeftAligned(const char *string, unsigned size);
};
+HRESULT CBenchCallbackToPrint::SetFreq(bool showFreq, UInt64 cpuFreq)
+{
+ ShowFreq = showFreq;
+ CpuFreq = cpuFreq;
+ return S_OK;
+}
+
HRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool final)
{
RINOK(_file->CheckBreak());
if (final)
{
- UInt64 rating = BenchProps.GetCompressRating(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize);
- PrintResults(*_file, info, rating, EncodeRes);
+ UInt64 rating = BenchProps.GetCompressRating(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize * info.NumIterations);
+ PrintResults(_file, info,
+ EncodeWeight, rating,
+ ShowFreq, CpuFreq, &EncodeRes);
+ if (!Use2Columns)
+ _file->NewLine();
}
return S_OK;
}
static const char *kSep = " | ";
-
HRESULT CBenchCallbackToPrint::SetDecodeResult(const CBenchInfo &info, bool final)
{
RINOK(_file->CheckBreak());
if (final)
{
UInt64 rating = BenchProps.GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);
- _file->Print(kSep);
+ if (Use2Columns)
+ _file->Print(kSep);
+ else
+ PrintSpaces(*_file, NameFieldSize);
CBenchInfo info2 = info;
info2.UnpackSize *= info2.NumIterations;
info2.PackSize *= info2.NumIterations;
info2.NumIterations = 1;
- PrintResults(*_file, info2, rating, DecodeRes);
+ PrintResults(_file, info2,
+ DecodeWeight, rating,
+ ShowFreq, CpuFreq, &DecodeRes);
}
return S_OK;
}
@@ -1346,43 +1963,355 @@ void CBenchCallbackToPrint::NewLine()
_file->NewLine();
}
-void CBenchCallbackToPrint::PrintLeftAligned(const char *s, unsigned size)
+void PrintLeft(IBenchPrintCallback &f, const char *s, unsigned size)
{
- AString s2 = s;
- for (unsigned len = (unsigned)strlen(s); len < size; len++)
- s2 += ' ';
- Print(s2);
+ f.Print(s);
+ int numSpaces = size - MyStringLen(s);
+ if (numSpaces > 0)
+ PrintSpaces(f, numSpaces);
+}
+
+void PrintRight(IBenchPrintCallback &f, const char *s, unsigned size)
+{
+ int numSpaces = size - MyStringLen(s);
+ if (numSpaces > 0)
+ PrintSpaces(f, numSpaces);
+ f.Print(s);
}
static HRESULT TotalBench(
- DECL_EXTERNAL_CODECS_LOC_VARS
- UInt32 numThreads, UInt32 unpackSize, IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback)
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ UInt64 complexInCommands,
+ UInt32 numThreads,
+ bool forceUnpackSize,
+ size_t unpackSize,
+ const Byte *fileData,
+ IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback)
{
- for (unsigned i = 0; i < sizeof(g_Bench) / sizeof(g_Bench[0]); i++)
+ for (unsigned i = 0; i < ARRAY_SIZE(g_Bench); i++)
{
- CBenchMethod bench = g_Bench[i];
- callback->PrintLeftAligned(bench.Name, 12);
+ const CBenchMethod &bench = g_Bench[i];
+ PrintLeft(*callback->_file, bench.Name, kFieldSize_Name);
callback->BenchProps.DecComplexUnc = bench.DecComplexUnc;
callback->BenchProps.DecComplexCompr = bench.DecComplexCompr;
callback->BenchProps.EncComplex = bench.EncComplex;
+
COneMethodInfo method;
NCOM::CPropVariant propVariant;
propVariant = bench.Name;
- RINOK(method.ParseMethodFromPROPVARIANT(L"", propVariant));
+ RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant));
+
+ size_t unpackSize2 = unpackSize;
+ if (!forceUnpackSize && bench.DictBits == 0)
+ unpackSize2 = kFilterUnpackSize;
+
+ callback->EncodeWeight = bench.Weight;
+ callback->DecodeWeight = bench.Weight;
HRESULT res = MethodBench(
EXTERNAL_CODECS_LOC_VARS
- false, numThreads, method, unpackSize, bench.dictBits,
+ complexInCommands,
+ false, numThreads, method,
+ unpackSize2, fileData,
+ bench.DictBits,
printCallback, callback, &callback->BenchProps);
+
if (res == E_NOTIMPL)
- callback->Print(" ---");
+ {
+ // callback->Print(" ---");
+ // we need additional empty line as line for decompression results
+ if (!callback->Use2Columns)
+ callback->NewLine();
+ }
else
{
RINOK(res);
}
+
callback->NewLine();
}
- return S_OK;
+ return S_OK;
+}
+
+
+static HRESULT FreqBench(
+ UInt64 complexInCommands,
+ UInt32 numThreads,
+ IBenchPrintCallback *_file,
+ bool showFreq,
+ UInt64 specifiedFreq,
+ UInt64 &cpuFreq,
+ UInt32 &res)
+{
+ res = 0;
+ cpuFreq = 0;
+
+ UInt32 bufferSize = 1 << 20;
+ UInt32 complexity = kNumFreqCommands;
+ if (numThreads == 0)
+ numThreads = 1;
+
+ #ifdef _7ZIP_ST
+ numThreads = 1;
+ #endif
+
+ UInt32 bsize = (bufferSize == 0 ? 1 : bufferSize);
+ UInt64 numIterations = complexInCommands / complexity / bsize;
+ if (numIterations == 0)
+ numIterations = 1;
+
+ CBenchInfoCalc progressInfoSpec;
+
+ #ifndef _7ZIP_ST
+ CFreqThreads threads;
+ if (numThreads > 1)
+ {
+ threads.Items = new CFreqInfo[numThreads];
+ UInt32 i;
+ for (i = 0; i < numThreads; i++)
+ {
+ CFreqInfo &info = threads.Items[i];
+ info.Callback = _file;
+ info.CallbackRes = S_OK;
+ info.NumIterations = numIterations;
+ info.Size = bufferSize;
+ }
+ progressInfoSpec.SetStartTime();
+ for (i = 0; i < numThreads; i++)
+ {
+ CFreqInfo &info = threads.Items[i];
+ RINOK(info.Thread.Create(FreqThreadFunction, &info));
+ threads.NumThreads++;
+ }
+ threads.WaitAll();
+ for (i = 0; i < numThreads; i++)
+ {
+ RINOK(threads.Items[i].CallbackRes);
+ }
+ }
+ else
+ #endif
+ {
+ progressInfoSpec.SetStartTime();
+ UInt32 sum = g_BenchCpuFreqTemp;
+ for (UInt64 k = numIterations; k > 0; k--)
+ {
+ RINOK(_file->CheckBreak());
+ sum = CountCpuFreq(sum, bufferSize, g_BenchCpuFreqTemp);
+ }
+ res += sum;
+ }
+
+ CBenchInfo info;
+ progressInfoSpec.SetFinishTime(info);
+
+ info.UnpackSize = 0;
+ info.PackSize = 0;
+ info.NumIterations = 1;
+
+ if (_file)
+ {
+ {
+ UInt64 numCommands = (UInt64)numIterations * bufferSize * numThreads * complexity;
+ UInt64 rating = info.GetSpeed(numCommands);
+ cpuFreq = rating / numThreads;
+ PrintResults(_file, info,
+ 0, // weight
+ rating,
+ showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : cpuFreq) : 0, NULL);
+ }
+ RINOK(_file->CheckBreak());
+ }
+
+ return S_OK;
+}
+
+
+
+static HRESULT CrcBench(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ UInt64 complexInCommands,
+ UInt32 numThreads, UInt32 bufferSize,
+ UInt64 &speed,
+ UInt32 complexity, unsigned benchWeight,
+ const UInt32 *checkSum,
+ const COneMethodInfo &method,
+ IBenchPrintCallback *_file,
+ CTotalBenchRes *encodeRes,
+ bool showFreq, UInt64 cpuFreq)
+{
+ if (numThreads == 0)
+ numThreads = 1;
+
+ #ifdef _7ZIP_ST
+ numThreads = 1;
+ #endif
+
+ AString methodName = method.MethodName;
+ // methodName.RemoveChar(L'-');
+ CMethodId hashID;
+ if (!FindHashMethod(
+ EXTERNAL_CODECS_LOC_VARS
+ methodName, hashID))
+ return E_NOTIMPL;
+
+ CBenchBuffer buffer;
+ size_t totalSize = (size_t)bufferSize * numThreads;
+ if (totalSize / numThreads != bufferSize)
+ return E_OUTOFMEMORY;
+ if (!buffer.Alloc(totalSize))
+ return E_OUTOFMEMORY;
+
+ Byte *buf = buffer.Buffer;
+ CBaseRandomGenerator RG;
+ UInt32 bsize = (bufferSize == 0 ? 1 : bufferSize);
+ UInt64 numIterations = complexInCommands * 256 / complexity / bsize;
+ if (numIterations == 0)
+ numIterations = 1;
+
+ CBenchInfoCalc progressInfoSpec;
+
+ #ifndef _7ZIP_ST
+ CCrcThreads threads;
+ if (numThreads > 1)
+ {
+ threads.Items = new CCrcInfo[numThreads];
+
+ UInt32 i;
+ for (i = 0; i < numThreads; i++)
+ {
+ CCrcInfo &info = threads.Items[i];
+ AString name;
+ RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, info.Hasher));
+ if (!info.Hasher)
+ return E_NOTIMPL;
+ CMyComPtr<ICompressSetCoderProperties> scp;
+ info.Hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
+ if (scp)
+ {
+ UInt64 reduceSize = 1;
+ RINOK(method.SetCoderProps(scp, &reduceSize));
+ }
+
+ Byte *data = buf + (size_t)bufferSize * i;
+ info.Callback = _file;
+ info.Data = data;
+ info.NumIterations = numIterations;
+ info.Size = bufferSize;
+ /* info.Crc = */ RandGenCrc(data, bufferSize, RG);
+ info.CheckSumDefined = false;
+ if (checkSum)
+ {
+ info.CheckSum = *checkSum;
+ info.CheckSumDefined = (checkSum && (i == 0));
+ }
+
+ #ifdef USE_ALLOCA
+ info.AllocaSize = (i * 16 * 21) & 0x7FF;
+ #endif
+ }
+
+ progressInfoSpec.SetStartTime();
+
+ for (i = 0; i < numThreads; i++)
+ {
+ CCrcInfo &info = threads.Items[i];
+ RINOK(info.Thread.Create(CrcThreadFunction, &info));
+ threads.NumThreads++;
+ }
+ threads.WaitAll();
+ for (i = 0; i < numThreads; i++)
+ {
+ RINOK(threads.Items[i].Res);
+ }
+ }
+ else
+ #endif
+ {
+ /* UInt32 crc = */ RandGenCrc(buf, bufferSize, RG);
+ progressInfoSpec.SetStartTime();
+ CMyComPtr<IHasher> hasher;
+ AString name;
+ RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, hasher));
+ if (!hasher)
+ return E_NOTIMPL;
+ CMyComPtr<ICompressSetCoderProperties> scp;
+ hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
+ if (scp)
+ {
+ UInt64 reduceSize = 1;
+ RINOK(method.SetCoderProps(scp, &reduceSize));
+ }
+ RINOK(CrcBig(buf, bufferSize, numIterations, checkSum, hasher, _file));
+ }
+
+ CBenchInfo info;
+ progressInfoSpec.SetFinishTime(info);
+
+ UInt64 unpSize = numIterations * bufferSize;
+ UInt64 unpSizeThreads = unpSize * numThreads;
+ info.UnpackSize = unpSizeThreads;
+ info.PackSize = unpSizeThreads;
+ info.NumIterations = 1;
+
+ if (_file)
+ {
+ {
+ UInt64 numCommands = unpSizeThreads * complexity / 256;
+ UInt64 rating = info.GetSpeed(numCommands);
+ PrintResults(_file, info,
+ benchWeight, rating,
+ showFreq, cpuFreq, encodeRes);
+ }
+ RINOK(_file->CheckBreak());
+ }
+
+ speed = info.GetSpeed(unpSizeThreads);
+
+ return S_OK;
+}
+
+static HRESULT TotalBench_Hash(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ UInt64 complexInCommands,
+ UInt32 numThreads, UInt32 bufSize,
+ IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback,
+ CTotalBenchRes *encodeRes,
+ bool showFreq, UInt64 cpuFreq)
+{
+ for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++)
+ {
+ const CBenchHash &bench = g_Hash[i];
+ PrintLeft(*callback->_file, bench.Name, kFieldSize_Name);
+ // callback->BenchProps.DecComplexUnc = bench.DecComplexUnc;
+ // callback->BenchProps.DecComplexCompr = bench.DecComplexCompr;
+ // callback->BenchProps.EncComplex = bench.EncComplex;
+
+ COneMethodInfo method;
+ NCOM::CPropVariant propVariant;
+ propVariant = bench.Name;
+ RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant));
+
+ UInt64 speed;
+ HRESULT res = CrcBench(
+ EXTERNAL_CODECS_LOC_VARS
+ complexInCommands,
+ numThreads, bufSize,
+ speed,
+ bench.Complex, bench.Weight,
+ &bench.CheckSum, method,
+ printCallback, encodeRes, showFreq, cpuFreq);
+ if (res == E_NOTIMPL)
+ {
+ // callback->Print(" ---");
+ }
+ else
+ {
+ RINOK(res);
+ }
+ callback->NewLine();
+ }
+ return S_OK;
}
struct CTempValues
@@ -1392,23 +2321,130 @@ struct CTempValues
~CTempValues() { delete []Values; }
};
-static void String_to_PropVariant(const UString &s, NCOM::CPropVariant &prop)
+static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
{
- const wchar_t *endPtr;
- UInt64 result = ConvertStringToUInt64(s, &endPtr);
- if (endPtr - (const wchar_t *)s != s.Length())
+ const wchar_t *end;
+ UInt64 result = ConvertStringToUInt64(s, &end);
+ if (*end != 0 || s.IsEmpty())
prop = s;
- else if (result <= 0xFFFFFFFF)
+ else if (result <= (UInt32)0xFFFFFFFF)
prop = (UInt32)result;
else
prop = result;
}
+static UInt32 GetNumThreadsNext(unsigned i, UInt32 numThreads)
+{
+ if (i < 2)
+ return i + 1;
+ i -= 1;
+ UInt32 num = (UInt32)(2 + (i & 1)) << (i >> 1);
+ return (num <= numThreads) ? num : 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;
+ }
+}
+
+
+#ifdef MY_CPU_X86_OR_AMD64
+
+static void PrintCpuChars(AString &s, UInt32 v)
+{
+ for (int j = 0; j < 4; j++)
+ {
+ Byte b = (Byte)(v & 0xFF);
+ v >>= 8;
+ if (b == 0)
+ break;
+ s += (char)b;
+ }
+}
+
+static void x86cpuid_to_String(const Cx86cpuid &c, AString &s)
+{
+ s.Empty();
+
+ UInt32 maxFunc2 = 0;
+ UInt32 t[3];
+
+ MyCPUID(0x80000000, &maxFunc2, &t[0], &t[1], &t[2]);
+
+ bool fullNameIsAvail = (maxFunc2 >= 0x80000004);
+
+ if (!fullNameIsAvail)
+ {
+ for (int i = 0; i < 3; i++)
+ PrintCpuChars(s, c.vendor[i]);
+ }
+ else
+ {
+ for (int i = 0; i < 3; i++)
+ {
+ UInt32 c[4] = { 0 };
+ MyCPUID(0x80000002 + i, &c[0], &c[1], &c[2], &c[3]);
+ for (int j = 0; j < 4; j++)
+ PrintCpuChars(s, c[j]);
+ }
+ }
+
+ s.Add_Space_if_NotEmpty();
+ {
+ char temp[32];
+ ConvertUInt32ToHex(c.ver, temp);
+ s += '(';
+ s += temp;
+ s += ')';
+ }
+}
+
+#endif
+
+
+void GetCpuName(AString &s)
+{
+ s.Empty();
+
+ #ifdef MY_CPU_X86_OR_AMD64
+ {
+ Cx86cpuid cpuid;
+ if (x86cpuid_CheckAndRead(&cpuid))
+ {
+ x86cpuid_to_String(cpuid, s);
+ return;
+ }
+ #ifdef MY_CPU_AMD64
+ s = "x64";
+ #else
+ s = "x86";
+ #endif
+ }
+ #else
+
+ #ifdef MY_CPU_LE
+ s = "LE";
+ #elif defined(MY_CPU_BE)
+ s = "BE";
+ #endif
+
+ #endif
+}
+
+
HRESULT Bench(
DECL_EXTERNAL_CODECS_LOC_VARS
IBenchPrintCallback *printCallback,
IBenchCallback *benchCallback,
- const CObjectVector<CProperty> props,
+ const CObjectVector<CProperty> &props,
UInt32 numIterations,
bool multiDict)
{
@@ -1416,43 +2452,205 @@ HRESULT Bench(
return S_FALSE;
UInt32 numCPUs = 1;
- UInt64 ramSize = (UInt64)512 << 20;
+ UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29;
+
#ifndef _7ZIP_ST
numCPUs = NSystem::GetNumberOfProcessors();
#endif
- #if !defined(_7ZIP_ST) || defined(_WIN32)
- ramSize = NSystem::GetRamSize();
- #endif
- UInt32 numThreads = numCPUs;
+
+ bool ramSize_Defined = NSystem::GetRamSize(ramSize);
- if (printCallback)
- PrintRequirements(*printCallback, "size: ", ramSize, "CPU hardware threads:", numCPUs);
+ UInt32 numThreadsSpecified = numCPUs;
+
+ UInt32 testTime = kComplexInSeconds;
+
+ UInt64 specifiedFreq = 0;
+
+ bool multiThreadTests = false;
COneMethodInfo method;
- int i;
+ unsigned i;
+
+ CBenchBuffer fileDataBuffer;
+
for (i = 0; i < props.Size(); i++)
{
const CProperty &property = props[i];
- NCOM::CPropVariant propVariant;
UString name = property.Name;
- name.MakeUpper();
+ name.MakeLower_Ascii();
+
+ if (name.IsEqualTo("file"))
+ {
+ if (property.Value.IsEmpty())
+ return E_INVALIDARG;
+
+ #ifdef USE_WIN_FILE
+
+ NFile::NIO::CInFile file;
+ if (!file.Open(us2fs(property.Value)))
+ return E_INVALIDARG;
+ UInt64 len;
+ if (!file.GetLength(len))
+ return E_FAIL;
+ if (len >= ((UInt32)1 << 31) || len == 0)
+ return E_INVALIDARG;
+ if (!fileDataBuffer.Alloc((size_t)len))
+ return E_OUTOFMEMORY;
+ UInt32 processedSize;
+ file.Read(fileDataBuffer.Buffer, (UInt32)len, processedSize);
+ if (processedSize != len)
+ return E_FAIL;
+ if (printCallback)
+ {
+ printCallback->Print("file size =");
+ // printCallback->Print(GetOemString(property.Value));
+ PrintNumber(*printCallback, len, 0);
+ printCallback->NewLine();
+ }
+ continue;
+
+ #else
+
+ return E_NOTIMPL;
+
+ #endif
+ }
+
+ NCOM::CPropVariant propVariant;
if (!property.Value.IsEmpty())
- String_to_PropVariant(property.Value, propVariant);
- if (name.Left(2).CompareNoCase(L"MT") == 0)
+ ParseNumberString(property.Value, propVariant);
+
+ if (name.IsEqualTo("time"))
+ {
+ RINOK(ParsePropToUInt32(L"", propVariant, testTime));
+ continue;
+ }
+
+ if (name.IsEqualTo("freq"))
+ {
+ UInt32 freq32 = 0;
+ RINOK(ParsePropToUInt32(L"", propVariant, freq32));
+ if (freq32 == 0)
+ return E_INVALIDARG;
+ specifiedFreq = (UInt64)freq32 * 1000000;
+
+ if (printCallback)
+ {
+ printCallback->Print("freq=");
+ PrintNumber(*printCallback, freq32, 0);
+ printCallback->NewLine();
+ }
+
+ continue;
+ }
+
+ if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
+ UString s = name.Ptr(2);
+ if (s == L"*")
+ {
+ multiThreadTests = true;
+ continue;
+ }
+ if (s.IsEmpty() && propVariant.vt == VT_BSTR)
+ {
+ if (wcscmp(propVariant.bstrVal, L"*") == 0)
+ {
+ multiThreadTests = true;
+ continue;
+ }
+ }
#ifndef _7ZIP_ST
- RINOK(ParseMtProp(name.Mid(2), propVariant, numCPUs, numThreads));
+ RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified));
#endif
continue;
}
+
RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant));
}
+ if (printCallback)
+ {
+ AString s;
+ GetCpuName(s);
+ printCallback->Print(s);
+ printCallback->NewLine();
+ }
+
+ if (printCallback)
+ {
+ printCallback->Print("CPU Freq:");
+ }
+
+ UInt64 complexInCommands = kComplexInCommands;
+
+ if (printCallback /* || benchCallback */)
+ {
+ UInt64 numMilCommands = 1 << 6;
+ if (specifiedFreq != 0)
+ {
+ while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000))
+ numMilCommands >>= 1;
+ }
+
+ for (int jj = 0;; jj++)
+ {
+ if (printCallback)
+ RINOK(printCallback->CheckBreak());
+
+ UInt64 start = ::GetTimeCount();
+ UInt32 sum = (UInt32)start;
+ sum = CountCpuFreq(sum, (UInt32)(numMilCommands * 1000000 / kNumFreqCommands), g_BenchCpuFreqTemp);
+ const UInt64 realDelta = ::GetTimeCount() - start;
+ start = realDelta;
+ if (start == 0)
+ start = 1;
+ UInt64 freq = GetFreq();
+ // mips is constant in some compilers
+ const UInt64 mipsVal = numMilCommands * freq / start;
+ if (printCallback)
+ {
+ if (realDelta == 0)
+ {
+ printCallback->Print(" -");
+ }
+ else
+ {
+ // PrintNumber(*printCallback, start, 0);
+ PrintNumber(*printCallback, mipsVal, 5 + ((sum == 0xF1541213) ? 1 : 0));
+ }
+ }
+ /*
+ if (benchCallback)
+ benchCallback->AddCpuFreq(mipsVal);
+ */
+
+ if (jj >= 3)
+ {
+ SetComplexCommands(testTime, false, mipsVal * 1000000, complexInCommands);
+ if (jj >= 8 || start >= freq)
+ break;
+ // break; // change it
+ numMilCommands <<= 1;
+ }
+ }
+ }
+
+ if (printCallback)
+ {
+ printCallback->NewLine();
+ printCallback->NewLine();
+ PrintRequirements(*printCallback, "size: ", ramSize_Defined, ramSize, "CPU hardware threads:", numCPUs);
+ }
+
+ if (numThreadsSpecified < 1 || numThreadsSpecified > kNumThreadsMax)
+ return E_INVALIDARG;
+
UInt32 dict;
bool dictIsDefined = method.Get_DicSize(dict);
if (method.MethodName.IsEmpty())
- method.MethodName = L"LZMA";
+ method.MethodName = "LZMA";
if (benchCallback)
{
@@ -1462,12 +2660,20 @@ HRESULT Bench(
UInt32 uncompressedDataSize = kAdditionalSize + dictSize;
return MethodBench(
EXTERNAL_CODECS_LOC_VARS
- true, numThreads,
- method, uncompressedDataSize,
+ complexInCommands,
+ true, numThreadsSpecified,
+ method,
+ uncompressedDataSize, fileDataBuffer.Buffer,
kOldLzmaDictBits, printCallback, benchCallback, &benchProps);
}
- if (method.MethodName.CompareNoCase(L"CRC") == 0)
+ AString methodName = method.MethodName;
+ if (methodName.IsEqualTo_Ascii_NoCase("CRC"))
+ methodName = "crc32";
+ method.MethodName = methodName;
+ CMethodId hashID;
+
+ if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, hashID))
{
if (!printCallback)
return S_FALSE;
@@ -1475,33 +2681,80 @@ HRESULT Bench(
if (!dictIsDefined)
dict = (1 << 24);
- CTempValues speedTotals(numThreads);
+
+ // methhodName.RemoveChar(L'-');
+ UInt32 complexity = 10000;
+ const UInt32 *checkSum = NULL;
+ {
+ for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++)
+ {
+ const CBenchHash &h = g_Hash[i];
+ AString s = h.Name;
+ AString hProp;
+ int propPos = s.Find(':');
+ if (propPos >= 0)
+ {
+ hProp = s.Ptr(propPos + 1);
+ s.DeleteFrom(propPos);
+ }
+
+ if (AreSameMethodNames(s, methodName))
+ {
+ complexity = h.Complex;
+ checkSum = &h.CheckSum;
+ if (method.PropsString.IsEqualTo_Ascii_NoCase(hProp))
+ break;
+ }
+ }
+ }
+
f.NewLine();
f.Print("Size");
- for (UInt32 ti = 0; ti < numThreads; ti++)
+ const int kFieldSize_CrcSpeed = 6;
+ unsigned numThreadsTests = 0;
+ for (;;)
{
- PrintNumber(f, ti + 1, 5);
- speedTotals.Values[ti] = 0;
+ UInt32 t = GetNumThreadsNext(numThreadsTests, numThreadsSpecified);
+ PrintNumber(f, t, kFieldSize_CrcSpeed);
+ numThreadsTests++;
+ if (t >= numThreadsSpecified)
+ break;
}
f.NewLine();
f.NewLine();
+ CTempValues speedTotals(numThreadsTests);
+ {
+ for (unsigned ti = 0; ti < numThreadsTests; ti++)
+ speedTotals.Values[ti] = 0;
+ }
UInt64 numSteps = 0;
for (UInt32 i = 0; i < numIterations; i++)
{
- for (int pow = 10; pow < 32; pow++)
+ for (unsigned pow = 10; pow < 32; pow++)
{
UInt32 bufSize = (UInt32)1 << pow;
if (bufSize > dict)
break;
- PrintNumber(f, pow, 2, false);
- f.Print(": ");
- for (UInt32 ti = 0; ti < numThreads; ti++)
+ char s[16];
+ ConvertUInt32ToString(pow, s);
+ unsigned pos = MyStringLen(s);
+ s[pos++] = ':';
+ s[pos++] = ' ';
+ s[pos] = 0;
+ f.Print(s);
+
+ for (unsigned ti = 0; ti < numThreadsTests; ti++)
{
RINOK(f.CheckBreak());
- UInt64 speed;
- RINOK(CrcBench(ti + 1, bufSize, speed));
- PrintNumber(f, (speed >> 20), 5);
+ UInt32 t = GetNumThreadsNext(ti, numThreadsSpecified);
+ UInt64 speed = 0;
+ RINOK(CrcBench(EXTERNAL_CODECS_LOC_VARS complexInCommands,
+ t, bufSize, speed,
+ complexity,
+ 1, // benchWeight,
+ (pow == kNumHashDictBits) ? checkSum : NULL, method, NULL, NULL, false, 0));
+ PrintNumber(f, (speed >> 20), kFieldSize_CrcSpeed);
speedTotals.Values[ti] += speed;
}
f.NewLine();
@@ -1512,100 +2765,302 @@ HRESULT Bench(
{
f.NewLine();
f.Print("Avg:");
- for (UInt32 ti = 0; ti < numThreads; ti++)
- PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), 5);
+ for (unsigned ti = 0; ti < numThreadsTests; ti++)
+ {
+ PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), kFieldSize_CrcSpeed);
+ }
f.NewLine();
}
return S_OK;
}
+ bool use2Columns = false;
+
+ bool totalBenchMode = (method.MethodName.IsEqualTo_Ascii_NoCase("*"));
+ bool onlyHashBench = false;
+ if (method.MethodName.IsEqualTo_Ascii_NoCase("hash"))
+ {
+ onlyHashBench = true;
+ totalBenchMode = true;
+ }
+
+ // ---------- Threads loop ----------
+ for (unsigned threadsPassIndex = 0; threadsPassIndex < 3; threadsPassIndex++)
+ {
+
+ UInt32 numThreads = numThreadsSpecified;
+
+ if (!multiThreadTests)
+ {
+ if (threadsPassIndex != 0)
+ break;
+ }
+ else
+ {
+ numThreads = 1;
+ if (threadsPassIndex != 0)
+ {
+ if (numCPUs < 2)
+ break;
+ numThreads = numCPUs;
+ if (threadsPassIndex == 1)
+ {
+ if (numCPUs >= 4)
+ numThreads = numCPUs / 2;
+ }
+ else if (numCPUs < 4)
+ break;
+ }
+ }
+
CBenchCallbackToPrint callback;
callback.Init();
callback._file = printCallback;
+
+ IBenchPrintCallback &f = *printCallback;
+
+ if (threadsPassIndex > 0)
+ {
+ f.NewLine();
+ f.NewLine();
+ }
if (!dictIsDefined)
{
- int dicSizeLog;
- for (dicSizeLog = 25; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)
- if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog)) + (8 << 20) <= ramSize)
+ const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25);
+ unsigned dicSizeLog = dicSizeLog_Main;
+
+ #ifdef UNDER_CE
+ dicSizeLog = (UInt64)1 << 20;
+ #endif
+
+ if (ramSize_Defined)
+ for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)
+ if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize)
break;
- dict = (1 << dicSizeLog);
+
+ dict = (UInt32)1 << dicSizeLog;
+
+ if (totalBenchMode && dicSizeLog != dicSizeLog_Main)
+ {
+ f.Print("Dictionary reduced to: ");
+ PrintNumber(f, dicSizeLog, 1);
+ f.NewLine();
+ }
}
- IBenchPrintCallback &f = *printCallback;
- PrintRequirements(f, "usage:", GetBenchMemoryUsage(numThreads, dict), "Benchmark threads: ", numThreads);
+ PrintRequirements(f, "usage:", true, GetBenchMemoryUsage(numThreads, dict, totalBenchMode), "Benchmark threads: ", numThreads);
- bool totalBenchMode = (method.MethodName == L"*");
f.NewLine();
- f.Print(totalBenchMode ? "Method " : "Dict");
- f.Print(" Compressing | Decompressing");
+
+ if (totalBenchMode)
+ {
+ callback.NameFieldSize = kFieldSize_Name;
+ use2Columns = false;
+ }
+ else
+ {
+ callback.NameFieldSize = kFieldSize_SmallName;
+ use2Columns = true;
+ }
+ callback.Use2Columns = use2Columns;
+
+ bool showFreq = false;
+ UInt64 cpuFreq = 0;
+
+ if (totalBenchMode)
+ {
+ showFreq = true;
+ }
+
+ int fileldSize = kFieldSize_TotalSize;
+ if (showFreq)
+ fileldSize += kFieldSize_EUAndEffec;
+
+ if (use2Columns)
+ {
+ PrintSpaces(f, callback.NameFieldSize);
+ PrintRight(f, "Compressing", fileldSize);
+ f.Print(kSep);
+ PrintRight(f, "Decompressing", fileldSize);
+ }
f.NewLine();
- const char *kSpaces = totalBenchMode ? " " : " ";
- f.Print(kSpaces);
+ PrintLeft(f, totalBenchMode ? "Method" : "Dict", callback.NameFieldSize);
+
int j;
-
+
for (j = 0; j < 2; j++)
{
- f.Print(" Speed Usage R/U Rating");
+ PrintRight(f, "Speed", kFieldSize_Speed + 1);
+ PrintRight(f, "Usage", kFieldSize_Usage + 1);
+ PrintRight(f, "R/U", kFieldSize_RU + 1);
+ PrintRight(f, "Rating", kFieldSize_Rating + 1);
+ if (showFreq)
+ {
+ PrintRight(f, "E/U", kFieldSize_EU + 1);
+ PrintRight(f, "Effec", kFieldSize_Effec + 1);
+ }
+ if (!use2Columns)
+ break;
if (j == 0)
f.Print(kSep);
}
+
f.NewLine();
- f.Print(kSpaces);
+ PrintSpaces(f, callback.NameFieldSize);
+
for (j = 0; j < 2; j++)
{
- f.Print(" KB/s % MIPS MIPS");
+ PrintRight(f, "KiB/s", kFieldSize_Speed + 1);
+ PrintRight(f, "%", kFieldSize_Usage + 1);
+ PrintRight(f, "MIPS", kFieldSize_RU + 1);
+ PrintRight(f, "MIPS", kFieldSize_Rating + 1);
+ if (showFreq)
+ {
+ PrintRight(f, "%", kFieldSize_EU + 1);
+ PrintRight(f, "%", kFieldSize_Effec + 1);
+ }
+ if (!use2Columns)
+ break;
if (j == 0)
f.Print(kSep);
}
+
f.NewLine();
f.NewLine();
+ if (specifiedFreq != 0)
+ cpuFreq = specifiedFreq;
+
+
if (totalBenchMode)
{
- if (!dictIsDefined)
- dict =
- #ifdef UNDER_CE
- (UInt64)1 << 20;
- #else
- (UInt64)1 << 24;
- #endif
for (UInt32 i = 0; i < numIterations; i++)
{
if (i != 0)
printCallback->NewLine();
- HRESULT res = TotalBench(
- EXTERNAL_CODECS_LOC_VARS
- numThreads, dict, printCallback, &callback);
+ HRESULT res;
+
+ int freqTest;
+ const int kNumCpuTests = 3;
+ for (freqTest = 0; freqTest < kNumCpuTests; freqTest++)
+ {
+ PrintLeft(f, "CPU", kFieldSize_Name);
+ UInt32 resVal;
+ RINOK(FreqBench(complexInCommands, numThreads, printCallback,
+ (freqTest == kNumCpuTests - 1 || specifiedFreq != 0), // showFreq
+ specifiedFreq,
+ cpuFreq, resVal));
+ callback.NewLine();
+
+ if (specifiedFreq != 0)
+ cpuFreq = specifiedFreq;
+
+ if (freqTest == kNumCpuTests - 1)
+ SetComplexCommands(testTime, specifiedFreq != 0, cpuFreq, complexInCommands);
+ }
+ callback.NewLine();
+
+ callback.SetFreq(true, cpuFreq);
+
+ if (!onlyHashBench)
+ {
+ res = TotalBench(EXTERNAL_CODECS_LOC_VARS
+ complexInCommands, numThreads,
+ dictIsDefined || fileDataBuffer.Buffer, // forceUnpackSize
+ fileDataBuffer.Buffer ? fileDataBuffer.BufferSize : dict,
+ fileDataBuffer.Buffer,
+ printCallback, &callback);
+ RINOK(res);
+ }
+
+ res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS complexInCommands, numThreads,
+ 1 << kNumHashDictBits, printCallback, &callback, &callback.EncodeRes, true, cpuFreq);
RINOK(res);
+
+ callback.NewLine();
+ {
+ PrintLeft(f, "CPU", kFieldSize_Name);
+ UInt32 resVal;
+ UInt64 cpuFreqLastTemp = cpuFreq;
+ RINOK(FreqBench(complexInCommands, numThreads, printCallback,
+ specifiedFreq != 0, // showFreq
+ specifiedFreq,
+ cpuFreqLastTemp, resVal));
+ callback.NewLine();
+ }
}
}
else
{
+ bool needSetComplexity = true;
+ if (!methodName.IsEqualTo_Ascii_NoCase("LZMA"))
+ {
+ for (unsigned i = 0; i < ARRAY_SIZE(g_Bench); i++)
+ {
+ const CBenchMethod &h = g_Bench[i];
+ AString s = h.Name;
+ if (AreSameMethodNames(h.Name, methodName))
+ {
+ callback.BenchProps.EncComplex = h.EncComplex;
+ callback.BenchProps.DecComplexCompr = h.DecComplexCompr;
+ callback.BenchProps.DecComplexUnc = h.DecComplexUnc;;
+ needSetComplexity = false;
+ break;
+ }
+ }
+ }
+ if (needSetComplexity)
+ callback.BenchProps.SetLzmaCompexity();
- callback.BenchProps.SetLzmaCompexity();
-
- for (i = 0; i < (int)numIterations; i++)
+ for (i = 0; i < numIterations; i++)
{
- const int kStartDicLog = 22;
- int pow = (dict < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog;
+ const unsigned kStartDicLog = 22;
+ unsigned pow = (dict < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog;
if (!multiDict)
pow = 31;
- while (((UInt32)1 << pow) > dict)
+ while (((UInt32)1 << pow) > dict && pow > 0)
pow--;
for (; ((UInt32)1 << pow) <= dict; pow++)
{
- PrintNumber(f, pow, 2, false);
- f.Print(":");
+ char s[16];
+ ConvertUInt32ToString(pow, s);
+ unsigned pos = MyStringLen(s);
+ s[pos++] = ':';
+ s[pos] = 0;
+ PrintLeft(f, s, kFieldSize_SmallName);
callback.DictSize = (UInt32)1 << pow;
- UInt32 uncompressedDataSize = kAdditionalSize + callback.DictSize;
+ COneMethodInfo method2 = method;
+
+ if (StringsAreEqualNoCase_Ascii(method2.MethodName, "LZMA"))
+ {
+ // We add dictionary size property.
+ // method2 can have two different dictionary size properties.
+ // And last property is main.
+ NCOM::CPropVariant propVariant = (UInt32)pow;
+ RINOK(method2.ParseMethodFromPROPVARIANT(L"d", propVariant));
+ }
+
+ size_t uncompressedDataSize;
+ if (fileDataBuffer.Buffer)
+ {
+ uncompressedDataSize = fileDataBuffer.BufferSize;
+ }
+ else
+ {
+ uncompressedDataSize = callback.DictSize;
+ if (uncompressedDataSize >= (1 << 18))
+ uncompressedDataSize += kAdditionalSize;
+ }
HRESULT res = MethodBench(
- EXTERNAL_CODECS_LOC_VARS
- true, numThreads,
- method, uncompressedDataSize,
- kOldLzmaDictBits, printCallback, &callback, &callback.BenchProps);
+ EXTERNAL_CODECS_LOC_VARS
+ complexInCommands,
+ true, numThreads,
+ method2,
+ uncompressedDataSize, fileDataBuffer.Buffer,
+ kOldLzmaDictBits, printCallback, &callback, &callback.BenchProps);
f.NewLine();
RINOK(res);
if (!multiDict)
@@ -1613,21 +3068,32 @@ HRESULT Bench(
}
}
}
- callback.Normalize();
- f.Print("----------------------------------------------------------------");
- f.NewLine();
- f.Print("Avr:");
- const char *kSpaces2 = totalBenchMode ? " " : "";
- f.Print(kSpaces2);
- PrintTotals(f, callback.EncodeRes);
- f.Print(" ");
- PrintTotals(f, callback.DecodeRes);
+
+ PrintChars(f, '-', callback.NameFieldSize + fileldSize);
+
+ if (use2Columns)
+ {
+ f.Print(kSep);
+ PrintChars(f, '-', fileldSize);
+ }
+
f.NewLine();
- f.Print("Tot:");
- f.Print(kSpaces2);
+
+ if (use2Columns)
+ {
+ PrintLeft(f, "Avr:", callback.NameFieldSize);
+ PrintTotals(f, showFreq, cpuFreq, callback.EncodeRes);
+ f.Print(kSep);
+ PrintTotals(f, showFreq, cpuFreq, callback.DecodeRes);
+ f.NewLine();
+ }
+
+ PrintLeft(f, "Tot:", callback.NameFieldSize);
CTotalBenchRes midRes;
- midRes.SetMid(callback.EncodeRes, callback.DecodeRes);
- PrintTotals(f, midRes);
+ midRes.SetSum(callback.EncodeRes, callback.DecodeRes);
+ PrintTotals(f, showFreq, cpuFreq, midRes);
f.NewLine();
+
+ }
return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Bench.h b/3rdparty/lzma/CPP/7zip/UI/Common/Bench.h
index 46146e24e1a..841250ef2cc 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/Bench.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/Bench.h
@@ -14,25 +14,27 @@ struct CBenchInfo
UInt64 UserFreq;
UInt64 UnpackSize;
UInt64 PackSize;
- UInt32 NumIterations;
+ UInt64 NumIterations;
CBenchInfo(): NumIterations(0) {}
UInt64 GetUsage() const;
UInt64 GetRatingPerUsage(UInt64 rating) const;
+ UInt64 GetSpeed(UInt64 numCommands) const;
};
struct IBenchCallback
{
+ virtual HRESULT SetFreq(bool showFreq, UInt64 cpuFreq) = 0;
virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0;
virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0;
};
UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
-UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations);
+UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations);
-const int kBenchMinDicLogSize = 18;
+const unsigned kBenchMinDicLogSize = 18;
-UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary);
+UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary, bool totalBench = false);
struct IBenchPrintCallback
{
@@ -45,7 +47,7 @@ HRESULT Bench(
DECL_EXTERNAL_CODECS_LOC_VARS
IBenchPrintCallback *printCallback,
IBenchCallback *benchCallback,
- const CObjectVector<CProperty> props,
+ const CObjectVector<CProperty> &props,
UInt32 numIterations,
bool multiDict
);
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.cpp
index 4335e273154..02f611c3d18 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.cpp
@@ -7,21 +7,23 @@
static UString GetDefaultName3(const UString &fileName,
const UString &extension, const UString &addSubExtension)
{
- int extLength = extension.Length();
- int fileNameLength = fileName.Length();
- if (fileNameLength > extLength + 1)
+ const unsigned extLen = extension.Len();
+ const unsigned fileNameLen = fileName.Len();
+
+ if (fileNameLen > extLen + 1)
{
- int dotPos = fileNameLength - (extLength + 1);
+ const unsigned dotPos = fileNameLen - (extLen + 1);
if (fileName[dotPos] == '.')
- if (extension.CompareNoCase(fileName.Mid(dotPos + 1)) == 0)
+ if (extension.IsEqualTo_NoCase(fileName.Ptr(dotPos + 1)))
return fileName.Left(dotPos) + addSubExtension;
}
- int dotPos = fileName.ReverseFind(L'.');
+
+ int dotPos = fileName.ReverseFind_Dot();
if (dotPos > 0)
return fileName.Left(dotPos) + addSubExtension;
if (addSubExtension.IsEmpty())
- return fileName + L"~";
+ return fileName + L'~';
else
return fileName + addSubExtension;
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.h b/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.h
index 9764ff8716b..df164560275 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.h
@@ -1,9 +1,9 @@
// DefaultName.h
-#ifndef __DEFAULTNAME_H
-#define __DEFAULTNAME_H
+#ifndef __DEFAULT_NAME_H
+#define __DEFAULT_NAME_H
-#include "Common/MyString.h"
+#include "../../../Common/MyString.h"
UString GetDefaultName2(const UString &fileName,
const UString &extension, const UString &addSubExtension);
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/DirItem.h b/3rdparty/lzma/CPP/7zip/UI/Common/DirItem.h
index 6d6dc673465..4286b4e8db0 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/DirItem.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/DirItem.h
@@ -3,10 +3,46 @@
#ifndef __DIR_ITEM_H
#define __DIR_ITEM_H
-#include "Common/MyString.h"
-#include "Common/Types.h"
+#include "../../../Common/MyString.h"
+
+#include "../../../Windows/FileFind.h"
+
+#include "../../Common/UniqBlocks.h"
+
#include "../../Archive/IArchive.h"
+struct CDirItemsStat
+{
+ UInt64 NumDirs;
+ UInt64 NumFiles;
+ UInt64 NumAltStreams;
+ UInt64 FilesSize;
+ UInt64 AltStreamsSize;
+
+ UInt64 NumErrors;
+ // UInt64 GetTotalItems() const { return NumDirs + NumFiles + NumAltStreams; }
+
+ UInt64 GetTotalBytes() const { return FilesSize + AltStreamsSize; }
+
+ CDirItemsStat():
+ NumDirs(0),
+ NumFiles(0),
+ NumAltStreams(0),
+ FilesSize(0),
+ AltStreamsSize(0),
+ NumErrors(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; \
+
+struct IDirItemsCallback
+{
+ INTERFACE_IDirItemsCallback(=0)
+};
+
struct CDirItem
{
UInt64 Size;
@@ -14,11 +50,23 @@ struct CDirItem
FILETIME ATime;
FILETIME MTime;
UString Name;
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // UString ShortName;
+ CByteBuffer ReparseData;
+ CByteBuffer ReparseData2; // fixed (reduced) absolute links
+
+ bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; }
+ #endif
+
UInt32 Attrib;
int PhyParent;
int LogParent;
+ int SecureIndex;
+
+ bool IsAltStream;
- CDirItem(): PhyParent(-1), LogParent(-1) {}
+ CDirItem(): PhyParent(-1), LogParent(-1), SecureIndex(-1), IsAltStream(false) {}
bool IsDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
};
@@ -29,24 +77,63 @@ class CDirItems
CIntVector LogParents;
UString GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const;
+
+ HRESULT EnumerateDir(int phyParent, int logParent, const FString &phyPrefix);
+
public:
CObjectVector<CDirItem> Items;
- int GetNumFolders() const { return Prefixes.Size(); }
- UString GetPhyPath(int index) const;
- UString GetLogPath(int index) const;
+ bool SymLinks;
- int AddPrefix(int phyParent, int logParent, const UString &prefix);
- void DeleteLastPrefix();
+ bool ScanAltStreams;
+
+ CDirItemsStat Stat;
+
+ #ifndef UNDER_CE
+ HRESULT SetLinkInfo(CDirItem &dirItem, const NWindows::NFile::NFind::CFileInfo &fi,
+ const FString &phyPrefix);
+ #endif
+
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+
+ CUniqBlocks SecureBlocks;
+ CByteBuffer TempSecureBuf;
+ bool _saclEnabled;
+ bool ReadSecure;
+
+ HRESULT AddSecurityItem(const FString &path, int &secureIndex);
+
+ #endif
- void EnumerateDirectory(int phyParent, int logParent, const FString &phyPrefix,
- FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes);
+ IDirItemsCallback *Callback;
- void EnumerateDirItems2(
+ CDirItems();
+
+ void AddDirFileInfo(int phyParent, int logParent, int secureIndex,
+ const NWindows::NFile::NFind::CFileInfo &fi);
+
+ HRESULT AddError(const FString &path, DWORD errorCode);
+ HRESULT AddError(const FString &path);
+
+ HRESULT ScanProgress(const FString &path);
+
+ // unsigned GetNumFolders() const { return Prefixes.Size(); }
+ FString GetPhyPath(unsigned index) const;
+ UString GetLogPath(unsigned index) const;
+
+ unsigned AddPrefix(int phyParent, int logParent, const UString &prefix);
+ void DeleteLastPrefix();
+
+ HRESULT EnumerateItems2(
const FString &phyPrefix,
const UString &logPrefix,
const FStringVector &filePaths,
- FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes);
+ FStringVector *requestedPaths);
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ void FillFixedReparse();
+ #endif
void ReserveDown();
};
@@ -57,13 +144,14 @@ struct CArcItem
FILETIME MTime;
UString Name;
bool IsDir;
+ bool IsAltStream;
bool SizeDefined;
bool MTimeDefined;
bool Censored;
UInt32 IndexInServer;
int TimeType;
- CArcItem(): IsDir(false), SizeDefined(false), MTimeDefined(false), Censored(false), TimeType(-1) {}
+ CArcItem(): IsDir(false), IsAltStream(false), SizeDefined(false), MTimeDefined(false), Censored(false), TimeType(-1) {}
};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp
index 8c83a9fbdc0..3ebf25aad8f 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp
@@ -2,7 +2,18 @@
#include "StdAfx.h"
-#include "Windows/FileName.h"
+#include <wchar.h>
+
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileIO.h"
+#include "../../../Windows/FileName.h"
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+#define _USE_SECURITY_CODE
+#include "../../../Windows/SecurityUtils.h"
+#endif
#include "EnumDirItems.h"
@@ -10,8 +21,8 @@ using namespace NWindows;
using namespace NFile;
using namespace NName;
-void AddDirFileInfo(int phyParent, int logParent,
- const NFind::CFileInfo &fi, CObjectVector<CDirItem> &dirItems)
+void CDirItems::AddDirFileInfo(int phyParent, int logParent, int secureIndex,
+ const NFind::CFileInfo &fi)
{
CDirItem di;
di.Size = fi.Size;
@@ -19,41 +30,83 @@ void AddDirFileInfo(int phyParent, int logParent,
di.ATime = fi.ATime;
di.MTime = fi.MTime;
di.Attrib = fi.Attrib;
+ di.IsAltStream = fi.IsAltStream;
di.PhyParent = phyParent;
di.LogParent = logParent;
+ di.SecureIndex = secureIndex;
di.Name = fs2us(fi.Name);
- dirItems.Add(di);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // di.ShortName = fs2us(fi.ShortName);
+ #endif
+ Items.Add(di);
+
+ if (fi.IsDir())
+ Stat.NumDirs++;
+ else if (fi.IsAltStream)
+ {
+ Stat.NumAltStreams++;
+ Stat.AltStreamsSize += fi.Size;
+ }
+ else
+ {
+ Stat.NumFiles++;
+ Stat.FilesSize += fi.Size;
+ }
+}
+
+HRESULT CDirItems::AddError(const FString &path, DWORD errorCode)
+{
+ Stat.NumErrors++;
+ if (Callback)
+ return Callback->ScanError(path, errorCode);
+ return S_OK;
+}
+
+HRESULT CDirItems::AddError(const FString &path)
+{
+ return AddError(path, ::GetLastError());
+}
+
+static const unsigned kScanProgressStepMask = (1 << 12) - 1;
+
+HRESULT CDirItems::ScanProgress(const FString &dirPath)
+{
+ if (Callback)
+ return Callback->ScanProgress(Stat, dirPath, true);
+ return S_OK;
}
UString CDirItems::GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const
{
UString path;
- int len = name.Length();
+ unsigned len = name.Len();
+
int i;
for (i = index; i >= 0; i = parents[i])
- len += Prefixes[i].Length();
- int totalLen = len;
- wchar_t *p = path.GetBuffer(len);
- p[len] = 0;
- len -= name.Length();
- memcpy(p + len, (const wchar_t *)name, name.Length() * sizeof(wchar_t));
+ len += Prefixes[i].Len();
+
+ wchar_t *p = path.GetBuf_SetEnd(len) + len;
+
+ p -= name.Len();
+ wmemcpy(p, (const wchar_t *)name, name.Len());
+
for (i = index; i >= 0; i = parents[i])
{
const UString &s = Prefixes[i];
- len -= s.Length();
- memcpy(p + len, (const wchar_t *)s, s.Length() * sizeof(wchar_t));
+ p -= s.Len();
+ wmemcpy(p, (const wchar_t *)s, s.Len());
}
- path.ReleaseBuffer(totalLen);
+
return path;
}
-UString CDirItems::GetPhyPath(int index) const
+FString CDirItems::GetPhyPath(unsigned index) const
{
const CDirItem &di = Items[index];
- return GetPrefixesPath(PhyParents, di.PhyParent, di.Name);
+ return us2fs(GetPrefixesPath(PhyParents, di.PhyParent, di.Name));
}
-UString CDirItems::GetLogPath(int index) const
+UString CDirItems::GetLogPath(unsigned index) const
{
const CDirItem &di = Items[index];
return GetPrefixesPath(LogParents, di.LogParent, di.Name);
@@ -67,7 +120,7 @@ void CDirItems::ReserveDown()
Items.ReserveDown();
}
-int CDirItems::AddPrefix(int phyParent, int logParent, const UString &prefix)
+unsigned CDirItems::AddPrefix(int phyParent, int logParent, const UString &prefix)
{
PhyParents.Add(phyParent);
LogParents.Add(logParent);
@@ -81,150 +134,473 @@ void CDirItems::DeleteLastPrefix()
Prefixes.DeleteBack();
}
-void CDirItems::EnumerateDirectory(int phyParent, int logParent, const FString &phyPrefix,
- FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)
+bool InitLocalPrivileges();
+
+CDirItems::CDirItems():
+ SymLinks(false),
+ ScanAltStreams(false)
+ #ifdef _USE_SECURITY_CODE
+ , ReadSecure(false)
+ #endif
+ , Callback(NULL)
{
+ #ifdef _USE_SECURITY_CODE
+ _saclEnabled = InitLocalPrivileges();
+ #endif
+}
+
+#ifdef _USE_SECURITY_CODE
+
+HRESULT CDirItems::AddSecurityItem(const FString &path, int &secureIndex)
+{
+ secureIndex = -1;
+
+ SECURITY_INFORMATION securInfo =
+ DACL_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ OWNER_SECURITY_INFORMATION;
+ if (_saclEnabled)
+ securInfo |= SACL_SECURITY_INFORMATION;
+
+ DWORD errorCode = 0;
+ DWORD secureSize;
+
+ BOOL res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize);
+
+ if (res)
+ {
+ if (secureSize == 0)
+ return S_OK;
+ if (secureSize > TempSecureBuf.Size())
+ errorCode = ERROR_INVALID_FUNCTION;
+ }
+ else
+ {
+ errorCode = GetLastError();
+ if (errorCode == ERROR_INSUFFICIENT_BUFFER)
+ {
+ if (secureSize <= TempSecureBuf.Size())
+ errorCode = ERROR_INVALID_FUNCTION;
+ else
+ {
+ TempSecureBuf.Alloc(secureSize);
+ res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize);
+ if (res)
+ {
+ if (secureSize != TempSecureBuf.Size())
+ errorCode = ERROR_INVALID_FUNCTION;;
+ }
+ else
+ errorCode = GetLastError();
+ }
+ }
+ }
+
+ if (res)
+ {
+ secureIndex = SecureBlocks.AddUniq(TempSecureBuf, secureSize);
+ return S_OK;
+ }
+
+ if (errorCode == 0)
+ errorCode = ERROR_INVALID_FUNCTION;
+ return AddError(path, errorCode);
+}
+
+#endif
+
+HRESULT CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phyPrefix)
+{
+ RINOK(ScanProgress(phyPrefix));
+
NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
- for (;;)
+ for (unsigned ttt = 0; ; ttt++)
{
NFind::CFileInfo fi;
bool found;
if (!enumerator.Next(fi, found))
{
- errorCodes.Add(::GetLastError());
- errorPaths.Add(phyPrefix);
- return;
+ return AddError(phyPrefix);
}
if (!found)
- break;
- AddDirFileInfo(phyParent, logParent, fi, Items);
+ return S_OK;
+
+ int secureIndex = -1;
+ #ifdef _USE_SECURITY_CODE
+ if (ReadSecure)
+ {
+ RINOK(AddSecurityItem(phyPrefix + fi.Name, secureIndex));
+ }
+ #endif
+
+ AddDirFileInfo(phyParent, logParent, secureIndex, fi);
+
+ if (Callback && (ttt & kScanProgressStepMask) == kScanProgressStepMask)
+ {
+ RINOK(ScanProgress(phyPrefix));
+ }
+
if (fi.IsDir())
{
const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR;
- int parent = AddPrefix(phyParent, logParent, fs2us(name2));
- EnumerateDirectory(parent, parent, phyPrefix + name2, errorPaths, errorCodes);
+ unsigned parent = AddPrefix(phyParent, logParent, fs2us(name2));
+ RINOK(EnumerateDir(parent, parent, phyPrefix + name2));
}
}
}
-void CDirItems::EnumerateDirItems2(const FString &phyPrefix, const UString &logPrefix,
- const FStringVector &filePaths, FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)
+HRESULT CDirItems::EnumerateItems2(
+ const FString &phyPrefix,
+ const UString &logPrefix,
+ const FStringVector &filePaths,
+ FStringVector *requestedPaths)
{
int phyParent = phyPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, fs2us(phyPrefix));
int logParent = logPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, logPrefix);
- for (int i = 0; i < filePaths.Size(); i++)
+ FOR_VECTOR (i, filePaths)
{
const FString &filePath = filePaths[i];
NFind::CFileInfo fi;
const FString phyPath = phyPrefix + filePath;
if (!fi.Find(phyPath))
{
- errorCodes.Add(::GetLastError());
- errorPaths.Add(phyPath);
+ RINOK(AddError(phyPath));
continue;
}
- int delimiter = filePath.ReverseFind(FCHAR_PATH_SEPARATOR);
+ if (requestedPaths)
+ requestedPaths->Add(phyPath);
+
+ int delimiter = filePath.ReverseFind_PathSepar();
FString phyPrefixCur;
int phyParentCur = phyParent;
if (delimiter >= 0)
{
- phyPrefixCur = filePath.Left(delimiter + 1);
+ phyPrefixCur.SetFrom(filePath, delimiter + 1);
phyParentCur = AddPrefix(phyParent, logParent, fs2us(phyPrefixCur));
}
- AddDirFileInfo(phyParentCur, logParent, fi, Items);
+
+ int secureIndex = -1;
+ #ifdef _USE_SECURITY_CODE
+ if (ReadSecure)
+ {
+ RINOK(AddSecurityItem(phyPath, secureIndex));
+ }
+ #endif
+
+ AddDirFileInfo(phyParentCur, logParent, secureIndex, fi);
+
if (fi.IsDir())
{
const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR;
- int parent = AddPrefix(phyParentCur, logParent, fs2us(name2));
- EnumerateDirectory(parent, parent, phyPrefix + phyPrefixCur + name2, errorPaths, errorCodes);
+ unsigned parent = AddPrefix(phyParentCur, logParent, fs2us(name2));
+ RINOK(EnumerateDir(parent, parent, phyPrefix + phyPrefixCur + name2));
}
}
+
ReserveDown();
+ return S_OK;
}
-static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
+
+
+
+
+
+static HRESULT EnumerateDirItems(
+ const NWildcard::CCensorNode &curNode,
int phyParent, int logParent, const FString &phyPrefix,
const UStringVector &addArchivePrefix,
CDirItems &dirItems,
- bool enterToSubFolders,
- IEnumDirItemCallback *callback,
- FStringVector &errorPaths,
- CRecordVector<DWORD> &errorCodes);
+ bool enterToSubFolders);
-static HRESULT EnumerateDirItems_Spec(const NWildcard::CCensorNode &curNode,
+static HRESULT EnumerateDirItems_Spec(
+ const NWildcard::CCensorNode &curNode,
int phyParent, int logParent, const FString &curFolderName,
const FString &phyPrefix,
const UStringVector &addArchivePrefix,
CDirItems &dirItems,
- bool enterToSubFolders,
- IEnumDirItemCallback *callback,
- FStringVector &errorPaths,
- CRecordVector<DWORD> &errorCodes)
-
+ bool enterToSubFolders)
{
const FString name2 = curFolderName + FCHAR_PATH_SEPARATOR;
- int parent = dirItems.AddPrefix(phyParent, logParent, fs2us(name2));
- int numItems = dirItems.Items.Size();
- HRESULT res = EnumerateDirItems(curNode, parent, parent, phyPrefix + name2,
- addArchivePrefix, dirItems, enterToSubFolders, callback, errorPaths, errorCodes);
+ unsigned parent = dirItems.AddPrefix(phyParent, logParent, fs2us(name2));
+ unsigned numItems = dirItems.Items.Size();
+ HRESULT res = EnumerateDirItems(
+ curNode, parent, parent, phyPrefix + name2,
+ addArchivePrefix, dirItems, enterToSubFolders);
if (numItems == dirItems.Items.Size())
dirItems.DeleteLastPrefix();
return res;
}
+#ifndef UNDER_CE
+
+#ifdef _WIN32
+
+static HRESULT EnumerateAltStreams(
+ const NFind::CFileInfo &fi,
+ const NWildcard::CCensorNode &curNode,
+ int phyParent, int logParent, const FString &fullPath,
+ const UStringVector &addArchivePrefix, // prefix from curNode
+ CDirItems &dirItems)
+{
+ NFind::CStreamEnumerator enumerator(fullPath);
+ for (;;)
+ {
+ NFind::CStreamInfo si;
+ bool found;
+ if (!enumerator.Next(si, found))
+ {
+ return dirItems.AddError(fullPath + FTEXT(":*")); // , (DWORD)E_FAIL
+ }
+ if (!found)
+ return S_OK;
+ if (si.IsMainStream())
+ continue;
+ UStringVector addArchivePrefixNew = addArchivePrefix;
+ UString reducedName = si.GetReducedName();
+ addArchivePrefixNew.Back() += reducedName;
+ if (curNode.CheckPathToRoot(false, addArchivePrefixNew, true))
+ continue;
+ NFind::CFileInfo fi2 = fi;
+ fi2.Name += us2fs(reducedName);
+ fi2.Size = si.Size;
+ fi2.Attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
+ fi2.IsAltStream = true;
+ dirItems.AddDirFileInfo(phyParent, logParent, -1, fi2);
+ }
+}
+
+#endif
+
+HRESULT CDirItems::SetLinkInfo(CDirItem &dirItem, const NFind::CFileInfo &fi,
+ const FString &phyPrefix)
+{
+ if (!SymLinks || !fi.HasReparsePoint())
+ return S_OK;
+ const FString path = phyPrefix + fi.Name;
+ CByteBuffer &buf = dirItem.ReparseData;
+ if (NIO::GetReparseData(path, buf))
+ {
+ CReparseAttr attr;
+ if (attr.Parse(buf, buf.Size()))
+ return S_OK;
+ }
+ DWORD res = ::GetLastError();
+ buf.Free();
+ return AddError(path , res);
+}
+
+#endif
-static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
+static HRESULT EnumerateForItem(
+ NFind::CFileInfo &fi,
+ const NWildcard::CCensorNode &curNode,
int phyParent, int logParent, const FString &phyPrefix,
const UStringVector &addArchivePrefix, // prefix from curNode
CDirItems &dirItems,
- bool enterToSubFolders,
- IEnumDirItemCallback *callback,
- FStringVector &errorPaths,
- CRecordVector<DWORD> &errorCodes)
+ bool enterToSubFolders)
+{
+ const UString name = fs2us(fi.Name);
+ bool enterToSubFolders2 = enterToSubFolders;
+ UStringVector addArchivePrefixNew = addArchivePrefix;
+ addArchivePrefixNew.Add(name);
+ {
+ UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);
+ if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fi.IsDir()))
+ return S_OK;
+ }
+ int dirItemIndex = -1;
+
+ if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fi.IsDir()))
+ {
+ int secureIndex = -1;
+ #ifdef _USE_SECURITY_CODE
+ if (dirItems.ReadSecure)
+ {
+ RINOK(dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex));
+ }
+ #endif
+
+ dirItemIndex = dirItems.Items.Size();
+ dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi);
+ if (fi.IsDir())
+ enterToSubFolders2 = true;
+ }
+
+ #ifndef UNDER_CE
+ if (dirItems.ScanAltStreams)
+ {
+ RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent,
+ phyPrefix + fi.Name,
+ addArchivePrefixNew, dirItems));
+ }
+
+ if (dirItemIndex >= 0)
+ {
+ CDirItem &dirItem = dirItems.Items[dirItemIndex];
+ RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix));
+ if (dirItem.ReparseData.Size() != 0)
+ return S_OK;
+ }
+ #endif
+
+ if (!fi.IsDir())
+ return S_OK;
+
+ const NWildcard::CCensorNode *nextNode = 0;
+ if (addArchivePrefix.IsEmpty())
+ {
+ int index = curNode.FindSubNode(name);
+ if (index >= 0)
+ nextNode = &curNode.SubNodes[index];
+ }
+ if (!enterToSubFolders2 && nextNode == 0)
+ return S_OK;
+
+ addArchivePrefixNew = addArchivePrefix;
+ if (nextNode == 0)
+ {
+ nextNode = &curNode;
+ addArchivePrefixNew.Add(name);
+ }
+
+ return EnumerateDirItems_Spec(
+ *nextNode, phyParent, logParent, fi.Name, phyPrefix,
+ addArchivePrefixNew,
+ dirItems,
+ enterToSubFolders2);
+}
+
+
+static bool CanUseFsDirect(const NWildcard::CCensorNode &curNode)
+{
+ FOR_VECTOR (i, curNode.IncludeItems)
+ {
+ const NWildcard::CItem &item = curNode.IncludeItems[i];
+ if (item.Recursive || item.PathParts.Size() != 1)
+ return false;
+ const UString &name = item.PathParts.Front();
+ /*
+ if (name.IsEmpty())
+ return false;
+ */
+
+ /* Windows doesn't support file name with wildcard
+ But if another system supports file name with wildcard,
+ and wildcard mode is disabled, we can ignore wildcard in name */
+ /*
+ if (!item.WildcardParsing)
+ continue;
+ */
+ if (DoesNameContainWildcard(name))
+ return false;
+ }
+ return true;
+}
+
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+static bool IsVirtualFsFolder(const FString &prefix, const UString &name)
+{
+ UString s = fs2us(prefix);
+ s += name;
+ s.Add_PathSepar();
+ return IsPathSepar(s[0]) && GetRootPrefixSize(s) == 0;
+}
+
+#endif
+
+static HRESULT EnumerateDirItems(
+ const NWildcard::CCensorNode &curNode,
+ int phyParent, int logParent, const FString &phyPrefix,
+ const UStringVector &addArchivePrefix, // prefix from curNode
+ CDirItems &dirItems,
+ bool enterToSubFolders)
{
if (!enterToSubFolders)
if (curNode.NeedCheckSubDirs())
enterToSubFolders = true;
- if (callback)
- RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), fs2us(phyPrefix)));
+
+ RINOK(dirItems.ScanProgress(phyPrefix));
// try direct_names case at first
if (addArchivePrefix.IsEmpty() && !enterToSubFolders)
{
- // check that all names are direct
- int i;
- for (i = 0; i < curNode.IncludeItems.Size(); i++)
- {
- const NWildcard::CItem &item = curNode.IncludeItems[i];
- if (item.Recursive || item.PathParts.Size() != 1)
- break;
- const UString &name = item.PathParts.Front();
- if (name.IsEmpty() || DoesNameContainWildCard(name))
- break;
- }
- if (i == curNode.IncludeItems.Size())
+ if (CanUseFsDirect(curNode))
{
// all names are direct (no wildcards)
// so we don't need file_system's dir enumerator
CRecordVector<bool> needEnterVector;
+ unsigned i;
+
for (i = 0; i < curNode.IncludeItems.Size(); i++)
{
const NWildcard::CItem &item = curNode.IncludeItems[i];
const UString &name = item.PathParts.Front();
- const FString fullPath = phyPrefix + us2fs(name);
+ FString fullPath = phyPrefix + us2fs(name);
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ bool needAltStreams = true;
+ #endif
+
+ #ifdef _USE_SECURITY_CODE
+ bool needSecurity = true;
+ #endif
+
+ if (phyPrefix.IsEmpty())
+ {
+ if (!item.ForFile)
+ {
+ /* we don't like some names for alt streams inside archive:
+ ":sname" for "\"
+ "c:::sname" for "C:\"
+ So we ignore alt streams for these cases */
+ if (name.IsEmpty())
+ {
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ needAltStreams = false;
+ #endif
+
+ /*
+ // do we need to ignore security info for "\\" folder ?
+ #ifdef _USE_SECURITY_CODE
+ needSecurity = false;
+ #endif
+ */
+
+ fullPath = FCHAR_PATH_SEPARATOR;
+ }
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ else if (item.IsDriveItem())
+ {
+ needAltStreams = false;
+ fullPath.Add_PathSepar();
+ }
+ #endif
+ }
+ }
+
NFind::CFileInfo fi;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (IsVirtualFsFolder(phyPrefix, name))
+ {
+ fi.SetAsDir();
+ fi.Name = us2fs(name);
+ }
+ else
+ #endif
if (!fi.Find(fullPath))
{
- errorCodes.Add(::GetLastError());
- errorPaths.Add(fullPath);
+ RINOK(dirItems.AddError(fullPath));
continue;
}
+
bool isDir = fi.IsDir();
if (isDir && !item.ForDir || !isDir && !item.ForFile)
{
- errorCodes.Add((DWORD)E_FAIL);
- errorPaths.Add(fullPath);
+ RINOK(dirItems.AddError(fullPath, (DWORD)E_FAIL));
continue;
}
{
@@ -233,7 +609,43 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
if (curNode.CheckPathToRoot(false, pathParts, !isDir))
continue;
}
- AddDirFileInfo(phyParent, logParent, fi, dirItems.Items);
+
+ int secureIndex = -1;
+ #ifdef _USE_SECURITY_CODE
+ if (needSecurity && dirItems.ReadSecure)
+ {
+ RINOK(dirItems.AddSecurityItem(fullPath, secureIndex));
+ }
+ #endif
+
+ dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi);
+
+ #ifndef UNDER_CE
+ {
+ CDirItem &dirItem = dirItems.Items.Back();
+ RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix));
+ if (dirItem.ReparseData.Size() != 0)
+ {
+ if (fi.IsAltStream)
+ dirItems.Stat.AltStreamsSize -= fi.Size;
+ else
+ dirItems.Stat.FilesSize -= fi.Size;
+ continue;
+ }
+ }
+ #endif
+
+
+ #ifndef UNDER_CE
+ if (needAltStreams && dirItems.ScanAltStreams)
+ {
+ UStringVector pathParts;
+ pathParts.Add(fs2us(fi.Name));
+ RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent,
+ fullPath, pathParts, dirItems));
+ }
+ #endif
+
if (!isDir)
continue;
@@ -254,110 +666,233 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
}
RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix,
- addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes));
+ addArchivePrefixNew, dirItems, true));
}
+
for (i = 0; i < curNode.SubNodes.Size(); i++)
{
if (i < needEnterVector.Size())
if (!needEnterVector[i])
continue;
const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
- const FString fullPath = phyPrefix + us2fs(nextNode.Name);
+ FString fullPath = phyPrefix + us2fs(nextNode.Name);
NFind::CFileInfo fi;
- if (!fi.Find(fullPath))
+
+ if (phyPrefix.IsEmpty())
{
- if (!nextNode.AreThereIncludeItems())
- continue;
- errorCodes.Add(::GetLastError());
- errorPaths.Add(fullPath);
- continue;
+ {
+ if (nextNode.Name.IsEmpty())
+ fullPath = FCHAR_PATH_SEPARATOR;
+ #ifdef _WIN32
+ else if (NWildcard::IsDriveColonName(nextNode.Name))
+ fullPath.Add_PathSepar();
+ #endif
+ }
}
- if (!fi.IsDir())
+
+ // we don't want to call fi.Find() for root folder or virtual folder
+ if (phyPrefix.IsEmpty() && nextNode.Name.IsEmpty()
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ || IsVirtualFsFolder(phyPrefix, nextNode.Name)
+ #endif
+ )
{
- errorCodes.Add((DWORD)E_FAIL);
- errorPaths.Add(fullPath);
- continue;
+ fi.SetAsDir();
+ fi.Name = us2fs(nextNode.Name);
+ }
+ else
+ {
+ if (!fi.Find(fullPath))
+ {
+ if (!nextNode.AreThereIncludeItems())
+ continue;
+ RINOK(dirItems.AddError(fullPath));
+ continue;
+ }
+
+ if (!fi.IsDir())
+ {
+ RINOK(dirItems.AddError(fullPath, (DWORD)E_FAIL));
+ continue;
+ }
}
RINOK(EnumerateDirItems_Spec(nextNode, phyParent, logParent, fi.Name, phyPrefix,
- UStringVector(), dirItems, false, callback, errorPaths, errorCodes));
+ UStringVector(), dirItems, false));
}
+
return S_OK;
}
}
+ #ifdef _WIN32
+ #ifndef UNDER_CE
+
+ // scan drives, if wildcard is "*:\"
+
+ if (phyPrefix.IsEmpty() && curNode.IncludeItems.Size() > 0)
+ {
+ unsigned i;
+ for (i = 0; i < curNode.IncludeItems.Size(); i++)
+ {
+ const NWildcard::CItem &item = curNode.IncludeItems[i];
+ if (item.PathParts.Size() < 1)
+ break;
+ const UString &name = item.PathParts.Front();
+ if (name.Len() != 2 || name[1] != ':')
+ break;
+ if (item.PathParts.Size() == 1)
+ if (item.ForFile || !item.ForDir)
+ break;
+ if (NWildcard::IsDriveColonName(name))
+ continue;
+ if (name[0] != '*' && name[0] != '?')
+ break;
+ }
+ if (i == curNode.IncludeItems.Size())
+ {
+ FStringVector driveStrings;
+ NFind::MyGetLogicalDriveStrings(driveStrings);
+ for (i = 0; i < driveStrings.Size(); i++)
+ {
+ FString driveName = driveStrings[i];
+ if (driveName.Len() < 3 || driveName.Back() != '\\')
+ return E_FAIL;
+ driveName.DeleteBack();
+ NFind::CFileInfo fi;
+ fi.SetAsDir();
+ fi.Name = driveName;
+
+ RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix,
+ addArchivePrefix, dirItems, enterToSubFolders));
+ }
+ return S_OK;
+ }
+ }
+
+ #endif
+ #endif
NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
- for (int ttt = 0; ; ttt++)
+ for (unsigned ttt = 0; ; ttt++)
{
NFind::CFileInfo fi;
bool found;
if (!enumerator.Next(fi, found))
{
- errorCodes.Add(::GetLastError());
- errorPaths.Add(phyPrefix);
+ RINOK(dirItems.AddError(phyPrefix));
break;
}
if (!found)
break;
- if (callback && (ttt & 0xFF) == 0xFF)
- RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), fs2us(phyPrefix)));
- const UString &name = fs2us(fi.Name);
- bool enterToSubFolders2 = enterToSubFolders;
- UStringVector addArchivePrefixNew = addArchivePrefix;
- addArchivePrefixNew.Add(name);
- {
- UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);
- if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fi.IsDir()))
- continue;
- }
- if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fi.IsDir()))
- {
- AddDirFileInfo(phyParent, logParent, fi, dirItems.Items);
- if (fi.IsDir())
- enterToSubFolders2 = true;
- }
- if (!fi.IsDir())
- continue;
-
- const NWildcard::CCensorNode *nextNode = 0;
- if (addArchivePrefix.IsEmpty())
- {
- int index = curNode.FindSubNode(name);
- if (index >= 0)
- nextNode = &curNode.SubNodes[index];
- }
- if (!enterToSubFolders2 && nextNode == 0)
- continue;
-
- addArchivePrefixNew = addArchivePrefix;
- if (nextNode == 0)
+ if (dirItems.Callback && (ttt & kScanProgressStepMask) == kScanProgressStepMask)
{
- nextNode = &curNode;
- addArchivePrefixNew.Add(name);
+ RINOK(dirItems.ScanProgress(phyPrefix));
}
- RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix,
- addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes));
+ RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix,
+ addArchivePrefix, dirItems, enterToSubFolders));
}
+
return S_OK;
}
HRESULT EnumerateItems(
const NWildcard::CCensor &censor,
- CDirItems &dirItems,
- IEnumDirItemCallback *callback,
- FStringVector &errorPaths,
- CRecordVector<DWORD> &errorCodes)
+ const NWildcard::ECensorPathMode pathMode,
+ const UString &addPathPrefix,
+ CDirItems &dirItems)
{
- for (int i = 0; i < censor.Pairs.Size(); i++)
+ FOR_VECTOR (i, censor.Pairs)
{
const NWildcard::CPair &pair = censor.Pairs[i];
int phyParent = pair.Prefix.IsEmpty() ? -1 : dirItems.AddPrefix(-1, -1, pair.Prefix);
- RINOK(EnumerateDirItems(pair.Head, phyParent, -1, us2fs(pair.Prefix), UStringVector(), dirItems, false,
- callback, errorPaths, errorCodes));
+ int logParent = -1;
+
+ if (pathMode == NWildcard::k_AbsPath)
+ logParent = phyParent;
+ else
+ {
+ if (!addPathPrefix.IsEmpty())
+ logParent = dirItems.AddPrefix(-1, -1, addPathPrefix);
+ }
+
+ RINOK(EnumerateDirItems(pair.Head, phyParent, logParent, us2fs(pair.Prefix), UStringVector(),
+ dirItems,
+ false // enterToSubFolders
+ ));
}
dirItems.ReserveDown();
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ dirItems.FillFixedReparse();
+ #endif
+
return S_OK;
}
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+void CDirItems::FillFixedReparse()
+{
+ /* imagex/WIM reduces absolute pathes in links (raparse data),
+ if we archive non root folder. We do same thing here */
+
+ if (!SymLinks)
+ return;
+
+ FOR_VECTOR(i, Items)
+ {
+ CDirItem &item = Items[i];
+ if (item.ReparseData.Size() == 0)
+ continue;
+
+ CReparseAttr attr;
+ if (!attr.Parse(item.ReparseData, item.ReparseData.Size()))
+ continue;
+ if (attr.IsRelative())
+ continue;
+
+ const UString &link = attr.GetPath();
+ if (!IsDrivePath(link))
+ continue;
+ // maybe we need to support networks paths also ?
+
+ FString fullPathF;
+ if (!NDir::MyGetFullPathName(GetPhyPath(i), fullPathF))
+ continue;
+ UString fullPath = fs2us(fullPathF);
+ const UString logPath = GetLogPath(i);
+ if (logPath.Len() >= fullPath.Len())
+ continue;
+ if (CompareFileNames(logPath, fullPath.RightPtr(logPath.Len())) != 0)
+ continue;
+
+ const UString prefix = fullPath.Left(fullPath.Len() - logPath.Len());
+ if (!IsPathSepar(prefix.Back()))
+ continue;
+
+ unsigned rootPrefixSize = GetRootPrefixSize(prefix);
+ if (rootPrefixSize == 0)
+ continue;
+ if (rootPrefixSize == prefix.Len())
+ continue; // simple case: paths are from root
+
+ if (link.Len() <= prefix.Len())
+ continue;
+
+ if (CompareFileNames(link.Left(prefix.Len()), prefix) != 0)
+ continue;
+
+ UString newLink = prefix.Left(rootPrefixSize);
+ newLink += link.Ptr(prefix.Len());
+
+ CByteBuffer data;
+ if (!FillLinkData(data, newLink, attr.IsSymLink()))
+ continue;
+ item.ReparseData2 = data;
+ }
+}
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.h b/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.h
index c96c7b9e83e..7afb800a033 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.h
@@ -3,23 +3,19 @@
#ifndef __ENUM_DIR_ITEMS_H
#define __ENUM_DIR_ITEMS_H
-#include "Common/Wildcard.h"
-#include "Windows/FileFind.h"
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/FileFind.h"
+
#include "DirItem.h"
-void AddDirFileInfo(int phyParent, int logParent,
+void AddDirFileInfo(int phyParent, int logParent, int secureIndex,
const NWindows::NFile::NFind::CFileInfo &fi, CObjectVector<CDirItem> &dirItems);
-struct IEnumDirItemCallback
-{
- virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path) = 0;
-};
-
HRESULT EnumerateItems(
const NWildcard::CCensor &censor,
- CDirItems &dirItems,
- IEnumDirItemCallback *callback,
- FStringVector &errorPaths,
- CRecordVector<DWORD> &errorCodes);
+ NWildcard::ECensorPathMode pathMode,
+ const UString &addPathPrefix,
+ CDirItems &dirItems);
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Extract.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/Extract.cpp
index 81186772a62..14aa74072bc 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/Extract.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/Extract.cpp
@@ -2,11 +2,13 @@
#include "StdAfx.h"
-#include <stdio.h>
+#include "../../../../C/Sort.h"
-#include "Windows/FileDir.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
+#include "../../../Common/StringConvert.h"
+
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/PropVariantConv.h"
#include "../Common/ExtractingFilePath.h"
@@ -14,111 +16,249 @@
#include "SetProperties.h"
using namespace NWindows;
+using namespace NFile;
+using namespace NDir;
static HRESULT DecompressArchive(
- const CArc &arc,
+ CCodecs *codecs,
+ const CArchiveLink &arcLink,
UInt64 packSize,
const NWildcard::CCensorNode &wildcardCensor,
const CExtractOptions &options,
+ bool calcCrc,
IExtractCallbackUI *callback,
- CArchiveExtractCallback *extractCallbackSpec,
+ CArchiveExtractCallback *ecs,
UString &errorMessage,
UInt64 &stdInProcessed)
{
+ const CArc &arc = arcLink.Arcs.Back();
stdInProcessed = 0;
IInArchive *archive = arc.Archive;
CRecordVector<UInt32> realIndices;
+
+ UStringVector removePathParts;
+
+ FString outDir = options.OutputDir;
+ UString replaceName = arc.DefaultName;
+
+ if (arcLink.Arcs.Size() > 1)
+ {
+ // Most "pe" archives have same name of archive subfile "[0]" or ".rsrc_1".
+ // So it extracts different archives to one folder.
+ // We will use top level archive name
+ const CArc &arc0 = arcLink.Arcs[0];
+ if (StringsAreEqualNoCase_Ascii(codecs->Formats[arc0.FormatIndex].Name, "pe"))
+ replaceName = arc0.DefaultName;
+ }
+
+ outDir.Replace(FSTRING_ANY_MASK, us2fs(Get_Correct_FsFile_Name(replaceName)));
+
+ bool elimIsPossible = false;
+ UString elimPrefix; // only pure name without dir delimiter
+ FString outDirReduced = outDir;
+
+ if (options.ElimDup.Val && options.PathMode != NExtract::NPathMode::kAbsPaths)
+ {
+ UString dirPrefix;
+ SplitPathToParts_Smart(fs2us(outDir), dirPrefix, elimPrefix);
+ if (!elimPrefix.IsEmpty())
+ {
+ if (IsPathSepar(elimPrefix.Back()))
+ elimPrefix.DeleteBack();
+ if (!elimPrefix.IsEmpty())
+ {
+ outDirReduced = us2fs(dirPrefix);
+ elimIsPossible = true;
+ }
+ }
+ }
+
+ bool allFilesAreAllowed = wildcardCensor.AreAllAllowed();
+
if (!options.StdInMode)
{
UInt32 numItems;
RINOK(archive->GetNumberOfItems(&numItems));
+ CReadArcItem item;
+
for (UInt32 i = 0; i < numItems; i++)
{
- UString filePath;
- RINOK(arc.GetItemPath(i, filePath));
- bool isFolder;
- RINOK(IsArchiveItemFolder(archive, i, isFolder));
- if (!wildcardCensor.CheckPath(filePath, !isFolder))
+ if (elimIsPossible || !allFilesAreAllowed)
+ {
+ RINOK(arc.GetItem(i, item));
+ }
+ else
+ {
+ #ifdef SUPPORT_ALT_STREAMS
+ item.IsAltStream = false;
+ if (!options.NtOptions.AltStreams.Val && arc.Ask_AltStream)
+ {
+ RINOK(Archive_IsItem_AltStream(arc.Archive, i, item.IsAltStream));
+ }
+ #endif
+ }
+
+ #ifdef SUPPORT_ALT_STREAMS
+ if (!options.NtOptions.AltStreams.Val && item.IsAltStream)
continue;
+ #endif
+
+ if (elimIsPossible)
+ {
+ const UString &s =
+ #ifdef SUPPORT_ALT_STREAMS
+ item.MainPath;
+ #else
+ item.Path;
+ #endif
+ if (!IsPath1PrefixedByPath2(s, elimPrefix))
+ elimIsPossible = false;
+ else
+ {
+ wchar_t c = s[elimPrefix.Len()];
+ if (c == 0)
+ {
+ if (!item.MainIsDir)
+ elimIsPossible = false;
+ }
+ else if (!IsPathSepar(c))
+ elimIsPossible = false;
+ }
+ }
+
+ if (!allFilesAreAllowed)
+ {
+ if (!CensorNode_CheckPath(wildcardCensor, item))
+ continue;
+ }
+
realIndices.Add(i);
}
+
if (realIndices.Size() == 0)
{
callback->ThereAreNoFiles();
- return S_OK;
+ return callback->ExtractResult(S_OK);
}
}
- UStringVector removePathParts;
+ if (elimIsPossible)
+ {
+ removePathParts.Add(elimPrefix);
+ // outDir = outDirReduced;
+ }
- FString outDir = options.OutputDir;
- outDir.Replace(FSTRING_ANY_MASK, us2fs(GetCorrectFsPath(arc.DefaultName)));
#ifdef _WIN32
// GetCorrectFullFsPath doesn't like "..".
// outDir.TrimRight();
// outDir = GetCorrectFullFsPath(outDir);
#endif
- if (!outDir.IsEmpty())
- if (!NFile::NDirectory::CreateComplexDirectory(outDir))
- {
- HRESULT res = ::GetLastError();
- if (res == S_OK)
- res = E_FAIL;
- errorMessage = ((UString)L"Can not create output directory ") + fs2us(outDir);
- return res;
- }
+ if (outDir.IsEmpty())
+ outDir = FTEXT(".") FSTRING_PATH_SEPARATOR;
+ /*
+ #ifdef _WIN32
+ else if (NName::IsAltPathPrefix(outDir)) {}
+ #endif
+ */
+ else if (!CreateComplexDir(outDir))
+ {
+ HRESULT res = ::GetLastError();
+ if (res == S_OK)
+ res = E_FAIL;
+ errorMessage.SetFromAscii("Can not create output directory: ");
+ errorMessage += fs2us(outDir);
+ return res;
+ }
- extractCallbackSpec->Init(
+ ecs->Init(
+ options.NtOptions,
options.StdInMode ? &wildcardCensor : NULL,
&arc,
callback,
- options.StdOutMode, options.TestMode, options.CalcCrc,
+ options.StdOutMode, options.TestMode,
outDir,
- removePathParts,
+ removePathParts, false,
packSize);
- #if !defined(_7ZIP_ST) && !defined(_SFX)
- RINOK(SetProperties(archive, options.Properties));
+
+ #ifdef SUPPORT_LINKS
+
+ if (!options.StdInMode &&
+ !options.TestMode &&
+ options.NtOptions.HardLinks.Val)
+ {
+ RINOK(ecs->PrepareHardLinks(&realIndices));
+ }
+
#endif
+
HRESULT result;
- Int32 testMode = (options.TestMode && !options.CalcCrc) ? 1: 0;
+ Int32 testMode = (options.TestMode && !calcCrc) ? 1: 0;
if (options.StdInMode)
{
- result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, extractCallbackSpec);
+ result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, ecs);
NCOM::CPropVariant prop;
if (archive->GetArchiveProperty(kpidPhySize, &prop) == S_OK)
- if (prop.vt == VT_UI8 || prop.vt == VT_UI4)
- stdInProcessed = ConvertPropVariantToUInt64(prop);
+ ConvertPropVariantToUInt64(prop, stdInProcessed);
}
else
- result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallbackSpec);
-
+ result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, ecs);
+ if (result == S_OK && !options.StdInMode)
+ result = ecs->SetDirsTimes();
return callback->ExtractResult(result);
}
-HRESULT DecompressArchives(
- CCodecs *codecs, const CIntVector &formatIndices,
+/* v9.31: BUG was fixed:
+ Sorted list for file paths was sorted with case insensitive compare function.
+ But FindInSorted function did binary search via case sensitive compare function */
+
+int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &name)
+{
+ unsigned left = 0, right = fileName.Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const UString &midValue = fileName[mid];
+ int compare = CompareFileNames(name, midValue);
+ if (compare == 0)
+ return mid;
+ if (compare < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ return -1;
+}
+
+HRESULT Extract(
+ CCodecs *codecs,
+ const CObjectVector<COpenType> &types,
+ const CIntVector &excludedFormats,
UStringVector &arcPaths, UStringVector &arcPathsFull,
const NWildcard::CCensorNode &wildcardCensor,
const CExtractOptions &options,
IOpenCallbackUI *openCallback,
IExtractCallbackUI *extractCallback,
+ #ifndef _SFX
+ IHashCalc *hash,
+ #endif
UString &errorMessage,
- CDecompressStat &stat)
+ CDecompressStat &st)
{
- stat.Clear();
- int i;
+ st.Clear();
UInt64 totalPackSize = 0;
- CRecordVector<UInt64> archiveSizes;
+ CRecordVector<UInt64> arcSizes;
- int numArcs = options.StdInMode ? 1 : arcPaths.Size();
+ unsigned numArcs = options.StdInMode ? 1 : arcPaths.Size();
+ unsigned i;
+
for (i = 0; i < numArcs; i++)
{
- NFile::NFind::CFileInfo fi;
+ NFind::CFileInfo fi;
fi.Size = 0;
if (!options.StdInMode)
{
@@ -128,21 +268,37 @@ HRESULT DecompressArchives(
if (fi.IsDir())
throw "can't decompress folder";
}
- archiveSizes.Add(fi.Size);
+ arcSizes.Add(fi.Size);
totalPackSize += fi.Size;
}
- CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
- CMyComPtr<IArchiveExtractCallback> ec(extractCallbackSpec);
+
+ CBoolArr skipArcs(numArcs);
+ for (i = 0; i < numArcs; i++)
+ skipArcs[i] = false;
+
+ CArchiveExtractCallback *ecs = new CArchiveExtractCallback;
+ CMyComPtr<IArchiveExtractCallback> ec(ecs);
bool multi = (numArcs > 1);
- extractCallbackSpec->InitForMulti(multi, options.PathMode, options.OverwriteMode);
+ ecs->InitForMulti(multi, options.PathMode, options.OverwriteMode);
+ #ifndef _SFX
+ ecs->SetHashMethods(hash);
+ #endif
+
if (multi)
{
RINOK(extractCallback->SetTotal(totalPackSize));
}
+
+ UInt64 totalPackProcessed = 0;
+ bool thereAreNotOpenArcs = false;
+
for (i = 0; i < numArcs; i++)
{
+ if (skipArcs[i])
+ continue;
+
const UString &arcPath = arcPaths[i];
- NFile::NFind::CFileInfo fi;
+ NFind::CFileInfo fi;
if (options.StdInMode)
{
fi.Size = 0;
@@ -154,21 +310,24 @@ HRESULT DecompressArchives(
throw "there is no such archive";
}
+ /*
#ifndef _NO_CRYPTO
- openCallback->Open_ClearPasswordWasAskedFlag();
+ openCallback->Open_Clear_PasswordWasAsked_Flag();
#endif
+ */
- RINOK(extractCallback->BeforeOpen(arcPath));
- CArchiveLink archiveLink;
+ RINOK(extractCallback->BeforeOpen(arcPath, options.TestMode));
+ CArchiveLink arcLink;
- CIntVector formatIndices2 = formatIndices;
+ CObjectVector<COpenType> types2 = types;
+ /*
#ifndef _SFX
- if (formatIndices.IsEmpty())
+ if (types.IsEmpty())
{
int pos = arcPath.ReverseFind(L'.');
if (pos >= 0)
{
- UString s = arcPath.Mid(pos + 1);
+ UString s = arcPath.Ptr(pos + 1);
int index = codecs->FindFormatForExtension(s);
if (index >= 0 && s == L"001")
{
@@ -176,88 +335,143 @@ HRESULT DecompressArchives(
pos = s.ReverseFind(L'.');
if (pos >= 0)
{
- int index2 = codecs->FindFormatForExtension(s.Mid(pos + 1));
- if (index2 >= 0 && s.CompareNoCase(L"rar") != 0)
+ int index2 = codecs->FindFormatForExtension(s.Ptr(pos + 1));
+ if (index2 >= 0) // && s.CompareNoCase(L"rar") != 0
{
- formatIndices2.Add(index2);
- formatIndices2.Add(index);
+ types2.Add(index2);
+ types2.Add(index);
}
}
}
}
}
#endif
- HRESULT result = archiveLink.Open2(codecs, formatIndices2, options.StdInMode, NULL, arcPath, openCallback);
+ */
+
+ COpenOptions op;
+ #ifndef _SFX
+ op.props = &options.Properties;
+ #endif
+ op.codecs = codecs;
+ op.types = &types2;
+ op.excludedFormats = &excludedFormats;
+ op.stdInMode = options.StdInMode;
+ op.stream = NULL;
+ op.filePath = arcPath;
+
+ HRESULT result = arcLink.Open3(op, openCallback);
+
if (result == E_ABORT)
return result;
- bool crypted = false;
- #ifndef _NO_CRYPTO
- crypted = openCallback->Open_WasPasswordAsked();
- #endif
+ if (result == S_OK && arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
+ result = S_FALSE;
+
+ // arcLink.Set_ErrorsText();
+ RINOK(extractCallback->OpenResult(codecs, arcLink, arcPath, result));
- RINOK(extractCallback->OpenResult(arcPath, result, crypted));
if (result != S_OK)
+ {
+ thereAreNotOpenArcs = true;
+ if (!options.StdInMode)
+ {
+ NFind::CFileInfo fi;
+ if (fi.Find(us2fs(arcPath)))
+ if (!fi.IsDir())
+ totalPackProcessed += fi.Size;
+ }
continue;
+ }
if (!options.StdInMode)
- for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
{
- int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]);
- if (index >= 0 && index > i)
+ // numVolumes += arcLink.VolumePaths.Size();
+ // arcLink.VolumesSize;
+
+ // totalPackSize -= DeleteUsedFileNamesFromList(arcLink, i + 1, arcPaths, arcPathsFull, &arcSizes);
+ // numArcs = arcPaths.Size();
+ if (arcLink.VolumePaths.Size() != 0)
{
- arcPaths.Delete(index);
- arcPathsFull.Delete(index);
- totalPackSize -= archiveSizes[index];
- archiveSizes.Delete(index);
- numArcs = arcPaths.Size();
+ Int64 correctionSize = arcLink.VolumesSize;
+ FOR_VECTOR (v, arcLink.VolumePaths)
+ {
+ int index = Find_FileName_InSortedVector(arcPathsFull, arcLink.VolumePaths[v]);
+ if (index >= 0)
+ {
+ if ((unsigned)index > i)
+ {
+ skipArcs[(unsigned)index] = true;
+ correctionSize -= arcSizes[(unsigned)index];
+ }
+ }
+ }
+ if (correctionSize != 0)
+ {
+ Int64 newPackSize = (Int64)totalPackSize + correctionSize;
+ if (newPackSize < 0)
+ newPackSize = 0;
+ totalPackSize = newPackSize;
+ RINOK(extractCallback->SetTotal(totalPackSize));
+ }
}
}
- if (archiveLink.VolumePaths.Size() != 0)
- {
- totalPackSize += archiveLink.VolumesSize;
- RINOK(extractCallback->SetTotal(totalPackSize));
- }
+
+ /*
+ // Now openCallback and extractCallback use same object. So we don't need to send password.
#ifndef _NO_CRYPTO
+ bool passwordIsDefined;
UString password;
- RINOK(openCallback->Open_GetPasswordIfAny(password));
- if (!password.IsEmpty())
+ RINOK(openCallback->Open_GetPasswordIfAny(passwordIsDefined, password));
+ if (passwordIsDefined)
{
RINOK(extractCallback->SetPassword(password));
}
#endif
+ */
- for (int v = 0; v < archiveLink.Arcs.Size(); v++)
- {
- const UString &s = archiveLink.Arcs[v].ErrorMessage;
- if (!s.IsEmpty())
- {
- RINOK(extractCallback->MessageError(s));
- }
- }
-
- CArc &arc = archiveLink.Arcs.Back();
+ CArc &arc = arcLink.Arcs.Back();
arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice);
arc.MTime = fi.MTime;
UInt64 packProcessed;
- RINOK(DecompressArchive(arc,
- fi.Size + archiveLink.VolumesSize,
- wildcardCensor, options, extractCallback, extractCallbackSpec, errorMessage, packProcessed));
+ bool calcCrc =
+ #ifndef _SFX
+ (hash != NULL);
+ #else
+ false;
+ #endif
+
+ RINOK(DecompressArchive(
+ codecs,
+ arcLink,
+ fi.Size + arcLink.VolumesSize,
+ wildcardCensor,
+ options,
+ calcCrc,
+ extractCallback, ecs, errorMessage, packProcessed));
+
if (!options.StdInMode)
- packProcessed = fi.Size + archiveLink.VolumesSize;
- extractCallbackSpec->LocalProgressSpec->InSize += packProcessed;
- extractCallbackSpec->LocalProgressSpec->OutSize = extractCallbackSpec->UnpackSize;
+ packProcessed = fi.Size + arcLink.VolumesSize;
+ totalPackProcessed += packProcessed;
+ ecs->LocalProgressSpec->InSize += packProcessed;
+ ecs->LocalProgressSpec->OutSize = ecs->UnpackSize;
if (!errorMessage.IsEmpty())
return E_FAIL;
}
- stat.NumFolders = extractCallbackSpec->NumFolders;
- stat.NumFiles = extractCallbackSpec->NumFiles;
- stat.UnpackSize = extractCallbackSpec->UnpackSize;
- stat.CrcSum = extractCallbackSpec->CrcSum;
- stat.NumArchives = arcPaths.Size();
- stat.PackSize = extractCallbackSpec->LocalProgressSpec->InSize;
+ if (multi || thereAreNotOpenArcs)
+ {
+ RINOK(extractCallback->SetTotal(totalPackSize));
+ RINOK(extractCallback->SetCompleted(&totalPackProcessed));
+ }
+
+ st.NumFolders = ecs->NumFolders;
+ st.NumFiles = ecs->NumFiles;
+ st.NumAltStreams = ecs->NumAltStreams;
+ st.UnpackSize = ecs->UnpackSize;
+ st.AltStreams_UnpackSize = ecs->AltStreams_UnpackSize;
+ st.NumArchives = arcPaths.Size();
+ st.PackSize = ecs->LocalProgressSpec->InSize;
return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Extract.h b/3rdparty/lzma/CPP/7zip/UI/Common/Extract.h
index 2904a0aba7f..03ac74b2d0b 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/Extract.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/Extract.h
@@ -3,7 +3,7 @@
#ifndef __EXTRACT_H
#define __EXTRACT_H
-#include "Windows/FileFind.h"
+#include "../../../Windows/FileFind.h"
#include "../../Archive/IArchive.h"
@@ -14,21 +14,37 @@
#include "../Common/LoadCodecs.h"
-struct CExtractOptions
+struct CExtractOptionsBase
+{
+ CBoolPair ElimDup;
+
+ bool PathMode_Force;
+ bool OverwriteMode_Force;
+ NExtract::NPathMode::EEnum PathMode;
+ NExtract::NOverwriteMode::EEnum OverwriteMode;
+
+ FString OutputDir;
+ CExtractNtOptions NtOptions;
+
+ CExtractOptionsBase():
+ PathMode_Force(false),
+ OverwriteMode_Force(false),
+ PathMode(NExtract::NPathMode::kFullPaths),
+ OverwriteMode(NExtract::NOverwriteMode::kAsk)
+ {}
+};
+
+struct CExtractOptions: public CExtractOptionsBase
{
bool StdInMode;
bool StdOutMode;
bool YesToAll;
bool TestMode;
- bool CalcCrc;
- NExtract::NPathMode::EEnum PathMode;
- NExtract::NOverwriteMode::EEnum OverwriteMode;
- FString OutputDir;
// bool ShowDialog;
// bool PasswordEnabled;
// UString Password;
- #if !defined(_7ZIP_ST) && !defined(_SFX)
+ #ifndef _SFX
CObjectVector<CProperty> Properties;
#endif
@@ -37,13 +53,10 @@ struct CExtractOptions
#endif
CExtractOptions():
+ TestMode(false),
StdInMode(false),
StdOutMode(false),
- YesToAll(false),
- TestMode(false),
- CalcCrc(false),
- PathMode(NExtract::NPathMode::kFullPathnames),
- OverwriteMode(NExtract::NOverwriteMode::kAskBefore)
+ YesToAll(false)
{}
};
@@ -51,26 +64,31 @@ struct CDecompressStat
{
UInt64 NumArchives;
UInt64 UnpackSize;
+ UInt64 AltStreams_UnpackSize;
UInt64 PackSize;
UInt64 NumFolders;
UInt64 NumFiles;
- UInt32 CrcSum;
+ UInt64 NumAltStreams;
void Clear()
{
- NumArchives = UnpackSize = PackSize = NumFolders = NumFiles = 0;
- CrcSum = 0;
+ NumArchives = UnpackSize = AltStreams_UnpackSize = PackSize = NumFolders = NumFiles = NumAltStreams = 0;
}
};
-HRESULT DecompressArchives(
- CCodecs *codecs, const CIntVector &formatIndices,
+HRESULT Extract(
+ CCodecs *codecs,
+ const CObjectVector<COpenType> &types,
+ const CIntVector &excludedFormats,
UStringVector &archivePaths, UStringVector &archivePathsFull,
const NWildcard::CCensorNode &wildcardCensor,
const CExtractOptions &options,
IOpenCallbackUI *openCallback,
IExtractCallbackUI *extractCallback,
+ #ifndef _SFX
+ IHashCalc *hash,
+ #endif
UString &errorMessage,
- CDecompressStat &stat);
+ CDecompressStat &st);
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ExtractMode.h b/3rdparty/lzma/CPP/7zip/UI/Common/ExtractMode.h
index b448fb30a6e..3b2b9a02e81 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/ExtractMode.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/ExtractMode.h
@@ -5,27 +5,30 @@
namespace NExtract {
- namespace NPathMode
+namespace NPathMode
+{
+ enum EEnum
{
- enum EEnum
- {
- kFullPathnames,
- kCurrentPathnames,
- kNoPathnames
- };
- }
-
- namespace NOverwriteMode
+ kFullPaths,
+ kCurPaths,
+ kNoPaths,
+ kAbsPaths,
+ kNoPathsAlt // alt streams must be extracted without name of base file
+ };
+}
+
+namespace NOverwriteMode
+{
+ enum EEnum
{
- enum EEnum
- {
- kAskBefore,
- kWithoutPrompt,
- kSkipExisting,
- kAutoRename,
- kAutoRenameExisting
- };
- }
+ kAsk,
+ kOverwrite,
+ kSkip,
+ kRename,
+ kRenameExisting
+ };
+}
+
}
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp
index 25494d0e642..39e67b7f2ed 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp
@@ -2,141 +2,236 @@
#include "StdAfx.h"
-#include "../../../../C/Types.h"
+#include "../../../Common/Wildcard.h"
-#include "Common/Wildcard.h"
+#include "../../../Windows/FileName.h"
#include "ExtractingFilePath.h"
-static UString ReplaceIncorrectChars(const UString &s)
+static void ReplaceIncorrectChars(UString &s)
{
+ {
+ for (unsigned i = 0; i < s.Len(); i++)
+ {
+ wchar_t c = s[i];
+ if (
+ #ifdef _WIN32
+ c == ':' || c == '*' || c == '?' || c < 0x20 || c == '<' || c == '>' || c == '|' || c == '"'
+ || c == '/'
+ // || c == 0x202E // RLO
+ ||
+ #endif
+ c == WCHAR_PATH_SEPARATOR)
+ s.ReplaceOneCharAtPos(i, '_');
+ }
+ }
+
#ifdef _WIN32
- UString res;
- for (int i = 0; i < s.Length(); i++)
{
- wchar_t c = s[i];
- if (c < 0x20 || c == '*' || c == '?' || c == '<' || c == '>' || c == '|' || c == ':' || c == '"')
- c = '_';
- res += c;
+ for (unsigned i = s.Len(); i != 0;)
+ {
+ wchar_t c = s[--i];
+ if (c != '.' && c != ' ')
+ break;
+ s.ReplaceOneCharAtPos(i, '_');
+ }
}
- res.TrimRight();
- while (!res.IsEmpty() && res.Back() == '.')
- res.DeleteBack();
- return res;
- #else
- return s;
#endif
}
#ifdef _WIN32
-static const wchar_t *g_ReservedNames[] =
-{
- L"CON", L"PRN", L"AUX", L"NUL"
-};
-static bool CheckTail(const UString &name, int len)
+/* WinXP-64 doesn't support ':', '\\' and '/' symbols in name of alt stream.
+ But colon in postfix ":$DATA" is allowed.
+ WIN32 functions don't allow empty alt stream name "name:" */
+
+void Correct_AltStream_Name(UString &s)
{
- int dotPos = name.Find(L'.');
- if (dotPos < 0)
- dotPos = name.Length();
- UString s = name.Left(dotPos);
- s.TrimRight();
- return (s.Length() != len);
+ unsigned len = s.Len();
+ const unsigned kPostfixSize = 6;
+ if (s.Len() >= kPostfixSize
+ && StringsAreEqualNoCase_Ascii(s.RightPtr(kPostfixSize), ":$DATA"))
+ len -= kPostfixSize;
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = s[i];
+ if (c == ':' || c == '\\' || c == '/'
+ || c == 0x202E // RLO
+ )
+ s.ReplaceOneCharAtPos(i, '_');
+ }
+ if (s.IsEmpty())
+ s = L'_';
}
-static bool CheckNameNum(const UString &name, const wchar_t *reservedName)
+static const unsigned g_ReservedWithNum_Index = 4;
+
+static const char * const g_ReservedNames[] =
{
- int len = MyStringLen(reservedName);
- if (name.Length() <= len)
- return true;
- if (name.Left(len).CompareNoCase(reservedName) != 0)
- return true;
- wchar_t c = name[len];
- if (c < L'0' || c > L'9')
- return true;
- return CheckTail(name, len + 1);
-}
+ "CON", "PRN", "AUX", "NUL",
+ "COM", "LPT"
+};
static bool IsSupportedName(const UString &name)
{
- for (int i = 0; i < sizeof(g_ReservedNames) / sizeof(g_ReservedNames[0]); i++)
+ for (unsigned i = 0; i < ARRAY_SIZE(g_ReservedNames); i++)
{
- const wchar_t *reservedName = g_ReservedNames[i];
- int len = MyStringLen(reservedName);
- if (name.Length() < len)
+ const char *reservedName = g_ReservedNames[i];
+ unsigned len = MyStringLen(reservedName);
+ if (name.Len() < len)
continue;
- if (name.Left(len).CompareNoCase(reservedName) != 0)
+ if (!name.IsPrefixedBy_Ascii_NoCase(reservedName))
continue;
- if (!CheckTail(name, len))
- return false;
+ if (i >= g_ReservedWithNum_Index)
+ {
+ wchar_t c = name[len];
+ if (c < L'0' || c > L'9')
+ continue;
+ len++;
+ }
+ for (;;)
+ {
+ wchar_t c = name[len++];
+ if (c == 0 || c == '.')
+ return false;
+ if (c != ' ')
+ break;
+ }
}
- if (!CheckNameNum(name, L"COM"))
- return false;
- return CheckNameNum(name, L"LPT");
+ return true;
}
+
+static void CorrectUnsupportedName(UString &name)
+{
+ if (!IsSupportedName(name))
+ name.InsertAtFront(L'_');
+}
+
#endif
-static UString GetCorrectFileName(const UString &path)
+static void Correct_PathPart(UString &s)
+{
+ // "." and ".."
+ if (s[0] == '.' && (s[1] == 0 || s[1] == '.' && s[2] == 0))
+ s.Empty();
+ #ifdef _WIN32
+ else
+ ReplaceIncorrectChars(s);
+ #endif
+}
+
+// static const wchar_t *k_EmptyReplaceName = L"[]";
+static const wchar_t k_EmptyReplaceName = L'_';
+
+UString Get_Correct_FsFile_Name(const UString &name)
{
- if (path == L".." || path == L".")
- return UString();
- return ReplaceIncorrectChars(path);
+ UString res = name;
+ Correct_PathPart(res);
+
+ #ifdef _WIN32
+ CorrectUnsupportedName(res);
+ #endif
+
+ if (res.IsEmpty())
+ res = k_EmptyReplaceName;
+ return res;
}
-void MakeCorrectPath(UStringVector &pathParts)
+
+void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir)
{
- for (int i = 0; i < pathParts.Size();)
+ unsigned i = 0;
+
+ if (absIsAllowed)
{
- UString &s = pathParts[i];
- s = GetCorrectFileName(s);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ bool isDrive = false;
+ #endif
+ if (parts[0].IsEmpty())
+ {
+ i = 1;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (parts.Size() > 1 && parts[1].IsEmpty())
+ {
+ i = 2;
+ if (parts.Size() > 2 && parts[2] == L"?")
+ {
+ i = 3;
+ if (parts.Size() > 3 && NWindows::NFile::NName::IsDrivePath2(parts[3]))
+ {
+ isDrive = true;
+ i = 4;
+ }
+ }
+ }
+ #endif
+ }
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ else if (NWindows::NFile::NName::IsDrivePath2(parts[0]))
+ {
+ isDrive = true;
+ i = 1;
+ }
+
+ if (isDrive)
+ {
+ // we convert "c:name" to "c:\name", if absIsAllowed path.
+ const UString &ds = parts[i - 1];
+ if (ds.Len() != 2)
+ {
+ UString s = ds.Ptr(2);
+ parts.Insert(i, s);
+ }
+ }
+ #endif
+ }
+
+ for (; i < parts.Size();)
+ {
+ UString &s = parts[i];
+
+ Correct_PathPart(s);
+
if (s.IsEmpty())
- pathParts.Delete(i);
+ {
+ if (isDir || i != parts.Size() - 1)
+ {
+ parts.Delete(i);
+ continue;
+ }
+ s = k_EmptyReplaceName;
+ }
else
{
#ifdef _WIN32
- if (!IsSupportedName(s))
- s = (UString)L"_" + s;
+ CorrectUnsupportedName(s);
#endif
- i++;
}
+
+ i++;
}
-}
-UString MakePathNameFromParts(const UStringVector &parts)
-{
- UString result;
- for (int i = 0; i < parts.Size(); i++)
+ if (!isDir)
{
- if (i != 0)
- result += WCHAR_PATH_SEPARATOR;
- result += parts[i];
+ if (parts.IsEmpty())
+ parts.Add(k_EmptyReplaceName);
+ else
+ {
+ UString &s = parts.Back();
+ if (s.IsEmpty())
+ s = k_EmptyReplaceName;
+ }
}
- return result;
}
-UString GetCorrectFsPath(const UString &path)
-{
- UString res = GetCorrectFileName(path);
- #ifdef _WIN32
- if (!IsSupportedName(res))
- res = (UString)L"_" + res;
- #endif
- return res;
-}
-
-UString GetCorrectFullFsPath(const UString &path)
+UString MakePathFromParts(const UStringVector &parts)
{
- UStringVector parts;
- SplitPathToParts(path, parts);
- for (int i = 0; i < parts.Size(); i++)
+ UString s;
+ FOR_VECTOR (i, parts)
{
- UString &s = parts[i];
- #ifdef _WIN32
- while (!s.IsEmpty() && s.Back() == '.')
- s.DeleteBack();
- if (!IsSupportedName(s))
- s = (UString)L"_" + s;
- #endif
+ if (i != 0)
+ s.Add_PathSepar();
+ s += parts[i];
}
- return MakePathNameFromParts(parts);
+ return s;
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h b/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h
index da28bfc23b7..a52a1f4a5b4 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h
@@ -3,11 +3,17 @@
#ifndef __EXTRACTING_FILE_PATH_H
#define __EXTRACTING_FILE_PATH_H
-#include "Common/MyString.h"
+#include "../../../Common/MyString.h"
-UString MakePathNameFromParts(const UStringVector &parts);
-void MakeCorrectPath(UStringVector &pathParts);
-UString GetCorrectFsPath(const UString &path);
-UString GetCorrectFullFsPath(const UString &path);
+#ifdef _WIN32
+void Correct_AltStream_Name(UString &s);
+#endif
+
+// replaces unsuported characters, and replaces "." , ".." and "" to "[]"
+UString Get_Correct_FsFile_Name(const UString &name);
+
+void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir);
+
+UString MakePathFromParts(const UStringVector &parts);
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.cpp
new file mode 100644
index 00000000000..c33f837fe77
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.cpp
@@ -0,0 +1,351 @@
+// HashCalc.cpp
+
+#include "StdAfx.h"
+
+#include "../../../../C/Alloc.h"
+
+#include "../../../Common/StringToInt.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Common/StreamUtils.h"
+
+#include "EnumDirItems.h"
+#include "HashCalc.h"
+
+using namespace NWindows;
+
+class CHashMidBuf
+{
+ void *_data;
+public:
+ CHashMidBuf(): _data(0) {}
+ operator void *() { return _data; }
+ bool Alloc(size_t size)
+ {
+ if (_data != 0)
+ return false;
+ _data = ::MidAlloc(size);
+ return _data != 0;
+ }
+ ~CHashMidBuf() { ::MidFree(_data); }
+};
+
+static const char *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);
+ }
+
+ CRecordVector<CMethodId> ids;
+ CObjectVector<COneMethodInfo> methods;
+
+ unsigned i;
+ for (i = 0; i < names.Size(); i++)
+ {
+ COneMethodInfo m;
+ RINOK(m.ParseMethodFromString(names[i]));
+
+ if (m.MethodName.IsEmpty())
+ m.MethodName = k_DefaultHashMethod;
+
+ if (m.MethodName == "*")
+ {
+ CRecordVector<CMethodId> tempMethods;
+ GetHashMethods(EXTERNAL_CODECS_LOC_VARS tempMethods);
+ methods.Clear();
+ ids.Clear();
+ FOR_VECTOR (t, tempMethods)
+ {
+ unsigned index = ids.AddToUniqueSorted(tempMethods[t]);
+ if (ids.Size() != methods.Size())
+ methods.Insert(index, m);
+ }
+ break;
+ }
+ else
+ {
+ // m.MethodName.RemoveChar(L'-');
+ CMethodId id;
+ if (!FindHashMethod(EXTERNAL_CODECS_LOC_VARS m.MethodName, id))
+ return E_NOTIMPL;
+ unsigned index = ids.AddToUniqueSorted(id);
+ if (ids.Size() != methods.Size())
+ methods.Insert(index, m);
+ }
+ }
+
+ for (i = 0; i < ids.Size(); i++)
+ {
+ CMyComPtr<IHasher> hasher;
+ AString name;
+ RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS ids[i], name, hasher));
+ if (!hasher)
+ throw "Can't create hasher";
+ const COneMethodInfo &m = methods[i];
+ {
+ CMyComPtr<ICompressSetCoderProperties> scp;
+ hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
+ if (scp)
+ RINOK(m.SetCoderProps(scp, NULL));
+ }
+ UInt32 digestSize = hasher->GetDigestSize();
+ if (digestSize > k_HashCalc_DigestSize_Max)
+ return E_NOTIMPL;
+ CHasherState &h = Hashers.AddNew();
+ h.Hasher = hasher;
+ h.Name = name;
+ h.DigestSize = digestSize;
+ for (unsigned i = 0; i < k_HashCalc_NumGroups; i++)
+ memset(h.Digests[i], 0, digestSize);
+ }
+
+ return S_OK;
+}
+
+void CHashBundle::InitForNewFile()
+{
+ CurSize = 0;
+ FOR_VECTOR (i, Hashers)
+ {
+ CHasherState &h = Hashers[i];
+ h.Hasher->Init();
+ memset(h.Digests[k_HashCalc_Index_Current], 0, h.DigestSize);
+ }
+}
+
+void CHashBundle::Update(const void *data, UInt32 size)
+{
+ CurSize += size;
+ FOR_VECTOR (i, Hashers)
+ Hashers[i].Hasher->Update(data, size);
+}
+
+void CHashBundle::SetSize(UInt64 size)
+{
+ CurSize = size;
+}
+
+static void AddDigests(Byte *dest, const Byte *src, UInt32 size)
+{
+ unsigned next = 0;
+ for (UInt32 i = 0; i < size; i++)
+ {
+ next += (unsigned)dest[i] + (unsigned)src[i];
+ dest[i] = (Byte)next;
+ next >>= 8;
+ }
+}
+
+void CHashBundle::Final(bool isDir, bool isAltStream, const UString &path)
+{
+ if (isDir)
+ NumDirs++;
+ else if (isAltStream)
+ {
+ NumAltStreams++;
+ AltStreamsSize += CurSize;
+ }
+ else
+ {
+ NumFiles++;
+ FilesSize += CurSize;
+ }
+
+ Byte pre[16];
+ memset(pre, 0, sizeof(pre));
+ if (isDir)
+ pre[0] = 1;
+
+ FOR_VECTOR (i, Hashers)
+ {
+ CHasherState &h = Hashers[i];
+ if (!isDir)
+ {
+ h.Hasher->Final(h.Digests[0]);
+ if (!isAltStream)
+ AddDigests(h.Digests[k_HashCalc_Index_DataSum], h.Digests[0], h.DigestSize);
+ }
+
+ h.Hasher->Init();
+ h.Hasher->Update(pre, sizeof(pre));
+ h.Hasher->Update(h.Digests[0], h.DigestSize);
+
+ for (unsigned k = 0; k < path.Len(); k++)
+ {
+ wchar_t c = path[k];
+ Byte temp[2] = { (Byte)(c & 0xFF), (Byte)((c >> 8) & 0xFF) };
+ h.Hasher->Update(temp, 2);
+ }
+
+ Byte tempDigest[k_HashCalc_DigestSize_Max];
+ h.Hasher->Final(tempDigest);
+ if (!isAltStream)
+ AddDigests(h.Digests[k_HashCalc_Index_NamesSum], tempDigest, h.DigestSize);
+ AddDigests(h.Digests[k_HashCalc_Index_StreamsSum], tempDigest, h.DigestSize);
+ }
+}
+
+
+HRESULT HashCalc(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const NWildcard::CCensor &censor,
+ const CHashOptions &options,
+ AString &errorInfo,
+ IHashCallbackUI *callback)
+{
+ CDirItems dirItems;
+ dirItems.Callback = callback;
+
+ if (options.StdInMode)
+ {
+ CDirItem di;
+ di.Size = (UInt64)(Int64)-1;
+ di.Attrib = 0;
+ di.MTime.dwLowDateTime = 0;
+ di.MTime.dwHighDateTime = 0;
+ di.CTime = di.ATime = di.MTime;
+ dirItems.Items.Add(di);
+ }
+ else
+ {
+ RINOK(callback->StartScanning());
+ dirItems.ScanAltStreams = options.AltStreamsMode;
+
+ HRESULT res = EnumerateItems(censor,
+ options.PathMode,
+ UString(),
+ dirItems);
+
+ if (res != S_OK)
+ {
+ if (res != E_ABORT)
+ errorInfo = "Scanning error";
+ return res;
+ }
+ RINOK(callback->FinishScanning(dirItems.Stat));
+ }
+
+ unsigned i;
+ CHashBundle hb;
+ RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS options.Methods));
+ hb.Init();
+
+ hb.NumErrors = dirItems.Stat.NumErrors;
+
+ if (options.StdInMode)
+ {
+ RINOK(callback->SetNumFiles(1));
+ }
+ else
+ {
+ RINOK(callback->SetTotal(dirItems.Stat.GetTotalBytes()));
+ }
+
+ const UInt32 kBufSize = 1 << 15;
+ CHashMidBuf buf;
+ if (!buf.Alloc(kBufSize))
+ return E_OUTOFMEMORY;
+
+ UInt64 completeValue = 0;
+
+ RINOK(callback->BeforeFirstFile(hb));
+
+ for (i = 0; i < dirItems.Items.Size(); i++)
+ {
+ CMyComPtr<ISequentialInStream> inStream;
+ UString path;
+ bool isDir = false;
+ bool isAltStream = false;
+ if (options.StdInMode)
+ {
+ inStream = new CStdInFileStream;
+ }
+ else
+ {
+ CInFileStream *inStreamSpec = new CInFileStream;
+ inStream = inStreamSpec;
+ const CDirItem &dirItem = dirItems.Items[i];
+ isDir = dirItem.IsDir();
+ isAltStream = dirItem.IsAltStream;
+ path = dirItems.GetLogPath(i);
+ if (!isDir)
+ {
+ FString phyPath = dirItems.GetPhyPath(i);
+ if (!inStreamSpec->OpenShared(phyPath, options.OpenShareForWrite))
+ {
+ HRESULT res = callback->OpenFileError(phyPath, ::GetLastError());
+ hb.NumErrors++;
+ if (res != S_FALSE)
+ return res;
+ continue;
+ }
+ }
+ }
+ RINOK(callback->GetStream(path, isDir));
+ UInt64 fileSize = 0;
+
+ hb.InitForNewFile();
+ if (!isDir)
+ {
+ for (UInt32 step = 0;; step++)
+ {
+ if ((step & 0xFF) == 0)
+ RINOK(callback->SetCompleted(&completeValue));
+ UInt32 size;
+ RINOK(inStream->Read(buf, kBufSize, &size));
+ if (size == 0)
+ break;
+ hb.Update(buf, size);
+ fileSize += size;
+ completeValue += size;
+ }
+ }
+ hb.Final(isDir, isAltStream, path);
+ RINOK(callback->SetOperationResult(fileSize, hb, !isDir));
+ RINOK(callback->SetCompleted(&completeValue));
+ }
+ return callback->AfterLastFile(hb);
+}
+
+
+static inline char GetHex(unsigned v)
+{
+ return (char)((v < 10) ? ('0' + v) : ('A' + (v - 10)));
+}
+
+void AddHashHexToString(char *dest, const Byte *data, UInt32 size)
+{
+ dest[size * 2] = 0;
+
+ if (!data)
+ {
+ for (UInt32 i = 0; i < size; i++)
+ {
+ dest[0] = ' ';
+ dest[1] = ' ';
+ dest += 2;
+ }
+ return;
+ }
+
+ int step = 2;
+ if (size <= 8)
+ {
+ step = -2;
+ dest += size * 2 - 2;
+ }
+
+ for (UInt32 i = 0; i < size; i++)
+ {
+ unsigned b = data[i];
+ dest[0] = GetHex((b >> 4) & 0xF);
+ dest[1] = GetHex(b & 0xF);
+ dest += step;
+ }
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.h b/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.h
new file mode 100644
index 00000000000..38908e2e8b3
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.h
@@ -0,0 +1,107 @@
+// HashCalc.h
+
+#ifndef __HASH_CALC_H
+#define __HASH_CALC_H
+
+#include "../../../Common/Wildcard.h"
+
+#include "../../Common/CreateCoder.h"
+#include "../../Common/MethodProps.h"
+
+#include "DirItem.h"
+#include "Property.h"
+
+const unsigned k_HashCalc_DigestSize_Max = 64;
+
+const unsigned k_HashCalc_NumGroups = 4;
+
+enum
+{
+ k_HashCalc_Index_Current,
+ k_HashCalc_Index_DataSum,
+ k_HashCalc_Index_NamesSum,
+ k_HashCalc_Index_StreamsSum
+};
+
+struct CHasherState
+{
+ CMyComPtr<IHasher> Hasher;
+ AString Name;
+ UInt32 DigestSize;
+ Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max];
+};
+
+struct IHashCalc
+{
+ virtual void InitForNewFile() = 0;
+ virtual void Update(const void *data, UInt32 size) = 0;
+ virtual void SetSize(UInt64 size) = 0;
+ virtual void Final(bool isDir, bool isAltStream, const UString &path) = 0;
+};
+
+struct CHashBundle: public IHashCalc
+{
+ CObjectVector<CHasherState> Hashers;
+
+ UInt64 NumDirs;
+ UInt64 NumFiles;
+ UInt64 NumAltStreams;
+ UInt64 FilesSize;
+ UInt64 AltStreamsSize;
+ UInt64 NumErrors;
+
+ UInt64 CurSize;
+
+ HRESULT SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &methods);
+
+ void Init()
+ {
+ NumDirs = NumFiles = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0;
+ }
+
+ void InitForNewFile();
+ void Update(const void *data, UInt32 size);
+ void SetSize(UInt64 size);
+ void Final(bool isDir, bool isAltStream, const UString &path);
+};
+
+#define INTERFACE_IHashCallbackUI(x) \
+ INTERFACE_IDirItemsCallback(x) \
+ virtual HRESULT StartScanning() x; \
+ virtual HRESULT FinishScanning(const CDirItemsStat &st) x; \
+ virtual HRESULT SetNumFiles(UInt64 numFiles) x; \
+ virtual HRESULT SetTotal(UInt64 size) x; \
+ virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \
+ virtual HRESULT CheckBreak() x; \
+ virtual HRESULT BeforeFirstFile(const CHashBundle &hb) x; \
+ virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x; \
+ virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x; \
+ virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x; \
+ virtual HRESULT AfterLastFile(const CHashBundle &hb) x; \
+
+struct IHashCallbackUI: public IDirItemsCallback
+{
+ INTERFACE_IHashCallbackUI(=0)
+};
+
+struct CHashOptions
+{
+ UStringVector Methods;
+ bool OpenShareForWrite;
+ bool StdInMode;
+ bool AltStreamsMode;
+ NWildcard::ECensorPathMode PathMode;
+
+ CHashOptions(): StdInMode(false), OpenShareForWrite(false), AltStreamsMode(false), PathMode(NWildcard::k_RelatPath) {};
+};
+
+HRESULT HashCalc(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const NWildcard::CCensor &censor,
+ const CHashOptions &options,
+ AString &errorInfo,
+ IHashCallbackUI *callback);
+
+void AddHashHexToString(char *dest, const Byte *data, UInt32 size);
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h b/3rdparty/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h
index e8dcdce5fa5..c456c862737 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h
@@ -1,11 +1,15 @@
// IFileExtractCallback.h
-#ifndef __IFILEEXTRACTCALLBACK_H
-#define __IFILEEXTRACTCALLBACK_H
+#ifndef __I_FILE_EXTRACT_CALLBACK_H
+#define __I_FILE_EXTRACT_CALLBACK_H
+
+#include "../../../Common/MyString.h"
-#include "Common/MyString.h"
#include "../../IDecl.h"
+#include "LoadCodecs.h"
+#include "OpenArchive.h"
+
namespace NOverwriteAnswer
{
enum EEnum
@@ -19,28 +23,92 @@ namespace NOverwriteAnswer
};
}
+
+/* ---------- IFolderArchiveExtractCallback ----------
+is implemented by
+ Console/ExtractCallbackConsole.h CExtractCallbackConsole
+ FileManager/ExtractCallback.h CExtractCallbackImp
+ FAR/ExtractEngine.cpp CExtractCallBackImp: (QueryInterface is not supported)
+
+IID_IFolderArchiveExtractCallback is requested by:
+ - Agent/ArchiveFolder.cpp
+ CAgentFolder::CopyTo(..., IFolderOperationsExtractCallback *callback)
+ is sent to IArchiveFolder::Extract()
+
+ - FileManager/PanelCopy.cpp
+ CPanel::CopyTo(), if (options->testMode)
+ is sent to IArchiveFolder::Extract()
+
+ IFolderArchiveExtractCallback is used by Common/ArchiveExtractCallback.cpp
+*/
+
+#define INTERFACE_IFolderArchiveExtractCallback(x) \
+ STDMETHOD(AskOverwrite)( \
+ const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, \
+ const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, \
+ Int32 *answer) x; \
+ STDMETHOD(PrepareOperation)(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 *position) x; \
+ STDMETHOD(MessageError)(const wchar_t *message) x; \
+ STDMETHOD(SetOperationResult)(Int32 opRes, Int32 encrypted) x; \
+
DECL_INTERFACE_SUB(IFolderArchiveExtractCallback, IProgress, 0x01, 0x07)
{
-public:
- STDMETHOD(AskOverwrite)(
- const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
- const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
- Int32 *answer) PURE;
- STDMETHOD(PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position) PURE;
- STDMETHOD(MessageError)(const wchar_t *message) PURE;
- STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted) PURE;
+ INTERFACE_IFolderArchiveExtractCallback(PURE)
};
+#define INTERFACE_IFolderArchiveExtractCallback2(x) \
+ STDMETHOD(ReportExtractResult)(Int32 opRes, Int32 encrypted, const wchar_t *name) x; \
+
+DECL_INTERFACE_SUB(IFolderArchiveExtractCallback2, IUnknown, 0x01, 0x08)
+{
+ INTERFACE_IFolderArchiveExtractCallback2(PURE)
+};
+
+/* ---------- IExtractCallbackUI ----------
+is implemented by
+ Console/ExtractCallbackConsole.h CExtractCallbackConsole
+ FileManager/ExtractCallback.h CExtractCallbackImp
+*/
+
+#ifdef _NO_CRYPTO
+ #define INTERFACE_IExtractCallbackUI_Crypto(x)
+#else
+ #define INTERFACE_IExtractCallbackUI_Crypto(x) \
+ virtual HRESULT SetPassword(const UString &password) x;
+#endif
+
+#define INTERFACE_IExtractCallbackUI(x) \
+ virtual HRESULT BeforeOpen(const wchar_t *name, bool testMode) x; \
+ virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) x; \
+ virtual HRESULT ThereAreNoFiles() x; \
+ virtual HRESULT ExtractResult(HRESULT result) x; \
+ INTERFACE_IExtractCallbackUI_Crypto(x)
+
struct IExtractCallbackUI: IFolderArchiveExtractCallback
{
- virtual HRESULT BeforeOpen(const wchar_t *name) = 0;
- virtual HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted) = 0;
- virtual HRESULT ThereAreNoFiles() = 0;
- virtual HRESULT ExtractResult(HRESULT result) = 0;
-
- #ifndef _NO_CRYPTO
- virtual HRESULT SetPassword(const UString &password) = 0;
- #endif
+ INTERFACE_IExtractCallbackUI(PURE)
};
+
+
+#define INTERFACE_IGetProp(x) \
+ STDMETHOD(GetProp)(PROPID propID, PROPVARIANT *value) x; \
+
+DECL_INTERFACE_SUB(IGetProp, IUnknown, 0x01, 0x20)
+{
+ INTERFACE_IGetProp(PURE)
+};
+
+#define INTERFACE_IFolderExtractToStreamCallback(x) \
+ STDMETHOD(UseExtractToStream)(Int32 *res) x; \
+ STDMETHOD(GetStream7)(const wchar_t *name, Int32 isDir, ISequentialOutStream **outStream, Int32 askExtractMode, IGetProp *getProp) x; \
+ STDMETHOD(PrepareOperation7)(Int32 askExtractMode) x; \
+ STDMETHOD(SetOperationResult7)(Int32 resultEOperationResult, Int32 encrypted) x; \
+
+DECL_INTERFACE_SUB(IFolderExtractToStreamCallback, IUnknown, 0x01, 0x30)
+{
+ INTERFACE_IFolderExtractToStreamCallback(PURE)
+};
+
+
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp
index cb4f83ee7a1..5435499baa8 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp
@@ -1,41 +1,93 @@
// LoadCodecs.cpp
+/*
+EXTERNAL_CODECS
+---------------
+ CCodecs::Load() tries to detect the directory with plugins.
+ It stops the checking, if it can find any of the following items:
+ - 7z.dll file
+ - "Formats" subdir
+ - "Codecs" subdir
+ The order of check:
+ 1) directory of client executable
+ 2) WIN32: directory for REGISTRY item [HKEY_*\Software\7-Zip\Path**]
+ The order for HKEY_* : Path** :
+ - HKEY_CURRENT_USER : PathXX
+ - HKEY_LOCAL_MACHINE : PathXX
+ - HKEY_CURRENT_USER : Path
+ - HKEY_LOCAL_MACHINE : Path
+ PathXX is Path32 in 32-bit code
+ PathXX is Path64 in 64-bit code
+
+
+EXPORT_CODECS
+-------------
+ if (EXTERNAL_CODECS) is defined, then the code exports internal
+ codecs of client from CCodecs object to external plugins.
+ 7-Zip doesn't use that feature. 7-Zip uses the scheme:
+ - client application without internal plugins.
+ - 7z.dll module contains all (or almost all) plugins.
+ 7z.dll can use codecs from another plugins, if required.
+*/
+
+
#include "StdAfx.h"
-#include "LoadCodecs.h"
+#include "../../../../C/7zVersion.h"
#include "../../../Common/MyCom.h"
+#include "../../../Common/StringToInt.h"
+#include "../../../Common/StringConvert.h"
+
+#include "../../../Windows/PropVariant.h"
+
+#include "LoadCodecs.h"
+
+using namespace NWindows;
+
#ifdef NEW_FOLDER_INTERFACE
#include "../../../Common/StringToInt.h"
#endif
-#include "../../../Windows/PropVariant.h"
#include "../../ICoder.h"
#include "../../Common/RegisterArc.h"
#ifdef EXTERNAL_CODECS
-#include "../../../Windows/FileFind.h"
-#include "../../../Windows/DLL.h"
+
+// #define EXPORT_CODECS
+
+#endif
+
#ifdef NEW_FOLDER_INTERFACE
+extern HINSTANCE g_hInstance;
#include "../../../Windows/ResourceString.h"
static const UINT kIconTypesResId = 100;
#endif
+#ifdef EXTERNAL_CODECS
+
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/DLL.h"
+
#ifdef _WIN32
-#include "Windows/FileName.h"
-#include "Windows/Registry.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/Registry.h"
#endif
-using namespace NWindows;
using namespace NFile;
-#ifdef _WIN32
-extern HINSTANCE g_hInstance;
-#endif
#define kCodecsFolderName FTEXT("Codecs")
#define kFormatsFolderName FTEXT("Formats")
-static CFSTR kMainDll = FTEXT("7z.dll");
+
+
+static CFSTR kMainDll =
+ // #ifdef _WIN32
+ FTEXT("7z.dll");
+ // #else
+ // FTEXT("7z.so");
+ // #endif
+
#ifdef _WIN32
@@ -64,7 +116,97 @@ static bool ReadPathFromRegistry(HKEY baseKey, LPCWSTR value, FString &path)
return false;
}
-#endif
+#endif // _WIN32
+
+#endif // EXTERNAL_CODECS
+
+
+static const unsigned kNumArcsMax = 64;
+static unsigned g_NumArcs = 0;
+static const CArcInfo *g_Arcs[kNumArcsMax];
+
+void RegisterArc(const CArcInfo *arcInfo) throw()
+{
+ if (g_NumArcs < kNumArcsMax)
+ {
+ g_Arcs[g_NumArcs] = arcInfo;
+ g_NumArcs++;
+ }
+}
+
+static void SplitString(const UString &srcString, UStringVector &destStrings)
+{
+ destStrings.Clear();
+ UString s;
+ unsigned len = srcString.Len();
+ if (len == 0)
+ return;
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = srcString[i];
+ if (c == L' ')
+ {
+ if (!s.IsEmpty())
+ {
+ destStrings.Add(s);
+ s.Empty();
+ }
+ }
+ else
+ s += c;
+ }
+ if (!s.IsEmpty())
+ destStrings.Add(s);
+}
+
+int CArcInfoEx::FindExtension(const UString &ext) const
+{
+ FOR_VECTOR (i, Exts)
+ if (ext.IsEqualTo_NoCase(Exts[i].Ext))
+ return i;
+ return -1;
+}
+
+void CArcInfoEx::AddExts(const UString &ext, const UString &addExt)
+{
+ UStringVector exts, addExts;
+ SplitString(ext, exts);
+ SplitString(addExt, addExts);
+ FOR_VECTOR (i, exts)
+ {
+ CArcExtInfo extInfo;
+ extInfo.Ext = exts[i];
+ if (i < addExts.Size())
+ {
+ extInfo.AddExt = addExts[i];
+ if (extInfo.AddExt == L"*")
+ extInfo.AddExt.Empty();
+ }
+ Exts.Add(extInfo);
+ }
+}
+
+#ifndef _SFX
+
+static bool ParseSignatures(const Byte *data, unsigned size, CObjectVector<CByteBuffer> &signatures)
+{
+ signatures.Clear();
+ while (size > 0)
+ {
+ unsigned len = *data++;
+ size--;
+ if (len > size)
+ return false;
+ signatures.AddNew().CopyFrom(data, len);
+ data += len;
+ size -= len;
+ }
+ return true;
+}
+
+#endif // _SFX
+
+#ifdef EXTERNAL_CODECS
static FString GetBaseFolderPrefixFromRegistry()
{
@@ -84,22 +226,17 @@ static FString GetBaseFolderPrefixFromRegistry()
return moduleFolderPrefix;
}
-typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods);
-typedef UInt32 (WINAPI *GetNumberOfFormatsFunc)(UInt32 *numFormats);
-typedef UInt32 (WINAPI *GetHandlerPropertyFunc)(PROPID propID, PROPVARIANT *value);
-typedef UInt32 (WINAPI *GetHandlerPropertyFunc2)(UInt32 index, PROPID propID, PROPVARIANT *value);
-typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *iid, void **outObject);
-typedef UInt32 (WINAPI *SetLargePageModeFunc)();
-
-static HRESULT GetCoderClass(GetMethodPropertyFunc getMethodProperty, UInt32 index,
+static HRESULT GetCoderClass(Func_GetMethodProperty getMethodProperty, UInt32 index,
PROPID propId, CLSID &clsId, bool &isAssigned)
{
- NWindows::NCOM::CPropVariant prop;
+ NCOM::CPropVariant prop;
isAssigned = false;
RINOK(getMethodProperty(index, propId, &prop));
if (prop.vt == VT_BSTR)
{
+ if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID))
+ return E_FAIL;
isAssigned = true;
clsId = *(const GUID *)prop.bstrVal;
}
@@ -111,34 +248,53 @@ static HRESULT GetCoderClass(GetMethodPropertyFunc getMethodProperty, UInt32 ind
HRESULT CCodecs::LoadCodecs()
{
CCodecLib &lib = Libs.Back();
- lib.GetMethodProperty = (GetMethodPropertyFunc)lib.Lib.GetProc("GetMethodProperty");
- if (lib.GetMethodProperty == NULL)
- return S_OK;
- UInt32 numMethods = 1;
- GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)lib.Lib.GetProc("GetNumberOfMethods");
- if (getNumberOfMethodsFunc != NULL)
+ lib.CreateDecoder = (Func_CreateDecoder)lib.Lib.GetProc("CreateDecoder");
+ lib.CreateEncoder = (Func_CreateEncoder)lib.Lib.GetProc("CreateEncoder");
+ lib.GetMethodProperty = (Func_GetMethodProperty)lib.Lib.GetProc("GetMethodProperty");
+
+ if (lib.GetMethodProperty)
{
- RINOK(getNumberOfMethodsFunc(&numMethods));
+ UInt32 numMethods = 1;
+ Func_GetNumberOfMethods getNumberOfMethods = (Func_GetNumberOfMethods)lib.Lib.GetProc("GetNumberOfMethods");
+ if (getNumberOfMethods)
+ {
+ RINOK(getNumberOfMethods(&numMethods));
+ }
+ for (UInt32 i = 0; i < numMethods; i++)
+ {
+ CDllCodecInfo info;
+ info.LibIndex = Libs.Size() - 1;
+ info.CodecIndex = i;
+ RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned));
+ RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned));
+ Codecs.Add(info);
+ }
}
- for(UInt32 i = 0; i < numMethods; i++)
+ Func_GetHashers getHashers = (Func_GetHashers)lib.Lib.GetProc("GetHashers");
+ if (getHashers)
{
- CDllCodecInfo info;
- info.LibIndex = Libs.Size() - 1;
- info.CodecIndex = i;
-
- RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned));
- RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned));
-
- Codecs.Add(info);
+ RINOK(getHashers(&lib.ComHashers));
+ if (lib.ComHashers)
+ {
+ UInt32 numMethods = lib.ComHashers->GetNumHashers();
+ for (UInt32 i = 0; i < numMethods; i++)
+ {
+ CDllHasherInfo info;
+ info.LibIndex = Libs.Size() - 1;
+ info.HasherIndex = i;
+ Hashers.Add(info);
+ }
+ }
}
+
return S_OK;
}
-static HRESULT ReadProp(
- GetHandlerPropertyFunc getProp,
- GetHandlerPropertyFunc2 getProp2,
+static HRESULT GetProp(
+ Func_GetHandlerProperty getProp,
+ Func_GetHandlerProperty2 getProp2,
UInt32 index, PROPID propID, NCOM::CPropVariant &prop)
{
if (getProp2)
@@ -146,13 +302,14 @@ static HRESULT ReadProp(
return getProp(propID, &prop);
}
-static HRESULT ReadBoolProp(
- GetHandlerPropertyFunc getProp,
- GetHandlerPropertyFunc2 getProp2,
+static HRESULT GetProp_Bool(
+ Func_GetHandlerProperty getProp,
+ Func_GetHandlerProperty2 getProp2,
UInt32 index, PROPID propID, bool &res)
{
+ res = false;
NCOM::CPropVariant prop;
- RINOK(ReadProp(getProp, getProp2, index, propID, prop));
+ RINOK(GetProp(getProp, getProp2, index, propID, prop));
if (prop.vt == VT_BOOL)
res = VARIANT_BOOLToBool(prop.boolVal);
else if (prop.vt != VT_EMPTY)
@@ -160,190 +317,154 @@ static HRESULT ReadBoolProp(
return S_OK;
}
-static HRESULT ReadStringProp(
- GetHandlerPropertyFunc getProp,
- GetHandlerPropertyFunc2 getProp2,
- UInt32 index, PROPID propID, UString &res)
+static HRESULT GetProp_UInt32(
+ Func_GetHandlerProperty getProp,
+ Func_GetHandlerProperty2 getProp2,
+ UInt32 index, PROPID propID, UInt32 &res, bool &defined)
{
+ res = 0;
+ defined = false;
NCOM::CPropVariant prop;
- RINOK(ReadProp(getProp, getProp2, index, propID, prop));
- if (prop.vt == VT_BSTR)
- res = prop.bstrVal;
+ RINOK(GetProp(getProp, getProp2, index, propID, prop));
+ if (prop.vt == VT_UI4)
+ {
+ res = prop.ulVal;
+ defined = true;
+ }
else if (prop.vt != VT_EMPTY)
return E_FAIL;
return S_OK;
}
-#endif
-
-static const unsigned int kNumArcsMax = 48;
-static unsigned int g_NumArcs = 0;
-static const CArcInfo *g_Arcs[kNumArcsMax];
-void RegisterArc(const CArcInfo *arcInfo)
+static HRESULT GetProp_String(
+ Func_GetHandlerProperty getProp,
+ Func_GetHandlerProperty2 getProp2,
+ UInt32 index, PROPID propID, UString &res)
{
- if (g_NumArcs < kNumArcsMax)
- g_Arcs[g_NumArcs++] = arcInfo;
+ res.Empty();
+ NCOM::CPropVariant prop;
+ RINOK(GetProp(getProp, getProp2, index, propID, prop));
+ if (prop.vt == VT_BSTR)
+ res.SetFromBstr(prop.bstrVal);
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
}
-static void SplitString(const UString &srcString, UStringVector &destStrings)
+static HRESULT GetProp_RawData(
+ Func_GetHandlerProperty getProp,
+ Func_GetHandlerProperty2 getProp2,
+ UInt32 index, PROPID propID, CByteBuffer &bb)
{
- destStrings.Clear();
- UString s;
- int len = srcString.Length();
- if (len == 0)
- return;
- for (int i = 0; i < len; i++)
+ bb.Free();
+ NCOM::CPropVariant prop;
+ RINOK(GetProp(getProp, getProp2, index, propID, prop));
+ if (prop.vt == VT_BSTR)
{
- wchar_t c = srcString[i];
- if (c == L' ')
- {
- if (!s.IsEmpty())
- {
- destStrings.Add(s);
- s.Empty();
- }
- }
- else
- s += c;
+ UINT len = ::SysStringByteLen(prop.bstrVal);
+ bb.CopyFrom((const Byte *)prop.bstrVal, len);
}
- if (!s.IsEmpty())
- destStrings.Add(s);
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
}
-int CArcInfoEx::FindExtension(const UString &ext) const
+static const UInt32 kArcFlagsPars[] =
{
- for (int i = 0; i < Exts.Size(); i++)
- if (ext.CompareNoCase(Exts[i].Ext) == 0)
- return i;
- return -1;
-}
+ NArchive::NHandlerPropID::kKeepName, NArcInfoFlags::kKeepName,
+ NArchive::NHandlerPropID::kAltStreams, NArcInfoFlags::kAltStreams,
+ NArchive::NHandlerPropID::kNtSecure, NArcInfoFlags::kNtSecure
+};
-void CArcInfoEx::AddExts(const wchar_t *ext, const wchar_t *addExt)
+HRESULT CCodecs::LoadFormats()
{
- UStringVector exts, addExts;
- if (ext != 0)
- SplitString(ext, exts);
- if (addExt != 0)
- SplitString(addExt, addExts);
- for (int i = 0; i < exts.Size(); i++)
+ const NDLL::CLibrary &lib = Libs.Back().Lib;
+
+ Func_GetHandlerProperty getProp = NULL;
+ Func_GetHandlerProperty2 getProp2 = (Func_GetHandlerProperty2)lib.GetProc("GetHandlerProperty2");
+ Func_GetIsArc getIsArc = (Func_GetIsArc)lib.GetProc("GetIsArc");
+
+ UInt32 numFormats = 1;
+
+ if (getProp2)
{
- CArcExtInfo extInfo;
- extInfo.Ext = exts[i];
- if (i < addExts.Size())
+ Func_GetNumberOfFormats getNumberOfFormats = (Func_GetNumberOfFormats)lib.GetProc("GetNumberOfFormats");
+ if (getNumberOfFormats)
{
- extInfo.AddExt = addExts[i];
- if (extInfo.AddExt == L"*")
- extInfo.AddExt.Empty();
+ RINOK(getNumberOfFormats(&numFormats));
}
- Exts.Add(extInfo);
}
-}
-
-#ifdef EXTERNAL_CODECS
-
-HRESULT CCodecs::LoadFormats()
-{
- const NDLL::CLibrary &lib = Libs.Back().Lib;
- GetHandlerPropertyFunc getProp = 0;
- GetHandlerPropertyFunc2 getProp2 = (GetHandlerPropertyFunc2)lib.GetProc("GetHandlerProperty2");
- if (getProp2 == NULL)
+ else
{
- getProp = (GetHandlerPropertyFunc)lib.GetProc("GetHandlerProperty");
- if (getProp == NULL)
+ getProp = (Func_GetHandlerProperty)lib.GetProc("GetHandlerProperty");
+ if (!getProp)
return S_OK;
}
-
- UInt32 numFormats = 1;
- GetNumberOfFormatsFunc getNumberOfFormats = (GetNumberOfFormatsFunc)lib.GetProc("GetNumberOfFormats");
- if (getNumberOfFormats != NULL)
- {
- RINOK(getNumberOfFormats(&numFormats));
- }
- if (getProp2 == NULL)
- numFormats = 1;
-
- for(UInt32 i = 0; i < numFormats; i++)
+
+ for (UInt32 i = 0; i < numFormats; i++)
{
CArcInfoEx item;
item.LibIndex = Libs.Size() - 1;
item.FormatIndex = i;
- RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kName, item.Name));
+ RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kName, item.Name));
- NCOM::CPropVariant prop;
- if (ReadProp(getProp, getProp2, i, NArchive::kClassID, prop) != S_OK)
- continue;
- if (prop.vt != VT_BSTR)
- continue;
- item.ClassID = *(const GUID *)prop.bstrVal;
- prop.Clear();
+ {
+ NCOM::CPropVariant prop;
+ if (GetProp(getProp, getProp2, i, NArchive::NHandlerPropID::kClassID, prop) != S_OK)
+ continue;
+ if (prop.vt != VT_BSTR)
+ continue;
+ if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID))
+ return E_FAIL;
+ item.ClassID = *(const GUID *)prop.bstrVal;
+ prop.Clear();
+ }
UString ext, addExt;
- RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kExtension, ext));
- RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kAddExtension, addExt));
+ RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kExtension, ext));
+ RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kAddExtension, addExt));
item.AddExts(ext, addExt);
- ReadBoolProp(getProp, getProp2, i, NArchive::kUpdate, item.UpdateEnabled);
- if (item.UpdateEnabled)
- ReadBoolProp(getProp, getProp2, i, NArchive::kKeepName, item.KeepName);
-
- if (ReadProp(getProp, getProp2, i, NArchive::kStartSignature, prop) == S_OK)
- if (prop.vt == VT_BSTR)
- {
- UINT len = ::SysStringByteLen(prop.bstrVal);
- item.StartSignature.SetCapacity(len);
- memmove(item.StartSignature, prop.bstrVal, len);
- }
- Formats.Add(item);
- }
- return S_OK;
-}
-
-#ifdef NEW_FOLDER_INTERFACE
-void CCodecIcons::LoadIcons(HMODULE m)
-{
- UString iconTypes = MyLoadStringW(m, kIconTypesResId);
- UStringVector pairs;
- SplitString(iconTypes, pairs);
- for (int i = 0; i < pairs.Size(); i++)
- {
- const UString &s = pairs[i];
- int pos = s.Find(L':');
- CIconPair iconPair;
- iconPair.IconIndex = -1;
- if (pos < 0)
- pos = s.Length();
- else
+ GetProp_Bool(getProp, getProp2, i, NArchive::NHandlerPropID::kUpdate, item.UpdateEnabled);
+ bool flags_Defined = false;
+ RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kFlags, item.Flags, flags_Defined));
+ item.NewInterface = flags_Defined;
+ if (!flags_Defined) // && item.UpdateEnabled
{
- UString num = s.Mid(pos + 1);
- if (!num.IsEmpty())
+ // support for DLL version before 9.31:
+ for (unsigned j = 0; j < ARRAY_SIZE(kArcFlagsPars); j += 2)
{
- const wchar_t *end;
- iconPair.IconIndex = (UInt32)ConvertStringToUInt64(num, &end);
- if (*end != L'\0')
- continue;
+ bool val = false;
+ GetProp_Bool(getProp, getProp2, i, kArcFlagsPars[j], val);
+ if (val)
+ item.Flags |= kArcFlagsPars[j + 1];
}
}
- iconPair.Ext = s.Left(pos);
- IconPairs.Add(iconPair);
- }
-}
-
-bool CCodecIcons::FindIconIndex(const UString &ext, int &iconIndex) const
-{
- iconIndex = -1;
- for (int i = 0; i < IconPairs.Size(); i++)
- {
- const CIconPair &pair = IconPairs[i];
- if (ext.CompareNoCase(pair.Ext) == 0)
+
+ CByteBuffer sig;
+ RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kSignature, sig));
+ if (sig.Size() != 0)
+ item.Signatures.Add(sig);
+ else
{
- iconIndex = pair.IconIndex;
- return true;
+ RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kMultiSignature, sig));
+ ParseSignatures(sig, (unsigned)sig.Size(), item.Signatures);
}
+
+ bool signatureOffset_Defined;
+ RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kSignatureOffset, item.SignatureOffset, signatureOffset_Defined));
+
+ // bool version_Defined;
+ // RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kVersion, item.Version, version_Defined));
+
+ if (getIsArc)
+ getIsArc(i, &item.IsArcFunc);
+
+ Formats.Add(item);
}
- return false;
+ return S_OK;
}
-#endif
#ifdef _7ZIP_LARGE_PAGES
extern "C"
@@ -352,23 +473,28 @@ extern "C"
}
#endif
-HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll)
+HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loadedOK)
{
+ if (loadedOK)
+ *loadedOK = false;
+
if (needCheckDll)
{
- NDLL::CLibrary library;
- if (!library.LoadEx(dllPath, LOAD_LIBRARY_AS_DATAFILE))
+ NDLL::CLibrary lib;
+ if (!lib.LoadEx(dllPath, LOAD_LIBRARY_AS_DATAFILE))
return S_OK;
}
- Libs.Add(CCodecLib());
+
+ Libs.AddNew();
CCodecLib &lib = Libs.Back();
- #ifdef NEW_FOLDER_INTERFACE
lib.Path = dllPath;
- #endif
bool used = false;
HRESULT res = S_OK;
+
if (lib.Lib.Load(dllPath))
{
+ if (loadedOK)
+ *loadedOK = true;
#ifdef NEW_FOLDER_INTERFACE
lib.LoadIcons();
#endif
@@ -376,28 +502,38 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll)
#ifdef _7ZIP_LARGE_PAGES
if (g_LargePageSize != 0)
{
- SetLargePageModeFunc setLargePageMode = (SetLargePageModeFunc)lib.Lib.GetProc("SetLargePageMode");
- if (setLargePageMode != 0)
+ Func_SetLargePageMode setLargePageMode = (Func_SetLargePageMode)lib.Lib.GetProc("SetLargePageMode");
+ if (setLargePageMode)
setLargePageMode();
}
#endif
- lib.CreateObject = (CreateObjectFunc)lib.Lib.GetProc("CreateObject");
- if (lib.CreateObject != 0)
+ if (CaseSensitiveChange)
{
- int startSize = Codecs.Size();
+ Func_SetCaseSensitive setCaseSensitive = (Func_SetCaseSensitive)lib.Lib.GetProc("SetCaseSensitive");
+ if (setCaseSensitive)
+ setCaseSensitive(CaseSensitive ? 1 : 0);
+ }
+
+ lib.CreateObject = (Func_CreateObject)lib.Lib.GetProc("CreateObject");
+ if (lib.CreateObject)
+ {
+ unsigned startSize = Codecs.Size() + Hashers.Size();
res = LoadCodecs();
- used = (Codecs.Size() != startSize);
+ used = (startSize != Codecs.Size() + Hashers.Size());
if (res == S_OK)
{
startSize = Formats.Size();
res = LoadFormats();
- used = used || (Formats.Size() != startSize);
+ if (startSize != Formats.Size())
+ used = true;
}
}
}
+
if (!used)
Libs.DeleteBack();
+
return res;
}
@@ -414,15 +550,31 @@ HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPrefix)
return S_OK;
}
-#endif
-
-#ifndef _SFX
-static inline void SetBuffer(CByteBuffer &bb, const Byte *data, int size)
+void CCodecs::CloseLibs()
{
- bb.SetCapacity(size);
- memmove((Byte *)bb, data, size);
+ // OutputDebugStringA("~CloseLibs start");
+ /*
+ WIN32: FreeLibrary() (CLibrary::Free()) function doesn't work as expected,
+ if it's called from another FreeLibrary() call.
+ So we need to call FreeLibrary() before global destructors.
+
+ Also we free global links from DLLs to object of this module before CLibrary::Free() call.
+ */
+
+ FOR_VECTOR(i, Libs)
+ {
+ const CCodecLib &lib = Libs[i];
+ if (lib.SetCodecs)
+ lib.SetCodecs(NULL);
+ }
+
+ // OutputDebugStringA("~CloseLibs after SetCodecs");
+ Libs.Clear();
+ // OutputDebugStringA("~CloseLibs end");
}
-#endif
+
+#endif // EXTERNAL_CODECS
+
HRESULT CCodecs::Load()
{
@@ -431,31 +583,92 @@ HRESULT CCodecs::Load()
#endif
Formats.Clear();
+
#ifdef EXTERNAL_CODECS
- Codecs.Clear();
+ MainDll_ErrorPath.Empty();
+ Codecs.Clear();
+ Hashers.Clear();
#endif
+
for (UInt32 i = 0; i < g_NumArcs; i++)
{
const CArcInfo &arc = *g_Arcs[i];
CArcInfoEx item;
- item.Name = arc.Name;
+
+ item.Name.SetFromAscii(arc.Name);
item.CreateInArchive = arc.CreateInArchive;
- item.CreateOutArchive = arc.CreateOutArchive;
- item.AddExts(arc.Ext, arc.AddExt);
- item.UpdateEnabled = (arc.CreateOutArchive != 0);
- item.KeepName = arc.KeepName;
+ item.IsArcFunc = arc.IsArc;
+ item.Flags = arc.Flags;
+
+ {
+ UString e, ae;
+ if (arc.Ext)
+ e.SetFromAscii(arc.Ext);
+ if (arc.AddExt)
+ ae.SetFromAscii(arc.AddExt);
+ item.AddExts(e, ae);
+ }
#ifndef _SFX
- SetBuffer(item.StartSignature, arc.Signature, arc.SignatureSize);
+
+ item.CreateOutArchive = arc.CreateOutArchive;
+ item.UpdateEnabled = (arc.CreateOutArchive != NULL);
+ item.SignatureOffset = arc.SignatureOffset;
+ // item.Version = MY_VER_MIX;
+ item.NewInterface = true;
+
+ if (arc.IsMultiSignature())
+ ParseSignatures(arc.Signature, arc.SignatureSize, item.Signatures);
+ else
+ item.Signatures.AddNew().CopyFrom(arc.Signature, arc.SignatureSize);
+
#endif
+
Formats.Add(item);
}
+
#ifdef EXTERNAL_CODECS
- const FString baseFolder = GetBaseFolderPrefixFromRegistry();
- RINOK(LoadDll(baseFolder + kMainDll, false));
- RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName FSTRING_PATH_SEPARATOR));
- RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName FSTRING_PATH_SEPARATOR));
+ const FString baseFolder = GetBaseFolderPrefixFromRegistry();
+ {
+ bool loadedOK;
+ RINOK(LoadDll(baseFolder + kMainDll, false, &loadedOK));
+ if (!loadedOK)
+ MainDll_ErrorPath = kMainDll;
+ }
+ RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName FSTRING_PATH_SEPARATOR));
+ RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName FSTRING_PATH_SEPARATOR));
+
+ NeedSetLibCodecs = true;
+
+ if (Libs.Size() == 0)
+ NeedSetLibCodecs = false;
+ else if (Libs.Size() == 1)
+ {
+ // we don't need to set ISetCompressCodecsInfo, if all arcs and codecs are in one external module.
+ #ifndef EXPORT_CODECS
+ if (g_NumArcs == 0)
+ NeedSetLibCodecs = false;
+ #endif
+ }
+
+ if (NeedSetLibCodecs)
+ {
+ /* 15.00: now we call global function in DLL: SetCompressCodecsInfo(c)
+ old versions called only ISetCompressCodecsInfo::SetCompressCodecsInfo(c) for each archive handler */
+
+ FOR_VECTOR(i, Libs)
+ {
+ CCodecLib &lib = Libs[i];
+ lib.SetCodecs = (Func_SetCodecs)lib.Lib.GetProc("SetCodecs");
+ if (lib.SetCodecs)
+ {
+ RINOK(lib.SetCodecs(this));
+ }
+ }
+ }
+
#endif
+
return S_OK;
}
@@ -463,16 +676,21 @@ HRESULT CCodecs::Load()
int CCodecs::FindFormatForArchiveName(const UString &arcPath) const
{
- int slashPos = arcPath.ReverseFind(WCHAR_PATH_SEPARATOR);
- int dotPos = arcPath.ReverseFind(L'.');
- if (dotPos < 0 || dotPos < slashPos)
+ int dotPos = arcPath.ReverseFind_Dot();
+ if (dotPos <= arcPath.ReverseFind_PathSepar())
return -1;
- const UString ext = arcPath.Mid(dotPos + 1);
- for (int i = 0; i < Formats.Size(); i++)
+ const UString ext = arcPath.Ptr(dotPos + 1);
+ if (ext.IsEmpty())
+ return -1;
+ if (ext.IsEqualTo_Ascii_NoCase("exe"))
+ return -1;
+ FOR_VECTOR (i, Formats)
{
const CArcInfoEx &arc = Formats[i];
+ /*
if (!arc.UpdateEnabled)
continue;
+ */
if (arc.FindExtension(ext) >= 0)
return i;
}
@@ -483,7 +701,7 @@ int CCodecs::FindFormatForExtension(const UString &ext) const
{
if (ext.IsEmpty())
return -1;
- for (int i = 0; i < Formats.Size(); i++)
+ FOR_VECTOR (i, Formats)
if (Formats[i].FindExtension(ext) >= 0)
return i;
return -1;
@@ -491,8 +709,8 @@ int CCodecs::FindFormatForExtension(const UString &ext) const
int CCodecs::FindFormatForArchiveType(const UString &arcType) const
{
- for (int i = 0; i < Formats.Size(); i++)
- if (Formats[i].Name.CompareNoCase(arcType) == 0)
+ FOR_VECTOR (i, Formats)
+ if (Formats[i].Name.IsEqualTo_NoCase(arcType))
return i;
return -1;
}
@@ -500,12 +718,14 @@ int CCodecs::FindFormatForArchiveType(const UString &arcType) const
bool CCodecs::FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const
{
formatIndices.Clear();
- for (int pos = 0; pos < arcType.Length();)
+ for (unsigned pos = 0; pos < arcType.Len();)
{
- int pos2 = arcType.Find('.', pos);
+ int pos2 = arcType.Find(L'.', pos);
if (pos2 < 0)
- pos2 = arcType.Length();
+ pos2 = arcType.Len();
const UString name = arcType.Mid(pos, pos2 - pos);
+ if (name.IsEmpty())
+ return false;
int index = FindFormatForArchiveType(name);
if (index < 0 && name != L"*")
{
@@ -518,24 +738,90 @@ bool CCodecs::FindFormatForArchiveType(const UString &arcType, CIntVector &forma
return true;
}
-#endif
+#endif // _SFX
+
+
+#ifdef NEW_FOLDER_INTERFACE
+
+void CCodecIcons::LoadIcons(HMODULE m)
+{
+ UString iconTypes;
+ MyLoadString(m, kIconTypesResId, iconTypes);
+ UStringVector pairs;
+ SplitString(iconTypes, pairs);
+ FOR_VECTOR (i, pairs)
+ {
+ const UString &s = pairs[i];
+ int pos = s.Find(L':');
+ CIconPair iconPair;
+ iconPair.IconIndex = -1;
+ if (pos < 0)
+ pos = s.Len();
+ else
+ {
+ UString num = s.Ptr(pos + 1);
+ if (!num.IsEmpty())
+ {
+ const wchar_t *end;
+ iconPair.IconIndex = ConvertStringToUInt32(num, &end);
+ if (*end != 0)
+ continue;
+ }
+ }
+ iconPair.Ext = s.Left(pos);
+ IconPairs.Add(iconPair);
+ }
+}
+
+bool CCodecIcons::FindIconIndex(const UString &ext, int &iconIndex) const
+{
+ iconIndex = -1;
+ FOR_VECTOR (i, IconPairs)
+ {
+ const CIconPair &pair = IconPairs[i];
+ if (ext.IsEqualTo_NoCase(pair.Ext))
+ {
+ iconIndex = pair.IconIndex;
+ return true;
+ }
+ }
+ return false;
+}
+
+#endif // NEW_FOLDER_INTERFACE
+
#ifdef EXTERNAL_CODECS
+// #define EXPORT_CODECS
+
#ifdef EXPORT_CODECS
-extern unsigned int g_NumCodecs;
-STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject);
+
+extern unsigned g_NumCodecs;
+STDAPI CreateDecoder(UInt32 index, const GUID *iid, void **outObject);
+STDAPI CreateEncoder(UInt32 index, const GUID *iid, void **outObject);
STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value);
-// STDAPI GetNumberOfMethods(UInt32 *numCodecs);
-#endif
+#define NUM_EXPORT_CODECS g_NumCodecs
+
+extern unsigned g_NumHashers;
+STDAPI CreateHasher(UInt32 index, IHasher **hasher);
+STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value);
+#define NUM_EXPORT_HASHERS g_NumHashers
+
+#else // EXPORT_CODECS
+
+#define NUM_EXPORT_CODECS 0
+#define NUM_EXPORT_HASHERS 0
-STDMETHODIMP CCodecs::GetNumberOfMethods(UInt32 *numMethods)
+#endif // EXPORT_CODECS
+
+STDMETHODIMP CCodecs::GetNumMethods(UInt32 *numMethods)
{
- *numMethods =
- #ifdef EXPORT_CODECS
- g_NumCodecs +
- #endif
- Codecs.Size();
+ *numMethods = NUM_EXPORT_CODECS
+ #ifdef EXTERNAL_CODECS
+ + Codecs.Size()
+ #endif
+ ;
return S_OK;
}
@@ -546,128 +832,197 @@ STDMETHODIMP CCodecs::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *valu
return GetMethodProperty(index, propID, value);
#endif
- const CDllCodecInfo &ci = Codecs[index
- #ifdef EXPORT_CODECS
- - g_NumCodecs
- #endif
- ];
+ #ifdef EXTERNAL_CODECS
+ const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS];
- if (propID == NMethodPropID::kDecoderIsAssigned)
+ if (propID == NMethodPropID::kDecoderIsAssigned ||
+ propID == NMethodPropID::kEncoderIsAssigned)
{
- NWindows::NCOM::CPropVariant propVariant;
- propVariant = ci.DecoderIsAssigned;
- propVariant.Detach(value);
- return S_OK;
- }
- if (propID == NMethodPropID::kEncoderIsAssigned)
- {
- NWindows::NCOM::CPropVariant propVariant;
- propVariant = ci.EncoderIsAssigned;
- propVariant.Detach(value);
+ NCOM::CPropVariant prop;
+ prop = (bool)((propID == NMethodPropID::kDecoderIsAssigned) ?
+ ci.DecoderIsAssigned :
+ ci.EncoderIsAssigned);
+ prop.Detach(value);
return S_OK;
}
- return Libs[ci.LibIndex].GetMethodProperty(ci.CodecIndex, propID, value);
+ const CCodecLib &lib = Libs[ci.LibIndex];
+ return lib.GetMethodProperty(ci.CodecIndex, propID, value);
+ #else
+ return E_FAIL;
+ #endif
}
STDMETHODIMP CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder)
{
#ifdef EXPORT_CODECS
if (index < g_NumCodecs)
- return CreateCoder2(false, index, iid, coder);
+ return CreateDecoder(index, iid, coder);
#endif
- const CDllCodecInfo &ci = Codecs[index
- #ifdef EXPORT_CODECS
- - g_NumCodecs
- #endif
- ];
+
+ #ifdef EXTERNAL_CODECS
+ const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS];
if (ci.DecoderIsAssigned)
- return Libs[ci.LibIndex].CreateObject(&ci.Decoder, 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);
+ }
return S_OK;
+ #else
+ return E_FAIL;
+ #endif
}
STDMETHODIMP CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder)
{
#ifdef EXPORT_CODECS
if (index < g_NumCodecs)
- return CreateCoder2(true, index, iid, coder);
+ return CreateEncoder(index, iid, coder);
#endif
- const CDllCodecInfo &ci = Codecs[index
- #ifdef EXPORT_CODECS
- - g_NumCodecs
- #endif
- ];
+
+ #ifdef EXTERNAL_CODECS
+ const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS];
if (ci.EncoderIsAssigned)
- return Libs[ci.LibIndex].CreateObject(&ci.Encoder, 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);
+ }
return S_OK;
+ #else
+ return E_FAIL;
+ #endif
}
-HRESULT CCodecs::CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const
+
+STDMETHODIMP_(UInt32) CCodecs::GetNumHashers()
{
- for (int i = 0; i < Codecs.Size(); i++)
- {
- const CDllCodecInfo &codec = Codecs[i];
- if (encode && !codec.EncoderIsAssigned || !encode && !codec.DecoderIsAssigned)
- continue;
- const CCodecLib &lib = Libs[codec.LibIndex];
- UString res;
- NWindows::NCOM::CPropVariant prop;
- RINOK(lib.GetMethodProperty(codec.CodecIndex, NMethodPropID::kName, &prop));
- if (prop.vt == VT_BSTR)
- res = prop.bstrVal;
- else if (prop.vt != VT_EMPTY)
- continue;
- if (name.CompareNoCase(res) == 0)
- return lib.CreateObject(encode ? &codec.Encoder : &codec.Decoder, &IID_ICompressCoder, (void **)&coder);
- }
- return CLASS_E_CLASSNOTAVAILABLE;
+ return NUM_EXPORT_HASHERS
+ #ifdef EXTERNAL_CODECS
+ + Hashers.Size()
+ #endif
+ ;
+}
+
+STDMETHODIMP CCodecs::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ #ifdef EXPORT_CODECS
+ if (index < g_NumHashers)
+ return ::GetHasherProp(index, propID, value);
+ #endif
+
+ #ifdef EXTERNAL_CODECS
+ const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS];
+ return Libs[ci.LibIndex].ComHashers->GetHasherProp(ci.HasherIndex, propID, value);
+ #else
+ return E_FAIL;
+ #endif
}
-int CCodecs::GetCodecLibIndex(UInt32 index)
+STDMETHODIMP CCodecs::CreateHasher(UInt32 index, IHasher **hasher)
+{
+ #ifdef EXPORT_CODECS
+ if (index < g_NumHashers)
+ return CreateHasher(index, hasher);
+ #endif
+ #ifdef EXTERNAL_CODECS
+ const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS];
+ return Libs[ci.LibIndex].ComHashers->CreateHasher(ci.HasherIndex, hasher);
+ #else
+ return E_FAIL;
+ #endif
+}
+
+int CCodecs::GetCodec_LibIndex(UInt32 index) const
{
#ifdef EXPORT_CODECS
if (index < g_NumCodecs)
return -1;
#endif
+
#ifdef EXTERNAL_CODECS
- const CDllCodecInfo &ci = Codecs[index
- #ifdef EXPORT_CODECS
- - g_NumCodecs
- #endif
- ];
+ const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS];
return ci.LibIndex;
#else
return -1;
#endif
}
-bool CCodecs::GetCodecEncoderIsAssigned(UInt32 index)
+int CCodecs::GetHasherLibIndex(UInt32 index)
+{
+ #ifdef EXPORT_CODECS
+ if (index < g_NumHashers)
+ return -1;
+ #endif
+
+ #ifdef EXTERNAL_CODECS
+ const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS];
+ return ci.LibIndex;
+ #else
+ return -1;
+ #endif
+}
+
+bool CCodecs::GetCodec_DecoderIsAssigned(UInt32 index) const
{
#ifdef EXPORT_CODECS
if (index < g_NumCodecs)
{
- NWindows::NCOM::CPropVariant prop;
- if (GetProperty(index, NMethodPropID::kEncoder, &prop) == S_OK)
- if (prop.vt != VT_EMPTY)
- return true;
+ NCOM::CPropVariant prop;
+ if (GetProperty(index, NMethodPropID::kDecoderIsAssigned, &prop) == S_OK)
+ {
+ if (prop.vt == VT_BOOL)
+ return VARIANT_BOOLToBool(prop.boolVal);
+ }
return false;
}
#endif
+
#ifdef EXTERNAL_CODECS
- const CDllCodecInfo &ci = Codecs[index
- #ifdef EXPORT_CODECS
- - g_NumCodecs
- #endif
- ];
- return ci.EncoderIsAssigned;
+ return Codecs[index - NUM_EXPORT_CODECS].DecoderIsAssigned;
#else
return false;
#endif
}
-HRESULT CCodecs::GetCodecId(UInt32 index, UInt64 &id)
+bool CCodecs::GetCodec_EncoderIsAssigned(UInt32 index) const
{
- UString s;
- NWindows::NCOM::CPropVariant prop;
+ #ifdef EXPORT_CODECS
+ if (index < g_NumCodecs)
+ {
+ NCOM::CPropVariant prop;
+ if (GetProperty(index, NMethodPropID::kEncoderIsAssigned, &prop) == S_OK)
+ {
+ if (prop.vt == VT_BOOL)
+ return VARIANT_BOOLToBool(prop.boolVal);
+ }
+ return false;
+ }
+ #endif
+
+ #ifdef EXTERNAL_CODECS
+ return Codecs[index - NUM_EXPORT_CODECS].EncoderIsAssigned;
+ #else
+ return false;
+ #endif
+}
+
+UInt32 CCodecs::GetCodec_NumStreams(UInt32 index)
+{
+ NCOM::CPropVariant prop;
+ RINOK(GetProperty(index, NMethodPropID::kPackStreams, &prop));
+ if (prop.vt == VT_UI4)
+ return (UInt32)prop.ulVal;
+ if (prop.vt == VT_EMPTY)
+ return 1;
+ return 0;
+}
+
+HRESULT CCodecs::GetCodec_Id(UInt32 index, UInt64 &id)
+{
+ NCOM::CPropVariant prop;
RINOK(GetProperty(index, NMethodPropID::kID, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
@@ -675,14 +1030,43 @@ HRESULT CCodecs::GetCodecId(UInt32 index, UInt64 &id)
return S_OK;
}
-UString CCodecs::GetCodecName(UInt32 index)
+AString CCodecs::GetCodec_Name(UInt32 index)
{
- UString s;
- NWindows::NCOM::CPropVariant prop;
+ AString s;
+ NCOM::CPropVariant prop;
if (GetProperty(index, NMethodPropID::kName, &prop) == S_OK)
if (prop.vt == VT_BSTR)
- s = prop.bstrVal;
+ s.SetFromWStr_if_Ascii(prop.bstrVal);
return s;
}
-#endif
+UInt64 CCodecs::GetHasherId(UInt32 index)
+{
+ NCOM::CPropVariant prop;
+ if (GetHasherProp(index, NMethodPropID::kID, &prop) != S_OK)
+ return 0;
+ if (prop.vt != VT_UI8)
+ return 0;
+ return prop.uhVal.QuadPart;
+}
+
+AString CCodecs::GetHasherName(UInt32 index)
+{
+ AString s;
+ NCOM::CPropVariant prop;
+ if (GetHasherProp(index, NMethodPropID::kName, &prop) == S_OK)
+ if (prop.vt == VT_BSTR)
+ s.SetFromWStr_if_Ascii(prop.bstrVal);
+ return s;
+}
+
+UInt32 CCodecs::GetHasherDigestSize(UInt32 index)
+{
+ NCOM::CPropVariant prop;
+ RINOK(GetHasherProp(index, NMethodPropID::kDigestSize, &prop));
+ if (prop.vt != VT_UI4)
+ return 0;
+ return prop.ulVal;
+}
+
+#endif // EXTERNAL_CODECS
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.h b/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.h
index f5963ed60ee..ac9eeac71dd 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.h
@@ -3,34 +3,88 @@
#ifndef __LOAD_CODECS_H
#define __LOAD_CODECS_H
+/*
+Client application uses LoadCodecs.* to load plugins to
+CCodecs object, that contains 3 lists of plugins:
+ 1) Formats - internal and external archive handlers
+ 2) Codecs - external codecs
+ 3) Hashers - external hashers
+
+EXTERNAL_CODECS
+---------------
+
+ if EXTERNAL_CODECS is defined, then the code tries to load external
+ plugins from DLL files (shared libraries).
+
+ There are two types of executables in 7-Zip:
+
+ 1) Executable that uses external plugins must be compiled
+ with EXTERNAL_CODECS defined:
+ - 7z.exe, 7zG.exe, 7zFM.exe
+
+ Note: EXTERNAL_CODECS is used also in CPP/7zip/Common/CreateCoder.h
+ that code is used in plugin module (7z.dll).
+
+ 2) Standalone modules are compiled without EXTERNAL_CODECS:
+ - SFX modules: 7z.sfx, 7zCon.sfx
+ - standalone versions of console 7-Zip: 7za.exe, 7zr.exe
+
+ if EXTERNAL_CODECS is defined, CCodecs class implements interfaces:
+ - ICompressCodecsInfo : for Codecs
+ - IHashers : for Hashers
+
+ The client application can send CCodecs object to each plugin module.
+ And plugin module can use ICompressCodecsInfo or IHashers interface to access
+ another plugins.
+
+ There are 2 ways to send (ICompressCodecsInfo * compressCodecsInfo) to plugin
+ 1) for old versions:
+ a) request ISetCompressCodecsInfo from created archive handler.
+ b) call ISetCompressCodecsInfo::SetCompressCodecsInfo(compressCodecsInfo)
+ 2) for new versions:
+ a) request "SetCodecs" function from DLL file
+ b) call SetCodecs(compressCodecsInfo) function from DLL file
+*/
+
+#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyCom.h"
#include "../../../Common/MyString.h"
-#include "../../../Common/Buffer.h"
-#include "../../ICoder.h"
+#include "../../../Common/ComTry.h"
#ifdef EXTERNAL_CODECS
#include "../../../Windows/DLL.h"
#endif
+#include "../../ICoder.h"
+
+#include "../../Archive/IArchive.h"
+
+
+#ifdef EXTERNAL_CODECS
+
struct CDllCodecInfo
{
- CLSID Encoder;
- CLSID Decoder;
+ unsigned LibIndex;
+ UInt32 CodecIndex;
bool EncoderIsAssigned;
bool DecoderIsAssigned;
- int LibIndex;
- UInt32 CodecIndex;
+ CLSID Encoder;
+ CLSID Decoder;
};
-#include "../../Archive/IArchive.h"
+struct CDllHasherInfo
+{
+ unsigned LibIndex;
+ UInt32 HasherIndex;
+};
-typedef IInArchive * (*CreateInArchiveP)();
-typedef IOutArchive * (*CreateOutArchiveP)();
+#endif
struct CArcExtInfo
{
UString Ext;
UString AddExt;
+
CArcExtInfo() {}
CArcExtInfo(const UString &ext): Ext(ext) {}
CArcExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}
@@ -39,24 +93,45 @@ struct CArcExtInfo
struct CArcInfoEx
{
- #ifdef EXTERNAL_CODECS
- int LibIndex;
- UInt32 FormatIndex;
- CLSID ClassID;
- #endif
- bool UpdateEnabled;
- CreateInArchiveP CreateInArchive;
- CreateOutArchiveP CreateOutArchive;
+ UInt32 Flags;
+
+ Func_CreateInArchive CreateInArchive;
+ Func_IsArc IsArcFunc;
+
UString Name;
CObjectVector<CArcExtInfo> Exts;
+
#ifndef _SFX
- CByteBuffer StartSignature;
- // CByteBuffer FinishSignature;
- #ifdef NEW_FOLDER_INTERFACE
- UStringVector AssociateExts;
+ Func_CreateOutArchive CreateOutArchive;
+ bool UpdateEnabled;
+ bool NewInterface;
+ // UInt32 Version;
+ UInt32 SignatureOffset;
+ CObjectVector<CByteBuffer> Signatures;
+ #ifdef NEW_FOLDER_INTERFACE
+ UStringVector AssociateExts;
+ #endif
#endif
+
+ #ifdef EXTERNAL_CODECS
+ int LibIndex;
+ UInt32 FormatIndex;
+ CLSID ClassID;
#endif
- bool KeepName;
+
+ bool Flags_KeepName() const { return (Flags & NArcInfoFlags::kKeepName) != 0; }
+ bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; }
+
+ bool Flags_AltStreams() const { return (Flags & NArcInfoFlags::kAltStreams) != 0; }
+ bool Flags_NtSecure() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; }
+ bool Flags_SymLinks() const { return (Flags & NArcInfoFlags::kSymLinks) != 0; }
+ bool Flags_HardLinks() const { return (Flags & NArcInfoFlags::kHardLinks) != 0; }
+
+ bool Flags_UseGlobalOffset() const { return (Flags & NArcInfoFlags::kUseGlobalOffset) != 0; }
+ bool Flags_StartOpen() const { return (Flags & NArcInfoFlags::kStartOpen) != 0; }
+ bool Flags_BackwardOpen() const { return (Flags & NArcInfoFlags::kBackwardOpen) != 0; }
+ bool Flags_PreArc() const { return (Flags & NArcInfoFlags::kPreArc) != 0; }
+ bool Flags_PureStartOpen() const { return (Flags & NArcInfoFlags::kPureStartOpen) != 0; }
UString GetMainExt() const
{
@@ -80,26 +155,30 @@ struct CArcInfoEx
}
*/
- void AddExts(const wchar_t* ext, const wchar_t* addExt);
+ void AddExts(const UString &ext, const UString &addExt);
+
+ bool IsSplit() const { return StringsAreEqualNoCase_Ascii(Name, "Split"); }
+ // bool IsRar() const { return StringsAreEqualNoCase_Ascii(Name, "Rar"); }
CArcInfoEx():
- #ifdef EXTERNAL_CODECS
- LibIndex(-1),
- #endif
- UpdateEnabled(false),
- CreateInArchive(0), CreateOutArchive(0),
- KeepName(false)
- #ifndef _SFX
- #endif
+ Flags(0),
+ CreateInArchive(NULL),
+ IsArcFunc(NULL)
+ #ifndef _SFX
+ , CreateOutArchive(NULL)
+ , UpdateEnabled(false)
+ , NewInterface(false)
+ // , Version(0)
+ , SignatureOffset(0)
+ #endif
+ #ifdef EXTERNAL_CODECS
+ , LibIndex(-1)
+ #endif
{}
};
-#ifdef EXTERNAL_CODECS
-typedef UInt32 (WINAPI *GetMethodPropertyFunc)(UInt32 index, PROPID propID, PROPVARIANT *value);
-typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *interfaceID, void **outObject);
-
-
#ifdef NEW_FOLDER_INTERFACE
+
struct CCodecIcons
{
struct CIconPair
@@ -108,57 +187,128 @@ struct CCodecIcons
int IconIndex;
};
CObjectVector<CIconPair> IconPairs;
+
void LoadIcons(HMODULE m);
bool FindIconIndex(const UString &ext, int &iconIndex) const;
};
+
#endif
+#ifdef EXTERNAL_CODECS
+
struct CCodecLib
-#ifdef NEW_FOLDER_INTERFACE
-: public CCodecIcons
-#endif
+ #ifdef NEW_FOLDER_INTERFACE
+ : public CCodecIcons
+ #endif
{
NWindows::NDLL::CLibrary Lib;
- GetMethodPropertyFunc GetMethodProperty;
- CreateObjectFunc CreateObject;
- #ifdef NEW_FOLDER_INTERFACE
FString Path;
+
+ Func_CreateObject CreateObject;
+ Func_GetMethodProperty GetMethodProperty;
+ Func_CreateDecoder CreateDecoder;
+ Func_CreateEncoder CreateEncoder;
+ Func_SetCodecs SetCodecs;
+
+ CMyComPtr<IHashers> ComHashers;
+
+ #ifdef NEW_FOLDER_INTERFACE
void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); }
#endif
- CCodecLib(): GetMethodProperty(0) {}
+
+ CCodecLib():
+ CreateObject(NULL),
+ GetMethodProperty(NULL),
+ CreateDecoder(NULL),
+ CreateEncoder(NULL),
+ SetCodecs(NULL)
+ {}
};
+
#endif
+
class CCodecs:
#ifdef EXTERNAL_CODECS
- public ICompressCodecsInfo,
+ public ICompressCodecsInfo,
+ public IHashers,
#else
- public IUnknown,
+ public IUnknown,
#endif
public CMyUnknownImp
{
+ CLASS_NO_COPY(CCodecs);
public:
#ifdef EXTERNAL_CODECS
+
CObjectVector<CCodecLib> Libs;
- CObjectVector<CDllCodecInfo> Codecs;
+ FString MainDll_ErrorPath;
- #ifdef NEW_FOLDER_INTERFACE
- CCodecIcons InternalIcons;
- #endif
+ void CloseLibs();
+
+ class CReleaser
+ {
+ CLASS_NO_COPY(CReleaser);
+
+ /* CCodecsReleaser object releases CCodecs links.
+ 1) CCodecs is COM object that is deleted when all links to that object will be released/
+ 2) CCodecs::Libs[i] can hold (ICompressCodecsInfo *) link to CCodecs object itself.
+ To break that reference loop, we must close all CCodecs::Libs in CCodecsReleaser desttructor. */
+
+ CCodecs *_codecs;
+
+ public:
+ CReleaser(): _codecs(NULL) {}
+ void Set(CCodecs *codecs) { _codecs = codecs; }
+ ~CReleaser() { if (_codecs) _codecs->CloseLibs(); }
+ };
+
+ bool NeedSetLibCodecs; // = false, if we don't need to set codecs for archive handler via ISetCompressCodecsInfo
HRESULT LoadCodecs();
HRESULT LoadFormats();
- HRESULT LoadDll(const FString &path, bool needCheckDll);
+ HRESULT LoadDll(const FString &path, bool needCheckDll, bool *loadedOK = NULL);
HRESULT LoadDllsFromFolder(const FString &folderPrefix);
- HRESULT CreateArchiveHandler(const CArcInfoEx &ai, void **archive, bool outHandler) const
+ HRESULT CreateArchiveHandler(const CArcInfoEx &ai, bool outHandler, void **archive) const
{
return Libs[ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive);
}
+
+ #endif
+
+ #ifdef NEW_FOLDER_INTERFACE
+ CCodecIcons InternalIcons;
#endif
-public:
CObjectVector<CArcInfoEx> Formats;
+
+ #ifdef EXTERNAL_CODECS
+ CRecordVector<CDllCodecInfo> Codecs;
+ CRecordVector<CDllHasherInfo> Hashers;
+ #endif
+
+ bool CaseSensitiveChange;
+ bool CaseSensitive;
+
+ CCodecs():
+ #ifdef EXTERNAL_CODECS
+ NeedSetLibCodecs(true),
+ #endif
+ CaseSensitiveChange(false),
+ CaseSensitive(false)
+ {}
+
+ ~CCodecs()
+ {
+ // OutputDebugStringA("~CCodecs");
+ }
+
+ const wchar_t *GetFormatNamePtr(int formatIndex) const
+ {
+ return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[formatIndex].Name;
+ }
+
HRESULT Load();
#ifndef _SFX
@@ -168,65 +318,107 @@ public:
bool FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const;
#endif
+ #ifdef EXTERNAL_CODECS
+
+ MY_UNKNOWN_IMP2(ICompressCodecsInfo, IHashers)
+
+ STDMETHOD(GetNumMethods)(UInt32 *numMethods);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder);
+ STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder);
+
+ STDMETHOD_(UInt32, GetNumHashers)();
+ STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher);
+
+ #else
+
MY_UNKNOWN_IMP
+ #endif // EXTERNAL_CODECS
+
+
#ifdef EXTERNAL_CODECS
- STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods);
- STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
- STDMETHOD(CreateDecoder)(UInt32 index, const GUID *interfaceID, void **coder);
- STDMETHOD(CreateEncoder)(UInt32 index, const GUID *interfaceID, void **coder);
- #endif
- int GetCodecLibIndex(UInt32 index);
- bool GetCodecEncoderIsAssigned(UInt32 index);
- HRESULT GetCodecId(UInt32 index, UInt64 &id);
- UString GetCodecName(UInt32 index);
+ int GetCodec_LibIndex(UInt32 index) const;
+ bool GetCodec_DecoderIsAssigned(UInt32 index) const;
+ bool GetCodec_EncoderIsAssigned(UInt32 index) const;
+ UInt32 GetCodec_NumStreams(UInt32 index);
+ HRESULT GetCodec_Id(UInt32 index, UInt64 &id);
+ AString GetCodec_Name(UInt32 index);
+
+ int GetHasherLibIndex(UInt32 index);
+ UInt64 GetHasherId(UInt32 index);
+ AString GetHasherName(UInt32 index);
+ UInt32 GetHasherDigestSize(UInt32 index);
+
+ #endif
- HRESULT CreateInArchive(int formatIndex, CMyComPtr<IInArchive> &archive) const
+ HRESULT CreateInArchive(unsigned formatIndex, CMyComPtr<IInArchive> &archive) const
{
const CArcInfoEx &ai = Formats[formatIndex];
#ifdef EXTERNAL_CODECS
if (ai.LibIndex < 0)
#endif
{
+ COM_TRY_BEGIN
archive = ai.CreateInArchive();
return S_OK;
+ COM_TRY_END
}
#ifdef EXTERNAL_CODECS
- return CreateArchiveHandler(ai, (void **)&archive, false);
+ return CreateArchiveHandler(ai, false, (void **)&archive);
#endif
}
- HRESULT CreateOutArchive(int formatIndex, CMyComPtr<IOutArchive> &archive) const
+
+ #ifndef _SFX
+
+ HRESULT CreateOutArchive(unsigned formatIndex, CMyComPtr<IOutArchive> &archive) const
{
const CArcInfoEx &ai = Formats[formatIndex];
#ifdef EXTERNAL_CODECS
if (ai.LibIndex < 0)
#endif
{
+ COM_TRY_BEGIN
archive = ai.CreateOutArchive();
return S_OK;
+ COM_TRY_END
}
+
#ifdef EXTERNAL_CODECS
- return CreateArchiveHandler(ai, (void **)&archive, true);
+ return CreateArchiveHandler(ai, true, (void **)&archive);
#endif
}
+
int FindOutFormatFromName(const UString &name) const
{
- for (int i = 0; i < Formats.Size(); i++)
+ FOR_VECTOR (i, Formats)
{
const CArcInfoEx &arc = Formats[i];
if (!arc.UpdateEnabled)
continue;
- if (arc.Name.CompareNoCase(name) == 0)
+ if (arc.Name.IsEqualTo_NoCase(name))
return i;
}
return -1;
}
- #ifdef EXTERNAL_CODECS
- HRESULT CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const;
- #endif
-
+ #endif // _SFX
};
+#ifdef EXTERNAL_CODECS
+ #define CREATE_CODECS_OBJECT \
+ CCodecs *codecs = new CCodecs; \
+ CExternalCodecs __externalCodecs; \
+ __externalCodecs.GetCodecs = codecs; \
+ __externalCodecs.GetHashers = codecs; \
+ CCodecs::CReleaser codecsReleaser; \
+ codecsReleaser.Set(codecs);
+#else
+ #define CREATE_CODECS_OBJECT \
+ CCodecs *codecs = new CCodecs; \
+ CMyComPtr<IUnknown> __codecsRef = codecs;
+#endif
+
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp
index 60d2f6f5ad1..e323abd2197 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -2,27 +2,454 @@
#include "StdAfx.h"
-#include "Common/Wildcard.h"
+// #define SHOW_DEBUG_INFO
-#include "Windows/FileDir.h"
-#include "Windows/PropVariant.h"
+#ifdef SHOW_DEBUG_INFO
+#include <stdio.h>
+#endif
+
+#include "../../../../C/CpuArch.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/StringToInt.h"
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/FileDir.h"
#include "../../Common/FileStreams.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/ProgressUtils.h"
#include "../../Common/StreamUtils.h"
+#include "../../Compress/CopyCoder.h"
+
#include "DefaultName.h"
#include "OpenArchive.h"
+#ifndef _SFX
+#include "SetProperties.h"
+#endif
+
+#ifdef SHOW_DEBUG_INFO
+#define PRF(x) x
+#else
+#define PRF(x)
+#endif
+
+// increase it, if you need to support larger SFX stubs
+static const UInt64 kMaxCheckStartPosition = 1 << 23;
+
+/*
+Open:
+ - formatIndex >= 0 (exact Format)
+ 1) Open with main type. Archive handler is allowed to use archive start finder.
+ Warning, if there is tail.
+
+ - formatIndex = -1 (Parser:0) (default)
+ - same as #1 but doesn't return Parser
+
+ - formatIndex = -2 (#1)
+ - file has supported extension (like a.7z)
+ Open with that main type (only starting from start of file).
+ - open OK:
+ - if there is no tail - return OK
+ - if there is tail:
+ - archive is not "Self Exe" - return OK with Warning, that there is tail
+ - archive is "Self Exe"
+ ignore "Self Exe" stub, and tries to open tail
+ - tail can be open as archive - shows that archive and stub size property.
+ - tail can't be open as archive - shows Parser ???
+ - open FAIL:
+ Try to open with all other types from offset 0 only.
+ If some open type is OK and physical archive size is uequal or larger
+ than file size, then return that archive with warning that can not be open as [extension type].
+ If extension was EXE, it will try to open as unknown_extension case
+ - file has unknown extension (like a.hhh)
+ It tries to open via parser code.
+ - if there is full archive or tail archive and unknown block or "Self Exe"
+ at front, it shows tail archive and stub size property.
+ - in another cases, if there is some archive inside file, it returns parser/
+ - in another cases, it retuens S_FALSE
+
+
+ - formatIndex = -3 (#2)
+ - same as #1, but
+ - stub (EXE) + archive is open in Parser
+
+ - formatIndex = -4 (#3)
+ - returns only Parser. skip full file archive. And show other sub-archives
+
+ - formatIndex = -5 (#4)
+ - returns only Parser. skip full file archive. And show other sub-archives for each byte pos
+
+*/
+
+
+
+
using namespace NWindows;
-// Static-SFX (for Linux) can be big.
-const UInt64 kMaxCheckStartPosition = 1 << 22;
+/*
+#ifdef _SFX
+#define OPEN_PROPS_PARAM
+#else
+#define OPEN_PROPS_PARAM , props
+#endif
+*/
+
+/*
+CArc::~CArc()
+{
+ GetRawProps.Release();
+ Archive.Release();
+ printf("\nCArc::~CArc()\n");
+}
+*/
+
+#ifndef _SFX
+
+namespace NArchive {
+namespace NParser {
+
+struct CParseItem
+{
+ UInt64 Offset;
+ UInt64 Size;
+ // UInt64 OkSize;
+ UString Name;
+ UString Extension;
+ FILETIME FileTime;
+ UString Comment;
+ UString ArcType;
+
+ bool FileTime_Defined;
+ bool UnpackSize_Defined;
+ bool NumSubDirs_Defined;
+ bool NumSubFiles_Defined;
+
+ bool IsSelfExe;
+ bool IsNotArcType;
+
+ UInt64 UnpackSize;
+ UInt64 NumSubDirs;
+ UInt64 NumSubFiles;
+
+ int FormatIndex;
+
+ bool LenIsUnknown;
+
+ CParseItem():
+ LenIsUnknown(false),
+ FileTime_Defined(false),
+ UnpackSize_Defined(false),
+ NumSubFiles_Defined(false),
+ NumSubDirs_Defined(false),
+ IsSelfExe(false),
+ IsNotArcType(false)
+ // OkSize(0)
+ {}
+
+ /*
+ bool IsEqualTo(const CParseItem &item) const
+ {
+ return Offset == item.Offset && Size == item.Size;
+ }
+ */
+
+ void NormalizeOffset()
+ {
+ if ((Int64)Offset < 0)
+ {
+ Size += Offset;
+ // OkSize += Offset;
+ Offset = 0;
+ }
+ }
+};
+
+class CHandler:
+ public IInArchive,
+ public IInArchiveGetStream,
+ public CMyUnknownImp
+{
+public:
+ CObjectVector<CParseItem> _items;
+ UInt64 _maxEndOffset;
+ CMyComPtr<IInStream> _stream;
+
+ MY_UNKNOWN_IMP2(
+ IInArchive,
+ IInArchiveGetStream)
+
+ INTERFACE_IInArchive(;)
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+
+ UInt64 GetLastEnd() const
+ {
+ if (_items.IsEmpty())
+ return 0;
+ const CParseItem &back = _items.Back();
+ return back.Offset + back.Size;
+ }
+
+ void AddUnknownItem(UInt64 next);
+ int FindInsertPos(const CParseItem &item) const;
+ void AddItem(const CParseItem &item);
+
+ CHandler(): _maxEndOffset(0) {}
+};
+
+int CHandler::FindInsertPos(const CParseItem &item) const
+{
+ unsigned left = 0, right = _items.Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const CParseItem & midItem = _items[mid];
+ if (item.Offset < midItem.Offset)
+ right = mid;
+ else if (item.Offset > midItem.Offset)
+ left = mid + 1;
+ else if (item.Size < midItem.Size)
+ right = mid;
+ else if (item.Size > midItem.Size)
+ left = mid + 1;
+ else
+ {
+ left = mid + 1;
+ // return -1;
+ }
+ }
+ return left;
+}
+
+void CHandler::AddUnknownItem(UInt64 next)
+{
+ /*
+ UInt64 prevEnd = 0;
+ if (!_items.IsEmpty())
+ {
+ const CParseItem &back = _items.Back();
+ prevEnd = back.Offset + back.Size;
+ }
+ */
+ if (_maxEndOffset < next)
+ {
+ CParseItem item2;
+ item2.Offset = _maxEndOffset;
+ item2.Size = next - _maxEndOffset;
+ _maxEndOffset = next;
+ _items.Add(item2);
+ }
+ else if (_maxEndOffset > next && !_items.IsEmpty())
+ {
+ CParseItem &back = _items.Back();
+ if (back.LenIsUnknown)
+ {
+ back.Size = next - back.Offset;
+ _maxEndOffset = next;
+ }
+ }
+}
+
+void CHandler::AddItem(const CParseItem &item)
+{
+ AddUnknownItem(item.Offset);
+ int pos = FindInsertPos(item);
+ if (pos >= 0)
+ {
+ _items.Insert(pos, item);
+ UInt64 next = item.Offset + item.Size;
+ if (_maxEndOffset < next)
+ _maxEndOffset = next;
+ }
+}
+
+/*
+static const CStatProp kProps[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidMTime, VT_FILETIME},
+ { NULL, kpidType, VT_BSTR},
+ { NULL, kpidComment, VT_BSTR},
+ { NULL, kpidOffset, VT_UI8},
+ { NULL, kpidUnpackSize, VT_UI8},
+// { NULL, kpidNumSubDirs, VT_UI8},
+};
+*/
+
+static const Byte kProps[] =
+{
+ kpidPath,
+ kpidSize,
+ kpidMTime,
+ kpidType,
+ kpidComment,
+ kpidOffset,
+ kpidUnpackSize
+};
+
+IMP_IInArchive_Props
+IMP_IInArchive_ArcProps_NO
+
+STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* openArchiveCallback */)
+{
+ COM_TRY_BEGIN
+ {
+ Close();
+ _stream = stream;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _items.Clear();
+ _stream.Release();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _items.Size();
+ return S_OK;
+}
-HRESULT GetArchiveItemBoolProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NCOM::CPropVariant prop;
+
+ const CParseItem &item = _items[index];
+
+ switch (propID)
+ {
+ case kpidPath:
+ {
+ wchar_t sz[32];
+ ConvertUInt32ToString(index + 1, sz);
+ UString s = sz;
+ if (!item.Name.IsEmpty())
+ {
+ s += L'.';
+ s += item.Name;
+ }
+ if (!item.Extension.IsEmpty())
+ {
+ s += L'.';
+ s += item.Extension;
+ }
+ prop = s; break;
+ }
+ case kpidSize:
+ case kpidPackSize: prop = item.Size; break;
+ case kpidOffset: prop = item.Offset; break;
+ case kpidUnpackSize: if (item.UnpackSize_Defined) prop = item.UnpackSize; break;
+ case kpidNumSubFiles: if (item.NumSubFiles_Defined) prop = item.NumSubFiles; break;
+ case kpidNumSubDirs: if (item.NumSubDirs_Defined) prop = item.NumSubDirs; break;
+ case kpidMTime: if (item.FileTime_Defined) prop = item.FileTime; break;
+ case kpidComment: if (!item.Comment.IsEmpty()) prop = item.Comment; break;
+ case kpidType: if (!item.ArcType.IsEmpty()) prop = item.ArcType; break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+
+ bool allFilesMode = (numItems == (UInt32)(Int32)-1);
+ if (allFilesMode)
+ numItems = _items.Size();
+ if (_stream && numItems == 0)
+ return S_OK;
+ UInt64 totalSize = 0;
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ totalSize += _items[allFilesMode ? i : indices[i]].Size;
+ extractCallback->SetTotal(totalSize);
+
+ totalSize = 0;
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+ streamSpec->SetStream(_stream);
+
+ CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+
+ for (i = 0; i < numItems; i++)
+ {
+ lps->InSize = totalSize;
+ lps->OutSize = totalSize;
+ RINOK(lps->SetCur());
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode = testMode ?
+ NExtract::NAskMode::kTest :
+ NExtract::NAskMode::kExtract;
+ Int32 index = allFilesMode ? i : indices[i];
+ const CParseItem &item = _items[index];
+
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+ UInt64 unpackSize = item.Size;
+ totalSize += unpackSize;
+ bool skipMode = false;
+ if (!testMode && !realOutStream)
+ continue;
+ RINOK(extractCallback->PrepareOperation(askMode));
+
+ outStreamSpec->SetStream(realOutStream);
+ realOutStream.Release();
+ outStreamSpec->Init(skipMode ? 0 : unpackSize, true);
+
+ Int32 opRes = NExtract::NOperationResult::kOK;
+ RINOK(_stream->Seek(item.Offset, STREAM_SEEK_SET, NULL));
+ streamSpec->Init(unpackSize);
+ RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
+
+ if (outStreamSpec->GetRem() != 0)
+ opRes = NExtract::NOperationResult::kDataError;
+ outStreamSpec->ReleaseStream();
+ RINOK(extractCallback->SetOperationResult(opRes));
+ }
+
+ return S_OK;
+
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ COM_TRY_BEGIN
+ const CParseItem &item = _items[index];
+ return CreateLimitedInStream(_stream, item.Offset, item.Size, stream);
+ COM_TRY_END
+}
+
+}}
+
+#endif
+
+HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw()
{
NCOM::CPropVariant prop;
result = false;
- RINOK(archive->GetProperty(index, propID, &prop));
+ RINOK(arc->GetProperty(index, propID, &prop));
if (prop.vt == VT_BOOL)
result = VARIANT_BOOLToBool(prop.boolVal);
else if (prop.vt != VT_EMPTY)
@@ -30,24 +457,276 @@ HRESULT GetArchiveItemBoolProp(IInArchive *archive, UInt32 index, PROPID propID,
return S_OK;
}
-HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
+HRESULT Archive_IsItem_Dir(IInArchive *arc, UInt32 index, bool &result) throw()
{
- return GetArchiveItemBoolProp(archive, index, kpidIsDir, result);
+ return Archive_GetItemBoolProp(arc, index, kpidIsDir, result);
}
+HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw()
+{
+ return Archive_GetItemBoolProp(arc, index, kpidIsAux, result);
+}
+
+HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw()
+{
+ return Archive_GetItemBoolProp(arc, index, kpidIsAltStream, result);
+}
+
+HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &result) throw()
+{
+ return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result);
+}
+
+static HRESULT Archive_GetArcBoolProp(IInArchive *arc, PROPID propid, bool &result) throw()
+{
+ NCOM::CPropVariant prop;
+ result = false;
+ RINOK(arc->GetArchiveProperty(propid, &prop));
+ if (prop.vt == VT_BOOL)
+ result = VARIANT_BOOLToBool(prop.boolVal);
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
+}
+
+static HRESULT Archive_GetArcProp_UInt(IInArchive *arc, PROPID propid, UInt64 &result, bool &defined)
+{
+ defined = false;
+ NCOM::CPropVariant prop;
+ RINOK(arc->GetArchiveProperty(propid, &prop));
+ switch (prop.vt)
+ {
+ case VT_UI4: result = prop.ulVal; defined = true; break;
+ case VT_I4: result = prop.lVal; defined = true; break;
+ case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; defined = true; break;
+ case VT_I8: result = (UInt64)prop.hVal.QuadPart; defined = true; break;
+ case VT_EMPTY: break;
+ default: return E_FAIL;
+ }
+ return S_OK;
+}
+
+static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &result, bool &defined)
+{
+ defined = false;
+ NCOM::CPropVariant prop;
+ RINOK(arc->GetArchiveProperty(propid, &prop));
+ switch (prop.vt)
+ {
+ case VT_UI4: result = prop.ulVal; defined = true; break;
+ case VT_I4: result = prop.lVal; defined = true; break;
+ case VT_UI8: result = (Int64)prop.uhVal.QuadPart; defined = true; break;
+ case VT_I8: result = (Int64)prop.hVal.QuadPart; defined = true; break;
+ case VT_EMPTY: break;
+ default: return E_FAIL;
+ }
+ return S_OK;
+}
+
+#ifndef _SFX
+
+HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const
+{
+ if (!GetRawProps)
+ return E_FAIL;
+ if (index == parent)
+ return S_OK;
+ UInt32 curIndex = index;
+
+ UString s;
+
+ bool prevWasAltStream = false;
+
+ for (;;)
+ {
+ #ifdef MY_CPU_LE
+ const void *p;
+ UInt32 size;
+ UInt32 propType;
+ RINOK(GetRawProps->GetRawProp(curIndex, kpidName, &p, &size, &propType));
+ if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE)
+ s = (const wchar_t *)p;
+ else
+ #endif
+ {
+ NCOM::CPropVariant prop;
+ RINOK(Archive->GetProperty(curIndex, kpidName, &prop));
+ if (prop.vt == VT_BSTR && prop.bstrVal)
+ s.SetFromBstr(prop.bstrVal);
+ else if (prop.vt == VT_EMPTY)
+ s.Empty();
+ else
+ return E_FAIL;
+ }
+
+ UInt32 curParent = (UInt32)(Int32)-1;
+ UInt32 parentType = 0;
+ RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType));
+
+ if (parentType != NParentType::kAltStream)
+ {
+ for (;;)
+ {
+ int pos = s.ReverseFind_PathSepar();
+ if (pos < 0)
+ {
+ break;
+ }
+ parts.Insert(0, s.Ptr(pos + 1));
+ s.DeleteFrom(pos);
+ }
+ }
+
+ parts.Insert(0, s);
+
+ if (prevWasAltStream)
+ {
+ {
+ UString &s = parts[parts.Size() - 2];
+ s += L':';
+ s += parts.Back();
+ }
+ parts.DeleteBack();
+ }
+
+ if (parent == curParent)
+ return S_OK;
+
+ prevWasAltStream = false;
+ if (parentType == NParentType::kAltStream)
+ prevWasAltStream = true;
+
+ if (curParent == (UInt32)(Int32)-1)
+ return E_FAIL;
+ curIndex = curParent;
+ }
+}
+
+#endif
+
HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
{
+ #ifdef MY_CPU_LE
+ if (GetRawProps)
+ {
+ const void *p;
+ UInt32 size;
+ UInt32 propType;
+ if (!IsTree)
+ {
+ if (GetRawProps->GetRawProp(index, kpidPath, &p, &size, &propType) == S_OK &&
+ propType == NPropDataType::kUtf16z)
+ {
+ unsigned len = size / 2 - 1;
+ wchar_t *s = result.GetBuf(len);
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = GetUi16(p);
+ p = (const void *)((const Byte *)p + 2);
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ if (c == L'/')
+ c = WCHAR_PATH_SEPARATOR;
+ #endif
+ *s++ = c;
+ }
+ *s = 0;
+ result.ReleaseBuf_SetLen(len);
+ if (len != 0)
+ return S_OK;
+ }
+ }
+ /*
+ else if (GetRawProps->GetRawProp(index, kpidName, &p, &size, &propType) == S_OK &&
+ p && propType == NPropDataType::kUtf16z)
+ {
+ size -= 2;
+ UInt32 totalSize = size;
+ bool isOK = false;
+
+ {
+ UInt32 index2 = index;
+ for (;;)
+ {
+ UInt32 parent = (UInt32)(Int32)-1;
+ UInt32 parentType = 0;
+ if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK)
+ break;
+ if (parent == (UInt32)(Int32)-1)
+ {
+ if (parentType != 0)
+ totalSize += 2;
+ isOK = true;
+ break;
+ }
+ index2 = parent;
+ UInt32 size2;
+ const void *p2;
+ if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK &&
+ p2 && propType == NPropDataType::kUtf16z)
+ break;
+ totalSize += size2;
+ }
+ }
+
+ if (isOK)
+ {
+ wchar_t *sz = result.GetBuf_SetEnd(totalSize / 2);
+ UInt32 pos = totalSize - size;
+ memcpy((Byte *)sz + pos, p, size);
+ UInt32 index2 = index;
+ for (;;)
+ {
+ UInt32 parent = (UInt32)(Int32)-1;
+ UInt32 parentType = 0;
+ if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK)
+ break;
+ if (parent == (UInt32)(Int32)-1)
+ {
+ if (parentType != 0)
+ sz[pos / 2 - 1] = L':';
+ break;
+ }
+ index2 = parent;
+ UInt32 size2;
+ const void *p2;
+ if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK)
+ break;
+ pos -= size2;
+ memcpy((Byte *)sz + pos, p2, size2);
+ sz[(pos + size2 - 2) / 2] = (parentType == 0) ? WCHAR_PATH_SEPARATOR : L':';
+ }
+ #ifdef _WIN32
+ // result.Replace(L'/', WCHAR_PATH_SEPARATOR);
+ #endif
+ return S_OK;
+ }
+ }
+ */
+ }
+ #endif
+
{
NCOM::CPropVariant prop;
RINOK(Archive->GetProperty(index, kpidPath, &prop));
- if (prop.vt == VT_BSTR)
- result = prop.bstrVal;
+ if (prop.vt == VT_BSTR && prop.bstrVal)
+ result.SetFromBstr(prop.bstrVal);
else if (prop.vt == VT_EMPTY)
result.Empty();
else
return E_FAIL;
}
+
if (result.IsEmpty())
+ return GetDefaultItemPath(index, result);
+ return S_OK;
+}
+
+HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const
+{
+ result.Empty();
+ bool isDir;
+ RINOK(Archive_IsItem_Dir(Archive, index, isDir));
+ if (!isDir)
{
result = DefaultName;
NCOM::CPropVariant prop;
@@ -63,6 +742,197 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
return S_OK;
}
+HRESULT CArc::GetItemPath2(UInt32 index, UString &result) const
+{
+ RINOK(GetItemPath(index, result));
+ if (Ask_Deleted)
+ {
+ bool isDeleted = false;
+ RINOK(Archive_IsItem_Deleted(Archive, index, isDeleted));
+ if (isDeleted)
+ result.Insert(0, L"[DELETED]" WSTRING_PATH_SEPARATOR);
+ }
+ return S_OK;
+}
+
+#ifdef SUPPORT_ALT_STREAMS
+
+int FindAltStreamColon_in_Path(const wchar_t *path)
+{
+ unsigned i = 0;
+ int colonPos = -1;
+ for (;; i++)
+ {
+ wchar_t c = path[i];
+ if (c == 0)
+ return colonPos;
+ if (c == ':')
+ {
+ if (colonPos < 0)
+ colonPos = i;
+ continue;
+ }
+ if (c == WCHAR_PATH_SEPARATOR)
+ colonPos = -1;
+ }
+}
+
+#endif
+
+HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
+{
+ #ifdef SUPPORT_ALT_STREAMS
+ item.IsAltStream = false;
+ item.AltStreamName.Empty();
+ item.MainPath.Empty();
+ #endif
+
+ item.IsDir = false;
+ item.Path.Empty();
+ item.ParentIndex = (UInt32)(Int32)-1;
+
+ item.PathParts.Clear();
+
+ RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir));
+ item.MainIsDir = item.IsDir;
+
+ RINOK(GetItemPath2(index, item.Path));
+
+ #ifndef _SFX
+ UInt32 mainIndex = index;
+ #endif
+
+ #ifdef SUPPORT_ALT_STREAMS
+
+ item.MainPath = item.Path;
+ if (Ask_AltStream)
+ {
+ RINOK(Archive_IsItem_AltStream(Archive, index, item.IsAltStream));
+ }
+
+ bool needFindAltStream = false;
+
+ if (item.IsAltStream)
+ {
+ needFindAltStream = true;
+ if (GetRawProps)
+ {
+ UInt32 parentType = 0;
+ UInt32 parentIndex;
+ RINOK(GetRawProps->GetParent(index, &parentIndex, &parentType));
+ if (parentType == NParentType::kAltStream)
+ {
+ NCOM::CPropVariant prop;
+ RINOK(Archive->GetProperty(index, kpidName, &prop));
+ if (prop.vt == VT_BSTR && prop.bstrVal)
+ item.AltStreamName.SetFromBstr(prop.bstrVal);
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ else
+ {
+ // item.IsAltStream = false;
+ }
+ /*
+ if (item.AltStreamName.IsEmpty())
+ item.IsAltStream = false;
+ */
+
+ needFindAltStream = false;
+ item.ParentIndex = parentIndex;
+ mainIndex = parentIndex;
+
+ if (parentIndex == (UInt32)(Int32)-1)
+ {
+ item.MainPath.Empty();
+ item.MainIsDir = true;
+ }
+ else
+ {
+ RINOK(GetItemPath2(parentIndex, item.MainPath));
+ RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir));
+ }
+ }
+ }
+ }
+
+ if (item.WriteToAltStreamIfColon || needFindAltStream)
+ {
+ /* 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)
+ {
+ item.MainPath.DeleteFrom(colon);
+ item.AltStreamName = item.Path.Ptr(colon + 1);
+ item.MainIsDir = (colon == 0 || IsPathSepar(item.Path[colon - 1]));
+ item.IsAltStream = true;
+ }
+ }
+
+ #endif
+
+ #ifndef _SFX
+ if (item._use_baseParentFolder_mode)
+ {
+ RINOK(GetItemPathToParent(mainIndex, item._baseParentFolder, item.PathParts));
+
+ #ifdef SUPPORT_ALT_STREAMS
+ if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty())
+ {
+ int colon;
+ {
+ UString &s = item.PathParts.Back();
+ colon = FindAltStreamColon_in_Path(s);
+ if (colon >= 0)
+ {
+ item.AltStreamName = s.Ptr(colon + 1);
+ item.MainIsDir = (colon == 0 || IsPathSepar(s[(unsigned)colon - 1]));
+ item.IsAltStream = true;
+ s.DeleteFrom(colon);
+ }
+ }
+ if (colon == 0)
+ item.PathParts.DeleteBack();
+ }
+ #endif
+
+ }
+ else
+ #endif
+ SplitPathToParts(
+ #ifdef SUPPORT_ALT_STREAMS
+ item.MainPath
+ #else
+ item.Path
+ #endif
+ , item.PathParts);
+
+ return S_OK;
+}
+
+#ifndef _SFX
+
+static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &size, bool &defined)
+{
+ NCOM::CPropVariant prop;
+ defined = false;
+ size = 0;
+ RINOK(archive->GetProperty(index, kpidSize, &prop));
+ switch (prop.vt)
+ {
+ case VT_UI1: size = prop.bVal; break;
+ case VT_UI2: size = prop.uiVal; break;
+ case VT_UI4: size = prop.ulVal; break;
+ case VT_UI8: size = (UInt64)prop.uhVal.QuadPart; break;
+ case VT_EMPTY: return S_OK;
+ default: return E_FAIL;
+ }
+ defined = true;
+ return S_OK;
+}
+
+#endif
+
HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const
{
NCOM::CPropVariant prop;
@@ -104,6 +974,7 @@ HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const
}
#ifndef _SFX
+
static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
{
for (size_t i = 0; i < size; i++)
@@ -111,296 +982,2097 @@ static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
return false;
return true;
}
+
+static void MakeCheckOrder(CCodecs *codecs,
+ CIntVector &orderIndices, unsigned numTypes, CIntVector &orderIndices2,
+ const Byte *data, size_t dataSize)
+{
+ for (unsigned i = 0; i < numTypes; i++)
+ {
+ int index = orderIndices[i];
+ if (index < 0)
+ continue;
+ const CArcInfoEx &ai = codecs->Formats[index];
+ if (ai.SignatureOffset != 0)
+ {
+ orderIndices2.Add(index);
+ orderIndices[i] = -1;
+ continue;
+ }
+
+ const CObjectVector<CByteBuffer> &sigs = ai.Signatures;
+ FOR_VECTOR (k, sigs)
+ {
+ const CByteBuffer &sig = sigs[k];
+ if (sig.Size() == 0 && dataSize == 0 ||
+ sig.Size() != 0 && sig.Size() <= dataSize &&
+ TestSignature(data, sig, sig.Size()))
+ {
+ orderIndices2.Add(index);
+ orderIndices[i] = -1;
+ break;
+ }
+ }
+ }
+}
+
#endif
#ifdef UNDER_CE
-static const int kNumHashBytes = 1;
-#define HASH_VAL(buf, pos) ((buf)[pos])
+ static const unsigned kNumHashBytes = 1;
+ #define HASH_VAL(buf, pos) ((buf)[pos])
#else
-static const int kNumHashBytes = 2;
-#define HASH_VAL(buf, pos) ((buf)[pos] | ((UInt32)(buf)[pos + 1] << 8))
+ static const unsigned kNumHashBytes = 2;
+ #define HASH_VAL(buf, pos) ((buf)[pos] | ((UInt32)(buf)[pos + 1] << 8))
#endif
-HRESULT CArc::OpenStream(
- CCodecs *codecs,
- int formatIndex,
- IInStream *stream,
- ISequentialInStream *seqStream,
- IArchiveOpenCallback *callback)
+#ifndef _SFX
+
+static bool IsExeExt(const UString &ext)
{
- Archive.Release();
+ return ext.IsEqualTo_Ascii_NoCase("exe");
+}
+
+static const char * const k_PreArcFormats[] =
+{
+ "pe"
+ , "elf"
+ , "macho"
+ , "mub"
+ , "te"
+};
+
+static bool IsNameFromList(const UString &s, const char * const names[], size_t num)
+{
+ for (unsigned i = 0; i < num; i++)
+ if (StringsAreEqualNoCase_Ascii(s, names[i]))
+ return true;
+ return false;
+}
+
+
+static bool IsPreArcFormat(const CArcInfoEx &ai)
+{
+ if (ai.Flags_PreArc())
+ return true;
+ return IsNameFromList(ai.Name, k_PreArcFormats, ARRAY_SIZE(k_PreArcFormats));
+}
+
+static const char * const k_Formats_with_simple_signuature[] =
+{
+ "7z"
+ , "xz"
+ , "rar"
+ , "bzip2"
+ , "gzip"
+ , "cab"
+ , "wim"
+ , "rpm"
+ , "vhd"
+ , "xar"
+};
+
+static bool IsNewStyleSignature(const CArcInfoEx &ai)
+{
+ // if (ai.Version >= 0x91F)
+ if (ai.NewInterface)
+ return true;
+ return IsNameFromList(ai.Name, k_Formats_with_simple_signuature, ARRAY_SIZE(k_Formats_with_simple_signuature));
+}
+
+class CArchiveOpenCallback_Offset:
+ public IArchiveOpenCallback,
+ public IArchiveOpenVolumeCallback,
+ #ifndef _NO_CRYPTO
+ public ICryptoGetTextPassword,
+ #endif
+ public CMyUnknownImp
+{
+public:
+ CMyComPtr<IArchiveOpenCallback> Callback;
+ CMyComPtr<IArchiveOpenVolumeCallback> OpenVolumeCallback;
+ UInt64 Files;
+ UInt64 Offset;
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoGetTextPassword> GetTextPassword;
+ #endif
+
+ MY_QUERYINTERFACE_BEGIN2(IArchiveOpenCallback)
+ MY_QUERYINTERFACE_ENTRY(IArchiveOpenVolumeCallback)
+ #ifndef _NO_CRYPTO
+ MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword)
+ #endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+ INTERFACE_IArchiveOpenCallback(;)
+ INTERFACE_IArchiveOpenVolumeCallback(;)
+ #ifndef _NO_CRYPTO
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+ #endif
+};
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password)
+{
+ COM_TRY_BEGIN
+ if (GetTextPassword)
+ return GetTextPassword->CryptoGetTextPassword(password);
+ return E_NOTIMPL;
+ COM_TRY_END
+}
+#endif
+
+STDMETHODIMP CArchiveOpenCallback_Offset::SetTotal(const UInt64 *, const UInt64 *)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 *, const UInt64 *bytes)
+{
+ if (!Callback)
+ return S_OK;
+ UInt64 value = Offset;
+ if (bytes)
+ value += *bytes;
+ return Callback->SetCompleted(&Files, &value);
+}
+
+STDMETHODIMP CArchiveOpenCallback_Offset::GetProperty(PROPID propID, PROPVARIANT *value)
+{
+ if (OpenVolumeCallback)
+ return OpenVolumeCallback->GetProperty(propID, value);
+ NCOM::PropVariant_Clear(value);
+ return S_OK;
+ // return E_NOTIMPL;
+}
+
+STDMETHODIMP CArchiveOpenCallback_Offset::GetStream(const wchar_t *name, IInStream **inStream)
+{
+ if (OpenVolumeCallback)
+ return OpenVolumeCallback->GetStream(name, inStream);
+ return S_FALSE;
+}
+
+#endif
+
+
+UInt32 GetOpenArcErrorFlags(const NCOM::CPropVariant &prop, bool *isDefinedProp)
+{
+ if (isDefinedProp != NULL)
+ *isDefinedProp = false;
+
+ switch (prop.vt)
+ {
+ case VT_UI8: if (isDefinedProp) *isDefinedProp = true; return (UInt32)prop.uhVal.QuadPart;
+ case VT_UI4: if (isDefinedProp) *isDefinedProp = true; return prop.ulVal;
+ case VT_EMPTY: return 0;
+ default: throw 151199;
+ }
+}
+
+void CArcErrorInfo::ClearErrors()
+{
+ // ErrorFormatIndex = -1; // we don't need to clear ErrorFormatIndex here !!!
+
+ ThereIsTail = false;
+ UnexpecedEnd = false;
+ IgnoreTail = false;
+ // NonZerosTail = false;
+ ErrorFlags_Defined = false;
+ ErrorFlags = 0;
+ WarningFlags = 0;
+ TailSize = 0;
+
ErrorMessage.Empty();
+ WarningMessage.Empty();
+}
+
+HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes)
+{
+ // OkPhySize_Defined = false;
+ PhySizeDefined = false;
+ PhySize = 0;
+ Offset = 0;
+ AvailPhySize = FileSize - startPos;
+
+ ErrorInfo.ClearErrors();
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidErrorFlags, &prop));
+ ErrorInfo.ErrorFlags = GetOpenArcErrorFlags(prop, &ErrorInfo.ErrorFlags_Defined);
+ }
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidWarningFlags, &prop));
+ ErrorInfo.WarningFlags = GetOpenArcErrorFlags(prop);
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidError, &prop));
+ if (prop.vt != VT_EMPTY)
+ ErrorInfo.ErrorMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown error");
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidWarning, &prop));
+ if (prop.vt != VT_EMPTY)
+ ErrorInfo.WarningMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown warning");
+ }
+
+ if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen())
+ {
+ RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySizeDefined));
+ /*
+ RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined));
+ if (!OkPhySize_Defined)
+ {
+ OkPhySize_Defined = PhySizeDefined;
+ OkPhySize = PhySize;
+ }
+ */
+
+ bool offsetDefined;
+ RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined));
+
+ Int64 globalOffset = startPos + Offset;
+ AvailPhySize = FileSize - globalOffset;
+ if (PhySizeDefined)
+ {
+ UInt64 endPos = globalOffset + PhySize;
+ if (endPos < FileSize)
+ {
+ AvailPhySize = PhySize;
+ ErrorInfo.ThereIsTail = true;
+ ErrorInfo.TailSize = FileSize - endPos;
+ }
+ else if (endPos > FileSize)
+ ErrorInfo.UnexpecedEnd = true;
+ }
+ }
+
+ return S_OK;
+}
+
+/*
+static PrintNumber(const char *s, int n)
+{
+ char temp[100];
+ sprintf(temp, "%s %d", s, n);
+ OutputDebugStringA(temp);
+}
+*/
+
+HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive)
+{
+ // OutputDebugStringA("a1");
+ // PrintNumber("formatIndex", formatIndex);
+
+ RINOK(op.codecs->CreateInArchive(formatIndex, archive));
+ // OutputDebugStringA("a2");
+ if (!archive)
+ return S_OK;
+
+ #ifdef EXTERNAL_CODECS
+ if (op.codecs->NeedSetLibCodecs)
+ {
+ const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
+ if (ai.LibIndex >= 0 ?
+ !op.codecs->Libs[ai.LibIndex].SetCodecs :
+ !op.codecs->Libs.IsEmpty())
+ {
+ CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
+ archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
+ if (setCompressCodecsInfo)
+ {
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(op.codecs));
+ }
+ }
+ }
+ #endif
+
+
+ #ifndef _SFX
+
+ const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
+
+ // OutputDebugStringW(ai.Name);
+ // OutputDebugStringA("a3");
+
+ if (ai.Flags_PreArc())
+ {
+ /* we notify parsers that extract executables, that they don't need
+ to open archive, if there is tail after executable (for SFX cases) */
+ CMyComPtr<IArchiveAllowTail> allowTail;
+ archive.QueryInterface(IID_IArchiveAllowTail, (void **)&allowTail);
+ if (allowTail)
+ allowTail->AllowTail(BoolToInt(true));
+ }
+
+ if (op.props)
+ {
+ /*
+ FOR_VECTOR (y, op.props)
+ {
+ const COptionalOpenProperties &optProps = (*op.props)[y];
+ if (optProps.FormatName.IsEmpty() || optProps.FormatName.CompareNoCase(ai.Name) == 0)
+ {
+ RINOK(SetProperties(archive, optProps.Props));
+ break;
+ }
+ }
+ */
+ RINOK(SetProperties(archive, *op.props));
+ }
+
+ #endif
+ return S_OK;
+}
+
+#ifndef _SFX
+
+static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NArchive::NParser::CParseItem &pi)
+{
+ pi.Extension = ai.GetMainExt();
+ pi.FileTime_Defined = false;
+ pi.ArcType = ai.Name;
+
+ RINOK(Archive_GetArcBoolProp(archive, kpidIsNotArcType, pi.IsNotArcType));
+
+ // RINOK(Archive_GetArcBoolProp(archive, kpidIsSelfExe, pi.IsSelfExe));
+ pi.IsSelfExe = ai.Flags_PreArc();
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidMTime, &prop));
+ if (prop.vt == VT_FILETIME)
+ {
+ pi.FileTime_Defined = true;
+ pi.FileTime = prop.filetime;
+ }
+ }
+
+ if (!pi.FileTime_Defined)
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidCTime, &prop));
+ if (prop.vt == VT_FILETIME)
+ {
+ pi.FileTime_Defined = true;
+ pi.FileTime = prop.filetime;
+ }
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidName, &prop));
+ if (prop.vt == VT_BSTR)
+ {
+ pi.Name.SetFromBstr(prop.bstrVal);
+ pi.Extension.Empty();
+ }
+ else
+ {
+ RINOK(archive->GetArchiveProperty(kpidExtension, &prop));
+ if (prop.vt == VT_BSTR)
+ pi.Extension.SetFromBstr(prop.bstrVal);
+ }
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidShortComment, &prop));
+ if (prop.vt == VT_BSTR)
+ pi.Comment.SetFromBstr(prop.bstrVal);
+ }
+
+
+ UInt32 numItems;
+ RINOK(archive->GetNumberOfItems(&numItems));
+
+ // pi.NumSubFiles = numItems;
+ // RINOK(Archive_GetArcProp_UInt(archive, kpidUnpackSize, pi.UnpackSize, pi.UnpackSize_Defined));
+ // if (!pi.UnpackSize_Defined)
+ {
+ pi.NumSubFiles = 0;
+ pi.NumSubDirs = 0;
+ pi.UnpackSize = 0;
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ UInt64 size = 0;
+ bool defined = false;
+ Archive_GetItem_Size(archive, i, size, defined);
+ if (defined)
+ {
+ pi.UnpackSize_Defined = true;
+ pi.UnpackSize += size;
+ }
+
+ bool isDir = false;
+ Archive_IsItem_Dir(archive, i, isDir);
+ if (isDir)
+ pi.NumSubDirs++;
+ else
+ pi.NumSubFiles++;
+ }
+ if (pi.NumSubDirs != 0)
+ pi.NumSubDirs_Defined = true;
+ pi.NumSubFiles_Defined = true;
+ }
+
+ return S_OK;
+}
+
+#endif
+
+HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset)
+{
+ if (!op.stream)
+ return S_OK;
+ RINOK(op.stream->Seek(offset, STREAM_SEEK_SET, NULL));
+ const UInt32 kBufSize = 1 << 11;
+ Byte buf[kBufSize];
+
+ for (;;)
+ {
+ UInt32 processed = 0;
+ RINOK(op.stream->Read(buf, kBufSize, &processed));
+ if (processed == 0)
+ {
+ // ErrorInfo.NonZerosTail = false;
+ ErrorInfo.IgnoreTail = true;
+ return S_OK;
+ }
+ for (size_t i = 0; i < processed; i++)
+ {
+ if (buf[i] != 0)
+ {
+ // ErrorInfo.IgnoreTail = false;
+ // ErrorInfo.NonZerosTail = true;
+ return S_OK;
+ }
+ }
+ }
+}
+
+#ifndef _SFX
+
+class CExtractCallback_To_OpenCallback:
+ public IArchiveExtractCallback,
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+public:
+ CMyComPtr<IArchiveOpenCallback> Callback;
+ UInt64 Files;
+ UInt64 Offset;
+
+ MY_UNKNOWN_IMP2(IArchiveExtractCallback, ICompressProgressInfo)
+ INTERFACE_IArchiveExtractCallback(;)
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+ void Init(IArchiveOpenCallback *callback)
+ {
+ Callback = callback;
+ Files = 0;
+ Offset = 0;
+ }
+};
+
+STDMETHODIMP CExtractCallback_To_OpenCallback::SetTotal(UInt64 /* size */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallback_To_OpenCallback::SetCompleted(const UInt64 * /* completeValue */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)
+{
+ if (Callback)
+ {
+ UInt64 value = Offset;
+ if (inSize)
+ value += *inSize;
+ return Callback->SetCompleted(&Files, &value);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */)
+{
+ *outStream = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallback_To_OpenCallback::PrepareOperation(Int32 /* askExtractMode */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* operationResult */)
+{
+ return S_OK;
+}
+
+static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize,
+ IInStream *stream, const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openCallback,
+ IArchiveExtractCallback *extractCallback)
+{
+ /*
+ if (needPhySize)
+ {
+ CMyComPtr<IArchiveOpen2> open2;
+ archive->QueryInterface(IID_IArchiveOpen2, (void **)&open2);
+ if (open2)
+ return open2->ArcOpen2(stream, kOpenFlags_RealPhySize, openCallback);
+ }
+ */
+ RINOK(archive->Open(stream, maxCheckStartPosition, openCallback));
+ if (needPhySize)
+ {
+ bool phySize_Defined = false;
+ UInt64 phySize = 0;
+ RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, phySize, phySize_Defined));
+ if (phySize_Defined)
+ return S_OK;
+
+ bool phySizeCantBeDetected = false;;
+ RINOK(Archive_GetArcBoolProp(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected));
+
+ if (!phySizeCantBeDetected)
+ {
+ RINOK(archive->Extract(0, (UInt32)(Int32)-1, BoolToInt(true), extractCallback));
+ }
+ }
+ return S_OK;
+}
+
+static int FindFormatForArchiveType(CCodecs *codecs, CIntVector orderIndices, const char *name)
+{
+ FOR_VECTOR (i, orderIndices)
+ if (StringsAreEqualNoCase_Ascii(codecs->Formats[orderIndices[i]].Name, name))
+ return i;
+ return -1;
+}
+
+#endif
+
+HRESULT CArc::OpenStream2(const COpenOptions &op)
+{
+ // fprintf(stdout, "\nOpen: %S", Path); fflush(stdout);
+
+ Archive.Release();
+ GetRawProps.Release();
+ GetRootProps.Release();
+
+ ErrorInfo.ClearErrors();
+ ErrorInfo.ErrorFormatIndex = -1;
+
+ IsParseArc = false;
+ ArcStreamOffset = 0;
+
+ // OutputDebugStringA("1");
+ // OutputDebugStringW(Path);
+
const UString fileName = ExtractFileNameFromPath(Path);
UString extension;
{
- int dotPos = fileName.ReverseFind(L'.');
+ int dotPos = fileName.ReverseFind_Dot();
if (dotPos >= 0)
- extension = fileName.Mid(dotPos + 1);
+ extension = fileName.Ptr(dotPos + 1);
}
+
CIntVector orderIndices;
+
+ bool searchMarkerInHandler = false;
+ #ifdef _SFX
+ searchMarkerInHandler = true;
+ #endif
+
+ CBoolArr isMainFormatArr(op.codecs->Formats.Size());
+ {
+ FOR_VECTOR(i, op.codecs->Formats)
+ isMainFormatArr[i] = false;
+ }
+
+ UInt64 maxStartOffset =
+ op.openType.MaxStartOffset_Defined ?
+ op.openType.MaxStartOffset :
+ kMaxCheckStartPosition;
+
+ #ifndef _SFX
+ bool isUnknownExt = false;
+ #endif
+
+ bool isForced = false;
+ unsigned numMainTypes = 0;
+ int formatIndex = op.openType.FormatIndex;
+
if (formatIndex >= 0)
+ {
+ isForced = true;
orderIndices.Add(formatIndex);
+ numMainTypes = 1;
+ isMainFormatArr[(unsigned)formatIndex] = true;
+
+ searchMarkerInHandler = true;
+ }
else
{
+ unsigned numFinded = 0;
+ #ifndef _SFX
+ bool isPrearcExt = false;
+ #endif
+
+ {
+ FOR_VECTOR (i, op.codecs->Formats)
+ {
+ const CArcInfoEx &ai = op.codecs->Formats[i];
+
+ if (IgnoreSplit || !op.openType.CanReturnArc)
+ if (ai.IsSplit())
+ continue;
+ if (op.excludedFormats->FindInSorted(i) >= 0)
+ continue;
+
+ #ifndef _SFX
+ if (IsPreArcFormat(ai))
+ isPrearcExt = true;
+ #endif
+
+ if (ai.FindExtension(extension) >= 0)
+ {
+ // PrintNumber("orderIndices.Insert", i);
+ orderIndices.Insert(numFinded++, i);
+ isMainFormatArr[i] = true;
+ }
+ else
+ orderIndices.Add(i);
+ }
+ }
+
+ if (!op.stream)
+ {
+ if (numFinded != 1)
+ return E_NOTIMPL;
+ orderIndices.DeleteFrom(1);
+ }
+ // PrintNumber("numFinded", numFinded );
+
+ /*
+ if (op.openOnlySpecifiedByExtension)
+ {
+ if (numFinded != 0 && !IsExeExt(extension))
+ orderIndices.DeleteFrom(numFinded);
+ }
+ */
+
+ #ifndef _SFX
+
+ if (op.stream && orderIndices.Size() >= 2)
+ {
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+ CByteBuffer byteBuffer;
+ CIntVector orderIndices2;
+ if (numFinded == 0 || IsExeExt(extension))
+ {
+ // signature search was here
+ }
+ else if (extension.IsEqualTo("000") || extension.IsEqualTo("001"))
+ {
+ int i = FindFormatForArchiveType(op.codecs, orderIndices, "rar");
+ if (i >= 0)
+ {
+ const size_t kBufSize = (1 << 10);
+ byteBuffer.Alloc(kBufSize);
+ size_t processedSize = kBufSize;
+ RINOK(ReadStream(op.stream, byteBuffer, &processedSize));
+ if (processedSize >= 16)
+ {
+ const Byte *buf = byteBuffer;
+ const Byte kRarHeader[] = { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 };
+ if (TestSignature(buf, kRarHeader, 7) && buf[9] == 0x73 && (buf[10] & 1) != 0)
+ {
+ orderIndices2.Add(orderIndices[i]);
+ orderIndices[i] = -1;
+ if (i >= (int)numFinded)
+ numFinded++;
+ }
+ }
+ }
+ }
+ else
+ {
+ const size_t kBufSize = (1 << 10);
+ byteBuffer.Alloc(kBufSize);
+ size_t processedSize = kBufSize;
+ RINOK(ReadStream(op.stream, byteBuffer, &processedSize));
+ if (processedSize == 0)
+ return S_FALSE;
+
+ /*
+ check type order:
+ 1) matched extension, no signuature
+ 2) matched extension, matched signuature
+ // 3) no signuature
+ // 4) matched signuature
+ */
+
+ MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, NULL, 0);
+ MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, byteBuffer, processedSize);
+ // MakeCheckOrder(op.codecs, orderIndices, orderIndices.Size(), orderIndices2, NULL, 0);
+ // MakeCheckOrder(op.codecs, orderIndices, orderIndices.Size(), orderIndices2, byteBuffer, processedSize);
+ }
+
+ FOR_VECTOR (i, orderIndices)
+ {
+ int val = orderIndices[i];
+ if (val != -1)
+ orderIndices2.Add(val);
+ }
+ orderIndices = orderIndices2;
+ }
+
+ if (orderIndices.Size() >= 2)
+ {
+ int iIso = FindFormatForArchiveType(op.codecs, orderIndices, "iso");
+ int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf");
+ if (iUdf > iIso && iIso >= 0)
+ {
+ int isoIndex = orderIndices[iIso];
+ int udfIndex = orderIndices[iUdf];
+ orderIndices[iUdf] = isoIndex;
+ orderIndices[iIso] = udfIndex;
+ }
+ }
+
+ numMainTypes = numFinded;
+ isUnknownExt = (numMainTypes == 0) || isPrearcExt;
+
+ #else // _SFX
+
+ numMainTypes = orderIndices.Size();
+
+ // we need correct numMainTypes for mutlivolume SFX (if some volume is missing)
+ if (numFinded != 0)
+ numMainTypes = numFinded;
+
+ #endif
+ }
+
+ UInt64 fileSize = 0;
+ if (op.stream)
+ {
+ RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize));
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+ }
+ FileSize = fileSize;
+
+
+ #ifndef _SFX
+
+ CBoolArr skipFrontalFormat(op.codecs->Formats.Size());
+ {
+ FOR_VECTOR(i, op.codecs->Formats)
+ skipFrontalFormat[i] = false;
+ }
+
+ #endif
+
+ const COpenType &mode = op.openType;
+
+
+
- int i;
- int numFinded = 0;
- for (i = 0; i < codecs->Formats.Size(); i++)
- if (codecs->Formats[i].FindExtension(extension) >= 0)
- orderIndices.Insert(numFinded++, i);
- else
- orderIndices.Add(i);
- if (!stream)
+ if (mode.CanReturnArc)
{
- if (numFinded != 1)
- return E_NOTIMPL;
- orderIndices.DeleteFrom(1);
+ // ---------- OPEN main type by extenssion ----------
+
+ unsigned numCheckTypes = orderIndices.Size();
+ if (formatIndex >= 0)
+ numCheckTypes = numMainTypes;
+
+ for (unsigned i = 0; i < numCheckTypes; i++)
+ {
+ FormatIndex = orderIndices[i];
+
+ bool exactOnly = false;
+
+ #ifndef _SFX
+
+ const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
+ // OutputDebugStringW(ai.Name);
+ if (i >= numMainTypes)
+ {
+ if (!ai.Flags_BackwardOpen()
+ // && !ai.Flags_PureStartOpen()
+ )
+ continue;
+ exactOnly = true;
+ }
+
+ #endif
+
+ // Some handlers do not set total bytes. So we set it here
+ if (op.callback)
+ RINOK(op.callback->SetTotal(NULL, &fileSize));
+
+ if (op.stream)
+ {
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+ }
+
+ CMyComPtr<IInArchive> archive;
+
+ RINOK(PrepareToOpen(op, FormatIndex, archive));
+ if (!archive)
+ continue;
+
+ HRESULT result;
+ if (op.stream)
+ {
+ UInt64 searchLimit = (!exactOnly && searchMarkerInHandler) ? maxStartOffset: 0;
+ result = archive->Open(op.stream, &searchLimit, op.callback);
+ }
+ else
+ {
+ CMyComPtr<IArchiveOpenSeq> openSeq;
+ archive.QueryInterface(IID_IArchiveOpenSeq, (void **)&openSeq);
+ if (!openSeq)
+ return E_NOTIMPL;
+ result = openSeq->OpenSeq(op.seqStream);
+ }
+
+ RINOK(ReadBasicProps(archive, 0, result));
+
+ if (result == S_FALSE)
+ {
+ bool isArc = ErrorInfo.IsArc_After_NonOpen();
+
+ #ifndef _SFX
+ // if it's archive, we allow another open attempt for parser
+ if (!mode.CanReturnParser || !isArc)
+ skipFrontalFormat[(unsigned)FormatIndex] = true;
+ #endif
+
+ if (exactOnly)
+ continue;
+
+ if (i == 0 && numMainTypes == 1)
+ {
+ // we set NonOpenErrorInfo, only if there is only one main format (defined by extension).
+ ErrorInfo.ErrorFormatIndex = FormatIndex;
+ NonOpen_ErrorInfo = ErrorInfo;
+
+ if (!mode.CanReturnParser && isArc)
+ {
+ // if (formatIndex < 0 && !searchMarkerInHandler)
+ {
+ // if bad archive was detected, we don't need additional open attempts
+ #ifndef _SFX
+ if (!IsPreArcFormat(ai) /* || !mode.SkipSfxStub */)
+ #endif
+ return S_FALSE;
+ }
+ }
+ }
+
+ /*
+ #ifndef _SFX
+ if (IsExeExt(extension) || ai.Flags_PreArc())
+ {
+ // openOnlyFullArc = false;
+ // canReturnTailArc = true;
+ // limitSignatureSearch = true;
+ }
+ #endif
+ */
+
+ continue;
+ }
+
+ RINOK(result);
+
+ #ifndef _SFX
+
+ bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex];
+ const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);
+
+ bool thereIsTail = ErrorInfo.ThereIsTail;
+ if (thereIsTail && mode.ZerosTailIsAllowed)
+ {
+ RINOK(CheckZerosTail(op, Offset + PhySize));
+ if (ErrorInfo.IgnoreTail)
+ thereIsTail = false;
+ }
+
+ if (Offset > 0)
+ {
+ if (exactOnly
+ || !searchMarkerInHandler
+ || !specFlags.CanReturn_NonStart()
+ || (mode.MaxStartOffset_Defined && (UInt64)Offset > mode.MaxStartOffset))
+ continue;
+ }
+ if (thereIsTail)
+ {
+ if (Offset > 0)
+ {
+ if (!specFlags.CanReturnMid)
+ continue;
+ }
+ else if (!specFlags.CanReturnFrontal)
+ continue;
+ }
+
+ if (Offset > 0 || thereIsTail)
+ {
+ if (formatIndex < 0)
+ {
+ if (IsPreArcFormat(ai))
+ {
+ // openOnlyFullArc = false;
+ // canReturnTailArc = true;
+ /*
+ if (mode.SkipSfxStub)
+ limitSignatureSearch = true;
+ */
+ // if (mode.SkipSfxStub)
+ {
+ // skipFrontalFormat[FormatIndex] = true;
+ continue;
+ }
+ }
+ }
+ }
+
+ #endif
+
+ Archive = archive;
+ return S_OK;
+ }
}
+
+
#ifndef _SFX
- if (orderIndices.Size() >= 2 && (numFinded == 0 || extension.CompareNoCase(L"exe") == 0))
+
+ if (!op.stream)
+ return S_FALSE;
+
+ if (formatIndex >= 0 && !mode.CanReturnParser)
{
- CIntVector orderIndices2;
+ if (mode.MaxStartOffset_Defined)
+ {
+ if (mode.MaxStartOffset == 0)
+ return S_FALSE;
+ }
+ else
+ {
+ const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
+ if (ai.FindExtension(extension) >= 0)
+ {
+ const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
+ if (ai.Flags_FindSignature() && searchMarkerInHandler)
+ return S_FALSE;
+ }
+ }
+ }
+
+ NArchive::NParser::CHandler *handlerSpec = new NArchive::NParser::CHandler;
+ CMyComPtr<IInArchive> handler = handlerSpec;
+
+ CExtractCallback_To_OpenCallback *extractCallback_To_OpenCallback_Spec = new CExtractCallback_To_OpenCallback;
+ CMyComPtr<IArchiveExtractCallback> extractCallback_To_OpenCallback = extractCallback_To_OpenCallback_Spec;
+ extractCallback_To_OpenCallback_Spec->Init(op.callback);
+
+ {
+ // ---------- Check all possible START archives ----------
+ // this code is better for full file archives than Parser's code.
+
CByteBuffer byteBuffer;
- const size_t kBufferSize = (1 << 21);
- byteBuffer.SetCapacity(kBufferSize);
- RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
- size_t processedSize = kBufferSize;
- RINOK(ReadStream(stream, byteBuffer, &processedSize));
- if (processedSize == 0)
- return S_FALSE;
+ bool endOfFile = false;
+ size_t processedSize;
+ {
+ size_t bufSize = 1 << 20; // it must be larger than max signature offset or IsArcFunc offset ((1 << 19) + x for UDF)
+ if (bufSize > fileSize)
+ {
+ bufSize = (size_t)fileSize;
+ endOfFile = true;
+ }
+ byteBuffer.Alloc(bufSize);
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+ processedSize = bufSize;
+ RINOK(ReadStream(op.stream, byteBuffer, &processedSize));
+ if (processedSize == 0)
+ return S_FALSE;
+ if (processedSize < bufSize)
+ endOfFile = true;
+ }
+ CUIntVector sortedFormats;
+
+ unsigned i;
+
+ int splitIndex = -1;
- const Byte *buf = byteBuffer;
- CByteBuffer hashBuffer;
- const UInt32 kNumVals = 1 << (kNumHashBytes * 8);
- hashBuffer.SetCapacity(kNumVals);
- Byte *hash = hashBuffer;
- memset(hash, 0xFF, kNumVals);
- Byte prevs[256];
- if (orderIndices.Size() >= 256)
- return S_FALSE;
- int i;
for (i = 0; i < orderIndices.Size(); i++)
{
- const CArcInfoEx &ai = codecs->Formats[orderIndices[i]];
- const CByteBuffer &sig = ai.StartSignature;
- if (sig.GetCapacity() < kNumHashBytes)
+ unsigned form = orderIndices[i];
+ if (skipFrontalFormat[form])
+ continue;
+ const CArcInfoEx &ai = op.codecs->Formats[form];
+ if (ai.IsSplit())
+ {
+ splitIndex = form;
continue;
- UInt32 v = HASH_VAL(sig, 0);
- prevs[i] = hash[v];
- hash[v] = (Byte)i;
+ }
+
+ if (ai.IsArcFunc)
+ {
+ UInt32 isArcRes = ai.IsArcFunc(byteBuffer, processedSize);
+ if (isArcRes == k_IsArc_Res_NO)
+ continue;
+ if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile)
+ continue;
+ // if (isArcRes == k_IsArc_Res_YES_LOW_PROB) continue;
+ sortedFormats.Insert(0, form);
+ continue;
+ }
+
+ bool isNewStyleSignature = IsNewStyleSignature(ai);
+ bool needCheck = !isNewStyleSignature
+ || ai.Signatures.IsEmpty()
+ || ai.Flags_PureStartOpen()
+ || ai.Flags_StartOpen()
+ || ai.Flags_BackwardOpen();
+
+ if (isNewStyleSignature && !ai.Signatures.IsEmpty())
+ {
+ unsigned k;
+ for (k = 0; k < ai.Signatures.Size(); k++)
+ {
+ const CByteBuffer &sig = ai.Signatures[k];
+ UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size();
+ if (processedSize < signatureEnd)
+ {
+ if (!endOfFile)
+ needCheck = true;
+ }
+ else if (memcmp(sig, byteBuffer + ai.SignatureOffset, sig.Size()) == 0)
+ break;
+ }
+ if (k != ai.Signatures.Size())
+ {
+ sortedFormats.Insert(0, form);
+ continue;
+ }
+ }
+ if (needCheck)
+ sortedFormats.Add(form);
}
- processedSize -= (kNumHashBytes - 1);
- for (UInt32 pos = 0; pos < processedSize; pos++)
+ if (splitIndex >= 0)
+ sortedFormats.Insert(0, splitIndex);
+
+ for (i = 0; i < sortedFormats.Size(); i++)
{
- for (; pos < processedSize && hash[HASH_VAL(buf, pos)] == 0xFF; pos++);
- if (pos == processedSize)
- break;
- UInt32 v = HASH_VAL(buf, pos);
- Byte *ptr = &hash[v];
- int i = *ptr;
- do
+ FormatIndex = sortedFormats[i];
+ const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
+
+ if (op.callback)
+ RINOK(op.callback->SetTotal(NULL, &fileSize));
+
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+
+ CMyComPtr<IInArchive> archive;
+ RINOK(PrepareToOpen(op, FormatIndex, archive));
+ if (!archive)
+ continue;
+
+ PRF(printf("\nSorted Open %S", (const wchar_t *)ai.Name));
+ HRESULT result;
{
- int index = orderIndices[i];
- const CArcInfoEx &ai = codecs->Formats[index];
- const CByteBuffer &sig = ai.StartSignature;
- if (sig.GetCapacity() != 0 && pos + sig.GetCapacity() <= processedSize + (kNumHashBytes - 1) &&
- TestSignature(buf + pos, sig, sig.GetCapacity()))
+ UInt64 searchLimit = 0;
+ /*
+ if (mode.CanReturnArc)
+ result = archive->Open(op.stream, &searchLimit, op.callback);
+ else
+ */
+ result = OpenArchiveSpec(archive, !mode.CanReturnArc, op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback);
+ }
+
+ if (result == S_FALSE)
+ {
+ skipFrontalFormat[(unsigned)FormatIndex] = true;
+ // FIXME: maybe we must use LenIsUnknown.
+ // printf(" OpenForSize Error");
+ continue;
+ }
+ RINOK(result);
+
+ RINOK(ReadBasicProps(archive, 0, result));
+
+ if (Offset > 0)
+ {
+ continue; // good handler doesn't return such Offset > 0
+ // but there are some cases like false prefixed PK00 archive, when
+ // we can support it?
+ }
+
+ NArchive::NParser::CParseItem pi;
+ pi.Offset = Offset;
+ pi.Size = AvailPhySize;
+
+ // bool needScan = false;
+
+ if (!PhySizeDefined)
+ {
+ // it's for Z format
+ pi.LenIsUnknown = true;
+ // needScan = true;
+ // phySize = arcRem;
+ // nextNeedCheckStartOpen = false;
+ }
+
+ /*
+ if (OkPhySize_Defined)
+ pi.OkSize = pi.OkPhySize;
+ else
+ pi.OkSize = pi.Size;
+ */
+
+ pi.NormalizeOffset();
+ // printf(" phySize = %8d", (unsigned)phySize);
+
+
+ if (mode.CanReturnArc)
+ {
+ bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex];
+ const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);
+ bool openCur = false;
+
+ if (!ErrorInfo.ThereIsTail)
+ openCur = true;
+ else
{
- orderIndices2.Add(index);
- orderIndices[i] = 0xFF;
- *ptr = prevs[i];
+ if (mode.ZerosTailIsAllowed)
+ {
+ RINOK(CheckZerosTail(op, Offset + PhySize));
+ if (ErrorInfo.IgnoreTail)
+ openCur = true;
+ }
+ if (!openCur)
+ {
+ openCur = specFlags.CanReturnFrontal;
+ if (formatIndex < 0) // format is not forced
+ {
+ if (IsPreArcFormat(ai))
+ {
+ // if (mode.SkipSfxStub)
+ {
+ openCur = false;
+ }
+ }
+ }
+ }
+ }
+
+ if (openCur)
+ {
+ InStream = op.stream;
+ Archive = archive;
+ return S_OK;
}
- else
- ptr = &prevs[i];
- i = *ptr;
}
- while (i != 0xFF);
+
+ skipFrontalFormat[(unsigned)FormatIndex] = true;
+
+
+ // if (!mode.CanReturnArc)
+ /*
+ if (!ErrorInfo.ThereIsTail)
+ continue;
+ */
+ if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize)
+ continue;
+
+ // printf("\nAdd offset = %d", (int)pi.Offset);
+ RINOK(ReadParseItemProps(archive, ai, pi));
+ handlerSpec->AddItem(pi);
}
-
- for (i = 0; i < orderIndices.Size(); i++)
+ }
+
+
+
+
+
+ // ---------- PARSER ----------
+
+ CUIntVector arc2sig; // formatIndex to signatureIndex
+ CUIntVector sig2arc; // signatureIndex to formatIndex;
+ {
+ unsigned sum = 0;
+ FOR_VECTOR (i, op.codecs->Formats)
{
- int val = orderIndices[i];
- if (val != 0xFF)
- orderIndices2.Add(val);
+ arc2sig.Add(sum);
+ const CObjectVector<CByteBuffer> &sigs = op.codecs->Formats[i].Signatures;
+ sum += sigs.Size();
+ FOR_VECTOR (k, sigs)
+ sig2arc.Add(i);
}
- orderIndices = orderIndices2;
}
- else if (extension == L"000" || extension == L"001")
+
{
- CByteBuffer byteBuffer;
- const size_t kBufferSize = (1 << 10);
- byteBuffer.SetCapacity(kBufferSize);
- Byte *buffer = byteBuffer;
- RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
- size_t processedSize = kBufferSize;
- RINOK(ReadStream(stream, buffer, &processedSize));
- if (processedSize >= 16)
- {
- Byte kRarHeader[] = {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00};
- if (TestSignature(buffer, kRarHeader, 7) && buffer[9] == 0x73 && (buffer[10] & 1) != 0)
- {
- for (int i = 0; i < orderIndices.Size(); i++)
- {
- int index = orderIndices[i];
- const CArcInfoEx &ai = codecs->Formats[index];
- if (ai.Name.CompareNoCase(L"rar") != 0)
+ const size_t kBeforeSize = 1 << 16;
+ const size_t kAfterSize = 1 << 20;
+ const size_t kBufSize = 1 << 22; // it must be more than kBeforeSize + kAfterSize
+
+ const UInt32 kNumVals = (UInt32)1 << (kNumHashBytes * 8);
+ CByteArr hashBuffer(kNumVals);
+ Byte *hash = hashBuffer;
+ memset(hash, 0xFF, kNumVals);
+ Byte prevs[256];
+ memset(prevs, 0xFF, sizeof(prevs));
+ if (sig2arc.Size() >= 0xFF)
+ return S_FALSE;
+
+ CUIntVector difficultFormats;
+ CBoolArr difficultBools(256);
+ {
+ for (unsigned i = 0; i < 256; i++)
+ difficultBools[i] = false;
+ }
+
+ bool thereAreHandlersForSearch = false;
+
+ // UInt32 maxSignatureEnd = 0;
+
+ FOR_VECTOR (i, orderIndices)
+ {
+ int index = orderIndices[i];
+ if (index < 0)
+ continue;
+ const CArcInfoEx &ai = op.codecs->Formats[index];
+ bool isDifficult = false;
+ // if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31)
+ if (!ai.NewInterface)
+ isDifficult = true;
+ else
+ {
+ if (ai.Flags_StartOpen())
+ isDifficult = true;
+ FOR_VECTOR (k, ai.Signatures)
+ {
+ const CByteBuffer &sig = ai.Signatures[k];
+ /*
+ UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size();
+ if (maxSignatureEnd < signatureEnd)
+ maxSignatureEnd = signatureEnd;
+ */
+ if (sig.Size() < kNumHashBytes)
+ {
+ isDifficult = true;
continue;
- orderIndices.Delete(i--);
- orderIndices.Insert(0, index);
- break;
+ }
+ thereAreHandlersForSearch = true;
+ UInt32 v = HASH_VAL(sig, 0);
+ unsigned sigIndex = arc2sig[(unsigned)index] + k;
+ prevs[sigIndex] = hash[v];
+ hash[v] = (Byte)sigIndex;
}
}
+ if (isDifficult)
+ {
+ difficultFormats.Add(index);
+ difficultBools[index] = true;
+ }
}
- }
- if (orderIndices.Size() >= 2)
- {
- int isoIndex = codecs->FindFormatForArchiveType(L"iso");
- int udfIndex = codecs->FindFormatForArchiveType(L"udf");
- int iIso = -1;
- int iUdf = -1;
- for (int i = 0; i < orderIndices.Size(); i++)
+
+ if (!thereAreHandlersForSearch)
{
- if (orderIndices[i] == isoIndex) iIso = i;
- if (orderIndices[i] == udfIndex) iUdf = i;
+ // openOnlyFullArc = true;
+ // canReturnTailArc = true;
}
- if (iUdf > iIso && iIso >= 0)
+
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+
+ CLimitedCachedInStream *limitedStreamSpec = new CLimitedCachedInStream;
+ CMyComPtr<IInStream> limitedStream = limitedStreamSpec;
+ limitedStreamSpec->SetStream(op.stream);
+
+ CArchiveOpenCallback_Offset *openCallback_Offset_Spec = NULL;
+ CMyComPtr<IArchiveOpenCallback> openCallback_Offset;
+ if (op.callback)
{
- orderIndices[iUdf] = isoIndex;
- orderIndices[iIso] = udfIndex;
+ openCallback_Offset_Spec = new CArchiveOpenCallback_Offset;
+ openCallback_Offset = openCallback_Offset_Spec;
+ openCallback_Offset_Spec->Callback = op.callback;
+ openCallback_Offset_Spec->Callback.QueryInterface(IID_IArchiveOpenVolumeCallback, &openCallback_Offset_Spec->OpenVolumeCallback);
+ #ifndef _NO_CRYPTO
+ openCallback_Offset_Spec->Callback.QueryInterface(IID_ICryptoGetTextPassword, &openCallback_Offset_Spec->GetTextPassword);
+ #endif
}
- }
- #endif
- }
+ if (op.callback)
+ RINOK(op.callback->SetTotal(NULL, &fileSize));
+
+ CByteBuffer &byteBuffer = limitedStreamSpec->Buffer;
+ byteBuffer.Alloc(kBufSize);
- for (int i = 0; i < orderIndices.Size(); i++)
- {
- if (stream)
+ UInt64 callbackPrev = 0;
+ bool needCheckStartOpen = true; // = true, if we need to test all archives types for current pos.
+
+ bool endOfFile = false;
+ UInt64 bufPhyPos = 0;
+ size_t bytesInBuf = 0;
+ // UInt64 prevPos = 0;
+
+ // ---------- Main Scan Loop ----------
+
+ UInt64 pos = 0;
+
+ if (!mode.EachPos && handlerSpec->_items.Size() == 1)
{
- RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
+ NArchive::NParser::CParseItem &pi = handlerSpec->_items[0];
+ if (!pi.LenIsUnknown && pi.Offset == 0)
+ pos = pi.Size;
}
- CMyComPtr<IInArchive> archive;
- FormatIndex = orderIndices[i];
- RINOK(codecs->CreateInArchive(FormatIndex, archive));
- if (!archive)
- continue;
-
- #ifdef EXTERNAL_CODECS
+ for (;;)
{
- CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
- archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
- if (setCompressCodecsInfo)
+ // printf("\nPos = %d", (int)pos);
+ UInt64 posInBuf = pos - bufPhyPos;
+
+ // if (pos > ((UInt64)1 << 35)) break;
+
+ if (!endOfFile)
{
- RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));
+ if (bytesInBuf < kBufSize)
+ {
+ size_t processedSize = kBufSize - bytesInBuf;
+ // printf("\nRead ask = %d", (unsigned)processedSize);
+ UInt64 seekPos = bufPhyPos + bytesInBuf;
+ RINOK(op.stream->Seek(bufPhyPos + bytesInBuf, STREAM_SEEK_SET, NULL));
+ RINOK(ReadStream(op.stream, byteBuffer + bytesInBuf, &processedSize));
+ // printf(" processed = %d", (unsigned)processedSize);
+ if (processedSize == 0)
+ {
+ fileSize = seekPos;
+ endOfFile = true;
+ }
+ else
+ {
+ bytesInBuf += processedSize;
+ limitedStreamSpec->SetCache(processedSize, (size_t)bufPhyPos);
+ }
+ continue;
+ }
+
+ if (bytesInBuf < posInBuf)
+ {
+ UInt64 skipSize = posInBuf - bytesInBuf;
+ if (skipSize <= kBeforeSize)
+ {
+ size_t keepSize = (size_t)(kBeforeSize - skipSize);
+ // printf("\nmemmove skip = %d", (int)keepSize);
+ memmove(byteBuffer, byteBuffer + bytesInBuf - keepSize, keepSize);
+ bytesInBuf = keepSize;
+ bufPhyPos = pos - keepSize;
+ continue;
+ }
+ // printf("\nSkip %d", (int)(skipSize - kBeforeSize));
+ // RINOK(op.stream->Seek(skipSize - kBeforeSize, STREAM_SEEK_CUR, NULL));
+ bytesInBuf = 0;
+ bufPhyPos = pos - kBeforeSize;
+ continue;
+ }
+
+ if (bytesInBuf - posInBuf < kAfterSize)
+ {
+ size_t beg = (size_t)posInBuf - kBeforeSize;
+ // printf("\nmemmove for after beg = %d", (int)beg);
+ memmove(byteBuffer, byteBuffer + beg, bytesInBuf - beg);
+ bufPhyPos += beg;
+ bytesInBuf -= beg;
+ continue;
+ }
}
+
+ bool useOffsetCallback = false;
+ if (openCallback_Offset)
+ {
+ openCallback_Offset_Spec->Files = handlerSpec->_items.Size();
+ openCallback_Offset_Spec->Offset = pos;
+
+ useOffsetCallback = (!op.openType.CanReturnArc || handlerSpec->_items.Size() > 1);
+
+ if (pos >= callbackPrev + (1 << 23))
+ {
+ RINOK(openCallback_Offset_Spec->SetCompleted(NULL, NULL));
+ callbackPrev = pos;
+ }
+ }
+
+ {
+ UInt64 endPos = bufPhyPos + bytesInBuf;
+ if (fileSize < endPos)
+ {
+ FileSize = fileSize; // why ????
+ fileSize = endPos;
+ }
+ }
+
+ size_t availSize = bytesInBuf - (size_t)posInBuf;
+ if (availSize < kNumHashBytes)
+ break;
+ size_t scanSize = availSize -
+ ((availSize >= kAfterSize) ? kAfterSize : kNumHashBytes);
+
+ {
+ /*
+ UInt64 scanLimit = openOnlyFullArc ?
+ maxSignatureEnd :
+ op.openType.ScanSize + maxSignatureEnd;
+ */
+ if (!mode.CanReturnParser)
+ {
+ if (pos > maxStartOffset)
+ break;
+ UInt64 remScan = maxStartOffset - pos;
+ if (scanSize > remScan)
+ scanSize = (size_t)remScan;
+ }
+ }
+
+ scanSize++;
+
+ const Byte *buf = byteBuffer + (size_t)posInBuf;
+ size_t ppp = 0;
+
+ if (!needCheckStartOpen)
+ {
+ for (; ppp < scanSize && hash[HASH_VAL(buf, ppp)] == 0xFF; ppp++);
+ pos += ppp;
+ if (ppp == scanSize)
+ continue;
+ }
+
+ UInt32 v = HASH_VAL(buf, ppp);
+ bool nextNeedCheckStartOpen = true;
+ unsigned i = hash[v];
+ unsigned indexOfDifficult = 0;
+
+ // ---------- Open Loop for Current Pos ----------
+ bool wasOpen = false;
+
+ for (;;)
+ {
+ unsigned index;
+ bool isDifficult;
+ if (needCheckStartOpen && indexOfDifficult < difficultFormats.Size())
+ {
+ index = difficultFormats[indexOfDifficult++];
+ isDifficult = true;
+ }
+ else
+ {
+ if (i == 0xFF)
+ break;
+ index = sig2arc[i];
+ unsigned sigIndex = i - arc2sig[index];
+ i = prevs[i];
+ if (needCheckStartOpen && difficultBools[index])
+ continue;
+ const CArcInfoEx &ai = op.codecs->Formats[index];
+
+ if (pos < ai.SignatureOffset)
+ continue;
+
+ /*
+ if (openOnlyFullArc)
+ if (pos != ai.SignatureOffset)
+ continue;
+ */
+
+ const CByteBuffer &sig = ai.Signatures[sigIndex];
+
+ if (ppp + sig.Size() > availSize
+ || !TestSignature(buf + ppp, sig, sig.Size()))
+ continue;
+ // printf("\nSignature OK: %10S %8x %5d", (const wchar_t *)ai.Name, (int)pos, (int)(pos - prevPos));
+ // prevPos = pos;
+ isDifficult = false;
+ }
+
+ const CArcInfoEx &ai = op.codecs->Formats[index];
+
+
+ if ((isDifficult && pos == 0) || ai.SignatureOffset == pos)
+ {
+ // we don't check same archive second time */
+ if (skipFrontalFormat[index])
+ continue;
+ }
+
+ UInt64 startArcPos = pos;
+ if (!isDifficult)
+ {
+ if (pos < ai.SignatureOffset)
+ continue;
+ startArcPos = pos - ai.SignatureOffset;
+ /*
+ // we don't need the check for Z files
+ if (startArcPos < handlerSpec->GetLastEnd())
+ continue;
+ */
+ }
+
+ if (ai.IsArcFunc && startArcPos >= bufPhyPos)
+ {
+ size_t offsetInBuf = (size_t)(startArcPos - bufPhyPos);
+ if (offsetInBuf < bytesInBuf)
+ {
+ UInt32 isArcRes = ai.IsArcFunc(byteBuffer + offsetInBuf, bytesInBuf - offsetInBuf);
+ if (isArcRes == k_IsArc_Res_NO)
+ continue;
+ if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile)
+ continue;
+ /*
+ if (isArcRes == k_IsArc_Res_YES_LOW_PROB)
+ {
+ // if (pos != ai.SignatureOffset)
+ continue;
+ }
+ */
+ }
+ // printf("\nIsArc OK: %S", (const wchar_t *)ai.Name);
+ }
+
+ /*
+ if (pos == 67109888)
+ pos = pos;
+ */
+ PRF(printf("\npos = %9I64d : %S", pos, (const wchar_t *)ai.Name));
+
+ bool isMainFormat = isMainFormatArr[index];
+ const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);
+
+ CMyComPtr<IInArchive> archive;
+ RINOK(PrepareToOpen(op, index, archive));
+ if (!archive)
+ return E_FAIL;
+
+ // OutputDebugStringW(ai.Name);
+
+ UInt64 rem = fileSize - startArcPos;
+
+ UInt64 arcStreamOffset = 0;
+
+ if (ai.Flags_UseGlobalOffset())
+ {
+ limitedStreamSpec->InitAndSeek(0, fileSize);
+ limitedStream->Seek(startArcPos, STREAM_SEEK_SET, NULL);
+ }
+ else
+ {
+ limitedStreamSpec->InitAndSeek(startArcPos, rem);
+ arcStreamOffset = startArcPos;
+ }
+
+ UInt64 maxCheckStartPosition = 0;
+
+ if (openCallback_Offset)
+ {
+ openCallback_Offset_Spec->Files = handlerSpec->_items.Size();
+ openCallback_Offset_Spec->Offset = startArcPos;
+ }
+
+ // HRESULT result = archive->Open(limitedStream, &maxCheckStartPosition, openCallback_Offset);
+ extractCallback_To_OpenCallback_Spec->Files = 0;
+ extractCallback_To_OpenCallback_Spec->Offset = startArcPos;
+
+ HRESULT result = OpenArchiveSpec(archive, true, limitedStream, &maxCheckStartPosition,
+ useOffsetCallback ? (IArchiveOpenCallback *)openCallback_Offset : (IArchiveOpenCallback *)op.callback,
+ extractCallback_To_OpenCallback);
+
+ RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result));
+
+ bool isOpen = false;
+ if (result == S_FALSE)
+ {
+ if (!mode.CanReturnParser)
+ {
+ if (formatIndex < 0 && ErrorInfo.IsArc_After_NonOpen())
+ {
+ ErrorInfo.ErrorFormatIndex = index;
+ NonOpen_ErrorInfo = ErrorInfo;
+ // if archive was detected, we don't need additional open attempts
+ return S_FALSE;
+ }
+ continue;
+ }
+ if (!ErrorInfo.IsArc_After_NonOpen() || !PhySizeDefined || PhySize == 0)
+ continue;
+ }
+ else
+ {
+ isOpen = true;
+ RINOK(result);
+ PRF(printf(" OK "));
+ }
+
+ // fprintf(stderr, "\n %8X %S", startArcPos, Path);
+ // printf("\nOpen OK: %S", ai.Name);
+
+
+ NArchive::NParser::CParseItem pi;
+ pi.Offset = startArcPos;
+
+ if (ai.Flags_UseGlobalOffset())
+ pi.Offset = Offset;
+ else if (Offset != 0)
+ return E_FAIL;
+ UInt64 arcRem = FileSize - pi.Offset;
+ UInt64 phySize = arcRem;
+ bool phySizeDefined = PhySizeDefined;
+ if (phySizeDefined)
+ {
+ if (pi.Offset + PhySize > FileSize)
+ {
+ // ErrorInfo.ThereIsTail = true;
+ PhySize = FileSize - pi.Offset;
+ }
+ phySize = PhySize;
+ }
+ if (phySize == 0 || (UInt64)phySize > ((UInt64)1 << 63))
+ return E_FAIL;
+
+ /*
+ if (!ai.UseGlobalOffset)
+ {
+ if (phySize > arcRem)
+ {
+ ThereIsTail = true;
+ phySize = arcRem;
+ }
+ }
+ */
+
+ bool needScan = false;
+
+
+ if (isOpen && !phySizeDefined)
+ {
+ // it's for Z format
+ pi.LenIsUnknown = true;
+ needScan = true;
+ phySize = arcRem;
+ nextNeedCheckStartOpen = false;
+ }
+
+ pi.Size = phySize;
+ /*
+ if (OkPhySize_Defined)
+ pi.OkSize = OkPhySize;
+ */
+ pi.NormalizeOffset();
+ // printf(" phySize = %8d", (unsigned)phySize);
+
+ /*
+ if (needSkipFullArc)
+ if (pi.Offset == 0 && phySizeDefined && pi.Size >= fileSize)
+ continue;
+ */
+ if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize)
+ {
+ // it's possible for dmg archives
+ if (!mode.CanReturnArc)
+ continue;
+ }
+
+ if (mode.EachPos)
+ pos++;
+ else if (needScan)
+ {
+ pos++;
+ /*
+ if (!OkPhySize_Defined)
+ pos++;
+ else
+ pos = pi.Offset + pi.OkSize;
+ */
+ }
+ else
+ pos = pi.Offset + pi.Size;
+
+
+ RINOK(ReadParseItemProps(archive, ai, pi));
+
+ if (pi.Offset < startArcPos && !mode.EachPos /* && phySizeDefined */)
+ {
+ /* It's for DMG format.
+ This code deletes all previous items that are included to current item */
+
+ while (!handlerSpec->_items.IsEmpty())
+ {
+ {
+ const NArchive::NParser::CParseItem &back = handlerSpec->_items.Back();
+ if (back.Offset < pi.Offset)
+ break;
+ if (back.Offset + back.Size > pi.Offset + pi.Size)
+ break;
+ }
+ handlerSpec->_items.DeleteBack();
+ }
+ }
+
+
+ if (isOpen && mode.CanReturnArc && phySizeDefined)
+ {
+ // if (pi.Offset + pi.Size >= fileSize)
+ bool openCur = false;
+
+ bool thereIsTail = ErrorInfo.ThereIsTail;
+ if (thereIsTail && mode.ZerosTailIsAllowed)
+ {
+ RINOK(CheckZerosTail(op, arcStreamOffset + Offset + PhySize));
+ if (ErrorInfo.IgnoreTail)
+ thereIsTail = false;
+ }
+
+ if (pi.Offset != 0)
+ {
+ if (!pi.IsNotArcType)
+ if (thereIsTail)
+ openCur = specFlags.CanReturnMid;
+ else
+ openCur = specFlags.CanReturnTail;
+ }
+ else
+ {
+ if (!thereIsTail)
+ openCur = true;
+ else
+ openCur = specFlags.CanReturnFrontal;
+
+
+ if (formatIndex >= -2)
+ openCur = true;
+ }
+ if (formatIndex < 0 && pi.IsSelfExe /* && mode.SkipSfxStub */)
+ openCur = false;
+
+ // We open file as SFX, if there is front archive or first archive is "Self Executable"
+ if (!openCur && !pi.IsSelfExe && !thereIsTail &&
+ (!pi.IsNotArcType || pi.Offset == 0))
+ {
+ if (handlerSpec->_items.IsEmpty())
+ {
+ if (specFlags.CanReturnTail)
+ openCur = true;
+ }
+ else if (handlerSpec->_items.Size() == 1)
+ {
+ if (handlerSpec->_items[0].IsSelfExe)
+ {
+ if (mode.SpecUnknownExt.CanReturnTail)
+ openCur = true;
+ }
+ }
+ }
+
+ if (openCur)
+ {
+ InStream = op.stream;
+ Archive = archive;
+ FormatIndex = index;
+ ArcStreamOffset = arcStreamOffset;
+ return S_OK;
+ }
+ }
+
+ /*
+ if (openOnlyFullArc)
+ {
+ ErrorInfo.ClearErrors();
+ return S_FALSE;
+ }
+ */
+
+ pi.FormatIndex = index;
+
+ // printf("\nAdd offset = %d", (int)pi.Offset);
+ handlerSpec->AddItem(pi);
+ wasOpen = true;
+ break;
+ }
+ // ---------- End of Open Loop for Current Pos ----------
+
+ if (!wasOpen)
+ pos++;
+ needCheckStartOpen = (nextNeedCheckStartOpen && wasOpen);
}
- #endif
+ // ---------- End of Main Scan Loop ----------
- // OutputDebugStringW(codecs->Formats[FormatIndex].Name);
+ /*
+ if (handlerSpec->_items.Size() == 1)
+ {
+ const NArchive::NParser::CParseItem &pi = handlerSpec->_items[0];
+ if (pi.Size == fileSize && pi.Offset == 0)
+ {
+ Archive = archive;
+ FormatIndex2 = pi.FormatIndex;
+ return S_OK;
+ }
+ }
+ */
- HRESULT result;
- if (stream)
- result = archive->Open(stream, &kMaxCheckStartPosition, callback);
- else
+ if (mode.CanReturnParser)
{
- CMyComPtr<IArchiveOpenSeq> openSeq;
- archive.QueryInterface(IID_IArchiveOpenSeq, (void **)&openSeq);
- if (!openSeq)
- return E_NOTIMPL;
- result = openSeq->OpenSeq(seqStream);
+ bool returnParser = (handlerSpec->_items.Size() == 1); // it's possible if fileSize was not correct at start of parsing
+ handlerSpec->AddUnknownItem(fileSize);
+ if (handlerSpec->_items.Size() == 0)
+ return S_FALSE;
+ if (returnParser || handlerSpec->_items.Size() != 1)
+ {
+ // return S_FALSE;
+ handlerSpec->_stream = op.stream;
+ Archive = handler;
+ ErrorInfo.ClearErrors();
+ IsParseArc = true;
+ FormatIndex = -1; // It's parser
+ Offset = 0;
+ return S_OK;
+ }
}
+ }
- if (result == S_FALSE)
- continue;
- RINOK(result);
+ #endif
+
+ if (!Archive)
+ return S_FALSE;
+ return S_OK;
+}
+
+HRESULT CArc::OpenStream(const COpenOptions &op)
+{
+ RINOK(OpenStream2(op));
+ // PrintNumber("op.formatIndex 3", op.formatIndex);
+
+ if (Archive)
+ {
+ GetRawProps.Release();
+ GetRootProps.Release();
+ Archive->QueryInterface(IID_IArchiveGetRawProps, (void **)&GetRawProps);
+ Archive->QueryInterface(IID_IArchiveGetRootProps, (void **)&GetRootProps);
+
+ RINOK(Archive_GetArcBoolProp(Archive, kpidIsTree, IsTree));
+ RINOK(Archive_GetArcBoolProp(Archive, kpidIsDeleted, Ask_Deleted));
+ RINOK(Archive_GetArcBoolProp(Archive, kpidIsAltStream, Ask_AltStream));
+ RINOK(Archive_GetArcBoolProp(Archive, kpidIsAux, Ask_Aux));
+ RINOK(Archive_GetArcBoolProp(Archive, kpidINode, Ask_INode));
+ RINOK(Archive_GetArcBoolProp(Archive, kpidReadOnly, IsReadOnly));
+ const UString fileName = ExtractFileNameFromPath(Path);
+ UString extension;
{
- NCOM::CPropVariant prop;
- archive->GetArchiveProperty(kpidError, &prop);
- if (prop.vt != VT_EMPTY)
- ErrorMessage = (prop.vt == VT_BSTR) ? prop.bstrVal : L"Unknown error";
+ int dotPos = fileName.ReverseFind_Dot();
+ if (dotPos >= 0)
+ extension = fileName.Ptr(dotPos + 1);
}
- Archive = archive;
- const CArcInfoEx &format = codecs->Formats[FormatIndex];
- if (format.Exts.Size() == 0)
- DefaultName = GetDefaultName2(fileName, L"", L"");
- else
+ DefaultName.Empty();
+ if (FormatIndex >= 0)
{
- int subExtIndex = format.FindExtension(extension);
- if (subExtIndex < 0)
- subExtIndex = 0;
- const CArcExtInfo &extInfo = format.Exts[subExtIndex];
- DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt);
+ const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
+ if (ai.Exts.Size() == 0)
+ DefaultName = GetDefaultName2(fileName, UString(), UString());
+ else
+ {
+ int subExtIndex = ai.FindExtension(extension);
+ if (subExtIndex < 0)
+ subExtIndex = 0;
+ const CArcExtInfo &extInfo = ai.Exts[subExtIndex];
+ DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt);
+ }
}
- return S_OK;
}
- return S_FALSE;
+
+ return S_OK;
}
-HRESULT CArc::OpenStreamOrFile(
- CCodecs *codecs,
- int formatIndex,
- bool stdInMode,
- IInStream *stream,
- IArchiveOpenCallback *callback)
+#ifdef _SFX
+
+#ifdef _WIN32
+ static const char *k_ExeExt = ".exe";
+ static const unsigned k_ExeExt_Len = 4;
+#else
+ static const char *k_ExeExt = "";
+ static const unsigned k_ExeExt_Len = 0;
+#endif
+
+#endif
+
+HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
{
CMyComPtr<IInStream> fileStream;
CMyComPtr<ISequentialInStream> seqStream;
- if (stdInMode)
+ CInFileStream *fileStreamSpec = NULL;
+
+ if (op.stdInMode)
+ {
seqStream = new CStdInFileStream;
- else if (!stream)
+ op.seqStream = seqStream;
+ }
+ else if (!op.stream)
{
- CInFileStream *fileStreamSpec = new CInFileStream;
+ fileStreamSpec = new CInFileStream;
fileStream = fileStreamSpec;
+ Path = filePath;
if (!fileStreamSpec->Open(us2fs(Path)))
+ {
return GetLastError();
- stream = fileStream;
+ }
+ op.stream = fileStream;
+ #ifdef _SFX
+ IgnoreSplit = true;
+ #endif
}
/*
if (callback)
{
UInt64 fileSize;
- RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize));
- RINOK(callback->SetTotal(NULL, &fileSize))
+ RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize));
+ RINOK(op.callback->SetTotal(NULL, &fileSize))
}
*/
- return OpenStream(codecs, formatIndex, stream, seqStream, callback);
+ HRESULT res = OpenStream(op);
+ IgnoreSplit = false;
+
+ #ifdef _SFX
+
+ if (res != S_FALSE
+ || !fileStreamSpec
+ || !op.callbackSpec
+ || NonOpen_ErrorInfo.IsArc_After_NonOpen())
+ return res;
+
+ {
+ if (filePath.Len() > k_ExeExt_Len
+ && StringsAreEqualNoCase_Ascii(filePath.RightPtr(k_ExeExt_Len), k_ExeExt))
+ {
+ const UString path2 = filePath.Left(filePath.Len() - k_ExeExt_Len);
+ FOR_VECTOR (i, op.codecs->Formats)
+ {
+ const CArcInfoEx &ai = op.codecs->Formats[i];
+ if (ai.IsSplit())
+ continue;
+ UString path3 = path2;
+ path3 += L'.';
+ path3 += ai.GetMainExt(); // "7z" for SFX.
+ Path = path3;
+ Path.AddAscii(".001");
+ bool isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path));
+ if (!isOk)
+ {
+ Path = path3;
+ isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path));
+ }
+ if (isOk)
+ {
+ if (fileStreamSpec->Open(us2fs(Path)))
+ {
+ op.stream = fileStream;
+ NonOpen_ErrorInfo.ClearErrors_Full();
+ if (OpenStream(op) == S_OK)
+ return S_OK;
+ }
+ }
+ }
+ }
+ }
+
+ #endif
+
+ return res;
+}
+
+void CArchiveLink::KeepModeForNextOpen()
+{
+ for (unsigned i = Arcs.Size(); i != 0;)
+ {
+ i--;
+ CMyComPtr<IArchiveKeepModeForNextOpen> keep;
+ Arcs[i].Archive->QueryInterface(IID_IArchiveKeepModeForNextOpen, (void **)&keep);
+ if (keep)
+ keep->KeepModeForNextOpen();
+ }
}
HRESULT CArchiveLink::Close()
{
- for (int i = Arcs.Size() - 1; i >= 0; i--)
+ for (unsigned i = Arcs.Size(); i != 0;)
{
- RINOK(Arcs[i].Archive->Close());
+ i--;
+ RINOK(Arcs[i].Close());
}
IsOpen = false;
+ // ErrorsText.Empty();
return S_OK;
}
void CArchiveLink::Release()
{
+ // NonOpenErrorFormatIndex = -1;
+ NonOpen_ErrorInfo.ClearErrors();
+ NonOpen_ArcPath.Empty();
while (!Arcs.IsEmpty())
Arcs.DeleteBack();
}
-HRESULT CArchiveLink::Open(
- CCodecs *codecs,
- const CIntVector &formatIndices,
- bool stdInMode,
- IInStream *stream,
- const UString &filePath,
- IArchiveOpenCallback *callback)
+/*
+void CArchiveLink::Set_ErrorsText()
+{
+ FOR_VECTOR(i, Arcs)
+ {
+ const CArc &arc = Arcs[i];
+ if (!arc.ErrorFlagsText.IsEmpty())
+ {
+ if (!ErrorsText.IsEmpty())
+ ErrorsText.Add_LF();
+ ErrorsText += GetUnicodeString(arc.ErrorFlagsText);
+ }
+ if (!arc.ErrorMessage.IsEmpty())
+ {
+ if (!ErrorsText.IsEmpty())
+ ErrorsText.Add_LF();
+ ErrorsText += arc.ErrorMessage;
+ }
+
+ if (!arc.WarningMessage.IsEmpty())
+ {
+ if (!ErrorsText.IsEmpty())
+ ErrorsText.Add_LF();
+ ErrorsText += arc.WarningMessage;
+ }
+ }
+}
+*/
+
+HRESULT CArchiveLink::Open(COpenOptions &op)
{
Release();
- if (formatIndices.Size() >= 32)
+ if (op.types->Size() >= 32)
return E_NOTIMPL;
HRESULT resSpec;
@@ -408,29 +3080,79 @@ HRESULT CArchiveLink::Open(
for (;;)
{
resSpec = S_OK;
- int formatIndex = -1;
- if (formatIndices.Size() >= 1)
+
+ op.openType = COpenType();
+ if (op.types->Size() >= 1)
{
- if (Arcs.Size() >= formatIndices.Size())
- break;
- formatIndex = formatIndices[formatIndices.Size() - Arcs.Size() - 1];
+ COpenType latest;
+ if (Arcs.Size() < op.types->Size())
+ latest = (*op.types)[op.types->Size() - Arcs.Size() - 1];
+ else
+ {
+ latest = (*op.types)[0];
+ if (!latest.Recursive)
+ break;
+ }
+ op.openType = latest;
+ }
+ else if (Arcs.Size() >= 32)
+ break;
+
+ /*
+ op.formatIndex = -1;
+ if (op.types->Size() >= 1)
+ {
+ int latest;
+ if (Arcs.Size() < op.types->Size())
+ latest = (*op.types)[op.types->Size() - Arcs.Size() - 1];
+ else
+ {
+ latest = (*op.types)[0];
+ if (latest != -2 && latest != -3)
+ break;
+ }
+ if (latest >= 0)
+ op.formatIndex = latest;
+ else if (latest == -1 || latest == -2)
+ {
+ // default
+ }
+ else if (latest == -3)
+ op.formatIndex = -2;
+ else
+ op.formatIndex = latest + 2;
}
else if (Arcs.Size() >= 32)
break;
+ */
if (Arcs.IsEmpty())
{
CArc arc;
- arc.Path = filePath;
+ arc.filePath = op.filePath;
+ arc.Path = op.filePath;
arc.SubfileIndex = (UInt32)(Int32)-1;
- RINOK(arc.OpenStreamOrFile(codecs, formatIndex, stdInMode, stream, callback));
+ HRESULT result = arc.OpenStreamOrFile(op);
+ if (result != S_OK)
+ {
+ if (result == S_FALSE)
+ {
+ NonOpen_ErrorInfo = arc.NonOpen_ErrorInfo;
+ // NonOpenErrorFormatIndex = arc.ErrorFormatIndex;
+ NonOpen_ArcPath = arc.Path;
+ }
+ return result;
+ }
Arcs.Add(arc);
continue;
}
+ // PrintNumber("op.formatIndex 11", op.formatIndex);
+
const CArc &arc = Arcs.Back();
- resSpec = (formatIndices.Size() == 0 ? S_OK : E_NOTIMPL);
+ if (op.types->Size() > Arcs.Size())
+ resSpec = E_NOTIMPL;
UInt32 mainSubfile;
{
@@ -461,46 +3183,57 @@ HRESULT CArchiveLink::Open(
CArc arc2;
RINOK(arc.GetItemPath(mainSubfile, arc2.Path));
-
- CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
- callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
- if (setSubArchiveName)
- setSubArchiveName->SetSubArchiveName(arc2.Path);
+
+ bool zerosTailIsAllowed;
+ RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed));
+
+
+ if (op.callback)
+ {
+ CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
+ op.callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
+ if (setSubArchiveName)
+ setSubArchiveName->SetSubArchiveName(arc2.Path);
+ }
arc2.SubfileIndex = mainSubfile;
- HRESULT result = arc2.OpenStream(codecs, formatIndex, subStream, NULL, callback);
- resSpec = (formatIndices.Size() == 0 ? S_OK : S_FALSE);
+
+ // CIntVector incl;
+ CIntVector excl;
+
+ COpenOptions op2;
+ #ifndef _SFX
+ op2.props = op.props;
+ #endif
+ op2.codecs = op.codecs;
+ // op2.types = &incl;
+ op2.openType = op.openType;
+ op2.openType.ZerosTailIsAllowed = zerosTailIsAllowed;
+ op2.excludedFormats = &excl;
+ op2.stdInMode = false;
+ op2.stream = subStream;
+ op2.filePath = arc2.Path;
+ op2.callback = op.callback;
+ op2.callbackSpec = op.callbackSpec;
+
+
+ HRESULT result = arc2.OpenStream(op2);
+ resSpec = (op.types->Size() == 0 ? S_OK : S_FALSE);
if (result == S_FALSE)
+ {
+ NonOpen_ErrorInfo = arc2.ErrorInfo;
+ NonOpen_ArcPath = arc2.Path;
break;
+ }
RINOK(result);
RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined));
Arcs.Add(arc2);
}
IsOpen = !Arcs.IsEmpty();
- return S_OK;
+ return resSpec;
}
-static void SetCallback(const FString &filePath,
- IOpenCallbackUI *callbackUI,
- IArchiveOpenCallback *reOpenCallback,
- CMyComPtr<IArchiveOpenCallback> &callback)
-{
- COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
- callback = openCallbackSpec;
- openCallbackSpec->Callback = callbackUI;
- openCallbackSpec->ReOpenCallback = reOpenCallback;
-
- FString dirPrefix, fileName;
- NFile::NDirectory::GetFullPathAndSplit(filePath, dirPrefix, fileName);
- openCallbackSpec->Init(dirPrefix, fileName);
-}
-
-HRESULT CArchiveLink::Open2(CCodecs *codecs,
- const CIntVector &formatIndices,
- bool stdInMode,
- IInStream *stream,
- const UString &filePath,
- IOpenCallbackUI *callbackUI)
+HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI)
{
VolumesSize = 0;
COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
@@ -508,41 +3241,266 @@ HRESULT CArchiveLink::Open2(CCodecs *codecs,
openCallbackSpec->Callback = callbackUI;
FString prefix, name;
- if (!stream && !stdInMode)
+
+ if (!op.stream && !op.stdInMode)
{
- NFile::NDirectory::GetFullPathAndSplit(us2fs(filePath), prefix, name);
+ NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), prefix, name);
openCallbackSpec->Init(prefix, name);
}
else
{
- openCallbackSpec->SetSubArchiveName(filePath);
+ openCallbackSpec->SetSubArchiveName(op.filePath);
}
- RINOK(Open(codecs, formatIndices, stdInMode, stream, filePath, callback));
- VolumePaths.Add(fs2us(prefix + name));
- for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)
- VolumePaths.Add(fs2us(prefix) + openCallbackSpec->FileNames[i]);
- VolumesSize = openCallbackSpec->TotalSize;
+ op.callback = callback;
+ op.callbackSpec = openCallbackSpec;
+
+ HRESULT res = Open(op);
+
+ PasswordWasAsked = openCallbackSpec->PasswordWasAsked;
+ // Password = openCallbackSpec->Password;
+
+ RINOK(res);
+ // VolumePaths.Add(fs2us(prefix + name));
+
+ FOR_VECTOR (i, openCallbackSpec->FileNames_WasUsed)
+ {
+ if (openCallbackSpec->FileNames_WasUsed[i])
+ {
+ VolumePaths.Add(fs2us(prefix) + openCallbackSpec->FileNames[i]);
+ VolumesSize += openCallbackSpec->FileSizes[i];
+ }
+ }
+ // VolumesSize = openCallbackSpec->TotalSize;
return S_OK;
}
-HRESULT CArchiveLink::ReOpen(CCodecs *codecs, const UString &filePath,
- IArchiveOpenCallback *callback)
+HRESULT CArc::ReOpen(const COpenOptions &op)
+{
+ ErrorInfo.ClearErrors();
+ ErrorInfo.ErrorFormatIndex = -1;
+
+ UInt64 fileSize = 0;
+ if (op.stream)
+ {
+ RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize));
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+ }
+ FileSize = fileSize;
+
+ CMyComPtr<IInStream> stream2;
+ Int64 globalOffset = GetGlobalOffset();
+ if (globalOffset <= 0)
+ stream2 = op.stream;
+ else
+ {
+ CTailInStream *tailStreamSpec = new CTailInStream;
+ stream2 = tailStreamSpec;
+ tailStreamSpec->Stream = op.stream;
+ tailStreamSpec->Offset = globalOffset;
+ tailStreamSpec->Init();
+ RINOK(tailStreamSpec->SeekToStart());
+ }
+
+ // There are archives with embedded STUBs (like ZIP), so we must support signature scanning
+ // But for another archives we can use 0 here. So the code can be fixed !!!
+ UInt64 maxStartPosition = kMaxCheckStartPosition;
+ HRESULT res = Archive->Open(stream2, &maxStartPosition, op.callback);
+
+ if (res == S_OK)
+ {
+ RINOK(ReadBasicProps(Archive, globalOffset, res));
+ ArcStreamOffset = globalOffset;
+ if (ArcStreamOffset != 0)
+ InStream = op.stream;
+ }
+ return res;
+}
+
+HRESULT CArchiveLink::Open3(COpenOptions &op, IOpenCallbackUI *callbackUI)
+{
+ HRESULT res = Open2(op, callbackUI);
+ if (callbackUI)
+ {
+ RINOK(callbackUI->Open_Finished());
+ }
+ return res;
+}
+
+HRESULT CArchiveLink::ReOpen(COpenOptions &op)
{
if (Arcs.Size() > 1)
return E_NOTIMPL;
- if (Arcs.Size() == 0)
- return Open2(codecs, CIntVector(), false, NULL, filePath, 0);
+ CObjectVector<COpenType> inc;
+ CIntVector excl;
+
+ op.types = &inc;
+ op.excludedFormats = &excl;
+ op.stdInMode = false;
+ op.stream = NULL;
+ if (Arcs.Size() == 0) // ???
+ return Open2(op, NULL);
+
+ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> openCallbackNew = openCallbackSpec;
+
+ openCallbackSpec->Callback = NULL;
+ openCallbackSpec->ReOpenCallback = op.callback;
+ {
+ FString dirPrefix, fileName;
+ NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), dirPrefix, fileName);
+ openCallbackSpec->Init(dirPrefix, fileName);
+ }
- CMyComPtr<IArchiveOpenCallback> openCallbackNew;
- SetCallback(us2fs(filePath), NULL, callback, openCallbackNew);
CInFileStream *fileStreamSpec = new CInFileStream;
CMyComPtr<IInStream> stream(fileStreamSpec);
- if (!fileStreamSpec->Open(us2fs(filePath)))
+ if (!fileStreamSpec->Open(us2fs(op.filePath)))
return GetLastError();
- HRESULT res = GetArchive()->Open(stream, &kMaxCheckStartPosition, callback);
+ op.stream = stream;
+
+ CArc &arc = Arcs[0];
+ HRESULT res = arc.ReOpen(op);
+
+ PasswordWasAsked = openCallbackSpec->PasswordWasAsked;
+ // Password = openCallbackSpec->Password;
+
IsOpen = (res == S_OK);
return res;
}
+
+#ifndef _SFX
+
+bool ParseComplexSize(const wchar_t *s, UInt64 &result)
+{
+ result = 0;
+ const wchar_t *end;
+ UInt64 number = ConvertStringToUInt64(s, &end);
+ if (end == s)
+ return false;
+ if (*end == 0)
+ {
+ result = number;
+ return true;
+ }
+ if (end[1] != 0)
+ return false;
+ unsigned numBits;
+ switch (MyCharLower_Ascii(*end))
+ {
+ case 'b': result = number; return true;
+ case 'k': numBits = 10; break;
+ case 'm': numBits = 20; break;
+ case 'g': numBits = 30; break;
+ case 't': numBits = 40; break;
+ default: return false;
+ }
+ if (number >= ((UInt64)1 << (64 - numBits)))
+ return false;
+ result = number << numBits;
+ return true;
+}
+
+static bool ParseTypeParams(const UString &s, COpenType &type)
+{
+ if (s[0] == 0)
+ return true;
+ if (s[1] == 0)
+ {
+ switch ((unsigned)(Byte)s[0])
+ {
+ case 'e': type.EachPos = true; return true;
+ case 'a': type.CanReturnArc = true; return true;
+ case 'r': type.Recursive = true; return true;
+ }
+ return false;
+ }
+ if (s[0] == 's')
+ {
+ UInt64 result;
+ if (!ParseComplexSize(s.Ptr(1), result))
+ return false;
+ type.MaxStartOffset = result;
+ type.MaxStartOffset_Defined = true;
+ return true;
+ }
+
+ return false;
+}
+
+bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
+{
+ int pos2 = s.Find(L':');
+ UString name;
+ if (pos2 < 0)
+ {
+ name = s;
+ pos2 = s.Len();
+ }
+ else
+ {
+ name = s.Left(pos2);
+ pos2++;
+ }
+
+ int index = codecs.FindFormatForArchiveType(name);
+ type.Recursive = false;
+
+ if (index < 0)
+ {
+ if (name[0] == '*')
+ {
+ if (name[1] != 0)
+ return false;
+ }
+ else if (name[0] == '#')
+ {
+ if (name[1] != 0)
+ return false;
+ type.CanReturnArc = false;
+ type.CanReturnParser = true;
+ }
+ else
+ return false;
+ }
+
+ type.FormatIndex = index;
+
+ for (unsigned i = pos2; i < s.Len();)
+ {
+ int next = s.Find(L':', i);
+ if (next < 0)
+ next = s.Len();
+ UString name = s.Mid(i, next - i);
+ if (name.IsEmpty())
+ return false;
+ if (!ParseTypeParams(name, type))
+ return false;
+ i = next + 1;
+ }
+
+ return true;
+}
+
+bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types)
+{
+ types.Clear();
+ for (unsigned pos = 0; pos < s.Len();)
+ {
+ int pos2 = s.Find(L'.', pos);
+ if (pos2 < 0)
+ pos2 = s.Len();
+ UString name = s.Mid(pos, pos2 - pos);
+ if (name.IsEmpty())
+ return false;
+ COpenType type;
+ if (!ParseType(codecs, name, type))
+ return false;
+ types.Add(type);
+ pos = pos2 + 1;
+ }
+ return true;
+}
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.h b/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.h
index 25f739e3035..10514ec4000 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.h
@@ -3,50 +3,364 @@
#ifndef __OPEN_ARCHIVE_H
#define __OPEN_ARCHIVE_H
-#include "Common/MyString.h"
-
-#include "Windows/FileFind.h"
-
-#include "../../Archive/IArchive.h"
+#include "../../../Windows/PropVariant.h"
#include "ArchiveOpenCallback.h"
#include "LoadCodecs.h"
+#include "Property.h"
+
+#ifndef _SFX
+
+#define SUPPORT_ALT_STREAMS
+
+#endif
+
+HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw();
+HRESULT Archive_IsItem_Dir(IInArchive *arc, UInt32 index, bool &result) throw();
+HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw();
+HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw();
+HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &deleted) throw();
+
+#ifdef SUPPORT_ALT_STREAMS
+int FindAltStreamColon_in_Path(const wchar_t *path);
+#endif
+
+/*
+struct COptionalOpenProperties
+{
+ UString FormatName;
+ CObjectVector<CProperty> Props;
+};
+*/
+
+#ifdef _SFX
+#define OPEN_PROPS_DECL
+#else
+#define OPEN_PROPS_DECL const CObjectVector<CProperty> *props;
+// #define OPEN_PROPS_DECL , const CObjectVector<COptionalOpenProperties> *props
+#endif
+
+struct COpenSpecFlags
+{
+ // bool CanReturnFull;
+ bool CanReturnFrontal;
+ bool CanReturnTail;
+ bool CanReturnMid;
+
+ bool CanReturn_NonStart() const { return CanReturnTail || CanReturnMid; }
+
+ COpenSpecFlags():
+ // CanReturnFull(true),
+ CanReturnFrontal(false),
+ CanReturnTail(false),
+ CanReturnMid(false)
+ {}
+};
+
+struct COpenType
+{
+ int FormatIndex;
+
+ COpenSpecFlags SpecForcedType;
+ COpenSpecFlags SpecMainType;
+ COpenSpecFlags SpecWrongExt;
+ COpenSpecFlags SpecUnknownExt;
-HRESULT GetArchiveItemBoolProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result);
-HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);
+ bool Recursive;
-struct CArc
+ bool CanReturnArc;
+ bool CanReturnParser;
+ bool EachPos;
+
+ // bool SkipSfxStub;
+ // bool ExeAsUnknown;
+
+ bool ZerosTailIsAllowed;
+
+ bool MaxStartOffset_Defined;
+ UInt64 MaxStartOffset;
+
+ const COpenSpecFlags &GetSpec(bool isForced, bool isMain, bool isUnknown) const
+ {
+ return isForced ? SpecForcedType : (isMain ? SpecMainType : (isUnknown ? SpecUnknownExt : SpecWrongExt));
+ }
+
+ COpenType():
+ FormatIndex(-1),
+ Recursive(true),
+ EachPos(false),
+ CanReturnArc(true),
+ CanReturnParser(false),
+ // SkipSfxStub(true),
+ // ExeAsUnknown(true),
+ ZerosTailIsAllowed(false),
+ MaxStartOffset_Defined(false),
+ MaxStartOffset(0)
+ {
+ SpecForcedType.CanReturnFrontal = true;
+ SpecForcedType.CanReturnTail = true;
+ SpecForcedType.CanReturnMid = true;
+
+ SpecMainType.CanReturnFrontal = true;
+
+ SpecUnknownExt.CanReturnTail = true; // for sfx
+ SpecUnknownExt.CanReturnMid = true;
+ SpecUnknownExt.CanReturnFrontal = true; // for alt streams of sfx with pad
+
+ // ZerosTailIsAllowed = true;
+ }
+};
+
+struct COpenOptions
{
+ CCodecs *codecs;
+ COpenType openType;
+ const CObjectVector<COpenType> *types;
+ const CIntVector *excludedFormats;
+
+ IInStream *stream;
+ ISequentialInStream *seqStream;
+ IArchiveOpenCallback *callback;
+ COpenCallbackImp *callbackSpec;
+ OPEN_PROPS_DECL
+ // bool openOnlySpecifiedByExtension,
+
+ bool stdInMode;
+ UString filePath;
+
+ COpenOptions():
+ codecs(NULL),
+ types(NULL),
+ excludedFormats(NULL),
+ stream(NULL),
+ seqStream(NULL),
+ callback(NULL),
+ callbackSpec(NULL),
+ stdInMode(false)
+ {}
+
+};
+
+UInt32 GetOpenArcErrorFlags(const NWindows::NCOM::CPropVariant &prop, bool *isDefinedProp = NULL);
+
+struct CArcErrorInfo
+{
+ bool ThereIsTail;
+ bool UnexpecedEnd;
+ bool IgnoreTail; // all are zeros
+ // bool NonZerosTail;
+ bool ErrorFlags_Defined;
+ UInt32 ErrorFlags;
+ UInt32 WarningFlags;
+ int ErrorFormatIndex; // - 1 means no Error.
+ // if FormatIndex == ErrorFormatIndex, the archive is open with offset
+ UInt64 TailSize;
+
+ /* if CArc is Open OK with some format:
+ - ErrorFormatIndex shows error format index, if extension is incorrect
+ - other variables show message and warnings of archive that is open */
+
+ UString ErrorMessage;
+ UString WarningMessage;
+
+ // call IsArc_After_NonOpen only if Open returns S_FALSE
+ bool IsArc_After_NonOpen() const
+ {
+ return (ErrorFlags_Defined && (ErrorFlags & kpv_ErrorFlags_IsNotArc) == 0);
+ }
+
+
+ CArcErrorInfo():
+ ThereIsTail(false),
+ UnexpecedEnd(false),
+ IgnoreTail(false),
+ // NonZerosTail(false),
+ ErrorFlags_Defined(false),
+ ErrorFlags(0),
+ WarningFlags(0),
+ ErrorFormatIndex(-1),
+ TailSize(0)
+ {}
+
+ void ClearErrors();
+
+ void ClearErrors_Full()
+ {
+ ErrorFormatIndex = -1;
+ ClearErrors();
+ }
+
+ bool IsThereErrorOrWarning() const
+ {
+ return ErrorFlags != 0
+ || WarningFlags != 0
+ || NeedTailWarning()
+ || UnexpecedEnd
+ || !ErrorMessage.IsEmpty()
+ || !WarningMessage.IsEmpty();
+ }
+
+ bool AreThereErrors() const { return ErrorFlags != 0 || UnexpecedEnd; }
+ bool AreThereWarnings() const { return WarningFlags != 0 || NeedTailWarning(); }
+
+ bool NeedTailWarning() const { return !IgnoreTail && ThereIsTail; }
+
+ UInt32 GetWarningFlags() const
+ {
+ UInt32 a = WarningFlags;
+ if (NeedTailWarning() && (ErrorFlags & kpv_ErrorFlags_DataAfterEnd) == 0)
+ a |= kpv_ErrorFlags_DataAfterEnd;
+ return a;
+ }
+
+ UInt32 GetErrorFlags() const
+ {
+ UInt32 a = ErrorFlags;
+ if (UnexpecedEnd)
+ a |= kpv_ErrorFlags_UnexpectedEnd;
+ return a;
+ }
+};
+
+struct CReadArcItem
+{
+ UString Path; // Path from root (including alt stream name, if alt stream)
+ UStringVector PathParts; // without altStream name, path from root or from _baseParentFolder, if _use_baseParentFolder_mode
+
+ #ifdef SUPPORT_ALT_STREAMS
+ UString MainPath;
+ /* MainPath = Path for non-AltStream,
+ MainPath = Path of parent, if there is parent for AltStream. */
+ UString AltStreamName;
+ bool IsAltStream;
+ bool WriteToAltStreamIfColon;
+ #endif
+
+ bool IsDir;
+ bool MainIsDir;
+ UInt32 ParentIndex; // use it, if IsAltStream
+
+ #ifndef _SFX
+ bool _use_baseParentFolder_mode;
+ int _baseParentFolder;
+ #endif
+
+ CReadArcItem()
+ {
+ #ifdef SUPPORT_ALT_STREAMS
+ WriteToAltStreamIfColon = false;
+ #endif
+
+ #ifndef _SFX
+ _use_baseParentFolder_mode = false;
+ _baseParentFolder = -1;
+ #endif
+ }
+};
+
+class CArc
+{
+ HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive);
+ HRESULT CheckZerosTail(const COpenOptions &op, UInt64 offset);
+ HRESULT OpenStream2(const COpenOptions &options);
+
+ #ifndef _SFX
+ // parts.Back() can contain alt stream name "nams:AltName"
+ HRESULT GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const;
+ #endif
+
+public:
CMyComPtr<IInArchive> Archive;
+ CMyComPtr<IInStream> InStream;
+ // we use InStream in 2 cases (ArcStreamOffset != 0):
+ // 1) if we use additional cache stream
+ // 2) we reopen sfx archive with CTailInStream
+
+ CMyComPtr<IArchiveGetRawProps> GetRawProps;
+ CMyComPtr<IArchiveGetRootProps> GetRootProps;
+
+ CArcErrorInfo ErrorInfo; // for OK archives
+ CArcErrorInfo NonOpen_ErrorInfo; // ErrorInfo for mainArchive (false OPEN)
+
UString Path;
+ UString filePath;
UString DefaultName;
- int FormatIndex;
+ int FormatIndex; // - 1 means Parser.
int SubfileIndex;
FILETIME MTime;
bool MTimeDefined;
- UString ErrorMessage;
+
+ Int64 Offset; // it's offset of start of archive inside stream that is open by Archive Handler
+ UInt64 PhySize;
+ // UInt64 OkPhySize;
+ bool PhySizeDefined;
+ // bool OkPhySize_Defined;
+ UInt64 FileSize;
+ UInt64 AvailPhySize; // PhySize, but it's reduced if exceed end of file
+ // bool offsetDefined;
+
+ UInt64 GetEstmatedPhySize() const { return PhySizeDefined ? PhySize : FileSize; }
+
+ UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler
+ Int64 GetGlobalOffset() const { return ArcStreamOffset + Offset; } // it's global offset of archive
+
+ // AString ErrorFlagsText;
+
+ bool IsParseArc;
+
+ bool IsTree;
+ bool IsReadOnly;
+
+ bool Ask_Deleted;
+ bool Ask_AltStream;
+ bool Ask_Aux;
+ bool Ask_INode;
+
+ bool IgnoreSplit; // don't try split handler
+
+ // void Set_ErrorFlagsText();
+
+ CArc():
+ MTimeDefined(false),
+ IsTree(false),
+ IsReadOnly(false),
+ Ask_Deleted(false),
+ Ask_AltStream(false),
+ Ask_Aux(false),
+ Ask_INode(false),
+ IgnoreSplit(false)
+ {}
+
+ HRESULT ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes);
+
+ // ~CArc();
- CArc(): MTimeDefined(false) {}
+ HRESULT Close()
+ {
+ InStream.Release();
+ return Archive->Close();
+ }
HRESULT GetItemPath(UInt32 index, UString &result) const;
+ HRESULT GetDefaultItemPath(UInt32 index, UString &result) const;
+
+ // GetItemPath2 adds [DELETED] dir prefix for deleted items.
+ HRESULT GetItemPath2(UInt32 index, UString &result) const;
+
+ HRESULT GetItem(UInt32 index, CReadArcItem &item) const;
+
HRESULT GetItemSize(UInt32 index, UInt64 &size, bool &defined) const;
HRESULT GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const;
HRESULT IsItemAnti(UInt32 index, bool &result) const
- { return GetArchiveItemBoolProp(Archive, index, kpidIsAnti, result); }
-
- HRESULT OpenStream(
- CCodecs *codecs,
- int formatIndex,
- IInStream *stream,
- ISequentialInStream *seqStream,
- IArchiveOpenCallback *callback);
-
- HRESULT OpenStreamOrFile(
- CCodecs *codecs,
- int formatIndex,
- bool stdInMode,
- IInStream *stream,
- IArchiveOpenCallback *callback);
+ { return Archive_GetItemBoolProp(Archive, index, kpidIsAnti, result); }
+
+
+ HRESULT OpenStream(const COpenOptions &options);
+ HRESULT OpenStreamOrFile(COpenOptions &options);
+
+ HRESULT ReOpen(const COpenOptions &options);
+
+ HRESULT CreateNewTailStream(CMyComPtr<IInStream> &stream);
};
struct CArchiveLink
@@ -56,33 +370,40 @@ struct CArchiveLink
UInt64 VolumesSize;
bool IsOpen;
- CArchiveLink(): VolumesSize(0), IsOpen(false) {}
+ bool PasswordWasAsked;
+ // UString Password;
+
+ // int NonOpenErrorFormatIndex; // - 1 means no Error.
+ UString NonOpen_ArcPath;
+
+ CArcErrorInfo NonOpen_ErrorInfo;
+
+ // UString ErrorsText;
+ // void Set_ErrorsText();
+
+ CArchiveLink():
+ VolumesSize(0),
+ IsOpen(false),
+ PasswordWasAsked(false)
+ {}
+
+ void KeepModeForNextOpen();
HRESULT Close();
void Release();
~CArchiveLink() { Release(); }
+ const CArc *GetArc() const { return &Arcs.Back(); }
IInArchive *GetArchive() const { return Arcs.Back().Archive; }
+ IArchiveGetRawProps *GetArchiveGetRawProps() const { return Arcs.Back().GetRawProps; }
+ IArchiveGetRootProps *GetArchiveGetRootProps() const { return Arcs.Back().GetRootProps; }
- HRESULT Open(
- CCodecs *codecs,
- const CIntVector &formatIndices,
- bool stdInMode,
- IInStream *stream,
- const UString &filePath,
- IArchiveOpenCallback *callback);
-
- HRESULT Open2(
- CCodecs *codecs,
- const CIntVector &formatIndices,
- bool stdInMode,
- IInStream *stream,
- const UString &filePath,
- IOpenCallbackUI *callbackUI);
-
- HRESULT ReOpen(
- CCodecs *codecs,
- const UString &filePath,
- IArchiveOpenCallback *callback);
+ HRESULT Open(COpenOptions &options);
+ HRESULT Open2(COpenOptions &options, IOpenCallbackUI *callbackUI);
+ HRESULT Open3(COpenOptions &options, IOpenCallbackUI *callbackUI);
+
+ HRESULT ReOpen(COpenOptions &options);
};
+bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types);
+
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp
index dacaca5f988..dccc08b171e 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp
@@ -2,33 +2,28 @@
#include "StdAfx.h"
-#include "Common/IntToString.h"
+#include "../../../../C/CpuArch.h"
-#include "Windows/FileFind.h"
-#include "Windows/PropVariantConversions.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
+
+#include "../../../Windows/FileIO.h"
+#include "../../../Windows/PropVariantConv.h"
#include "../../PropID.h"
#include "PropIDUtils.h"
-using namespace NWindows;
+#define Get16(x) GetUi16(x)
+#define Get32(x) GetUi32(x)
-void ConvertUInt32ToHex(UInt32 value, wchar_t *s)
-{
- for (int i = 0; i < 8; i++)
- {
- int t = value & 0xF;
- value >>= 4;
- s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10)));
- }
- s[8] = L'\0';
-}
+using namespace NWindows;
-static const char g_WinAttrib[17] = "RHS8DAdNTsrCOnE_";
+static const char g_WinAttribChars[16 + 1] = "RHS8DAdNTsLCOnE_";
/*
0 READONLY
1 HIDDEN
-3 SYSTEM
+2 SYSTEM
4 DIRECTORY
5 ARCHIVE
@@ -46,75 +41,534 @@ static const char g_WinAttrib[17] = "RHS8DAdNTsrCOnE_";
*/
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 : L'-';
+#define MY_ATTR_CHAR(a, n, c) ((a) & (1 << (n))) ? c : '-';
-UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool full)
+static void ConvertPosixAttribToString(char *s, UInt32 a) throw()
{
- switch(propID)
+ s[0] = kPosixTypes[(a >> 12) & 0xF];
+ for (int i = 6; i >= 0; i -= 3)
+ {
+ s[7 - i] = MY_ATTR_CHAR(a, i + 2, 'r');
+ s[8 - i] = MY_ATTR_CHAR(a, i + 1, 'w');
+ s[9 - i] = MY_ATTR_CHAR(a, i + 0, 'x');
+ }
+ if ((a & 0x800) != 0) s[3] = ((a & (1 << 6)) ? 's' : 'S');
+ if ((a & 0x400) != 0) s[6] = ((a & (1 << 3)) ? 's' : 'S');
+ if ((a & 0x200) != 0) s[9] = ((a & (1 << 0)) ? 't' : 'T');
+ s[10] = 0;
+
+ a &= ~(UInt32)0xFFFF;
+ if (a != 0)
+ {
+ s[10] = ' ';
+ ConvertUInt32ToHex8Digits(a, s + 11);
+ }
+}
+
+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;
+
+ // 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
+
+ // if (wa & 0x8000)
+ if ((wa >> 16) != 0)
+ {
+ *s++ = ' ';
+ ConvertPosixAttribToString(s, wa >> 16);
+ }
+}
+
+void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID propID, bool full) throw()
+{
+ *dest = 0;
+
+ if (prop.vt == VT_FILETIME)
+ {
+ FILETIME localFileTime;
+ if ((prop.filetime.dwHighDateTime == 0 &&
+ prop.filetime.dwLowDateTime == 0) ||
+ !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
+ return;
+ ConvertFileTimeToString(localFileTime, dest, true, full);
+ return;
+ }
+
+ switch (propID)
{
- case kpidCTime:
- case kpidATime:
- case kpidMTime:
- {
- if (prop.vt != VT_FILETIME)
- break;
- FILETIME localFileTime;
- if ((prop.filetime.dwHighDateTime == 0 &&
- prop.filetime.dwLowDateTime == 0) ||
- !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
- return UString();
- return ConvertFileTimeToString(localFileTime, true, full);
- }
case kpidCRC:
{
if (prop.vt != VT_UI4)
break;
- wchar_t temp[12];
- ConvertUInt32ToHex(prop.ulVal, temp);
- return temp;
+ ConvertUInt32ToHex8Digits(prop.ulVal, dest);
+ return;
}
case kpidAttrib:
{
if (prop.vt != VT_UI4)
break;
UInt32 a = prop.ulVal;
- wchar_t sz[32];
- int pos = 0;
- for (int i = 0; i < 16; i++)
- if (a & (1 << i) && i != 7)
- sz[pos++] = g_WinAttrib[i];
- sz[pos] = '\0';
- return sz;
+
+ /*
+ if ((a & 0x8000) && (a & 0x7FFF) == 0)
+ ConvertPosixAttribToString(dest, a >> 16);
+ else
+ */
+ ConvertWinAttribToString(dest, a);
+ return;
}
case kpidPosixAttrib:
{
if (prop.vt != VT_UI4)
break;
- UString res;
- UInt32 a = prop.ulVal;
- wchar_t temp[16];
+ ConvertPosixAttribToString(dest, prop.ulVal);
+ return;
+ }
+ case kpidINode:
+ {
+ if (prop.vt != VT_UI8)
+ break;
+ ConvertUInt32ToString((UInt32)(prop.uhVal.QuadPart >> 48), dest);
+ dest += strlen(dest);
+ *dest++ = '-';
+ UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1);
+ ConvertUInt64ToString(low, dest);
+ return;
+ }
+ case kpidVa:
+ {
+ UInt64 v = 0;
+ if (prop.vt == VT_UI4)
+ v = prop.ulVal;
+ else if (prop.vt == VT_UI8)
+ v = (UInt64)prop.uhVal.QuadPart;
+ else
+ break;
+ dest[0] = '0';
+ dest[1] = 'x';
+ ConvertUInt64ToHex(v, dest + 2);
+ return;
+ }
+ }
+
+ ConvertPropVariantToShortString(prop, dest);
+}
- temp[0] = kPosixTypes[(a >> 12) & 0xF];
- for (int i = 6; i >= 0; i -= 3)
- {
- temp[7 - i] = MY_ATTR_CHAR(a, i + 2, L'r');
- temp[8 - i] = MY_ATTR_CHAR(a, i + 1, L'w');
- temp[9 - i] = MY_ATTR_CHAR(a, i + 0, L'x');
- }
- if ((a & 0x800) != 0) temp[3] = ((a & (1 << 6)) ? 's' : 'S');
- if ((a & 0x400) != 0) temp[6] = ((a & (1 << 3)) ? 's' : 'S');
- if ((a & 0x200) != 0) temp[9] = ((a & (1 << 0)) ? 't' : 'T');
- temp[10] = 0;
- res = temp;
-
- a &= ~(UInt32)0xFFFF;
- if (a != 0)
+void ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID propID, bool full)
+{
+ if (prop.vt == VT_BSTR)
+ {
+ dest.SetFromBstr(prop.bstrVal);
+ return;
+ }
+ char temp[64];
+ ConvertPropertyToShortString(temp, prop, propID, full);
+ dest.SetFromAscii(temp);
+}
+
+static inline unsigned GetHex(unsigned v)
+{
+ return (v < 10) ? ('0' + v) : ('A' + (v - 10));
+}
+
+#ifndef _SFX
+
+static inline void AddHexToString(AString &res, unsigned v)
+{
+ res += (char)GetHex(v >> 4);
+ res += (char)GetHex(v & 0xF);
+ res += ' ';
+}
+
+/*
+static AString Data_To_Hex(const Byte *data, size_t size)
+{
+ AString s;
+ for (size_t i = 0; i < size; i++)
+ AddHexToString(s, data[i]);
+ return s;
+}
+*/
+
+static const char * const sidNames[] =
+{
+ "0"
+ , "Dialup"
+ , "Network"
+ , "Batch"
+ , "Interactive"
+ , "Logon" // S-1-5-5-X-Y
+ , "Service"
+ , "Anonymous"
+ , "Proxy"
+ , "EnterpriseDC"
+ , "Self"
+ , "AuthenticatedUsers"
+ , "RestrictedCode"
+ , "TerminalServer"
+ , "RemoteInteractiveLogon"
+ , "ThisOrganization"
+ , "16"
+ , "IUserIIS"
+ , "LocalSystem"
+ , "LocalService"
+ , "NetworkService"
+ , "Domains"
+};
+
+struct CSecID2Name
+{
+ UInt32 n;
+ const char *sz;
+};
+
+static const CSecID2Name sid_32_Names[] =
+{
+ { 544, "Administrators" },
+ { 545, "Users" },
+ { 546, "Guests" },
+ { 547, "PowerUsers" },
+ { 548, "AccountOperators" },
+ { 549, "ServerOperators" },
+ { 550, "PrintOperators" },
+ { 551, "BackupOperators" },
+ { 552, "Replicators" },
+ { 553, "Backup Operators" },
+ { 554, "PreWindows2000CompatibleAccess" },
+ { 555, "RemoteDesktopUsers" },
+ { 556, "NetworkConfigurationOperators" },
+ { 557, "IncomingForestTrustBuilders" },
+ { 558, "PerformanceMonitorUsers" },
+ { 559, "PerformanceLogUsers" },
+ { 560, "WindowsAuthorizationAccessGroup" },
+ { 561, "TerminalServerLicenseServers" },
+ { 562, "DistributedCOMUsers" },
+ { 569, "CryptographicOperators" },
+ { 573, "EventLogReaders" },
+ { 574, "CertificateServiceDCOMAccess" }
+};
+
+static const CSecID2Name sid_21_Names[] =
+{
+ { 500, "Administrator" },
+ { 501, "Guest" },
+ { 502, "KRBTGT" },
+ { 512, "DomainAdmins" },
+ { 513, "DomainUsers" },
+ { 515, "DomainComputers" },
+ { 516, "DomainControllers" },
+ { 517, "CertPublishers" },
+ { 518, "SchemaAdmins" },
+ { 519, "EnterpriseAdmins" },
+ { 520, "GroupPolicyCreatorOwners" },
+ { 553, "RASandIASServers" },
+ { 553, "RASandIASServers" },
+ { 571, "AllowedRODCPasswordReplicationGroup" },
+ { 572, "DeniedRODCPasswordReplicationGroup" }
+};
+
+struct CServicesToName
+{
+ UInt32 n[5];
+ const char *sz;
+};
+
+static const CServicesToName services_to_name[] =
+{
+ { { 0x38FB89B5, 0xCBC28419, 0x6D236C5C, 0x6E770057, 0x876402C0 } , "TrustedInstaller" }
+};
+
+static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
+{
+ sidSize = 0;
+ if (lim < 8)
+ {
+ s += "ERROR";
+ return;
+ }
+ UInt32 rev = p[0];
+ if (rev != 1)
+ {
+ s += "UNSUPPORTED";
+ return;
+ }
+ UInt32 num = p[1];
+ if (8 + num * 4 > lim)
+ {
+ s += "ERROR";
+ return;
+ }
+ sidSize = 8 + num * 4;
+ UInt32 authority = GetBe32(p + 4);
+
+ if (p[2] == 0 && p[3] == 0 && authority == 5 && num >= 1)
+ {
+ UInt32 v0 = Get32(p + 8);
+ if (v0 < ARRAY_SIZE(sidNames))
+ {
+ s += sidNames[v0];
+ return;
+ }
+ 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;
+ }
+ }
+ 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;
+ }
+ }
+ if (v0 == 80 && num == 6)
+ {
+ for (unsigned i = 0; i < ARRAY_SIZE(services_to_name); i++)
{
- ConvertUInt32ToHex(a, temp);
- res = UString(temp) + L' ' + res;
+ const CServicesToName &sn = services_to_name[i];
+ int j;
+ for (j = 0; j < 5 && sn.n[j] == Get32(p + 8 + 4 + j * 4); j++);
+ if (j == 5)
+ {
+ s += sn.sz;
+ return;
+ }
}
- return res;
}
}
- return ConvertPropVariantToString(prop);
+
+ char sz[16];
+ s += "S-1-";
+ if (p[2] == 0 && p[3] == 0)
+ {
+ ConvertUInt32ToString(authority, sz);
+ s += sz;
+ }
+ else
+ {
+ s += "0x";
+ for (int i = 2; i < 8; i++)
+ AddHexToString(s, p[i]);
+ }
+ for (UInt32 i = 0; i < num; i++)
+ {
+ s += '-';
+ ConvertUInt32ToString(Get32(p + 8 + i * 4), sz);
+ s += sz;
+ }
}
+
+static void ParseOwner(AString &s, const Byte *p, UInt32 size, UInt32 pos)
+{
+ if (pos > size)
+ {
+ s += "ERROR";
+ return;
+ }
+ UInt32 sidSize = 0;
+ 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 += strName;
+ if (pos >= size)
+ return;
+ p += pos;
+ size -= pos;
+ if (size < 8)
+ return;
+ if (Get16(p) != 2) // revision
+ return;
+ UInt32 num = Get32(p + 4);
+ AddUInt32ToString(s, num);
+
+ /*
+ UInt32 aclSize = Get16(p + 2);
+ if (num >= (1 << 16))
+ return;
+ if (aclSize > size)
+ return;
+ size = aclSize;
+ size -= 8;
+ p += 8;
+ for (UInt32 i = 0 ; i < num; i++)
+ {
+ if (size <= 8)
+ return;
+ // Byte type = p[0];
+ // Byte flags = p[1];
+ // UInt32 aceSize = Get16(p + 2);
+ // UInt32 mask = Get32(p + 4);
+ p += 8;
+ size -= 8;
+
+ UInt32 sidSize = 0;
+ s += ' ';
+ ParseSid(s, p, size, sidSize);
+ if (sidSize == 0)
+ return;
+ p += sidSize;
+ size -= sidSize;
+ }
+
+ // the tail can contain zeros. So (size != 0) is not ERROR
+ // if (size != 0) s += " ERROR";
+ */
+}
+
+#define MY_SE_OWNER_DEFAULTED (0x0001)
+#define MY_SE_GROUP_DEFAULTED (0x0002)
+#define MY_SE_DACL_PRESENT (0x0004)
+#define MY_SE_DACL_DEFAULTED (0x0008)
+#define MY_SE_SACL_PRESENT (0x0010)
+#define MY_SE_SACL_DEFAULTED (0x0020)
+#define MY_SE_DACL_AUTO_INHERIT_REQ (0x0100)
+#define MY_SE_SACL_AUTO_INHERIT_REQ (0x0200)
+#define MY_SE_DACL_AUTO_INHERITED (0x0400)
+#define MY_SE_SACL_AUTO_INHERITED (0x0800)
+#define MY_SE_DACL_PROTECTED (0x1000)
+#define MY_SE_SACL_PROTECTED (0x2000)
+#define MY_SE_RM_CONTROL_VALID (0x4000)
+#define MY_SE_SELF_RELATIVE (0x8000)
+
+void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s)
+{
+ s.Empty();
+ if (size < 20 || size > (1 << 18))
+ {
+ s += "ERROR";
+ return;
+ }
+ if (Get16(data) != 1) // revision
+ {
+ s += "UNSUPPORTED";
+ return;
+ }
+ ParseOwner(s, data, size, Get32(data + 4));
+ s += ' ';
+ 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 += '\n';
+ // s += Data_To_Hex(data, size);
+}
+
+#ifdef _WIN32
+
+static bool CheckSid(const Byte *data, UInt32 size, UInt32 pos) throw()
+{
+ if (pos >= size)
+ return false;
+ size -= pos;
+ if (size < 8)
+ return false;
+ UInt32 rev = data[pos];
+ if (rev != 1)
+ return false;
+ UInt32 num = data[pos + 1];
+ return (8 + num * 4 <= size);
+}
+
+static bool CheckAcl(const Byte *p, UInt32 size, UInt32 flags, UInt32 offset) throw()
+{
+ UInt32 control = Get16(p + 2);
+ if ((flags & control) == 0)
+ return true;
+ UInt32 pos = Get32(p + offset);
+ if (pos >= size)
+ return false;
+ p += pos;
+ size -= pos;
+ if (size < 8)
+ return false;
+ UInt32 aclSize = Get16(p + 2);
+ return (aclSize <= size);
+}
+
+bool CheckNtSecure(const Byte *data, UInt32 size) throw()
+{
+ if (size < 20)
+ return false;
+ if (Get16(data) != 1) // revision
+ return true; // windows function can handle such error, so we allow it
+ if (size > (1 << 18))
+ return false;
+ if (!CheckSid(data, size, Get32(data + 4))) return false;
+ if (!CheckSid(data, size, Get32(data + 8))) return false;
+ if (!CheckAcl(data, size, MY_SE_SACL_PRESENT, 12)) return false;
+ if (!CheckAcl(data, size, MY_SE_DACL_PRESENT, 16)) return false;
+ return true;
+}
+
+#endif
+
+bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
+{
+ s.Empty();
+ NFile::CReparseAttr attr;
+ if (attr.Parse(data, size))
+ {
+ if (!attr.IsSymLink())
+ s.AddAscii("Junction: ");
+ s += attr.GetPath();
+ if (!attr.IsOkNamePair())
+ {
+ s.AddAscii(" : ");
+ s += attr.PrintName;
+ }
+ return true;
+ }
+
+ if (size < 8)
+ return false;
+ UInt32 tag = Get32(data);
+ UInt32 len = Get16(data + 4);
+ if (len + 8 > size)
+ return false;
+ if (Get16(data + 6) != 0) // padding
+ return false;
+
+ char hex[16];
+ ConvertUInt32ToHex8Digits(tag, hex);
+ s.AddAscii(hex);
+ s.Add_Space();
+
+ data += 8;
+
+ for (UInt32 i = 0; i < len; i++)
+ {
+ unsigned b = ((const Byte *)data)[i];
+ s += (wchar_t)GetHex((b >> 4) & 0xF);
+ s += (wchar_t)GetHex(b & 0xF);
+ }
+ return true;
+}
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.h b/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.h
index ca14d091da3..1dea321e9ac 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.h
@@ -3,10 +3,16 @@
#ifndef __PROPID_UTILS_H
#define __PROPID_UTILS_H
-#include "Common/MyString.h"
-#include "Common/Types.h"
+#include "../../../Common/MyString.h"
-void ConvertUInt32ToHex(UInt32 value, wchar_t *s);
-UString ConvertPropertyToString(const PROPVARIANT &propVariant, PROPID propID, bool full = true);
+// 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);
+
+bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s);
+void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s);
+bool CheckNtSecure(const Byte *data, UInt32 size) throw();;
+
+void ConvertWinAttribToString(char *s, UInt32 wa) throw();
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.cpp
index ac9b59a381d..c3de5d5a323 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.cpp
@@ -2,25 +2,26 @@
#include "StdAfx.h"
-#include "SetProperties.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Common/MyString.h"
+#include "../../../Common/StringToInt.h"
-#include "Windows/PropVariant.h"
-#include "Common/MyString.h"
-#include "Common/StringToInt.h"
-#include "Common/MyCom.h"
+#include "../../../Windows/PropVariant.h"
#include "../../Archive/IArchive.h"
+#include "SetProperties.h"
+
using namespace NWindows;
using namespace NCOM;
static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
{
- const wchar_t *endPtr;
- UInt64 result = ConvertStringToUInt64(s, &endPtr);
- if (endPtr - (const wchar_t *)s != s.Length())
+ const wchar_t *end;
+ UInt64 result = ConvertStringToUInt64(s, &end);
+ if (*end != 0 || s.IsEmpty())
prop = s;
- else if (result <= 0xFFFFFFFF)
+ else if (result <= (UInt32)0xFFFFFFFF)
prop = (UInt32)result;
else
prop = result;
@@ -39,8 +40,8 @@ HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &propert
CPropVariant *values = new CPropVariant[properties.Size()];
try
{
- int i;
- for(i = 0; i < properties.Size(); i++)
+ unsigned i;
+ for (i = 0; i < properties.Size(); i++)
{
const CProperty &property = properties[i];
NCOM::CPropVariant propVariant;
@@ -64,7 +65,7 @@ HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &propert
values[i] = propVariant;
}
CRecordVector<const wchar_t *> names;
- for(i = 0; i < realNames.Size(); i++)
+ for (i = 0; i < realNames.Size(); i++)
names.Add((const wchar_t *)realNames[i]);
RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.cpp
index 061e7773079..5f29249bdeb 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.cpp
@@ -2,21 +2,24 @@
#include "StdAfx.h"
+#include "../../../Common/Wildcard.h"
+
#include "SortUtils.h"
-#include "Common/Wildcard.h"
-static int CompareStrings(const int *p1, const int *p2, void *param)
+static int CompareStrings(const unsigned *p1, const unsigned *p2, void *param)
{
const UStringVector &strings = *(const UStringVector *)param;
return CompareFileNames(strings[*p1], strings[*p2]);
}
-void SortFileNames(const UStringVector &strings, CIntVector &indices)
+void SortFileNames(const UStringVector &strings, CUIntVector &indices)
{
- indices.Clear();
- int numItems = strings.Size();
- indices.Reserve(numItems);
- for(int i = 0; i < numItems; i++)
- indices.Add(i);
+ const unsigned numItems = strings.Size();
+ indices.ClearAndSetSize(numItems);
+ if (numItems == 0)
+ return;
+ unsigned *vals = &indices[0];
+ for (unsigned i = 0; i < numItems; i++)
+ vals[i] = i;
indices.Sort(CompareStrings, (void *)&strings);
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.h b/3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.h
index e15224611b7..8e42e06827a 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.h
@@ -1,10 +1,10 @@
// SortUtils.h
-#ifndef __SORTUTLS_H
-#define __SORTUTLS_H
+#ifndef __SORT_UTLS_H
+#define __SORT_UTLS_H
-#include "Common/MyString.h"
+#include "../../../Common/MyString.h"
-void SortFileNames(const UStringVector &strings, CIntVector &indices);
+void SortFileNames(const UStringVector &strings, CUIntVector &indices);
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/StdAfx.h b/3rdparty/lzma/CPP/7zip/UI/Common/StdAfx.h
index 9a8e7d21a28..2854ff3e935 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/StdAfx.h
@@ -1,9 +1,8 @@
-// stdafx.h
+// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../../Common/MyWindows.h"
-#include "../../../Common/NewHandler.h"
+#include "../../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.cpp
index c799c7bfa4f..2f868381f9b 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.cpp
@@ -2,9 +2,9 @@
#include "StdAfx.h"
-#include "TempFiles.h"
+#include "../../../Windows/FileDir.h"
-#include "Windows/FileDir.h"
+#include "TempFiles.h"
using namespace NWindows;
using namespace NFile;
@@ -13,9 +13,7 @@ void CTempFiles::Clear()
{
while (!Paths.IsEmpty())
{
- NDirectory::DeleteFileAlways(Paths.Back());
+ NDir::DeleteFileAlways(Paths.Back());
Paths.DeleteBack();
}
}
-
-
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.h b/3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.h
index 5dcda5b63ee..4099e655898 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.h
@@ -3,7 +3,7 @@
#ifndef __TEMP_FILES_H
#define __TEMP_FILES_H
-#include "Common/MyString.h"
+#include "../../../Common/MyString.h"
class CTempFiles
{
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp
index e740e8a70f7..2dfb210458d 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp
@@ -4,18 +4,19 @@
#include "Update.h"
-#include "Common/IntToString.h"
-#include "Common/StringConvert.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
-#include "Windows/DLL.h"
-#include "Windows/FileDir.h"
-#include "Windows/FileFind.h"
-#include "Windows/FileName.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
-#include "Windows/Time.h"
+#include "../../../Windows/DLL.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/PropVariantConv.h"
+#include "../../../Windows/TimeUtils.h"
#include "../../Common/FileStreams.h"
+#include "../../Common/LimitedStreams.h"
#include "../../Compress/CopyCoder.h"
@@ -35,22 +36,59 @@ static const char *kUpdateIsNotSupoorted =
using namespace NWindows;
using namespace NCOM;
using namespace NFile;
+using namespace NDir;
using namespace NName;
static CFSTR kTempFolderPrefix = FTEXT("7zE");
+
+void CUpdateErrorInfo::SetFromLastError(const char *message)
+{
+ SystemError = ::GetLastError();
+ Message = message;
+}
+
+HRESULT CUpdateErrorInfo::SetFromLastError(const char *message, const FString &fileName)
+{
+ SetFromLastError(message);
+ FileNames.Add(fileName);
+ return Get_HRESULT_Error();
+}
+
+static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path)
+{
+ NFind::CFileInfo fileInfo;
+ FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
+ {
+ NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK);
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDir())
+ if (!DeleteEmptyFolderAndEmptySubFolders(pathPrefix + fileInfo.Name))
+ return false;
+ }
+ }
+ /*
+ // we don't need clear read-only for folders
+ if (!MySetFileAttributes(path, 0))
+ return false;
+ */
+ return RemoveDir(path);
+}
+
+
using namespace NUpdateArchive;
class COutMultiVolStream:
public IOutStream,
public CMyUnknownImp
{
- int _streamIndex; // required stream
+ unsigned _streamIndex; // required stream
UInt64 _offsetPos; // offset from start of _streamIndex index
UInt64 _absPos;
UInt64 _length;
- struct CSubStreamInfo
+ struct CAltStreamInfo
{
COutFileStream *StreamSpec;
CMyComPtr<IOutStream> Stream;
@@ -58,7 +96,7 @@ class COutMultiVolStream:
UInt64 Pos;
UInt64 RealSize;
};
- CObjectVector<CSubStreamInfo> Streams;
+ CObjectVector<CAltStreamInfo> Streams;
public:
// CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
CRecordVector<UInt64> Sizes;
@@ -73,8 +111,11 @@ public:
_length = 0;
}
+ bool SetMTime(const FILETIME *mTime);
HRESULT Close();
+ UInt64 GetSize() const { return _length; }
+
MY_UNKNOWN_IMP1(IOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
@@ -87,12 +128,12 @@ public:
HRESULT COutMultiVolStream::Close()
{
HRESULT res = S_OK;
- for (int i = 0; i < Streams.Size(); i++)
+ FOR_VECTOR (i, Streams)
{
- CSubStreamInfo &s = Streams[i];
- if (s.StreamSpec)
+ COutFileStream *s = Streams[i].StreamSpec;
+ if (s)
{
- HRESULT res2 = s.StreamSpec->Close();
+ HRESULT res2 = s->Close();
if (res2 != S_OK)
res = res2;
}
@@ -100,6 +141,19 @@ HRESULT COutMultiVolStream::Close()
return res;
}
+bool COutMultiVolStream::SetMTime(const FILETIME *mTime)
+{
+ bool res = true;
+ FOR_VECTOR (i, Streams)
+ {
+ COutFileStream *s = Streams[i].StreamSpec;
+ if (s)
+ if (!s->SetMTime(mTime))
+ res = false;
+ }
+ return res;
+}
+
STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize != NULL)
@@ -108,32 +162,32 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
{
if (_streamIndex >= Streams.Size())
{
- CSubStreamInfo subStream;
+ CAltStreamInfo altStream;
FChar temp[16];
ConvertUInt32ToString(_streamIndex + 1, temp);
- FString res = temp;
- while (res.Length() < 3)
- res = FString(FTEXT('0')) + res;
- FString name = Prefix + res;
- subStream.StreamSpec = new COutFileStream;
- subStream.Stream = subStream.StreamSpec;
- if (!subStream.StreamSpec->Create(name, false))
+ FString name = temp;
+ while (name.Len() < 3)
+ name.InsertAtFront(FTEXT('0'));
+ name.Insert(0, Prefix);
+ altStream.StreamSpec = new COutFileStream;
+ altStream.Stream = altStream.StreamSpec;
+ if (!altStream.StreamSpec->Create(name, false))
return ::GetLastError();
{
// NSynchronization::CCriticalSectionLock lock(g_TempPathsCS);
TempFiles->Paths.Add(name);
}
- subStream.Pos = 0;
- subStream.RealSize = 0;
- subStream.Name = name;
- Streams.Add(subStream);
+ altStream.Pos = 0;
+ altStream.RealSize = 0;
+ altStream.Name = name;
+ Streams.Add(altStream);
continue;
}
- CSubStreamInfo &subStream = Streams[_streamIndex];
+ CAltStreamInfo &altStream = Streams[_streamIndex];
- int index = _streamIndex;
+ unsigned index = _streamIndex;
if (index >= Sizes.Size())
index = Sizes.Size() - 1;
UInt64 volSize = Sizes[index];
@@ -144,29 +198,29 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
_streamIndex++;
continue;
}
- if (_offsetPos != subStream.Pos)
+ if (_offsetPos != altStream.Pos)
{
// CMyComPtr<IOutStream> outStream;
- // RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
- RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
- subStream.Pos = _offsetPos;
+ // RINOK(altStream.Stream.QueryInterface(IID_IOutStream, &outStream));
+ RINOK(altStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
+ altStream.Pos = _offsetPos;
}
- UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos);
+ UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - altStream.Pos);
UInt32 realProcessed;
- RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
+ RINOK(altStream.Stream->Write(data, curSize, &realProcessed));
data = (void *)((Byte *)data + realProcessed);
size -= realProcessed;
- subStream.Pos += realProcessed;
+ altStream.Pos += realProcessed;
_offsetPos += realProcessed;
_absPos += realProcessed;
if (_absPos > _length)
_length = _absPos;
- if (_offsetPos > subStream.RealSize)
- subStream.RealSize = _offsetPos;
+ if (_offsetPos > altStream.RealSize)
+ altStream.RealSize = _offsetPos;
if (processedSize != NULL)
*processedSize += realProcessed;
- if (subStream.Pos == volSize)
+ if (altStream.Pos == volSize)
{
_streamIndex++;
_offsetPos = 0;
@@ -182,17 +236,11 @@ STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *n
{
if (seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET:
- _absPos = offset;
- break;
- case STREAM_SEEK_CUR:
- _absPos += offset;
- break;
- case STREAM_SEEK_END:
- _absPos = _length + offset;
- break;
+ case STREAM_SEEK_SET: _absPos = offset; break;
+ case STREAM_SEEK_CUR: _absPos += offset; break;
+ case STREAM_SEEK_END: _absPos = _length + offset; break;
}
_offsetPos = _absPos;
if (newPosition != NULL)
@@ -205,24 +253,24 @@ STDMETHODIMP COutMultiVolStream::SetSize(UInt64 newSize)
{
if (newSize < 0)
return E_INVALIDARG;
- int i = 0;
+ unsigned i = 0;
while (i < Streams.Size())
{
- CSubStreamInfo &subStream = Streams[i++];
- if ((UInt64)newSize < subStream.RealSize)
+ CAltStreamInfo &altStream = Streams[i++];
+ if ((UInt64)newSize < altStream.RealSize)
{
- RINOK(subStream.Stream->SetSize(newSize));
- subStream.RealSize = newSize;
+ RINOK(altStream.Stream->SetSize(newSize));
+ altStream.RealSize = newSize;
break;
}
- newSize -= subStream.RealSize;
+ newSize -= altStream.RealSize;
}
while (i < Streams.Size())
{
{
- CSubStreamInfo &subStream = Streams.Back();
- subStream.Stream.Release();
- NDirectory::DeleteFileAlways(subStream.Name);
+ CAltStreamInfo &altStream = Streams.Back();
+ altStream.Stream.Release();
+ DeleteFileAlways(altStream.Name);
}
Streams.DeleteBack();
}
@@ -232,53 +280,140 @@ STDMETHODIMP COutMultiVolStream::SetSize(UInt64 newSize)
return S_OK;
}
-static const wchar_t *kDefaultArchiveType = L"7z";
-static const wchar_t *kSFXExtension =
+void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode)
+{
+ OriginalPath = path;
+
+ SplitPathToParts_2(path, Prefix, Name);
+
+ if (mode == k_ArcNameMode_Add)
+ return;
+ if (mode == k_ArcNameMode_Exact)
+ {
+ BaseExtension.Empty();
+ return;
+ }
+
+ int dotPos = Name.ReverseFind_Dot();
+ if (dotPos < 0)
+ return;
+ if ((unsigned)dotPos == Name.Len() - 1)
+ {
+ Name.DeleteBack();
+ BaseExtension.Empty();
+ return;
+ }
+ const UString ext = Name.Ptr(dotPos + 1);
+ if (BaseExtension.IsEqualTo_NoCase(ext))
+ {
+ BaseExtension = ext;
+ Name.DeleteFrom(dotPos);
+ }
+ else
+ BaseExtension.Empty();
+}
+
+UString CArchivePath::GetFinalPath() const
+{
+ UString path = GetPathWithoutExt();
+ if (!BaseExtension.IsEmpty())
+ {
+ path += L'.';
+ path += BaseExtension;
+ }
+ return path;
+}
+
+UString CArchivePath::GetFinalVolPath() const
+{
+ UString path = GetPathWithoutExt();
+ if (!BaseExtension.IsEmpty())
+ {
+ path += L'.';
+ path += VolExtension;
+ }
+ return path;
+}
+
+FString CArchivePath::GetTempPath() const
+{
+ FString path = TempPrefix;
+ path += us2fs(Name);
+ if (!BaseExtension.IsEmpty())
+ {
+ path += FTEXT('.');
+ path += us2fs(BaseExtension);
+ }
+ path.AddAscii(".tmp");
+ path += TempPostfix;
+ return path;
+}
+
+static const wchar_t *kDefaultArcType = L"7z";
+static const wchar_t *kDefaultArcExt = L"7z";
+static const char *kSFXExtension =
#ifdef _WIN32
- L"exe";
+ "exe";
#else
- L"";
+ "";
#endif
-bool CUpdateOptions::Init(const CCodecs *codecs, const CIntVector &formatIndices, const UString &arcPath)
+bool CUpdateOptions::InitFormatIndex(const CCodecs *codecs,
+ const CObjectVector<COpenType> &types, const UString &arcPath)
{
- if (formatIndices.Size() > 1)
+ if (types.Size() > 1)
return false;
- int arcTypeIndex = -1;
- if (formatIndices.Size() != 0)
- arcTypeIndex = formatIndices[0];
- if (arcTypeIndex >= 0)
- MethodMode.FormatIndex = arcTypeIndex;
+ // int arcTypeIndex = -1;
+ if (types.Size() != 0)
+ {
+ MethodMode.Type = types[0];
+ MethodMode.Type_Defined = true;
+ }
+ if (MethodMode.Type.FormatIndex < 0)
+ {
+ // MethodMode.Type = -1;
+ MethodMode.Type = COpenType();
+ if (ArcNameMode != k_ArcNameMode_Add)
+ {
+ MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveName(arcPath);
+ if (MethodMode.Type.FormatIndex >= 0)
+ MethodMode.Type_Defined = true;
+ }
+ }
+ return true;
+}
+
+bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath)
+{
+ UString typeExt;
+ int formatIndex = MethodMode.Type.FormatIndex;
+ if (formatIndex < 0)
+ {
+ typeExt = kDefaultArcExt;
+ }
else
{
- MethodMode.FormatIndex = codecs->FindFormatForArchiveName(arcPath);
- // It works incorrectly for update command if archive has some non-default extension!
- if (MethodMode.FormatIndex < 0)
- MethodMode.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArchiveType);
+ const CArcInfoEx &arcInfo = codecs->Formats[formatIndex];
+ if (!arcInfo.UpdateEnabled)
+ return false;
+ typeExt = arcInfo.GetMainExt();
}
- if (MethodMode.FormatIndex < 0)
- return false;
- const CArcInfoEx &arcInfo = codecs->Formats[MethodMode.FormatIndex];
- if (!arcInfo.UpdateEnabled)
- return false;
- UString typeExt = arcInfo.GetMainExt();
UString ext = typeExt;
if (SfxMode)
- ext = kSFXExtension;
+ ext.SetFromAscii(kSFXExtension);
ArchivePath.BaseExtension = ext;
ArchivePath.VolExtension = typeExt;
- ArchivePath.ParseFromPath(arcPath);
- for (int i = 0; i < Commands.Size(); i++)
+ ArchivePath.ParseFromPath(arcPath, ArcNameMode);
+ FOR_VECTOR (i, Commands)
{
CUpdateArchiveCommand &uc = Commands[i];
uc.ArchivePath.BaseExtension = ext;
uc.ArchivePath.VolExtension = typeExt;
- uc.ArchivePath.ParseFromPath(uc.UserArchivePath);
+ uc.ArchivePath.ParseFromPath(uc.UserArchivePath, ArcNameMode);
}
return true;
}
-/*
struct CUpdateProduceCallbackImp: public IUpdateProduceCallback
{
const CObjectVector<CArcItem> *_arcItems;
@@ -286,45 +421,104 @@ struct CUpdateProduceCallbackImp: public IUpdateProduceCallback
CUpdateProduceCallbackImp(const CObjectVector<CArcItem> *a,
IUpdateCallbackUI *callback): _arcItems(a), _callback(callback) {}
- virtual HRESULT ShowDeleteFile(int arcIndex);
+ virtual HRESULT ShowDeleteFile(unsigned arcIndex);
};
-HRESULT CUpdateProduceCallbackImp::ShowDeleteFile(int arcIndex)
+HRESULT CUpdateProduceCallbackImp::ShowDeleteFile(unsigned arcIndex)
+{
+ const CArcItem &ai = (*_arcItems)[arcIndex];
+ return _callback->ShowDeleteFile(ai.Name, ai.IsDir);
+}
+
+bool CRenamePair::Prepare()
+{
+ if (RecursedType != NRecursedType::kNonRecursed)
+ return false;
+ if (!WildcardParsing)
+ return true;
+ return !DoesNameContainWildcard(OldName);
+}
+
+extern bool g_CaseSensitive;
+
+static unsigned CompareTwoNames(const wchar_t *s1, const wchar_t *s2)
+{
+ for (unsigned i = 0;; i++)
+ {
+ wchar_t c1 = s1[i];
+ wchar_t c2 = s2[i];
+ if (c1 == 0 || c2 == 0)
+ return i;
+ if (c1 == c2)
+ continue;
+ if (!g_CaseSensitive && (MyCharUpper(c1) == MyCharUpper(c2)))
+ continue;
+ if (IsPathSepar(c1) && IsPathSepar(c2))
+ continue;
+ return i;
+ }
+}
+
+bool CRenamePair::GetNewPath(bool isFolder, const UString &src, UString &dest) const
{
- return _callback->ShowDeleteFile((*_arcItems)[arcIndex].Name);
+ unsigned num = CompareTwoNames(OldName, src);
+ if (OldName[num] == 0)
+ {
+ if (src[num] != 0 && !IsPathSepar(src[num]) && num != 0 && !IsPathSepar(src[num - 1]))
+ return false;
+ }
+ else
+ {
+ // OldName[num] != 0
+ // OldName = "1\1a.txt"
+ // src = "1"
+
+ if (!isFolder
+ || src[num] != 0
+ || !IsPathSepar(OldName[num])
+ || OldName[num + 1] != 0)
+ return false;
+ }
+ dest = NewName + src.Ptr(num);
+ return true;
}
-*/
+
+#ifdef SUPPORT_ALT_STREAMS
+int FindAltStreamColon_in_Path(const wchar_t *path);
+#endif
static HRESULT Compress(
+ const CUpdateOptions &options,
+ bool isUpdatingItself,
CCodecs *codecs,
const CActionSet &actionSet,
- IInArchive *archive,
- const CCompressionMethodMode &compressionMethod,
+ const CArc *arc,
CArchivePath &archivePath,
const CObjectVector<CArcItem> &arcItems,
- bool shareForWrite,
- bool stdInMode,
- /* const UString & stdInFileName, */
- bool stdOutMode,
+ Byte *processedItemsStatuses,
const CDirItems &dirItems,
- bool sfxMode,
- const FString &sfxModule,
- const CRecordVector<UInt64> &volumesSizes,
+ const CDirItem *parentDirItem,
CTempFiles &tempFiles,
CUpdateErrorInfo &errorInfo,
- IUpdateCallbackUI *callback)
+ IUpdateCallbackUI *callback,
+ CFinishArchiveStat &st)
{
CMyComPtr<IOutArchive> outArchive;
- if (archive != NULL)
+ int formatIndex = options.MethodMode.Type.FormatIndex;
+
+ if (arc)
{
- CMyComPtr<IInArchive> archive2 = archive;
+ formatIndex = arc->FormatIndex;
+ if (formatIndex < 0)
+ return E_NOTIMPL;
+ CMyComPtr<IInArchive> archive2 = arc->Archive;
HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive);
if (result != S_OK)
throw kUpdateIsNotSupoorted;
}
else
{
- RINOK(codecs->CreateOutArchive(compressionMethod.FormatIndex, outArchive));
+ RINOK(codecs->CreateOutArchive(formatIndex, outArchive));
#ifdef EXTERNAL_CODECS
{
@@ -337,75 +531,170 @@ static HRESULT Compress(
}
#endif
}
+
if (outArchive == 0)
throw kUpdateIsNotSupoorted;
NFileTimeType::EEnum fileTimeType;
- UInt32 value;
- RINOK(outArchive->GetFileTimeType(&value));
+ {
+ UInt32 value;
+ RINOK(outArchive->GetFileTimeType(&value));
+
+ switch (value)
+ {
+ case NFileTimeType::kWindows:
+ case NFileTimeType::kUnix:
+ case NFileTimeType::kDOS:
+ fileTimeType = (NFileTimeType::EEnum)value;
+ break;
+ default:
+ return E_FAIL;
+ }
+ }
- switch(value)
{
- case NFileTimeType::kWindows:
- case NFileTimeType::kUnix:
- case NFileTimeType::kDOS:
- fileTimeType = (NFileTimeType::EEnum)value;
- break;
- default:
- return E_FAIL;
+ const CArcInfoEx &arcInfo = codecs->Formats[formatIndex];
+ if (options.AltStreams.Val && !arcInfo.Flags_AltStreams())
+ return E_NOTIMPL;
+ if (options.NtSecurity.Val && !arcInfo.Flags_NtSecure())
+ return E_NOTIMPL;
}
CRecordVector<CUpdatePair2> updatePairs2;
+ UStringVector newNames;
+
+ if (options.RenamePairs.Size() != 0)
+ {
+ FOR_VECTOR (i, arcItems)
+ {
+ const CArcItem &ai = arcItems[i];
+ bool needRename = false;
+ UString dest;
+
+ if (ai.Censored)
+ {
+ FOR_VECTOR (j, options.RenamePairs)
+ {
+ const CRenamePair &rp = options.RenamePairs[j];
+ if (rp.GetNewPath(ai.IsDir, ai.Name, dest))
+ {
+ needRename = true;
+ break;
+ }
+
+ #ifdef SUPPORT_ALT_STREAMS
+ if (ai.IsAltStream)
+ {
+ int colonPos = FindAltStreamColon_in_Path(ai.Name);
+ if (colonPos >= 0)
+ {
+ UString mainName = ai.Name.Left(colonPos);
+ /*
+ actually we must improve that code to support cases
+ with folder renaming like: rn arc dir1\ dir2\
+ */
+ if (rp.GetNewPath(false, mainName, dest))
+ {
+ needRename = true;
+ dest += L':';
+ dest += ai.Name.Ptr(colonPos + 1);
+ break;
+ }
+ }
+ }
+ #endif
+ }
+ }
+
+ CUpdatePair2 up2;
+ up2.SetAs_NoChangeArcItem(ai.IndexInServer);
+ if (needRename)
+ {
+ up2.NewProps = true;
+ RINOK(arc->IsItemAnti(i, up2.IsAnti));
+ up2.NewNameIndex = newNames.Add(dest);
+ }
+ updatePairs2.Add(up2);
+ }
+ }
+ else
{
CRecordVector<CUpdatePair> updatePairs;
GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!!
- // CUpdateProduceCallbackImp upCallback(&arcItems, callback);
- UpdateProduce(updatePairs, actionSet, updatePairs2, NULL /* &upCallback */);
+ CUpdateProduceCallbackImp upCallback(&arcItems, callback);
+
+ UpdateProduce(updatePairs, actionSet, updatePairs2, isUpdatingItself ? &upCallback : NULL);
}
- UInt32 numFiles = 0;
- for (int i = 0; i < updatePairs2.Size(); i++)
- if (updatePairs2[i].NewData)
- numFiles++;
-
- RINOK(callback->SetNumFiles(numFiles));
-
+ {
+ UInt32 numItems = 0;
+ FOR_VECTOR (i, updatePairs2)
+ if (updatePairs2[i].NewData)
+ numItems++;
+ RINOK(callback->SetNumItems(numItems));
+ }
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
- updateCallbackSpec->ShareForWrite = shareForWrite;
- updateCallbackSpec->StdInMode = stdInMode;
+ updateCallbackSpec->ShareForWrite = options.OpenShareForWrite;
+ updateCallbackSpec->StdInMode = options.StdInMode;
updateCallbackSpec->Callback = callback;
+
+ if (arc)
+ {
+ // we set Archive to allow to transfer GetProperty requests back to DLL.
+ updateCallbackSpec->Archive = arc->Archive;
+ }
+
updateCallbackSpec->DirItems = &dirItems;
+ updateCallbackSpec->ParentDirItem = parentDirItem;
+
+ updateCallbackSpec->StoreNtSecurity = options.NtSecurity.Val;
+ updateCallbackSpec->StoreHardLinks = options.HardLinks.Val;
+ updateCallbackSpec->StoreSymLinks = options.SymLinks.Val;
+
+ updateCallbackSpec->Arc = arc;
updateCallbackSpec->ArcItems = &arcItems;
updateCallbackSpec->UpdatePairs = &updatePairs2;
+ updateCallbackSpec->ProcessedItemsStatuses = processedItemsStatuses;
+
+ if (options.RenamePairs.Size() != 0)
+ updateCallbackSpec->NewNames = &newNames;
+
+ CMyComPtr<IOutStream> outSeekStream;
CMyComPtr<ISequentialOutStream> outStream;
- if (!stdOutMode)
+ if (!options.StdOutMode)
{
FString dirPrefix;
- if (!NFile::NDirectory::GetOnlyDirPrefix(us2fs(archivePath.GetFinalPath()), dirPrefix))
+ if (!GetOnlyDirPrefix(us2fs(archivePath.GetFinalPath()), dirPrefix))
throw 1417161;
- NFile::NDirectory::CreateComplexDirectory(dirPrefix);
+ CreateComplexDir(dirPrefix);
}
COutFileStream *outStreamSpec = NULL;
+ CStdOutFileStream *stdOutFileStreamSpec = NULL;
COutMultiVolStream *volStreamSpec = NULL;
- if (volumesSizes.Size() == 0)
+ if (options.VolumesSizes.Size() == 0)
{
- if (stdOutMode)
- outStream = new CStdOutFileStream;
+ if (options.StdOutMode)
+ {
+ stdOutFileStreamSpec = new CStdOutFileStream;
+ outStream = stdOutFileStreamSpec;
+ }
else
{
outStreamSpec = new COutFileStream;
- outStream = outStreamSpec;
+ outSeekStream = outStreamSpec;
+ outStream = outSeekStream;
bool isOK = false;
FString realPath;
- for (int i = 0; i < (1 << 16); i++)
+
+ for (unsigned i = 0; i < (1 << 16); i++)
{
if (archivePath.Temp)
{
@@ -430,23 +719,24 @@ static HRESULT Compress(
if (!archivePath.Temp)
break;
}
+
if (!isOK)
- {
- errorInfo.SystemError = ::GetLastError();
- errorInfo.FileName = realPath;
- errorInfo.Message = L"7-Zip cannot open file";
- return E_FAIL;
- }
+ return errorInfo.SetFromLastError("cannot open file", realPath);
}
}
else
{
- if (stdOutMode)
+ if (options.StdOutMode)
return E_FAIL;
+ if (arc && arc->GetGlobalOffset() > 0)
+ return E_NOTIMPL;
+
volStreamSpec = new COutMultiVolStream;
- outStream = volStreamSpec;
- volStreamSpec->Sizes = volumesSizes;
- volStreamSpec->Prefix = us2fs(archivePath.GetFinalPath() + L".");
+ outSeekStream = volStreamSpec;
+ outStream = outSeekStream;
+ volStreamSpec->Sizes = options.VolumesSizes;
+ volStreamSpec->Prefix = us2fs(archivePath.GetFinalVolPath());
+ volStreamSpec->Prefix += FTEXT('.');
volStreamSpec->TempFiles = &tempFiles;
volStreamSpec->Init();
@@ -458,23 +748,18 @@ static HRESULT Compress(
*/
}
- RINOK(SetProperties(outArchive, compressionMethod.Properties));
+ RINOK(SetProperties(outArchive, options.MethodMode.Properties));
- if (sfxMode)
+ if (options.SfxMode)
{
CInFileStream *sfxStreamSpec = new CInFileStream;
CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
- if (!sfxStreamSpec->Open(sfxModule))
- {
- errorInfo.SystemError = ::GetLastError();
- errorInfo.Message = L"7-Zip cannot open SFX module";
- errorInfo.FileName = sfxModule;
- return E_FAIL;
- }
+ if (!sfxStreamSpec->Open(options.SfxModule))
+ return errorInfo.SetFromLastError("cannot open SFX module", options.SfxModule);
CMyComPtr<ISequentialOutStream> sfxOutStream;
COutFileStream *outStreamSpec = NULL;
- if (volumesSizes.Size() == 0)
+ if (options.VolumesSizes.Size() == 0)
sfxOutStream = outStream;
else
{
@@ -482,23 +767,97 @@ static HRESULT Compress(
sfxOutStream = outStreamSpec;
FString realPath = us2fs(archivePath.GetFinalPath());
if (!outStreamSpec->Create(realPath, false))
- {
- errorInfo.SystemError = ::GetLastError();
- errorInfo.FileName = realPath;
- errorInfo.Message = L"7-Zip cannot open file";
- return E_FAIL;
- }
+ return errorInfo.SetFromLastError("cannot open file", realPath);
+ }
+
+ {
+ UInt64 sfxSize;
+ RINOK(sfxStreamSpec->GetSize(&sfxSize));
+ RINOK(callback->WriteSfx(fs2us(options.SfxModule), sfxSize));
}
+
RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL));
+
if (outStreamSpec)
{
RINOK(outStreamSpec->Close());
}
}
- HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(), updateCallback);
- callback->Finilize();
+ CMyComPtr<ISequentialOutStream> tailStream;
+
+ if (options.SfxMode || !arc || arc->ArcStreamOffset == 0)
+ tailStream = outStream;
+ else
+ {
+ // Int64 globalOffset = arc->GetGlobalOffset();
+ RINOK(arc->InStream->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL));
+ if (options.StdOutMode)
+ tailStream = outStream;
+ else
+ {
+ CTailOutStream *tailStreamSpec = new CTailOutStream;
+ tailStream = tailStreamSpec;
+ tailStreamSpec->Stream = outSeekStream;
+ tailStreamSpec->Offset = arc->ArcStreamOffset;
+ tailStreamSpec->Init();
+ }
+ }
+
+
+ HRESULT result = outArchive->UpdateItems(tailStream, updatePairs2.Size(), updateCallback);
+ // callback->Finalize();
RINOK(result);
+
+ if (!updateCallbackSpec->AreAllFilesClosed())
+ {
+ errorInfo.Message = "There are unclosed input file:";
+ errorInfo.FileNames = updateCallbackSpec->_openFiles_Paths;
+ return E_FAIL;
+ }
+
+ if (options.SetArcMTime)
+ {
+ FILETIME ft;
+ ft.dwLowDateTime = 0;
+ ft.dwHighDateTime = 0;
+ FOR_VECTOR (i, updatePairs2)
+ {
+ CUpdatePair2 &pair2 = updatePairs2[i];
+ const FILETIME *ft2 = NULL;
+ if (pair2.NewProps && pair2.DirIndex >= 0)
+ ft2 = &dirItems.Items[pair2.DirIndex].MTime;
+ else if (pair2.UseArcProps && pair2.ArcIndex >= 0)
+ ft2 = &arcItems[pair2.ArcIndex].MTime;
+ if (ft2)
+ {
+ if (::CompareFileTime(&ft, ft2) < 0)
+ ft = *ft2;
+ }
+ }
+ if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0)
+ {
+ if (outStreamSpec)
+ outStreamSpec->SetMTime(&ft);
+ else if (volStreamSpec)
+ volStreamSpec->SetMTime(&ft);;
+ }
+ }
+
+ if (callback)
+ {
+ UInt64 size = 0;
+ if (outStreamSpec)
+ outStreamSpec->GetSize(&size);
+ else if (stdOutFileStreamSpec)
+ size = stdOutFileStreamSpec->GetSize();
+ else
+ size = volStreamSpec->GetSize();
+
+ st.OutArcFileSize = size;
+ }
+
if (outStreamSpec)
result = outStreamSpec->Close();
else if (volStreamSpec)
@@ -506,7 +865,27 @@ static HRESULT Compress(
return result;
}
-HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
+bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include);
+
+static bool Censor_CheckPath(const NWildcard::CCensor &censor, const CReadArcItem &item)
+{
+ bool finded = false;
+ FOR_VECTOR (i, censor.Pairs)
+ {
+ bool include;
+ if (CensorNode_CheckPath2(censor.Pairs[i].Head, item, include))
+ {
+ if (!include)
+ return false;
+ finded = true;
+ }
+ }
+ return finded;
+}
+
+static HRESULT EnumerateInArchiveItems(
+ // bool storeStreamsMode,
+ const NWildcard::CCensor &censor,
const CArc &arc,
CObjectVector<CArcItem> &arcItems)
{
@@ -514,14 +893,30 @@ HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
UInt32 numItems;
IInArchive *archive = arc.Archive;
RINOK(archive->GetNumberOfItems(&numItems));
- arcItems.Reserve(numItems);
+ arcItems.ClearAndReserve(numItems);
+
+ CReadArcItem item;
+
for (UInt32 i = 0; i < numItems; i++)
{
CArcItem ai;
- RINOK(arc.GetItemPath(i, ai.Name));
- RINOK(IsArchiveItemFolder(archive, i, ai.IsDir));
- ai.Censored = censor.CheckPath(ai.Name, !ai.IsDir);
+ RINOK(arc.GetItem(i, item));
+ ai.Name = item.Path;
+ ai.IsDir = item.IsDir;
+ ai.IsAltStream =
+ #ifdef SUPPORT_ALT_STREAMS
+ item.IsAltStream;
+ #else
+ false;
+ #endif
+
+ /*
+ if (!storeStreamsMode && ai.IsAltStream)
+ continue;
+ */
+ ai.Censored = Censor_CheckPath(censor, item);
+
RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined));
RINOK(arc.GetItemSize(i, ai.Size, ai.SizeDefined));
@@ -531,7 +926,7 @@ HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
if (prop.vt == VT_UI4)
{
ai.TimeType = (int)(NFileTimeType::EEnum)prop.ulVal;
- switch(ai.TimeType)
+ switch (ai.TimeType)
{
case NFileTimeType::kWindows:
case NFileTimeType::kUnix:
@@ -544,110 +939,99 @@ HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
}
ai.IndexInServer = i;
- arcItems.Add(ai);
+ arcItems.AddInReserved(ai);
}
return S_OK;
}
+#if defined(_WIN32) && !defined(UNDER_CE)
-static HRESULT UpdateWithItemLists(
- CCodecs *codecs,
- CUpdateOptions &options,
- IInArchive *archive,
- const CObjectVector<CArcItem> &arcItems,
- CDirItems &dirItems,
- CTempFiles &tempFiles,
- CUpdateErrorInfo &errorInfo,
- IUpdateCallbackUI2 *callback)
-{
- for(int i = 0; i < options.Commands.Size(); i++)
- {
- CUpdateArchiveCommand &command = options.Commands[i];
- if (options.StdOutMode)
- {
- RINOK(callback->StartArchive(L"stdout", archive != 0));
- }
- else
- {
- RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(),
- i == 0 && options.UpdateArchiveItself && archive != 0));
- }
+#include <mapi.h>
- RINOK(Compress(
- codecs,
- command.ActionSet, archive,
- options.MethodMode,
- command.ArchivePath,
- arcItems,
- options.OpenShareForWrite,
- options.StdInMode,
- /* options.StdInFileName, */
- options.StdOutMode,
- dirItems,
- options.SfxMode, options.SfxModule,
- options.VolumesSizes,
- tempFiles,
- errorInfo, callback));
-
- RINOK(callback->FinishArchive());
- }
- return S_OK;
-}
+#endif
-#if defined(_WIN32) && !defined(UNDER_CE)
-class CCurrentDirRestorer
+struct CRefSortPair
{
- FString _path;
-public:
- CCurrentDirRestorer() { NFile::NDirectory::MyGetCurrentDirectory(_path); }
- ~CCurrentDirRestorer() { RestoreDirectory();}
- bool RestoreDirectory() const { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(_path)); }
+ unsigned Len;
+ unsigned Index;
};
-#endif
-struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback
+#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)
{
- IUpdateCallbackUI2 *Callback;
- HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path)
+ for (unsigned numSlashes = 0;;)
{
- return Callback->ScanProgress(numFolders, numFiles, path);
+ FChar c = *s++;
+ if (c == 0)
+ return numSlashes;
+ if (IS_PATH_SEPAR(c))
+ numSlashes++;
}
-};
+}
#ifdef _WIN32
-typedef ULONG (FAR PASCAL MY_MAPISENDDOCUMENTS)(
- ULONG_PTR ulUIParam,
- LPSTR lpszDelimChar,
- LPSTR lpszFilePaths,
- LPSTR lpszFileNames,
- ULONG ulReserved
-);
-typedef MY_MAPISENDDOCUMENTS FAR *MY_LPMAPISENDDOCUMENTS;
+void ConvertToLongNames(NWildcard::CCensor &censor);
#endif
HRESULT UpdateArchive(
CCodecs *codecs,
- const NWildcard::CCensor &censor,
+ const CObjectVector<COpenType> &types,
+ const UString &cmdArcPath2,
+ NWildcard::CCensor &censor,
CUpdateOptions &options,
CUpdateErrorInfo &errorInfo,
IOpenCallbackUI *openCallback,
- IUpdateCallbackUI2 *callback)
+ IUpdateCallbackUI2 *callback,
+ bool needSetPath)
{
if (options.StdOutMode && options.EMailMode)
return E_FAIL;
- if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode))
+ if (types.Size() > 1)
+ return E_NOTIMPL;
+
+ bool renameMode = !options.RenamePairs.IsEmpty();
+ if (renameMode)
+ {
+ if (options.Commands.Size() != 1)
+ return E_FAIL;
+ }
+
+ if (options.DeleteAfterCompressing)
+ {
+ if (options.Commands.Size() != 1)
+ return E_NOTIMPL;
+ const CActionSet &as = options.Commands[0].ActionSet;
+ for (int i = 2; i < NPairState::kNumValues; i++)
+ if (as.StateActions[i] != NPairAction::kCompress)
+ return E_NOTIMPL;
+ }
+
+ censor.AddPathsToCensor(options.PathMode);
+ #ifdef _WIN32
+ ConvertToLongNames(censor);
+ #endif
+ censor.ExtendExclude();
+
+
+ if (options.VolumesSizes.Size() > 0 && (options.EMailMode /* || options.SfxMode */))
return E_NOTIMPL;
if (options.SfxMode)
{
CProperty property;
- property.Name = L"rsfx";
- property.Value = L"on";
+ property.Name.SetFromAscii("rsfx");
options.MethodMode.Properties.Add(property);
if (options.SfxModule.IsEmpty())
{
- errorInfo.Message = L"SFX file is not specified";
+ errorInfo.Message = "SFX file is not specified";
return E_FAIL;
}
bool found = false;
@@ -663,57 +1047,133 @@ HRESULT UpdateArchive(
if (!found)
{
if (!NFind::DoesFileExist(options.SfxModule))
- {
- errorInfo.SystemError = ::GetLastError();
- errorInfo.Message = L"7-Zip cannot find specified SFX module";
- errorInfo.FileName = options.SfxModule;
- return E_FAIL;
- }
+ return errorInfo.SetFromLastError("cannot find specified SFX module", options.SfxModule);
}
}
-
CArchiveLink arcLink;
- const UString arcPath = options.ArchivePath.GetFinalPath();
- if (!options.ArchivePath.OriginalPath.IsEmpty())
+
+ if (needSetPath)
+ {
+ if (!options.InitFormatIndex(codecs, types, cmdArcPath2) ||
+ !options.SetArcPath(codecs, cmdArcPath2))
+ return E_NOTIMPL;
+ }
+ UString arcPath = options.ArchivePath.GetFinalPath();
+
+ if (cmdArcPath2.IsEmpty())
+ {
+ if (options.MethodMode.Type.FormatIndex < 0)
+ throw "type of archive is not specified";
+ }
+ else
{
NFind::CFileInfo fi;
- if (fi.Find(us2fs(arcPath)))
+ if (!fi.Find(us2fs(arcPath)))
+ {
+ if (renameMode)
+ throw "can't find archive";;
+ if (options.MethodMode.Type.FormatIndex < 0)
+ {
+ if (!options.SetArcPath(codecs, cmdArcPath2))
+ return E_NOTIMPL;
+ }
+ }
+ else
{
if (fi.IsDir())
throw "there is no such archive";
+ if (fi.IsDevice)
+ return E_NOTIMPL;
if (options.VolumesSizes.Size() > 0)
return E_NOTIMPL;
- CIntVector formatIndices;
- if (options.MethodMode.FormatIndex >= 0)
- formatIndices.Add(options.MethodMode.FormatIndex);
- HRESULT result = arcLink.Open2(codecs, formatIndices, false, NULL, arcPath, openCallback);
+ CObjectVector<COpenType> types;
+ // change it.
+ if (options.MethodMode.Type_Defined)
+ types.Add(options.MethodMode.Type);
+ // We need to set Properties to open archive only in some cases (WIM archives).
+
+ CIntVector excl;
+ COpenOptions op;
+ #ifndef _SFX
+ op.props = &options.MethodMode.Properties;
+ #endif
+ op.codecs = codecs;
+ op.types = &types;
+ op.excludedFormats = &excl;
+ op.stdInMode = false;
+ op.stream = NULL;
+ op.filePath = arcPath;
+
+ RINOK(callback->StartOpenArchive(arcPath));
+
+ HRESULT result = arcLink.Open3(op, openCallback);
+
if (result == E_ABORT)
return result;
- RINOK(callback->OpenResult(arcPath, result));
+
+ if (result == S_OK && arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
+ result = S_FALSE;
+
+ HRESULT res2 = callback->OpenResult(codecs, arcLink, arcPath, result);
+ /*
+ if (result == S_FALSE)
+ return E_FAIL;
+ */
+ RINOK(res2);
RINOK(result);
+
if (arcLink.VolumePaths.Size() > 1)
{
errorInfo.SystemError = (DWORD)E_NOTIMPL;
- errorInfo.Message = L"Updating for multivolume archives is not implemented";
+ errorInfo.Message = "Updating for multivolume archives is not implemented";
return E_NOTIMPL;
}
CArc &arc = arcLink.Arcs.Back();
arc.MTimeDefined = !fi.IsDevice;
arc.MTime = fi.MTime;
+
+ if (arc.ErrorInfo.ThereIsTail)
+ {
+ errorInfo.SystemError = (DWORD)E_NOTIMPL;
+ errorInfo.Message = "There is some data block after the end of the archive";
+ return E_NOTIMPL;
+ }
+ if (options.MethodMode.Type.FormatIndex < 0)
+ {
+ options.MethodMode.Type.FormatIndex = arcLink.GetArc()->FormatIndex;
+ if (!options.SetArcPath(codecs, cmdArcPath2))
+ return E_NOTIMPL;
+ }
}
}
- else
+
+ if (options.MethodMode.Type.FormatIndex < 0)
{
- /*
- if (archiveType.IsEmpty())
- throw "type of archive is not specified";
- */
+ options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArcType);
+ if (options.MethodMode.Type.FormatIndex < 0)
+ return E_NOTIMPL;
}
+ bool thereIsInArchive = arcLink.IsOpen;
+ if (!thereIsInArchive && renameMode)
+ return E_FAIL;
+
CDirItems dirItems;
+ dirItems.Callback = callback;
+
+ CDirItem parentDirItem;
+ CDirItem *parentDirItem_Ptr = NULL;
+
+ /*
+ FStringVector requestedPaths;
+ FStringVector *requestedPaths_Ptr = NULL;
+ if (options.DeleteAfterCompressing)
+ requestedPaths_Ptr = &requestedPaths;
+ */
+
if (options.StdInMode)
{
CDirItem di;
@@ -727,28 +1187,70 @@ HRESULT UpdateArchive(
else
{
bool needScanning = false;
- for(int i = 0; i < options.Commands.Size(); i++)
+
+ if (!renameMode)
+ FOR_VECTOR (i, options.Commands)
if (options.Commands[i].ActionSet.NeedScanning())
needScanning = true;
+
if (needScanning)
{
- CEnumDirItemUpdateCallback enumCallback;
- enumCallback.Callback = callback;
RINOK(callback->StartScanning());
- FStringVector errorPaths;
- CRecordVector<DWORD> errorCodes;
- HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPaths, errorCodes);
- for (int i = 0; i < errorPaths.Size(); i++)
- {
- RINOK(callback->CanNotFindError(fs2us(errorPaths[i]), errorCodes[i]));
- }
+
+ dirItems.SymLinks = options.SymLinks.Val;
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ dirItems.ReadSecure = options.NtSecurity.Val;
+ #endif
+
+ dirItems.ScanAltStreams = options.AltStreams.Val;
+
+ HRESULT res = EnumerateItems(censor,
+ options.PathMode,
+ options.AddPathPrefix,
+ dirItems);
+
if (res != S_OK)
{
if (res != E_ABORT)
- errorInfo.Message = L"Scanning error";
+ errorInfo.Message = "Scanning error";
return res;
}
- RINOK(callback->FinishScanning());
+
+ RINOK(callback->FinishScanning(dirItems.Stat));
+
+ if (censor.Pairs.Size() == 1)
+ {
+ NFind::CFileInfo fi;
+ FString prefix = us2fs(censor.Pairs[0].Prefix);
+ prefix += FTEXT('.');
+ // UString prefix = censor.Pairs[0].Prefix;
+ /*
+ if (prefix.Back() == WCHAR_PATH_SEPARATOR)
+ {
+ prefix.DeleteBack();
+ }
+ */
+ if (fi.Find(prefix))
+ if (fi.IsDir())
+ {
+ parentDirItem.Size = fi.Size;
+ parentDirItem.CTime = fi.CTime;
+ parentDirItem.ATime = fi.ATime;
+ parentDirItem.MTime = fi.MTime;
+ parentDirItem.Attrib = fi.Attrib;
+ parentDirItem_Ptr = &parentDirItem;
+
+ int secureIndex = -1;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (options.NtSecurity.Val)
+ dirItems.AddSecurityItem(prefix, secureIndex);
+ #endif
+ parentDirItem.SecureIndex = secureIndex;
+
+ parentDirItem_Ptr = &parentDirItem;
+ }
+ }
}
}
@@ -756,7 +1258,7 @@ HRESULT UpdateArchive(
bool usesTempDir = false;
#ifdef _WIN32
- NDirectory::CTempDir tempDirectory;
+ CTempDir tempDirectory;
if (options.EMailMode && options.EMailRemoveAfter)
{
tempDirectory.Create(kTempFolderPrefix);
@@ -770,8 +1272,6 @@ HRESULT UpdateArchive(
bool createTempFile = false;
- bool thereIsInArchive = arcLink.IsOpen;
-
if (!options.StdOutMode && options.UpdateArchiveItself)
{
CArchivePath &ap = options.Commands[0].ArchivePath;
@@ -782,14 +1282,15 @@ HRESULT UpdateArchive(
createTempFile = true;
ap.Temp = true;
if (!options.WorkingDir.IsEmpty())
- {
ap.TempPrefix = options.WorkingDir;
- NormalizeDirPathPrefix(ap.TempPrefix);
- }
+ else
+ ap.TempPrefix = us2fs(ap.Prefix);
+ NormalizeDirPathPrefix(ap.TempPrefix);
}
}
- for (int i = 0; i < options.Commands.Size(); i++)
+ unsigned i;
+ for (i = 0; i < options.Commands.Size(); i++)
{
CArchivePath &ap = options.Commands[i].ArchivePath;
if (usesTempDir)
@@ -805,10 +1306,10 @@ HRESULT UpdateArchive(
const FString path = us2fs(ap.GetFinalPath());
if (NFind::DoesFileOrDirExist(path))
{
- errorInfo.SystemError = 0;
- errorInfo.Message = L"The file already exists";
- errorInfo.FileName = path;
- return E_FAIL;
+ errorInfo.SystemError = ERROR_FILE_EXISTS;
+ errorInfo.Message = "The file already exists";
+ errorInfo.FileNames.Add(path);
+ return errorInfo.Get_HRESULT_Error();
}
}
}
@@ -816,13 +1317,77 @@ HRESULT UpdateArchive(
CObjectVector<CArcItem> arcItems;
if (thereIsInArchive)
{
- RINOK(EnumerateInArchiveItems(censor, arcLink.Arcs.Back(), arcItems));
+ RINOK(EnumerateInArchiveItems(
+ // options.StoreAltStreams,
+ censor, arcLink.Arcs.Back(), arcItems));
+ }
+
+ /*
+ FStringVector processedFilePaths;
+ FStringVector *processedFilePaths_Ptr = NULL;
+ if (options.DeleteAfterCompressing)
+ processedFilePaths_Ptr = &processedFilePaths;
+ */
+
+ CByteBuffer processedItems;
+ if (options.DeleteAfterCompressing)
+ {
+ unsigned num = dirItems.Items.Size();
+ processedItems.Alloc(num);
+ for (i = 0; i < num; i++)
+ processedItems[i] = 0;
+ }
+
+ /*
+ #ifndef _NO_CRYPTO
+ if (arcLink.PasswordWasAsked)
+ {
+ // We set password, if open have requested password
+ RINOK(callback->SetPassword(arcLink.Password));
+ }
+ #endif
+ */
+
+ for (i = 0; i < options.Commands.Size(); i++)
+ {
+ const CArc *arc = thereIsInArchive ? arcLink.GetArc() : NULL;
+ CUpdateArchiveCommand &command = options.Commands[i];
+ UString name;
+ bool isUpdating;
+
+ if (options.StdOutMode)
+ {
+ name.SetFromAscii("stdout");
+ isUpdating = thereIsInArchive;
+ }
+ else
+ {
+ name = command.ArchivePath.GetFinalPath();
+ isUpdating = (i == 0 && options.UpdateArchiveItself && thereIsInArchive);
+ }
+
+ RINOK(callback->StartArchive(name, isUpdating))
+
+ CFinishArchiveStat st;
+
+ RINOK(Compress(options,
+ isUpdating,
+ codecs,
+ command.ActionSet,
+ arc,
+ command.ArchivePath,
+ arcItems,
+ options.DeleteAfterCompressing ? (Byte *)processedItems : NULL,
+
+ dirItems,
+ parentDirItem_Ptr,
+
+ tempFiles,
+ errorInfo, callback, st));
+
+ RINOK(callback->FinishArchive(st));
}
- RINOK(UpdateWithItemLists(codecs, options,
- thereIsInArchive ? arcLink.GetArchive() : 0,
- arcItems, dirItems,
- tempFiles, errorInfo, callback));
if (thereIsInArchive)
{
@@ -837,21 +1402,16 @@ HRESULT UpdateArchive(
{
CArchivePath &ap = options.Commands[0].ArchivePath;
const FString &tempPath = ap.GetTempPath();
+
if (thereIsInArchive)
- if (!NDirectory::DeleteFileAlways(us2fs(arcPath)))
- {
- errorInfo.SystemError = ::GetLastError();
- errorInfo.Message = L"7-Zip cannot delete the file";
- errorInfo.FileName = us2fs(arcPath);
- return E_FAIL;
- }
- if (!NDirectory::MyMoveFile(tempPath, us2fs(arcPath)))
+ if (!DeleteFileAlways(us2fs(arcPath)))
+ return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath));
+
+ if (!MyMoveFile(tempPath, us2fs(arcPath)))
{
- errorInfo.SystemError = ::GetLastError();
- errorInfo.Message = L"7-Zip cannot move the file";
- errorInfo.FileName = tempPath;
- errorInfo.FileName2 = us2fs(arcPath);
- return E_FAIL;
+ errorInfo.SetFromLastError("cannot move the file", tempPath);
+ errorInfo.FileNames.Add(us2fs(arcPath));
+ return errorInfo.Get_HRESULT_Error();
}
}
catch(...)
@@ -860,38 +1420,49 @@ HRESULT UpdateArchive(
}
}
+
#if defined(_WIN32) && !defined(UNDER_CE)
+
if (options.EMailMode)
{
NDLL::CLibrary mapiLib;
if (!mapiLib.Load(FTEXT("Mapi32.dll")))
{
- errorInfo.SystemError = ::GetLastError();
- errorInfo.Message = L"7-Zip cannot load Mapi32.dll";
- return E_FAIL;
+ errorInfo.SetFromLastError("cannot load Mapi32.dll");
+ return errorInfo.Get_HRESULT_Error();
}
- MY_LPMAPISENDDOCUMENTS fnSend = (MY_LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments");
+
+ /*
+ LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments");
if (fnSend == 0)
{
- errorInfo.SystemError = ::GetLastError();
- errorInfo.Message = L"7-Zip cannot find MAPISendDocuments function";
- return E_FAIL;
+ errorInfo.SetFromLastError)("7-Zip cannot find MAPISendDocuments function");
+ return errorInfo.Get_HRESULT_Error();
+ }
+ */
+
+ LPMAPISENDMAIL sendMail = (LPMAPISENDMAIL)mapiLib.GetProc("MAPISendMail");
+ if (sendMail == 0)
+ {
+ errorInfo.SetFromLastError("7-Zip cannot find MAPISendMail function");
+ return errorInfo.Get_HRESULT_Error();;
}
+
FStringVector fullPaths;
- int i;
+ unsigned i;
+
for (i = 0; i < options.Commands.Size(); i++)
{
CArchivePath &ap = options.Commands[i].ArchivePath;
+ FString finalPath = us2fs(ap.GetFinalPath());
FString arcPath;
- if (!NFile::NDirectory::MyGetFullPathName(us2fs(ap.GetFinalPath()), arcPath))
- {
- errorInfo.SystemError = ::GetLastError();
- errorInfo.Message = L"GetFullPathName error";
- return E_FAIL;
- }
+ if (!MyGetFullPathName(finalPath, arcPath))
+ return errorInfo.SetFromLastError("GetFullPathName error", finalPath);
fullPaths.Add(arcPath);
}
+
CCurrentDirRestorer curDirRestorer;
+
for (i = 0; i < fullPaths.Size(); i++)
{
UString arcPath = fs2us(fullPaths[i]);
@@ -899,9 +1470,86 @@ HRESULT UpdateArchive(
AString path = GetAnsiString(arcPath);
AString name = GetAnsiString(fileName);
// Warning!!! MAPISendDocuments function changes Current directory
- fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
+ // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
+
+ MapiFileDesc f;
+ memset(&f, 0, sizeof(f));
+ f.nPosition = 0xFFFFFFFF;
+ f.lpszPathName = (char *)(const char *)path;
+ f.lpszFileName = (char *)(const char *)name;
+
+ MapiMessage m;
+ memset(&m, 0, sizeof(m));
+ m.nFileCount = 1;
+ m.lpFiles = &f;
+
+ const AString addr = GetAnsiString(options.EMailAddress);
+ MapiRecipDesc rec;
+ if (!addr.IsEmpty())
+ {
+ memset(&rec, 0, sizeof(rec));
+ rec.ulRecipClass = MAPI_TO;
+ rec.lpszAddress = (char *)(const char *)addr;
+ m.nRecipCount = 1;
+ m.lpRecips = &rec;
+ }
+
+ sendMail((LHANDLE)0, 0, &m, MAPI_DIALOG, 0);
}
}
+
#endif
+
+ if (options.DeleteAfterCompressing)
+ {
+ CRecordVector<CRefSortPair> pairs;
+ FStringVector foldersNames;
+
+ for (i = 0; i < dirItems.Items.Size(); i++)
+ {
+ const CDirItem &dirItem = dirItems.Items[i];
+ FString phyPath = dirItems.GetPhyPath(i);
+ if (dirItem.IsDir())
+ {
+ CRefSortPair pair;
+ pair.Index = i;
+ pair.Len = GetNumSlashes(phyPath);
+ pairs.Add(pair);
+ }
+ else
+ {
+ if (processedItems[i] != 0 || dirItem.Size == 0)
+ {
+ RINOK(callback->DeletingAfterArchiving(phyPath, false));
+ DeleteFileAlways(phyPath);
+ }
+ else
+ {
+ // file was skipped
+ /*
+ errorInfo.SystemError = 0;
+ errorInfo.Message = "file was not processed";
+ errorInfo.FileName = phyPath;
+ return E_FAIL;
+ */
+ }
+ }
+ }
+
+ pairs.Sort(CompareRefSortPair, NULL);
+
+ for (i = 0; i < pairs.Size(); i++)
+ {
+ FString phyPath = dirItems.GetPhyPath(pairs[i].Index);
+ if (NFind::DoesDirExist(phyPath))
+ {
+ RINOK(callback->DeletingAfterArchiving(phyPath, true));
+ RemoveDir(phyPath);
+ }
+ }
+
+ RINOK(callback->FinishDeletingAfterArchiving());
+ }
+
return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Update.h b/3rdparty/lzma/CPP/7zip/UI/Common/Update.h
index 43a3c0fdb83..0301ae7660e 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/Update.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/Update.h
@@ -3,14 +3,24 @@
#ifndef __COMMON_UPDATE_H
#define __COMMON_UPDATE_H
-#include "Common/Wildcard.h"
+#include "../../../Common/Wildcard.h"
#include "ArchiveOpenCallback.h"
#include "LoadCodecs.h"
+#include "OpenArchive.h"
#include "Property.h"
#include "UpdateAction.h"
#include "UpdateCallback.h"
+#include "DirItem.h"
+
+enum EArcNameMode
+{
+ k_ArcNameMode_Smart,
+ k_ArcNameMode_Exact,
+ k_ArcNameMode_Add,
+};
+
struct CArchivePath
{
UString OriginalPath;
@@ -26,52 +36,11 @@ struct CArchivePath
CArchivePath(): Temp(false) {};
- void ParseFromPath(const UString &path)
- {
- OriginalPath = path;
-
- SplitPathToParts(path, Prefix, Name);
- int dotPos = Name.ReverseFind(L'.');
- if (dotPos < 0)
- return;
- if (dotPos == Name.Length() - 1)
- {
- Name = Name.Left(dotPos);
- BaseExtension.Empty();
- return;
- }
- if (BaseExtension.CompareNoCase(Name.Mid(dotPos + 1)) == 0)
- {
- BaseExtension = Name.Mid(dotPos + 1);
- Name = Name.Left(dotPos);
- }
- else
- BaseExtension.Empty();
- }
-
- UString GetPathWithoutExt() const
- {
- return Prefix + Name;
- }
-
- UString GetFinalPath() const
- {
- UString path = GetPathWithoutExt();
- if (!BaseExtension.IsEmpty())
- path += UString(L'.') + BaseExtension;
- return path;
- }
-
-
- FString GetTempPath() const
- {
- FString path = TempPrefix + us2fs(Name);
- if (!BaseExtension.IsEmpty())
- path += FString(FTEXT('.')) + us2fs(BaseExtension);
- path += FTEXT(".tmp");
- path += TempPostfix;
- return path;
- }
+ void ParseFromPath(const UString &path, EArcNameMode mode);
+ UString GetPathWithoutExt() const { return Prefix + Name; }
+ UString GetFinalPath() const;
+ UString GetFinalVolPath() const;
+ FString GetTempPath() const;
};
struct CUpdateArchiveCommand
@@ -83,9 +52,31 @@ struct CUpdateArchiveCommand
struct CCompressionMethodMode
{
- int FormatIndex;
+ bool Type_Defined;
+ COpenType Type;
CObjectVector<CProperty> Properties;
- CCompressionMethodMode(): FormatIndex(-1) {}
+
+ CCompressionMethodMode(): Type_Defined(false) {}
+};
+
+namespace NRecursedType { enum EEnum
+{
+ kRecursed,
+ kWildcardOnlyRecursed,
+ kNonRecursed
+};}
+
+struct CRenamePair
+{
+ UString OldName;
+ UString NewName;
+ bool WildcardParsing;
+ NRecursedType::EEnum RecursedType;
+
+ CRenamePair(): WildcardParsing(true), RecursedType(NRecursedType::kNonRecursed) {}
+
+ bool Prepare();
+ bool GetNewPath(bool isFolder, const UString &src, UString &dest) const;
};
struct CUpdateOptions
@@ -95,7 +86,8 @@ struct CUpdateOptions
CObjectVector<CUpdateArchiveCommand> Commands;
bool UpdateArchiveItself;
CArchivePath ArchivePath;
-
+ EArcNameMode ArcNameMode;
+
bool SfxMode;
FString SfxModule;
@@ -110,8 +102,22 @@ struct CUpdateOptions
UString EMailAddress;
FString WorkingDir;
+ NWildcard::ECensorPathMode PathMode;
+ UString AddPathPrefix;
- bool Init(const CCodecs *codecs, const CIntVector &formatIndices, const UString &arcPath);
+ CBoolPair NtSecurity;
+ CBoolPair AltStreams;
+ CBoolPair HardLinks;
+ CBoolPair SymLinks;
+
+ bool DeleteAfterCompressing;
+
+ bool SetArcMTime;
+
+ CObjectVector<CRenamePair> RenamePairs;
+
+ bool InitFormatIndex(const CCodecs *codecs, const CObjectVector<COpenType> &types, const UString &arcPath);
+ bool SetArcPath(const CCodecs *codecs, const UString &arcPath);
CUpdateOptions():
UpdateArchiveItself(true),
@@ -120,56 +126,73 @@ struct CUpdateOptions
StdOutMode(false),
EMailMode(false),
EMailRemoveAfter(false),
- OpenShareForWrite(false)
+ OpenShareForWrite(false),
+ ArcNameMode(k_ArcNameMode_Smart),
+ PathMode(NWildcard::k_RelatPath),
+
+ DeleteAfterCompressing(false),
+ SetArcMTime(false)
+
{};
- void SetAddActionCommand()
+ void SetActionCommand_Add()
{
Commands.Clear();
CUpdateArchiveCommand c;
- c.ActionSet = NUpdateArchive::kAddActionSet;
+ c.ActionSet = NUpdateArchive::k_ActionSet_Add;
Commands.Add(c);
}
CRecordVector<UInt64> VolumesSizes;
};
-struct CErrorInfo
+struct CUpdateErrorInfo
{
DWORD SystemError;
- FString FileName;
- FString FileName2;
- UString Message;
- // UStringVector ErrorPaths;
- // CRecordVector<DWORD> ErrorCodes;
- CErrorInfo(): SystemError(0) {};
+ AString Message;
+ FStringVector FileNames;
+
+ bool ThereIsError() const { return SystemError != 0 || !Message.IsEmpty() || !FileNames.IsEmpty(); }
+ HRESULT Get_HRESULT_Error() const { return SystemError == 0 ? E_FAIL : HRESULT_FROM_WIN32(SystemError); }
+ void SetFromLastError(const char *message);
+ HRESULT SetFromLastError(const char *message, const FString &fileName);
+
+ CUpdateErrorInfo(): SystemError(0) {};
};
-struct CUpdateErrorInfo: public CErrorInfo
+struct CFinishArchiveStat
{
+ UInt64 OutArcFileSize;
+
+ CFinishArchiveStat(): OutArcFileSize(0) {}
};
#define INTERFACE_IUpdateCallbackUI2(x) \
INTERFACE_IUpdateCallbackUI(x) \
- virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) x; \
+ INTERFACE_IDirItemsCallback(x) \
+ virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) x; \
virtual HRESULT StartScanning() x; \
- virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path) x; \
- virtual HRESULT CanNotFindError(const wchar_t *name, DWORD systemError) x; \
- virtual HRESULT FinishScanning() x; \
+ virtual HRESULT FinishScanning(const CDirItemsStat &st) x; \
+ virtual HRESULT StartOpenArchive(const wchar_t *name) x; \
virtual HRESULT StartArchive(const wchar_t *name, bool updating) x; \
- virtual HRESULT FinishArchive() x; \
+ virtual HRESULT FinishArchive(const CFinishArchiveStat &st) x; \
+ virtual HRESULT DeletingAfterArchiving(const FString &path, bool isDir) x; \
+ virtual HRESULT FinishDeletingAfterArchiving() x; \
-struct IUpdateCallbackUI2: public IUpdateCallbackUI
+struct IUpdateCallbackUI2: public IUpdateCallbackUI, public IDirItemsCallback
{
INTERFACE_IUpdateCallbackUI2(=0)
};
HRESULT UpdateArchive(
CCodecs *codecs,
- const NWildcard::CCensor &censor,
+ const CObjectVector<COpenType> &types,
+ const UString &cmdArcPath2,
+ NWildcard::CCensor &censor,
CUpdateOptions &options,
CUpdateErrorInfo &errorInfo,
IOpenCallbackUI *openCallback,
- IUpdateCallbackUI2 *callback);
+ IUpdateCallbackUI2 *callback,
+ bool needSetPath);
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.cpp
index 879a49c57db..a80db7212e1 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.cpp
@@ -6,7 +6,7 @@
namespace NUpdateArchive {
-const CActionSet kAddActionSet =
+const CActionSet k_ActionSet_Add =
{{
NPairAction::kCopy,
NPairAction::kCopy,
@@ -17,7 +17,7 @@ const CActionSet kAddActionSet =
NPairAction::kCompress
}};
-const CActionSet kUpdateActionSet =
+const CActionSet k_ActionSet_Update =
{{
NPairAction::kCopy,
NPairAction::kCopy,
@@ -28,7 +28,7 @@ const CActionSet kUpdateActionSet =
NPairAction::kCompress
}};
-const CActionSet kFreshActionSet =
+const CActionSet k_ActionSet_Fresh =
{{
NPairAction::kCopy,
NPairAction::kCopy,
@@ -39,7 +39,7 @@ const CActionSet kFreshActionSet =
NPairAction::kCompress
}};
-const CActionSet kSynchronizeActionSet =
+const CActionSet k_ActionSet_Sync =
{{
NPairAction::kCopy,
NPairAction::kIgnore,
@@ -50,7 +50,7 @@ const CActionSet kSynchronizeActionSet =
NPairAction::kCompress,
}};
-const CActionSet kDeleteActionSet =
+const CActionSet k_ActionSet_Delete =
{{
NPairAction::kCopy,
NPairAction::kIgnore,
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.h b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.h
index 0ac1c1080e7..bc53fcdbbb1 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.h
@@ -7,7 +7,7 @@ namespace NUpdateArchive {
namespace NPairState
{
- const int kNumValues = 7;
+ const unsigned kNumValues = 7;
enum EEnum
{
kNotMasked = 0,
@@ -34,9 +34,18 @@ namespace NUpdateArchive {
struct CActionSet
{
NPairAction::EEnum StateActions[NPairState::kNumValues];
+
+ bool IsEqualTo(const CActionSet &a) const
+ {
+ for (unsigned i = 0; i < NPairState::kNumValues; i++)
+ if (StateActions[i] != a.StateActions[i])
+ return false;
+ return true;
+ }
+
bool NeedScanning() const
{
- int i;
+ unsigned i;
for (i = 0; i < NPairState::kNumValues; i++)
if (StateActions[i] == NPairAction::kCompress)
return true;
@@ -47,11 +56,11 @@ namespace NUpdateArchive {
}
};
- extern const CActionSet kAddActionSet;
- extern const CActionSet kUpdateActionSet;
- extern const CActionSet kFreshActionSet;
- extern const CActionSet kSynchronizeActionSet;
- extern const CActionSet kDeleteActionSet;
+ extern const CActionSet k_ActionSet_Add;
+ extern const CActionSet k_ActionSet_Update;
+ extern const CActionSet k_ActionSet_Fresh;
+ extern const CActionSet k_ActionSet_Sync;
+ extern const CActionSet k_ActionSet_Delete;
}
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp
index 21146bb0a2d..6c439cfd78d 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp
@@ -2,29 +2,70 @@
#include "StdAfx.h"
-#include "Common/ComTry.h"
-#include "Common/Defs.h"
-#include "Common/IntToString.h"
-#include "Common/StringConvert.h"
+#ifndef _7ZIP_ST
+#include "../../../Windows/Synchronization.h"
+#endif
-#include "Windows/PropVariant.h"
+#include "../../../Common/ComTry.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/Wildcard.h"
-#include "../../Common/FileStreams.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/PropVariant.h"
+
+#include "../../Common/StreamObjects.h"
#include "UpdateCallback.h"
+#if defined(_WIN32) && !defined(UNDER_CE)
+#define _USE_SECURITY_CODE
+#include "../../../Windows/SecurityUtils.h"
+#endif
+
using namespace NWindows;
+using namespace NFile;
+
+#ifndef _7ZIP_ST
+static NSynchronization::CCriticalSection g_CriticalSection;
+#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+#else
+#define MT_LOCK
+#endif
+
+
+#ifdef _USE_SECURITY_CODE
+bool InitLocalPrivileges();
+#endif
CArchiveUpdateCallback::CArchiveUpdateCallback():
- Callback(0),
- ShareForWrite(false),
- StdInMode(false),
- DirItems(0),
- ArcItems(0),
- UpdatePairs(0),
- NewNames(0),
- KeepOriginalItemNames(0)
- {}
+ _hardIndex_From((UInt32)(Int32)-1),
+
+ Callback(NULL),
+
+ DirItems(NULL),
+ ParentDirItem(NULL),
+
+ Arc(NULL),
+ ArcItems(NULL),
+ UpdatePairs(NULL),
+ NewNames(NULL),
+
+ ShareForWrite(false),
+ StdInMode(false),
+
+ KeepOriginalItemNames(false),
+ StoreNtSecurity(false),
+ StoreHardLinks(false),
+ StoreSymLinks(false),
+
+ ProcessedItemsStatuses(NULL)
+{
+ #ifdef _USE_SECURITY_CODE
+ _saclEnabled = InitLocalPrivileges();
+ #endif
+}
STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
@@ -50,7 +91,7 @@ STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UI
/*
-STATPROPSTG kProperties[] =
+static const CStatProp kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL},
@@ -64,7 +105,7 @@ STATPROPSTG kProperties[] =
STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
{
- return CStatPropEnumerator::CreateEnumerator(kProperties, sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
+ return CStatPropEnumerator::CreateEnumerator(kProps, ARRAY_SIZE(kProps), enumerator);
}
*/
@@ -74,11 +115,11 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
COM_TRY_BEGIN
RINOK(Callback->CheckBreak());
const CUpdatePair2 &up = (*UpdatePairs)[index];
- if (newData != NULL) *newData = BoolToInt(up.NewData);
- if (newProps != NULL) *newProps = BoolToInt(up.NewProps);
- if (indexInArchive != NULL)
+ if (newData) *newData = BoolToInt(up.NewData);
+ if (newProps) *newProps = BoolToInt(up.NewProps);
+ if (indexInArchive)
{
- *indexInArchive = (UInt32)-1;
+ *indexInArchive = (UInt32)(Int32)-1;
if (up.ExistInArchive())
*indexInArchive = (ArcItems == 0) ? up.ArcIndex : (*ArcItems)[up.ArcIndex].IndexInServer;
}
@@ -86,84 +127,300 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+STDMETHODIMP CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value)
{
- COM_TRY_BEGIN
- const CUpdatePair2 &up = (*UpdatePairs)[index];
- NWindows::NCOM::CPropVariant prop;
-
- if (propID == kpidIsAnti)
+ NCOM::CPropVariant prop;
+ switch (propID)
{
- prop = up.IsAnti;
- prop.Detach(value);
- return S_OK;
+ case kpidIsDir: prop = true; break;
+ case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->Attrib; break;
+ case kpidCTime: if (ParentDirItem) prop = ParentDirItem->CTime; break;
+ case kpidATime: if (ParentDirItem) prop = ParentDirItem->ATime; break;
+ case kpidMTime: if (ParentDirItem) prop = ParentDirItem->MTime; break;
}
+ prop.Detach(value);
+ return S_OK;
+}
- if (up.IsAnti)
+STDMETHODIMP CArchiveUpdateCallback::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)
+{
+ *parentType = NParentType::kDir;
+ *parent = (UInt32)(Int32)-1;
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps)
+{
+ *numProps = 0;
+ if (StoreNtSecurity)
+ *numProps = 1;
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)
+{
+ *name = NULL;
+ *propID = kpidNtSecure;
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID
+ #ifdef _USE_SECURITY_CODE
+ propID
+ #endif
+ , const void **data, UInt32 *dataSize, UInt32 *propType)
+{
+ *data = 0;
+ *dataSize = 0;
+ *propType = 0;
+ if (!StoreNtSecurity)
+ return S_OK;
+ #ifdef _USE_SECURITY_CODE
+ if (propID == kpidNtSecure)
{
- switch(propID)
+ if (StdInMode)
+ return S_OK;
+
+ if (ParentDirItem)
{
- case kpidIsDir:
- case kpidPath:
- break;
- case kpidSize:
- prop = (UInt64)0;
- prop.Detach(value);
+ if (ParentDirItem->SecureIndex < 0)
return S_OK;
- default:
- prop.Detach(value);
+ const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[ParentDirItem->SecureIndex];
+ *data = buf;
+ *dataSize = (UInt32)buf.Size();
+ *propType = NPropDataType::kRaw;
+ return S_OK;
+ }
+
+ if (Arc && Arc->GetRootProps)
+ return Arc->GetRootProps->GetRootRawProp(propID, data, dataSize, propType);
+ }
+ #endif
+ return S_OK;
+}
+
+// #ifdef _USE_SECURITY_CODE
+// #endif
+
+STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
+{
+ *data = 0;
+ *dataSize = 0;
+ *propType = 0;
+
+ if (propID == kpidNtSecure ||
+ propID == kpidNtReparse)
+ {
+ if (StdInMode)
+ return S_OK;
+
+ const CUpdatePair2 &up = (*UpdatePairs)[index];
+ if (up.UseArcProps && up.ExistInArchive() && Arc->GetRawProps)
+ return Arc->GetRawProps->GetRawProp(
+ ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex,
+ propID, data, dataSize, propType);
+
+ {
+ const CUpdatePair2 &up = (*UpdatePairs)[index];
+ /*
+ if (!up.NewData)
+ return E_FAIL;
+ */
+ if (up.IsAnti)
return S_OK;
+
+ #ifndef UNDER_CE
+ const CDirItem &di = DirItems->Items[up.DirIndex];
+ #endif
+
+ #ifdef _USE_SECURITY_CODE
+ if (propID == kpidNtSecure)
+ {
+ if (!StoreNtSecurity)
+ return S_OK;
+ if (di.SecureIndex < 0)
+ return S_OK;
+ const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[di.SecureIndex];
+ *data = buf;
+ *dataSize = (UInt32)buf.Size();
+ *propType = NPropDataType::kRaw;
+ }
+ else
+ #endif
+ {
+ // propID == kpidNtReparse
+ if (!StoreSymLinks)
+ return S_OK;
+ #ifndef UNDER_CE
+ const CByteBuffer *buf = &di.ReparseData2;
+ if (buf->Size() == 0)
+ buf = &di.ReparseData;
+ if (buf->Size() != 0)
+ {
+ *data = *buf;
+ *dataSize = (UInt32)buf->Size();
+ *propType = NPropDataType::kRaw;
+ }
+ #endif
+ }
+
+ return S_OK;
}
}
+
+ return S_OK;
+}
+
+#ifndef UNDER_CE
+
+static UString GetRelativePath(const UString &to, const UString &from)
+{
+ UStringVector partsTo, partsFrom;
+ SplitPathToParts(to, partsTo);
+ SplitPathToParts(from, partsFrom);
+
+ unsigned i;
+ for (i = 0;; i++)
+ {
+ if (i + 1 >= partsFrom.Size() ||
+ i + 1 >= partsTo.Size())
+ break;
+ if (CompareFileNames(partsFrom[i], partsTo[i]) != 0)
+ break;
+ }
+
+ if (i == 0)
+ {
+ #ifdef _WIN32
+ if (NName::IsDrivePath(to) ||
+ NName::IsDrivePath(from))
+ return to;
+ #endif
+ }
+
+ UString s;
+ unsigned k;
+
+ for (k = i + 1; k < partsFrom.Size(); k++)
+ s += L".." WSTRING_PATH_SEPARATOR;
- if (up.ExistOnDisk())
+ for (k = i; k < partsTo.Size(); k++)
{
- const CDirItem &di = DirItems->Items[up.DirIndex];
- switch(propID)
+ if (k != i)
+ s.Add_PathSepar();
+ s += partsTo[k];
+ }
+
+ return s;
+}
+
+#endif
+
+STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ const CUpdatePair2 &up = (*UpdatePairs)[index];
+ NCOM::CPropVariant prop;
+
+ if (up.NewData)
+ {
+ /*
+ if (propID == kpidIsHardLink)
+ {
+ prop = _isHardLink;
+ prop.Detach(value);
+ return S_OK;
+ }
+ */
+ if (propID == kpidSymLink)
{
- case kpidPath:
+ if (index == _hardIndex_From)
+ {
+ prop.Detach(value);
+ return S_OK;
+ }
+ if (up.DirIndex >= 0)
+ {
+ #ifndef UNDER_CE
+ const CDirItem &di = DirItems->Items[up.DirIndex];
+ // if (di.IsDir())
{
- if (KeepOriginalItemNames)
+ CReparseAttr attr;
+ if (attr.Parse(di.ReparseData, di.ReparseData.Size()))
{
- if (up.ExistInArchive() && Archive)
+ UString simpleName = attr.GetPath();
+ if (attr.IsRelative())
+ prop = simpleName;
+ else
{
- UInt32 indexInArchive;
- if (ArcItems == 0)
- indexInArchive = up.ArcIndex;
- else
- indexInArchive = (*ArcItems)[up.ArcIndex].IndexInServer;
- return Archive->GetProperty(indexInArchive, propID, value);
+ const FString phyPath = DirItems->GetPhyPath(up.DirIndex);
+ FString fullPath;
+ if (NDir::MyGetFullPathName(phyPath, fullPath))
+ {
+ prop = GetRelativePath(simpleName, fs2us(fullPath));
+ }
}
+ prop.Detach(value);
+ return S_OK;
}
- prop = DirItems->GetLogPath(up.DirIndex); break;
}
- case kpidIsDir: prop = di.IsDir(); break;
- case kpidSize: prop = di.Size; break;
- case kpidAttrib: prop = di.Attrib; break;
- case kpidCTime: prop = di.CTime; break;
- case kpidATime: prop = di.ATime; break;
- case kpidMTime: prop = di.MTime; break;
+ #endif
+ }
}
- }
- else
- {
- if (propID == kpidPath)
+ else if (propID == kpidHardLink)
{
- if (up.NewNameIndex >= 0)
+ if (index == _hardIndex_From)
+ {
+ const CKeyKeyValPair &pair = _map[_hardIndex_To];
+ const CUpdatePair2 &up2 = (*UpdatePairs)[pair.Value];
+ prop = DirItems->GetLogPath(up2.DirIndex);
+ prop.Detach(value);
+ return S_OK;
+ }
+ if (up.DirIndex >= 0)
{
- prop = (*NewNames)[up.NewNameIndex];
prop.Detach(value);
return S_OK;
}
}
- if (up.ExistInArchive() && Archive)
+ }
+
+ if (up.IsAnti
+ && propID != kpidIsDir
+ && propID != kpidPath
+ && propID != kpidIsAltStream)
+ {
+ switch (propID)
{
- UInt32 indexInArchive;
- if (ArcItems == 0)
- indexInArchive = up.ArcIndex;
- else
- indexInArchive = (*ArcItems)[up.ArcIndex].IndexInServer;
- return Archive->GetProperty(indexInArchive, propID, value);
+ case kpidSize: prop = (UInt64)0; break;
+ case kpidIsAnti: prop = true; break;
+ }
+ }
+ else if (propID == kpidPath && up.NewNameIndex >= 0)
+ prop = (*NewNames)[up.NewNameIndex];
+ else if (propID == kpidShortName && up.NewNameIndex >= 0 && up.IsMainRenameItem)
+ {
+ // we can generate new ShortName here;
+ }
+ else if ((up.UseArcProps || (KeepOriginalItemNames && (propID == kpidPath || propID == kpidIsAltStream)))
+ && up.ExistInArchive() && Archive)
+ return Archive->GetProperty(ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex, propID, value);
+ else if (up.ExistOnDisk())
+ {
+ const CDirItem &di = DirItems->Items[up.DirIndex];
+ switch (propID)
+ {
+ case kpidPath: prop = DirItems->GetLogPath(up.DirIndex); break;
+ case kpidIsDir: prop = di.IsDir(); break;
+ case kpidSize: prop = di.IsDir() ? (UInt64)0 : di.Size; break;
+ case kpidAttrib: prop = di.Attrib; break;
+ case kpidCTime: prop = di.CTime; break;
+ case kpidATime: prop = di.ATime; break;
+ case kpidMTime: prop = di.MTime; break;
+ case kpidIsAltStream: prop = di.IsAltStream; break;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // case kpidShortName: prop = di.ShortName; break;
+ #endif
}
}
prop.Detach(value);
@@ -171,28 +428,56 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
+#ifndef _7ZIP_ST
+static NSynchronization::CCriticalSection CS;
+#endif
+
+STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)
{
COM_TRY_BEGIN
+ *inStream = NULL;
const CUpdatePair2 &up = (*UpdatePairs)[index];
if (!up.NewData)
return E_FAIL;
RINOK(Callback->CheckBreak());
- RINOK(Callback->Finilize());
+ // RINOK(Callback->Finalize());
+
+ bool isDir = IsDir(up);
if (up.IsAnti)
{
- return Callback->GetStream((*ArcItems)[up.ArcIndex].Name, true);
+ UString name;
+ if (up.ArcIndex >= 0)
+ name = (*ArcItems)[up.ArcIndex].Name;
+ else if (up.DirIndex >= 0)
+ name = DirItems->GetLogPath(up.DirIndex);
+ RINOK(Callback->GetStream(name, isDir, true, mode));
+
+ /* 9.33: fixed. Handlers expect real stream object for files, even for anti-file.
+ so we return empty stream */
+
+ if (!isDir)
+ {
+ CBufInStream *inStreamSpec = new CBufInStream();
+ CMyComPtr<ISequentialInStream> inStreamLoc = inStreamSpec;
+ inStreamSpec->Init(NULL, 0);
+ *inStream = inStreamLoc.Detach();
+ }
+ return S_OK;
}
- const CDirItem &di = DirItems->Items[up.DirIndex];
- RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), false));
+
+ RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), isDir, false, mode));
- if (di.IsDir())
+ if (isDir)
return S_OK;
if (StdInMode)
{
+ if (mode != NUpdateNotifyOp::kAdd &&
+ mode != NUpdateNotifyOp::kUpdate)
+ return S_OK;
+
CStdInFileStream *inStreamSpec = new CStdInFileStream;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
*inStream = inStreamLoc.Detach();
@@ -201,21 +486,196 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream
{
CInFileStream *inStreamSpec = new CInFileStream;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
- const UString path = DirItems->GetPhyPath(up.DirIndex);
- if (!inStreamSpec->OpenShared(us2fs(path), ShareForWrite))
+
+ inStreamSpec->SupportHardLinks = StoreHardLinks;
+ inStreamSpec->Callback = this;
+ inStreamSpec->CallbackRef = index;
+
+ const FString path = DirItems->GetPhyPath(up.DirIndex);
+ _openFiles_Indexes.Add(index);
+ _openFiles_Paths.Add(path);
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (DirItems->Items[up.DirIndex].AreReparseData())
+ {
+ if (!inStreamSpec->File.OpenReparse(path))
+ {
+ return Callback->OpenFileError(path, ::GetLastError());
+ }
+ }
+ else
+ #endif
+ if (!inStreamSpec->OpenShared(path, ShareForWrite))
{
return Callback->OpenFileError(path, ::GetLastError());
}
+
+ if (StoreHardLinks)
+ {
+ CStreamFileProps props;
+ if (inStreamSpec->GetProps2(&props) == S_OK)
+ {
+ if (props.NumLinks > 1)
+ {
+ CKeyKeyValPair pair;
+ pair.Key1 = props.VolID;
+ pair.Key2 = props.FileID_Low;
+ pair.Value = index;
+ unsigned numItems = _map.Size();
+ unsigned pairIndex = _map.AddToUniqueSorted2(pair);
+ if (numItems == _map.Size())
+ {
+ // const CKeyKeyValPair &pair2 = _map.Pairs[pairIndex];
+ _hardIndex_From = index;
+ _hardIndex_To = pairIndex;
+ // we could return NULL as stream, but it's better to return real stream
+ // return S_OK;
+ }
+ }
+ }
+ }
+
+ if (ProcessedItemsStatuses)
+ {
+ #ifndef _7ZIP_ST
+ NSynchronization::CCriticalSectionLock lock(CS);
+ #endif
+ ProcessedItemsStatuses[(unsigned)up.DirIndex] = 1;
+ }
*inStream = inStreamLoc.Detach();
}
+
return S_OK;
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
+STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 opRes)
+{
+ COM_TRY_BEGIN
+ return Callback->SetOperationResult(opRes);
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
{
COM_TRY_BEGIN
- return Callback->SetOperationResult(operationResult);
+ return GetStream2(index, inStream,
+ (*UpdatePairs)[index].ArcIndex < 0 ?
+ NUpdateNotifyOp::kAdd :
+ NUpdateNotifyOp::kUpdate);
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 index, UInt32 op)
+{
+ COM_TRY_BEGIN
+
+ bool isDir = false;
+
+ if (indexType == NArchive::NEventIndexType::kOutArcIndex)
+ {
+ UString name;
+ if (index != (UInt32)(Int32)-1)
+ {
+ const CUpdatePair2 &up = (*UpdatePairs)[index];
+ if (up.ExistOnDisk())
+ {
+ name = DirItems->GetLogPath(up.DirIndex);
+ isDir = DirItems->Items[up.DirIndex].IsDir();
+ }
+ }
+ return Callback->ReportUpdateOpeartion(op, name.IsEmpty() ? NULL : name.Ptr(), isDir);
+ }
+
+ wchar_t temp[16];
+ UString s2;
+ const wchar_t *s = NULL;
+
+ if (indexType == NArchive::NEventIndexType::kInArcIndex)
+ {
+ if (index != (UInt32)(Int32)-1)
+ {
+ if (ArcItems)
+ {
+ const CArcItem &ai = (*ArcItems)[index];
+ s = ai.Name;
+ isDir = ai.IsDir;
+ }
+ else if (Arc)
+ {
+ RINOK(Arc->GetItemPath(index, s2));
+ s = s2;
+ RINOK(Archive_IsItem_Dir(Arc->Archive, index, isDir));
+ }
+ }
+ }
+ else if (indexType == NArchive::NEventIndexType::kBlockIndex)
+ {
+ temp[0] = '#';
+ ConvertUInt32ToString(index, temp + 1);
+ s = temp;
+ }
+
+ if (!s)
+ s = L"";
+
+ return Callback->ReportUpdateOpeartion(op, s, isDir);
+
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)
+{
+ COM_TRY_BEGIN
+
+ bool isEncrypted = false;
+ wchar_t temp[16];
+ UString s2;
+ const wchar_t *s = NULL;
+
+ if (indexType == NArchive::NEventIndexType::kOutArcIndex)
+ {
+ /*
+ UString name;
+ if (index != (UInt32)(Int32)-1)
+ {
+ const CUpdatePair2 &up = (*UpdatePairs)[index];
+ if (up.ExistOnDisk())
+ {
+ s2 = DirItems->GetLogPath(up.DirIndex);
+ s = s2;
+ }
+ }
+ */
+ return E_FAIL;
+ }
+
+ if (indexType == NArchive::NEventIndexType::kInArcIndex)
+ {
+ if (index != (UInt32)(Int32)-1)
+ {
+ if (ArcItems)
+ s = (*ArcItems)[index].Name;
+ else if (Arc)
+ {
+ RINOK(Arc->GetItemPath(index, s2));
+ s = s2;
+ }
+ if (Archive)
+ {
+ RINOK(Archive_GetItemBoolProp(Archive, index, kpidEncrypted, isEncrypted));
+ }
+ }
+ }
+ else if (indexType == NArchive::NEventIndexType::kBlockIndex)
+ {
+ temp[0] = '#';
+ ConvertUInt32ToString(index, temp + 1);
+ s = temp;
+ }
+
+ return Callback->ReportExtractResult(opRes, BoolToInt(isEncrypted), s);
+
COM_TRY_END
}
@@ -235,10 +695,10 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOu
FChar temp[16];
ConvertUInt32ToString(index + 1, temp);
FString res = temp;
- while (res.Length() < 2)
- res = FString(FTEXT('0')) + res;
+ while (res.Len() < 2)
+ res.InsertAtFront(FTEXT('0'));
FString fileName = VolName;
- fileName += L'.';
+ fileName += FTEXT('.');
fileName += res;
fileName += VolExt;
COutFileStream *streamSpec = new COutFileStream;
@@ -263,3 +723,37 @@ STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)
return Callback->CryptoGetTextPassword(password);
COM_TRY_END
}
+
+HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error)
+{
+ if (error == ERROR_LOCK_VIOLATION)
+ {
+ MT_LOCK
+ UInt32 index = (UInt32)val;
+ FOR_VECTOR(i, _openFiles_Indexes)
+ {
+ if (_openFiles_Indexes[i] == index)
+ {
+ RINOK(Callback->ReadingFileError(_openFiles_Paths[i], error));
+ break;
+ }
+ }
+ }
+ return HRESULT_FROM_WIN32(error);
+}
+
+void CArchiveUpdateCallback::InFileStream_On_Destroy(UINT_PTR val)
+{
+ MT_LOCK
+ UInt32 index = (UInt32)val;
+ FOR_VECTOR(i, _openFiles_Indexes)
+ {
+ if (_openFiles_Indexes[i] == index)
+ {
+ _openFiles_Indexes.Delete(i);
+ _openFiles_Paths.Delete(i);
+ return;
+ }
+ }
+ throw 20141125;
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.h b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.h
index 09f1c0d3705..4ff4a7ebe1d 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.h
@@ -1,10 +1,11 @@
// UpdateCallback.h
-#ifndef __UPDATECALLBACK_H
-#define __UPDATECALLBACK_H
+#ifndef __UPDATE_CALLBACK_H
+#define __UPDATE_CALLBACK_H
-#include "Common/MyCom.h"
-#include "Common/MyString.h"
+#include "../../../Common/MyCom.h"
+
+#include "../../Common/FileStreams.h"
#include "../../IPassword.h"
#include "../../ICoder.h"
@@ -12,64 +13,135 @@
#include "../Common/UpdatePair.h"
#include "../Common/UpdateProduce.h"
+#include "OpenArchive.h"
+
#define INTERFACE_IUpdateCallbackUI(x) \
+ virtual HRESULT WriteSfx(const wchar_t *name, UInt64 size) x; \
virtual HRESULT SetTotal(UInt64 size) x; \
virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \
virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) x; \
virtual HRESULT CheckBreak() x; \
- virtual HRESULT Finilize() x; \
- virtual HRESULT SetNumFiles(UInt64 numFiles) x; \
- virtual HRESULT GetStream(const wchar_t *name, bool isAnti) x; \
- virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError) x; \
- virtual HRESULT SetOperationResult(Int32 operationResult) x; \
+ /* virtual HRESULT Finalize() x; */ \
+ virtual HRESULT SetNumItems(UInt64 numItems) 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; \
+ virtual HRESULT SetOperationResult(Int32 opRes) x; \
+ virtual HRESULT ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) x; \
+ virtual HRESULT ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool isDir) x; \
+ /* virtual HRESULT SetPassword(const UString &password) x; */ \
virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \
virtual HRESULT CryptoGetTextPassword(BSTR *password) x; \
- /* virtual HRESULT ShowDeleteFile(const wchar_t *name) x; */ \
- /* virtual HRESULT CloseProgress() { return S_OK; }; */
+ virtual HRESULT ShowDeleteFile(const wchar_t *name, bool isDir) x; \
+ /* virtual HRESULT CloseProgress() { return S_OK; } */
struct IUpdateCallbackUI
{
INTERFACE_IUpdateCallbackUI(=0)
};
+struct CKeyKeyValPair
+{
+ UInt64 Key1;
+ UInt64 Key2;
+ unsigned Value;
+
+ int Compare(const CKeyKeyValPair &a) const
+ {
+ if (Key1 < a.Key1) return -1;
+ if (Key1 > a.Key1) return 1;
+ return MyCompare(Key2, a.Key2);
+ }
+};
+
+
class CArchiveUpdateCallback:
public IArchiveUpdateCallback2,
+ public IArchiveUpdateCallbackFile,
+ public IArchiveExtractCallbackMessage,
+ public IArchiveGetRawProps,
+ public IArchiveGetRootProps,
public ICryptoGetTextPassword2,
public ICryptoGetTextPassword,
public ICompressProgressInfo,
+ public IInFileStream_Callback,
public CMyUnknownImp
{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ bool _saclEnabled;
+ #endif
+ CRecordVector<CKeyKeyValPair> _map;
+
+ UInt32 _hardIndex_From;
+ UInt32 _hardIndex_To;
+
public:
- MY_UNKNOWN_IMP4(
- IArchiveUpdateCallback2,
- ICryptoGetTextPassword2,
- ICryptoGetTextPassword,
- ICompressProgressInfo)
+ MY_QUERYINTERFACE_BEGIN2(IArchiveUpdateCallback2)
+ MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackFile)
+ MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage)
+ MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
+ MY_QUERYINTERFACE_ENTRY(IArchiveGetRootProps)
+ MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword2)
+ MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword)
+ MY_QUERYINTERFACE_ENTRY(ICompressProgressInfo)
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
INTERFACE_IArchiveUpdateCallback2(;)
+ INTERFACE_IArchiveUpdateCallbackFile(;)
+ INTERFACE_IArchiveExtractCallbackMessage(;)
+ INTERFACE_IArchiveGetRawProps(;)
+ INTERFACE_IArchiveGetRootProps(;)
STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
-public:
+ CRecordVector<UInt32> _openFiles_Indexes;
+ FStringVector _openFiles_Paths;
+
+ bool AreAllFilesClosed() const { return _openFiles_Indexes.IsEmpty(); }
+ virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error);
+ virtual void InFileStream_On_Destroy(UINT_PTR val);
+
CRecordVector<UInt64> VolumesSizes;
FString VolName;
FString VolExt;
IUpdateCallbackUI *Callback;
- bool ShareForWrite;
- bool StdInMode;
const CDirItems *DirItems;
+ const CDirItem *ParentDirItem;
+
+ const CArc *Arc;
+ CMyComPtr<IInArchive> Archive;
const CObjectVector<CArcItem> *ArcItems;
const CRecordVector<CUpdatePair2> *UpdatePairs;
const UStringVector *NewNames;
- CMyComPtr<IInArchive> Archive;
+
+ bool ShareForWrite;
+ bool StdInMode;
+
bool KeepOriginalItemNames;
+ bool StoreNtSecurity;
+ bool StoreHardLinks;
+ bool StoreSymLinks;
+
+ Byte *ProcessedItemsStatuses;
+
CArchiveUpdateCallback();
+
+ bool IsDir(const CUpdatePair2 &up) const
+ {
+ if (up.DirIndex >= 0)
+ return DirItems->Items[up.DirIndex].IsDir();
+ else if (up.ArcIndex >= 0)
+ return (*ArcItems)[up.ArcIndex].IsDir;
+ return false;
+ }
};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp
index a43a9e77055..e21151974be 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp
@@ -4,10 +4,9 @@
#include <time.h>
-#include "Common/Defs.h"
-#include "Common/Wildcard.h"
+#include "../../../Common/Wildcard.h"
-#include "Windows/Time.h"
+#include "../../../Windows/TimeUtils.h"
#include "SortUtils.h"
#include "UpdatePair.h"
@@ -17,7 +16,7 @@ using namespace NTime;
static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time1, const FILETIME &time2)
{
- switch(fileTimeType)
+ switch (fileTimeType)
{
case NFileTimeType::kWindows:
return ::CompareFileTime(&time1, &time2);
@@ -39,24 +38,38 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time
throw 4191618;
}
-static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:";
-static const wchar_t *kNotCensoredCollisionMessaged = L"Internal file name collision (file on disk, file in archive):";
+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 void ThrowError(const UString &message, const UString &s1, const UString &s2)
+static void ThrowError(const char *message, const UString &s1, const UString &s2)
{
- UString m = message;
- m += L'\n';
- m += s1;
- m += L'\n';
- m += s2;
+ UString m;
+ m.SetFromAscii(message);
+ m.Add_LF(); m += s1;
+ m.Add_LF(); m += s2;
throw m;
}
-static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices)
+static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2)
{
- for(int i = 0; i + 1 < indices.Size(); i++)
- if (CompareFileNames(strings[indices[i]], strings[indices[i + 1]]) == 0)
- ThrowError(kDuplicateFileNameMessage, strings[indices[i]], strings[indices[i + 1]]);
+ int res = CompareFileNames(ai1.Name, ai2.Name);
+ if (res != 0)
+ return res;
+ if (ai1.IsDir != ai2.IsDir)
+ return ai1.IsDir ? -1 : 1;
+ return 0;
+}
+
+static int CompareArcItems(const unsigned *p1, const unsigned *p2, void *param)
+{
+ unsigned i1 = *p1;
+ unsigned i2 = *p2;
+ const CObjectVector<CArcItem> &arcItems = *(const CObjectVector<CArcItem> *)param;
+ int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]);
+ if (res != 0)
+ return res;
+ return MyCompare(i1, i2);
}
void GetUpdatePairInfoList(
@@ -65,48 +78,104 @@ void GetUpdatePairInfoList(
NFileTimeType::EEnum fileTimeType,
CRecordVector<CUpdatePair> &updatePairs)
{
- CIntVector dirIndices, arcIndices;
-
- int numDirItems = dirItems.Items.Size();
- int numArcItems = arcItems.Size();
+ CUIntVector dirIndices, arcIndices;
+ unsigned numDirItems = dirItems.Items.Size();
+ unsigned numArcItems = arcItems.Size();
+ CIntArr duplicatedArcItem(numArcItems);
{
- UStringVector arcNames;
- arcNames.Reserve(numArcItems);
- for (int i = 0; i < numArcItems; i++)
- arcNames.Add(arcItems[i].Name);
- SortFileNames(arcNames, arcIndices);
- TestDuplicateString(arcNames, arcIndices);
+ int *vals = &duplicatedArcItem[0];
+ for (unsigned i = 0; i < numArcItems; i++)
+ vals[i] = 0;
+ }
+
+ {
+ arcIndices.ClearAndSetSize(numArcItems);
+ if (numArcItems != 0)
+ {
+ unsigned *vals = &arcIndices[0];
+ for (unsigned i = 0; i < numArcItems; i++)
+ vals[i] = i;
+ }
+ arcIndices.Sort(CompareArcItems, (void *)&arcItems);
+ for (unsigned i = 0; i + 1 < numArcItems; i++)
+ if (CompareArcItemsBase(
+ arcItems[arcIndices[i]],
+ arcItems[arcIndices[i + 1]]) == 0)
+ {
+ duplicatedArcItem[i] = 1;
+ duplicatedArcItem[i + 1] = -1;
+ }
}
UStringVector dirNames;
{
- dirNames.Reserve(numDirItems);
- for (int i = 0; i < numDirItems; i++)
- dirNames.Add(dirItems.GetLogPath(i));
+ dirNames.ClearAndReserve(numDirItems);
+ unsigned i;
+ for (i = 0; i < numDirItems; i++)
+ dirNames.AddInReserved(dirItems.GetLogPath(i));
SortFileNames(dirNames, dirIndices);
- TestDuplicateString(dirNames, dirIndices);
+ for (i = 0; i + 1 < numDirItems; i++)
+ {
+ const UString &s1 = dirNames[dirIndices[i]];
+ const UString &s2 = dirNames[dirIndices[i + 1]];
+ if (CompareFileNames(s1, s2) == 0)
+ ThrowError(k_Duplicate_inDir_Message, s1, s2);
+ }
}
- int dirIndex = 0, arcIndex = 0;
- while (dirIndex < numDirItems && arcIndex < numArcItems)
+ unsigned dirIndex = 0;
+ unsigned arcIndex = 0;
+
+ int prevHostFile = -1;
+ const UString *prevHostName = NULL;
+
+ while (dirIndex < numDirItems || arcIndex < numArcItems)
{
CUpdatePair pair;
- int dirIndex2 = dirIndices[dirIndex];
- int arcIndex2 = arcIndices[arcIndex];
- const CDirItem &di = dirItems.Items[dirIndex2];
- const CArcItem &ai = arcItems[arcIndex2];
- int compareResult = CompareFileNames(dirNames[dirIndex2], ai.Name);
+
+ int dirIndex2 = -1;
+ int arcIndex2 = -1;
+ const CDirItem *di = NULL;
+ const CArcItem *ai = NULL;
+
+ int compareResult = -1;
+ const UString *name = NULL;
+
+ if (dirIndex < numDirItems)
+ {
+ dirIndex2 = dirIndices[dirIndex];
+ di = &dirItems.Items[dirIndex2];
+ }
+
+ if (arcIndex < numArcItems)
+ {
+ arcIndex2 = arcIndices[arcIndex];
+ ai = &arcItems[arcIndex2];
+ compareResult = 1;
+ if (dirIndex < numDirItems)
+ {
+ compareResult = CompareFileNames(dirNames[dirIndex2], ai->Name);
+ if (compareResult == 0)
+ {
+ if (di->IsDir() != ai->IsDir)
+ compareResult = (ai->IsDir ? 1 : -1);
+ }
+ }
+ }
+
if (compareResult < 0)
{
+ name = &dirNames[dirIndex2];
pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
pair.DirIndex = dirIndex2;
dirIndex++;
}
else if (compareResult > 0)
{
- pair.State = ai.Censored ?
+ name = &ai->Name;
+ pair.State = ai->Censored ?
NUpdateArchive::NPairState::kOnlyInArchive:
NUpdateArchive::NPairState::kNotMasked;
pair.ArcIndex = arcIndex2;
@@ -114,43 +183,50 @@ void GetUpdatePairInfoList(
}
else
{
- if (!ai.Censored)
- ThrowError(kNotCensoredCollisionMessaged, dirNames[dirIndex2], ai.Name);
+ int dupl = duplicatedArcItem[arcIndex];
+ if (dupl != 0)
+ ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[arcIndex + dupl]].Name);
+
+ name = &dirNames[dirIndex2];
+ if (!ai->Censored)
+ ThrowError(k_NotCensoredCollision_Message, *name, ai->Name);
+
pair.DirIndex = dirIndex2;
pair.ArcIndex = arcIndex2;
- switch (ai.MTimeDefined ? MyCompareTime(
- ai.TimeType != - 1 ? (NFileTimeType::EEnum)ai.TimeType : fileTimeType,
- di.MTime, ai.MTime): 0)
+
+ switch (ai->MTimeDefined ? MyCompareTime(
+ ai->TimeType != - 1 ? (NFileTimeType::EEnum)ai->TimeType : fileTimeType,
+ di->MTime, ai->MTime): 0)
{
case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break;
- case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break;
+ case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break;
default:
- pair.State = (ai.SizeDefined && di.Size == ai.Size) ?
+ pair.State = (ai->SizeDefined && di->Size == ai->Size) ?
NUpdateArchive::NPairState::kSameFiles :
NUpdateArchive::NPairState::kUnknowNewerFiles;
}
+
dirIndex++;
arcIndex++;
}
- updatePairs.Add(pair);
- }
-
- for (; dirIndex < numDirItems; dirIndex++)
- {
- CUpdatePair pair;
- pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
- pair.DirIndex = dirIndices[dirIndex];
- updatePairs.Add(pair);
- }
-
- for (; arcIndex < numArcItems; arcIndex++)
- {
- CUpdatePair pair;
- int arcIndex2 = arcIndices[arcIndex];
- pair.State = arcItems[arcIndex2].Censored ?
- NUpdateArchive::NPairState::kOnlyInArchive:
- NUpdateArchive::NPairState::kNotMasked;
- pair.ArcIndex = arcIndex2;
+
+ if ((di && di->IsAltStream) ||
+ (ai && ai->IsAltStream))
+ {
+ if (prevHostName)
+ {
+ unsigned hostLen = prevHostName->Len();
+ if (name->Len() > hostLen)
+ if ((*name)[hostLen] == ':' && CompareFileNames(*prevHostName, name->Left(hostLen)) == 0)
+ pair.HostIndex = prevHostFile;
+ }
+ }
+ else
+ {
+ prevHostFile = updatePairs.Size();
+ prevHostName = name;
+ }
+
updatePairs.Add(pair);
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.h b/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.h
index 3a332649c91..296d3b09745 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.h
@@ -13,7 +13,9 @@ struct CUpdatePair
NUpdateArchive::NPairState::EEnum State;
int ArcIndex;
int DirIndex;
- CUpdatePair(): ArcIndex(-1), DirIndex(-1) {}
+ int HostIndex; // >= 0 for alt streams only, contains index of host pair
+
+ CUpdatePair(): ArcIndex(-1), DirIndex(-1), HostIndex(-1) {}
};
void GetUpdatePairInfoList(
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp
index c21db3b2a63..e6eabcf148e 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp
@@ -14,32 +14,41 @@ void UpdateProduce(
CRecordVector<CUpdatePair2> &operationChain,
IUpdateProduceCallback *callback)
{
- for (int i = 0; i < updatePairs.Size(); i++)
+ FOR_VECTOR (i, updatePairs)
{
const CUpdatePair &pair = updatePairs[i];
CUpdatePair2 up2;
- up2.IsAnti = false;
up2.DirIndex = pair.DirIndex;
up2.ArcIndex = pair.ArcIndex;
up2.NewData = up2.NewProps = true;
+ up2.UseArcProps = false;
- switch(actionSet.StateActions[pair.State])
+ switch (actionSet.StateActions[(unsigned)pair.State])
{
case NPairAction::kIgnore:
- /*
- if (pair.State != NPairState::kOnlyOnDisk)
- IgnoreArchiveItem(m_ArchiveItems[pair.ArcIndex]);
- // cout << "deleting";
- */
- if (callback)
+ if (pair.ArcIndex >= 0 && callback)
callback->ShowDeleteFile(pair.ArcIndex);
continue;
case NPairAction::kCopy:
if (pair.State == NPairState::kOnlyOnDisk)
throw kUpdateActionSetCollision;
+ if (pair.State == NPairState::kOnlyInArchive)
+ {
+ if (pair.HostIndex >= 0)
+ {
+ /*
+ ignore alt stream if
+ 1) no such alt stream in Disk
+ 2) there is Host file in disk
+ */
+ if (updatePairs[pair.HostIndex].DirIndex >= 0)
+ continue;
+ }
+ }
up2.NewData = up2.NewProps = false;
+ up2.UseArcProps = true;
break;
case NPairAction::kCompress:
@@ -50,9 +59,12 @@ void UpdateProduce(
case NPairAction::kCompressAsAnti:
up2.IsAnti = true;
+ up2.UseArcProps = (pair.ArcIndex >= 0);
break;
}
+
operationChain.Add(up2);
}
+
operationChain.ReserveDown();
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.h b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.h
index e18648cd9bd..64c58cc5772 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.h
@@ -9,21 +9,41 @@ struct CUpdatePair2
{
bool NewData;
bool NewProps;
- bool IsAnti;
+ bool UseArcProps; // if (UseArcProps && NewProps), we want to change only some properties.
+ bool IsAnti; // if (!IsAnti) we use other ways to detect Anti status
int DirIndex;
int ArcIndex;
int NewNameIndex;
+ bool IsMainRenameItem;
+
+ void SetAs_NoChangeArcItem(int arcIndex)
+ {
+ NewData = NewProps = false;
+ UseArcProps = true;
+ IsAnti = false;
+ ArcIndex = arcIndex;
+ }
+
bool ExistOnDisk() const { return DirIndex != -1; }
bool ExistInArchive() const { return ArcIndex != -1; }
- CUpdatePair2(): IsAnti(false), DirIndex(-1), ArcIndex(-1), NewNameIndex(-1) {}
+ CUpdatePair2():
+ NewData(false),
+ NewProps(false),
+ UseArcProps(false),
+ IsAnti(false),
+ DirIndex(-1),
+ ArcIndex(-1),
+ NewNameIndex(-1),
+ IsMainRenameItem(false)
+ {}
};
struct IUpdateProduceCallback
{
- virtual HRESULT ShowDeleteFile(int arcIndex) = 0;
+ virtual HRESULT ShowDeleteFile(unsigned arcIndex) = 0;
};
void UpdateProduce(
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.cpp
index 1ecb5b54066..284eaa16ac3 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.cpp
@@ -2,21 +2,22 @@
#include "StdAfx.h"
-#include "Common/StringConvert.h"
-#include "Common/Wildcard.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/Wildcard.h"
-#include "Windows/FileName.h"
+#include "../../../Windows/FileName.h"
#include "WorkDir.h"
using namespace NWindows;
using namespace NFile;
-using namespace NDirectory;
+using namespace NDir;
FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName)
{
NWorkDir::NMode::EEnum mode = workDirInfo.Mode;
- #ifndef UNDER_CE
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
if (workDirInfo.ForRemovableOnly)
{
mode = NWorkDir::NMode::kCurrent;
@@ -36,13 +37,15 @@ FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FStr
*/
}
#endif
- int pos = path.ReverseFind(FCHAR_PATH_SEPARATOR) + 1;
- fileName = path.Mid(pos);
+
+ int pos = path.ReverseFind_PathSepar() + 1;
+ fileName = path.Ptr(pos);
+
switch (mode)
{
case NWorkDir::NMode::kCurrent:
{
- return path.Left(pos);;
+ return path.Left(pos);
}
case NWorkDir::NMode::kSpecified:
{
@@ -66,7 +69,7 @@ HRESULT CWorkDirTempFile::CreateTempFile(const FString &originalPath)
workDirInfo.Load();
FString namePart;
FString workDir = GetWorkDir(workDirInfo, originalPath, namePart);
- CreateComplexDirectory(workDir);
+ CreateComplexDir(workDir);
CTempFile tempFile;
_outStreamSpec = new COutFileStream;
OutStream = _outStreamSpec;
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.h b/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.h
index 79ea2b9d856..75850a92b1c 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.h
@@ -3,18 +3,18 @@
#ifndef __WORK_DIR_H
#define __WORK_DIR_H
-#include "Windows/FileDir.h"
-
-#include "ZipRegistry.h"
+#include "../../../Windows/FileDir.h"
#include "../../Common/FileStreams.h"
+#include "ZipRegistry.h"
+
FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName);
class CWorkDirTempFile
{
FString _originalPath;
- NWindows::NFile::NDirectory::CTempFile _tempFile;
+ NWindows::NFile::NDir::CTempFile _tempFile;
COutFileStream *_outStreamSpec;
public:
CMyComPtr<IOutStream> OutStream;
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ZipRegistry.h b/3rdparty/lzma/CPP/7zip/UI/Common/ZipRegistry.h
index 6d8b7c1337d..935f97bbaa4 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/ZipRegistry.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/ZipRegistry.h
@@ -3,8 +3,8 @@
#ifndef __ZIP_REGISTRY_H
#define __ZIP_REGISTRY_H
-#include "Common/MyString.h"
-#include "Common/Types.h"
+#include "../../../Common/MyTypes.h"
+#include "../../../Common/MyString.h"
#include "ExtractMode.h"
@@ -14,12 +14,21 @@ namespace NExtract
{
NPathMode::EEnum PathMode;
NOverwriteMode::EEnum OverwriteMode;
- bool ShowPassword;
+ bool PathMode_Force;
+ bool OverwriteMode_Force;
+
+ CBoolPair SplitDest;
+ CBoolPair ElimDup;
+ // CBoolPair AltStreams;
+ CBoolPair NtSecurity;
+ CBoolPair ShowPassword;
+
UStringVector Paths;
void Save() const;
void Load();
};
+
void Save_ShowPassword(bool showPassword);
bool Read_ShowPassword();
}
@@ -59,6 +68,11 @@ namespace NCompression
CObjectVector<CFormatOptions> Formats;
+ CBoolPair NtSecurity;
+ CBoolPair AltStreams;
+ CBoolPair HardLinks;
+ CBoolPair SymLinks;
+
void Save() const;
void Load();
};
@@ -97,7 +111,11 @@ namespace NWorkDir
struct CContextMenuInfo
{
- bool Cascaded;
+ CBoolPair Cascaded;
+ CBoolPair MenuIcons;
+ CBoolPair ElimDup;
+
+ bool Flags_Def;
UInt32 Flags;
void Save() const;
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp
index d0e432226a6..a7c9e6762c8 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp
@@ -23,7 +23,7 @@ void CPrintBenchCallback::Print(const char *s)
void CPrintBenchCallback::NewLine()
{
- Print("\n");
+ fputc('\n', _file);
}
HRESULT CPrintBenchCallback::CheckBreak()
@@ -32,11 +32,10 @@ HRESULT CPrintBenchCallback::CheckBreak()
}
HRESULT BenchCon(DECL_EXTERNAL_CODECS_LOC_VARS
- const CObjectVector<CProperty> props, UInt32 numIterations, FILE *f)
+ const CObjectVector<CProperty> &props, UInt32 numIterations, FILE *f)
{
CPrintBenchCallback callback;
callback._file = f;
- callback.NewLine();
return Bench(EXTERNAL_CODECS_LOC_VARS
&callback, NULL, props, numIterations, true);
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h b/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h
index 739721864bb..c9da1de399c 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h
@@ -9,6 +9,6 @@
#include "../../UI/Common/Property.h"
HRESULT BenchCon(DECL_EXTERNAL_CODECS_LOC_VARS
- const CObjectVector<CProperty> props, UInt32 numIterations, FILE *f);
+ const CObjectVector<CProperty> &props, UInt32 numIterations, FILE *f);
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/Console.mak b/3rdparty/lzma/CPP/7zip/UI/Console/Console.mak
new file mode 100644
index 00000000000..05a07e5ad8a
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/Console.mak
@@ -0,0 +1,36 @@
+CONSOLE_OBJS = \
+ $O\BenchCon.obj \
+ $O\ConsoleClose.obj \
+ $O\ExtractCallbackConsole.obj \
+ $O\HashCon.obj \
+ $O\List.obj \
+ $O\Main.obj \
+ $O\MainAr.obj \
+ $O\OpenCallbackConsole.obj \
+ $O\PercentPrinter.obj \
+ $O\UpdateCallbackConsole.obj \
+ $O\UserInputUtils.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveCommandLine.obj \
+ $O\ArchiveExtractCallback.obj \
+ $O\ArchiveOpenCallback.obj \
+ $O\Bench.obj \
+ $O\DefaultName.obj \
+ $O\EnumDirItems.obj \
+ $O\Extract.obj \
+ $O\ExtractingFilePath.obj \
+ $O\HashCalc.obj \
+ $O\LoadCodecs.obj \
+ $O\OpenArchive.obj \
+ $O\PropIDUtils.obj \
+ $O\SetProperties.obj \
+ $O\SortUtils.obj \
+ $O\TempFiles.obj \
+ $O\Update.obj \
+ $O\UpdateAction.obj \
+ $O\UpdateCallback.obj \
+ $O\UpdatePair.obj \
+ $O\UpdateProduce.obj \
+
+#
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp
index 5acae942dd8..734981886d0 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp
@@ -4,11 +4,15 @@
#include "ConsoleClose.h"
-static int g_BreakCounter = 0;
-static const int kBreakAbortThreshold = 2;
+#if !defined(UNDER_CE) && defined(_WIN32)
+#include "../../../Common/MyWindows.h"
+#endif
namespace NConsoleClose {
+unsigned g_BreakCounter = 0;
+static const unsigned kBreakAbortThreshold = 2;
+
#if !defined(UNDER_CE) && defined(_WIN32)
static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
{
@@ -23,7 +27,7 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
return TRUE;
return FALSE;
/*
- switch(ctrlType)
+ switch (ctrlType)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
@@ -35,29 +39,18 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
}
#endif
-bool TestBreakSignal()
-{
- #ifdef UNDER_CE
- return false;
- #else
- /*
- if (g_BreakCounter > 0)
- return true;
- */
- return (g_BreakCounter > 0);
- #endif
-}
-
+/*
void CheckCtrlBreak()
{
if (TestBreakSignal())
throw CCtrlBreakException();
}
+*/
CCtrlHandlerSetter::CCtrlHandlerSetter()
{
#if !defined(UNDER_CE) && defined(_WIN32)
- if(!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
+ if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
throw "SetConsoleCtrlHandler fails";
#endif
}
@@ -65,7 +58,7 @@ CCtrlHandlerSetter::CCtrlHandlerSetter()
CCtrlHandlerSetter::~CCtrlHandlerSetter()
{
#if !defined(UNDER_CE) && defined(_WIN32)
- if(!SetConsoleCtrlHandler(HandlerRoutine, FALSE))
+ if (!SetConsoleCtrlHandler(HandlerRoutine, FALSE))
throw "SetConsoleCtrlHandler fails";
#endif
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h b/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h
index 9019c4ce2bd..11c1631ca71 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h
@@ -1,11 +1,20 @@
-// ConsoleCloseUtils.h
+// ConsoleClose.h
-#ifndef __CONSOLECLOSEUTILS_H
-#define __CONSOLECLOSEUTILS_H
+#ifndef __CONSOLE_CLOSE_H
+#define __CONSOLE_CLOSE_H
namespace NConsoleClose {
-bool TestBreakSignal();
+extern unsigned g_BreakCounter;
+
+inline bool TestBreakSignal()
+{
+ #ifdef UNDER_CE
+ return false;
+ #else
+ return (g_BreakCounter != 0);
+ #endif
+}
class CCtrlHandlerSetter
{
@@ -17,7 +26,7 @@ public:
class CCtrlBreakException
{};
-void CheckCtrlBreak();
+// void CheckCtrlBreak();
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
index af379861737..8dac7fbc3e9 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
@@ -1,40 +1,156 @@
-// ExtractCallbackConsole.h
+// ExtractCallbackConsole.cpp
#include "StdAfx.h"
-#include "ExtractCallbackConsole.h"
-#include "UserInputUtils.h"
-#include "ConsoleClose.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/Wildcard.h"
-#include "Common/Wildcard.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/TimeUtils.h"
+#include "../../../Windows/ErrorMsg.h"
+#include "../../../Windows/PropVariantConv.h"
-#include "Windows/FileDir.h"
-#include "Windows/FileFind.h"
-#include "Windows/Time.h"
-#include "Windows/Defs.h"
-#include "Windows/PropVariant.h"
-#include "Windows/Error.h"
-#include "Windows/PropVariantConversions.h"
+#ifndef _7ZIP_ST
+#include "../../../Windows/Synchronization.h"
+#endif
#include "../../Common/FilePathAutoRename.h"
#include "../Common/ExtractingFilePath.h"
+#include "ConsoleClose.h"
+#include "ExtractCallbackConsole.h"
+#include "UserInputUtils.h"
+
using namespace NWindows;
using namespace NFile;
-using namespace NDirectory;
+using namespace NDir;
-static const char *kTestString = "Testing ";
-static const char *kExtractString = "Extracting ";
-static const char *kSkipString = "Skipping ";
+static HRESULT CheckBreak2()
+{
+ return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK;
+}
+
+static const char *kError = "ERROR: ";
+
+
+void CExtractScanConsole::StartScanning()
+{
+ if (NeedPercents())
+ _percent.Command = "Scan";
+}
+
+HRESULT CExtractScanConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */)
+{
+ if (NeedPercents())
+ {
+ _percent.Files = st.NumDirs + st.NumFiles;
+ _percent.Completed = st.GetTotalBytes();
+ _percent.FileName = fs2us(path);
+ _percent.Print();
+ }
+
+ return CheckBreak2();
+}
+
+HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError)
+{
+ ClosePercentsAndFlush();
+
+ if (_se)
+ {
+ *_se << endl << kError << NError::MyFormatMessage(systemError) << endl <<
+ fs2us(path) << endl << endl;
+ _se->Flush();
+ }
+ return HRESULT_FROM_WIN32(systemError);
+}
+
+
+void Print_UInt64_and_String(AString &s, UInt64 val, const char *name)
+{
+ char temp[32];
+ ConvertUInt64ToString(val, temp);
+ s += temp;
+ s.Add_Space();
+ s += name;
+}
+
+void PrintSize_bytes_Smart(AString &s, UInt64 val)
+{
+ Print_UInt64_and_String(s, val, "bytes");
+
+ if (val == 0)
+ return;
+
+ unsigned numBits = 10;
+ char c = 'K';
+ char temp[4] = { 'K', 'i', 'B', 0 };
+ if (val >= ((UInt64)10 << 30)) { numBits = 30; c = 'G'; }
+ else if (val >= ((UInt64)10 << 20)) { numBits = 20; c = 'M'; }
+ temp[0] = c;
+ s += " (";
+ Print_UInt64_and_String(s, ((val + ((UInt64)1 << numBits) - 1) >> numBits), temp);
+ s += ')';
+}
+
+void Print_DirItemsStat(AString &s, const CDirItemsStat &st)
+{
+ if (st.NumDirs != 0)
+ {
+ Print_UInt64_and_String(s, st.NumDirs, st.NumDirs == 1 ? "folder" : "folders");
+ s += ", ";
+ }
+ Print_UInt64_and_String(s, st.NumFiles, st.NumFiles == 1 ? "file" : "files");
+ s += ", ";
+ PrintSize_bytes_Smart(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);
+ }
+}
+
+void CExtractScanConsole::PrintStat(const CDirItemsStat &st)
+{
+ if (_so)
+ {
+ AString s;
+ Print_DirItemsStat(s, st);
+ *_so << s << endl;
+ }
+}
+
+
+
+
+
+
+
+#ifndef _7ZIP_ST
+static NSynchronization::CCriticalSection g_CriticalSection;
+#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+#else
+#define MT_LOCK
+#endif
+
+
+static const char *kTestString = "T";
+static const char *kExtractString = "-";
+static const char *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 *kError = "ERROR: ";
+
static const char *kMemoryExceptionMessage = "Can't allocate required memory!";
-static const char *kProcessing = "Processing archive: ";
+static const char *kExtracting = "Extracting archive: ";
+static const char *kTesting = "Testing archive: ";
+
static const char *kEverythingIsOk = "Everything is Ok";
static const char *kNoFiles = "No files to process";
@@ -43,34 +159,96 @@ 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 *kUnknownError = "Unknown 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";
+static const char *kWrongPassword = "Wrong password";
-STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64)
+static const char * const k_ErrorFlagsMessages[] =
{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- return S_OK;
+ "Is not archive"
+ , "Headers Error"
+ , "Headers Error in encrypted archive. Wrong password?"
+ , "Unavailable start of archive"
+ , "Unconfirmed start of archive"
+ , "Unexpected end of archive"
+ , "There are data after the end of archive"
+ , "Unsupported method"
+ , "Unsupported feature"
+ , "Data Error"
+ , "CRC Error"
+};
+
+STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64 size)
+{
+ MT_LOCK
+
+ if (NeedPercents())
+ {
+ _percent.Total = size;
+ _percent.Print();
+ }
+ return CheckBreak2();
}
-STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *)
+STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue)
{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- return S_OK;
+ MT_LOCK
+
+ if (NeedPercents())
+ {
+ if (completeValue)
+ _percent.Completed = *completeValue;
+ _percent.Print();
+ }
+ return CheckBreak2();
+}
+
+static const char *kTab = " ";
+
+static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size)
+{
+ *_so << kTab << "Path: " << path << endl;
+ if (size)
+ {
+ AString s;
+ PrintSize_bytes_Smart(s, *size);
+ *_so << kTab << "Size: " << s << endl;
+ }
+ if (ft)
+ {
+ char temp[64];
+ FILETIME locTime;
+ if (FileTimeToLocalFileTime(ft, &locTime))
+ if (ConvertFileTimeToString(locTime, temp, true, true))
+ *_so << kTab << "Modified: " << temp << endl;
+ }
}
STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
- const wchar_t *existName, const FILETIME *, const UInt64 *,
- const wchar_t *newName, const FILETIME *, const UInt64 *,
+ const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
+ const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
Int32 *answer)
{
- (*OutStream) << "file " << existName <<
- "\nalready exists. Overwrite with " << endl;
- (*OutStream) << newName;
+ MT_LOCK
+
+ RINOK(CheckBreak2());
+
+ ClosePercentsAndFlush();
+
+ if (_so)
+ {
+ *_so << endl << "Would you like to replace the existing file:\n";
+ PrintFileInfo(_so, existName, existTime, existSize);
+ *_so << "with the file from archive:\n";
+ PrintFileInfo(_so, newName, newTime, newSize);
+ }
- NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream);
+ NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(_so);
- switch(overwriteAnswer)
+ switch (overwriteAnswer)
{
case NUserAnswerMode::kQuit: return E_ABORT;
case NUserAnswerMode::kNo: *answer = NOverwriteAnswer::kNo; break;
@@ -80,62 +258,192 @@ STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
case NUserAnswerMode::kAutoRenameAll: *answer = NOverwriteAnswer::kAutoRename; break;
default: return E_FAIL;
}
- return S_OK;
+
+ if (_so)
+ {
+ *_so << endl;
+ if (NeedFlush)
+ _so->Flush();
+ }
+
+ return CheckBreak2();
}
-STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, bool /* isFolder */, Int32 askExtractMode, const UInt64 *position)
+STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 /* isFolder */, Int32 askExtractMode, const UInt64 *position)
{
+ MT_LOCK
+
+ _currentName = name;
+
+ const char *s;
+ unsigned requiredLevel = 1;
+
switch (askExtractMode)
{
- case NArchive::NExtract::NAskMode::kExtract: (*OutStream) << kExtractString; break;
- case NArchive::NExtract::NAskMode::kTest: (*OutStream) << kTestString; break;
- case NArchive::NExtract::NAskMode::kSkip: (*OutStream) << kSkipString; break;
+ case NArchive::NExtract::NAskMode::kExtract: s = kExtractString; break;
+ case NArchive::NExtract::NAskMode::kTest: s = kTestString; break;
+ case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; requiredLevel = 2; break;
+ default: s = "???"; requiredLevel = 2;
};
- (*OutStream) << name;
- if (position != 0)
- (*OutStream) << " <" << *position << ">";
- return S_OK;
+
+ bool show2 = (LogLevel >= requiredLevel && _so);
+
+ if (show2)
+ {
+ ClosePercents_for_so();
+
+ _tempA = s;
+ if (name)
+ _tempA.Add_Space();
+ *_so << _tempA;
+
+ _tempU.Empty();
+ if (name)
+ _tempU = name;
+ _so->PrintUString(_tempU, _tempA);
+ if (position)
+ *_so << " <" << *position << ">";
+ *_so << endl;
+
+ if (NeedFlush)
+ _so->Flush();
+ }
+
+ if (NeedPercents())
+ {
+ if (PercentsNameLevel >= 1)
+ {
+ _percent.FileName.Empty();
+ _percent.Command.Empty();
+ if (PercentsNameLevel > 1 || !show2)
+ {
+ _percent.Command = s;
+ if (name)
+ _percent.FileName = name;
+ }
+ }
+ _percent.Print();
+ }
+
+ return CheckBreak2();
}
STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message)
{
- (*OutStream) << message << endl;
- NumFileErrorsInCurrentArchive++;
+ MT_LOCK
+
+ RINOK(CheckBreak2());
+
+ NumFileErrors_in_Current++;
NumFileErrors++;
- return S_OK;
+
+ ClosePercentsAndFlush();
+ if (_se)
+ {
+ *_se << kError << message << endl;
+ _se->Flush();
+ }
+
+ return CheckBreak2();
+}
+
+void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest)
+{
+ dest.Empty();
+ const char *s = NULL;
+
+ switch (opRes)
+ {
+ case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
+ s = kUnsupportedMethod;
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ s = (encrypted ? kCrcFailedEncrypted : kCrcFailed);
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ s = (encrypted ? kDataErrorEncrypted : kDataError);
+ break;
+ case NArchive::NExtract::NOperationResult::kUnavailable:
+ s = kUnavailableData;
+ break;
+ case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
+ s = kUnexpectedEnd;
+ break;
+ case NArchive::NExtract::NOperationResult::kDataAfterEnd:
+ s = kDataAfterEnd;
+ break;
+ case NArchive::NExtract::NOperationResult::kIsNotArc:
+ s = kIsNotArc;
+ break;
+ case NArchive::NExtract::NOperationResult::kHeadersError:
+ s = kHeadersError;
+ break;
+ case NArchive::NExtract::NOperationResult::kWrongPassword:
+ s = kWrongPassword;
+ break;
+ }
+
+ dest += kError;
+ if (s)
+ dest += s;
+ else
+ {
+ char temp[16];
+ ConvertUInt32ToString(opRes, temp);
+ dest += "Error #";
+ dest += temp;
+ }
}
-STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted)
+STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encrypted)
{
- switch(operationResult)
+ MT_LOCK
+
+ if (opRes == NArchive::NExtract::NOperationResult::kOK)
{
- case NArchive::NExtract::NOperationResult::kOK:
- break;
- default:
+ if (NeedPercents())
{
- NumFileErrorsInCurrentArchive++;
- NumFileErrors++;
- (*OutStream) << " ";
- switch(operationResult)
- {
- case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
- (*OutStream) << kUnsupportedMethod;
- break;
- case NArchive::NExtract::NOperationResult::kCRCError:
- (*OutStream) << (encrypted ? kCrcFailedEncrypted: kCrcFailed);
- break;
- case NArchive::NExtract::NOperationResult::kDataError:
- (*OutStream) << (encrypted ? kDataErrorEncrypted : kDataError);
- break;
- default:
- (*OutStream) << kUnknownError;
- }
+ _percent.Command.Empty();
+ _percent.FileName.Empty();
+ _percent.Files++;
}
}
- (*OutStream) << endl;
- return S_OK;
+ else
+ {
+ NumFileErrors_in_Current++;
+ NumFileErrors++;
+
+ if (_se)
+ {
+ ClosePercentsAndFlush();
+
+ AString s;
+ SetExtractErrorMessage(opRes, encrypted, s);
+
+ *_se << s;
+ if (!_currentName.IsEmpty())
+ *_se << " : " << _currentName;
+ *_se << endl;
+ _se->Flush();
+ }
+ }
+
+ return CheckBreak2();
+}
+
+STDMETHODIMP CExtractCallbackConsole::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)
+{
+ if (opRes != NArchive::NExtract::NOperationResult::kOK)
+ {
+ _currentName = name;
+ return SetOperationResult(opRes, encrypted);
+ }
+
+ return CheckBreak2();
}
+
+
#ifndef _NO_CRYPTO
HRESULT CExtractCallbackConsole::SetPassword(const UString &password)
@@ -147,78 +455,310 @@ HRESULT CExtractCallbackConsole::SetPassword(const UString &password)
STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)
{
- if (!PasswordIsDefined)
- {
- Password = GetPassword(OutStream);
- PasswordIsDefined = true;
- }
- return StringToBstr(Password, password);
+ COM_TRY_BEGIN
+ MT_LOCK
+ return Open_CryptoGetTextPassword(password);
+ COM_TRY_END
}
#endif
-HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name)
+HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name, bool testMode)
{
- NumArchives++;
- NumFileErrorsInCurrentArchive = 0;
- (*OutStream) << endl << kProcessing << name << endl;
+ RINOK(CheckBreak2());
+
+ NumTryArcs++;
+ ThereIsError_in_Current = false;
+ ThereIsWarning_in_Current = false;
+ NumFileErrors_in_Current = 0;
+
+ ClosePercents_for_so();
+ if (_so)
+ *_so << endl << (testMode ? kTesting : kExtracting) << name << endl;
+
+ if (NeedPercents())
+ _percent.Command = "Open";
return S_OK;
}
-HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT result, bool encrypted)
+HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink);
+HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink);
+
+static AString GetOpenArcErrorMessage(UInt32 errorFlags)
{
- (*OutStream) << endl;
- if (result != S_OK)
+ AString s;
+
+ for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsMessages); i++)
+ {
+ UInt32 f = (1 << i);
+ if ((errorFlags & f) == 0)
+ continue;
+ const char *m = k_ErrorFlagsMessages[i];
+ if (!s.IsEmpty())
+ s.Add_LF();
+ s += m;
+ errorFlags &= ~f;
+ }
+
+ if (errorFlags != 0)
{
- (*OutStream) << "Error: ";
- if (result == S_FALSE)
+ char sz[16];
+ sz[0] = '0';
+ sz[1] = 'x';
+ ConvertUInt32ToHex(errorFlags, sz + 2);
+ if (!s.IsEmpty())
+ s.Add_LF();
+ s += sz;
+ }
+
+ return s;
+}
+
+void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags)
+{
+ if (errorFlags == 0)
+ return;
+ so << s << endl << GetOpenArcErrorMessage(errorFlags) << endl;
+}
+
+void Add_Messsage_Pre_ArcType(UString &s, const char *pre, const wchar_t *arcType)
+{
+ s.Add_LF();
+ s.AddAscii(pre);
+ s.AddAscii(" as [");
+ s += arcType;
+ s.AddAscii("] 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;
+ if (arc.FormatIndex == er.ErrorFormatIndex)
+ {
+ s.Add_LF();
+ s.AddAscii("The archive is open with offset");
+ }
+ else
+ {
+ Add_Messsage_Pre_ArcType(s, "Can not open the file", codecs->GetFormatNamePtr(er.ErrorFormatIndex));
+ Add_Messsage_Pre_ArcType(s, "The file is open", codecs->GetFormatNamePtr(arc.FormatIndex));
+ }
+
+ *_so << s << endl << endl;
+}
+
+
+HRESULT CExtractCallbackConsole::OpenResult(
+ const CCodecs *codecs, const CArchiveLink &arcLink,
+ const wchar_t *name, HRESULT result)
+{
+ ClosePercents();
+
+ if (NeedPercents())
+ {
+ _percent.Files = 0;
+ _percent.Command.Empty();
+ _percent.FileName.Empty();
+ }
+
+
+ ClosePercentsAndFlush();
+
+ FOR_VECTOR (level, arcLink.Arcs)
+ {
+ const CArc &arc = arcLink.Arcs[level];
+ const CArcErrorInfo &er = arc.ErrorInfo;
+
+ UInt32 errorFlags = er.GetErrorFlags();
+
+ if (errorFlags != 0 || !er.ErrorMessage.IsEmpty())
{
- (*OutStream) << (encrypted ?
- "Can not open encrypted archive. Wrong password?" :
- "Can not open file as archive");
+ if (_se)
+ {
+ *_se << endl;
+ if (level != 0)
+ *_se << arc.Path << endl;
+ }
+
+ if (errorFlags != 0)
+ {
+ if (_se)
+ PrintErrorFlags(*_se, "ERRORS:", errorFlags);
+ NumOpenArcErrors++;
+ ThereIsError_in_Current = true;
+ }
+
+ if (!er.ErrorMessage.IsEmpty())
+ {
+ if (_se)
+ *_se << "ERRORS:" << endl << er.ErrorMessage << endl;
+ NumOpenArcErrors++;
+ ThereIsError_in_Current = true;
+ }
+
+ if (_se)
+ {
+ *_se << endl;
+ _se->Flush();
+ }
}
- else
+
+ UInt32 warningFlags = er.GetWarningFlags();
+
+ if (warningFlags != 0 || !er.WarningMessage.IsEmpty())
{
- if (result == E_OUTOFMEMORY)
- (*OutStream) << "Can't allocate required memory";
+ if (_so)
+ {
+ *_so << endl;
+ if (level != 0)
+ *_so << arc.Path << endl;
+ }
+
+ if (warningFlags != 0)
+ {
+ if (_so)
+ PrintErrorFlags(*_so, "WARNINGS:", warningFlags);
+ NumOpenArcWarnings++;
+ ThereIsWarning_in_Current = true;
+ }
+
+ if (!er.WarningMessage.IsEmpty())
+ {
+ if (_so)
+ *_so << "WARNINGS:" << endl << er.WarningMessage << endl;
+ NumOpenArcWarnings++;
+ ThereIsWarning_in_Current = true;
+ }
+
+ if (_so)
+ {
+ *_so << endl;
+ if (NeedFlush)
+ _so->Flush();
+ }
+ }
+
+
+ if (er.ErrorFormatIndex >= 0)
+ {
+ if (_so)
+ {
+ Print_ErrorFormatIndex_Warning(_so, codecs, arc);
+ if (NeedFlush)
+ _so->Flush();
+ }
+ ThereIsWarning_in_Current = true;
+ }
+ }
+
+ if (result == S_OK)
+ {
+ if (_so)
+ {
+ RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink));
+ *_so << endl;
+ }
+ }
+ else
+ {
+ NumCantOpenArcs++;
+ if (_so)
+ _so->Flush();
+ if (_se)
+ {
+ *_se << kError << name << endl;
+ HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink);
+ RINOK(res);
+ if (result == S_FALSE)
+ {
+ }
else
- (*OutStream) << NError::MyFormatMessageW(result);
+ {
+ if (result == E_OUTOFMEMORY)
+ *_se << "Can't allocate required memory";
+ else
+ *_se << NError::MyFormatMessage(result);
+ *_se << endl;
+ }
+ _se->Flush();
}
- (*OutStream) << endl;
- NumArchiveErrors++;
}
- return S_OK;
+
+
+ return CheckBreak2();
}
HRESULT CExtractCallbackConsole::ThereAreNoFiles()
{
- (*OutStream) << endl << kNoFiles << endl;
- return S_OK;
+ ClosePercents_for_so();
+
+ if (_so)
+ {
+ *_so << endl << kNoFiles << endl;
+ if (NeedFlush)
+ _so->Flush();
+ }
+ return CheckBreak2();
}
HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)
{
+ MT_LOCK
+
+ if (NeedPercents())
+ {
+ _percent.ClosePrint(true);
+ _percent.Command.Empty();
+ _percent.FileName.Empty();
+ }
+
+ if (_so)
+ _so->Flush();
+
if (result == S_OK)
{
- (*OutStream) << endl;
- if (NumFileErrorsInCurrentArchive == 0)
- (*OutStream) << kEverythingIsOk << endl;
+ if (NumFileErrors_in_Current == 0 && !ThereIsError_in_Current)
+ {
+ if (ThereIsWarning_in_Current)
+ NumArcsWithWarnings++;
+ else
+ NumOkArcs++;
+ if (_so)
+ *_so << kEverythingIsOk << endl;
+ }
else
{
- NumArchiveErrors++;
- (*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl;
+ NumArcsWithError++;
+ if (_so)
+ {
+ *_so << endl;
+ if (NumFileErrors_in_Current != 0)
+ *_so << "Sub items Errors: " << NumFileErrors_in_Current << endl;
+ }
}
+ if (_so && NeedFlush)
+ _so->Flush();
}
- if (result == S_OK)
- return result;
- NumArchiveErrors++;
- if (result == E_ABORT || result == ERROR_DISK_FULL)
- return result;
- (*OutStream) << endl << kError;
- if (result == E_OUTOFMEMORY)
- (*OutStream) << kMemoryExceptionMessage;
else
- (*OutStream) << NError::MyFormatMessageW(result);
- (*OutStream) << endl;
- return S_OK;
+ {
+ NumArcsWithError++;
+ if (result == E_ABORT || result == ERROR_DISK_FULL)
+ return result;
+
+ if (_se)
+ {
+ *_se << endl << kError;
+ if (result == E_OUTOFMEMORY)
+ *_se << kMemoryExceptionMessage;
+ else
+ *_se << NError::MyFormatMessage(result);
+ *_se << endl;
+ _se->Flush();
+ }
+ }
+
+ return CheckBreak2();
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h b/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h
index e42ca6f403b..dc659521e03 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h
@@ -1,24 +1,95 @@
// ExtractCallbackConsole.h
-#ifndef __EXTRACTCALLBACKCONSOLE_H
-#define __EXTRACTCALLBACKCONSOLE_H
+#ifndef __EXTRACT_CALLBACK_CONSOLE_H
+#define __EXTRACT_CALLBACK_CONSOLE_H
+
+#include "../../../Common/StdOutStream.h"
-#include "Common/MyString.h"
-#include "Common/StdOutStream.h"
-#include "../../Common/FileStreams.h"
#include "../../IPassword.h"
+
#include "../../Archive/IArchive.h"
+
#include "../Common/ArchiveExtractCallback.h"
+#include "PercentPrinter.h"
+
+#include "OpenCallbackConsole.h"
+
+class CExtractScanConsole: public IDirItemsCallback
+{
+ CStdOutStream *_so;
+ CStdOutStream *_se;
+ CPercentPrinter _percent;
+
+ bool NeedPercents() const { return _percent._so != NULL; }
+
+ void ClosePercentsAndFlush()
+ {
+ if (NeedPercents())
+ _percent.ClosePrint(true);
+ if (_so)
+ _so->Flush();
+ }
+
+public:
+ void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
+ {
+ _so = outStream;
+ _se = errorStream;
+ _percent._so = percentStream;
+ }
+
+ void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
+
+ void StartScanning();
+
+ INTERFACE_IDirItemsCallback(;)
+
+ void CloseScanning()
+ {
+ if (NeedPercents())
+ _percent.ClosePrint(true);
+ }
+
+ void PrintStat(const CDirItemsStat &st);
+};
+
+
+
+
class CExtractCallbackConsole:
public IExtractCallbackUI,
+ // public IArchiveExtractCallbackMessage,
+ public IFolderArchiveExtractCallback2,
#ifndef _NO_CRYPTO
public ICryptoGetTextPassword,
#endif
+ public COpenCallbackConsole,
public CMyUnknownImp
{
+ AString _tempA;
+ UString _tempU;
+
+ UString _currentName;
+
+ void ClosePercents_for_so()
+ {
+ if (NeedPercents() && _so == _percent._so)
+ _percent.ClosePrint(false);
+ }
+
+ void ClosePercentsAndFlush()
+ {
+ if (NeedPercents())
+ _percent.ClosePrint(true);
+ if (_so)
+ _so->Flush();
+ }
+
public:
MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback)
+ // MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage)
+ MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback2)
#ifndef _NO_CRYPTO
MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword)
#endif
@@ -28,46 +99,66 @@ public:
STDMETHOD(SetTotal)(UInt64 total);
STDMETHOD(SetCompleted)(const UInt64 *completeValue);
- // IFolderArchiveExtractCallback
- STDMETHOD(AskOverwrite)(
- const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
- const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
- Int32 *answer);
- STDMETHOD (PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position);
-
- STDMETHOD(MessageError)(const wchar_t *message);
- STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted);
+ INTERFACE_IFolderArchiveExtractCallback(;)
- HRESULT BeforeOpen(const wchar_t *name);
- HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted);
- HRESULT ThereAreNoFiles();
- HRESULT ExtractResult(HRESULT result);
+ INTERFACE_IExtractCallbackUI(;)
+ // INTERFACE_IArchiveExtractCallbackMessage(;)
+ INTERFACE_IFolderArchiveExtractCallback2(;)
-
#ifndef _NO_CRYPTO
- HRESULT SetPassword(const UString &password);
- STDMETHOD(CryptoGetTextPassword)(BSTR *password);
- bool PasswordIsDefined;
- UString Password;
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
#endif
- UInt64 NumArchives;
- UInt64 NumArchiveErrors;
+ UInt64 NumTryArcs;
+
+ bool ThereIsError_in_Current;
+ bool ThereIsWarning_in_Current;
+
+ UInt64 NumOkArcs;
+ UInt64 NumCantOpenArcs;
+ UInt64 NumArcsWithError;
+ UInt64 NumArcsWithWarnings;
+
+ UInt64 NumOpenArcErrors;
+ UInt64 NumOpenArcWarnings;
+
UInt64 NumFileErrors;
- UInt64 NumFileErrorsInCurrentArchive;
+ UInt64 NumFileErrors_in_Current;
+
+ bool NeedFlush;
+ unsigned PercentsNameLevel;
+ unsigned LogLevel;
- CStdOutStream *OutStream;
+ CExtractCallbackConsole():
+ NeedFlush(false),
+ PercentsNameLevel(1),
+ LogLevel(0)
+ {}
- void Init()
+ void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
+
+ void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
{
- NumArchives = 0;
- NumArchiveErrors = 0;
+ COpenCallbackConsole::Init(outStream, errorStream, percentStream);
+
+ NumTryArcs = 0;
+
+ ThereIsError_in_Current = false;
+ ThereIsWarning_in_Current = false;
+
+ NumOkArcs = 0;
+ NumCantOpenArcs = 0;
+ NumArcsWithError = 0;
+ NumArcsWithWarnings = 0;
+
+ NumOpenArcErrors = 0;
+ NumOpenArcWarnings = 0;
+
NumFileErrors = 0;
- NumFileErrorsInCurrentArchive = 0;
+ NumFileErrors_in_Current = 0;
}
-
};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.cpp
new file mode 100644
index 00000000000..a71e4b50d21
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.cpp
@@ -0,0 +1,367 @@
+// HashCon.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/IntToString.h"
+
+#include "ConsoleClose.h"
+#include "HashCon.h"
+
+static const wchar_t *kEmptyFileAlias = L"[Content]";
+
+static const char *kScanningMessage = "Scanning";
+
+static HRESULT CheckBreak2()
+{
+ return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK;
+}
+
+HRESULT CHashCallbackConsole::CheckBreak()
+{
+ return CheckBreak2();
+}
+
+HRESULT CHashCallbackConsole::StartScanning()
+{
+ if (PrintHeaders && _so)
+ *_so << kScanningMessage << endl;
+ if (NeedPercents())
+ {
+ _percent.ClearCurState();
+ _percent.Command = "Scan";
+ }
+ return CheckBreak2();
+}
+
+HRESULT CHashCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */)
+{
+ if (NeedPercents())
+ {
+ _percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams;
+ _percent.Completed = st.GetTotalBytes();
+ _percent.FileName = fs2us(path);
+ _percent.Print();
+ }
+ return CheckBreak2();
+}
+
+HRESULT CHashCallbackConsole::ScanError(const FString &path, DWORD systemError)
+{
+ return ScanError_Base(path, systemError);
+}
+
+void Print_DirItemsStat(AString &s, const CDirItemsStat &st);
+
+HRESULT CHashCallbackConsole::FinishScanning(const CDirItemsStat &st)
+{
+ if (NeedPercents())
+ {
+ _percent.ClosePrint(true);
+ _percent.ClearCurState();
+ }
+ if (PrintHeaders && _so)
+ {
+ Print_DirItemsStat(_s, st);
+ *_so << _s << endl << endl;
+ }
+ return CheckBreak2();
+}
+
+HRESULT CHashCallbackConsole::SetNumFiles(UInt64 /* numFiles */)
+{
+ return CheckBreak2();
+}
+
+HRESULT CHashCallbackConsole::SetTotal(UInt64 size)
+{
+ if (NeedPercents())
+ {
+ _percent.Total = size;
+ _percent.Print();
+ }
+ return CheckBreak2();
+}
+
+HRESULT CHashCallbackConsole::SetCompleted(const UInt64 *completeValue)
+{
+ if (completeValue && NeedPercents())
+ {
+ _percent.Completed = *completeValue;
+ _percent.Print();
+ }
+ return CheckBreak2();
+}
+
+static void AddMinuses(AString &s, unsigned num)
+{
+ for (unsigned i = 0; i < num; i++)
+ s += '-';
+}
+
+static void AddSpaces_if_Positive(AString &s, int num)
+{
+ for (int i = 0; i < num; i++)
+ s.Add_Space();
+}
+
+static void SetSpacesAndNul(char *s, unsigned num)
+{
+ for (unsigned i = 0; i < num; i++)
+ s[i] = ' ';
+ s[num] = 0;
+}
+
+static const unsigned kSizeField_Len = 13;
+static const unsigned kNameField_Len = 12;
+
+static const unsigned kHashColumnWidth_Min = 4 * 2;
+
+static unsigned GetColumnWidth(unsigned digestSize)
+{
+ unsigned width = digestSize * 2;
+ return width < kHashColumnWidth_Min ? kHashColumnWidth_Min: width;
+}
+
+void CHashCallbackConsole::PrintSeparatorLine(const CObjectVector<CHasherState> &hashers)
+{
+ _s.Empty();
+
+ for (unsigned i = 0; i < hashers.Size(); i++)
+ {
+ if (i != 0)
+ _s.Add_Space();
+ const CHasherState &h = hashers[i];
+ AddMinuses(_s, GetColumnWidth(h.DigestSize));
+ }
+
+ if (PrintSize)
+ {
+ _s.Add_Space();
+ AddMinuses(_s, kSizeField_Len);
+ }
+
+ if (PrintName)
+ {
+ AddSpacesBeforeName();
+ AddMinuses(_s, kNameField_Len);
+ }
+
+ *_so << _s << endl;
+}
+
+HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb)
+{
+ if (PrintHeaders && _so)
+ {
+ _s.Empty();
+ ClosePercents_for_so();
+
+ FOR_VECTOR (i, hb.Hashers)
+ {
+ if (i != 0)
+ _s.Add_Space();
+ const CHasherState &h = hb.Hashers[i];
+ _s += h.Name;
+ AddSpaces_if_Positive(_s, (int)GetColumnWidth(h.DigestSize) - (int)h.Name.Len());
+ }
+
+ if (PrintSize)
+ {
+ _s.Add_Space();
+ const AString s2 = "Size";
+ AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len());
+ _s += s2;
+ }
+
+ if (PrintName)
+ {
+ AddSpacesBeforeName();
+ _s += "Name";
+ }
+
+ *_so << _s << endl;
+ PrintSeparatorLine(hb.Hashers);
+ }
+
+ return CheckBreak2();
+}
+
+HRESULT CHashCallbackConsole::OpenFileError(const FString &path, DWORD systemError)
+{
+ return OpenFileError_Base(path, systemError);
+}
+
+HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool /* isFolder */)
+{
+ _fileName = name;
+
+ if (NeedPercents())
+ {
+ if (PrintNameInPercents)
+ {
+ _percent.FileName.Empty();
+ if (name)
+ _percent.FileName = name;
+ }
+ _percent.Print();
+ }
+ return CheckBreak2();
+}
+
+void CHashCallbackConsole::PrintResultLine(UInt64 fileSize,
+ const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash)
+{
+ ClosePercents_for_so();
+
+ _s.Empty();
+
+ FOR_VECTOR (i, hashers)
+ {
+ const CHasherState &h = hashers[i];
+ char s[k_HashCalc_DigestSize_Max * 2 + 64];
+ s[0] = 0;
+ if (showHash)
+ AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize);
+ SetSpacesAndNul(s + strlen(s), (int)GetColumnWidth(h.DigestSize) - (int)strlen(s));
+ if (i != 0)
+ _s.Add_Space();
+ _s += s;
+ }
+
+ if (PrintSize)
+ {
+ _s.Add_Space();
+
+ char s[kSizeField_Len + 32];
+ char *p = s;
+
+ if (showHash)
+ {
+ p = s + kSizeField_Len;
+ ConvertUInt64ToString(fileSize, p);
+ int numSpaces = kSizeField_Len - (int)strlen(p);
+ if (numSpaces > 0)
+ {
+ p -= (unsigned)numSpaces;
+ for (unsigned i = 0; i < (unsigned)numSpaces; i++)
+ p[i] = ' ';
+ }
+ }
+ else
+ SetSpacesAndNul(s, kSizeField_Len);
+
+ _s += p;
+ }
+
+ if (PrintName)
+ AddSpacesBeforeName();
+
+ *_so << _s;
+}
+
+HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash)
+{
+ if (_so)
+ {
+ PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash);
+ if (PrintName)
+ {
+ if (_fileName.IsEmpty())
+ *_so << kEmptyFileAlias;
+ else
+ *_so << _fileName;
+ }
+ *_so << endl;
+ }
+
+ if (NeedPercents())
+ {
+ _percent.Files++;
+ _percent.Print();
+ }
+
+ return CheckBreak2();
+}
+
+static const char *k_DigestTitles[] =
+{
+ " : "
+ , " for data: "
+ , " for data and names: "
+ , " for streams and names: "
+};
+
+static void PrintSum(CStdOutStream &so, const CHasherState &h, unsigned digestIndex)
+{
+ so << h.Name;
+
+ {
+ AString temp;
+ AddSpaces_if_Positive(temp, 6 - (int)h.Name.Len());
+ so << temp;
+ }
+
+ so << k_DigestTitles[digestIndex];
+
+ char s[k_HashCalc_DigestSize_Max * 2 + 64];
+ s[0] = 0;
+ AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize);
+ so << s << endl;
+}
+
+void PrintHashStat(CStdOutStream &so, const CHashBundle &hb)
+{
+ FOR_VECTOR (i, hb.Hashers)
+ {
+ const CHasherState &h = hb.Hashers[i];
+ PrintSum(so, h, k_HashCalc_Index_DataSum);
+ if (hb.NumFiles != 1 || hb.NumDirs != 0)
+ PrintSum(so, h, k_HashCalc_Index_NamesSum);
+ if (hb.NumAltStreams != 0)
+ PrintSum(so, h, k_HashCalc_Index_StreamsSum);
+ so << endl;
+ }
+}
+
+void CHashCallbackConsole::PrintProperty(const char *name, UInt64 value)
+{
+ char s[32];
+ s[0] = ':';
+ s[1] = ' ';
+ ConvertUInt64ToString(value, s + 2);
+ *_so << name << s << endl;
+}
+
+HRESULT CHashCallbackConsole::AfterLastFile(const CHashBundle &hb)
+{
+ ClosePercents2();
+
+ if (PrintHeaders && _so)
+ {
+ PrintSeparatorLine(hb.Hashers);
+
+ PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true);
+
+ *_so << endl << endl;
+
+ if (hb.NumFiles != 1 || hb.NumDirs != 0)
+ {
+ if (hb.NumDirs != 0)
+ PrintProperty("Folders", hb.NumDirs);
+ PrintProperty("Files", hb.NumFiles);
+ }
+
+ PrintProperty("Size", hb.FilesSize);
+
+ if (hb.NumAltStreams != 0)
+ {
+ PrintProperty("Alternate streams", hb.NumAltStreams);
+ PrintProperty("Alternate streams size", hb.AltStreamsSize);
+ }
+
+ *_so << endl;
+ PrintHashStat(*_so, hb);
+ }
+
+ return S_OK;
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.h b/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.h
new file mode 100644
index 00000000000..5b30b69a058
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.h
@@ -0,0 +1,48 @@
+// HashCon.h
+
+#ifndef __HASH_CON_H
+#define __HASH_CON_H
+
+#include "../Common/HashCalc.h"
+
+#include "UpdateCallbackConsole.h"
+
+class CHashCallbackConsole: public IHashCallbackUI, public CCallbackConsoleBase
+{
+ UString _fileName;
+ AString _s;
+
+ void AddSpacesBeforeName()
+ {
+ _s.Add_Space();
+ _s.Add_Space();
+ }
+
+ void PrintSeparatorLine(const CObjectVector<CHasherState> &hashers);
+ void PrintResultLine(UInt64 fileSize,
+ const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash);
+ void PrintProperty(const char *name, UInt64 value);
+
+public:
+ bool PrintNameInPercents;
+
+ bool PrintHeaders;
+
+ bool PrintSize;
+ bool PrintName;
+
+ CHashCallbackConsole():
+ PrintNameInPercents(true),
+ PrintHeaders(false),
+ PrintSize(true),
+ PrintName(true)
+ {}
+
+ ~CHashCallbackConsole() { }
+
+ INTERFACE_IHashCallbackUI(;)
+};
+
+void PrintHashStat(CStdOutStream &so, const CHashBundle &hb);
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/List.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/List.cpp
index 7de2379ad11..e70f1b67ed2 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/List.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/List.cpp
@@ -2,17 +2,16 @@
#include "StdAfx.h"
-#include "Common/IntToString.h"
-#include "Common/MyCom.h"
-#include "Common/StdOutStream.h"
-#include "Common/StringConvert.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Common/StdOutStream.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/UTFConvert.h"
-#include "Windows/Error.h"
-#include "Windows/FileDir.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
-
-#include "../../Archive/IArchive.h"
+#include "../../../Windows/ErrorMsg.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/PropVariantConv.h"
#include "../Common/OpenArchive.h"
#include "../Common/PropIDUtils.h"
@@ -22,88 +21,137 @@
#include "OpenCallbackConsole.h"
using namespace NWindows;
+using namespace NCOM;
-struct CPropIdToName
-{
- PROPID PropID;
- const wchar_t *Name;
-};
+extern CStdOutStream *g_StdStream;
+extern CStdOutStream *g_ErrStream;
-static const CPropIdToName kPropIdToName[] =
-{
- { kpidPath, L"Path" },
- { kpidName, L"Name" },
- { kpidIsDir, L"Folder" },
- { kpidSize, L"Size" },
- { kpidPackSize, L"Packed Size" },
- { kpidAttrib, L"Attributes" },
- { kpidCTime, L"Created" },
- { kpidATime, L"Accessed" },
- { kpidMTime, L"Modified" },
- { kpidSolid, L"Solid" },
- { kpidCommented, L"Commented" },
- { kpidEncrypted, L"Encrypted" },
- { kpidSplitBefore, L"Split Before" },
- { kpidSplitAfter, L"Split After" },
- { kpidDictionarySize, L"Dictionary Size" },
- { kpidCRC, L"CRC" },
- { kpidType, L"Type" },
- { kpidIsAnti, L"Anti" },
- { kpidMethod, L"Method" },
- { kpidHostOS, L"Host OS" },
- { kpidFileSystem, L"File System" },
- { kpidUser, L"User" },
- { kpidGroup, L"Group" },
- { kpidBlock, L"Block" },
- { kpidComment, L"Comment" },
- { kpidPosition, L"Position" },
- { kpidPrefix, L"Prefix" },
- { kpidNumSubDirs, L"Folders" },
- { kpidNumSubFiles, L"Files" },
- { kpidUnpackVer, L"Version" },
- { kpidVolume, L"Volume" },
- { kpidIsVolume, L"Multivolume" },
- { kpidOffset, L"Offset" },
- { kpidLinks, L"Links" },
- { kpidNumBlocks, L"Blocks" },
- { kpidNumVolumes, L"Volumes" },
-
- { kpidBit64, L"64-bit" },
- { kpidBigEndian, L"Big-endian" },
- { kpidCpu, L"CPU" },
- { kpidPhySize, L"Physical Size" },
- { kpidHeadersSize, L"Headers Size" },
- { kpidChecksum, L"Checksum" },
- { kpidCharacts, L"Characteristics" },
- { kpidVa, L"Virtual Address" },
- { kpidId, L"ID" },
- { kpidShortName, L"Short Name" },
- { kpidCreatorApp, L"Creator Application"},
- { kpidSectorSize, L"Sector Size" },
- { kpidPosixAttrib, L"Mode" },
- { kpidLink, L"Link" },
- { kpidError, L"Error" },
-
- { kpidTotalSize, L"Total Size" },
- { kpidFreeSpace, L"Free Space" },
- { kpidClusterSize, L"Cluster Size" },
- { kpidVolumeName, L"Label" }
+static const char * const kPropIdToName[] =
+{
+ "0"
+ , "1"
+ , "2"
+ , "Path"
+ , "Name"
+ , "Extension"
+ , "Folder"
+ , "Size"
+ , "Packed Size"
+ , "Attributes"
+ , "Created"
+ , "Accessed"
+ , "Modified"
+ , "Solid"
+ , "Commented"
+ , "Encrypted"
+ , "Split Before"
+ , "Split After"
+ , "Dictionary Size"
+ , "CRC"
+ , "Type"
+ , "Anti"
+ , "Method"
+ , "Host OS"
+ , "File System"
+ , "User"
+ , "Group"
+ , "Block"
+ , "Comment"
+ , "Position"
+ , "Path Prefix"
+ , "Folders"
+ , "Files"
+ , "Version"
+ , "Volume"
+ , "Multivolume"
+ , "Offset"
+ , "Links"
+ , "Blocks"
+ , "Volumes"
+ , "Time Type"
+ , "64-bit"
+ , "Big-endian"
+ , "CPU"
+ , "Physical Size"
+ , "Headers Size"
+ , "Checksum"
+ , "Characteristics"
+ , "Virtual Address"
+ , "ID"
+ , "Short Name"
+ , "Creator Application"
+ , "Sector Size"
+ , "Mode"
+ , "Symbolic Link"
+ , "Error"
+ , "Total Size"
+ , "Free Space"
+ , "Cluster Size"
+ , "Label"
+ , "Local Name"
+ , "Provider"
+ , "NT Security"
+ , "Alternate Stream"
+ , "Aux"
+ , "Deleted"
+ , "Tree"
+ , "SHA-1"
+ , "SHA-256"
+ , "Error Type"
+ , "Errors"
+ , "Errors"
+ , "Warnings"
+ , "Warning"
+ , "Streams"
+ , "Alternate Streams"
+ , "Alternate Streams Size"
+ , "Virtual Size"
+ , "Unpack Size"
+ , "Total Physical Size"
+ , "Volume Index"
+ , "SubType"
+ , "Short Comment"
+ , "Code Page"
+ , "Is not archive type"
+ , "Physical Size can't be detected"
+ , "Zeros Tail Is Allowed"
+ , "Tail Size"
+ , "Embedded Stub Size"
+ , "Link"
+ , "Hard Link"
+ , "iNode"
+ , "Stream ID"
+ , "Read-only"
+ , "Out Name"
+ , "Copy Link"
};
static const char kEmptyAttribChar = '.';
static const char *kListing = "Listing archive: ";
-static const wchar_t *kFilesMessage = L"files";
-static const wchar_t *kDirsMessage = L"folders";
-static void GetAttribString(DWORD wa, bool isDir, char *s)
+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 *kError = "ERROR: ";
+
+static void GetAttribString(UInt32 wa, bool isDir, bool allAttribs, char *s)
{
- s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : kEmptyAttribChar;
- s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar;
- s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar;
- s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar;
- s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar;
- s[5] = '\0';
+ if (isDir)
+ wa |= FILE_ATTRIBUTE_DIRECTORY;
+ if (allAttribs)
+ {
+ ConvertWinAttribToString(s, wa);
+ return;
+ }
+ s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0) ? 'D': kEmptyAttribChar;
+ s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar;
+ s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar;
+ s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar;
+ s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar;
+ s[5] = 0;
}
enum EAdjustment
@@ -116,108 +164,294 @@ enum EAdjustment
struct CFieldInfo
{
PROPID PropID;
- UString Name;
+ bool IsRawProp;
+ UString NameU;
+ AString NameA;
EAdjustment TitleAdjustment;
EAdjustment TextAdjustment;
- int PrefixSpacesWidth;
- int Width;
+ unsigned PrefixSpacesWidth;
+ unsigned Width;
};
struct CFieldInfoInit
{
PROPID PropID;
- const wchar_t *Name;
+ const char *Name;
EAdjustment TitleAdjustment;
EAdjustment TextAdjustment;
- int PrefixSpacesWidth;
- int Width;
+ unsigned PrefixSpacesWidth;
+ unsigned Width;
};
-static CFieldInfoInit kStandardFieldTable[] =
+static const CFieldInfoInit kStandardFieldTable[] =
{
- { kpidMTime, L" Date Time", kLeft, kLeft, 0, 19 },
- { kpidAttrib, L"Attr", kRight, kCenter, 1, 5 },
- { kpidSize, L"Size", kRight, kRight, 1, 12 },
- { kpidPackSize, L"Compressed", kRight, kRight, 1, 12 },
- { kpidPath, L"Name", kLeft, kLeft, 2, 24 }
+ { kpidMTime, " Date Time", kLeft, kLeft, 0, 19 },
+ { kpidAttrib, "Attr", kRight, kCenter, 1, 5 },
+ { kpidSize, "Size", kRight, kRight, 1, 12 },
+ { kpidPackSize, "Compressed", kRight, kRight, 1, 12 },
+ { kpidPath, "Name", kLeft, kLeft, 2, 24 }
};
-static void PrintSpaces(int numSpaces)
+const unsigned kNumSpacesMax = 32; // it must be larger than max CFieldInfoInit.Width
+static const char *g_Spaces =
+" " ;
+
+static void PrintSpaces(unsigned numSpaces)
{
- for (int i = 0; i < numSpaces; i++)
- g_StdOut << ' ';
+ if (numSpaces > 0 && numSpaces <= kNumSpacesMax)
+ g_StdOut << g_Spaces + (kNumSpacesMax - numSpaces);
}
-static void PrintString(EAdjustment adjustment, int width, const UString &textString)
+static void PrintSpacesToString(char *dest, unsigned numSpaces)
{
- const int numSpaces = width - textString.Length();
- int numLeftSpaces = 0;
- switch (adjustment)
+ unsigned i;
+ for (i = 0; i < numSpaces; i++)
+ dest[i] = ' ';
+ dest[i] = 0;
+}
+
+// extern int g_CodePage;
+
+static void PrintUString(EAdjustment adj, unsigned width, const UString &s, AString &temp)
+{
+ /*
+ // we don't need multibyte align.
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8(s, temp);
+ else
+ UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
+ */
+
+ unsigned numSpaces = 0;
+
+ if (width > s.Len())
{
- case kLeft:
- numLeftSpaces = 0;
- break;
- case kCenter:
- numLeftSpaces = numSpaces / 2;
- break;
- case kRight:
- numLeftSpaces = numSpaces;
- break;
+ numSpaces = width - s.Len();
+ unsigned numLeftSpaces = 0;
+ switch (adj)
+ {
+ case kLeft: numLeftSpaces = 0; break;
+ case kCenter: numLeftSpaces = numSpaces / 2; break;
+ case kRight: numLeftSpaces = numSpaces; break;
+ }
+ PrintSpaces(numLeftSpaces);
+ numSpaces -= numLeftSpaces;
}
- PrintSpaces(numLeftSpaces);
- g_StdOut << textString;
- PrintSpaces(numSpaces - numLeftSpaces);
+
+ g_StdOut.PrintUString(s, temp);
+ PrintSpaces(numSpaces);
}
+static void PrintString(EAdjustment adj, unsigned width, const char *s)
+{
+ unsigned numSpaces = 0;
+ unsigned len = (unsigned)strlen(s);
+
+ if (width > len)
+ {
+ numSpaces = width - len;
+ unsigned numLeftSpaces = 0;
+ switch (adj)
+ {
+ case kLeft: numLeftSpaces = 0; break;
+ case kCenter: numLeftSpaces = numSpaces / 2; break;
+ case kRight: numLeftSpaces = numSpaces; break;
+ }
+ PrintSpaces(numLeftSpaces);
+ numSpaces -= numLeftSpaces;
+ }
+
+ g_StdOut << s;
+ PrintSpaces(numSpaces);
+}
+
+static void PrintStringToString(char *dest, EAdjustment adj, unsigned width, const char *textString)
+{
+ unsigned numSpaces = 0;
+ unsigned len = (unsigned)strlen(textString);
+
+ if (width > len)
+ {
+ numSpaces = width - len;
+ unsigned numLeftSpaces = 0;
+ switch (adj)
+ {
+ case kLeft: numLeftSpaces = 0; break;
+ case kCenter: numLeftSpaces = numSpaces / 2; break;
+ case kRight: numLeftSpaces = numSpaces; break;
+ }
+ PrintSpacesToString(dest, numLeftSpaces);
+ dest += numLeftSpaces;
+ numSpaces -= numLeftSpaces;
+ }
+
+ memcpy(dest, textString, len);
+ dest += len;
+ PrintSpacesToString(dest, numSpaces);
+}
+
+struct CListUInt64Def
+{
+ UInt64 Val;
+ bool Def;
+
+ CListUInt64Def(): Val(0), Def(false) {}
+ void Add(UInt64 v) { Val += v; Def = true; }
+ void Add(const CListUInt64Def &v) { if (v.Def) Add(v.Val); }
+};
+
+struct CListFileTimeDef
+{
+ FILETIME Val;
+ bool Def;
+
+ CListFileTimeDef(): Def(false) { Val.dwLowDateTime = 0; Val.dwHighDateTime = 0; }
+ void Update(const CListFileTimeDef &t)
+ {
+ if (t.Def && (!Def || CompareFileTime(&Val, &t.Val) < 0))
+ {
+ Val = t.Val;
+ Def = true;
+ }
+ }
+};
+
+struct CListStat
+{
+ CListUInt64Def Size;
+ CListUInt64Def PackSize;
+ CListFileTimeDef MTime;
+ UInt64 NumFiles;
+
+ CListStat(): NumFiles(0) {}
+ void Update(const CListStat &st)
+ {
+ Size.Add(st.Size);
+ PackSize.Add(st.PackSize);
+ MTime.Update(st.MTime);
+ NumFiles += st.NumFiles;
+ }
+ void SetSizeDefIfNoFiles() { if (NumFiles == 0) Size.Def = true; }
+};
+
+struct CListStat2
+{
+ CListStat MainFiles;
+ CListStat AltStreams;
+ UInt64 NumDirs;
+
+ CListStat2(): NumDirs(0) {}
+
+ void Update(const CListStat2 &st)
+ {
+ MainFiles.Update(st.MainFiles);
+ AltStreams.Update(st.AltStreams);
+ NumDirs += st.NumDirs;
+ }
+ const UInt64 GetNumStreams() const { return MainFiles.NumFiles + AltStreams.NumFiles; }
+ CListStat &GetStat(bool altStreamsMode) { return altStreamsMode ? AltStreams : MainFiles; }
+};
+
class CFieldPrinter
{
CObjectVector<CFieldInfo> _fields;
+
+ void AddProp(const wchar_t *name, PROPID propID, bool isRawProp);
public:
- void Clear() { _fields.Clear(); }
- void Init(const CFieldInfoInit *standardFieldTable, int numItems);
- HRESULT Init(IInArchive *archive);
+ const CArc *Arc;
+ bool TechMode;
+ UString FilePath;
+ AString TempAString;
+ UString TempWString;
+ bool IsDir;
+
+ AString LinesString;
+
+ void Clear() { _fields.Clear(); LinesString.Empty(); }
+ void Init(const CFieldInfoInit *standardFieldTable, unsigned numItems);
+
+ HRESULT AddMainProps(IInArchive *archive);
+ HRESULT AddRawProps(IArchiveGetRawProps *getRawProps);
+
void PrintTitle();
void PrintTitleLines();
- HRESULT PrintItemInfo(const CArc &arc, UInt32 index, bool techMode);
- HRESULT PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs,
- const UInt64 *size, const UInt64 *compressedSize);
+ HRESULT PrintItemInfo(UInt32 index, const CListStat &st);
+ void PrintSum(const CListStat &st, UInt64 numDirs, const char *str);
+ void PrintSum(const CListStat2 &stat2);
};
-void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems)
+void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, unsigned numItems)
{
Clear();
- for (int i = 0; i < numItems; i++)
+ for (unsigned i = 0; i < numItems; i++)
{
- CFieldInfo fieldInfo;
- const CFieldInfoInit &fieldInfoInit = standardFieldTable[i];
- fieldInfo.PropID = fieldInfoInit.PropID;
- fieldInfo.Name = fieldInfoInit.Name;
- fieldInfo.TitleAdjustment = fieldInfoInit.TitleAdjustment;
- fieldInfo.TextAdjustment = fieldInfoInit.TextAdjustment;
- fieldInfo.PrefixSpacesWidth = fieldInfoInit.PrefixSpacesWidth;
- fieldInfo.Width = fieldInfoInit.Width;
- _fields.Add(fieldInfo);
+ CFieldInfo &f = _fields.AddNew();
+ const CFieldInfoInit &fii = standardFieldTable[i];
+ f.PropID = fii.PropID;
+ f.IsRawProp = false;
+ f.NameA = fii.Name;
+ f.TitleAdjustment = fii.TitleAdjustment;
+ f.TextAdjustment = fii.TextAdjustment;
+ f.PrefixSpacesWidth = fii.PrefixSpacesWidth;
+ f.Width = fii.Width;
+
+ unsigned k;
+ for (k = 0; k < fii.PrefixSpacesWidth; k++)
+ LinesString.Add_Space();
+ for (k = 0; k < fii.Width; k++)
+ LinesString += '-';
}
}
-static UString GetPropName(PROPID propID, BSTR name)
+static void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UString &nameU)
{
- for (int i = 0; i < sizeof(kPropIdToName) / sizeof(kPropIdToName[0]); i++)
+ if (propID < ARRAY_SIZE(kPropIdToName))
{
- const CPropIdToName &propIdToName = kPropIdToName[i];
- if (propIdToName.PropID == propID)
- return propIdToName.Name;
+ nameA = kPropIdToName[propID];
+ return;
}
if (name)
- return name;
- wchar_t s[16];
- ConvertUInt32ToString(propID, s);
- return s;
+ nameU = name;
+ else
+ {
+ char s[16];
+ ConvertUInt32ToString(propID, s);
+ nameA = s;
+ }
}
-HRESULT CFieldPrinter::Init(IInArchive *archive)
+void CFieldPrinter::AddProp(const wchar_t *name, PROPID propID, bool isRawProp)
+{
+ CFieldInfo f;
+ f.PropID = propID;
+ f.IsRawProp = isRawProp;
+ GetPropName(propID, name, f.NameA, f.NameU);
+ f.NameU.AddAscii(" = ");
+ if (!f.NameA.IsEmpty())
+ f.NameA += " = ";
+ else
+ {
+ const UString &s = f.NameU;
+ AString sA;
+ unsigned i;
+ for (i = 0; i < s.Len(); i++)
+ {
+ wchar_t c = s[i];
+ if (c >= 0x80)
+ break;
+ sA += (char)c;
+ }
+ if (i == s.Len())
+ f.NameA = sA;
+ }
+ _fields.Add(f);
+}
+
+HRESULT CFieldPrinter::AddMainProps(IInArchive *archive)
{
- Clear();
UInt32 numProps;
RINOK(archive->GetNumberOfProperties(&numProps));
for (UInt32 i = 0; i < numProps; i++)
@@ -226,64 +460,80 @@ HRESULT CFieldPrinter::Init(IInArchive *archive)
PROPID propID;
VARTYPE vt;
RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt));
- CFieldInfo fieldInfo;
- fieldInfo.PropID = propID;
- fieldInfo.Name = GetPropName(propID, name);
- _fields.Add(fieldInfo);
+ AddProp(name, propID, false);
}
return S_OK;
}
-void CFieldPrinter::PrintTitle()
+HRESULT CFieldPrinter::AddRawProps(IArchiveGetRawProps *getRawProps)
{
- for (int i = 0; i < _fields.Size(); i++)
+ UInt32 numProps;
+ RINOK(getRawProps->GetNumRawProps(&numProps));
+ for (UInt32 i = 0; i < numProps; i++)
{
- const CFieldInfo &fieldInfo = _fields[i];
- PrintSpaces(fieldInfo.PrefixSpacesWidth);
- PrintString(fieldInfo.TitleAdjustment,
- ((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name);
+ CMyComBSTR name;
+ PROPID propID;
+ RINOK(getRawProps->GetRawPropInfo(i, &name, &propID));
+ AddProp(name, propID, true);
}
+ return S_OK;
}
-void CFieldPrinter::PrintTitleLines()
+void CFieldPrinter::PrintTitle()
{
- for (int i = 0; i < _fields.Size(); i++)
+ FOR_VECTOR (i, _fields)
{
- const CFieldInfo &fieldInfo = _fields[i];
- PrintSpaces(fieldInfo.PrefixSpacesWidth);
- for (int i = 0; i < fieldInfo.Width; i++)
- g_StdOut << '-';
+ const CFieldInfo &f = _fields[i];
+ PrintSpaces(f.PrefixSpacesWidth);
+ PrintString(f.TitleAdjustment, ((f.PropID == kpidPath) ? 0: f.Width), f.NameA);
}
}
+void CFieldPrinter::PrintTitleLines()
+{
+ g_StdOut << LinesString;
+}
-static BOOL IsFileTimeZero(CONST FILETIME *lpFileTime)
+static void PrintTime(char *dest, const FILETIME *ft)
{
- return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0);
+ *dest = 0;
+ if (ft->dwLowDateTime == 0 && ft->dwHighDateTime == 0)
+ return;
+ FILETIME locTime;
+ if (!FileTimeToLocalFileTime(ft, &locTime))
+ throw 20121211;
+ ConvertFileTimeToString(locTime, dest, true, true);
}
-static const char *kEmptyTimeString = " ";
-static void PrintTime(const NCOM::CPropVariant &prop)
+#ifndef _SFX
+
+static inline char GetHex(Byte value)
{
- if (prop.vt != VT_FILETIME)
- throw "incorrect item";
- if (IsFileTimeZero(&prop.filetime))
- g_StdOut << kEmptyTimeString;
- else
+ return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+}
+
+static void HexToString(char *dest, const Byte *data, UInt32 size)
+{
+ for (UInt32 i = 0; i < size; i++)
{
- FILETIME localFileTime;
- if (!FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
- throw "FileTimeToLocalFileTime error";
- char s[32];
- if (ConvertFileTimeToString(localFileTime, s, true, true))
- g_StdOut << s;
- else
- g_StdOut << kEmptyTimeString;
+ Byte b = data[i];
+ dest[0] = GetHex((Byte)((b >> 4) & 0xF));
+ dest[1] = GetHex((Byte)(b & 0xF));
+ dest += 2;
}
+ *dest = 0;
}
-HRESULT CFieldPrinter::PrintItemInfo(const CArc &arc, UInt32 index, bool techMode)
+#endif
+
+#define MY_ENDL endl
+
+HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st)
{
+ char temp[128];
+ size_t tempPos = 0;
+
+ bool techMode = this->TechMode;
/*
if (techMode)
{
@@ -292,165 +542,502 @@ HRESULT CFieldPrinter::PrintItemInfo(const CArc &arc, UInt32 index, bool techMod
g_StdOut << endl;
}
*/
- for (int i = 0; i < _fields.Size(); i++)
+ FOR_VECTOR (i, _fields)
{
- const CFieldInfo &fieldInfo = _fields[i];
- if (!techMode)
- PrintSpaces(fieldInfo.PrefixSpacesWidth);
+ const CFieldInfo &f = _fields[i];
- NCOM::CPropVariant prop;
- if (fieldInfo.PropID == kpidPath)
- {
- UString s;
- RINOK(arc.GetItemPath(index, s));
- prop = s;
- }
- else
+ if (!techMode)
{
- RINOK(arc.Archive->GetProperty(index, fieldInfo.PropID, &prop));
+ PrintSpacesToString(temp + tempPos, f.PrefixSpacesWidth);
+ tempPos += f.PrefixSpacesWidth;
}
+
if (techMode)
{
- g_StdOut << fieldInfo.Name << " = ";
- }
- int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width;
- if (fieldInfo.PropID == kpidAttrib && (prop.vt == VT_EMPTY || prop.vt == VT_UI4))
- {
- UInt32 attrib = (prop.vt == VT_EMPTY) ? 0 : prop.ulVal;
- bool isFolder;
- RINOK(IsArchiveItemFolder(arc.Archive, index, isFolder));
- char s[8];
- GetAttribString(attrib, isFolder, s);
- g_StdOut << s;
+ if (!f.NameA.IsEmpty())
+ g_StdOut << f.NameA;
+ else
+ g_StdOut << f.NameU;
}
- else if (prop.vt == VT_EMPTY)
+
+ if (f.PropID == kpidPath)
{
if (!techMode)
- PrintSpaces(width);
- }
- else if (fieldInfo.PropID == kpidMTime)
- {
- PrintTime(prop);
+ g_StdOut << temp;
+ g_StdOut.PrintUString(FilePath, TempAString);
+ if (techMode)
+ g_StdOut << MY_ENDL;
+ continue;
}
- else if (prop.vt == VT_BSTR)
+
+ const unsigned width = f.Width;
+
+ if (f.IsRawProp)
{
- if (techMode)
- g_StdOut << prop.bstrVal;
- else
- PrintString(fieldInfo.TextAdjustment, width, prop.bstrVal);
+ #ifndef _SFX
+
+ const void *data;
+ UInt32 dataSize;
+ UInt32 propType;
+ RINOK(Arc->GetRawProps->GetRawProp(index, f.PropID, &data, &dataSize, &propType));
+
+ if (dataSize != 0)
+ {
+ bool needPrint = true;
+
+ if (f.PropID == kpidNtSecure)
+ {
+ if (propType != NPropDataType::kRaw)
+ return E_FAIL;
+ #ifndef _SFX
+ ConvertNtSecureToString((const Byte *)data, dataSize, TempAString);
+ g_StdOut << TempAString;
+ needPrint = false;
+ #endif
+ }
+ else if (f.PropID == kpidNtReparse)
+ {
+ UString s;
+ if (ConvertNtReparseToString((const Byte *)data, dataSize, s))
+ {
+ needPrint = false;
+ g_StdOut.PrintUString(s, TempAString);
+ }
+ }
+
+ if (needPrint)
+ {
+ if (propType != NPropDataType::kRaw)
+ return E_FAIL;
+
+ const UInt32 kMaxDataSize = 64;
+
+ if (dataSize > kMaxDataSize)
+ {
+ g_StdOut << "data:";
+ g_StdOut << dataSize;
+ }
+ else
+ {
+ char hexStr[kMaxDataSize * 2 + 4];
+ HexToString(hexStr, (const Byte *)data, dataSize);
+ g_StdOut << hexStr;
+ }
+ }
+ }
+
+ #endif
}
else
{
- UString s = ConvertPropertyToString(prop, fieldInfo.PropID);
- s.Replace(wchar_t(0xA), L' ');
- s.Replace(wchar_t(0xD), L' ');
-
- if (techMode)
- g_StdOut << s;
+ CPropVariant prop;
+ switch (f.PropID)
+ {
+ case kpidSize: if (st.Size.Def) prop = st.Size.Val; break;
+ case kpidPackSize: if (st.PackSize.Def) prop = st.PackSize.Val; break;
+ case kpidMTime: if (st.MTime.Def) prop = st.MTime.Val; break;
+ default:
+ RINOK(Arc->Archive->GetProperty(index, f.PropID, &prop));
+ }
+ if (f.PropID == kpidAttrib && (prop.vt == VT_EMPTY || prop.vt == VT_UI4))
+ {
+ GetAttribString((prop.vt == VT_EMPTY) ? 0 : prop.ulVal, IsDir, techMode, temp + tempPos);
+ if (techMode)
+ g_StdOut << temp + tempPos;
+ else
+ tempPos += strlen(temp + tempPos);
+ }
+ else if (prop.vt == VT_EMPTY)
+ {
+ if (!techMode)
+ {
+ PrintSpacesToString(temp + tempPos, width);
+ tempPos += width;
+ }
+ }
+ else if (prop.vt == VT_FILETIME)
+ {
+ PrintTime(temp + tempPos, &prop.filetime);
+ if (techMode)
+ g_StdOut << temp + tempPos;
+ else
+ {
+ size_t len = strlen(temp + tempPos);
+ tempPos += len;
+ if (len < (unsigned)f.Width)
+ {
+ len = f.Width - len;
+ PrintSpacesToString(temp + tempPos, (unsigned)len);
+ tempPos += len;
+ }
+ }
+ }
+ else if (prop.vt == VT_BSTR)
+ {
+ TempWString.SetFromBstr(prop.bstrVal);
+ if (techMode)
+ {
+ // replace CR/LF here.
+ g_StdOut.PrintUString(TempWString, TempAString);
+ }
+ else
+ PrintUString(f.TextAdjustment, width, TempWString, TempAString);
+ }
else
- PrintString(fieldInfo.TextAdjustment, width, s);
+ {
+ char s[64];
+ ConvertPropertyToShortString(s, prop, f.PropID);
+ if (techMode)
+ g_StdOut << s;
+ else
+ {
+ PrintStringToString(temp + tempPos, f.TextAdjustment, width, s);
+ tempPos += strlen(temp + tempPos);
+ }
+ }
}
if (techMode)
- g_StdOut << endl;
+ g_StdOut << MY_ENDL;
}
+ g_StdOut << MY_ENDL;
return S_OK;
}
-static void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value)
+static void PrintNumber(EAdjustment adj, unsigned width, const CListUInt64Def &value)
{
- wchar_t textString[32] = { 0 };
- if (value != NULL)
- ConvertUInt64ToString(*value, textString);
- PrintString(adjustment, width, textString);
+ char s[32];
+ s[0] = 0;
+ if (value.Def)
+ ConvertUInt64ToString(value.Val, s);
+ PrintString(adj, width, s);
}
+void Print_UInt64_and_String(AString &s, UInt64 val, const char *name);
-HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs,
- const UInt64 *size, const UInt64 *compressedSize)
+void CFieldPrinter::PrintSum(const CListStat &st, UInt64 numDirs, const char *str)
{
- for (int i = 0; i < _fields.Size(); i++)
+ FOR_VECTOR (i, _fields)
{
- const CFieldInfo &fieldInfo = _fields[i];
- PrintSpaces(fieldInfo.PrefixSpacesWidth);
- NCOM::CPropVariant prop;
- if (fieldInfo.PropID == kpidSize)
- PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, size);
- else if (fieldInfo.PropID == kpidPackSize)
- PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, compressedSize);
- else if (fieldInfo.PropID == kpidPath)
+ const CFieldInfo &f = _fields[i];
+ PrintSpaces(f.PrefixSpacesWidth);
+ if (f.PropID == kpidSize)
+ PrintNumber(f.TextAdjustment, f.Width, st.Size);
+ else if (f.PropID == kpidPackSize)
+ PrintNumber(f.TextAdjustment, f.Width, st.PackSize);
+ else if (f.PropID == kpidMTime)
{
- wchar_t textString[32];
- ConvertUInt64ToString(numFiles, textString);
- UString temp = textString;
- temp += L" ";
- temp += kFilesMessage;
- temp += L", ";
- ConvertUInt64ToString(numDirs, textString);
- temp += textString;
- temp += L" ";
- temp += kDirsMessage;
- PrintString(fieldInfo.TextAdjustment, 0, temp);
+ char s[64];
+ s[0] = 0;
+ if (st.MTime.Def)
+ PrintTime(s, &st.MTime.Val);
+ PrintString(f.TextAdjustment, f.Width, s);
}
+ else if (f.PropID == kpidPath)
+ {
+ AString s;
+ Print_UInt64_and_String(s, st.NumFiles, str);
+ if (numDirs != 0)
+ {
+ s += ", ";
+ Print_UInt64_and_String(s, numDirs, kString_Dirs);
+ }
+ PrintString(f.TextAdjustment, 0, s);
+ }
+ else
+ PrintString(f.TextAdjustment, f.Width, "");
+ }
+ g_StdOut << endl;
+}
+
+void CFieldPrinter::PrintSum(const CListStat2 &stat2)
+{
+ PrintSum(stat2.MainFiles, stat2.NumDirs, kString_Files);
+ if (stat2.AltStreams.NumFiles != 0)
+ {
+ PrintSum(stat2.AltStreams, 0, kString_AltStreams);;
+ CListStat st = stat2.MainFiles;
+ st.Update(stat2.AltStreams);
+ PrintSum(st, 0, kString_Streams);
+ }
+}
+
+static HRESULT GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, CListUInt64Def &value)
+{
+ value.Val = 0;
+ value.Def = false;
+ CPropVariant prop;
+ RINOK(archive->GetProperty(index, propID, &prop));
+ value.Def = ConvertPropVariantToUInt64(prop, value.Val);
+ return S_OK;
+}
+
+static HRESULT GetItemMTime(IInArchive *archive, UInt32 index, CListFileTimeDef &t)
+{
+ t.Val.dwLowDateTime = 0;
+ t.Val.dwHighDateTime = 0;
+ t.Def = false;
+ CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidMTime, &prop));
+ if (prop.vt == VT_FILETIME)
+ {
+ t.Val = prop.filetime;
+ t.Def = true;
+ }
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
+}
+
+static void PrintPropNameAndNumber(CStdOutStream &so, const char *name, UInt64 val)
+{
+ so << name << ": " << val << endl;
+}
+
+static void PrintPropName_and_Eq(CStdOutStream &so, PROPID propID)
+{
+ const char *s;
+ char temp[16];
+ if (propID < ARRAY_SIZE(kPropIdToName))
+ s = kPropIdToName[propID];
+ else
+ {
+ ConvertUInt32ToString(propID, temp);
+ s = temp;
+ }
+ so << s << " = ";
+}
+
+static void PrintPropNameAndNumber(CStdOutStream &so, PROPID propID, UInt64 val)
+{
+ PrintPropName_and_Eq(so, propID);
+ so << val << endl;
+}
+
+static void PrintPropNameAndNumber_Signed(CStdOutStream &so, PROPID propID, Int64 val)
+{
+ PrintPropName_and_Eq(so, propID);
+ so << val << endl;
+}
+
+static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val)
+{
+ so << name << " = " << val << endl;
+}
+
+
+static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *name, const CPropVariant &prop)
+{
+ UString s;
+ ConvertPropertyToString(s, prop, propID);
+ if (!s.IsEmpty())
+ {
+ AString nameA;
+ UString nameU;
+ GetPropName(propID, name, nameA, nameU);
+ if (!nameA.IsEmpty())
+ PrintPropPair(so, nameA, s);
else
- PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L"");
+ so << nameU << " = " << s << endl;
}
+}
+
+static HRESULT PrintArcProp(CStdOutStream &so, IInArchive *archive, PROPID propID, const wchar_t *name)
+{
+ CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(propID, &prop));
+ PrintPropertyPair2(so, propID, name, prop);
return S_OK;
}
-bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value)
+static void PrintArcTypeError(CStdOutStream &so, const UString &type, bool isWarning)
{
- NCOM::CPropVariant prop;
- if (archive->GetProperty(index, propID, &prop) != S_OK)
- throw "GetPropertyValue error";
- if (prop.vt == VT_EMPTY)
- return false;
- value = ConvertPropVariantToUInt64(prop);
- return true;
+ so << "Open " << (isWarning ? "WARNING" : "ERROR")
+ << ": Can not open the file as ["
+ << type
+ << "] archive"
+ << endl;
}
-static void PrintPropPair(const wchar_t *name, const wchar_t *value)
+int Find_FileName_InSortedVector(const UStringVector &fileName, const UString& name);
+
+void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags);
+
+static void ErrorInfo_Print(CStdOutStream &so, const CArcErrorInfo &er)
{
- g_StdOut << name << " = " << value << endl;
+ PrintErrorFlags(so, "ERRORS:", er.GetErrorFlags());
+ if (!er.ErrorMessage.IsEmpty())
+ PrintPropPair(so, "ERROR", er.ErrorMessage);
+
+ PrintErrorFlags(so, "WARNINGS:", er.GetWarningFlags());
+ if (!er.WarningMessage.IsEmpty())
+ PrintPropPair(so, "WARNING", er.WarningMessage);
}
-HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
+HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink)
+{
+ FOR_VECTOR (r, arcLink.Arcs)
+ {
+ const CArc &arc = arcLink.Arcs[r];
+ const CArcErrorInfo &er = arc.ErrorInfo;
+
+ so << "--\n";
+ PrintPropPair(so, "Path", arc.Path);
+ if (er.ErrorFormatIndex >= 0)
+ {
+ if (er.ErrorFormatIndex == arc.FormatIndex)
+ so << "Warning: The archive is open with offset" << endl;
+ else
+ PrintArcTypeError(so, codecs->GetFormatNamePtr(er.ErrorFormatIndex), true);
+ }
+ PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex));
+
+ ErrorInfo_Print(so, er);
+
+ Int64 offset = arc.GetGlobalOffset();
+ if (offset != 0)
+ PrintPropNameAndNumber_Signed(so, kpidOffset, offset);
+ IInArchive *archive = arc.Archive;
+ RINOK(PrintArcProp(so, archive, kpidPhySize, NULL));
+ if (er.TailSize != 0)
+ PrintPropNameAndNumber(so, kpidTailSize, er.TailSize);
+ UInt32 numProps;
+ RINOK(archive->GetNumberOfArchiveProperties(&numProps));
+
+ {
+ for (UInt32 j = 0; j < numProps; j++)
+ {
+ CMyComBSTR name;
+ PROPID propID;
+ VARTYPE vt;
+ RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt));
+ RINOK(PrintArcProp(so, archive, propID, name));
+ }
+ }
+
+ if (r != arcLink.Arcs.Size() - 1)
+ {
+ UInt32 numProps;
+ so << "----\n";
+ if (archive->GetNumberOfProperties(&numProps) == S_OK)
+ {
+ UInt32 mainIndex = arcLink.Arcs[r + 1].SubfileIndex;
+ for (UInt32 j = 0; j < numProps; j++)
+ {
+ CMyComBSTR name;
+ PROPID propID;
+ VARTYPE vt;
+ RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt));
+ CPropVariant prop;
+ RINOK(archive->GetProperty(mainIndex, propID, &prop));
+ PrintPropertyPair2(so, propID, name, prop);
+ }
+ }
+ }
+ }
+ return S_OK;
+}
+
+HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink)
+{
+ #ifndef _NO_CRYPTO
+ if (arcLink.PasswordWasAsked)
+ so << "Can not open encrypted archive. Wrong password?";
+ else
+ #endif
+ {
+ if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
+ {
+ so << arcLink.NonOpen_ArcPath << endl;
+ PrintArcTypeError(so, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
+ }
+ else
+ so << "Can not open the file as archive";
+ }
+
+ so << endl;
+ so << endl;
+ ErrorInfo_Print(so, arcLink.NonOpen_ErrorInfo);
+
+ return S_OK;
+}
+
+bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
+
+HRESULT ListArchives(CCodecs *codecs,
+ const CObjectVector<COpenType> &types,
+ const CIntVector &excludedFormats,
bool stdInMode,
UStringVector &arcPaths, UStringVector &arcPathsFull,
+ bool processAltStreams, bool showAltStreams,
const NWildcard::CCensorNode &wildcardCensor,
bool enableHeaders, bool techMode,
#ifndef _NO_CRYPTO
bool &passwordEnabled, UString &password,
#endif
- UInt64 &numErrors)
+ #ifndef _SFX
+ const CObjectVector<CProperty> *props,
+ #endif
+ UInt64 &numErrors,
+ UInt64 &numWarnings)
{
+ bool allFilesAreAllowed = wildcardCensor.AreAllAllowed();
+
numErrors = 0;
- CFieldPrinter fieldPrinter;
+ numWarnings = 0;
+
+ CFieldPrinter fp;
if (!techMode)
- fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));
+ fp.Init(kStandardFieldTable, ARRAY_SIZE(kStandardFieldTable));
- UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;
- UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;
- int numArcs = /* stdInMode ? 1 : */ arcPaths.Size();
- for (int i = 0; i < numArcs; i++)
+ CListStat2 stat2total;
+
+ CBoolArr skipArcs(arcPaths.Size());
+ unsigned arcIndex;
+ for (arcIndex = 0; arcIndex < arcPaths.Size(); arcIndex++)
+ skipArcs[arcIndex] = false;
+ UInt64 numVolumes = 0;
+ UInt64 numArcs = 0;
+ UInt64 totalArcSizes = 0;
+
+ HRESULT lastError = 0;
+
+ for (arcIndex = 0; arcIndex < arcPaths.Size(); arcIndex++)
{
- const UString &archiveName = arcPaths[i];
+ if (skipArcs[arcIndex])
+ continue;
+ const UString &arcPath = arcPaths[arcIndex];
UInt64 arcPackSize = 0;
+
if (!stdInMode)
{
NFile::NFind::CFileInfo fi;
- if (!fi.Find(us2fs(archiveName)) || fi.IsDir())
+ if (!fi.Find(us2fs(arcPath)))
{
- g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;
+ DWORD errorCode = GetLastError();
+ if (errorCode == 0)
+ errorCode = ERROR_FILE_NOT_FOUND;
+ lastError = HRESULT_FROM_WIN32(lastError);;
+ g_StdOut.Flush();
+ *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) <<
+ endl << arcPath << endl << endl;
+ numErrors++;
+ continue;
+ }
+ if (fi.IsDir())
+ {
+ g_StdOut.Flush();
+ *g_ErrStream << endl << kError << arcPath << " is not a file" << endl << endl;
numErrors++;
continue;
}
arcPackSize = fi.Size;
+ totalArcSizes += arcPackSize;
}
- CArchiveLink archiveLink;
+ CArchiveLink arcLink;
COpenCallbackConsole openCallback;
- openCallback.OutStream = &g_StdOut;
+ openCallback.Init(&g_StdOut, g_ErrStream, NULL);
#ifndef _NO_CRYPTO
@@ -459,95 +1046,97 @@ HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
#endif
- HRESULT result = archiveLink.Open2(codecs, formatIndices, stdInMode, NULL, archiveName, &openCallback);
+ /*
+ CObjectVector<COptionalOpenProperties> optPropsVector;
+ COptionalOpenProperties &optProps = optPropsVector.AddNew();
+ optProps.Props = *props;
+ */
+
+ COpenOptions options;
+ #ifndef _SFX
+ options.props = props;
+ #endif
+ options.codecs = codecs;
+ options.types = &types;
+ options.excludedFormats = &excludedFormats;
+ options.stdInMode = stdInMode;
+ options.stream = NULL;
+ options.filePath = arcPath;
+
+ if (enableHeaders)
+ {
+ g_StdOut << endl << kListing << arcPath << endl << endl;
+ }
+
+ HRESULT result = arcLink.Open3(options, &openCallback);
+
if (result != S_OK)
{
if (result == E_ABORT)
return result;
- g_StdOut << endl << "Error: " << archiveName << ": ";
+ g_StdOut.Flush();
+ *g_ErrStream << endl << kError << arcPath << " : ";
if (result == S_FALSE)
{
- #ifndef _NO_CRYPTO
- if (openCallback.Open_WasPasswordAsked())
- g_StdOut << "Can not open encrypted archive. Wrong password?";
- else
- #endif
- g_StdOut << "Can not open file as archive";
+ Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink);
}
- else if (result == E_OUTOFMEMORY)
- g_StdOut << "Can't allocate required memory";
else
- g_StdOut << NError::MyFormatMessageW(result);
- g_StdOut << endl;
+ {
+ lastError = result;
+ *g_ErrStream << "opening : ";
+ if (result == E_OUTOFMEMORY)
+ *g_ErrStream << "Can't allocate required memory";
+ else
+ *g_ErrStream << NError::MyFormatMessage(result);
+ }
+ *g_ErrStream << endl;
numErrors++;
continue;
}
+
+ {
+ if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
+ numErrors++;
+
+ FOR_VECTOR (r, arcLink.Arcs)
+ {
+ const CArcErrorInfo &arc = arcLink.Arcs[r].ErrorInfo;
+ if (!arc.WarningMessage.IsEmpty())
+ numWarnings++;
+ if (arc.AreThereWarnings())
+ numWarnings++;
+ if (arc.ErrorFormatIndex >= 0)
+ numWarnings++;
+ if (arc.AreThereErrors())
+ {
+ numErrors++;
+ // break;
+ }
+ if (!arc.ErrorMessage.IsEmpty())
+ numErrors++;
+ }
+ }
+
+ numArcs++;
+ numVolumes++;
if (!stdInMode)
- for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
{
- int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]);
- if (index >= 0 && index > i)
+ numVolumes += arcLink.VolumePaths.Size();
+ totalArcSizes += arcLink.VolumesSize;
+ FOR_VECTOR (v, arcLink.VolumePaths)
{
- arcPaths.Delete(index);
- arcPathsFull.Delete(index);
- numArcs = arcPaths.Size();
+ int index = Find_FileName_InSortedVector(arcPathsFull, arcLink.VolumePaths[v]);
+ if (index >= 0 && (unsigned)index > arcIndex)
+ skipArcs[(unsigned)index] = true;
}
}
+
if (enableHeaders)
{
- g_StdOut << endl << kListing << archiveName << endl << endl;
+ RINOK(Print_OpenArchive_Props(g_StdOut, codecs, arcLink));
- for (int i = 0; i < archiveLink.Arcs.Size(); i++)
- {
- const CArc &arc = archiveLink.Arcs[i];
-
- g_StdOut << "--\n";
- PrintPropPair(L"Path", arc.Path);
- PrintPropPair(L"Type", codecs->Formats[arc.FormatIndex].Name);
- if (!arc.ErrorMessage.IsEmpty())
- PrintPropPair(L"Error", arc.ErrorMessage);
- UInt32 numProps;
- IInArchive *archive = arc.Archive;
- if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK)
- {
- for (UInt32 j = 0; j < numProps; j++)
- {
- CMyComBSTR name;
- PROPID propID;
- VARTYPE vt;
- RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt));
- NCOM::CPropVariant prop;
- RINOK(archive->GetArchiveProperty(propID, &prop));
- UString s = ConvertPropertyToString(prop, propID);
- if (!s.IsEmpty())
- PrintPropPair(GetPropName(propID, name), s);
- }
- }
- if (i != archiveLink.Arcs.Size() - 1)
- {
- UInt32 numProps;
- g_StdOut << "----\n";
- if (archive->GetNumberOfProperties(&numProps) == S_OK)
- {
- UInt32 mainIndex = archiveLink.Arcs[i + 1].SubfileIndex;
- for (UInt32 j = 0; j < numProps; j++)
- {
- CMyComBSTR name;
- PROPID propID;
- VARTYPE vt;
- RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt));
- NCOM::CPropVariant prop;
- RINOK(archive->GetProperty(mainIndex, propID, &prop));
- UString s = ConvertPropertyToString(prop, propID);
- if (!s.IsEmpty())
- PrintPropPair(GetPropName(propID, name), s);
- }
- }
- }
-
- }
g_StdOut << endl;
if (techMode)
g_StdOut << "----------\n";
@@ -555,100 +1144,148 @@ HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
if (enableHeaders && !techMode)
{
- fieldPrinter.PrintTitle();
+ fp.PrintTitle();
g_StdOut << endl;
- fieldPrinter.PrintTitleLines();
+ fp.PrintTitleLines();
g_StdOut << endl;
}
- const CArc &arc = archiveLink.Arcs.Back();
+ const CArc &arc = arcLink.Arcs.Back();
+ fp.Arc = &arc;
+ fp.TechMode = techMode;
IInArchive *archive = arc.Archive;
if (techMode)
{
- RINOK(fieldPrinter.Init(archive));
+ fp.Clear();
+ RINOK(fp.AddMainProps(archive));
+ if (arc.GetRawProps)
+ {
+ RINOK(fp.AddRawProps(arc.GetRawProps));
+ }
}
- UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0;
- UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;
+
+ CListStat2 stat2;
+
UInt32 numItems;
RINOK(archive->GetNumberOfItems(&numItems));
+
+ CReadArcItem item;
+ UStringVector pathParts;
+
for (UInt32 i = 0; i < numItems; i++)
{
if (NConsoleClose::TestBreakSignal())
return E_ABORT;
- UString filePath;
- HRESULT res = arc.GetItemPath(i, filePath);
+ HRESULT res = arc.GetItemPath2(i, fp.FilePath);
+
if (stdInMode && res == E_INVALIDARG)
break;
RINOK(res);
- bool isFolder;
- RINOK(IsArchiveItemFolder(archive, i, isFolder));
- if (!wildcardCensor.CheckPath(filePath, !isFolder))
- continue;
-
- fieldPrinter.PrintItemInfo(arc, i, techMode);
+ if (arc.Ask_Aux)
+ {
+ bool isAux;
+ RINOK(Archive_IsItem_Aux(archive, i, isAux));
+ if (isAux)
+ continue;
+ }
+
+ bool isAltStream = false;
+ if (arc.Ask_AltStream)
+ {
+ RINOK(Archive_IsItem_AltStream(archive, i, isAltStream));
+ if (isAltStream && !processAltStreams)
+ continue;
+ }
+
+ RINOK(Archive_IsItem_Dir(archive, i, fp.IsDir));
+
+ if (!allFilesAreAllowed)
+ {
+ if (isAltStream)
+ {
+ RINOK(arc.GetItem(i, item));
+ if (!CensorNode_CheckPath(wildcardCensor, item))
+ continue;
+ }
+ else
+ {
+ SplitPathToParts(fp.FilePath, pathParts);;
+ bool include;
+ if (!wildcardCensor.CheckPathVect(pathParts, !fp.IsDir, include))
+ continue;
+ if (!include)
+ continue;
+ }
+ }
- UInt64 packSize, unpackSize;
- if (!GetUInt64Value(archive, i, kpidSize, unpackSize))
- unpackSize = 0;
- else
- totalUnPackSizePointer = &totalUnPackSize;
- if (!GetUInt64Value(archive, i, kpidPackSize, packSize))
- packSize = 0;
- else
- totalPackSizePointer = &totalPackSize;
+ CListStat st;
- g_StdOut << endl;
+ RINOK(GetUInt64Value(archive, i, kpidSize, st.Size));
+ RINOK(GetUInt64Value(archive, i, kpidPackSize, st.PackSize));
+ RINOK(GetItemMTime(archive, i, st.MTime));
- if (isFolder)
- numDirs++;
+ if (fp.IsDir)
+ stat2.NumDirs++;
else
- numFiles++;
- totalPackSize += packSize;
- totalUnPackSize += unpackSize;
- }
+ st.NumFiles = 1;
+ stat2.GetStat(isAltStream).Update(st);
- if (!stdInMode && totalPackSizePointer == 0)
- {
- if (archiveLink.VolumePaths.Size() != 0)
- arcPackSize += archiveLink.VolumesSize;
- totalPackSize = (numFiles == 0) ? 0 : arcPackSize;
- totalPackSizePointer = &totalPackSize;
+ if (isAltStream && !showAltStreams)
+ continue;
+ RINOK(fp.PrintItemInfo(i, st));
}
- if (totalUnPackSizePointer == 0 && numFiles == 0)
+
+ UInt64 numStreams = stat2.GetNumStreams();
+ if (!stdInMode
+ && !stat2.MainFiles.PackSize.Def
+ && !stat2.AltStreams.PackSize.Def)
{
- totalUnPackSize = 0;
- totalUnPackSizePointer = &totalUnPackSize;
+ if (arcLink.VolumePaths.Size() != 0)
+ arcPackSize += arcLink.VolumesSize;
+ stat2.MainFiles.PackSize.Add((numStreams == 0) ? 0 : arcPackSize);
}
+
+ stat2.MainFiles.SetSizeDefIfNoFiles();
+ stat2.AltStreams.SetSizeDefIfNoFiles();
+
if (enableHeaders && !techMode)
{
- fieldPrinter.PrintTitleLines();
+ fp.PrintTitleLines();
g_StdOut << endl;
- fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer);
- g_StdOut << endl;
- }
- if (totalPackSizePointer != 0)
- {
- totalPackSizePointer2 = &totalPackSize2;
- totalPackSize2 += totalPackSize;
+ fp.PrintSum(stat2);
}
- if (totalUnPackSizePointer != 0)
+
+ if (enableHeaders)
{
- totalUnPackSizePointer2 = &totalUnPackSize2;
- totalUnPackSize2 += totalUnPackSize;
+ if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
+ {
+ g_StdOut << "----------\n";
+ PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath);
+ PrintArcTypeError(g_StdOut, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
+ }
}
- numFiles2 += numFiles;
- numDirs2 += numDirs;
+
+ stat2total.Update(stat2);
+
+ g_StdOut.Flush();
}
- if (enableHeaders && !techMode && numArcs > 1)
+
+ if (enableHeaders && !techMode && (arcPaths.Size() > 1 || numVolumes > 1))
{
g_StdOut << endl;
- fieldPrinter.PrintTitleLines();
+ fp.PrintTitleLines();
g_StdOut << endl;
- fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2);
+ fp.PrintSum(stat2total);
g_StdOut << endl;
- g_StdOut << "Archives: " << numArcs << endl;
+ PrintPropNameAndNumber(g_StdOut, "Archives", numArcs);
+ PrintPropNameAndNumber(g_StdOut, "Volumes", numVolumes);
+ PrintPropNameAndNumber(g_StdOut, "Total archives size", totalArcSizes);
}
+
+ if (numErrors == 1 && lastError != 0)
+ return lastError;
+
return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/List.h b/3rdparty/lzma/CPP/7zip/UI/Console/List.h
index 97d9fb15ab3..462c4710375 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/List.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/List.h
@@ -3,18 +3,25 @@
#ifndef __LIST_H
#define __LIST_H
-#include "Common/Wildcard.h"
+#include "../../../Common/Wildcard.h"
+
#include "../Common/LoadCodecs.h"
-HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
+HRESULT ListArchives(CCodecs *codecs,
+ const CObjectVector<COpenType> &types,
+ const CIntVector &excludedFormats,
bool stdInMode,
UStringVector &archivePaths, UStringVector &archivePathsFull,
+ bool processAltStreams, bool showAltStreams,
const NWildcard::CCensorNode &wildcardCensor,
bool enableHeaders, bool techMode,
#ifndef _NO_CRYPTO
bool &passwordEnabled, UString &password,
#endif
- UInt64 &errors);
+ #ifndef _SFX
+ const CObjectVector<CProperty> *props,
+ #endif
+ UInt64 &errors,
+ UInt64 &numWarnings);
#endif
-
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp
index f5a703979eb..50652555de7 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp
@@ -2,42 +2,55 @@
#include "StdAfx.h"
-#if defined( _WIN32) && defined( _7ZIP_LARGE_PAGES)
+#include "../../../Common/MyWindows.h"
+
+#ifdef _WIN32
+#include <Psapi.h>
+#endif
+
+#include "../../../../C/CpuArch.h"
+
+#if defined( _7ZIP_LARGE_PAGES)
#include "../../../../C/Alloc.h"
#endif
-#include "Common/MyInitGuid.h"
+#include "../../../Common/MyInitGuid.h"
-#include "Common/CommandLineParser.h"
-#include "Common/IntToString.h"
-#include "Common/MyException.h"
-#include "Common/StdOutStream.h"
-#include "Common/StringConvert.h"
-#include "Common/StringToInt.h"
+#include "../../../Common/CommandLineParser.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/MyException.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/StringToInt.h"
+#include "../../../Common/UTFConvert.h"
+
+#include "../../../Windows/ErrorMsg.h"
-#include "Windows/Error.h"
#ifdef _WIN32
-#include "Windows/MemoryLock.h"
+#include "../../../Windows/MemoryLock.h"
#endif
+#include "../../../Windows/TimeUtils.h"
+
#include "../Common/ArchiveCommandLine.h"
#include "../Common/ExitCode.h"
#include "../Common/Extract.h"
+
#ifdef EXTERNAL_CODECS
#include "../Common/LoadCodecs.h"
#endif
+#include "../../Common/RegisterCodec.h"
+
#include "BenchCon.h"
+#include "ConsoleClose.h"
#include "ExtractCallbackConsole.h"
#include "List.h"
#include "OpenCallbackConsole.h"
#include "UpdateCallbackConsole.h"
-#if !defined(EXTERNAL_CODECS) && defined(_NO_CRYPTO)
-#define IT_IS_REDUCED_VERSION
-#endif
+#include "HashCon.h"
-#ifdef IT_IS_REDUCED_VERSION
+#ifdef PROG_VARIANT_R
#include "../../../../C/7zVersion.h"
#else
#include "../../MyVersion.h"
@@ -50,27 +63,37 @@ using namespace NCommandLineParser;
#ifdef _WIN32
HINSTANCE g_hInstance = 0;
#endif
+
extern CStdOutStream *g_StdStream;
+extern CStdOutStream *g_ErrStream;
+
+extern unsigned g_NumCodecs;
+extern const CCodecInfo *g_Codecs[];
+
+extern unsigned g_NumHashers;
+extern const CHasherInfo *g_Hashers[];
static const char *kCopyrightString = "\n7-Zip"
#ifndef EXTERNAL_CODECS
-#ifdef IT_IS_REDUCED_VERSION
+#ifdef PROG_VARIANT_R
" (r)"
#else
" (a)"
#endif
#endif
-#ifdef _WIN64
+#ifdef MY_CPU_64BIT
" [64]"
+#elif defined MY_CPU_32BIT
+" [32]"
#endif
-" " MY_VERSION_COPYRIGHT_DATE "\n";
+" " MY_VERSION_COPYRIGHT_DATE "\n\n";
static const char *kHelpString =
- "\nUsage: 7z"
+ "Usage: 7z"
#ifndef EXTERNAL_CODECS
-#ifdef IT_IS_REDUCED_VERSION
+#ifdef PROG_VARIANT_R
"r"
#else
"a"
@@ -80,42 +103,65 @@ static const char *kHelpString =
" [<@listfiles...>]\n"
"\n"
"<Commands>\n"
- " a: Add files to archive\n"
- " b: Benchmark\n"
- " d: Delete files from archive\n"
- " e: Extract files from archive (without using directory names)\n"
- " l: List contents of archive\n"
-// " l[a|t][f]: List contents of archive\n"
-// " a - with Additional fields\n"
-// " t - with all fields\n"
-// " f - with Full pathnames\n"
- " t: Test integrity of archive\n"
- " u: Update files to archive\n"
- " x: eXtract files with full paths\n"
+ " a : Add files to archive\n"
+ " b : Benchmark\n"
+ " d : Delete files from archive\n"
+ " e : Extract files from archive (without using directory names)\n"
+ " h : Calculate hash values for files\n"
+ " i : Show information about supported formats\n"
+ " l : List contents of archive\n"
+ " rn : Rename files in archive\n"
+ " t : Test integrity of archive\n"
+ " u : Update files to archive\n"
+ " x : eXtract files with full paths\n"
+ "\n"
"<Switches>\n"
- " -ai[r[-|0]]{@listfile|!wildcard}: Include archives\n"
- " -ax[r[-|0]]{@listfile|!wildcard}: eXclude archives\n"
- " -bd: Disable percentage indicator\n"
- " -i[r[-|0]]{@listfile|!wildcard}: Include filenames\n"
- " -m{Parameters}: set compression Method\n"
- " -o{Directory}: set Output directory\n"
+ " -- : Stop switches parsing\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"
+ " -an : disable archive_name field\n"
+ " -bb[0-3] : set output log level\n"
+ " -bd : disable progress indicator\n"
+ " -bs{o|e|p}{0|1|2} : set output stream for output/error/progress line\n"
+ " -bt : show execution time statistics\n"
+ " -i[r[-|0]]{@listfile|!wildcard} : Include filenames\n"
+ " -m{Parameters} : set compression Method\n"
+ " -mmt[N] : set number of CPU threads\n"
+ " -o{Directory} : set Output directory\n"
#ifndef _NO_CRYPTO
- " -p{Password}: set Password\n"
+ " -p{Password} : set Password\n"
#endif
- " -r[-|0]: Recurse subdirectories\n"
- " -scs{UTF-8 | WIN | DOS}: set charset for list files\n"
- " -sfx[{name}]: Create SFX archive\n"
- " -si[{name}]: read data from stdin\n"
- " -slt: show technical information for l (List) command\n"
- " -so: write data to stdout\n"
- " -ssc[-]: set sensitive case mode\n"
- " -ssw: compress shared files\n"
- " -t{Type}: Set type of archive\n"
- " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n"
- " -v{Size}[b|k|m|g]: Create volumes\n"
- " -w[{path}]: assign Work directory. Empty path means a temporary directory\n"
- " -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n"
- " -y: assume Yes on all queries\n";
+ " -r[-|0] : Recurse subdirectories\n"
+ " -sa{a|e|s} : set Archive name mode\n"
+ " -scc{UTF-8|WIN|DOS} : set charset for for console input/output\n"
+ " -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n"
+ " -scrc[CRC32|CRC64|SHA1|SHA256|*] : set hash function for x, e, h commands\n"
+ " -sdel : delete files after compression\n"
+ " -seml[.] : send archive by email\n"
+ " -sfx[{name}] : Create SFX archive\n"
+ " -si[{name}] : read data from stdin\n"
+ " -slp : set Large Pages mode\n"
+ " -slt : show technical information for l (List) command\n"
+ " -snh : store hard links as links\n"
+ " -snl : store symbolic links as links\n"
+ " -sni : store NT security information\n"
+ " -sns[-] : store NTFS alternate streams\n"
+ " -so : write data to stdout\n"
+ " -spd : disable wildcard matching for file names\n"
+ " -spe : eliminate duplication of root folder for extract command\n"
+ " -spf : use fully qualified file paths\n"
+ " -ssc[-] : set sensitive case mode\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"
+ " -stx{Type} : exclude archive type\n"
+ " -t{Type} : Set type of archive\n"
+ " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options\n"
+ " -v{Size}[b|k|m|g] : Create volumes\n"
+ " -w[{path}] : assign Work directory. Empty path means a temporary directory\n"
+ " -x[r[-|0]]{@listfile|!wildcard} : eXclude filenames\n"
+ " -y : assume Yes on all queries\n";
// ---------------------------
// exception messages
@@ -124,21 +170,17 @@ 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 CFSTR kDefaultSfxModule = FTEXT("7zCon.sfx");
-static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code)
+static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code)
{
- s << message << endl;
+ if (g_ErrStream)
+ *g_ErrStream << endl << "ERROR: " << message << endl;
throw code;
}
-static void PrintHelpAndExit(CStdOutStream &s)
-{
- s << kHelpString;
- ShowMessageAndThrowException(s, kUserErrorMessage, NExitCode::kUserError);
-}
-
#ifndef _WIN32
static void GetArguments(int numArgs, const char *args[], UStringVector &parts)
{
@@ -151,48 +193,295 @@ static void GetArguments(int numArgs, const char *args[], UStringVector &parts)
}
#endif
-static void ShowCopyrightAndHelp(CStdOutStream &s, bool needHelp)
+static void ShowCopyrightAndHelp(CStdOutStream *so, bool needHelp)
{
- s << kCopyrightString;
- // s << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << "\n";
+ if (!so)
+ return;
+ *so << kCopyrightString;
+ // *so << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << endl;
if (needHelp)
- s << kHelpString;
+ *so << kHelpString;
}
-#ifdef EXTERNAL_CODECS
-static void PrintString(CStdOutStream &stdStream, const AString &s, int size)
+
+static void PrintStringRight(CStdOutStream &so, const AString &s, unsigned size)
+{
+ unsigned len = s.Len();
+ for (unsigned i = len; i < size; i++)
+ so << ' ';
+ so << s;
+}
+
+static void PrintUInt32(CStdOutStream &so, UInt32 val, unsigned size)
+{
+ char s[16];
+ ConvertUInt32ToString(val, s);
+ PrintStringRight(so, s, size);
+}
+
+static void PrintLibIndex(CStdOutStream &so, int libIndex)
+{
+ if (libIndex >= 0)
+ PrintUInt32(so, libIndex, 2);
+ else
+ so << " ";
+ so << ' ';
+}
+
+static void PrintString(CStdOutStream &so, const UString &s, unsigned size)
+{
+ unsigned len = s.Len();
+ so << s;
+ for (unsigned i = len; i < size; i++)
+ so << ' ';
+}
+
+static inline char GetHex(unsigned val)
+{
+ return (char)((val < 10) ? ('0' + val) : ('A' + (val - 10)));
+}
+
+static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so)
+{
+ FOR_VECTOR(i, pc.Paths)
+ {
+ so << pc.Paths[i] << " : ";
+ so << NError::MyFormatMessage(pc.Codes[i]) << endl;
+ }
+ so << "----------------" << endl;
+}
+
+static int WarningsCheck(HRESULT result, const CCallbackConsoleBase &callback,
+ const CUpdateErrorInfo &errorInfo,
+ CStdOutStream *so,
+ CStdOutStream *se,
+ bool showHeaders)
+{
+ int exitCode = NExitCode::kSuccess;
+
+ if (callback.ScanErrors.Paths.Size() != 0)
+ {
+ if (se)
+ {
+ *se << endl;
+ *se << "Scan WARNINGS for files and folders:" << endl << endl;
+ PrintWarningsPaths(callback.ScanErrors, *se);
+ *se << "Scan WARNINGS: " << callback.ScanErrors.Paths.Size();
+ *se << endl;
+ }
+ exitCode = NExitCode::kWarning;
+ }
+
+ if (result != S_OK || errorInfo.ThereIsError())
+ {
+ if (se)
+ {
+ UString message;
+ if (!errorInfo.Message.IsEmpty())
+ {
+ message.AddAscii(errorInfo.Message);
+ message.Add_LF();
+ }
+ {
+ FOR_VECTOR(i, errorInfo.FileNames)
+ {
+ message += fs2us(errorInfo.FileNames[i]);
+ message.Add_LF();
+ }
+ }
+ if (errorInfo.SystemError != 0)
+ {
+ message += NError::MyFormatMessage(errorInfo.SystemError);
+ message.Add_LF();
+ }
+ if (!message.IsEmpty())
+ *se << L"\nError:\n" << message;
+ }
+
+ // we will work with (result) later
+ // throw CSystemException(result);
+ return NExitCode::kFatalError;
+ }
+
+ unsigned numErrors = callback.FailedFiles.Paths.Size();
+ if (numErrors == 0)
+ {
+ if (showHeaders)
+ if (callback.ScanErrors.Paths.Size() == 0)
+ if (so)
+ {
+ if (se)
+ se->Flush();
+ *so << kEverythingIsOk << endl;
+ }
+ }
+ else
+ {
+ if (se)
+ {
+ *se << endl;
+ *se << "WARNINGS for files:" << endl << endl;
+ PrintWarningsPaths(callback.FailedFiles, *se);
+ *se << "WARNING: Cannot open " << numErrors << " file";
+ if (numErrors > 1)
+ *se << 's';
+ *se << endl;
+ }
+ exitCode = NExitCode::kWarning;
+ }
+
+ return exitCode;
+}
+
+static void ThrowException_if_Error(HRESULT res)
+{
+ if (res != S_OK)
+ throw CSystemException(res);
+}
+
+
+static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ')
+{
+ char temp[64];
+ char *p = temp + 32;
+ ConvertUInt64ToString(val, p);
+ unsigned len = MyStringLen(p);
+ for (; len < numDigits; len++)
+ *--p = c;
+ *g_StdStream << p;
+}
+
+static void PrintTime(const char *s, UInt64 val, UInt64 total)
+{
+ *g_StdStream << endl << s << " Time =";
+ const UInt32 kFreq = 10000000;
+ UInt64 sec = val / kFreq;
+ PrintNum(sec, 6);
+ *g_StdStream << '.';
+ UInt32 ms = (UInt32)(val - (sec * kFreq)) / (kFreq / 1000);
+ PrintNum(ms, 3, '0');
+
+ while (val > ((UInt64)1 << 56))
+ {
+ val >>= 1;
+ total >>= 1;
+ }
+
+ UInt64 percent = 0;
+ if (total != 0)
+ percent = val * 100 / total;
+ *g_StdStream << " =";
+ PrintNum(percent, 5);
+ *g_StdStream << '%';
+}
+
+#ifndef UNDER_CE
+
+#define SHIFT_SIZE_VALUE(x, num) (((x) + (1 << (num)) - 1) >> (num))
+
+static void PrintMemUsage(const char *s, UInt64 val)
{
- int len = s.Length();
- stdStream << s;
- for (int i = len; i < size; i++)
- stdStream << ' ';
+ *g_StdStream << " " << s << " Memory =";
+ PrintNum(SHIFT_SIZE_VALUE(val, 20), 7);
+ *g_StdStream << " MB";
}
+
+EXTERN_C_BEGIN
+typedef BOOL (WINAPI *Func_GetProcessMemoryInfo)(HANDLE Process,
+ PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb);
+EXTERN_C_END
+
#endif
-static void PrintString(CStdOutStream &stdStream, const UString &s, int size)
+static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
+
+static void PrintStat()
{
- int len = s.Length();
- stdStream << s;
- for (int i = len; i < size; i++)
- stdStream << ' ';
+ FILETIME creationTimeFT, exitTimeFT, kernelTimeFT, userTimeFT;
+ if (!
+ #ifdef UNDER_CE
+ ::GetThreadTimes(::GetCurrentThread()
+ #else
+ // NT 3.5
+ ::GetProcessTimes(::GetCurrentProcess()
+ #endif
+ , &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT))
+ return;
+ FILETIME curTimeFT;
+ NTime::GetCurUtcFileTime(curTimeFT);
+
+ #ifndef UNDER_CE
+
+ PROCESS_MEMORY_COUNTERS m;
+ memset(&m, 0, sizeof(m));
+ BOOL memDefined = FALSE;
+ {
+ /* NT 4.0: GetProcessMemoryInfo() in Psapi.dll
+ Win7: new function K32GetProcessMemoryInfo() in kernel32.dll
+ It's faster to call kernel32.dll code than Psapi.dll code
+ GetProcessMemoryInfo() requires Psapi.lib
+ Psapi.lib in SDK7+ can link to K32GetProcessMemoryInfo in kernel32.dll
+ The program with K32GetProcessMemoryInfo will not work on systems before Win7
+ // memDefined = GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m));
+ */
+
+ Func_GetProcessMemoryInfo my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)
+ ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "K32GetProcessMemoryInfo");
+ if (!my_GetProcessMemoryInfo)
+ {
+ HMODULE lib = LoadLibraryW(L"Psapi.dll");
+ if (lib)
+ my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)::GetProcAddress(lib, "GetProcessMemoryInfo");
+ }
+ if (my_GetProcessMemoryInfo)
+ memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m));
+ // FreeLibrary(lib);
+ }
+
+ #endif
+
+ UInt64 curTime = GetTime64(curTimeFT);
+ UInt64 creationTime = GetTime64(creationTimeFT);
+ UInt64 kernelTime = GetTime64(kernelTimeFT);
+ UInt64 userTime = GetTime64(userTimeFT);
+
+ UInt64 totalTime = curTime - creationTime;
+
+ PrintTime("Kernel ", kernelTime, totalTime);
+ PrintTime("User ", userTime, totalTime);
+
+ PrintTime("Process", kernelTime + userTime, totalTime);
+ #ifndef UNDER_CE
+ if (memDefined) PrintMemUsage("Virtual ", m.PeakPagefileUsage);
+ #endif
+
+ PrintTime("Global ", totalTime, totalTime);
+ #ifndef UNDER_CE
+ if (memDefined) PrintMemUsage("Physical", m.PeakWorkingSetSize);
+ #endif
+
+ *g_StdStream << endl;
}
-static inline char GetHex(Byte value)
+static void PrintHexId(CStdOutStream &so, UInt64 id)
{
- return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+ char s[32];
+ ConvertUInt64ToHex(id, s);
+ PrintStringRight(so, s, 8);
}
int Main2(
#ifndef _WIN32
- int numArgs, const char *args[]
+ int numArgs, char *args[]
#endif
)
{
#if defined(_WIN32) && !defined(UNDER_CE)
SetFileApisToOEM();
#endif
-
+
UStringVector commandStrings;
+
#ifdef _WIN32
NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
#else
@@ -201,89 +490,185 @@ int Main2(
if (commandStrings.Size() == 1)
{
- ShowCopyrightAndHelp(g_StdOut, true);
+ ShowCopyrightAndHelp(g_StdStream, true);
return 0;
}
+
commandStrings.Delete(0);
- CArchiveCommandLineOptions options;
+ CArcCmdLineOptions options;
- CArchiveCommandLineParser parser;
+ CArcCmdLineParser parser;
parser.Parse1(commandStrings, options);
+
+ if (options.Number_for_Out != k_OutStream_stdout)
+ g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL);
+
+ if (options.Number_for_Errors != k_OutStream_stderr)
+ g_ErrStream = (options.Number_for_Errors == k_OutStream_stdout ? &g_StdOut : NULL);
+
+ CStdOutStream *percentsStream = NULL;
+ if (options.Number_for_Percents != k_OutStream_disabled)
+ percentsStream = (options.Number_for_Percents == k_OutStream_stderr) ? &g_StdErr : &g_StdOut;;
+
if (options.HelpMode)
{
- ShowCopyrightAndHelp(g_StdOut, true);
+ ShowCopyrightAndHelp(g_StdStream, true);
return 0;
}
- #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ NSecurity::EnablePrivilege_SymLink();
+ #endif
+
+ #ifdef _7ZIP_LARGE_PAGES
if (options.LargePages)
{
SetLargePageSize();
- NSecurity::EnableLockMemoryPrivilege();
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ NSecurity::EnablePrivilege_LockMemory();
+ #endif
}
#endif
- CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut;
- g_StdStream = &stdStream;
-
if (options.EnableHeaders)
- ShowCopyrightAndHelp(stdStream, false);
+ ShowCopyrightAndHelp(g_StdStream, false);
parser.Parse2(options);
- CCodecs *codecs = new CCodecs;
- CMyComPtr<
- #ifdef EXTERNAL_CODECS
- ICompressCodecsInfo
+ unsigned percentsNameLevel = 1;
+ if (options.LogLevel == 0 || options.Number_for_Percents != options.Number_for_Out)
+ percentsNameLevel = 2;
+
+ unsigned consoleWidth = 80;
+
+ if (percentsStream)
+ {
+ #ifdef _WIN32
+
+ #if !defined(UNDER_CE)
+ CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
+ consoleWidth = consoleInfo.dwSize.X;
+ #endif
+
#else
- IUnknown
+
+ struct winsize w;
+ if (ioctl(0, TIOCGWINSZ, &w) == )
+ consoleWidth = w.ws_col;
+
#endif
- > compressCodecsInfo = codecs;
- HRESULT result = codecs->Load();
- if (result != S_OK)
- throw CSystemException(result);
+ }
+
+ CREATE_CODECS_OBJECT
+
+ codecs->CaseSensitiveChange = options.CaseSensitiveChange;
+ codecs->CaseSensitive = options.CaseSensitive;
+ ThrowException_if_Error(codecs->Load());
bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
if (codecs->Formats.Size() == 0 &&
- (isExtractGroupCommand ||
- options.Command.CommandType == NCommandType::kList ||
- options.Command.IsFromUpdateGroup()))
+ (isExtractGroupCommand
+ || options.Command.CommandType == NCommandType::kList
+ || options.Command.IsFromUpdateGroup()))
+ {
+ #ifdef EXTERNAL_CODECS
+ if (!codecs->MainDll_ErrorPath.IsEmpty())
+ {
+ UString s = L"Can't load module ";
+ s += fs2us(codecs->MainDll_ErrorPath);
+ throw s;
+ }
+ #endif
+
throw kNoFormats;
+ }
- CIntVector formatIndices;
- if (!codecs->FindFormatForArchiveType(options.ArcType, formatIndices))
+ CObjectVector<COpenType> types;
+ if (!ParseOpenTypes(*codecs, options.ArcType, types))
throw kUnsupportedArcTypeMessage;
+ CIntVector excludedFormats;
+ FOR_VECTOR (k, options.ExcludedArcTypes)
+ {
+ CIntVector tempIndices;
+ if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices)
+ || tempIndices.Size() != 1)
+ throw kUnsupportedArcTypeMessage;
+ excludedFormats.AddToUniqueSorted(tempIndices[0]);
+ // excludedFormats.Sort();
+ }
+
+
+ #ifdef EXTERNAL_CODECS
+ if (isExtractGroupCommand
+ || options.Command.CommandType == NCommandType::kHash
+ || options.Command.CommandType == NCommandType::kBenchmark)
+ ThrowException_if_Error(__externalCodecs.Load());
+ #endif
+
+ int retCode = NExitCode::kSuccess;
+ HRESULT hresultMain = S_OK;
+
+ // bool showStat = options.ShowTime;
+
+ /*
+ if (!options.EnableHeaders ||
+ options.TechMode)
+ showStat = false;
+ */
+
+
if (options.Command.CommandType == NCommandType::kInfo)
{
- stdStream << endl << "Formats:" << endl;
- int i;
+ CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut);
+ unsigned i;
+
+ #ifdef EXTERNAL_CODECS
+ so << endl << "Libs:" << endl;
+ for (i = 0; i < codecs->Libs.Size(); i++)
+ {
+ PrintLibIndex(so, i);
+ so << ' ' << codecs->Libs[i].Path << endl;
+ }
+ #endif
+
+ so << endl << "Formats:" << endl;
+
+ const char *kArcFlags = "KSNFMGOPBELH";
+ const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags);
+
for (i = 0; i < codecs->Formats.Size(); i++)
{
const CArcInfoEx &arc = codecs->Formats[i];
+
#ifdef EXTERNAL_CODECS
- if (arc.LibIndex >= 0)
+ PrintLibIndex(so, arc.LibIndex);
+ #else
+ so << " ";
+ #endif
+
+ so << (char)(arc.UpdateEnabled ? 'C' : ' ');
+
+ for (unsigned b = 0; b < kNumArcFlags; b++)
{
- char s[16];
- ConvertUInt32ToString(arc.LibIndex, s);
- PrintString(stdStream, s, 2);
+ so << (char)
+ ((arc.Flags & ((UInt32)1 << b)) != 0 ? kArcFlags[b] : ' ');
}
- else
- #endif
- stdStream << " ";
- stdStream << ' ';
- stdStream << (char)(arc.UpdateEnabled ? 'C' : ' ');
- stdStream << (char)(arc.KeepName ? 'K' : ' ');
- stdStream << " ";
- PrintString(stdStream, arc.Name, 6);
- stdStream << " ";
+
+ so << ' ';
+ PrintString(so, arc.Name, 8);
+ so << ' ';
UString s;
- for (int t = 0; t < arc.Exts.Size(); t++)
+
+ FOR_VECTOR (t, arc.Exts)
{
+ if (t != 0)
+ s.Add_Space();
const CArcExtInfo &ext = arc.Exts[t];
s += ext.Ext;
if (!ext.AddExt.IsEmpty())
@@ -292,199 +677,381 @@ int Main2(
s += ext.AddExt;
s += L')';
}
- s += L' ';
}
- PrintString(stdStream, s, 14);
- stdStream << " ";
- const CByteBuffer &sig = arc.StartSignature;
- for (size_t j = 0; j < sig.GetCapacity(); j++)
+
+ PrintString(so, s, 13);
+ so << ' ';
+
+ if (arc.SignatureOffset != 0)
+ so << "offset=" << arc.SignatureOffset << ' ';
+
+ FOR_VECTOR(si, arc.Signatures)
{
- Byte b = sig[j];
- if (b > 0x20 && b < 0x80)
- {
- stdStream << (char)b;
- }
- else
+ if (si != 0)
+ so << " || ";
+
+ const CByteBuffer &sig = arc.Signatures[si];
+
+ for (size_t j = 0; j < sig.Size(); j++)
{
- stdStream << GetHex((Byte)((b >> 4) & 0xF));
- stdStream << GetHex((Byte)(b & 0xF));
+ if (j != 0)
+ so << ' ';
+ Byte b = sig[j];
+ if (b > 0x20 && b < 0x80)
+ {
+ so << (char)b;
+ }
+ else
+ {
+ so << GetHex((b >> 4) & 0xF);
+ so << GetHex(b & 0xF);
+ }
}
- stdStream << ' ';
}
- stdStream << endl;
+ so << endl;
+ }
+
+ so << endl << "Codecs:" << endl; // << "Lib ID Name" << endl;
+
+ for (i = 0; i < g_NumCodecs; i++)
+ {
+ const CCodecInfo &cod = *g_Codecs[i];
+
+ PrintLibIndex(so, -1);
+
+ if (cod.NumStreams == 1)
+ so << ' ';
+ else
+ so << cod.NumStreams;
+
+ so << (char)(cod.CreateEncoder ? 'E' : ' ');
+ so << (char)(cod.CreateDecoder ? 'D' : ' ');
+
+ so << ' ';
+ PrintHexId(so, cod.Id);
+ so << ' ' << cod.Name << endl;
}
- stdStream << endl << "Codecs:" << endl;
+
#ifdef EXTERNAL_CODECS
+
UInt32 numMethods;
- if (codecs->GetNumberOfMethods(&numMethods) == S_OK)
+ if (codecs->GetNumMethods(&numMethods) == S_OK)
for (UInt32 j = 0; j < numMethods; j++)
{
- int libIndex = codecs->GetCodecLibIndex(j);
- if (libIndex >= 0)
- {
- char s[16];
- ConvertUInt32ToString(libIndex, s);
- PrintString(stdStream, s, 2);
- }
+ PrintLibIndex(so, codecs->GetCodec_LibIndex(j));
+
+ UInt32 numStreams = codecs->GetCodec_NumStreams(j);
+ if (numStreams == 1)
+ so << ' ';
else
- stdStream << " ";
- stdStream << ' ';
- stdStream << (char)(codecs->GetCodecEncoderIsAssigned(j) ? 'C' : ' ');
+ so << numStreams;
+
+ so << (char)(codecs->GetCodec_EncoderIsAssigned(j) ? 'E' : ' ');
+ so << (char)(codecs->GetCodec_DecoderIsAssigned(j) ? 'D' : ' ');
+
+ so << ' ';
UInt64 id;
- stdStream << " ";
- HRESULT res = codecs->GetCodecId(j, id);
+ HRESULT res = codecs->GetCodec_Id(j, id);
if (res != S_OK)
id = (UInt64)(Int64)-1;
- char s[32];
- ConvertUInt64ToString(id, s, 16);
- PrintString(stdStream, s, 8);
- stdStream << " ";
- PrintString(stdStream, codecs->GetCodecName(j), 11);
- stdStream << endl;
- /*
- if (res != S_OK)
- throw "incorrect Codec ID";
- */
+ PrintHexId(so, id);
+ so << ' ' << codecs->GetCodec_Name(j) << endl;
}
+
#endif
- return S_OK;
+
+
+ so << endl << "Hashers:" << endl; // << " L Size ID Name" << endl;
+
+ for (i = 0; i < g_NumHashers; i++)
+ {
+ const CHasherInfo &codec = *g_Hashers[i];
+ PrintLibIndex(so, -1);
+ PrintUInt32(so, codec.DigestSize, 4);
+ so << ' ';
+ PrintHexId(so, codec.Id);
+ so << ' ' << codec.Name << endl;
+ }
+
+ #ifdef EXTERNAL_CODECS
+
+ numMethods = codecs->GetNumHashers();
+ for (UInt32 j = 0; j < numMethods; j++)
+ {
+ PrintLibIndex(so, codecs->GetHasherLibIndex(j));
+ PrintUInt32(so, codecs->GetHasherDigestSize(j), 4);
+ so << ' ';
+ PrintHexId(so, codecs->GetHasherId(j));
+ so << ' ' << codecs->GetHasherName(j) << endl;
+ }
+
+ #endif
+
}
else if (options.Command.CommandType == NCommandType::kBenchmark)
{
+ CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut);
+ hresultMain = BenchCon(EXTERNAL_CODECS_VARS_L
+ options.Properties, options.NumIterations, (FILE *)so);
+ if (hresultMain == S_FALSE)
{
- HRESULT res;
- #ifdef EXTERNAL_CODECS
- CObjectVector<CCodecInfoEx> externalCodecs;
- res = LoadExternalCodecs(compressCodecsInfo, externalCodecs);
- if (res != S_OK)
- throw CSystemException(res);
- #endif
- res = BenchCon(
- #ifdef EXTERNAL_CODECS
- compressCodecsInfo, &externalCodecs,
- #endif
- options.Properties, options.NumIterations, (FILE *)stdStream);
- if (res != S_OK)
+ if (g_ErrStream)
+ *g_ErrStream << "\nDecoding ERROR\n";
+ retCode = NExitCode::kFatalError;
+ hresultMain = S_OK;
+ }
+ }
+ else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
+ {
+ UStringVector ArchivePathsSorted;
+ UStringVector ArchivePathsFullSorted;
+
+ if (options.StdInMode)
+ {
+ ArchivePathsSorted.Add(options.ArcName_for_StdInMode);
+ ArchivePathsFullSorted.Add(options.ArcName_for_StdInMode);
+ }
+ else
+ {
+ CExtractScanConsole scan;
+
+ scan.Init(options.EnableHeaders ? g_StdStream : NULL, g_ErrStream, percentsStream);
+ scan.SetWindowWidth(consoleWidth);
+
+ if (g_StdStream && options.EnableHeaders)
+ *g_StdStream << "Scanning the drive for archives:" << endl;
+
+ CDirItemsStat st;
+
+ scan.StartScanning();
+
+ hresultMain = EnumerateDirItemsAndSort(
+ options.arcCensor,
+ NWildcard::k_RelatPath,
+ UString(), // addPathPrefix
+ ArchivePathsSorted,
+ ArchivePathsFullSorted,
+ st,
+ &scan);
+
+ scan.CloseScanning();
+
+ if (hresultMain == S_OK)
{
- if (res == S_FALSE)
+ if (options.EnableHeaders)
+ scan.PrintStat(st);
+ }
+ else
+ {
+ /*
+ if (res != E_ABORT)
{
- stdStream << "\nDecoding Error\n";
- return NExitCode::kFatalError;
+ throw CSystemException(res);
+ // errorInfo.Message = "Scanning error";
}
- throw CSystemException(res);
+ return res;
+ */
}
}
- }
- else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
- {
+
+ if (hresultMain == S_OK)
if (isExtractGroupCommand)
{
CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
- ecs->OutStream = &stdStream;
-
#ifndef _NO_CRYPTO
ecs->PasswordIsDefined = options.PasswordEnabled;
ecs->Password = options.Password;
#endif
- ecs->Init();
+ ecs->Init(g_StdStream, g_ErrStream, percentsStream);
+ ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1);
+ ecs->LogLevel = options.LogLevel;
+ ecs->PercentsNameLevel = percentsNameLevel;
+
+ if (percentsStream)
+ ecs->SetWindowWidth(consoleWidth);
+
+ /*
COpenCallbackConsole openCallback;
- openCallback.OutStream = &stdStream;
+ openCallback.Init(g_StdStream, g_ErrStream);
#ifndef _NO_CRYPTO
openCallback.PasswordIsDefined = options.PasswordEnabled;
openCallback.Password = options.Password;
#endif
+ */
CExtractOptions eo;
+ (CExtractOptionsBase &)eo = options.ExtractOptions;
+
eo.StdInMode = options.StdInMode;
eo.StdOutMode = options.StdOutMode;
- eo.PathMode = options.Command.GetPathMode();
- eo.TestMode = options.Command.IsTestMode();
- eo.OverwriteMode = options.OverwriteMode;
- eo.OutputDir = options.OutputDir;
eo.YesToAll = options.YesToAll;
- eo.CalcCrc = options.CalcCrc;
- #if !defined(_7ZIP_ST) && !defined(_SFX)
+ eo.TestMode = options.Command.IsTestCommand();
+
+ #ifndef _SFX
eo.Properties = options.Properties;
#endif
+
UString errorMessage;
CDecompressStat stat;
- HRESULT result = DecompressArchives(
+ CHashBundle hb;
+ IHashCalc *hashCalc = NULL;
+
+ if (!options.HashMethods.IsEmpty())
+ {
+ hashCalc = &hb;
+ ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods));
+ hb.Init();
+ }
+
+ hresultMain = Extract(
codecs,
- formatIndices,
- options.ArchivePathsSorted,
- options.ArchivePathsFullSorted,
- options.WildcardCensor.Pairs.Front().Head,
- eo, &openCallback, ecs, errorMessage, stat);
+ types,
+ excludedFormats,
+ ArchivePathsSorted,
+ ArchivePathsFullSorted,
+ options.Censor.Pairs.Front().Head,
+ eo, ecs, ecs, hashCalc, errorMessage, stat);
+
+ ecs->ClosePercents();
+
if (!errorMessage.IsEmpty())
{
- stdStream << endl << "Error: " << errorMessage;
- if (result == S_OK)
- result = E_FAIL;
+ if (g_ErrStream)
+ *g_ErrStream << endl << "ERROR:" << endl << errorMessage << endl;
+ if (hresultMain == S_OK)
+ hresultMain = E_FAIL;
}
- stdStream << endl;
- if (ecs->NumArchives > 1)
- stdStream << "Archives: " << ecs->NumArchives << endl;
- if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)
+ CStdOutStream *so = g_StdStream;
+
+ bool isError = false;
+
+ if (so)
+ {
+ *so << endl;
+
+ if (ecs->NumTryArcs > 1)
+ {
+ *so << "Archives: " << ecs->NumTryArcs << endl;
+ *so << "OK archives: " << ecs->NumOkArcs << endl;
+ }
+ }
+
+ if (ecs->NumCantOpenArcs != 0)
+ {
+ isError = true;
+ if (so)
+ *so << "Can't open as archive: " << ecs->NumCantOpenArcs << endl;
+ }
+
+ if (ecs->NumArcsWithError != 0)
+ {
+ isError = true;
+ if (so)
+ *so << "Archives with Errors: " << ecs->NumArcsWithError << endl;
+ }
+
+ if (so)
{
- if (ecs->NumArchives > 1)
+ if (ecs->NumArcsWithWarnings != 0)
+ *so << "Archives with Warnings: " << ecs->NumArcsWithWarnings << endl;
+
+ if (ecs->NumOpenArcWarnings != 0)
{
- stdStream << endl;
- if (ecs->NumArchiveErrors != 0)
- stdStream << "Archive Errors: " << ecs->NumArchiveErrors << endl;
+ *so << endl;
+ if (ecs->NumOpenArcWarnings != 0)
+ *so << "Warnings: " << ecs->NumOpenArcWarnings << endl;
+ }
+ }
+
+ if (ecs->NumOpenArcErrors != 0)
+ {
+ isError = true;
+ if (so)
+ {
+ *so << endl;
+ if (ecs->NumOpenArcErrors != 0)
+ *so << "Open Errors: " << ecs->NumOpenArcErrors << endl;
+ }
+ }
+
+ if (isError)
+ retCode = NExitCode::kFatalError;
+
+ if (so)
+ if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0)
+ {
+ // if (ecs->NumArchives > 1)
+ {
+ *so << endl;
if (ecs->NumFileErrors != 0)
- stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl;
+ *so << "Sub items Errors: " << ecs->NumFileErrors << endl;
}
- if (result != S_OK)
- throw CSystemException(result);
- return NExitCode::kFatalError;
}
- if (result != S_OK)
- throw CSystemException(result);
- if (stat.NumFolders != 0)
- stdStream << "Folders: " << stat.NumFolders << endl;
- if (stat.NumFiles != 1 || stat.NumFolders != 0)
- stdStream << "Files: " << stat.NumFiles << endl;
- stdStream
- << "Size: " << stat.UnpackSize << endl
- << "Compressed: " << stat.PackSize << endl;
- if (options.CalcCrc)
+ else if (hresultMain == S_OK)
{
- char s[16];
- ConvertUInt32ToHexWithZeros(stat.CrcSum, s);
- stdStream << "CRC: " << s << endl;
+ if (stat.NumFolders != 0)
+ *so << "Folders: " << stat.NumFolders << endl;
+ if (stat.NumFiles != 1 || stat.NumFolders != 0 || stat.NumAltStreams != 0)
+ *so << "Files: " << stat.NumFiles << endl;
+ if (stat.NumAltStreams != 0)
+ {
+ *so << "Alternate Streams: " << stat.NumAltStreams << endl;
+ *so << "Alternate Streams Size: " << stat.AltStreams_UnpackSize << endl;
+ }
+
+ *so
+ << "Size: " << stat.UnpackSize << endl
+ << "Compressed: " << stat.PackSize << endl;
+ if (hashCalc)
+ {
+ *so << endl;
+ PrintHashStat(*so, hb);
+ }
}
}
else
{
UInt64 numErrors = 0;
- HRESULT result = ListArchives(
+ UInt64 numWarnings = 0;
+
+ // options.ExtractNtOptions.StoreAltStreams = true, if -sns[-] is not definmed
+
+ hresultMain = ListArchives(
codecs,
- formatIndices,
+ types,
+ excludedFormats,
options.StdInMode,
- options.ArchivePathsSorted,
- options.ArchivePathsFullSorted,
- options.WildcardCensor.Pairs.Front().Head,
+ ArchivePathsSorted,
+ ArchivePathsFullSorted,
+ options.ExtractOptions.NtOptions.AltStreams.Val,
+ options.AltStreams.Val, // we don't want to show AltStreams by default
+ options.Censor.Pairs.Front().Head,
options.EnableHeaders,
options.TechMode,
#ifndef _NO_CRYPTO
options.PasswordEnabled,
options.Password,
#endif
- numErrors);
+ &options.Properties,
+ numErrors, numWarnings);
+
+ if (options.EnableHeaders)
+ if (numWarnings > 0)
+ g_StdOut << endl << "Warnings: " << numWarnings << endl;
+
if (numErrors > 0)
{
- g_StdOut << endl << "Errors: " << numErrors << endl;
- return NExitCode::kFatalError;
+ if (options.EnableHeaders)
+ g_StdOut << endl << "Errors: " << numErrors << endl;
+ retCode = NExitCode::kFatalError;
}
- if (result != S_OK)
- throw CSystemException(result);
}
}
else if (options.Command.IsFromUpdateGroup())
@@ -494,105 +1061,86 @@ int Main2(
uo.SfxModule = kDefaultSfxModule;
COpenCallbackConsole openCallback;
- openCallback.OutStream = &stdStream;
+ openCallback.Init(g_StdStream, g_ErrStream, percentsStream);
#ifndef _NO_CRYPTO
bool passwordIsDefined =
- options.PasswordEnabled && !options.Password.IsEmpty();
+ (options.PasswordEnabled && !options.Password.IsEmpty());
openCallback.PasswordIsDefined = passwordIsDefined;
openCallback.Password = options.Password;
#endif
CUpdateCallbackConsole callback;
- callback.EnablePercents = options.EnablePercents;
+ callback.LogLevel = options.LogLevel;
+ callback.PercentsNameLevel = percentsNameLevel;
+
+ if (percentsStream)
+ callback.SetWindowWidth(consoleWidth);
#ifndef _NO_CRYPTO
callback.PasswordIsDefined = passwordIsDefined;
- callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();
+ callback.AskPassword = (options.PasswordEnabled && options.Password.IsEmpty());
callback.Password = options.Password;
#endif
+
callback.StdOutMode = uo.StdOutMode;
- callback.Init(&stdStream);
+ callback.Init(
+ // NULL,
+ g_StdStream, g_ErrStream, percentsStream);
CUpdateErrorInfo errorInfo;
- if (!uo.Init(codecs, formatIndices, options.ArchiveName))
- throw kUnsupportedArcTypeMessage;
- HRESULT result = UpdateArchive(codecs,
- options.WildcardCensor, uo,
- errorInfo, &openCallback, &callback);
+ /*
+ if (!uo.Init(codecs, types, options.ArchiveName))
+ throw kUnsupportedUpdateArcType;
+ */
+ hresultMain = UpdateArchive(codecs,
+ types,
+ options.ArchiveName,
+ options.Censor,
+ uo,
+ errorInfo, &openCallback, &callback, true);
- int exitCode = NExitCode::kSuccess;
- if (callback.CantFindFiles.Size() > 0)
- {
- stdStream << endl;
- stdStream << "WARNINGS for files:" << endl << endl;
- int numErrors = callback.CantFindFiles.Size();
- for (int i = 0; i < numErrors; i++)
- {
- stdStream << callback.CantFindFiles[i] << " : ";
- stdStream << NError::MyFormatMessageW(callback.CantFindCodes[i]) << endl;
- }
- stdStream << "----------------" << endl;
- stdStream << "WARNING: Cannot find " << numErrors << " file";
- if (numErrors > 1)
- stdStream << "s";
- stdStream << endl;
- exitCode = NExitCode::kWarning;
- }
+ callback.ClosePercents2();
- if (result != S_OK)
- {
- UString message;
- if (!errorInfo.Message.IsEmpty())
- {
- message += errorInfo.Message;
- message += L"\n";
- }
- if (!errorInfo.FileName.IsEmpty())
- {
- message += fs2us(errorInfo.FileName);
- message += L"\n";
- }
- if (!errorInfo.FileName2.IsEmpty())
- {
- message += fs2us(errorInfo.FileName2);
- message += L"\n";
- }
- if (errorInfo.SystemError != 0)
- {
- message += NError::MyFormatMessageW(errorInfo.SystemError);
- message += L"\n";
- }
- if (!message.IsEmpty())
- stdStream << L"\nError:\n" << message;
- throw CSystemException(result);
- }
- int numErrors = callback.FailedFiles.Size();
- if (numErrors == 0)
- {
- if (callback.CantFindFiles.Size() == 0)
- stdStream << kEverythingIsOk << endl;
- }
- else
- {
- stdStream << endl;
- stdStream << "WARNINGS for files:" << endl << endl;
- for (int i = 0; i < numErrors; i++)
- {
- stdStream << callback.FailedFiles[i] << " : ";
- stdStream << NError::MyFormatMessageW(callback.FailedCodes[i]) << endl;
- }
- stdStream << "----------------" << endl;
- stdStream << "WARNING: Cannot open " << numErrors << " file";
- if (numErrors > 1)
- stdStream << "s";
- stdStream << endl;
- exitCode = NExitCode::kWarning;
- }
- return exitCode;
+ CStdOutStream *se = g_StdStream;
+ if (!se)
+ se = g_ErrStream;
+
+ retCode = WarningsCheck(hresultMain, callback, errorInfo,
+ g_StdStream, se,
+ true // options.EnableHeaders
+ );
+ }
+ else if (options.Command.CommandType == NCommandType::kHash)
+ {
+ const CHashOptions &uo = options.HashOptions;
+
+ CHashCallbackConsole callback;
+ if (percentsStream)
+ callback.SetWindowWidth(consoleWidth);
+
+ callback.Init(g_StdStream, g_ErrStream, percentsStream);
+ callback.PrintHeaders = options.EnableHeaders;
+
+ AString errorInfoString;
+ hresultMain = HashCalc(EXTERNAL_CODECS_VARS_L
+ options.Censor, uo,
+ errorInfoString, &callback);
+ CUpdateErrorInfo errorInfo;
+ errorInfo.Message = errorInfoString;
+ CStdOutStream *se = g_StdStream;
+ if (!se)
+ se = g_ErrStream;
+ retCode = WarningsCheck(hresultMain, callback, errorInfo, g_StdStream, se, options.EnableHeaders);
}
else
- PrintHelpAndExit(stdStream);
- return 0;
+ ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError);
+
+ if (options.ShowTime && g_StdStream)
+ PrintStat();
+
+ ThrowException_if_Error(hresultMain);
+
+ return retCode;
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp
index 25f4bd0df44..d30a96e4be2 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp
@@ -2,11 +2,11 @@
#include "StdAfx.h"
-#include "Common/MyException.h"
-#include "Common/StdOutStream.h"
+#include "../../../Common/MyException.h"
+#include "../../../Common/StdOutStream.h"
-#include "Windows/Error.h"
-#include "Windows/NtCheck.h"
+#include "../../../Windows/ErrorMsg.h"
+#include "../../../Windows/NtCheck.h"
#include "../Common/ArchiveCommandLine.h"
#include "../Common/ExitCode.h"
@@ -15,35 +15,52 @@
using namespace NWindows;
-CStdOutStream *g_StdStream = 0;
+CStdOutStream *g_StdStream = NULL;
+CStdOutStream *g_ErrStream = NULL;
extern int Main2(
#ifndef _WIN32
- int numArgs, const char *args[]
+ int numArgs, char *args[]
#endif
);
-static const char *kExceptionErrorMessage = "\n\nError:\n";
-static const char *kUserBreak = "\nBreak signaled\n";
-static const char *kMemoryExceptionMessage = "\n\nERROR: Can't allocate required memory!\n";
-static const char *kUnknownExceptionMessage = "\n\nUnknown Error\n";
+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 #";
-#define NT_CHECK_FAIL_ACTION (*g_StdStream) << "Unsupported Windows version"; return NExitCode::kFatalError;
+static void FlushStreams()
+{
+ if (g_StdStream)
+ g_StdStream->Flush();
+}
+
+static void PrintError(const char *message)
+{
+ FlushStreams();
+ if (g_ErrStream)
+ *g_ErrStream << "\n\n" << message << endl;
+}
+
+#define NT_CHECK_FAIL_ACTION *g_StdStream << "Unsupported Windows version"; return NExitCode::kFatalError;
int MY_CDECL main
(
#ifndef _WIN32
- int numArgs, const char *args[]
+ int numArgs, char *args[]
#endif
)
{
+ g_ErrStream = &g_StdErr;
g_StdStream = &g_StdOut;
NT_CHECK
NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter;
int res = 0;
+
try
{
res = Main2(
@@ -54,71 +71,97 @@ int MY_CDECL main
}
catch(const CNewException &)
{
- (*g_StdStream) << kMemoryExceptionMessage;
+ PrintError(kMemoryExceptionMessage);
return (NExitCode::kMemoryError);
}
catch(const NConsoleClose::CCtrlBreakException &)
{
- (*g_StdStream) << endl << kUserBreak;
+ PrintError(kUserBreakMessage);
return (NExitCode::kUserBreak);
}
- catch(const CArchiveCommandLineException &e)
+ catch(const CArcCmdLineException &e)
{
- (*g_StdStream) << kExceptionErrorMessage << e << endl;
+ PrintError(kException_CmdLine_Error_Message);
+ if (g_ErrStream)
+ *g_ErrStream << e << endl;
return (NExitCode::kUserError);
}
catch(const CSystemException &systemError)
{
if (systemError.ErrorCode == E_OUTOFMEMORY)
{
- (*g_StdStream) << kMemoryExceptionMessage;
+ PrintError(kMemoryExceptionMessage);
return (NExitCode::kMemoryError);
}
if (systemError.ErrorCode == E_ABORT)
{
- (*g_StdStream) << endl << kUserBreak;
+ PrintError(kUserBreakMessage);
return (NExitCode::kUserBreak);
}
- (*g_StdStream) << endl << endl << "System error:" << endl <<
- NError::MyFormatMessageW(systemError.ErrorCode) << endl;
+ if (g_ErrStream)
+ {
+ PrintError("System ERROR:");
+ *g_ErrStream << NError::MyFormatMessage(systemError.ErrorCode) << endl;
+ }
return (NExitCode::kFatalError);
}
catch(NExitCode::EEnum &exitCode)
{
- (*g_StdStream) << kInternalExceptionMessage << exitCode << endl;
+ FlushStreams();
+ if (g_ErrStream)
+ *g_ErrStream << kInternalExceptionMessage << exitCode << endl;
return (exitCode);
}
- /*
- catch(const NExitCode::CMultipleErrors &multipleErrors)
- {
- (*g_StdStream) << endl << multipleErrors.NumErrors << " errors" << endl;
- return (NExitCode::kFatalError);
- }
- */
catch(const UString &s)
{
- (*g_StdStream) << kExceptionErrorMessage << s << endl;
+ if (g_ErrStream)
+ {
+ PrintError(kExceptionErrorMessage);
+ *g_ErrStream << s << endl;
+ }
return (NExitCode::kFatalError);
}
catch(const AString &s)
{
- (*g_StdStream) << kExceptionErrorMessage << s << endl;
+ if (g_ErrStream)
+ {
+ PrintError(kExceptionErrorMessage);
+ *g_ErrStream << s << endl;
+ }
return (NExitCode::kFatalError);
}
catch(const char *s)
{
- (*g_StdStream) << kExceptionErrorMessage << s << endl;
+ if (g_ErrStream)
+ {
+ PrintError(kExceptionErrorMessage);
+ *g_ErrStream << s << endl;
+ }
return (NExitCode::kFatalError);
}
- catch(int t)
+ catch(const wchar_t *s)
{
- (*g_StdStream) << kInternalExceptionMessage << t << endl;
+ if (g_ErrStream)
+ {
+ PrintError(kExceptionErrorMessage);
+ *g_ErrStream << s << endl;
+ }
return (NExitCode::kFatalError);
}
+ catch(int t)
+ {
+ if (g_ErrStream)
+ {
+ FlushStreams();
+ *g_ErrStream << kInternalExceptionMessage << t << endl;
+ return (NExitCode::kFatalError);
+ }
+ }
catch(...)
{
- (*g_StdStream) << kUnknownExceptionMessage;
+ PrintError(kUnknownExceptionMessage);
return (NExitCode::kFatalError);
}
- return res;
+
+ return res;
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
index 7dba2ad5d9b..9d25a729ca0 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
@@ -7,41 +7,93 @@
#include "ConsoleClose.h"
#include "UserInputUtils.h"
+static HRESULT CheckBreak2()
+{
+ return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK;
+}
+
HRESULT COpenCallbackConsole::Open_CheckBreak()
{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- return S_OK;
+ return CheckBreak2();
}
-HRESULT COpenCallbackConsole::Open_SetTotal(const UInt64 *, const UInt64 *)
+HRESULT COpenCallbackConsole::Open_SetTotal(const UInt64 *files, const UInt64 *bytes)
{
- return Open_CheckBreak();
+ if (!MultiArcMode && NeedPercents())
+ {
+ if (files)
+ {
+ _totalFilesDefined = true;
+ // _totalFiles = *files;
+ _percent.Total = *files;
+ }
+ else
+ _totalFilesDefined = false;
+
+ if (bytes)
+ {
+ _totalBytesDefined = true;
+ // _totalBytes = *bytes;
+ if (!files)
+ _percent.Total = *bytes;
+ }
+ else
+ _totalBytesDefined = false;
+ }
+
+ return CheckBreak2();
}
-HRESULT COpenCallbackConsole::Open_SetCompleted(const UInt64 *, const UInt64 *)
+HRESULT COpenCallbackConsole::Open_SetCompleted(const UInt64 *files, const UInt64 *bytes)
{
- return Open_CheckBreak();
+ if (!MultiArcMode && NeedPercents())
+ {
+ if (files)
+ {
+ _percent.Files = *files;
+ if (_totalFilesDefined)
+ _percent.Completed = *files;
+ }
+
+ if (bytes)
+ {
+ if (!_totalFilesDefined)
+ _percent.Completed = *bytes;
+ }
+ _percent.Print();
+ }
+
+ return CheckBreak2();
}
-
+
+HRESULT COpenCallbackConsole::Open_Finished()
+{
+ ClosePercents();
+ return S_OK;
+}
+
+
#ifndef _NO_CRYPTO
HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password)
{
- PasswordWasAsked = true;
- RINOK(Open_CheckBreak());
+ *password = NULL;
+ RINOK(CheckBreak2());
+
if (!PasswordIsDefined)
{
- Password = GetPassword(OutStream);
+ ClosePercents();
+ Password = GetPassword(_so);
PasswordIsDefined = true;
}
return StringToBstr(Password, password);
}
-HRESULT COpenCallbackConsole::Open_GetPasswordIfAny(UString &password)
+/*
+HRESULT COpenCallbackConsole::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password)
{
- if (PasswordIsDefined)
- password = Password;
+ passwordIsDefined = PasswordIsDefined;
+ password = Password;
return S_OK;
}
@@ -50,9 +102,10 @@ bool COpenCallbackConsole::Open_WasPasswordAsked()
return PasswordWasAsked;
}
-void COpenCallbackConsole::Open_ClearPasswordWasAskedFlag()
+void COpenCallbackConsole::Open_Clear_PasswordWasAsked_Flag ()
{
PasswordWasAsked = false;
}
+*/
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h b/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h
index c002e6a726f..0dd4e1d1c82 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h
@@ -1,23 +1,64 @@
// OpenCallbackConsole.h
-#ifndef __OPENCALLBACKCONSOLE_H
-#define __OPENCALLBACKCONSOLE_H
+#ifndef __OPEN_CALLBACK_CONSOLE_H
+#define __OPEN_CALLBACK_CONSOLE_H
+
+#include "../../../Common/StdOutStream.h"
-#include "Common/StdOutStream.h"
#include "../Common/ArchiveOpenCallback.h"
+#include "PercentPrinter.h"
+
class COpenCallbackConsole: public IOpenCallbackUI
{
+protected:
+ CPercentPrinter _percent;
+
+ CStdOutStream *_so;
+ CStdOutStream *_se;
+
+ bool _totalFilesDefined;
+ bool _totalBytesDefined;
+ // UInt64 _totalFiles;
+ // UInt64 _totalBytes;
+
+ bool NeedPercents() const { return _percent._so != NULL; }
+
public:
- INTERFACE_IOpenCallbackUI(;)
+
+ bool MultiArcMode;
+
+ void ClosePercents()
+ {
+ if (NeedPercents())
+ _percent.ClosePrint(true);
+ }
+
+ COpenCallbackConsole():
+ _totalFilesDefined(false),
+ _totalBytesDefined(false),
+ MultiArcMode(false)
+
+ #ifndef _NO_CRYPTO
+ , PasswordIsDefined(false)
+ // , PasswordWasAsked(false)
+ #endif
+
+ {}
- CStdOutStream *OutStream;
+ void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
+ {
+ _so = outStream;
+ _se = errorStream;
+ _percent._so = percentStream;
+ }
+ INTERFACE_IOpenCallbackUI(;)
+
#ifndef _NO_CRYPTO
bool PasswordIsDefined;
- bool PasswordWasAsked;
+ // bool PasswordWasAsked;
UString Password;
- COpenCallbackConsole(): PasswordIsDefined(false), PasswordWasAsked(false) {}
#endif
};
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp
index 786db1bcebb..e3e8d599811 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp
@@ -2,101 +2,180 @@
#include "StdAfx.h"
-#include "Common/IntToString.h"
-#include "Common/MyString.h"
+#include "../../../Common/IntToString.h"
#include "PercentPrinter.h"
-static const unsigned kPaddingSize = 2;
static const unsigned kPercentsSize = 4;
-static const unsigned kMaxExtraSize = kPaddingSize + 32 + kPercentsSize;
-static void ClearPrev(char *p, unsigned num)
+CPercentPrinter::~CPercentPrinter()
{
- unsigned i;
- for (i = 0; i < num; i++) *p++ = '\b';
- for (i = 0; i < num; i++) *p++ = ' ';
- for (i = 0; i < num; i++) *p++ = '\b';
- *p = '\0';
-}
-
-void CPercentPrinter::ClosePrint()
-{
- if (m_NumExtraChars == 0)
- return;
- char s[kMaxExtraSize * 3 + 1];
- ClearPrev(s, m_NumExtraChars);
- (*OutStream) << s;
- m_NumExtraChars = 0;
+ ClosePrint(false);
}
-void CPercentPrinter::PrintString(const char *s)
+void CPercentPrinterState::ClearCurState()
{
- ClosePrint();
- (*OutStream) << s;
+ Completed = 0;
+ Total = ((UInt64)(Int64)-1);
+ Files = 0;
+ Command.Empty();
+ FileName.Empty();
}
-void CPercentPrinter::PrintString(const wchar_t *s)
+void CPercentPrinter::ClosePrint(bool needFlush)
{
- ClosePrint();
- (*OutStream) << s;
-}
+ unsigned num = _printedString.Len();
+ if (num != 0)
+ {
-void CPercentPrinter::PrintNewLine()
-{
- ClosePrint();
- (*OutStream) << "\n";
+ unsigned i;
+
+ /* '\r' in old MAC OS means "new line".
+ So we can't use '\r' in some systems */
+
+ #ifdef _WIN32
+ char *start = _temp.GetBuf(num + 2);
+ char *p = start;
+ *p++ = '\r';
+ for (i = 0; i < num; i++) *p++ = ' ';
+ *p++ = '\r';
+ #else
+ char *start = _temp.GetBuf(num * 3);
+ char *p = start;
+ for (i = 0; i < num; i++) *p++ = '\b';
+ for (i = 0; i < num; i++) *p++ = ' ';
+ for (i = 0; i < num; i++) *p++ = '\b';
+ #endif
+
+ *p = 0;
+ _temp.ReleaseBuf_SetLen((unsigned)(p - start));
+ *_so << _temp;
+ }
+ if (needFlush)
+ _so->Flush();
+ _printedString.Empty();
}
-void CPercentPrinter::RePrintRatio()
+void CPercentPrinter::GetPercents()
{
char s[32];
unsigned size;
{
char c = '%';
- UInt64 value = 0;
- if (m_Total == (UInt64)(Int64)-1)
+ UInt64 val = 0;
+ if (Total == (UInt64)(Int64)-1)
{
- value = m_CurValue >> 20;
+ val = Completed >> 20;
c = 'M';
}
- else if (m_Total != 0)
- value = m_CurValue * 100 / m_Total;
- ConvertUInt64ToString(value, s);
+ else if (Total != 0)
+ val = Completed * 100 / Total;
+ ConvertUInt64ToString(val, s);
size = (unsigned)strlen(s);
s[size++] = c;
- s[size] = '\0';
+ s[size] = 0;
}
- unsigned extraSize = kPaddingSize + MyMax(size, kPercentsSize);
- if (extraSize < m_NumExtraChars)
- extraSize = m_NumExtraChars;
-
- char fullString[kMaxExtraSize * 3];
- char *p = fullString;
- unsigned i;
- if (m_NumExtraChars == 0)
+ while (size < kPercentsSize)
{
- for (i = 0; i < extraSize; i++)
- *p++ = ' ';
- m_NumExtraChars = extraSize;
+ _s += ' ';
+ size++;
}
- for (i = 0; i < m_NumExtraChars; i++)
- *p++ = '\b';
- m_NumExtraChars = extraSize;
- for (; size < extraSize; size++)
- *p++ = ' ';
- MyStringCopy(p, s);
- (*OutStream) << fullString;
- OutStream->Flush();
- m_PrevValue = m_CurValue;
+ _s += s;
}
-void CPercentPrinter::PrintRatio()
+void CPercentPrinter::Print()
{
- if (m_CurValue < m_PrevValue + m_MinStepSize &&
- m_CurValue + m_MinStepSize > m_PrevValue && m_NumExtraChars != 0)
+ DWORD tick = 0;
+ if (_tickStep != 0)
+ tick = GetTickCount();
+
+ bool onlyPercentsChanged = false;
+
+ if (!_printedString.IsEmpty())
+ {
+ if (_tickStep != 0 && (UInt32)(tick - _prevTick) < _tickStep)
+ return;
+
+ CPercentPrinterState &st = *this;
+ if (_printedState.Command == st.Command
+ && _printedState.FileName == st.FileName
+ && _printedState.Files == st.Files)
+ {
+ if (_printedState.Total == st.Total
+ && _printedState.Completed == st.Completed)
+ return;
+ onlyPercentsChanged = true;
+ }
+ }
+
+ _s.Empty();
+
+ GetPercents();
+
+ if (onlyPercentsChanged && _s == _printedPercents)
return;
- RePrintRatio();
+
+ _printedPercents = _s;
+
+ if (Files != 0)
+ {
+ char s[32];
+ ConvertUInt64ToString(Files, s);
+ // unsigned size = (unsigned)strlen(s);
+ // for (; size < 3; size++) _s += ' ';
+ _s += ' ';
+ _s += s;
+ // _s += "f";
+ }
+
+
+ if (!Command.IsEmpty())
+ {
+ _s += ' ';
+ _s += Command;
+ }
+
+ if (!FileName.IsEmpty() && _s.Len() < MaxLen)
+ {
+ _s += ' ';
+
+ StdOut_Convert_UString_to_AString(FileName, _temp);
+ _temp.Replace('\n', ' ');
+ if (_s.Len() + _temp.Len() > MaxLen)
+ {
+ unsigned len = FileName.Len();
+ for (; len != 0;)
+ {
+ unsigned delta = len / 8;
+ if (delta == 0)
+ delta = 1;
+ len -= delta;
+ _tempU = FileName;
+ _tempU.Delete(len / 2, FileName.Len() - len);
+ _tempU.Insert(len / 2, L" . ");
+ StdOut_Convert_UString_to_AString(_tempU, _temp);
+ if (_s.Len() + _temp.Len() <= MaxLen)
+ break;
+ }
+ if (len == 0)
+ _temp.Empty();
+ }
+ _s += _temp;
+ }
+
+ if (_printedString != _s)
+ {
+ ClosePrint(false);
+ *_so << _s;
+ if (NeedFlush)
+ _so->Flush();
+ _printedString = _s;
+ }
+
+ _printedState = *this;
+
+ if (_tickStep != 0)
+ _prevTick = tick;
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h b/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h
index d970cc4b94f..95290b37e9c 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h
@@ -3,28 +3,60 @@
#ifndef __PERCENT_PRINTER_H
#define __PERCENT_PRINTER_H
-#include "Common/StdOutStream.h"
+#include "../../../Common/StdOutStream.h"
-class CPercentPrinter
+struct CPercentPrinterState
{
- UInt64 m_MinStepSize;
- UInt64 m_PrevValue;
- UInt64 m_CurValue;
- UInt64 m_Total;
- unsigned m_NumExtraChars;
+ UInt64 Completed;
+ UInt64 Total;
+
+ UInt64 Files;
+
+ AString Command;
+ UString FileName;
+
+ void ClearCurState();
+
+ CPercentPrinterState():
+ Completed(0),
+ Total((UInt64)(Int64)-1),
+ Files(0)
+ {}
+};
+
+class CPercentPrinter: public CPercentPrinterState
+{
+ UInt32 _tickStep;
+ DWORD _prevTick;
+
+ AString _s;
+
+ AString _printedString;
+ AString _temp;
+ UString _tempU;
+
+ CPercentPrinterState _printedState;
+ AString _printedPercents;
+
+ void GetPercents();
+
public:
- CStdOutStream *OutStream;
-
- CPercentPrinter(UInt64 minStepSize = 1): m_MinStepSize(minStepSize),
- m_PrevValue(0), m_CurValue(0), m_Total((UInt64)(Int64)-1), m_NumExtraChars(0) {}
- void SetTotal(UInt64 total) { m_Total = total; m_PrevValue = 0; }
- void SetRatio(UInt64 doneValue) { m_CurValue = doneValue; }
- void PrintString(const char *s);
- void PrintString(const wchar_t *s);
- void PrintNewLine();
- void ClosePrint();
- void RePrintRatio();
- void PrintRatio();
+ CStdOutStream *_so;
+
+ bool NeedFlush;
+ unsigned MaxLen;
+
+ CPercentPrinter(UInt32 tickStep = 200):
+ _tickStep(tickStep),
+ _prevTick(0),
+ NeedFlush(true),
+ MaxLen(80 - 1)
+ {}
+
+ ~CPercentPrinter();
+
+ void ClosePrint(bool needFlush);
+ void Print();
};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h b/3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h
index 2e4be10b291..2854ff3e935 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../../Common/MyWindows.h"
-#include "../../../Common/NewHandler.h"
+#include "../../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
index 7f337319714..f4f2d10210d 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
@@ -2,15 +2,17 @@
#include "StdAfx.h"
-#include "UpdateCallbackConsole.h"
+#include "../../../Common/IntToString.h"
+
+#include "../../../Windows/ErrorMsg.h"
-#include "Windows/Error.h"
#ifndef _7ZIP_ST
-#include "Windows/Synchronization.h"
+#include "../../../Windows/Synchronization.h"
#endif
#include "ConsoleClose.h"
#include "UserInputUtils.h"
+#include "UpdateCallbackConsole.h"
using namespace NWindows;
@@ -23,179 +25,590 @@ static NSynchronization::CCriticalSection g_CriticalSection;
static const wchar_t *kEmptyFileAlias = L"[Content]";
-static const char *kCreatingArchiveMessage = "Creating archive ";
-static const char *kUpdatingArchiveMessage = "Updating archive ";
-static const char *kScanningMessage = "Scanning";
+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 *kError = "ERROR: ";
+static const char *kWarning = "WARNING: ";
+
+static HRESULT CheckBreak2()
+{
+ return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK;
+}
+
+HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink);
+HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink);
+
+void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags);
+void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc);
-HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result)
+HRESULT CUpdateCallbackConsole::OpenResult(
+ const CCodecs *codecs, const CArchiveLink &arcLink,
+ const wchar_t *name, HRESULT result)
{
- (*OutStream) << endl;
- if (result != S_OK)
- (*OutStream) << "Error: " << name << " is not supported archive" << endl;
+ ClosePercents2();
+
+ FOR_VECTOR (level, arcLink.Arcs)
+ {
+ const CArc &arc = arcLink.Arcs[level];
+ const CArcErrorInfo &er = arc.ErrorInfo;
+
+ UInt32 errorFlags = er.GetErrorFlags();
+
+ if (errorFlags != 0 || !er.ErrorMessage.IsEmpty())
+ {
+ if (_se)
+ {
+ *_se << endl;
+ if (level != 0)
+ *_se << arc.Path << endl;
+ }
+
+ if (errorFlags != 0)
+ {
+ if (_se)
+ PrintErrorFlags(*_se, "ERRORS:", errorFlags);
+ }
+
+ if (!er.ErrorMessage.IsEmpty())
+ {
+ if (_se)
+ *_se << "ERRORS:" << endl << er.ErrorMessage << endl;
+ }
+
+ if (_se)
+ {
+ *_se << endl;
+ _se->Flush();
+ }
+ }
+
+ UInt32 warningFlags = er.GetWarningFlags();
+
+ if (warningFlags != 0 || !er.WarningMessage.IsEmpty())
+ {
+ if (_so)
+ {
+ *_so << endl;
+ if (level != 0)
+ *_so << arc.Path << endl;
+ }
+
+ if (warningFlags != 0)
+ {
+ if (_so)
+ PrintErrorFlags(*_so, "WARNINGS:", warningFlags);
+ }
+
+ if (!er.WarningMessage.IsEmpty())
+ {
+ if (_so)
+ *_so << "WARNINGS:" << endl << er.WarningMessage << endl;
+ }
+
+ if (_so)
+ {
+ *_so << endl;
+ if (NeedFlush)
+ _so->Flush();
+ }
+ }
+
+
+ if (er.ErrorFormatIndex >= 0)
+ {
+ if (_so)
+ {
+ Print_ErrorFormatIndex_Warning(_so, codecs, arc);
+ if (NeedFlush)
+ _so->Flush();
+ }
+ }
+ }
+
+ if (result == S_OK)
+ {
+ if (_so)
+ {
+ RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink));
+ *_so << endl;
+ }
+ }
+ else
+ {
+ if (_so)
+ _so->Flush();
+ if (_se)
+ {
+ *_se << kError << name << endl;
+ HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink);
+ RINOK(res);
+ _se->Flush();
+ }
+ }
+
return S_OK;
}
HRESULT CUpdateCallbackConsole::StartScanning()
{
- (*OutStream) << kScanningMessage;
+ if (_so)
+ *_so << kScanningMessage << endl;
+ _percent.Command = "Scan ";
return S_OK;
}
-HRESULT CUpdateCallbackConsole::ScanProgress(UInt64 /* numFolders */, UInt64 /* numFiles */, const wchar_t * /* path */)
+HRESULT CUpdateCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */)
{
+ if (NeedPercents())
+ {
+ _percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams;
+ _percent.Completed = st.GetTotalBytes();
+ _percent.FileName = fs2us(path);
+ _percent.Print();
+ }
+
return CheckBreak();
}
-HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError)
+void CCallbackConsoleBase::CommonError(const FString &path, DWORD systemError, bool isWarning)
+{
+ ClosePercents2();
+
+ if (_se)
+ {
+ if (_so)
+ _so->Flush();
+
+ *_se << endl << (isWarning ? kWarning : kError)
+ << NError::MyFormatMessage(systemError)
+ << endl << fs2us(path) << endl << endl;
+ _se->Flush();
+ }
+}
+
+
+HRESULT CCallbackConsoleBase::ScanError_Base(const FString &path, DWORD systemError)
+{
+ MT_LOCK
+
+ ScanErrors.AddError(path, systemError);
+ CommonError(path, systemError, true);
+
+ return S_OK;
+}
+
+HRESULT CCallbackConsoleBase::OpenFileError_Base(const FString &path, DWORD systemError)
+{
+ MT_LOCK
+ FailedFiles.AddError(path, systemError);
+ /*
+ if (systemError == ERROR_SHARING_VIOLATION)
+ {
+ */
+ CommonError(path, systemError, true);
+ return S_FALSE;
+ /*
+ }
+ return systemError;
+ */
+}
+
+HRESULT CCallbackConsoleBase::ReadingFileError_Base(const FString &path, DWORD systemError)
+{
+ MT_LOCK
+ CommonError(path, systemError, false);
+ return HRESULT_FROM_WIN32(systemError);
+}
+
+HRESULT CUpdateCallbackConsole::ScanError(const FString &path, DWORD systemError)
+{
+ return ScanError_Base(path, systemError);
+}
+
+
+static void PrintPropPair(AString &s, const char *name, UInt64 val)
+{
+ char temp[32];
+ ConvertUInt64ToString(val, temp);
+ s += name;
+ s += ": ";
+ s += temp;
+}
+
+void PrintSize_bytes_Smart(AString &s, UInt64 val);
+void Print_DirItemsStat(AString &s, const CDirItemsStat &st);
+
+HRESULT CUpdateCallbackConsole::FinishScanning(const CDirItemsStat &st)
{
- CantFindFiles.Add(name);
- CantFindCodes.Add(systemError);
- // m_PercentPrinter.ClosePrint();
- if (!m_WarningsMode)
+ if (NeedPercents())
+ {
+ _percent.ClosePrint(true);
+ _percent.ClearCurState();
+ }
+
+ if (_so)
{
- (*OutStream) << endl << endl;
- m_PercentPrinter.PrintNewLine();
- m_WarningsMode = true;
+ AString s;
+ Print_DirItemsStat(s, st);
+ *_so << s << endl << endl;
}
- m_PercentPrinter.PrintString(name);
- m_PercentPrinter.PrintString(": WARNING: ");
- m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
- m_PercentPrinter.PrintNewLine();
return S_OK;
}
-HRESULT CUpdateCallbackConsole::FinishScanning()
+static const char *k_StdOut_ArcName = "StdOut";
+
+HRESULT CUpdateCallbackConsole::StartOpenArchive(const wchar_t *name)
{
- (*OutStream) << endl << endl;
+ if (_so)
+ {
+ *_so << kOpenArchiveMessage;
+ if (name)
+ *_so << name;
+ else
+ *_so << k_StdOut_ArcName;
+ *_so << endl;
+ }
return S_OK;
}
HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating)
{
- if(updating)
- (*OutStream) << kUpdatingArchiveMessage;
- else
- (*OutStream) << kCreatingArchiveMessage;
- if (name != 0)
- (*OutStream) << name;
- else
- (*OutStream) << "StdOut";
- (*OutStream) << endl << endl;
+ if (_so)
+ {
+ *_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage);
+ if (name != 0)
+ *_so << name;
+ else
+ *_so << k_StdOut_ArcName;
+ *_so << endl << endl;
+ }
return S_OK;
}
-HRESULT CUpdateCallbackConsole::FinishArchive()
+HRESULT CUpdateCallbackConsole::FinishArchive(const CFinishArchiveStat &st)
{
- (*OutStream) << endl;
+ ClosePercents2();
+
+ if (_so)
+ {
+ AString s;
+ // Print_UInt64_and_String(s, _percent.Files == 1 ? "file" : "files", _percent.Files);
+ PrintPropPair(s, "Files read from disk", _percent.Files);
+ s.Add_LF();
+ s += "Archive size: ";
+ PrintSize_bytes_Smart(s, st.OutArcFileSize);
+ s.Add_LF();
+ *_so << endl;
+ *_so << s;
+ // *_so << endl;
+ }
+
return S_OK;
}
-HRESULT CUpdateCallbackConsole::CheckBreak()
+HRESULT CUpdateCallbackConsole::WriteSfx(const wchar_t *name, UInt64 size)
{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
+ if (_so)
+ {
+ *_so << "Write SFX: ";
+ *_so << name;
+ AString s = " : ";
+ PrintSize_bytes_Smart(s, size);
+ *_so << s << endl;
+ }
return S_OK;
}
-HRESULT CUpdateCallbackConsole::Finilize()
+
+HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */)
{
- MT_LOCK
- if (m_NeedBeClosed)
+ if (LogLevel > 0 && _so)
+ {
+ ClosePercents_for_so();
+
+ if (!DeleteMessageWasShown)
+ {
+ if (_so)
+ *_so << endl << ": Removing files after including to archive" << endl;
+ }
+
+ {
+ {
+ _tempA = "Removing";
+ _tempA.Add_Space();
+ *_so << _tempA;
+ _tempU = fs2us(path);
+ _so->PrintUString(_tempU, _tempA);
+ *_so << endl;
+ if (NeedFlush)
+ _so->Flush();
+ }
+ }
+ }
+
+ if (!DeleteMessageWasShown)
{
- if (EnablePercents)
+ if (NeedPercents())
{
- m_PercentPrinter.ClosePrint();
+ _percent.ClearCurState();
}
- if (!StdOutMode && m_NeedNewLine)
+ DeleteMessageWasShown = true;
+ }
+ else
+ {
+ _percent.Files++;
+ }
+
+ if (NeedPercents())
+ {
+ // if (!FullLog)
{
- m_PercentPrinter.PrintNewLine();
- m_NeedNewLine = false;
+ _percent.Command = "Removing";
+ _percent.FileName = fs2us(path);
}
- m_NeedBeClosed = false;
+ _percent.Print();
}
+
+ return S_OK;
+}
+
+
+HRESULT CUpdateCallbackConsole::FinishDeletingAfterArchiving()
+{
+ ClosePercents2();
+ if (_so && DeleteMessageWasShown)
+ *_so << endl;
return S_OK;
}
-HRESULT CUpdateCallbackConsole::SetNumFiles(UInt64 /* numFiles */)
+HRESULT CUpdateCallbackConsole::CheckBreak()
+{
+ return CheckBreak2();
+}
+
+/*
+HRESULT CUpdateCallbackConsole::Finalize()
+{
+ // MT_LOCK
+ return S_OK;
+}
+*/
+
+HRESULT CUpdateCallbackConsole::SetNumItems(UInt64 numItems)
{
+ if (_so)
+ {
+ ClosePercents_for_so();
+ AString s;
+ PrintPropPair(s, "Items to compress", numItems);
+ *_so << s << endl << endl;
+ }
return S_OK;
}
HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size)
{
MT_LOCK
- if (EnablePercents)
- m_PercentPrinter.SetTotal(size);
+ if (NeedPercents())
+ {
+ _percent.Total = size;
+ _percent.Print();
+ }
return S_OK;
}
HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue)
{
MT_LOCK
- if (completeValue != NULL)
+ if (completeValue)
{
- if (EnablePercents)
+ if (NeedPercents())
{
- m_PercentPrinter.SetRatio(*completeValue);
- m_PercentPrinter.PrintRatio();
- m_NeedBeClosed = true;
+ _percent.Completed = *completeValue;
+ _percent.Print();
}
}
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- return S_OK;
+ return CheckBreak2();
}
HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 * /* outSize */)
{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- return S_OK;
+ return CheckBreak2();
}
-HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti)
+HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *command, bool showInLog)
{
MT_LOCK
+
+ bool show2 = (showInLog && _so);
+
+ if (show2)
+ {
+ ClosePercents_for_so();
+
+ _tempA = command;
+ if (name)
+ _tempA.Add_Space();
+ *_so << _tempA;
+
+ _tempU.Empty();
+ if (name)
+ _tempU = name;
+ _so->PrintUString(_tempU, _tempA);
+ *_so << endl;
+ if (NeedFlush)
+ _so->Flush();
+ }
+
+ if (NeedPercents())
+ {
+ if (PercentsNameLevel >= 1)
+ {
+ _percent.FileName.Empty();
+ _percent.Command.Empty();
+ if (PercentsNameLevel > 1 || !show2)
+ {
+ _percent.Command = command;
+ if (name)
+ _percent.FileName = name;
+ }
+ }
+ _percent.Print();
+ }
+
+ return CheckBreak2();
+}
+
+HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool /* isDir */, bool isAnti, UInt32 mode)
+{
if (StdOutMode)
return S_OK;
- if(isAnti)
- m_PercentPrinter.PrintString("Anti item ");
- else
- m_PercentPrinter.PrintString("Compressing ");
- if (name[0] == 0)
+
+ if (!name || name[0] == 0)
name = kEmptyFileAlias;
- m_PercentPrinter.PrintString(name);
- if (EnablePercents)
- m_PercentPrinter.RePrintRatio();
- return S_OK;
+
+ unsigned requiredLevel = 1;
+
+ const char *s;
+ if (mode == NUpdateNotifyOp::kAdd ||
+ mode == NUpdateNotifyOp::kUpdate)
+ {
+ if (isAnti)
+ s = "Anti";
+ else if (mode == NUpdateNotifyOp::kAdd)
+ s = "+";
+ else
+ s = "U";
+ }
+ else
+ {
+ requiredLevel = 3;
+ if (mode == NUpdateNotifyOp::kAnalyze)
+ s = "A";
+ else
+ s = "Reading";
+ }
+
+ return PrintProgress(name, s, LogLevel >= requiredLevel);
+}
+
+HRESULT CUpdateCallbackConsole::OpenFileError(const FString &path, DWORD systemError)
+{
+ return OpenFileError_Base(path, systemError);
+}
+
+HRESULT CUpdateCallbackConsole::ReadingFileError(const FString &path, DWORD systemError)
+{
+ return ReadingFileError_Base(path, systemError);
}
-HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError)
+HRESULT CUpdateCallbackConsole::SetOperationResult(Int32)
{
MT_LOCK
- FailedCodes.Add(systemError);
- FailedFiles.Add(name);
- // if (systemError == ERROR_SHARING_VIOLATION)
+ _percent.Files++;
+ return S_OK;
+}
+
+void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest);
+
+HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name)
+{
+ // if (StdOutMode) return S_OK;
+
+ if (opRes != NArchive::NExtract::NOperationResult::kOK)
{
- m_PercentPrinter.ClosePrint();
- m_PercentPrinter.PrintNewLine();
- m_PercentPrinter.PrintString("WARNING: ");
- m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
- return S_FALSE;
+ ClosePercents2();
+
+ if (_se)
+ {
+ if (_so)
+ _so->Flush();
+
+ AString s;
+ SetExtractErrorMessage(opRes, isEncrypted, s);
+ *_se << s << " : " << endl << name << endl << endl;
+ _se->Flush();
+ }
+ return S_OK;
+ }
+ return S_OK;
+}
+
+
+HRESULT CUpdateCallbackConsole::ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool /* isDir */)
+{
+ // if (StdOutMode) return S_OK;
+
+ char temp[16];
+ const char *s;
+
+ unsigned requiredLevel = 1;
+
+ switch (op)
+ {
+ case NUpdateNotifyOp::kAdd: s = "+"; break;
+ case NUpdateNotifyOp::kUpdate: s = "U"; break;
+ case NUpdateNotifyOp::kAnalyze: s = "A"; requiredLevel = 3; break;
+ case NUpdateNotifyOp::kReplicate: s = "="; requiredLevel = 3; break;
+ case NUpdateNotifyOp::kRepack: s = "R"; requiredLevel = 2; break;
+ case NUpdateNotifyOp::kSkip: s = "."; requiredLevel = 2; break;
+ case NUpdateNotifyOp::kDelete: s = "D"; requiredLevel = 3; break;
+ case NUpdateNotifyOp::kHeader: s = "Header creation"; requiredLevel = 100; break;
+ default:
+ {
+ temp[0] = 'o';
+ temp[1] = 'p';
+ ConvertUInt64ToString(op, temp + 2);
+ s = temp;
+ }
}
- // return systemError;
+
+ return PrintProgress(name, s, LogLevel >= requiredLevel);
}
-HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 )
+/*
+HRESULT CUpdateCallbackConsole::SetPassword(const UString &
+ #ifndef _NO_CRYPTO
+ password
+ #endif
+ )
{
- m_NeedBeClosed = true;
- m_NeedNewLine = true;
+ #ifndef _NO_CRYPTO
+ PasswordIsDefined = true;
+ Password = password;
+ #endif
return S_OK;
}
+*/
HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
{
+ COM_TRY_BEGIN
+
*password = NULL;
#ifdef _NO_CRYPTO
@@ -209,7 +622,7 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined,
{
if (AskPassword)
{
- Password = GetPassword(OutStream);
+ Password = GetPassword(_so);
PasswordIsDefined = true;
}
}
@@ -217,10 +630,14 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined,
return StringToBstr(Password, password);
#endif
+
+ COM_TRY_END
}
HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password)
{
+ COM_TRY_BEGIN
+
*password = NULL;
#ifdef _NO_CRYPTO
@@ -232,30 +649,26 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password)
if (!PasswordIsDefined)
{
{
- Password = GetPassword(OutStream);
+ Password = GetPassword(_so);
PasswordIsDefined = true;
}
}
return StringToBstr(Password, password);
#endif
+ COM_TRY_END
}
-/*
-HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name)
+HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool /* isDir */)
{
- // MT_LOCK
if (StdOutMode)
return S_OK;
- RINOK(Finilize());
- m_PercentPrinter.PrintString("Deleting ");
- if (name[0] == 0)
- name = kEmptyFileAlias;
- m_PercentPrinter.PrintString(name);
- if (EnablePercents)
- m_PercentPrinter.RePrintRatio();
- m_NeedBeClosed = true;
- m_NeedNewLine = true;
+
+ if (LogLevel > 7)
+ {
+ if (!name || name[0] == 0)
+ name = kEmptyFileAlias;
+ return PrintProgress(name, "D", true);
+ }
return S_OK;
}
-*/
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h b/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h
index 5ffe3eb7ae4..ba8614ebaa3 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h
@@ -3,60 +3,122 @@
#ifndef __UPDATE_CALLBACK_CONSOLE_H
#define __UPDATE_CALLBACK_CONSOLE_H
-#include "Common/StdOutStream.h"
+#include "../../../Common/StdOutStream.h"
#include "../Common/Update.h"
#include "PercentPrinter.h"
-class CUpdateCallbackConsole: public IUpdateCallbackUI2
+struct CErrorPathCodes
{
- CPercentPrinter m_PercentPrinter;
- bool m_NeedBeClosed;
- bool m_NeedNewLine;
+ FStringVector Paths;
+ CRecordVector<DWORD> Codes;
- bool m_WarningsMode;
+ void AddError(const FString &path, DWORD systemError)
+ {
+ Paths.Add(path);
+ Codes.Add(systemError);
+ }
+ void Clear()
+ {
+ Paths.Clear();
+ Codes.Clear();
+ }
+};
+
+class CCallbackConsoleBase
+{
+protected:
+ CPercentPrinter _percent;
+
+ CStdOutStream *_so;
+ CStdOutStream *_se;
+
+ void CommonError(const FString &path, DWORD systemError, bool isWarning);
+
+ HRESULT ScanError_Base(const FString &path, DWORD systemError);
+ HRESULT OpenFileError_Base(const FString &name, DWORD systemError);
+ HRESULT ReadingFileError_Base(const FString &name, DWORD systemError);
- CStdOutStream *OutStream;
public:
- bool EnablePercents;
+ bool NeedPercents() const { return _percent._so != NULL; };
+
bool StdOutMode;
+ bool NeedFlush;
+ unsigned PercentsNameLevel;
+ unsigned LogLevel;
+
+ AString _tempA;
+ UString _tempU;
+
+ CCallbackConsoleBase():
+ StdOutMode(false),
+ NeedFlush(false),
+ PercentsNameLevel(1),
+ LogLevel(0)
+ {}
+
+ void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
+
+ void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
+ {
+ FailedFiles.Clear();
+
+ _so = outStream;
+ _se = errorStream;
+ _percent._so = percentStream;
+ }
+
+ void ClosePercents2()
+ {
+ if (NeedPercents())
+ _percent.ClosePrint(true);
+ }
+
+ void ClosePercents_for_so()
+ {
+ if (NeedPercents() && _so == _percent._so)
+ _percent.ClosePrint(false);
+ }
+
+
+ CErrorPathCodes FailedFiles;
+ CErrorPathCodes ScanErrors;
+
+ HRESULT PrintProgress(const wchar_t *name, const char *command, bool showInLog);
+
+};
+
+class CUpdateCallbackConsole: public IUpdateCallbackUI2, public CCallbackConsoleBase
+{
+ // void PrintPropPair(const char *name, const wchar_t *val);
+
+public:
#ifndef _NO_CRYPTO
bool PasswordIsDefined;
UString Password;
bool AskPassword;
#endif
- CUpdateCallbackConsole():
- m_PercentPrinter(1 << 16),
+ bool DeleteMessageWasShown;
+
+ CUpdateCallbackConsole()
+ : DeleteMessageWasShown(false)
#ifndef _NO_CRYPTO
- PasswordIsDefined(false),
- AskPassword(false),
+ , PasswordIsDefined(false)
+ , AskPassword(false)
#endif
- StdOutMode(false),
- EnablePercents(true),
- m_WarningsMode(false)
{}
- ~CUpdateCallbackConsole() { Finilize(); }
+ /*
void Init(CStdOutStream *outStream)
{
- m_NeedBeClosed = false;
- m_NeedNewLine = false;
- FailedFiles.Clear();
- FailedCodes.Clear();
- OutStream = outStream;
- m_PercentPrinter.OutStream = outStream;
+ CCallbackConsoleBase::Init(outStream);
}
-
+ */
+ // ~CUpdateCallbackConsole() { if (NeedPercents()) _percent.ClosePrint(); }
INTERFACE_IUpdateCallbackUI2(;)
-
- UStringVector FailedFiles;
- CRecordVector<HRESULT> FailedCodes;
-
- UStringVector CantFindFiles;
- CRecordVector<HRESULT> CantFindCodes;
};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp
index 754680090bc..c7f830ff999 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp
@@ -2,19 +2,19 @@
#include "StdAfx.h"
-#include "Common/StdInStream.h"
-#include "Common/StringConvert.h"
+#include "../../../Common/StdInStream.h"
+#include "../../../Common/StringConvert.h"
#include "UserInputUtils.h"
-static const char kYes = 'Y';
-static const char kNo = 'N';
-static const char kYesAll = 'A';
-static const char kNoAll = 'S';
-static const char kAutoRenameAll = 'U';
-static const char kQuit = 'Q';
+static const char kYes = 'y';
+static const char kNo = 'n';
+static const char kYesAll = 'a';
+static const char kNoAll = 's';
+static const char kAutoRenameAll = 'u';
+static const char kQuit = 'q';
-static const char *kFirstQuestionMessage = "?\n";
+static const char *kFirstQuestionMessage = "? ";
static const char *kHelpQuestionMessage =
"(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? ";
@@ -22,33 +22,26 @@ static const char *kHelpQuestionMessage =
NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
{
- (*outStream) << kFirstQuestionMessage;
+ if (outStream)
+ *outStream << kFirstQuestionMessage;
for (;;)
{
- (*outStream) << kHelpQuestionMessage;
- outStream->Flush();
+ if (outStream)
+ {
+ *outStream << kHelpQuestionMessage;
+ outStream->Flush();
+ }
AString scannedString = g_StdIn.ScanStringUntilNewLine();
scannedString.Trim();
if (!scannedString.IsEmpty())
- switch(
- ::MyCharUpper(
- #ifdef UNDER_CE
- (wchar_t)
- #endif
- scannedString[0]))
+ switch (::MyCharLower_Ascii(scannedString[0]))
{
- case kYes:
- return NUserAnswerMode::kYes;
- case kNo:
- return NUserAnswerMode::kNo;
- case kYesAll:
- return NUserAnswerMode::kYesAll;
- case kNoAll:
- return NUserAnswerMode::kNoAll;
- case kAutoRenameAll:
- return NUserAnswerMode::kAutoRenameAll;
- case kQuit:
- return NUserAnswerMode::kQuit;
+ case kYes: return NUserAnswerMode::kYes;
+ case kNo: return NUserAnswerMode::kNo;
+ case kYesAll: return NUserAnswerMode::kYesAll;
+ case kNoAll: return NUserAnswerMode::kNoAll;
+ case kAutoRenameAll: return NUserAnswerMode::kAutoRenameAll;
+ case kQuit: return NUserAnswerMode::kQuit;
}
}
}
@@ -61,14 +54,18 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
UString GetPassword(CStdOutStream *outStream)
{
- (*outStream) << "\nEnter password"
+ if (outStream)
+ {
+ *outStream << "\nEnter password"
#ifdef MY_DISABLE_ECHO
" (will not be echoed)"
#endif
":";
- outStream->Flush();
+ outStream->Flush();
+ }
#ifdef MY_DISABLE_ECHO
+
HANDLE console = GetStdHandle(STD_INPUT_HANDLE);
bool wasChanged = false;
DWORD mode = 0;
@@ -78,10 +75,16 @@ UString GetPassword(CStdOutStream *outStream)
UString res = g_StdIn.ScanUStringUntilNewLine();
if (wasChanged)
SetConsoleMode(console, mode);
- (*outStream) << "\n";
- outStream->Flush();
+ if (outStream)
+ {
+ *outStream << endl;
+ outStream->Flush();
+ }
return res;
+
#else
+
return g_StdIn.ScanUStringUntilNewLine();
+
#endif
}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h b/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h
index 8b5232b3fc2..16f045803e4 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h
@@ -1,9 +1,9 @@
// UserInputUtils.h
-#ifndef __USERINPUTUTILS_H
-#define __USERINPUTUTILS_H
+#ifndef __USER_INPUT_UTILS_H
+#define __USER_INPUT_UTILS_H
-#include "Common/StdOutStream.h"
+#include "../../../Common/StdOutStream.h"
namespace NUserAnswerMode {
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/makefile b/3rdparty/lzma/CPP/7zip/UI/Console/makefile
index f100f63589e..98ad91c2440 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Console/makefile
+++ b/3rdparty/lzma/CPP/7zip/UI/Console/makefile
@@ -1,25 +1,12 @@
PROG = 7z.exe
MY_CONSOLE = 1
-CFLAGS = $(CFLAGS) -I ../../../ \
+CFLAGS = $(CFLAGS) \
-DEXTERNAL_CODECS \
!IFNDEF UNDER_CE
CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE
!ENDIF
-
-CONSOLE_OBJS = \
- $O\ConsoleClose.obj \
- $O\ExtractCallbackConsole.obj \
- $O\List.obj \
- $O\BenchCon.obj \
- $O\Main.obj \
- $O\MainAr.obj \
- $O\OpenCallbackConsole.obj \
- $O\PercentPrinter.obj \
- $O\UpdateCallbackConsole.obj \
- $O\UserInputUtils.obj \
-
COMMON_OBJS = \
$O\CommandLineParser.obj \
$O\CRC.obj \
@@ -37,88 +24,46 @@ COMMON_OBJS = \
WIN_OBJS = \
$O\DLL.obj \
- $O\Error.obj \
+ $O\ErrorMsg.obj \
$O\FileDir.obj \
$O\FileFind.obj \
$O\FileIO.obj \
+ $O\FileLink.obj \
$O\FileName.obj \
+ $O\FileSystem.obj \
$O\MemoryLock.obj \
$O\PropVariant.obj \
- $O\PropVariantConversions.obj \
+ $O\PropVariantConv.obj \
$O\Registry.obj \
$O\System.obj \
- $O\Time.obj \
+ $O\TimeUtils.obj \
7ZIP_COMMON_OBJS = \
$O\CreateCoder.obj \
$O\FilePathAutoRename.obj \
$O\FileStreams.obj \
$O\FilterCoder.obj \
+ $O\LimitedStreams.obj \
$O\MethodProps.obj \
$O\ProgressUtils.obj \
+ $O\PropId.obj \
+ $O\StreamObjects.obj \
$O\StreamUtils.obj \
-
-UI_COMMON_OBJS = \
- $O\ArchiveCommandLine.obj \
- $O\ArchiveExtractCallback.obj \
- $O\ArchiveOpenCallback.obj \
- $O\DefaultName.obj \
- $O\EnumDirItems.obj \
- $O\Extract.obj \
- $O\ExtractingFilePath.obj \
- $O\Bench.obj \
- $O\LoadCodecs.obj \
- $O\OpenArchive.obj \
- $O\PropIDUtils.obj \
- $O\SetProperties.obj \
- $O\SortUtils.obj \
- $O\TempFiles.obj \
- $O\Update.obj \
- $O\UpdateAction.obj \
- $O\UpdateCallback.obj \
- $O\UpdatePair.obj \
- $O\UpdateProduce.obj \
+ $O\UniqBlocks.obj \
AR_COMMON_OBJS = \
$O\OutStreamWithCRC.obj \
+COMPRESS_OBJS = \
+ $O\CopyCoder.obj \
+
C_OBJS = \
$O\Alloc.obj \
$O\CpuArch.obj \
+ $O\Sort.obj \
$O\Threads.obj \
!include "../../Crc.mak"
+!include "Console.mak"
-OBJS = \
- $O\StdAfx.obj \
- $(CONSOLE_OBJS) \
- $(COMMON_OBJS) \
- $(WIN_OBJS) \
- $(7ZIP_COMMON_OBJS) \
- $(UI_COMMON_OBJS) \
- $(AR_COMMON_OBJS) \
- $O\CopyCoder.obj \
- $(C_OBJS) \
- $(ASM_OBJS) \
- $O\resource.res
-
-!include "../../../Build.mak"
-
-$(CONSOLE_OBJS): $(*B).cpp
- $(COMPL)
-$(COMMON_OBJS): ../../../Common/$(*B).cpp
- $(COMPL)
-$(WIN_OBJS): ../../../Windows/$(*B).cpp
- $(COMPL)
-$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
- $(COMPL)
-$(UI_COMMON_OBJS): ../Common/$(*B).cpp
- $(COMPL)
-$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
- $(COMPL)
-$O\CopyCoder.obj: ../../Compress/$(*B).cpp
- $(COMPL)
-$(C_OBJS): ../../../../C/$(*B).c
- $(COMPL_O2)
-
-!include "../../Asm.mak"
+!include "../../7zip.mak"
diff --git a/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.cpp b/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.cpp
new file mode 100644
index 00000000000..70c2a4608d3
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.cpp
@@ -0,0 +1,37 @@
+// MyMessages.cpp
+
+#include "StdAfx.h"
+
+#include "MyMessages.h"
+
+#include "../../../Windows/ErrorMsg.h"
+#include "../../../Windows/ResourceString.h"
+
+#include "../FileManager/LangUtils.h"
+
+using namespace NWindows;
+
+void ShowErrorMessage(HWND window, LPCWSTR message)
+{
+ ::MessageBoxW(window, message, L"7-Zip", MB_OK | MB_ICONSTOP);
+}
+
+void ShowErrorMessageHwndRes(HWND window, UINT resID)
+{
+ ShowErrorMessage(window, LangString(resID));
+}
+
+void ShowErrorMessageRes(UINT resID)
+{
+ ShowErrorMessageHwndRes(0, resID);
+}
+
+void ShowErrorMessageDWORD(HWND window, DWORD errorCode)
+{
+ ShowErrorMessage(window, NError::MyFormatMessage(errorCode));
+}
+
+void ShowLastErrorMessage(HWND window)
+{
+ ShowErrorMessageDWORD(window, ::GetLastError());
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.h b/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.h
new file mode 100644
index 00000000000..d5822f45f1c
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.h
@@ -0,0 +1,16 @@
+// MyMessages.h
+
+#ifndef __MY_MESSAGES_H
+#define __MY_MESSAGES_H
+
+#include "../../../Common/MyString.h"
+
+void ShowErrorMessage(HWND window, LPCWSTR message);
+inline void ShowErrorMessage(LPCWSTR message) { ShowErrorMessage(0, message); }
+
+void ShowErrorMessageHwndRes(HWND window, UInt32 langID);
+void ShowErrorMessageRes(UInt32 langID);
+
+void ShowLastErrorMessage(HWND window = 0);
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.cpp
new file mode 100644
index 00000000000..066ac219190
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.cpp
@@ -0,0 +1,1024 @@
+// BrowseDialog.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/MyWindows.h"
+
+#include <commctrl.h>
+
+#ifndef UNDER_CE
+#include "../../../Windows/CommonDialog.h"
+#include "../../../Windows/Shell.h"
+#endif
+
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/FileFind.h"
+
+#ifdef UNDER_CE
+#include <commdlg.h>
+#endif
+
+#include "BrowseDialog.h"
+
+#define USE_MY_BROWSE_DIALOG
+
+#ifdef USE_MY_BROWSE_DIALOG
+
+#include "../../../Common/Defs.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/PropVariantConv.h"
+
+#include "../../../Windows/Control/ComboBox.h"
+#include "../../../Windows/Control/Dialog.h"
+#include "../../../Windows/Control/Edit.h"
+#include "../../../Windows/Control/ListView.h"
+
+#include "BrowseDialogRes.h"
+#include "PropertyNameRes.h"
+#include "SysIconUtils.h"
+
+#ifndef _SFX
+#include "RegistryUtils.h"
+#endif
+
+#endif
+
+#include "ComboDialog.h"
+#include "LangUtils.h"
+
+#include "resource.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+using namespace NFind;
+
+#ifdef USE_MY_BROWSE_DIALOG
+
+extern bool g_LVN_ITEMACTIVATE_Support;
+
+static const int kParentIndex = -1;
+static const UINT k_Message_RefreshPathEdit = WM_APP + 1;
+
+static HRESULT GetNormalizedError()
+{
+ DWORD errorCode = GetLastError();
+ return errorCode == 0 ? E_FAIL : errorCode;
+}
+
+extern UString HResultToMessage(HRESULT errorCode);
+
+static void MessageBox_Error_Global(HWND wnd, const wchar_t *message)
+{
+ ::MessageBoxW(wnd, message, L"7-Zip", MB_ICONERROR);
+}
+
+static void MessageBox_HResError(HWND wnd, HRESULT errorCode, const wchar_t *name)
+{
+ UString s = HResultToMessage(errorCode);
+ if (name)
+ {
+ s.Add_LF();
+ s += name;
+ }
+ MessageBox_Error_Global(wnd, s);
+}
+
+class CBrowseDialog: public NControl::CModalDialog
+{
+ NControl::CListView _list;
+ NControl::CEdit _pathEdit;
+ NControl::CComboBox _filterCombo;
+
+ CObjectVector<CFileInfo> _files;
+
+ CExtToIconMap _extToIconMap;
+ int _sortIndex;
+ bool _ascending;
+ bool _showDots;
+ UString _topDirPrefix; // we don't open parent of that folder
+ UString DirPrefix;
+
+ virtual bool OnInit();
+ virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
+ virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+ virtual bool OnNotify(UINT controlID, LPNMHDR header);
+ virtual bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo);
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnOK();
+
+ void Post_RefreshPathEdit() { PostMsg(k_Message_RefreshPathEdit); }
+
+ bool GetParentPath(const UString &path, UString &parentPrefix, UString &name);
+ // Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter
+ HRESULT Reload(const UString &pathPrefix, const UString &selectedName);
+ HRESULT Reload();
+
+ void OpenParentFolder();
+ void SetPathEditText();
+ void OnCreateDir();
+ void OnItemEnter();
+ void FinishOnOK();
+
+ int GetRealItemIndex(int indexInListView) const
+ {
+ LPARAM param;
+ if (!_list.GetItemParam(indexInListView, param))
+ return (int)-1;
+ return (int)param;
+ }
+
+public:
+ bool FolderMode;
+ UString Title;
+ UString FilePath; // input/ result path
+ bool ShowAllFiles;
+ UStringVector Filters;
+ UString FilterDescription;
+
+ CBrowseDialog(): FolderMode(false), _showDots(false), ShowAllFiles(true) {}
+ void SetFilter(const UString &s);
+ INT_PTR Create(HWND parent = 0) { return CModalDialog::Create(IDD_BROWSE, parent); }
+ int CompareItems(LPARAM lParam1, LPARAM lParam2);
+};
+
+void CBrowseDialog::SetFilter(const UString &s)
+{
+ Filters.Clear();
+ UString mask;
+ unsigned i;
+ for (i = 0; i < s.Len(); i++)
+ {
+ wchar_t c = s[i];
+ if (c == ';')
+ {
+ if (!mask.IsEmpty())
+ Filters.Add(mask);
+ mask.Empty();
+ }
+ else
+ mask += c;
+ }
+ if (!mask.IsEmpty())
+ Filters.Add(mask);
+ ShowAllFiles = Filters.IsEmpty();
+ for (i = 0; i < Filters.Size(); i++)
+ {
+ const UString &f = Filters[i];
+ if (f == L"*.*" || f == L"*")
+ {
+ ShowAllFiles = true;
+ break;
+ }
+ }
+}
+
+bool CBrowseDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetDlgItems(*this, NULL, 0);
+ #endif
+ if (!Title.IsEmpty())
+ SetText(Title);
+ _list.Attach(GetItem(IDL_BROWSE));
+ _filterCombo.Attach(GetItem(IDC_BROWSE_FILTER));
+ _pathEdit.Attach(GetItem(IDE_BROWSE_PATH));
+
+ if (FolderMode)
+ HideItem(IDC_BROWSE_FILTER);
+ else
+ EnableItem(IDC_BROWSE_FILTER, false);
+
+ #ifndef UNDER_CE
+ _list.SetUnicodeFormat();
+ #endif
+
+ #ifndef _SFX
+ CFmSettings st;
+ st.Load();
+ if (st.SingleClick)
+ _list.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT);
+ _showDots = st.ShowDots;
+ #endif
+
+ {
+ UString s;
+ if (!FilterDescription.IsEmpty())
+ s = FilterDescription;
+ else if (ShowAllFiles)
+ s = L"*.*";
+ else
+ {
+ FOR_VECTOR (i, Filters)
+ {
+ if (i != 0)
+ s.Add_Space();
+ s += Filters[i];
+ }
+ }
+ _filterCombo.AddString(s);
+ _filterCombo.SetCurSel(0);
+ }
+
+ _list.SetImageList(GetSysImageList(true), LVSIL_SMALL);
+ _list.SetImageList(GetSysImageList(false), LVSIL_NORMAL);
+
+ _list.InsertColumn(0, LangString(IDS_PROP_NAME), 100);
+ _list.InsertColumn(1, LangString(IDS_PROP_MTIME), 100);
+ {
+ LV_COLUMNW column;
+ column.iSubItem = 2;
+ column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
+ column.fmt = LVCFMT_RIGHT;
+ column.cx = 100;
+ const UString s = LangString(IDS_PROP_SIZE);
+ column.pszText = (wchar_t *)(const wchar_t *)s;
+ _list.InsertColumn(2, &column);
+ }
+
+ _list.InsertItem(0, L"12345678901234567"
+ #ifndef UNDER_CE
+ L"1234567890"
+ #endif
+ );
+ _list.SetSubItem(0, 1, L"2009-09-09"
+ #ifndef UNDER_CE
+ L" 09:09"
+ #endif
+ );
+ _list.SetSubItem(0, 2, L"9999 MB");
+ for (int i = 0; i < 3; i++)
+ _list.SetColumnWidthAuto(i);
+ _list.DeleteAllItems();
+
+ _ascending = true;
+ _sortIndex = 0;
+
+ NormalizeSize();
+
+ _topDirPrefix.Empty();
+ {
+ int rootSize = GetRootPrefixSize(FilePath);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // We can go up from root folder to drives list
+ if (IsDrivePath(FilePath))
+ rootSize = 0;
+ else if (IsSuperPath(FilePath))
+ {
+ if (IsDrivePath(FilePath.Ptr(kSuperPathPrefixSize)))
+ rootSize = kSuperPathPrefixSize;
+ }
+ #endif
+ _topDirPrefix.SetFrom(FilePath, rootSize);
+ }
+
+ UString name;
+ if (!GetParentPath(FilePath, DirPrefix, name))
+ DirPrefix = _topDirPrefix;
+
+ for (;;)
+ {
+ UString baseFolder = DirPrefix;
+ if (Reload(baseFolder, name) == S_OK)
+ break;
+ name.Empty();
+ if (DirPrefix.IsEmpty())
+ break;
+ UString parent, name2;
+ GetParentPath(DirPrefix, parent, name2);
+ DirPrefix = parent;
+ }
+
+ if (name.IsEmpty())
+ name = FilePath;
+ if (FolderMode)
+ NormalizeDirPathPrefix(name);
+ _pathEdit.SetText(name);
+
+ #ifndef UNDER_CE
+ /* If we clear UISF_HIDEFOCUS, the focus rectangle in ListView will be visible,
+ even if we use mouse for pressing the button to open this dialog. */
+ PostMsg(MY__WM_UPDATEUISTATE, MAKEWPARAM(MY__UIS_CLEAR, MY__UISF_HIDEFOCUS));
+ #endif
+
+ return CModalDialog::OnInit();
+}
+
+bool CBrowseDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
+{
+ int mx, my;
+ {
+ RECT r;
+ GetClientRectOfItem(IDB_BROWSE_PARENT, r);
+ mx = r.left;
+ my = r.top;
+ }
+ InvalidateRect(NULL);
+
+ int xLim = xSize - mx;
+ {
+ RECT r;
+ GetClientRectOfItem(IDT_BROWSE_FOLDER, r);
+ MoveItem(IDT_BROWSE_FOLDER, r.left, r.top, xLim - r.left, RECT_SIZE_Y(r));
+ }
+
+ int bx1, bx2, by;
+ GetItemSizes(IDCANCEL, bx1, by);
+ GetItemSizes(IDOK, bx2, by);
+ int y = ySize - my - by;
+ int x = xLim - bx1;
+ MoveItem(IDCANCEL, x, y, bx1, by);
+ MoveItem(IDOK, x - mx - bx2, y, bx2, by);
+
+ // Y_Size of ComboBox is tricky. So we use Y_Size of _pathEdit instead
+
+ int yPathSize;
+ {
+ RECT r;
+ GetClientRectOfItem(IDE_BROWSE_PATH, r);
+ yPathSize = RECT_SIZE_Y(r);
+ _pathEdit.Move(r.left, y - my - yPathSize - my - yPathSize, xLim - r.left, yPathSize);
+ }
+
+ {
+ RECT r;
+ GetClientRectOfItem(IDC_BROWSE_FILTER, r);
+ _filterCombo.Move(r.left, y - my - yPathSize, xLim - r.left, RECT_SIZE_Y(r));
+ }
+
+ {
+ RECT r;
+ GetClientRectOfItem(IDL_BROWSE, r);
+ _list.Move(r.left, r.top, xLim - r.left, y - my - yPathSize - my - yPathSize - my - r.top);
+ }
+
+ return false;
+}
+
+bool CBrowseDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if (message == k_Message_RefreshPathEdit)
+ {
+ SetPathEditText();
+ return true;
+ }
+ return CModalDialog::OnMessage(message, wParam, lParam);
+}
+
+bool CBrowseDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
+{
+ if (header->hwndFrom != _list)
+ return false;
+ switch (header->code)
+ {
+ case LVN_ITEMACTIVATE:
+ if (g_LVN_ITEMACTIVATE_Support)
+ OnItemEnter();
+ break;
+ case NM_DBLCLK:
+ case NM_RETURN: // probabably it's unused
+ if (!g_LVN_ITEMACTIVATE_Support)
+ OnItemEnter();
+ break;
+ case LVN_COLUMNCLICK:
+ {
+ int index = LPNMLISTVIEW(header)->iSubItem;
+ if (index == _sortIndex)
+ _ascending = !_ascending;
+ else
+ {
+ _ascending = (index == 0);
+ _sortIndex = index;
+ }
+ Reload();
+ return false;
+ }
+ case LVN_KEYDOWN:
+ {
+ bool boolResult = OnKeyDown(LPNMLVKEYDOWN(header));
+ Post_RefreshPathEdit();
+ return boolResult;
+ }
+ case NM_RCLICK:
+ case NM_CLICK:
+ case LVN_BEGINDRAG:
+ Post_RefreshPathEdit();
+ break;
+ }
+ return false;
+}
+
+bool CBrowseDialog::OnKeyDown(LPNMLVKEYDOWN keyDownInfo)
+{
+ bool ctrl = IsKeyDown(VK_CONTROL);
+
+ switch (keyDownInfo->wVKey)
+ {
+ case VK_BACK:
+ OpenParentFolder();
+ return true;
+ case 'R':
+ if (ctrl)
+ {
+ Reload();
+ return true;
+ }
+ return false;
+ case VK_F7:
+ OnCreateDir();
+ return true;
+ }
+ return false;
+}
+
+bool CBrowseDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch (buttonID)
+ {
+ case IDB_BROWSE_PARENT: OpenParentFolder(); break;
+ case IDB_BROWSE_CREATE_DIR: OnCreateDir(); break;
+ default: return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+ }
+ _list.SetFocus();
+ return true;
+}
+
+void CBrowseDialog::OnOK()
+{
+ /* When we press "Enter" in listview, Windows sends message to first Button.
+ We check that message was from ListView; */
+ if (GetFocus() == _list)
+ {
+ OnItemEnter();
+ return;
+ }
+ FinishOnOK();
+}
+
+
+bool CBrowseDialog::GetParentPath(const UString &path, UString &parentPrefix, UString &name)
+{
+ parentPrefix.Empty();
+ name.Empty();
+ if (path.IsEmpty())
+ return false;
+ if (_topDirPrefix == path)
+ return false;
+ UString s = path;
+ if (s.Back() == WCHAR_PATH_SEPARATOR)
+ s.DeleteBack();
+ if (s.IsEmpty())
+ return false;
+ if (s.Back() == WCHAR_PATH_SEPARATOR)
+ return false;
+ int pos = s.ReverseFind_PathSepar();
+ parentPrefix.SetFrom(s, pos + 1);
+ name = s.Ptr(pos + 1);
+ return true;
+}
+
+int CBrowseDialog::CompareItems(LPARAM lParam1, LPARAM lParam2)
+{
+ if (lParam1 == kParentIndex) return -1;
+ if (lParam2 == kParentIndex) return 1;
+ const CFileInfo &f1 = _files[(int)lParam1];
+ const CFileInfo &f2 = _files[(int)lParam2];
+
+ bool isDir1 = f1.IsDir();
+ bool isDir2 = f2.IsDir();
+ if (isDir1 && !isDir2) return -1;
+ if (isDir2 && !isDir1) return 1;
+
+ int res = 0;
+ switch (_sortIndex)
+ {
+ case 0: res = CompareFileNames(fs2us(f1.Name), fs2us(f2.Name)); break;
+ case 1: res = CompareFileTime(&f1.MTime, &f2.MTime); break;
+ case 2: res = MyCompare(f1.Size, f2.Size); break;
+ }
+ return _ascending ? res: -res;
+}
+
+static int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
+{
+ return ((CBrowseDialog *)lpData)->CompareItems(lParam1, lParam2);
+}
+
+static void ConvertSizeToString(UInt64 v, wchar_t *s)
+{
+ Byte c = 0;
+ if (v >= ((UInt64)10000 << 20)) { v >>= 30; c = 'G'; }
+ else if (v >= ((UInt64)10000 << 10)) { v >>= 20; c = 'M'; }
+ else if (v >= ((UInt64)10000 << 0)) { v >>= 10; c = 'K'; }
+ ConvertUInt64ToString(v, s);
+ if (c != 0)
+ {
+ s += MyStringLen(s);
+ *s++ = ' ';
+ *s++ = c;
+ *s++ = 0;
+ }
+}
+
+// Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter
+
+HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selectedName)
+{
+ CObjectVector<CFileInfo> files;
+
+ #ifndef UNDER_CE
+ bool isDrive = false;
+ if (pathPrefix.IsEmpty() || pathPrefix == kSuperPathPrefix)
+ {
+ isDrive = true;
+ FStringVector drives;
+ if (!MyGetLogicalDriveStrings(drives))
+ return GetNormalizedError();
+ FOR_VECTOR (i, drives)
+ {
+ FString d = drives[i];
+ if (d.Len() < 3 || d.Back() != '\\')
+ return E_FAIL;
+ d.DeleteBack();
+ CFileInfo &fi = files.AddNew();
+ fi.SetAsDir();
+ fi.Name = d;
+ }
+ }
+ else
+ #endif
+ {
+ CEnumerator enumerator(us2fs(pathPrefix + L'*'));
+ for (;;)
+ {
+ bool found;
+ CFileInfo fi;
+ if (!enumerator.Next(fi, found))
+ return GetNormalizedError();
+ if (!found)
+ break;
+ if (!fi.IsDir())
+ {
+ if (FolderMode)
+ continue;
+ if (!ShowAllFiles)
+ {
+ unsigned i;
+ for (i = 0; i < Filters.Size(); i++)
+ if (DoesWildcardMatchName(Filters[i], fs2us(fi.Name)))
+ break;
+ if (i == Filters.Size())
+ continue;
+ }
+ }
+ files.Add(fi);
+ }
+ }
+
+ DirPrefix = pathPrefix;
+
+ _files = files;
+
+ SetItemText(IDT_BROWSE_FOLDER, DirPrefix);
+
+ _list.SetRedraw(false);
+ _list.DeleteAllItems();
+
+ LVITEMW item;
+
+ int index = 0;
+ int cursorIndex = -1;
+
+ #ifndef _SFX
+ if (_showDots && _topDirPrefix != DirPrefix)
+ {
+ item.iItem = index;
+ const UString itemName = L"..";
+ if (selectedName.IsEmpty())
+ cursorIndex = index;
+ item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
+ int subItem = 0;
+ item.iSubItem = subItem++;
+ item.lParam = kParentIndex;
+ item.pszText = (wchar_t *)(const wchar_t *)itemName;
+ item.iImage = _extToIconMap.GetIconIndex(FILE_ATTRIBUTE_DIRECTORY, DirPrefix);
+ if (item.iImage < 0)
+ item.iImage = 0;
+ _list.InsertItem(&item);
+ _list.SetSubItem(index, subItem++, L"");
+ _list.SetSubItem(index, subItem++, L"");
+ index++;
+ }
+ #endif
+
+ for (unsigned i = 0; i < _files.Size(); i++, index++)
+ {
+ item.iItem = index;
+ const CFileInfo &fi = _files[i];
+ const UString name = fs2us(fi.Name);
+ if (!selectedName.IsEmpty() && CompareFileNames(name, selectedName) == 0)
+ cursorIndex = index;
+ item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
+ int subItem = 0;
+ item.iSubItem = subItem++;
+ item.lParam = i;
+ item.pszText = (wchar_t *)(const wchar_t *)name;
+
+ const UString fullPath = DirPrefix + name;
+ #ifndef UNDER_CE
+ if (isDrive)
+ {
+ if (GetRealIconIndex(fi.Name + FCHAR_PATH_SEPARATOR, FILE_ATTRIBUTE_DIRECTORY, item.iImage) == 0)
+ item.iImage = 0;
+ }
+ else
+ #endif
+ item.iImage = _extToIconMap.GetIconIndex(fi.Attrib, fullPath);
+ if (item.iImage < 0)
+ item.iImage = 0;
+ _list.InsertItem(&item);
+ wchar_t s[32];
+ {
+ FILETIME ft;
+ s[0] = 0;
+ if (FileTimeToLocalFileTime(&fi.MTime, &ft))
+ ConvertFileTimeToString(ft, s,
+ #ifndef UNDER_CE
+ true
+ #else
+ false
+ #endif
+ , false);
+ _list.SetSubItem(index, subItem++, s);
+ }
+ {
+ s[0] = 0;
+ if (!fi.IsDir())
+ ConvertSizeToString(fi.Size, s);
+ _list.SetSubItem(index, subItem++, s);
+ }
+ }
+
+ if (_list.GetItemCount() > 0 && cursorIndex >= 0)
+ _list.SetItemState_FocusedSelected(cursorIndex);
+ _list.SortItems(CompareItems2, (LPARAM)this);
+ if (_list.GetItemCount() > 0 && cursorIndex < 0)
+ _list.SetItemState(0, LVIS_FOCUSED, LVIS_FOCUSED);
+ _list.EnsureVisible(_list.GetFocusedItem(), false);
+ _list.SetRedraw(true);
+ _list.InvalidateRect(NULL, true);
+ return S_OK;
+}
+
+HRESULT CBrowseDialog::Reload()
+{
+ UString selected;
+ int index = _list.GetNextSelectedItem(-1);
+ if (index >= 0)
+ {
+ int fileIndex = GetRealItemIndex(index);
+ if (fileIndex != kParentIndex)
+ selected = fs2us(_files[fileIndex].Name);
+ }
+ UString dirPathTemp = DirPrefix;
+ return Reload(dirPathTemp, selected);
+}
+
+void CBrowseDialog::OpenParentFolder()
+{
+ UString parent, selected;
+ if (GetParentPath(DirPrefix, parent, selected))
+ {
+ Reload(parent, selected);
+ SetPathEditText();
+ }
+}
+
+void CBrowseDialog::SetPathEditText()
+{
+ int index = _list.GetNextSelectedItem(-1);
+ if (index < 0)
+ {
+ if (FolderMode)
+ _pathEdit.SetText(DirPrefix);
+ return;
+ }
+ int fileIndex = GetRealItemIndex(index);
+ if (fileIndex == kParentIndex)
+ {
+ if (FolderMode)
+ _pathEdit.SetText(L".." WSTRING_PATH_SEPARATOR);
+ return;
+ }
+ const CFileInfo &file = _files[fileIndex];
+ if (file.IsDir())
+ {
+ if (!FolderMode)
+ return;
+ _pathEdit.SetText(fs2us(file.Name) + WCHAR_PATH_SEPARATOR);
+ }
+ else
+ _pathEdit.SetText(fs2us(file.Name));
+}
+
+void CBrowseDialog::OnCreateDir()
+{
+ UString name;
+ {
+ UString enteredName;
+ Dlg_CreateFolder((HWND)*this, enteredName);
+ if (enteredName.IsEmpty())
+ return;
+ if (!CorrectFsPath(DirPrefix, enteredName, name))
+ {
+ MessageBox_HResError((HWND)*this, ERROR_INVALID_NAME, name);
+ return;
+ }
+ }
+ if (name.IsEmpty())
+ return;
+
+ FString destPath;
+ if (GetFullPath(us2fs(DirPrefix), us2fs(name), destPath))
+ {
+ if (!NDir::CreateComplexDir(destPath))
+ {
+ MessageBox_HResError((HWND)*this, GetNormalizedError(), fs2us(destPath));
+ }
+ else
+ {
+ UString tempPath = DirPrefix;
+ Reload(tempPath, name);
+ SetPathEditText();
+ }
+ _list.SetFocus();
+ }
+}
+
+void CBrowseDialog::OnItemEnter()
+{
+ int index = _list.GetNextSelectedItem(-1);
+ if (index < 0)
+ return;
+ int fileIndex = GetRealItemIndex(index);
+ if (fileIndex == kParentIndex)
+ OpenParentFolder();
+ else
+ {
+ const CFileInfo &file = _files[fileIndex];
+ if (!file.IsDir())
+ {
+ if (!FolderMode)
+ FinishOnOK();
+ /*
+ MessageBox_Error_Global(*this, FolderMode ?
+ L"You must select some folder":
+ L"You must select some file");
+ */
+ return;
+ }
+ UString s = DirPrefix + fs2us(file.Name) + WCHAR_PATH_SEPARATOR;
+ HRESULT res = Reload(s, L"");
+ if (res != S_OK)
+ MessageBox_HResError(*this, res, s);
+ SetPathEditText();
+ }
+}
+
+void CBrowseDialog::FinishOnOK()
+{
+ UString s;
+ _pathEdit.GetText(s);
+ FString destPath;
+ if (!GetFullPath(us2fs(DirPrefix), us2fs(s), destPath))
+ {
+ MessageBox_HResError((HWND)*this, ERROR_INVALID_NAME, s);
+ return;
+ }
+ FilePath = fs2us(destPath);
+ if (FolderMode)
+ NormalizeDirPathPrefix(FilePath);
+ End(IDOK);
+}
+
+#endif
+
+bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultPath)
+{
+ resultPath.Empty();
+
+ #ifndef UNDER_CE
+
+ #ifdef USE_MY_BROWSE_DIALOG
+ if (!IsSuperOrDevicePath(path))
+ #endif
+ return NShell::BrowseForFolder(owner, title, path, resultPath);
+
+ #endif
+
+ #ifdef USE_MY_BROWSE_DIALOG
+
+ CBrowseDialog dialog;
+ dialog.FolderMode = true;
+ if (title)
+ dialog.Title = title;
+ if (path)
+ dialog.FilePath = path;
+ if (dialog.Create(owner) != IDOK)
+ return false;
+ resultPath = dialog.FilePath;
+ #endif
+
+ return true;
+}
+
+bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path,
+ LPCWSTR filterDescription, LPCWSTR filter, UString &resultPath)
+{
+ resultPath.Empty();
+
+ #ifndef UNDER_CE
+
+ #ifdef USE_MY_BROWSE_DIALOG
+ if (!IsSuperOrDevicePath(path))
+ #endif
+ {
+ if (MyGetOpenFileName(owner, title, NULL, path, filterDescription, filter, resultPath))
+ return true;
+ #ifdef UNDER_CE
+ return false;
+ #else
+ // maybe we must use GetLastError in WinCE.
+ DWORD errorCode = CommDlgExtendedError();
+ const wchar_t *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";
+ }
+ if (!errorMessage)
+ return false;
+ {
+ UString s = errorMessage;
+ s.Add_LF();
+ s += path;
+ MessageBox_Error_Global(owner, s);
+ }
+ #endif
+ }
+
+ #endif
+
+ #ifdef USE_MY_BROWSE_DIALOG
+ CBrowseDialog dialog;
+ if (title)
+ dialog.Title = title;
+ if (path)
+ dialog.FilePath = path;
+ dialog.FolderMode = false;
+ if (filter)
+ dialog.SetFilter(filter);
+ if (filterDescription)
+ dialog.FilterDescription = filterDescription;
+ if (dialog.Create(owner) != IDOK)
+ return false;
+ resultPath = dialog.FilePath;
+ #endif
+
+ return true;
+}
+
+
+#ifdef _WIN32
+
+static void RemoveDotsAndSpaces(UString &path)
+{
+ while (!path.IsEmpty())
+ {
+ wchar_t c = path.Back();
+ if (c != ' ' && c != '.')
+ return;
+ path.DeleteBack();
+ }
+}
+
+
+bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result)
+{
+ result.Empty();
+
+ UString path = path2;
+ path.Replace(L'/', WCHAR_PATH_SEPARATOR);
+ unsigned start = 0;
+ UString base;
+
+ if (IsAbsolutePath(path))
+ {
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (IsSuperOrDevicePath(path))
+ {
+ result = path;
+ return true;
+ }
+ #endif
+ int pos = GetRootPrefixSize(path);
+ if (pos > 0)
+ start = pos;
+ }
+ else
+ {
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (IsSuperOrDevicePath(relBase))
+ {
+ result = path;
+ return true;
+ }
+ #endif
+ base = relBase;
+ }
+
+ /* We can't use backward, since we must change only disk paths */
+ /*
+ for (;;)
+ {
+ if (path.Len() <= start)
+ break;
+ if (DoesFileOrDirExist(us2fs(path)))
+ break;
+ if (path.Back() == WCHAR_PATH_SEPARATOR)
+ {
+ path.DeleteBack();
+ result.Insert(0, WCHAR_PATH_SEPARATOR);;
+ }
+ int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR) + 1;
+ UString cur = path.Ptr(pos);
+ RemoveDotsAndSpaces(cur);
+ result.Insert(0, cur);
+ path.DeleteFrom(pos);
+ }
+ result.Insert(0, path);
+ return true;
+ */
+
+ result += path.Left(start);
+ bool checkExist = true;
+ UString cur;
+
+ for (;;)
+ {
+ if (start == path.Len())
+ break;
+ int slashPos = path.Find(WCHAR_PATH_SEPARATOR, start);
+ cur.SetFrom(path.Ptr(start), (slashPos < 0 ? path.Len() : slashPos) - start);
+ if (checkExist)
+ {
+ CFileInfo fi;
+ if (fi.Find(us2fs(base + result + cur)))
+ {
+ if (!fi.IsDir())
+ {
+ result = path;
+ break;
+ }
+ }
+ else
+ checkExist = false;
+ }
+ if (!checkExist)
+ RemoveDotsAndSpaces(cur);
+ result += cur;
+ if (slashPos < 0)
+ break;
+ result.Add_PathSepar();
+ start = slashPos + 1;
+ }
+
+ return true;
+}
+
+#else
+
+bool CorrectFsPath(const UString & /* relBase */, const UString &path, UString &result)
+{
+ result = path;
+ return true;
+}
+
+#endif
+
+bool Dlg_CreateFolder(HWND wnd, UString &destName)
+{
+ destName.Empty();
+ CComboDialog dlg;
+ LangString(IDS_CREATE_FOLDER, dlg.Title);
+ LangString(IDS_CREATE_FOLDER_NAME, dlg.Static);
+ LangString(IDS_CREATE_FOLDER_DEFAULT_NAME, dlg.Value);
+ if (dlg.Create(wnd) != IDOK)
+ return false;
+ destName = dlg.Value;
+ return true;
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.h
new file mode 100644
index 00000000000..957af2e2577
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.h
@@ -0,0 +1,21 @@
+// BrowseDialog.h
+
+#ifndef __BROWSE_DIALOG_H
+#define __BROWSE_DIALOG_H
+
+#include "../../../Common/MyString.h"
+
+bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultPath);
+bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path, LPCWSTR filterDescription, LPCWSTR filter, UString &resultPath);
+
+/* CorrectFsPath removes undesirable characters in names (dots and spaces at the end of file)
+ But it doesn't change "bad" name in any of the following cases:
+ - path is Super Path (with \\?\ prefix)
+ - path is relative and relBase is Super Path
+ - there is file or dir in filesystem with specified "bad" name */
+
+bool CorrectFsPath(const UString &relBase, const UString &path, UString &result);
+
+bool Dlg_CreateFolder(HWND wnd, UString &destName);
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialogRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialogRes.h
new file mode 100644
index 00000000000..aff84ec9aa3
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialogRes.h
@@ -0,0 +1,9 @@
+#define IDD_BROWSE 95
+
+#define IDL_BROWSE 100
+#define IDT_BROWSE_FOLDER 101
+#define IDE_BROWSE_PATH 102
+#define IDC_BROWSE_FILTER 103
+
+#define IDB_BROWSE_PARENT 110
+#define IDB_BROWSE_CREATE_DIR 112
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.cpp
new file mode 100644
index 00000000000..729743e8795
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.cpp
@@ -0,0 +1,64 @@
+// ComboDialog.cpp
+
+#include "StdAfx.h"
+#include "ComboDialog.h"
+
+#include "../../../Windows/Control/Static.h"
+
+#ifdef LANG
+#include "LangUtils.h"
+#endif
+
+using namespace NWindows;
+
+bool CComboDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetDlgItems(*this, NULL, 0);
+ #endif
+ _comboBox.Attach(GetItem(IDC_COMBO));
+
+ /*
+ // why it doesn't work ?
+ DWORD style = _comboBox.GetStyle();
+ if (Sorted)
+ style |= CBS_SORT;
+ else
+ style &= ~CBS_SORT;
+ _comboBox.SetStyle(style);
+ */
+ SetText(Title);
+
+ NControl::CStatic staticContol;
+ staticContol.Attach(GetItem(IDT_COMBO));
+ staticContol.SetText(Static);
+ _comboBox.SetText(Value);
+ FOR_VECTOR (i, Strings)
+ _comboBox.AddString(Strings[i]);
+ NormalizeSize();
+ return CModalDialog::OnInit();
+}
+
+bool CComboDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
+{
+ int mx, my;
+ GetMargins(8, mx, my);
+ int bx1, bx2, by;
+ GetItemSizes(IDCANCEL, bx1, by);
+ GetItemSizes(IDOK, bx2, by);
+ int y = ySize - my - by;
+ int x = xSize - mx - bx1;
+
+ InvalidateRect(NULL);
+
+ MoveItem(IDCANCEL, x, y, bx1, by);
+ MoveItem(IDOK, x - mx - bx2, y, bx2, by);
+ ChangeSubWindowSizeX(_comboBox, xSize - mx * 2);
+ return false;
+}
+
+void CComboDialog::OnOK()
+{
+ _comboBox.GetText(Value);
+ CModalDialog::OnOK();
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.h
new file mode 100644
index 00000000000..29b28b5b49c
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.h
@@ -0,0 +1,28 @@
+// ComboDialog.h
+
+#ifndef __COMBO_DIALOG_H
+#define __COMBO_DIALOG_H
+
+#include "../../../Windows/Control/ComboBox.h"
+#include "../../../Windows/Control/Dialog.h"
+
+#include "ComboDialogRes.h"
+
+class CComboDialog: public NWindows::NControl::CModalDialog
+{
+ NWindows::NControl::CComboBox _comboBox;
+ virtual void OnOK();
+ virtual bool OnInit();
+ virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
+public:
+ // bool Sorted;
+ UString Title;
+ UString Static;
+ UString Value;
+ UStringVector Strings;
+
+ // CComboDialog(): Sorted(false) {};
+ INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_COMBO, parentWindow); }
+};
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialogRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialogRes.h
new file mode 100644
index 00000000000..a044797e456
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialogRes.h
@@ -0,0 +1,4 @@
+#define IDD_COMBO 98
+
+#define IDT_COMBO 100
+#define IDC_COMBO 101
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/DialogSize.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/DialogSize.h
new file mode 100644
index 00000000000..504541bdf3c
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/DialogSize.h
@@ -0,0 +1,16 @@
+// DialogSize.h
+
+#ifndef __DIALOG_SIZE_H
+#define __DIALOG_SIZE_H
+
+#include "../../../Windows/Control/Dialog.h"
+
+#ifdef UNDER_CE
+#define BIG_DIALOG_SIZE(x, y) bool isBig = NWindows::NControl::IsDialogSizeOK(x, y);
+#define SIZED_DIALOG(big) (isBig ? big : big ## _2)
+#else
+#define BIG_DIALOG_SIZE(x, y)
+#define SIZED_DIALOG(big) big
+#endif
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.cpp
new file mode 100644
index 00000000000..7d61d14d9d9
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.cpp
@@ -0,0 +1,1035 @@
+// ExtractCallback.cpp
+
+#include "StdAfx.h"
+
+
+#include "../../../Common/ComTry.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/Lang.h"
+#include "../../../Common/StringConvert.h"
+
+#include "../../../Windows/ErrorMsg.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/PropVariantConv.h"
+
+#include "../../Common/FilePathAutoRename.h"
+#include "../../Common/StreamUtils.h"
+#include "../Common/ExtractingFilePath.h"
+
+#ifndef _SFX
+#include "../Common/ZipRegistry.h"
+#endif
+
+#include "../GUI/ExtractRes.h"
+#include "resourceGui.h"
+
+#include "ExtractCallback.h"
+#include "FormatUtils.h"
+#include "LangUtils.h"
+#include "OverwriteDialog.h"
+#ifndef _NO_CRYPTO
+#include "PasswordDialog.h"
+#endif
+#include "PropertyName.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NFind;
+
+CExtractCallbackImp::~CExtractCallbackImp() {}
+
+void CExtractCallbackImp::Init()
+{
+ _lang_Extracting = LangString(IDS_PROGRESS_EXTRACTING);
+ _lang_Testing = LangString(IDS_PROGRESS_TESTING);
+ _lang_Skipping = LangString(IDS_PROGRESS_SKIPPING);
+
+ NumArchiveErrors = 0;
+ ThereAreMessageErrors = false;
+ #ifndef _SFX
+ NumFolders = NumFiles = 0;
+ NeedAddFile = false;
+ #endif
+}
+
+void CExtractCallbackImp::AddError_Message(LPCWSTR s)
+{
+ ThereAreMessageErrors = true;
+ ProgressDialog->Sync.AddError_Message(s);
+}
+
+#ifndef _SFX
+
+STDMETHODIMP CExtractCallbackImp::SetNumFiles(UInt64
+ #ifndef _SFX
+ numFiles
+ #endif
+ )
+{
+ #ifndef _SFX
+ ProgressDialog->Sync.Set_NumFilesTotal(numFiles);
+ #endif
+ return S_OK;
+}
+
+#endif
+
+STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 total)
+{
+ ProgressDialog->Sync.Set_NumBytesTotal(total);
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *value)
+{
+ return ProgressDialog->Sync.Set_NumBytesCur(value);
+}
+
+HRESULT CExtractCallbackImp::Open_CheckBreak()
+{
+ return ProgressDialog->Sync.CheckStop();
+}
+
+HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 *files, const UInt64 *bytes)
+{
+ HRESULT res = S_OK;
+ if (!MultiArcMode)
+ {
+ if (files)
+ {
+ _totalFilesDefined = true;
+ // res = ProgressDialog->Sync.Set_NumFilesTotal(*files);
+ }
+ else
+ _totalFilesDefined = false;
+
+ if (bytes)
+ {
+ _totalBytesDefined = true;
+ ProgressDialog->Sync.Set_NumBytesTotal(*bytes);
+ }
+ else
+ _totalBytesDefined = false;
+ }
+
+ return res;
+}
+
+HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 *files, const UInt64 *bytes)
+{
+ if (!MultiArcMode)
+ {
+ if (files)
+ {
+ ProgressDialog->Sync.Set_NumFilesCur(*files);
+ }
+
+ if (bytes)
+ {
+ }
+ }
+
+ return ProgressDialog->Sync.CheckStop();
+}
+
+HRESULT CExtractCallbackImp::Open_Finished()
+{
+ return ProgressDialog->Sync.CheckStop();
+}
+
+#ifndef _NO_CRYPTO
+
+HRESULT CExtractCallbackImp::Open_CryptoGetTextPassword(BSTR *password)
+{
+ return CryptoGetTextPassword(password);
+}
+
+/*
+HRESULT CExtractCallbackImp::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password)
+{
+ passwordIsDefined = PasswordIsDefined;
+ password = Password;
+ return S_OK;
+}
+
+bool CExtractCallbackImp::Open_WasPasswordAsked()
+{
+ return PasswordWasAsked;
+}
+
+void CExtractCallbackImp::Open_Clear_PasswordWasAsked_Flag()
+{
+ PasswordWasAsked = false;
+}
+*/
+
+#endif
+
+
+#ifndef _SFX
+STDMETHODIMP CExtractCallbackImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+ ProgressDialog->Sync.Set_Ratio(inSize, outSize);
+ return S_OK;
+}
+#endif
+
+/*
+STDMETHODIMP CExtractCallbackImp::SetTotalFiles(UInt64 total)
+{
+ ProgressDialog->Sync.SetNumFilesTotal(total);
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetCompletedFiles(const UInt64 *value)
+{
+ if (value != NULL)
+ ProgressDialog->Sync.SetNumFilesCur(*value);
+ return S_OK;
+}
+*/
+
+STDMETHODIMP CExtractCallbackImp::AskOverwrite(
+ const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
+ const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
+ Int32 *answer)
+{
+ COverwriteDialog dialog;
+
+ dialog.OldFileInfo.SetTime(existTime);
+ dialog.OldFileInfo.SetSize(existSize);
+ dialog.OldFileInfo.Name = existName;
+
+ dialog.NewFileInfo.SetTime(newTime);
+ dialog.NewFileInfo.SetSize(newSize);
+ dialog.NewFileInfo.Name = newName;
+
+ ProgressDialog->WaitCreating();
+ INT_PTR writeAnswer = dialog.Create(*ProgressDialog);
+
+ switch (writeAnswer)
+ {
+ case IDCANCEL: *answer = NOverwriteAnswer::kCancel; return E_ABORT;
+ case IDYES: *answer = NOverwriteAnswer::kYes; break;
+ case IDNO: *answer = NOverwriteAnswer::kNo; break;
+ case IDB_YES_TO_ALL: *answer = NOverwriteAnswer::kYesToAll; break;
+ case IDB_NO_TO_ALL: *answer = NOverwriteAnswer::kNoToAll; break;
+ case IDB_AUTO_RENAME: *answer = NOverwriteAnswer::kAutoRename; break;
+ default: return E_FAIL;
+ }
+ return S_OK;
+}
+
+
+STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 * /* position */)
+{
+ _isFolder = IntToBool(isFolder);
+ _currentFilePath = name;
+
+ const UString *msg = &_lang_Empty;
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract: msg = &_lang_Extracting; break;
+ case NArchive::NExtract::NAskMode::kTest: msg = &_lang_Testing; break;
+ case NArchive::NExtract::NAskMode::kSkip: msg = &_lang_Skipping; break;
+ // default: s = "Unknown operation";
+ }
+
+ return ProgressDialog->Sync.Set_Status2(*msg, name, IntToBool(isFolder));
+}
+
+STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *s)
+{
+ AddError_Message(s);
+ return S_OK;
+}
+
+HRESULT CExtractCallbackImp::MessageError(const char *message, const FString &path)
+{
+ ThereAreMessageErrors = true;
+ ProgressDialog->Sync.AddError_Message_Name(GetUnicodeString(message), fs2us(path));
+ return S_OK;
+}
+
+#ifndef _SFX
+
+STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *s)
+{
+ AddError_Message(s);
+ return S_OK;
+}
+
+#endif
+
+void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s)
+{
+ s.Empty();
+
+ if (opRes == NArchive::NExtract::NOperationResult::kOK)
+ return;
+
+ UINT messageID = 0;
+ UINT id = 0;
+
+ switch (opRes)
+ {
+ case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
+ messageID = IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD;
+ id = IDS_EXTRACT_MSG_UNSUPPORTED_METHOD;
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ messageID = encrypted ?
+ IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED:
+ IDS_EXTRACT_MESSAGE_DATA_ERROR;
+ id = IDS_EXTRACT_MSG_DATA_ERROR;
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ messageID = encrypted ?
+ IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED:
+ IDS_EXTRACT_MESSAGE_CRC_ERROR;
+ id = IDS_EXTRACT_MSG_CRC_ERROR;
+ break;
+ case NArchive::NExtract::NOperationResult::kUnavailable:
+ id = IDS_EXTRACT_MSG_UNAVAILABLE_DATA;
+ break;
+ case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
+ id = IDS_EXTRACT_MSG_UEXPECTED_END;
+ break;
+ case NArchive::NExtract::NOperationResult::kDataAfterEnd:
+ id = IDS_EXTRACT_MSG_DATA_AFTER_END;
+ break;
+ case NArchive::NExtract::NOperationResult::kIsNotArc:
+ id = IDS_EXTRACT_MSG_IS_NOT_ARC;
+ break;
+ case NArchive::NExtract::NOperationResult::kHeadersError:
+ id = IDS_EXTRACT_MSG_HEADERS_ERROR;
+ break;
+ case NArchive::NExtract::NOperationResult::kWrongPassword:
+ id = IDS_EXTRACT_MSG_WRONG_PSW_CLAIM;
+ break;
+ /*
+ default:
+ messageID = IDS_EXTRACT_MESSAGE_UNKNOWN_ERROR;
+ break;
+ */
+ }
+
+ UString msg;
+ UString msgOld;
+
+ #ifndef _SFX
+ if (id != 0)
+ LangString_OnlyFromLangFile(id, msg);
+ if (messageID != 0 && msg.IsEmpty())
+ LangString_OnlyFromLangFile(messageID, msgOld);
+ #endif
+
+ if (msg.IsEmpty() && !msgOld.IsEmpty())
+ s = MyFormatNew(msgOld, fileName);
+ else
+ {
+ if (msg.IsEmpty() && id != 0)
+ LangString(id, msg);
+ if (!msg.IsEmpty())
+ s += msg;
+ else
+ {
+ char temp[16];
+ ConvertUInt32ToString(opRes, temp);
+ s.AddAscii("Error #");
+ s.AddAscii(temp);
+ }
+
+ if (encrypted && opRes != NArchive::NExtract::NOperationResult::kWrongPassword)
+ {
+ // s.AddAscii(" : ");
+ // AddLangString(s, IDS_EXTRACT_MSG_ENCRYPTED);
+ s.AddAscii(" : ");
+ AddLangString(s, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
+ }
+ s.AddAscii(" : ");
+ s += fileName;
+ }
+}
+
+STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted)
+{
+ switch (opRes)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ break;
+ default:
+ {
+ UString s;
+ SetExtractErrorMessage(opRes, encrypted, _currentFilePath, s);
+ Add_ArchiveName_Error();
+ AddError_Message(s);
+ }
+ }
+
+ #ifndef _SFX
+ if (_isFolder)
+ NumFolders++;
+ else
+ NumFiles++;
+ ProgressDialog->Sync.Set_NumFilesCur(NumFiles);
+ #endif
+
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)
+{
+ if (opRes != NArchive::NExtract::NOperationResult::kOK)
+ {
+ UString s;
+ SetExtractErrorMessage(opRes, encrypted, name, s);
+ Add_ArchiveName_Error();
+ AddError_Message(s);
+ }
+ return S_OK;
+}
+
+////////////////////////////////////////
+// IExtractCallbackUI
+
+HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name, bool /* testMode */)
+{
+ #ifndef _SFX
+ RINOK(ProgressDialog->Sync.CheckStop());
+ ProgressDialog->Sync.Set_TitleFileName(name);
+ #endif
+ _currentArchivePath = name;
+ return S_OK;
+}
+
+HRESULT CExtractCallbackImp::SetCurrentFilePath2(const wchar_t *path)
+{
+ _currentFilePath = path;
+ #ifndef _SFX
+ ProgressDialog->Sync.Set_FilePath(path);
+ #endif
+ return S_OK;
+}
+
+#ifndef _SFX
+
+HRESULT CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path)
+{
+ #ifndef _SFX
+ if (NeedAddFile)
+ NumFiles++;
+ NeedAddFile = true;
+ ProgressDialog->Sync.Set_NumFilesCur(NumFiles);
+ #endif
+ return SetCurrentFilePath2(path);
+}
+
+#endif
+
+UString HResultToMessage(HRESULT errorCode);
+
+static const UInt32 k_ErrorFlagsIds[] =
+{
+ IDS_EXTRACT_MSG_IS_NOT_ARC,
+ IDS_EXTRACT_MSG_HEADERS_ERROR,
+ IDS_EXTRACT_MSG_HEADERS_ERROR,
+ IDS_OPEN_MSG_UNAVAILABLE_START,
+ IDS_OPEN_MSG_UNCONFIRMED_START,
+ IDS_EXTRACT_MSG_UEXPECTED_END,
+ IDS_EXTRACT_MSG_DATA_AFTER_END,
+ IDS_EXTRACT_MSG_UNSUPPORTED_METHOD,
+ IDS_OPEN_MSG_UNSUPPORTED_FEATURE,
+ IDS_EXTRACT_MSG_DATA_ERROR,
+ IDS_EXTRACT_MSG_CRC_ERROR
+};
+
+static void AddNewLineString(UString &s, const UString &m)
+{
+ s += m;
+ s.Add_LF();
+}
+
+UString GetOpenArcErrorMessage(UInt32 errorFlags)
+{
+ UString s;
+
+ for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsIds); i++)
+ {
+ UInt32 f = ((UInt32)1 << i);
+ if ((errorFlags & f) == 0)
+ continue;
+ UInt32 id = k_ErrorFlagsIds[i];
+ UString m = LangString(id);
+ if (m.IsEmpty())
+ continue;
+ if (f == kpv_ErrorFlags_EncryptedHeadersError)
+ {
+ m.AddAscii(" : ");
+ AddLangString(m, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
+ }
+ if (!s.IsEmpty())
+ s.Add_LF();
+ s += m;
+ errorFlags &= ~f;
+ }
+
+ if (errorFlags != 0)
+ {
+ char sz[16];
+ sz[0] = '0';
+ sz[1] = 'x';
+ ConvertUInt32ToHex(errorFlags, sz + 2);
+ if (!s.IsEmpty())
+ s.Add_LF();
+ s.AddAscii(sz);
+ }
+
+ return s;
+}
+
+static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
+{
+ UInt32 errorFlags = er.GetErrorFlags();
+ UInt32 warningFlags = er.GetWarningFlags();
+
+ if (errorFlags != 0)
+ AddNewLineString(s, GetOpenArcErrorMessage(errorFlags));
+
+ if (!er.ErrorMessage.IsEmpty())
+ AddNewLineString(s, er.ErrorMessage);
+
+ if (warningFlags != 0)
+ {
+ s += GetNameOfProperty(kpidWarningFlags, L"Warnings");
+ s.AddAscii(":");
+ s.Add_LF();
+ AddNewLineString(s, GetOpenArcErrorMessage(warningFlags));
+ }
+
+ if (!er.WarningMessage.IsEmpty())
+ {
+ s += GetNameOfProperty(kpidWarning, L"Warning");
+ s.AddAscii(": ");
+ s += er.WarningMessage;
+ s.Add_LF();
+ }
+}
+
+static UString GetBracedType(const wchar_t *type)
+{
+ UString s = L'[';
+ s += type;
+ s += L']';
+ return s;
+}
+
+void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result)
+{
+ FOR_VECTOR (level, arcLink.Arcs)
+ {
+ const CArc &arc = arcLink.Arcs[level];
+ const CArcErrorInfo &er = arc.ErrorInfo;
+
+ if (!er.IsThereErrorOrWarning() && er.ErrorFormatIndex < 0)
+ continue;
+
+ if (s.IsEmpty())
+ {
+ s += name;
+ s.Add_LF();
+ }
+
+ if (level != 0)
+ {
+ AddNewLineString(s, arc.Path);
+ }
+
+ ErrorInfo_Print(s, er);
+
+ if (er.ErrorFormatIndex >= 0)
+ {
+ AddNewLineString(s, GetNameOfProperty(kpidWarning, L"Warning"));
+ if (arc.FormatIndex == er.ErrorFormatIndex)
+ {
+ AddNewLineString(s, LangString(IDS_IS_OPEN_WITH_OFFSET));
+ }
+ else
+ {
+ AddNewLineString(s, MyFormatNew(IDS_CANT_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(er.ErrorFormatIndex))));
+ AddNewLineString(s, MyFormatNew(IDS_IS_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(arc.FormatIndex))));
+ }
+ }
+ }
+
+ if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result != S_OK)
+ {
+ s += name;
+ s.Add_LF();
+ if (!arcLink.Arcs.IsEmpty())
+ AddNewLineString(s, arcLink.NonOpen_ArcPath);
+
+ if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result == S_FALSE)
+ {
+ UINT id = IDS_CANT_OPEN_ARCHIVE;
+ UString param;
+ if (arcLink.PasswordWasAsked)
+ id = IDS_CANT_OPEN_ENCRYPTED_ARCHIVE;
+ else if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
+ {
+ id = IDS_CANT_OPEN_AS_TYPE;
+ param = GetBracedType(codecs->GetFormatNamePtr(arcLink.NonOpen_ErrorInfo.ErrorFormatIndex));
+ }
+ UString s2 = MyFormatNew(id, param);
+ s2.Replace(L" ''", L"");
+ s2.Replace(L"''", L"");
+ s += s2;
+ }
+ else
+ s += HResultToMessage(result);
+
+ s.Add_LF();
+ ErrorInfo_Print(s, arcLink.NonOpen_ErrorInfo);
+ }
+
+ if (!s.IsEmpty() && s.Back() == '\n')
+ s.DeleteBack();
+}
+
+HRESULT CExtractCallbackImp::OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result)
+{
+ _currentArchivePath = name;
+ _needWriteArchivePath = true;
+
+ UString s;
+ OpenResult_GUI(s, codecs, arcLink, name, result);
+ if (!s.IsEmpty())
+ {
+ NumArchiveErrors++;
+ AddError_Message(s);
+ _needWriteArchivePath = false;
+ }
+
+ return S_OK;
+}
+
+HRESULT CExtractCallbackImp::ThereAreNoFiles()
+{
+ return S_OK;
+}
+
+void CExtractCallbackImp::Add_ArchiveName_Error()
+{
+ if (_needWriteArchivePath)
+ {
+ if (!_currentArchivePath.IsEmpty())
+ AddError_Message(_currentArchivePath);
+ _needWriteArchivePath = false;
+ }
+}
+
+HRESULT CExtractCallbackImp::ExtractResult(HRESULT result)
+{
+ if (result == S_OK)
+ return result;
+ NumArchiveErrors++;
+ if (result == E_ABORT || result == ERROR_DISK_FULL)
+ return result;
+
+ Add_ArchiveName_Error();
+ if (!_currentFilePath.IsEmpty())
+ MessageError(_currentFilePath);
+ MessageError(NError::MyFormatMessage(result));
+ return S_OK;
+}
+
+#ifndef _NO_CRYPTO
+
+HRESULT CExtractCallbackImp::SetPassword(const UString &password)
+{
+ PasswordIsDefined = true;
+ Password = password;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password)
+{
+ PasswordWasAsked = true;
+ if (!PasswordIsDefined)
+ {
+ CPasswordDialog dialog;
+ #ifndef _SFX
+ bool showPassword = NExtract::Read_ShowPassword();
+ dialog.ShowPassword = showPassword;
+ #endif
+ ProgressDialog->WaitCreating();
+ if (dialog.Create(*ProgressDialog) != IDOK)
+ return E_ABORT;
+ Password = dialog.Password;
+ PasswordIsDefined = true;
+ #ifndef _SFX
+ if (dialog.ShowPassword != showPassword)
+ NExtract::Save_ShowPassword(dialog.ShowPassword);
+ #endif
+ }
+ return StringToBstr(Password, password);
+}
+
+#endif
+
+#ifndef _SFX
+
+STDMETHODIMP CExtractCallbackImp::AskWrite(
+ const wchar_t *srcPath, Int32 srcIsFolder,
+ const FILETIME *srcTime, const UInt64 *srcSize,
+ const wchar_t *destPath,
+ BSTR *destPathResult,
+ Int32 *writeAnswer)
+{
+ UString destPathResultTemp = destPath;
+
+ // RINOK(StringToBstr(destPath, destPathResult));
+
+ *destPathResult = 0;
+ *writeAnswer = BoolToInt(false);
+
+ FString destPathSys = us2fs(destPath);
+ bool srcIsFolderSpec = IntToBool(srcIsFolder);
+ CFileInfo destFileInfo;
+
+ if (destFileInfo.Find(destPathSys))
+ {
+ if (srcIsFolderSpec)
+ {
+ if (!destFileInfo.IsDir())
+ {
+ RINOK(MessageError("can not replace file with folder with same name", destPathSys));
+ return E_ABORT;
+ }
+ *writeAnswer = BoolToInt(false);
+ return S_OK;
+ }
+
+ if (destFileInfo.IsDir())
+ {
+ RINOK(MessageError("can not replace folder with file with same name", destPathSys));
+ *writeAnswer = BoolToInt(false);
+ return S_OK;
+ }
+
+ switch (OverwriteMode)
+ {
+ case NExtract::NOverwriteMode::kSkip:
+ return S_OK;
+ case NExtract::NOverwriteMode::kAsk:
+ {
+ Int32 overwriteResult;
+ UString destPathSpec = destPath;
+ int slashPos = destPathSpec.ReverseFind_PathSepar();
+ destPathSpec.DeleteFrom(slashPos + 1);
+ destPathSpec += fs2us(destFileInfo.Name);
+
+ RINOK(AskOverwrite(
+ destPathSpec,
+ &destFileInfo.MTime, &destFileInfo.Size,
+ srcPath,
+ srcTime, srcSize,
+ &overwriteResult));
+
+ switch (overwriteResult)
+ {
+ case NOverwriteAnswer::kCancel: return E_ABORT;
+ case NOverwriteAnswer::kNo: return S_OK;
+ case NOverwriteAnswer::kNoToAll: OverwriteMode = NExtract::NOverwriteMode::kSkip; return S_OK;
+ case NOverwriteAnswer::kYes: break;
+ case NOverwriteAnswer::kYesToAll: OverwriteMode = NExtract::NOverwriteMode::kOverwrite; break;
+ case NOverwriteAnswer::kAutoRename: OverwriteMode = NExtract::NOverwriteMode::kRename; break;
+ default:
+ return E_FAIL;
+ }
+ }
+ }
+
+ if (OverwriteMode == NExtract::NOverwriteMode::kRename)
+ {
+ if (!AutoRenamePath(destPathSys))
+ {
+ RINOK(MessageError("can not create name for file", destPathSys));
+ return E_ABORT;
+ }
+ destPathResultTemp = fs2us(destPathSys);
+ }
+ else
+ if (!NDir::DeleteFileAlways(destPathSys))
+ {
+ RINOK(MessageError("can not delete output file", destPathSys));
+ return E_ABORT;
+ }
+ }
+ *writeAnswer = BoolToInt(true);
+ return StringToBstr(destPathResultTemp, destPathResult);
+}
+
+
+STDMETHODIMP CExtractCallbackImp::UseExtractToStream(Int32 *res)
+{
+ *res = BoolToInt(StreamMode);
+ return S_OK;
+}
+
+static HRESULT GetTime(IGetProp *getProp, PROPID propID, FILETIME &ft, bool &ftDefined)
+{
+ ftDefined = false;
+ NCOM::CPropVariant prop;
+ RINOK(getProp->GetProp(propID, &prop));
+ if (prop.vt == VT_FILETIME)
+ {
+ ft = prop.filetime;
+ ftDefined = (ft.dwHighDateTime != 0 || ft.dwLowDateTime != 0);
+ }
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
+}
+
+
+static HRESULT GetItemBoolProp(IGetProp *getProp, PROPID propID, bool &result)
+{
+ NCOM::CPropVariant prop;
+ result = false;
+ RINOK(getProp->GetProp(propID, &prop));
+ if (prop.vt == VT_BOOL)
+ result = VARIANT_BOOLToBool(prop.boolVal);
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
+}
+
+
+STDMETHODIMP CExtractCallbackImp::GetStream7(const wchar_t *name,
+ Int32 isDir,
+ ISequentialOutStream **outStream, Int32 askExtractMode,
+ IGetProp *getProp)
+{
+ COM_TRY_BEGIN
+ *outStream = 0;
+ _newVirtFileWasAdded = false;
+ _hashStreamWasUsed = false;
+ _needUpdateStat = false;
+
+ if (_hashStream)
+ _hashStreamSpec->ReleaseStream();
+
+ GetItemBoolProp(getProp, kpidIsAltStream, _isAltStream);
+
+ if (!ProcessAltStreams && _isAltStream)
+ return S_OK;
+
+ _filePath = name;
+ _isFolder = IntToBool(isDir);
+ _curSize = 0;
+ _curSizeDefined = false;
+
+ UInt64 size = 0;
+ bool sizeDefined;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(getProp->GetProp(kpidSize, &prop));
+ sizeDefined = ConvertPropVariantToUInt64(prop, size);
+ }
+
+ if (sizeDefined)
+ {
+ _curSize = size;
+ _curSizeDefined = true;
+ }
+
+ if (askExtractMode != NArchive::NExtract::NAskMode::kExtract &&
+ askExtractMode != NArchive::NExtract::NAskMode::kTest)
+ return S_OK;
+
+ _needUpdateStat = true;
+
+ CMyComPtr<ISequentialOutStream> outStreamLoc;
+
+ if (VirtFileSystem && askExtractMode == NArchive::NExtract::NAskMode::kExtract)
+ {
+ CVirtFile &file = VirtFileSystemSpec->AddNewFile();
+ _newVirtFileWasAdded = true;
+ file.Name = name;
+ file.IsDir = IntToBool(isDir);
+ file.IsAltStream = _isAltStream;
+ file.Size = 0;
+
+ RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTimeDefined));
+ RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATimeDefined));
+ RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTimeDefined));
+
+ NCOM::CPropVariant prop;
+ RINOK(getProp->GetProp(kpidAttrib, &prop));
+ if (prop.vt == VT_UI4)
+ {
+ file.Attrib = prop.ulVal;
+ file.AttribDefined = true;
+ }
+ // else if (isDir) file.Attrib = FILE_ATTRIBUTE_DIRECTORY;
+
+ file.ExpectedSize = 0;
+ if (sizeDefined)
+ file.ExpectedSize = size;
+ outStreamLoc = VirtFileSystem;
+ }
+
+ if (_hashStream)
+ {
+ {
+ _hashStreamSpec->SetStream(outStreamLoc);
+ outStreamLoc = _hashStream;
+ _hashStreamSpec->Init(true);
+ _hashStreamWasUsed = true;
+ }
+ }
+
+ if (outStreamLoc)
+ *outStream = outStreamLoc.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode)
+{
+ COM_TRY_BEGIN
+ _needUpdateStat = (
+ askExtractMode == NArchive::NExtract::NAskMode::kExtract ||
+ askExtractMode == NArchive::NExtract::NAskMode::kTest);
+
+ /*
+ _extractMode = false;
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ if (_testMode)
+ askExtractMode = NArchive::NExtract::NAskMode::kTest;
+ else
+ _extractMode = true;
+ break;
+ };
+ */
+ return SetCurrentFilePath2(_filePath);
+ COM_TRY_END
+}
+
+STDMETHODIMP CExtractCallbackImp::SetOperationResult7(Int32 opRes, Int32 encrypted)
+{
+ COM_TRY_BEGIN
+ if (VirtFileSystem && _newVirtFileWasAdded)
+ {
+ // FIXME: probably we must request file size from VirtFileSystem
+ // _curSize = VirtFileSystem->GetLastFileSize()
+ // _curSizeDefined = true;
+ RINOK(VirtFileSystemSpec->CloseMemFile());
+ }
+ if (_hashStream && _hashStreamWasUsed)
+ {
+ _hashStreamSpec->_hash->Final(_isFolder, _isAltStream, _filePath);
+ _curSize = _hashStreamSpec->GetSize();
+ _curSizeDefined = true;
+ _hashStreamSpec->ReleaseStream();
+ _hashStreamWasUsed = false;
+ }
+ else if (_hashCalc && _needUpdateStat)
+ {
+ _hashCalc->SetSize(_curSize);
+ _hashCalc->Final(_isFolder, _isAltStream, _filePath);
+ }
+ return SetOperationResult(opRes, encrypted);
+ COM_TRY_END
+}
+
+
+static const size_t k_SizeT_MAX = (size_t)((size_t)0 - 1);
+
+static const UInt32 kBlockSize = ((UInt32)1 << 31);
+
+STDMETHODIMP CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+ if (size == 0)
+ return S_OK;
+ if (!_fileMode)
+ {
+ CVirtFile &file = Files.Back();
+ size_t rem = file.Data.Size() - (size_t)file.Size;
+ bool useMem = true;
+ if (rem < size)
+ {
+ UInt64 b = 0;
+ if (file.Data.Size() == 0)
+ b = file.ExpectedSize;
+ UInt64 a = file.Size + size;
+ if (b < a)
+ b = a;
+ a = (UInt64)file.Data.Size() * 2;
+ if (b < a)
+ b = a;
+ useMem = false;
+ if (b <= k_SizeT_MAX && b <= MaxTotalAllocSize)
+ useMem = file.Data.ReAlloc_KeepData((size_t)b, (size_t)file.Size);
+ }
+ if (useMem)
+ {
+ memcpy(file.Data + file.Size, data, size);
+ file.Size += size;
+ if (processedSize)
+ *processedSize = (UInt32)size;
+ return S_OK;
+ }
+ _fileMode = true;
+ }
+ RINOK(FlushToDisk(false));
+ return _outFileStream->Write(data, size, processedSize);
+}
+
+HRESULT CVirtFileSystem::FlushToDisk(bool closeLast)
+{
+ if (!_outFileStream)
+ {
+ _outFileStreamSpec = new COutFileStream;
+ _outFileStream = _outFileStreamSpec;
+ }
+ while (_numFlushed < Files.Size())
+ {
+ const CVirtFile &file = Files[_numFlushed];
+ const FString path = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.Name));
+ if (!_fileIsOpen)
+ {
+ if (!_outFileStreamSpec->Create(path, false))
+ {
+ _outFileStream.Release();
+ return E_FAIL;
+ // MessageBoxMyError(UString(L"Can't create file ") + fs2us(tempFilePath));
+ }
+ _fileIsOpen = true;
+ RINOK(WriteStream(_outFileStream, file.Data, (size_t)file.Size));
+ }
+ if (_numFlushed == Files.Size() - 1 && !closeLast)
+ break;
+ if (file.CTimeDefined ||
+ file.ATimeDefined ||
+ file.MTimeDefined)
+ _outFileStreamSpec->SetTime(
+ file.CTimeDefined ? &file.CTime : NULL,
+ file.ATimeDefined ? &file.ATime : NULL,
+ file.MTimeDefined ? &file.MTime : NULL);
+ _outFileStreamSpec->Close();
+ _numFlushed++;
+ _fileIsOpen = false;
+ if (file.AttribDefined)
+ NDir::SetFileAttrib(path, file.Attrib);
+ }
+ return S_OK;
+}
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.h
new file mode 100644
index 00000000000..6cd8d0aa83d
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.h
@@ -0,0 +1,328 @@
+// ExtractCallback.h
+
+#ifndef __EXTRACT_CALLBACK_H
+#define __EXTRACT_CALLBACK_H
+
+#include "../../../../C/Alloc.h"
+
+#include "../../../Common/MyCom.h"
+#include "../../../Common/StringConvert.h"
+
+#ifndef _SFX
+#include "../Agent/IFolderArchive.h"
+#endif
+
+#include "../Common/ArchiveExtractCallback.h"
+#include "../Common/ArchiveOpenCallback.h"
+
+#ifndef _NO_CRYPTO
+#include "../../IPassword.h"
+#endif
+
+#ifndef _SFX
+#include "IFolder.h"
+#endif
+
+#include "ProgressDialog2.h"
+
+#ifdef LANG
+#include "LangUtils.h"
+#endif
+
+#ifndef _SFX
+
+class CGrowBuf
+{
+ Byte *_items;
+ size_t _size;
+
+ CLASS_NO_COPY(CGrowBuf);
+
+public:
+ bool ReAlloc_KeepData(size_t newSize, size_t keepSize)
+ {
+ void *buf = MyAlloc(newSize);
+ if (!buf)
+ return false;
+ if (keepSize != 0)
+ memcpy(buf, _items, keepSize);
+ MyFree(_items);
+ _items = (Byte *)buf;
+ _size = newSize;
+ return true;
+ }
+
+ CGrowBuf(): _items(0), _size(0) {}
+ ~CGrowBuf() { MyFree(_items); }
+
+ operator Byte *() { return _items; }
+ operator const Byte *() const { return _items; }
+ size_t Size() const { return _size; }
+};
+
+struct CVirtFile
+{
+ CGrowBuf Data;
+
+ UInt64 Size; // real size
+ UInt64 ExpectedSize; // the size from props request. 0 if unknown
+
+ UString Name;
+
+ bool CTimeDefined;
+ bool ATimeDefined;
+ bool MTimeDefined;
+ bool AttribDefined;
+
+ bool IsDir;
+ bool IsAltStream;
+
+ DWORD Attrib;
+
+ FILETIME CTime;
+ FILETIME ATime;
+ FILETIME MTime;
+
+ CVirtFile():
+ CTimeDefined(false),
+ ATimeDefined(false),
+ MTimeDefined(false),
+ AttribDefined(false),
+ IsDir(false),
+ IsAltStream(false) {}
+};
+
+class CVirtFileSystem:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ UInt64 _totalAllocSize;
+
+ size_t _pos;
+ unsigned _numFlushed;
+ bool _fileIsOpen;
+ bool _fileMode;
+ COutFileStream *_outFileStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outFileStream;
+public:
+ CObjectVector<CVirtFile> Files;
+ UInt64 MaxTotalAllocSize;
+ FString DirPrefix;
+
+ CVirtFile &AddNewFile()
+ {
+ if (!Files.IsEmpty())
+ {
+ MaxTotalAllocSize -= Files.Back().Data.Size();
+ }
+ return Files.AddNew();
+ }
+ HRESULT CloseMemFile()
+ {
+ if (_fileMode)
+ {
+ return FlushToDisk(true);
+ }
+ CVirtFile &file = Files.Back();
+ if (file.Data.Size() != file.Size)
+ {
+ file.Data.ReAlloc_KeepData((size_t)file.Size, (size_t)file.Size);
+ }
+ return S_OK;
+ }
+
+ bool IsStreamInMem() const
+ {
+ if (_fileMode)
+ return false;
+ if (Files.Size() < 1 || /* Files[0].IsAltStream || */ Files[0].IsDir)
+ return false;
+ return true;
+ }
+
+ size_t GetMemStreamWrittenSize() const { return _pos; }
+
+ CVirtFileSystem(): _outFileStreamSpec(NULL), MaxTotalAllocSize((UInt64)0 - 1) {}
+
+ void Init()
+ {
+ _totalAllocSize = 0;
+ _fileMode = false;
+ _pos = 0;
+ _numFlushed = 0;
+ _fileIsOpen = false;
+ }
+
+ HRESULT CloseFile(const FString &path);
+ HRESULT FlushToDisk(bool closeLast);
+ size_t GetPos() const { return _pos; }
+
+ MY_UNKNOWN_IMP
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
+
+class CExtractCallbackImp:
+ public IExtractCallbackUI, // it includes IFolderArchiveExtractCallback
+ public IOpenCallbackUI,
+ public IFolderArchiveExtractCallback2,
+ #ifndef _SFX
+ public IFolderOperationsExtractCallback,
+ public IFolderExtractToStreamCallback,
+ public ICompressProgressInfo,
+ #endif
+ #ifndef _NO_CRYPTO
+ public ICryptoGetTextPassword,
+ #endif
+ public CMyUnknownImp
+{
+ HRESULT MessageError(const char *message, const FString &path);
+ void Add_ArchiveName_Error();
+public:
+ MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback)
+ MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback2)
+ #ifndef _SFX
+ MY_QUERYINTERFACE_ENTRY(IFolderOperationsExtractCallback)
+ MY_QUERYINTERFACE_ENTRY(IFolderExtractToStreamCallback)
+ MY_QUERYINTERFACE_ENTRY(ICompressProgressInfo)
+ #endif
+ #ifndef _NO_CRYPTO
+ MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword)
+ #endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+ INTERFACE_IProgress(;)
+ INTERFACE_IOpenCallbackUI(;)
+ INTERFACE_IFolderArchiveExtractCallback(;)
+ INTERFACE_IFolderArchiveExtractCallback2(;)
+ // STDMETHOD(SetTotalFiles)(UInt64 total);
+ // STDMETHOD(SetCompletedFiles)(const UInt64 *value);
+
+ INTERFACE_IExtractCallbackUI(;)
+
+ #ifndef _SFX
+ // IFolderOperationsExtractCallback
+ STDMETHOD(AskWrite)(
+ const wchar_t *srcPath,
+ Int32 srcIsFolder,
+ const FILETIME *srcTime,
+ const UInt64 *srcSize,
+ const wchar_t *destPathRequest,
+ BSTR *destPathResult,
+ Int32 *writeAnswer);
+ STDMETHOD(ShowMessage)(const wchar_t *message);
+ STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath);
+ STDMETHOD(SetNumFiles)(UInt64 numFiles);
+ INTERFACE_IFolderExtractToStreamCallback(;)
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+ #endif
+
+ // ICryptoGetTextPassword
+ #ifndef _NO_CRYPTO
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+ #endif
+
+private:
+ UString _currentArchivePath;
+ bool _needWriteArchivePath;
+
+ UString _currentFilePath;
+ bool _isFolder;
+
+ bool _isAltStream;
+ UInt64 _curSize;
+ bool _curSizeDefined;
+ UString _filePath;
+ // bool _extractMode;
+ // bool _testMode;
+ bool _newVirtFileWasAdded;
+ bool _needUpdateStat;
+
+
+ HRESULT SetCurrentFilePath2(const wchar_t *filePath);
+ void AddError_Message(LPCWSTR message);
+
+ #ifndef _SFX
+ bool _hashStreamWasUsed;
+ COutStreamWithHash *_hashStreamSpec;
+ CMyComPtr<ISequentialOutStream> _hashStream;
+ IHashCalc *_hashCalc; // it's for stat in Test operation
+ #endif
+
+public:
+
+ #ifndef _SFX
+ CVirtFileSystem *VirtFileSystemSpec;
+ CMyComPtr<ISequentialOutStream> VirtFileSystem;
+ #endif
+
+ bool ProcessAltStreams;
+
+ bool StreamMode;
+
+ CProgressDialog *ProgressDialog;
+ #ifndef _SFX
+ UInt64 NumFolders;
+ UInt64 NumFiles;
+ bool NeedAddFile;
+ #endif
+ UInt32 NumArchiveErrors;
+ bool ThereAreMessageErrors;
+ NExtract::NOverwriteMode::EEnum OverwriteMode;
+
+ #ifndef _NO_CRYPTO
+ bool PasswordIsDefined;
+ bool PasswordWasAsked;
+ UString Password;
+ #endif
+
+
+ UString _lang_Extracting;
+ UString _lang_Testing;
+ UString _lang_Skipping;
+ UString _lang_Empty;
+
+ bool _totalFilesDefined;
+ bool _totalBytesDefined;
+ bool MultiArcMode;
+
+ CExtractCallbackImp():
+ #ifndef _NO_CRYPTO
+ PasswordIsDefined(false),
+ PasswordWasAsked(false),
+ #endif
+ OverwriteMode(NExtract::NOverwriteMode::kAsk),
+ StreamMode(false),
+ ProcessAltStreams(true),
+
+ _totalFilesDefined(false),
+ _totalBytesDefined(false),
+ MultiArcMode(false)
+
+ #ifndef _SFX
+ , _hashCalc(NULL)
+ #endif
+ {}
+
+ ~CExtractCallbackImp();
+ void Init();
+
+ #ifndef _SFX
+ void SetHashCalc(IHashCalc *hashCalc) { _hashCalc = hashCalc; }
+
+ void SetHashMethods(IHashCalc *hash)
+ {
+ if (!hash)
+ return;
+ _hashStreamSpec = new COutStreamWithHash;
+ _hashStream = _hashStreamSpec;
+ _hashStreamSpec->_hash = hash;
+ }
+ #endif
+
+ bool IsOK() const { return NumArchiveErrors == 0 && !ThereAreMessageErrors; }
+};
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.cpp
new file mode 100644
index 00000000000..2143c3f1b12
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.cpp
@@ -0,0 +1,28 @@
+// FormatUtils.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/IntToString.h"
+
+#include "FormatUtils.h"
+
+#include "LangUtils.h"
+
+UString NumberToString(UInt64 number)
+{
+ wchar_t numberString[32];
+ ConvertUInt64ToString(number, numberString);
+ return numberString;
+}
+
+UString MyFormatNew(const UString &format, const UString &argument)
+{
+ UString result = format;
+ result.Replace(L"{0}", argument);
+ return result;
+}
+
+UString MyFormatNew(UINT resourceID, const UString &argument)
+{
+ return MyFormatNew(LangString(resourceID), argument);
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.h
new file mode 100644
index 00000000000..993e803390f
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.h
@@ -0,0 +1,14 @@
+// FormatUtils.h
+
+#ifndef __FORMAT_UTILS_H
+#define __FORMAT_UTILS_H
+
+#include "../../../Common/MyTypes.h"
+#include "../../../Common/MyString.h"
+
+UString NumberToString(UInt64 number);
+
+UString MyFormatNew(const UString &format, const UString &argument);
+UString MyFormatNew(UINT resourceID, const UString &argument);
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/LangUtils.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/LangUtils.h
new file mode 100644
index 00000000000..d63a443c6d3
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/LangUtils.h
@@ -0,0 +1,40 @@
+// LangUtils.h
+
+#ifndef __LANG_UTILS_H
+#define __LANG_UTILS_H
+
+#include "../../../Windows/ResourceString.h"
+
+#ifdef LANG
+
+extern UString g_LangID;
+
+struct CIDLangPair
+{
+ UInt32 ControlID;
+ UInt32 LangID;
+};
+
+void ReloadLang();
+void LoadLangOneTime();
+FString GetLangDirPrefix();
+
+void LangSetDlgItemText(HWND dialog, UInt32 controlID, UInt32 langID);
+void LangSetDlgItems(HWND dialog, const UInt32 *ids, unsigned numItems);
+void LangSetDlgItems_Colon(HWND dialog, const UInt32 *ids, unsigned numItems);
+void LangSetWindowText(HWND window, UInt32 langID);
+
+UString LangString(UInt32 langID);
+void AddLangString(UString &s, UInt32 langID);
+void LangString(UInt32 langID, UString &dest);
+void LangString_OnlyFromLangFile(UInt32 langID, UString &dest);
+
+#else
+
+inline UString LangString(UInt32 langID) { return NWindows::MyLoadString(langID); }
+inline void LangString(UInt32 langID, UString &dest) { NWindows::MyLoadString(langID, dest); }
+inline void AddLangString(UString &s, UInt32 langID) { s += NWindows::MyLoadString(langID); }
+
+#endif
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/MyWindowsNew.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/MyWindowsNew.h
new file mode 100644
index 00000000000..48a95359e6f
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/MyWindowsNew.h
@@ -0,0 +1,76 @@
+// MyWindowsNew.h
+
+#ifndef __MY_WINDOWS_NEW_H
+#define __MY_WINDOWS_NEW_H
+
+#ifdef _MSC_VER
+
+#include <ShObjIdl.h>
+
+#ifndef __ITaskbarList3_INTERFACE_DEFINED__
+#define __ITaskbarList3_INTERFACE_DEFINED__
+
+typedef enum THUMBBUTTONFLAGS
+{
+ THBF_ENABLED = 0,
+ THBF_DISABLED = 0x1,
+ THBF_DISMISSONCLICK = 0x2,
+ THBF_NOBACKGROUND = 0x4,
+ THBF_HIDDEN = 0x8,
+ THBF_NONINTERACTIVE = 0x10
+} THUMBBUTTONFLAGS;
+
+typedef enum THUMBBUTTONMASK
+{
+ THB_BITMAP = 0x1,
+ THB_ICON = 0x2,
+ THB_TOOLTIP = 0x4,
+ THB_FLAGS = 0x8
+} THUMBBUTTONMASK;
+
+// #include <pshpack8.h>
+
+typedef struct THUMBBUTTON
+{
+ THUMBBUTTONMASK dwMask;
+ UINT iId;
+ UINT iBitmap;
+ HICON hIcon;
+ WCHAR szTip[260];
+ THUMBBUTTONFLAGS dwFlags;
+} THUMBBUTTON;
+
+typedef struct THUMBBUTTON *LPTHUMBBUTTON;
+
+typedef enum TBPFLAG
+{
+ TBPF_NOPROGRESS = 0,
+ TBPF_INDETERMINATE = 0x1,
+ TBPF_NORMAL = 0x2,
+ TBPF_ERROR = 0x4,
+ TBPF_PAUSED = 0x8
+} TBPFLAG;
+
+DEFINE_GUID(IID_ITaskbarList3, 0xEA1AFB91, 0x9E28, 0x4B86, 0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF);
+
+struct ITaskbarList3: public ITaskbarList2
+{
+ STDMETHOD(SetProgressValue)(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) = 0;
+ STDMETHOD(SetProgressState)(HWND hwnd, TBPFLAG tbpFlags) = 0;
+ STDMETHOD(RegisterTab)(HWND hwndTab, HWND hwndMDI) = 0;
+ STDMETHOD(UnregisterTab)(HWND hwndTab) = 0;
+ STDMETHOD(SetTabOrder)(HWND hwndTab, HWND hwndInsertBefore) = 0;
+ STDMETHOD(SetTabActive)(HWND hwndTab, HWND hwndMDI, DWORD dwReserved) = 0;
+ STDMETHOD(ThumbBarAddButtons)(HWND hwnd, UINT cButtons, LPTHUMBBUTTON pButton) = 0;
+ STDMETHOD(ThumbBarUpdateButtons)(HWND hwnd, UINT cButtons, LPTHUMBBUTTON pButton) = 0;
+ STDMETHOD(ThumbBarSetImageList)(HWND hwnd, HIMAGELIST himl) = 0;
+ STDMETHOD(SetOverlayIcon)(HWND hwnd, HICON hIcon, LPCWSTR pszDescription) = 0;
+ STDMETHOD(SetThumbnailTooltip)(HWND hwnd, LPCWSTR pszTip) = 0;
+ STDMETHOD(SetThumbnailClip)(HWND hwnd, RECT *prcClip) = 0;
+};
+
+#endif
+
+#endif
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
new file mode 100644
index 00000000000..c6feb9021bb
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
@@ -0,0 +1,119 @@
+// OverwriteDialog.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/StringConvert.h"
+
+#include "../../../Windows/PropVariantConv.h"
+#include "../../../Windows/ResourceString.h"
+
+#include "../../../Windows/Control/Static.h"
+
+#include "FormatUtils.h"
+#include "LangUtils.h"
+#include "OverwriteDialog.h"
+
+#include "PropertyNameRes.h"
+
+using namespace NWindows;
+
+#ifdef LANG
+static const UInt32 kLangIDs[] =
+{
+ IDT_OVERWRITE_HEADER,
+ IDT_OVERWRITE_QUESTION_BEGIN,
+ IDT_OVERWRITE_QUESTION_END,
+ IDB_YES_TO_ALL,
+ IDB_NO_TO_ALL,
+ IDB_AUTO_RENAME
+};
+#endif
+
+static const unsigned kCurrentFileNameSizeLimit = 82;
+static const unsigned kCurrentFileNameSizeLimit2 = 30;
+
+void COverwriteDialog::ReduceString(UString &s)
+{
+ unsigned size = _isBig ? kCurrentFileNameSizeLimit : kCurrentFileNameSizeLimit2;
+ if (s.Len() > size)
+ {
+ s.Delete(size / 2, s.Len() - size);
+ s.Insert(size / 2, L" ... ");
+ }
+}
+
+void COverwriteDialog::SetFileInfoControl(int textID, int iconID,
+ const NOverwriteDialog::CFileInfo &fileInfo)
+{
+ UString sizeString;
+ if (fileInfo.SizeIsDefined)
+ sizeString = MyFormatNew(IDS_FILE_SIZE, NumberToString(fileInfo.Size));
+
+ const UString &fileName = fileInfo.Name;
+ int slashPos = fileName.ReverseFind_PathSepar();
+ UString s1 = fileName.Left(slashPos + 1);
+ UString s2 = fileName.Ptr(slashPos + 1);
+
+ ReduceString(s1);
+ ReduceString(s2);
+
+ UString s = s1;
+ s.Add_LF();
+ s += s2;
+ s.Add_LF();
+ s += sizeString;
+ s.Add_LF();
+
+ 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 += t;
+ }
+
+ NControl::CDialogChildControl control;
+ control.Init(*this, textID);
+ control.SetText(s);
+
+ SHFILEINFO shellFileInfo;
+ if (::SHGetFileInfo(
+ GetSystemString(fileInfo.Name), FILE_ATTRIBUTE_NORMAL, &shellFileInfo,
+ sizeof(shellFileInfo), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | SHGFI_LARGEICON))
+ {
+ NControl::CStatic staticContol;
+ staticContol.Attach(GetItem(iconID));
+ staticContol.SetIcon(shellFileInfo.hIcon);
+ }
+}
+
+bool COverwriteDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetWindowText(*this, IDD_OVERWRITE);
+ LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
+ #endif
+ SetFileInfoControl(IDT_OVERWRITE_OLD_FILE_SIZE_TIME, IDI_OVERWRITE_OLD_FILE, OldFileInfo);
+ SetFileInfoControl(IDT_OVERWRITE_NEW_FILE_SIZE_TIME, IDI_OVERWRITE_NEW_FILE, NewFileInfo);
+ NormalizePosition();
+ return CModalDialog::OnInit();
+}
+
+bool COverwriteDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch (buttonID)
+ {
+ case IDYES:
+ case IDNO:
+ case IDB_YES_TO_ALL:
+ case IDB_NO_TO_ALL:
+ case IDB_AUTO_RENAME:
+ End(buttonID);
+ return true;
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.h
new file mode 100644
index 00000000000..da7fa55ff68
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.h
@@ -0,0 +1,69 @@
+// OverwriteDialog.h
+
+#ifndef __OVERWRITE_DIALOG_H
+#define __OVERWRITE_DIALOG_H
+
+#include "../../../Windows/Control/Dialog.h"
+
+#include "DialogSize.h"
+#include "OverwriteDialogRes.h"
+
+namespace NOverwriteDialog
+{
+ struct CFileInfo
+ {
+ bool SizeIsDefined;
+ bool TimeIsDefined;
+ UInt64 Size;
+ FILETIME Time;
+ UString Name;
+
+ void SetTime(const FILETIME *t)
+ {
+ if (t == 0)
+ TimeIsDefined = false;
+ else
+ {
+ TimeIsDefined = true;
+ Time = *t;
+ }
+ }
+ void SetSize(const UInt64 *size)
+ {
+ if (size == 0)
+ SizeIsDefined = false;
+ else
+ {
+ SizeIsDefined = true;
+ Size = *size;
+ }
+ }
+ };
+}
+
+class COverwriteDialog: public NWindows::NControl::CModalDialog
+{
+ bool _isBig;
+
+ void SetFileInfoControl(int textID, int iconID, const NOverwriteDialog::CFileInfo &fileInfo);
+ virtual bool OnInit();
+ bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ void ReduceString(UString &s);
+
+public:
+ INT_PTR Create(HWND parent = 0)
+ {
+ BIG_DIALOG_SIZE(280, 200);
+ #ifdef UNDER_CE
+ _isBig = isBig;
+ #else
+ _isBig = true;
+ #endif
+ return CModalDialog::Create(SIZED_DIALOG(IDD_OVERWRITE), parent);
+ }
+
+ NOverwriteDialog::CFileInfo OldFileInfo;
+ NOverwriteDialog::CFileInfo NewFileInfo;
+};
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.rc b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.rc
new file mode 100644
index 00000000000..29f99122bfd
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.rc
@@ -0,0 +1,91 @@
+#include "OverwriteDialogRes.h"
+#include "../../GuiCommon.rc"
+
+#define xc 280
+#define yc 200
+
+#undef iconSize
+#define iconSize 24
+
+#undef x
+#undef fx
+#undef fy
+#define x (m + iconSize + m)
+#define fx (xc - iconSize - m)
+#define fy 50
+
+#define bSizeBig 104
+#undef bx1
+#define bx1 (xs - m - bSizeBig)
+
+IDD_OVERWRITE DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT
+CAPTION "Confirm File Replace"
+BEGIN
+ LTEXT "Destination folder already contains processed file.", IDT_OVERWRITE_HEADER, m, 7, xc, 8
+ LTEXT "Would you like to replace the existing file", IDT_OVERWRITE_QUESTION_BEGIN, m, 28, xc, 8
+
+ ICON "", IDI_OVERWRITE_OLD_FILE, m, 44, iconSize, iconSize
+ LTEXT "", IDT_OVERWRITE_OLD_FILE_SIZE_TIME, x, 44, fx, fy, SS_NOPREFIX
+
+ LTEXT "with this one?", IDT_OVERWRITE_QUESTION_END, m, 98, xc, 8
+
+ ICON "", IDI_OVERWRITE_NEW_FILE, m, 114, iconSize, iconSize
+ LTEXT "", IDT_OVERWRITE_NEW_FILE_SIZE_TIME, x, 114, fx, fy, SS_NOPREFIX
+
+ PUSHBUTTON "&Yes", IDYES, bx3, by2, bxs, bys
+ PUSHBUTTON "Yes to &All", IDB_YES_TO_ALL, bx2, by2, bxs, bys
+ PUSHBUTTON "A&uto Rename", IDB_AUTO_RENAME, bx1, by2, bSizeBig, bys
+ PUSHBUTTON "&No", IDNO, bx3, by1, bxs, bys
+ PUSHBUTTON "No to A&ll", IDB_NO_TO_ALL, bx2, by1, bxs, bys
+ PUSHBUTTON "&Cancel", IDCANCEL, xs - m - bxs, by1, bxs, bys
+END
+
+
+#ifdef UNDER_CE
+
+#undef m
+#undef xc
+#undef yc
+
+#define m 4
+#define xc 152
+#define yc 144
+
+#undef fy
+#define fy 40
+
+#undef bxs
+#define bxs 48
+
+#undef bx1
+
+#define bx1 (xs - m - bxs)
+
+IDD_OVERWRITE_2 DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT
+CAPTION "Confirm File Replace"
+BEGIN
+ LTEXT "Would you like to replace the existing file", IDT_OVERWRITE_QUESTION_BEGIN, m, m, xc, 8
+
+ ICON "", IDI_OVERWRITE_OLD_FILE, m, 20, iconSize, iconSize
+ LTEXT "", IDT_OVERWRITE_OLD_FILE_SIZE_TIME, x, 20, fx, fy, SS_NOPREFIX
+
+ LTEXT "with this one?", IDT_OVERWRITE_QUESTION_END, m, 60, xc, 8
+
+ ICON "", IDI_OVERWRITE_NEW_FILE, m, 72, iconSize, iconSize
+ LTEXT "", IDT_OVERWRITE_NEW_FILE_SIZE_TIME, x, 72, fx, fy, SS_NOPREFIX
+
+ PUSHBUTTON "&Yes", IDYES, bx3, by2, bxs, bys
+ PUSHBUTTON "Yes to &All", IDB_YES_TO_ALL, bx2, by2, bxs, bys
+ PUSHBUTTON "A&uto Rename", IDB_AUTO_RENAME, bx1, by2, bxs, bys
+ PUSHBUTTON "&No", IDNO, bx3, by1, bxs, bys
+ PUSHBUTTON "No to A&ll", IDB_NO_TO_ALL, bx2, by1, bxs, bys
+ PUSHBUTTON "&Cancel", IDCANCEL, bx1, by1, bxs, bys
+END
+
+#endif
+
+
+STRINGTABLE
+BEGIN
+ IDS_FILE_SIZE "{0} bytes"
+END
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialogRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialogRes.h
new file mode 100644
index 00000000000..b480ba1634c
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialogRes.h
@@ -0,0 +1,17 @@
+#define IDD_OVERWRITE 3500
+#define IDD_OVERWRITE_2 13500
+
+#define IDT_OVERWRITE_HEADER 3501
+#define IDT_OVERWRITE_QUESTION_BEGIN 3502
+#define IDT_OVERWRITE_QUESTION_END 3503
+#define IDS_FILE_SIZE 3504
+
+#define IDB_AUTO_RENAME 3505
+#define IDB_YES_TO_ALL 440
+#define IDB_NO_TO_ALL 441
+
+#define IDI_OVERWRITE_OLD_FILE 100
+#define IDI_OVERWRITE_NEW_FILE 101
+
+#define IDT_OVERWRITE_OLD_FILE_SIZE_TIME 102
+#define IDT_OVERWRITE_NEW_FILE_SIZE_TIME 103
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.cpp
new file mode 100644
index 00000000000..6ead39c3764
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.cpp
@@ -0,0 +1,58 @@
+// PasswordDialog.cpp
+
+#include "StdAfx.h"
+
+#include "PasswordDialog.h"
+
+#ifdef LANG
+#include "LangUtils.h"
+#endif
+
+#ifdef LANG
+static const UInt32 kLangIDs[] =
+{
+ IDT_PASSWORD_ENTER,
+ IDX_PASSWORD_SHOW
+};
+#endif
+
+void CPasswordDialog::ReadControls()
+{
+ _passwordEdit.GetText(Password);
+ ShowPassword = IsButtonCheckedBool(IDX_PASSWORD_SHOW);
+}
+
+void CPasswordDialog::SetTextSpec()
+{
+ _passwordEdit.SetPasswordChar(ShowPassword ? 0: TEXT('*'));
+ _passwordEdit.SetText(Password);
+}
+
+bool CPasswordDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetWindowText(*this, IDD_PASSWORD);
+ LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
+ #endif
+ _passwordEdit.Attach(GetItem(IDE_PASSWORD_PASSWORD));
+ CheckButton(IDX_PASSWORD_SHOW, ShowPassword);
+ SetTextSpec();
+ return CModalDialog::OnInit();
+}
+
+bool CPasswordDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ if (buttonID == IDX_PASSWORD_SHOW)
+ {
+ ReadControls();
+ SetTextSpec();
+ return true;
+ }
+ return CDialog::OnButtonClicked(buttonID, buttonHWND);
+}
+
+void CPasswordDialog::OnOK()
+{
+ ReadControls();
+ CModalDialog::OnOK();
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.h
new file mode 100644
index 00000000000..339ebdaf072
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.h
@@ -0,0 +1,28 @@
+// PasswordDialog.h
+
+#ifndef __PASSWORD_DIALOG_H
+#define __PASSWORD_DIALOG_H
+
+#include "../../../Windows/Control/Dialog.h"
+#include "../../../Windows/Control/Edit.h"
+
+#include "PasswordDialogRes.h"
+
+class CPasswordDialog: public NWindows::NControl::CModalDialog
+{
+ NWindows::NControl::CEdit _passwordEdit;
+
+ virtual void OnOK();
+ virtual bool OnInit();
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ void SetTextSpec();
+ void ReadControls();
+public:
+ UString Password;
+ bool ShowPassword;
+
+ CPasswordDialog(): ShowPassword(false) {}
+ INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_PASSWORD, parentWindow); }
+};
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.rc b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.rc
new file mode 100644
index 00000000000..90c57efa607
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.rc
@@ -0,0 +1,14 @@
+#include "PasswordDialogRes.h"
+#include "../../GuiCommon.rc"
+
+#define xc 140
+#define yc 72
+
+IDD_PASSWORD DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT
+CAPTION "Enter password"
+BEGIN
+ LTEXT "&Enter password:", IDT_PASSWORD_ENTER, m, m, xc, 8
+ EDITTEXT IDE_PASSWORD_PASSWORD, m, 20, xc, 14, ES_PASSWORD | ES_AUTOHSCROLL
+ CONTROL "&Show password", IDX_PASSWORD_SHOW, MY_CHECKBOX, m, 42, xc, 10
+ OK_CANCEL
+END
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialogRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialogRes.h
new file mode 100644
index 00000000000..1fe32e10aa5
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialogRes.h
@@ -0,0 +1,5 @@
+#define IDD_PASSWORD 3800
+#define IDT_PASSWORD_ENTER 3801
+#define IDX_PASSWORD_SHOW 3803
+
+#define IDE_PASSWORD_PASSWORD 120
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.cpp
new file mode 100644
index 00000000000..65201a9ed16
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.cpp
@@ -0,0 +1,196 @@
+// ProgressDialog.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/IntToString.h"
+
+#include "resource.h"
+
+#include "ProgressDialog.h"
+
+using namespace NWindows;
+
+extern HINSTANCE g_hInstance;
+
+static const UINT_PTR kTimerID = 3;
+static const UINT kTimerElapse = 100;
+
+#ifdef LANG
+#include "LangUtils.h"
+#endif
+
+HRESULT CProgressSync::ProcessStopAndPause()
+{
+ for (;;)
+ {
+ if (GetStopped())
+ return E_ABORT;
+ if (!GetPaused())
+ break;
+ ::Sleep(100);
+ }
+ return S_OK;
+}
+
+#ifndef _SFX
+CProgressDialog::~CProgressDialog()
+{
+ AddToTitle(L"");
+}
+void CProgressDialog::AddToTitle(LPCWSTR s)
+{
+ if (MainWindow != 0)
+ MySetWindowText(MainWindow, UString(s) + MainTitle);
+}
+#endif
+
+
+bool CProgressDialog::OnInit()
+{
+ _range = (UInt64)(Int64)-1;
+ _prevPercentValue = -1;
+
+ _wasCreated = true;
+ _dialogCreatedEvent.Set();
+
+ #ifdef LANG
+ LangSetDlgItems(*this, NULL, 0);
+ #endif
+
+ m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
+
+ if (IconID >= 0)
+ {
+ HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IconID));
+ SetIcon(ICON_BIG, icon);
+ }
+
+ _timer = SetTimer(kTimerID, kTimerElapse);
+ SetText(_title);
+ CheckNeedClose();
+ return CModalDialog::OnInit();
+}
+
+void CProgressDialog::OnCancel() { Sync.SetStopped(true); }
+void CProgressDialog::OnOK() { }
+
+void CProgressDialog::SetRange(UInt64 range)
+{
+ _range = range;
+ _peviousPos = (UInt64)(Int64)-1;
+ _converter.Init(range);
+ m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100%
+}
+
+void CProgressDialog::SetPos(UInt64 pos)
+{
+ bool redraw = true;
+ if (pos < _range && pos > _peviousPos)
+ {
+ UInt64 posDelta = pos - _peviousPos;
+ if (posDelta < (_range >> 10))
+ redraw = false;
+ }
+ if (redraw)
+ {
+ m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100%
+ _peviousPos = pos;
+ }
+}
+
+bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
+{
+ if (Sync.GetPaused())
+ return true;
+
+ CheckNeedClose();
+
+ UInt64 total, completed;
+ Sync.GetProgress(total, completed);
+ if (total != _range)
+ SetRange(total);
+ SetPos(completed);
+
+ if (total == 0)
+ total = 1;
+
+ int percentValue = (int)(completed * 100 / total);
+ if (percentValue != _prevPercentValue)
+ {
+ wchar_t s[64];
+ ConvertUInt64ToString(percentValue, s);
+ UString title = s;
+ title += L"% ";
+ SetText(title + _title);
+ #ifndef _SFX
+ AddToTitle(title + MainAddTitle);
+ #endif
+ _prevPercentValue = percentValue;
+ }
+ return true;
+}
+
+bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case kCloseMessage:
+ {
+ KillTimer(_timer);
+ _timer = 0;
+ if (_inCancelMessageBox)
+ {
+ _externalCloseMessageWasReceived = true;
+ break;
+ }
+ return OnExternalCloseMessage();
+ }
+ /*
+ case WM_SETTEXT:
+ {
+ if (_timer == 0)
+ return true;
+ }
+ */
+ }
+ return CModalDialog::OnMessage(message, wParam, lParam);
+}
+
+bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch (buttonID)
+ {
+ case IDCANCEL:
+ {
+ bool paused = Sync.GetPaused();
+ Sync.SetPaused(true);
+ _inCancelMessageBox = true;
+ int res = ::MessageBoxW(*this, L"Are you sure you want to cancel?", _title, MB_YESNOCANCEL);
+ _inCancelMessageBox = false;
+ Sync.SetPaused(paused);
+ if (res == IDCANCEL || res == IDNO)
+ {
+ if (_externalCloseMessageWasReceived)
+ OnExternalCloseMessage();
+ return true;
+ }
+ break;
+ }
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
+
+void CProgressDialog::CheckNeedClose()
+{
+ if (_needClose)
+ {
+ PostMsg(kCloseMessage);
+ _needClose = false;
+ }
+}
+
+bool CProgressDialog::OnExternalCloseMessage()
+{
+ End(0);
+ return true;
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.h
new file mode 100644
index 00000000000..0f41b57aed6
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.h
@@ -0,0 +1,170 @@
+// ProgressDialog.h
+
+#ifndef __PROGRESS_DIALOG_H
+#define __PROGRESS_DIALOG_H
+
+#include "../../../Windows/Synchronization.h"
+#include "../../../Windows/Thread.h"
+
+#include "../../../Windows/Control/Dialog.h"
+#include "../../../Windows/Control/ProgressBar.h"
+
+#include "ProgressDialogRes.h"
+
+class CProgressSync
+{
+ NWindows::NSynchronization::CCriticalSection _cs;
+ bool _stopped;
+ bool _paused;
+ UInt64 _total;
+ UInt64 _completed;
+public:
+ CProgressSync(): _stopped(false), _paused(false), _total(1), _completed(0) {}
+
+ HRESULT ProcessStopAndPause();
+ bool GetStopped()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
+ return _stopped;
+ }
+ void SetStopped(bool value)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
+ _stopped = value;
+ }
+ bool GetPaused()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
+ return _paused;
+ }
+ void SetPaused(bool value)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
+ _paused = value;
+ }
+ void SetProgress(UInt64 total, UInt64 completed)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
+ _total = total;
+ _completed = completed;
+ }
+ void SetPos(UInt64 completed)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
+ _completed = completed;
+ }
+ void GetProgress(UInt64 &total, UInt64 &completed)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
+ total = _total;
+ completed = _completed;
+ }
+};
+
+class CU64ToI32Converter
+{
+ UInt64 _numShiftBits;
+public:
+ void Init(UInt64 range)
+ {
+ // Windows CE doesn't like big number here.
+ for (_numShiftBits = 0; range > (1 << 15); _numShiftBits++)
+ range >>= 1;
+ }
+ int Count(UInt64 value) { return int(value >> _numShiftBits); }
+};
+
+class CProgressDialog: public NWindows::NControl::CModalDialog
+{
+private:
+ UINT_PTR _timer;
+
+ UString _title;
+ CU64ToI32Converter _converter;
+ UInt64 _peviousPos;
+ UInt64 _range;
+ NWindows::NControl::CProgressBar m_ProgressBar;
+
+ int _prevPercentValue;
+
+ bool _wasCreated;
+ bool _needClose;
+ bool _inCancelMessageBox;
+ bool _externalCloseMessageWasReceived;
+
+ bool OnTimer(WPARAM timerID, LPARAM callback);
+ void SetRange(UInt64 range);
+ void SetPos(UInt64 pos);
+ virtual bool OnInit();
+ virtual void OnCancel();
+ virtual void OnOK();
+ NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent;
+ #ifndef _SFX
+ void AddToTitle(LPCWSTR string);
+ #endif
+ bool OnButtonClicked(int buttonID, HWND buttonHWND);
+
+ void WaitCreating() { _dialogCreatedEvent.Lock(); }
+ void CheckNeedClose();
+ bool OnExternalCloseMessage();
+public:
+ CProgressSync Sync;
+ int IconID;
+
+ #ifndef _SFX
+ HWND MainWindow;
+ UString MainTitle;
+ UString MainAddTitle;
+ ~CProgressDialog();
+ #endif
+
+ CProgressDialog(): _timer(0)
+ #ifndef _SFX
+ ,MainWindow(0)
+ #endif
+ {
+ IconID = -1;
+ _wasCreated = false;
+ _needClose = false;
+ _inCancelMessageBox = false;
+ _externalCloseMessageWasReceived = false;
+
+ if (_dialogCreatedEvent.Create() != S_OK)
+ throw 1334987;
+ }
+
+ INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0)
+ {
+ _title = title;
+ INT_PTR res = CModalDialog::Create(IDD_PROGRESS, wndParent);
+ thread.Wait();
+ return res;
+ }
+
+ enum
+ {
+ kCloseMessage = WM_APP + 1
+ };
+
+ virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+
+ void ProcessWasFinished()
+ {
+ WaitCreating();
+ if (_wasCreated)
+ PostMsg(kCloseMessage);
+ else
+ _needClose = true;
+ };
+};
+
+
+class CProgressCloser
+{
+ CProgressDialog *_p;
+public:
+ CProgressCloser(CProgressDialog &p) : _p(&p) {}
+ ~CProgressCloser() { _p->ProcessWasFinished(); }
+};
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.rc b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.rc
new file mode 100644
index 00000000000..55d99233b05
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.rc
@@ -0,0 +1,12 @@
+#include "ProgressDialogRes.h"
+#include "../../GuiCommon.rc"
+
+#define xc 172
+#define yc 44
+
+IDD_PROGRESS DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT
+CAPTION "Progress"
+BEGIN
+ PUSHBUTTON "Cancel", IDCANCEL, bx, by, bxs, bys
+ CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, m, m, xc, 14
+END
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
new file mode 100644
index 00000000000..378ad9035c3
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
@@ -0,0 +1,1319 @@
+// ProgressDialog2.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
+
+#include "../../../Windows/Control/Static.h"
+#include "../../../Windows/ErrorMsg.h"
+
+#include "../GUI/ExtractRes.h"
+
+#include "LangUtils.h"
+
+#include "DialogSize.h"
+#include "ProgressDialog2.h"
+#include "ProgressDialog2Res.h"
+
+using namespace NWindows;
+
+extern HINSTANCE g_hInstance;
+
+static const UINT_PTR kTimerID = 3;
+
+static const UINT kCloseMessage = WM_APP + 1;
+// we can't use WM_USER, since WM_USER can be used by standard Windows procedure for Dialog
+
+static const UINT kTimerElapse =
+ #ifdef UNDER_CE
+ 500
+ #else
+ 200
+ #endif
+ ;
+
+static const UINT kCreateDelay =
+ #ifdef UNDER_CE
+ 2500
+ #else
+ 500
+ #endif
+ ;
+
+static const DWORD kPauseSleepTime = 100;
+
+#ifdef LANG
+
+static const UInt32 kLangIDs[] =
+{
+ IDT_PROGRESS_ELAPSED,
+ IDT_PROGRESS_REMAINING,
+ IDT_PROGRESS_TOTAL,
+ IDT_PROGRESS_SPEED,
+ IDT_PROGRESS_PROCESSED,
+ IDT_PROGRESS_RATIO,
+ IDT_PROGRESS_ERRORS,
+ IDB_PROGRESS_BACKGROUND,
+ IDB_PAUSE
+};
+
+static const UInt32 kLangIDs_Colon[] =
+{
+ IDT_PROGRESS_PACKED,
+ IDT_PROGRESS_FILES
+};
+
+#endif
+
+
+#define UNDEFINED_VAL ((UInt64)(Int64)-1)
+#define INIT_AS_UNDEFINED(v) v = UNDEFINED_VAL;
+#define IS_UNDEFINED_VAL(v) ((v) == UNDEFINED_VAL)
+#define IS_DEFINED_VAL(v) ((v) != UNDEFINED_VAL)
+
+CProgressSync::CProgressSync():
+ _stopped(false), _paused(false),
+ _bytesProgressMode(true),
+ _totalBytes(UNDEFINED_VAL), _completedBytes(0),
+ _totalFiles(UNDEFINED_VAL), _curFiles(0),
+ _inSize(UNDEFINED_VAL),
+ _outSize(UNDEFINED_VAL),
+ _isDir(false)
+ {}
+
+#define CHECK_STOP if (_stopped) return E_ABORT; if (!_paused) return S_OK;
+#define CRITICAL_LOCK NSynchronization::CCriticalSectionLock lock(_cs);
+
+bool CProgressSync::Get_Paused()
+{
+ CRITICAL_LOCK
+ return _paused;
+}
+
+HRESULT CProgressSync::CheckStop()
+{
+ for (;;)
+ {
+ {
+ CRITICAL_LOCK
+ CHECK_STOP
+ }
+ ::Sleep(kPauseSleepTime);
+ }
+}
+
+HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir)
+{
+ {
+ CRITICAL_LOCK
+ _totalFiles = numFiles;
+ _totalBytes = totalSize;
+ _filePath = fs2us(fileName);
+ _isDir = isDir;
+ // _completedBytes = 0;
+ CHECK_STOP
+ }
+ return CheckStop();
+}
+
+HRESULT CProgressSync::Set_NumFilesTotal(UInt64 val)
+{
+ {
+ CRITICAL_LOCK
+ _totalFiles = val;
+ CHECK_STOP
+ }
+ return CheckStop();
+}
+
+void CProgressSync::Set_NumBytesTotal(UInt64 val)
+{
+ CRITICAL_LOCK
+ _totalBytes = val;
+}
+
+void CProgressSync::Set_NumFilesCur(UInt64 val)
+{
+ CRITICAL_LOCK
+ _curFiles = val;
+}
+
+HRESULT CProgressSync::Set_NumBytesCur(const UInt64 *val)
+{
+ {
+ CRITICAL_LOCK
+ if (val)
+ _completedBytes = *val;
+ CHECK_STOP
+ }
+ return CheckStop();
+}
+
+HRESULT CProgressSync::Set_NumBytesCur(UInt64 val)
+{
+ {
+ CRITICAL_LOCK
+ _completedBytes = val;
+ CHECK_STOP
+ }
+ return CheckStop();
+}
+
+void CProgressSync::Set_Ratio(const UInt64 *inSize, const UInt64 *outSize)
+{
+ CRITICAL_LOCK
+ if (inSize)
+ _inSize = *inSize;
+ if (outSize)
+ _outSize = *outSize;
+}
+
+void CProgressSync::Set_TitleFileName(const UString &fileName)
+{
+ CRITICAL_LOCK
+ _titleFileName = fileName;
+}
+
+void CProgressSync::Set_Status(const UString &s)
+{
+ CRITICAL_LOCK
+ _status = s;
+}
+
+HRESULT CProgressSync::Set_Status2(const UString &s, const wchar_t *path, bool isDir)
+{
+ {
+ CRITICAL_LOCK
+ _status = s;
+ if (path)
+ _filePath = path;
+ else
+ _filePath.Empty();
+ _isDir = isDir;
+ }
+ return CheckStop();
+}
+
+void CProgressSync::Set_FilePath(const wchar_t *path, bool isDir)
+{
+ CRITICAL_LOCK
+ if (path)
+ _filePath = path;
+ else
+ _filePath.Empty();
+ _isDir = isDir;
+}
+
+
+void CProgressSync::AddError_Message(const wchar_t *message)
+{
+ CRITICAL_LOCK
+ Messages.Add(message);
+}
+
+void CProgressSync::AddError_Message_Name(const wchar_t *message, const wchar_t *name)
+{
+ UString s;
+ if (name && *name != 0)
+ s += name;
+ if (message && *message != 0 )
+ {
+ if (!s.IsEmpty())
+ s.Add_LF();
+ s += message;
+ if (!s.IsEmpty() && s.Back() == L'\n')
+ s.DeleteBack();
+ }
+ AddError_Message(s);
+}
+
+void CProgressSync::AddError_Code_Name(DWORD systemError, const wchar_t *name)
+{
+ UString s = NError::MyFormatMessage(systemError);
+ if (systemError == 0)
+ s = L"Error";
+ AddError_Message_Name(s, name);
+}
+
+CProgressDialog::CProgressDialog(): _timer(0), CompressingMode(true), MainWindow(0)
+{
+ _isDir = false;
+
+ _numMessages = 0;
+ IconID = -1;
+ MessagesDisplayed = false;
+ _wasCreated = false;
+ _needClose = false;
+ _inCancelMessageBox = false;
+ _externalCloseMessageWasReceived = false;
+
+ _numPostedMessages = 0;
+ _numAutoSizeMessages = 0;
+ _errorsWereDisplayed = false;
+ _waitCloseByCancelButton = false;
+ _cancelWasPressed = false;
+ ShowCompressionInfo = true;
+ WaitMode = false;
+ if (_dialogCreatedEvent.Create() != S_OK)
+ throw 1334987;
+ if (_createDialogEvent.Create() != S_OK)
+ throw 1334987;
+ #ifdef __ITaskbarList3_INTERFACE_DEFINED__
+ CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void**)&_taskbarList);
+ if (_taskbarList)
+ _taskbarList->HrInit();
+ #endif
+}
+
+#ifndef _SFX
+
+CProgressDialog::~CProgressDialog()
+{
+ #ifdef __ITaskbarList3_INTERFACE_DEFINED__
+ SetTaskbarProgressState(TBPF_NOPROGRESS);
+ #endif
+ AddToTitle(L"");
+}
+void CProgressDialog::AddToTitle(LPCWSTR s)
+{
+ if (MainWindow != 0)
+ {
+ CWindow window(MainWindow);
+ window.SetText((UString)s + MainTitle);
+ }
+}
+
+#endif
+
+
+void CProgressDialog::SetTaskbarProgressState()
+{
+ #ifdef __ITaskbarList3_INTERFACE_DEFINED__
+ if (_taskbarList && _hwndForTaskbar)
+ {
+ TBPFLAG tbpFlags;
+ if (Sync.Get_Paused())
+ tbpFlags = TBPF_PAUSED;
+ else
+ tbpFlags = _errorsWereDisplayed ? TBPF_ERROR: TBPF_NORMAL;
+ SetTaskbarProgressState(tbpFlags);
+ }
+ #endif
+}
+
+static const unsigned kTitleFileNameSizeLimit = 36;
+static const unsigned kCurrentFileNameSizeLimit = 82;
+
+static void ReduceString(UString &s, unsigned size)
+{
+ if (s.Len() <= size)
+ return;
+ s.Delete(size / 2, s.Len() - size);
+ s.Insert(size / 2, L" ... ");
+}
+
+void CProgressDialog::EnableErrorsControls(bool enable)
+{
+ ShowItem_Bool(IDT_PROGRESS_ERRORS, enable);
+ ShowItem_Bool(IDT_PROGRESS_ERRORS_VAL, enable);
+ ShowItem_Bool(IDL_PROGRESS_MESSAGES, enable);
+}
+
+bool CProgressDialog::OnInit()
+{
+ _hwndForTaskbar = MainWindow;
+ if (!_hwndForTaskbar)
+ _hwndForTaskbar = GetParent();
+ if (!_hwndForTaskbar)
+ _hwndForTaskbar = *this;
+
+ INIT_AS_UNDEFINED(_progressBar_Range);
+ INIT_AS_UNDEFINED(_progressBar_Pos);
+
+ INIT_AS_UNDEFINED(_prevPercentValue);
+ INIT_AS_UNDEFINED(_prevElapsedSec);
+ INIT_AS_UNDEFINED(_prevRemainingSec);
+
+ INIT_AS_UNDEFINED(_prevSpeed);
+ _prevSpeed_MoveBits = 0;
+
+ _prevTime = ::GetTickCount();
+ _elapsedTime = 0;
+
+ INIT_AS_UNDEFINED(_totalBytes_Prev);
+ INIT_AS_UNDEFINED(_processed_Prev);
+ INIT_AS_UNDEFINED(_packed_Prev);
+ INIT_AS_UNDEFINED(_ratio_Prev);
+ _filesStr_Prev.Empty();
+
+ _foreground = true;
+
+ m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
+ _messageList.Attach(GetItem(IDL_PROGRESS_MESSAGES));
+ _messageList.SetUnicodeFormat();
+
+ _wasCreated = true;
+ _dialogCreatedEvent.Set();
+
+ #ifdef LANG
+ LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
+ LangSetDlgItems_Colon(*this, kLangIDs_Colon, ARRAY_SIZE(kLangIDs_Colon));
+ #endif
+
+ CWindow window(GetItem(IDB_PROGRESS_BACKGROUND));
+ window.GetText(_background_String);
+ _backgrounded_String = _background_String;
+ _backgrounded_String.RemoveChar(L'&');
+
+ window = GetItem(IDB_PAUSE);
+ window.GetText(_pause_String);
+
+ LangString(IDS_PROGRESS_FOREGROUND, _foreground_String);
+ LangString(IDS_CONTINUE, _continue_String);
+ LangString(IDS_PROGRESS_PAUSED, _paused_String);
+
+ SetText(_title);
+ SetPauseText();
+ SetPriorityText();
+
+ _messageList.InsertColumn(0, L"", 30);
+ _messageList.InsertColumn(1, L"", 600);
+
+ _messageList.SetColumnWidthAuto(0);
+ _messageList.SetColumnWidthAuto(1);
+
+ EnableErrorsControls(false);
+
+ GetItemSizes(IDCANCEL, _buttonSizeX, _buttonSizeY);
+ _numReduceSymbols = kCurrentFileNameSizeLimit;
+ NormalizeSize(true);
+
+ if (!ShowCompressionInfo)
+ {
+ HideItem(IDT_PROGRESS_PACKED);
+ HideItem(IDT_PROGRESS_PACKED_VAL);
+ HideItem(IDT_PROGRESS_RATIO);
+ HideItem(IDT_PROGRESS_RATIO_VAL);
+ }
+
+ if (IconID >= 0)
+ {
+ HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IconID));
+ // SetIcon(ICON_SMALL, icon);
+ SetIcon(ICON_BIG, icon);
+ }
+ _timer = SetTimer(kTimerID, kTimerElapse);
+ #ifdef UNDER_CE
+ Foreground();
+ #endif
+
+ CheckNeedClose();
+
+ SetTaskbarProgressState();
+
+ return CModalDialog::OnInit();
+}
+
+static const UINT kIDs[] =
+{
+ IDT_PROGRESS_ELAPSED, IDT_PROGRESS_ELAPSED_VAL,
+ IDT_PROGRESS_REMAINING, IDT_PROGRESS_REMAINING_VAL,
+ IDT_PROGRESS_FILES, IDT_PROGRESS_FILES_VAL,
+ IDT_PROGRESS_RATIO, IDT_PROGRESS_RATIO_VAL,
+ IDT_PROGRESS_ERRORS, IDT_PROGRESS_ERRORS_VAL,
+
+ IDT_PROGRESS_TOTAL, IDT_PROGRESS_TOTAL_VAL,
+ IDT_PROGRESS_SPEED, IDT_PROGRESS_SPEED_VAL,
+ IDT_PROGRESS_PROCESSED, IDT_PROGRESS_PROCESSED_VAL,
+ IDT_PROGRESS_PACKED, IDT_PROGRESS_PACKED_VAL
+};
+
+bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
+{
+ int sY;
+ int sStep;
+ int mx, my;
+ {
+ RECT r;
+ GetClientRectOfItem(IDT_PROGRESS_ELAPSED, r);
+ mx = r.left;
+ my = r.top;
+ sY = RECT_SIZE_Y(r);
+ GetClientRectOfItem(IDT_PROGRESS_REMAINING, r);
+ sStep = r.top - my;
+ }
+
+ InvalidateRect(NULL);
+
+ int xSizeClient = xSize - mx * 2;
+
+ {
+ int i;
+ for (i = 800; i > 40; i = i * 9 / 10)
+ if (Units_To_Pixels_X(i) <= xSizeClient)
+ break;
+ _numReduceSymbols = i / 4;
+ }
+
+ int yPos = ySize - my - _buttonSizeY;
+
+ ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_STATUS), xSize - mx * 2);
+ ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_FILE_NAME), xSize - mx * 2);
+ ChangeSubWindowSizeX(GetItem(IDC_PROGRESS1), xSize - mx * 2);
+
+ int bSizeX = _buttonSizeX;
+ int mx2 = mx;
+ for (;; mx2--)
+ {
+ int bSize2 = bSizeX * 3 + mx2 * 2;
+ if (bSize2 <= xSizeClient)
+ break;
+ if (mx2 < 5)
+ {
+ bSizeX = (xSizeClient - mx2 * 2) / 3;
+ break;
+ }
+ }
+ if (bSizeX < 2)
+ bSizeX = 2;
+
+ {
+ RECT r;
+ GetClientRectOfItem(IDL_PROGRESS_MESSAGES, r);
+ int y = r.top;
+ int ySize2 = yPos - my - y;
+ const int kMinYSize = _buttonSizeY + _buttonSizeY * 3 / 4;
+ int xx = xSize - mx * 2;
+ if (ySize2 < kMinYSize)
+ {
+ ySize2 = kMinYSize;
+ if (xx > bSizeX * 2)
+ xx -= bSizeX;
+ }
+
+ _messageList.Move(mx, y, xx, ySize2);
+ }
+
+ {
+ int xPos = xSize - mx;
+ xPos -= bSizeX;
+ MoveItem(IDCANCEL, xPos, yPos, bSizeX, _buttonSizeY);
+ xPos -= (mx2 + bSizeX);
+ MoveItem(IDB_PAUSE, xPos, yPos, bSizeX, _buttonSizeY);
+ xPos -= (mx2 + bSizeX);
+ MoveItem(IDB_PROGRESS_BACKGROUND, xPos, yPos, bSizeX, _buttonSizeY);
+ }
+
+ int valueSize;
+ int labelSize;
+ int padSize;
+
+ labelSize = Units_To_Pixels_X(MY_PROGRESS_LABEL_UNITS_MIN);
+ valueSize = Units_To_Pixels_X(MY_PROGRESS_VAL_UNITS);
+ padSize = Units_To_Pixels_X(MY_PROGRESS_PAD_UNITS);
+ int requiredSize = (labelSize + valueSize) * 2 + padSize;
+
+ int gSize;
+ {
+ if (requiredSize < xSizeClient)
+ {
+ int incr = (xSizeClient - requiredSize) / 3;
+ labelSize += incr;
+ }
+ else
+ labelSize = (xSizeClient - valueSize * 2 - padSize) / 2;
+ if (labelSize < 0)
+ labelSize = 0;
+
+ gSize = labelSize + valueSize;
+ padSize = xSizeClient - gSize * 2;
+ }
+
+ labelSize = gSize - valueSize;
+
+ yPos = my;
+ for (int i = 0; i < ARRAY_SIZE(kIDs); i += 2)
+ {
+ int x = mx;
+ const int kNumColumn1Items = 5 * 2;
+ if (i >= kNumColumn1Items)
+ {
+ if (i == kNumColumn1Items)
+ yPos = my;
+ x = mx + gSize + padSize;
+ }
+ MoveItem(kIDs[i], x, yPos, labelSize, sY);
+ MoveItem(kIDs[i + 1], x + labelSize, yPos, valueSize, sY);
+ yPos += sStep;
+ }
+ return false;
+}
+
+void CProgressDialog::OnCancel() { Sync.Set_Stopped(true); }
+void CProgressDialog::OnOK() { }
+
+void CProgressDialog::SetProgressRange(UInt64 range)
+{
+ if (range == _progressBar_Range)
+ return;
+ _progressBar_Range = range;
+ INIT_AS_UNDEFINED(_progressBar_Pos);
+ _progressConv.Init(range);
+ m_ProgressBar.SetRange32(0, _progressConv.Count(range));
+}
+
+void CProgressDialog::SetProgressPos(UInt64 pos)
+{
+ if (pos >= _progressBar_Range ||
+ pos <= _progressBar_Pos ||
+ pos - _progressBar_Pos >= (_progressBar_Range >> 10))
+ {
+ m_ProgressBar.SetPos(_progressConv.Count(pos));
+ #ifdef __ITaskbarList3_INTERFACE_DEFINED__
+ if (_taskbarList && _hwndForTaskbar)
+ _taskbarList->SetProgressValue(_hwndForTaskbar, pos, _progressBar_Range);
+ #endif
+ _progressBar_Pos = pos;
+ }
+}
+
+#define UINT_TO_STR_2(val) { s[0] = (wchar_t)('0' + (val) / 10); s[1] = (wchar_t)('0' + (val) % 10); s += 2; }
+
+void GetTimeString(UInt64 timeValue, wchar_t *s)
+{
+ UInt64 hours = timeValue / 3600;
+ UInt32 seconds = (UInt32)(timeValue - hours * 3600);
+ UInt32 minutes = seconds / 60;
+ seconds %= 60;
+ if (hours > 99)
+ {
+ ConvertUInt64ToString(hours, s);
+ for (; *s != 0; s++);
+ }
+ else
+ {
+ UInt32 hours32 = (UInt32)hours;
+ UINT_TO_STR_2(hours32);
+ }
+ *s++ = ':'; UINT_TO_STR_2(minutes);
+ *s++ = ':'; UINT_TO_STR_2(seconds);
+ *s = 0;
+}
+
+static void ConvertSizeToString(UInt64 v, wchar_t *s)
+{
+ Byte c = 0;
+ if (v >= ((UInt64)100000 << 20)) { v >>= 30; c = 'G'; }
+ else if (v >= ((UInt64)100000 << 10)) { v >>= 20; c = 'M'; }
+ else if (v >= ((UInt64)100000 << 0)) { v >>= 10; c = 'K'; }
+ ConvertUInt64ToString(v, s);
+ if (c != 0)
+ {
+ s += MyStringLen(s);
+ *s++ = ' ';
+ *s++ = c;
+ *s++ = 0;
+ }
+}
+
+void CProgressDialog::ShowSize(int id, UInt64 val, UInt64 &prev)
+{
+ if (val == prev)
+ return;
+ prev = val;
+ wchar_t s[40];
+ s[0] = 0;
+ if (IS_DEFINED_VAL(val))
+ ConvertSizeToString(val, s);
+ SetItemText(id, s);
+}
+
+static void GetChangedString(const UString &newStr, UString &prevStr, bool &hasChanged)
+{
+ hasChanged = !(prevStr == newStr);
+ if (hasChanged)
+ prevStr = newStr;
+}
+
+static unsigned GetPower32(UInt32 val)
+{
+ const unsigned kStart = 32;
+ UInt32 mask = ((UInt32)1 << (kStart - 1));
+ for (unsigned i = kStart;; i--)
+ {
+ if (i == 0 || (val & mask) != 0)
+ return i;
+ mask >>= 1;
+ }
+}
+
+static unsigned GetPower64(UInt64 val)
+{
+ UInt32 high = (UInt32)(val >> 32);
+ if (high == 0)
+ return GetPower32((UInt32)val);
+ return GetPower32(high) + 32;
+}
+
+static UInt64 MyMultAndDiv(UInt64 mult1, UInt64 mult2, UInt64 divider)
+{
+ unsigned pow1 = GetPower64(mult1);
+ unsigned pow2 = GetPower64(mult2);
+ while (pow1 + pow2 > 64)
+ {
+ if (pow1 > pow2) { pow1--; mult1 >>= 1; }
+ else { pow2--; mult2 >>= 1; }
+ divider >>= 1;
+ }
+ UInt64 res = mult1 * mult2;
+ if (divider != 0)
+ res /= divider;
+ return res;
+}
+
+void CProgressDialog::UpdateStatInfo(bool showAll)
+{
+ UInt64 total, completed, totalFiles, completedFiles, inSize, outSize;
+ bool bytesProgressMode;
+
+ bool titleFileName_Changed;
+ bool curFilePath_Changed;
+ bool status_Changed;
+ unsigned numErrors;
+ {
+ NSynchronization::CCriticalSectionLock lock(Sync._cs);
+ total = Sync._totalBytes;
+ completed = Sync._completedBytes;
+ totalFiles = Sync._totalFiles;
+ completedFiles = Sync._curFiles;
+ inSize = Sync._inSize;
+ outSize = Sync._outSize;
+ bytesProgressMode = Sync._bytesProgressMode;
+
+ GetChangedString(Sync._titleFileName, _titleFileName, titleFileName_Changed);
+ GetChangedString(Sync._filePath, _filePath, curFilePath_Changed);
+ GetChangedString(Sync._status, _status, status_Changed);
+ if (_isDir != Sync._isDir)
+ {
+ curFilePath_Changed = true;
+ _isDir = Sync._isDir;
+ }
+ numErrors = Sync.Messages.Size();
+ }
+
+ UInt32 curTime = ::GetTickCount();
+
+ const UInt64 progressTotal = bytesProgressMode ? total : totalFiles;
+ const UInt64 progressCompleted = bytesProgressMode ? completed : completedFiles;
+ {
+ if (IS_UNDEFINED_VAL(progressTotal))
+ {
+ // SetPos(0);
+ // SetRange(progressCompleted);
+ }
+ else
+ {
+ if (_progressBar_Pos != 0 || progressCompleted != 0 ||
+ (_progressBar_Range == 0 && progressTotal != 0))
+ {
+ SetProgressRange(progressTotal);
+ SetProgressPos(progressCompleted);
+ }
+ }
+ }
+
+ ShowSize(IDT_PROGRESS_TOTAL_VAL, total, _totalBytes_Prev);
+
+ _elapsedTime += (curTime - _prevTime);
+ _prevTime = curTime;
+ UInt64 elapsedSec = _elapsedTime / 1000;
+ bool elapsedChanged = false;
+ if (elapsedSec != _prevElapsedSec)
+ {
+ _prevElapsedSec = elapsedSec;
+ elapsedChanged = true;
+ wchar_t s[40];
+ GetTimeString(elapsedSec, s);
+ SetItemText(IDT_PROGRESS_ELAPSED_VAL, s);
+ }
+
+ bool needSetTitle = false;
+ if (elapsedChanged || showAll)
+ {
+ if (numErrors > _numPostedMessages)
+ {
+ UpdateMessagesDialog();
+ wchar_t s[32];
+ ConvertUInt64ToString(numErrors, s);
+ SetItemText(IDT_PROGRESS_ERRORS_VAL, s);
+ if (!_errorsWereDisplayed)
+ {
+ _errorsWereDisplayed = true;
+ EnableErrorsControls(true);
+ SetTaskbarProgressState();
+ }
+ }
+
+ if (progressCompleted != 0)
+ {
+ if (IS_UNDEFINED_VAL(progressTotal))
+ {
+ if (IS_DEFINED_VAL(_prevRemainingSec))
+ {
+ INIT_AS_UNDEFINED(_prevRemainingSec);
+ SetItemText(IDT_PROGRESS_REMAINING_VAL, L"");
+ }
+ }
+ else
+ {
+ UInt64 remainingTime = 0;
+ if (progressCompleted < progressTotal)
+ remainingTime = MyMultAndDiv(_elapsedTime, progressTotal - progressCompleted, progressCompleted);
+ UInt64 remainingSec = remainingTime / 1000;
+ if (remainingSec != _prevRemainingSec)
+ {
+ _prevRemainingSec = remainingSec;
+ wchar_t s[40];
+ GetTimeString(remainingSec, s);
+ SetItemText(IDT_PROGRESS_REMAINING_VAL, s);
+ }
+ }
+ {
+ UInt64 elapsedTime = (_elapsedTime == 0) ? 1 : _elapsedTime;
+ UInt64 v = (progressCompleted * 1000) / elapsedTime;
+ Byte c = 0;
+ unsigned moveBits = 0;
+ if (v >= ((UInt64)10000 << 10)) { moveBits = 20; c = 'M'; }
+ else if (v >= ((UInt64)10000 << 0)) { moveBits = 10; c = 'K'; }
+ v >>= moveBits;
+ if (moveBits != _prevSpeed_MoveBits || v != _prevSpeed)
+ {
+ _prevSpeed_MoveBits = moveBits;
+ _prevSpeed = v;
+ wchar_t s[40];
+ ConvertUInt64ToString(v, s);
+ unsigned pos = MyStringLen(s);
+ s[pos++] = ' ';
+ if (moveBits != 0)
+ s[pos++] = c;
+ s[pos++] = 'B';
+ s[pos++] = '/';
+ s[pos++] = 's';
+ s[pos++] = 0;
+ SetItemText(IDT_PROGRESS_SPEED_VAL, s);
+ }
+ }
+ }
+
+ {
+ UInt64 percent = 0;
+ {
+ if (IS_DEFINED_VAL(progressTotal))
+ {
+ percent = progressCompleted * 100;
+ if (progressTotal != 0)
+ percent /= progressTotal;
+ }
+ }
+ if (percent != _prevPercentValue)
+ {
+ _prevPercentValue = percent;
+ needSetTitle = true;
+ }
+ }
+
+ {
+ wchar_t s[64];
+ ConvertUInt64ToString(completedFiles, s);
+ if (IS_DEFINED_VAL(totalFiles))
+ {
+ wcscat(s, L" / ");
+ ConvertUInt64ToString(totalFiles, s + wcslen(s));
+ }
+ if (_filesStr_Prev != s)
+ {
+ _filesStr_Prev = s;
+ SetItemText(IDT_PROGRESS_FILES_VAL, s);
+ }
+ }
+
+ const UInt64 packSize = CompressingMode ? outSize : inSize;
+ const UInt64 unpackSize = CompressingMode ? inSize : outSize;
+
+ if (IS_UNDEFINED_VAL(unpackSize) &&
+ IS_UNDEFINED_VAL(packSize))
+ {
+ ShowSize(IDT_PROGRESS_PROCESSED_VAL, completed, _processed_Prev);
+ ShowSize(IDT_PROGRESS_PACKED_VAL, UNDEFINED_VAL, _packed_Prev);
+ }
+ else
+ {
+ ShowSize(IDT_PROGRESS_PROCESSED_VAL, unpackSize, _processed_Prev);
+ ShowSize(IDT_PROGRESS_PACKED_VAL, packSize, _packed_Prev);
+
+ if (IS_DEFINED_VAL(packSize) &&
+ IS_DEFINED_VAL(unpackSize) &&
+ unpackSize != 0)
+ {
+ wchar_t s[32];
+ UInt64 ratio = packSize * 100 / unpackSize;
+ if (_ratio_Prev != ratio)
+ {
+ _ratio_Prev = ratio;
+ ConvertUInt64ToString(ratio, s);
+ wcscat(s, L"%");
+ SetItemText(IDT_PROGRESS_RATIO_VAL, s);
+ }
+ }
+ }
+ }
+
+ if (needSetTitle || titleFileName_Changed)
+ SetTitleText();
+
+ if (status_Changed)
+ {
+ UString s = _status;
+ ReduceString(s, _numReduceSymbols);
+ SetItemText(IDT_PROGRESS_STATUS, _status);
+ }
+
+ if (curFilePath_Changed)
+ {
+ UString s1, s2;
+ if (_isDir)
+ s1 = _filePath;
+ else
+ {
+ int slashPos = _filePath.ReverseFind_PathSepar();
+ if (slashPos >= 0)
+ {
+ s1.SetFrom(_filePath, slashPos + 1);
+ s2 = _filePath.Ptr(slashPos + 1);
+ }
+ else
+ s2 = _filePath;
+ }
+ ReduceString(s1, _numReduceSymbols);
+ ReduceString(s2, _numReduceSymbols);
+ s1.Add_LF();
+ s1 += s2;
+ SetItemText(IDT_PROGRESS_FILE_NAME, s1);
+ }
+}
+
+bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
+{
+ if (Sync.Get_Paused())
+ return true;
+ CheckNeedClose();
+ UpdateStatInfo(false);
+ return true;
+}
+
+struct CWaitCursor
+{
+ HCURSOR _waitCursor;
+ HCURSOR _oldCursor;
+ CWaitCursor()
+ {
+ _waitCursor = LoadCursor(NULL, IDC_WAIT);
+ if (_waitCursor != NULL)
+ _oldCursor = SetCursor(_waitCursor);
+ }
+ ~CWaitCursor()
+ {
+ if (_waitCursor != NULL)
+ SetCursor(_oldCursor);
+ }
+};
+
+INT_PTR CProgressDialog::Create(const UString &title, NWindows::CThread &thread, HWND wndParent)
+{
+ INT_PTR res = 0;
+ try
+ {
+ if (WaitMode)
+ {
+ CWaitCursor waitCursor;
+ HANDLE h[] = { thread, _createDialogEvent };
+
+ WRes res = WaitForMultipleObjects(ARRAY_SIZE(h), h, FALSE, kCreateDelay);
+ if (res == WAIT_OBJECT_0 && !Sync.ThereIsMessage())
+ return 0;
+ }
+ _title = title;
+ BIG_DIALOG_SIZE(360, 192);
+ res = CModalDialog::Create(SIZED_DIALOG(IDD_PROGRESS), wndParent);
+ }
+ catch(...)
+ {
+ _wasCreated = true;
+ _dialogCreatedEvent.Set();
+ res = res;
+ }
+ thread.Wait();
+ if (!MessagesDisplayed)
+ MessageBoxW(wndParent, L"Progress Error", L"7-Zip", MB_ICONERROR);
+ return res;
+}
+
+bool CProgressDialog::OnExternalCloseMessage()
+{
+ // it doesn't work if there is MessageBox.
+ #ifdef __ITaskbarList3_INTERFACE_DEFINED__
+ SetTaskbarProgressState(TBPF_NOPROGRESS);
+ #endif
+ // AddToTitle(L"Finished ");
+ // SetText(L"Finished2 ");
+
+ UpdateStatInfo(true);
+
+ SetItemText(IDCANCEL, LangString(IDS_CLOSE));
+ ::SendMessage(GetItem(IDCANCEL), BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0));
+ HideItem(IDB_PROGRESS_BACKGROUND);
+ HideItem(IDB_PAUSE);
+
+ bool thereAreMessages;
+ CProgressFinalMessage fm;
+ {
+ NSynchronization::CCriticalSectionLock lock(Sync._cs);
+ 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";
+ 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";
+ MessageBoxW(*this, fm.OkMessage.Message, fm.OkMessage.Title, MB_OK);
+ }
+ }
+
+ if (thereAreMessages && !_cancelWasPressed)
+ {
+ _waitCloseByCancelButton = true;
+ UpdateMessagesDialog();
+ return true;
+ }
+
+ End(0);
+ return true;
+}
+
+bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case kCloseMessage:
+ {
+ KillTimer(_timer);
+ _timer = 0;
+ if (_inCancelMessageBox)
+ {
+ _externalCloseMessageWasReceived = true;
+ break;
+ }
+ return OnExternalCloseMessage();
+ }
+ /*
+ case WM_SETTEXT:
+ {
+ if (_timer == 0)
+ return true;
+ break;
+ }
+ */
+ }
+ return CModalDialog::OnMessage(message, wParam, lParam);
+}
+
+void CProgressDialog::SetTitleText()
+{
+ UString s;
+ if (Sync.Get_Paused())
+ {
+ s += _paused_String;
+ s.Add_Space();
+ }
+ if (IS_DEFINED_VAL(_prevPercentValue))
+ {
+ char temp[32];
+ ConvertUInt64ToString(_prevPercentValue, temp);
+ s.AddAscii(temp);
+ s += L'%';
+ }
+ if (!_foreground)
+ {
+ s.Add_Space();
+ s += _backgrounded_String;
+ }
+
+ s.Add_Space();
+ #ifndef _SFX
+ {
+ unsigned len = s.Len();
+ s += MainAddTitle;
+ AddToTitle(s);
+ s.DeleteFrom(len);
+ }
+ #endif
+
+ s += _title;
+ if (!_titleFileName.IsEmpty())
+ {
+ UString fileName = _titleFileName;
+ ReduceString(fileName, kTitleFileNameSizeLimit);
+ s.Add_Space();
+ s += fileName;
+ }
+ SetText(s);
+}
+
+void CProgressDialog::SetPauseText()
+{
+ SetItemText(IDB_PAUSE, Sync.Get_Paused() ? _continue_String : _pause_String);
+ SetTitleText();
+}
+
+void CProgressDialog::OnPauseButton()
+{
+ bool paused = !Sync.Get_Paused();
+ Sync.Set_Paused(paused);
+ UInt32 curTime = ::GetTickCount();
+ if (paused)
+ _elapsedTime += (curTime - _prevTime);
+ SetTaskbarProgressState();
+ _prevTime = curTime;
+ SetPauseText();
+}
+
+void CProgressDialog::SetPriorityText()
+{
+ SetItemText(IDB_PROGRESS_BACKGROUND, _foreground ?
+ _background_String :
+ _foreground_String);
+ SetTitleText();
+}
+
+void CProgressDialog::OnPriorityButton()
+{
+ _foreground = !_foreground;
+ #ifndef UNDER_CE
+ SetPriorityClass(GetCurrentProcess(), _foreground ? NORMAL_PRIORITY_CLASS: IDLE_PRIORITY_CLASS);
+ #endif
+ SetPriorityText();
+}
+
+void CProgressDialog::AddMessageDirect(LPCWSTR message, bool needNumber)
+{
+ int itemIndex = _messageList.GetItemCount();
+ wchar_t sz[16];
+ sz[0] = 0;
+ if (needNumber)
+ ConvertUInt32ToString(_numMessages + 1, sz);
+ _messageList.InsertItem(itemIndex, sz);
+ _messageList.SetSubItem(itemIndex, 1, message);
+}
+
+void CProgressDialog::AddMessage(LPCWSTR message)
+{
+ UString s = message;
+ bool needNumber = true;
+ while (!s.IsEmpty())
+ {
+ int pos = s.Find(L'\n');
+ if (pos < 0)
+ break;
+ AddMessageDirect(s.Left(pos), needNumber);
+ needNumber = false;
+ s.DeleteFrontal(pos + 1);
+ }
+ AddMessageDirect(s, needNumber);
+ _numMessages++;
+}
+
+static unsigned GetNumDigits(UInt32 val)
+{
+ unsigned i;
+ for (i = 0; val >= 10; i++)
+ val /= 10;
+ return i;
+}
+
+void CProgressDialog::UpdateMessagesDialog()
+{
+ UStringVector messages;
+ {
+ NSynchronization::CCriticalSectionLock lock(Sync._cs);
+ unsigned num = Sync.Messages.Size();
+ if (num > _numPostedMessages)
+ {
+ messages.ClearAndReserve(num - _numPostedMessages);
+ for (unsigned i = _numPostedMessages; i < num; i++)
+ messages.AddInReserved(Sync.Messages[i]);
+ _numPostedMessages = num;
+ }
+ }
+ if (!messages.IsEmpty())
+ {
+ FOR_VECTOR (i, messages)
+ AddMessage(messages[i]);
+ if (_numAutoSizeMessages < 256 || GetNumDigits(_numPostedMessages) > GetNumDigits(_numAutoSizeMessages))
+ {
+ _messageList.SetColumnWidthAuto(0);
+ _messageList.SetColumnWidthAuto(1);
+ _numAutoSizeMessages = _numPostedMessages;
+ }
+ }
+}
+
+
+bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch (buttonID)
+ {
+ // case IDOK: // if IDCANCEL is not DEFPUSHBUTTON
+ case IDCANCEL:
+ {
+ if (_waitCloseByCancelButton)
+ {
+ MessagesDisplayed = true;
+ End(IDCLOSE);
+ break;
+ }
+
+ bool paused = Sync.Get_Paused();
+ if (!paused)
+ OnPauseButton();
+ _inCancelMessageBox = true;
+ int res = ::MessageBoxW(*this, LangString(IDS_PROGRESS_ASK_CANCEL), _title, MB_YESNOCANCEL);
+ _inCancelMessageBox = false;
+ if (!paused)
+ OnPauseButton();
+ if (res == IDCANCEL || res == IDNO)
+ {
+ if (_externalCloseMessageWasReceived)
+ OnExternalCloseMessage();
+ return true;
+ }
+
+ _cancelWasPressed = true;
+ MessagesDisplayed = true;
+ break;
+ }
+
+ case IDB_PAUSE:
+ OnPauseButton();
+ return true;
+ case IDB_PROGRESS_BACKGROUND:
+ OnPriorityButton();
+ return true;
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
+
+void CProgressDialog::CheckNeedClose()
+{
+ if (_needClose)
+ {
+ PostMsg(kCloseMessage);
+ _needClose = false;
+ }
+}
+
+void CProgressDialog::ProcessWasFinished()
+{
+ // Set Window title here.
+ if (!WaitMode)
+ WaitCreating();
+
+ if (_wasCreated)
+ PostMsg(kCloseMessage);
+ else
+ _needClose = true;
+}
+
+
+HRESULT CProgressThreadVirt::Create(const UString &title, HWND parentWindow)
+{
+ NWindows::CThread thread;
+ RINOK(thread.Create(MyThreadFunction, this));
+ ProgressDialog.Create(title, thread, parentWindow);
+ return S_OK;
+}
+
+static void AddMessageToString(UString &dest, const UString &src)
+{
+ if (!src.IsEmpty())
+ {
+ if (!dest.IsEmpty())
+ dest.Add_LF();
+ dest += src;
+ }
+}
+
+void CProgressThreadVirt::Process()
+{
+ CProgressCloser closer(ProgressDialog);
+ UString m;
+ try { Result = ProcessVirt(); }
+ catch(const wchar_t *s) { m = s; }
+ catch(const UString &s) { m = s; }
+ catch(const char *s) { m = GetUnicodeString(s); }
+ catch(int v)
+ {
+ wchar_t s[16];
+ ConvertUInt32ToString(v, s);
+ m = L"Error #";
+ m += s;
+ }
+ catch(...) { m = L"Error"; }
+ if (Result != E_ABORT)
+ {
+ if (m.IsEmpty() && Result != S_OK)
+ m = HResultToMessage(Result);
+ }
+ AddMessageToString(m, FinalMessage.ErrorMessage.Message);
+
+ {
+ FOR_VECTOR(i, ErrorPaths)
+ {
+ if (i >= 32)
+ break;
+ AddMessageToString(m, fs2us(ErrorPaths[i]));
+ }
+ }
+
+ CProgressSync &sync = ProgressDialog.Sync;
+ NSynchronization::CCriticalSectionLock lock(sync._cs);
+ if (m.IsEmpty())
+ {
+ if (!FinalMessage.OkMessage.Message.IsEmpty())
+ sync.FinalMessage.OkMessage = FinalMessage.OkMessage;
+ }
+ else
+ {
+ sync.FinalMessage.ErrorMessage.Message = m;
+ if (Result == S_OK)
+ Result = E_FAIL;
+ }
+}
+
+UString HResultToMessage(HRESULT errorCode)
+{
+ if (errorCode == E_OUTOFMEMORY)
+ return LangString(IDS_MEM_ERROR);
+ else
+ return NError::MyFormatMessage(errorCode);
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.h
new file mode 100644
index 00000000000..03f836da219
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.h
@@ -0,0 +1,313 @@
+// ProgressDialog2.h
+
+#ifndef __PROGRESS_DIALOG_2_H
+#define __PROGRESS_DIALOG_2_H
+
+#include "../../../Common/MyCom.h"
+
+#include "../../../Windows/ErrorMsg.h"
+#include "../../../Windows/Synchronization.h"
+#include "../../../Windows/Thread.h"
+
+#include "../../../Windows/Control/Dialog.h"
+#include "../../../Windows/Control/ListView.h"
+#include "../../../Windows/Control/ProgressBar.h"
+
+#include "MyWindowsNew.h"
+
+struct CProgressMessageBoxPair
+{
+ UString Title;
+ UString Message;
+};
+
+struct CProgressFinalMessage
+{
+ CProgressMessageBoxPair ErrorMessage;
+ CProgressMessageBoxPair OkMessage;
+
+ bool ThereIsMessage() const { return !ErrorMessage.Message.IsEmpty() || !OkMessage.Message.IsEmpty(); }
+};
+
+class CProgressSync
+{
+ bool _stopped;
+ bool _paused;
+
+public:
+ bool _bytesProgressMode;
+ UInt64 _totalBytes;
+ UInt64 _completedBytes;
+ UInt64 _totalFiles;
+ UInt64 _curFiles;
+ UInt64 _inSize;
+ UInt64 _outSize;
+
+ UString _titleFileName;
+ UString _status;
+ UString _filePath;
+ bool _isDir;
+
+ UStringVector Messages;
+ CProgressFinalMessage FinalMessage;
+
+ NWindows::NSynchronization::CCriticalSection _cs;
+
+ CProgressSync();
+
+ bool Get_Stopped()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
+ return _stopped;
+ }
+ void Set_Stopped(bool val)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
+ _stopped = val;
+ }
+
+ bool Get_Paused();
+ void Set_Paused(bool val)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
+ _paused = val;
+ }
+
+ void Set_BytesProgressMode(bool bytesProgressMode)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
+ _bytesProgressMode = bytesProgressMode;
+ }
+
+ HRESULT CheckStop();
+ HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir = false);
+
+ HRESULT Set_NumFilesTotal(UInt64 val);
+ void Set_NumBytesTotal(UInt64 val);
+ void Set_NumFilesCur(UInt64 val);
+ HRESULT Set_NumBytesCur(const UInt64 *val);
+ HRESULT Set_NumBytesCur(UInt64 val);
+ void Set_Ratio(const UInt64 *inSize, const UInt64 *outSize);
+
+ void Set_TitleFileName(const UString &fileName);
+ void Set_Status(const UString &s);
+ HRESULT Set_Status2(const UString &s, const wchar_t *path, bool isDir = false);
+ void Set_FilePath(const wchar_t *path, bool isDir = false);
+
+ void AddError_Message(const wchar_t *message);
+ void AddError_Message_Name(const wchar_t *message, const wchar_t *name);
+ void AddError_Code_Name(DWORD systemError, const wchar_t *name);
+
+ bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); }
+};
+
+class CProgressDialog: public NWindows::NControl::CModalDialog
+{
+ UString _titleFileName;
+ UString _filePath;
+ UString _status;
+ bool _isDir;
+
+ UString _background_String;
+ UString _backgrounded_String;
+ UString _foreground_String;
+ UString _pause_String;
+ UString _continue_String;
+ UString _paused_String;
+
+ int _buttonSizeX;
+ int _buttonSizeY;
+
+ UINT_PTR _timer;
+
+ UString _title;
+
+ class CU64ToI32Converter
+ {
+ unsigned _numShiftBits;
+ UInt64 _range;
+ public:
+ CU64ToI32Converter(): _numShiftBits(0), _range(1) {}
+ void Init(UInt64 range)
+ {
+ _range = range;
+ // Windows CE doesn't like big number for ProgressBar.
+ for (_numShiftBits = 0; range >= ((UInt32)1 << 15); _numShiftBits++)
+ range >>= 1;
+ }
+ int Count(UInt64 val)
+ {
+ int res = (int)(val >> _numShiftBits);
+ if (val == _range)
+ res++;
+ return res;
+ }
+ };
+
+ CU64ToI32Converter _progressConv;
+ UInt64 _progressBar_Pos;
+ UInt64 _progressBar_Range;
+
+ NWindows::NControl::CProgressBar m_ProgressBar;
+ NWindows::NControl::CListView _messageList;
+
+ int _numMessages;
+
+ #ifdef __ITaskbarList3_INTERFACE_DEFINED__
+ CMyComPtr<ITaskbarList3> _taskbarList;
+ #endif
+ HWND _hwndForTaskbar;
+
+ UInt32 _prevTime;
+ UInt64 _elapsedTime;
+
+ UInt64 _prevPercentValue;
+ UInt64 _prevElapsedSec;
+ UInt64 _prevRemainingSec;
+
+ UInt64 _totalBytes_Prev;
+ UInt64 _processed_Prev;
+ UInt64 _packed_Prev;
+ UInt64 _ratio_Prev;
+ UString _filesStr_Prev;
+
+ unsigned _prevSpeed_MoveBits;
+ UInt64 _prevSpeed;
+
+ bool _foreground;
+
+ unsigned _numReduceSymbols;
+
+ bool _wasCreated;
+ bool _needClose;
+
+ unsigned _numPostedMessages;
+ UInt32 _numAutoSizeMessages;
+
+ bool _errorsWereDisplayed;
+
+ bool _waitCloseByCancelButton;
+ bool _cancelWasPressed;
+
+ bool _inCancelMessageBox;
+ bool _externalCloseMessageWasReceived;
+
+
+ #ifdef __ITaskbarList3_INTERFACE_DEFINED__
+ void SetTaskbarProgressState(TBPFLAG tbpFlags)
+ {
+ if (_taskbarList && _hwndForTaskbar)
+ _taskbarList->SetProgressState(_hwndForTaskbar, tbpFlags);
+ }
+ #endif
+ void SetTaskbarProgressState();
+
+ void UpdateStatInfo(bool showAll);
+ bool OnTimer(WPARAM timerID, LPARAM callback);
+ void SetProgressRange(UInt64 range);
+ void SetProgressPos(UInt64 pos);
+ virtual bool OnInit();
+ virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
+ virtual void OnCancel();
+ virtual void OnOK();
+ NWindows::NSynchronization::CManualResetEvent _createDialogEvent;
+ NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent;
+ #ifndef _SFX
+ void AddToTitle(LPCWSTR string);
+ #endif
+
+ void SetPauseText();
+ void SetPriorityText();
+ void OnPauseButton();
+ void OnPriorityButton();
+ bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+
+ void SetTitleText();
+ void ShowSize(int id, UInt64 val, UInt64 &prev);
+
+ void UpdateMessagesDialog();
+
+ void AddMessageDirect(LPCWSTR message, bool needNumber);
+ void AddMessage(LPCWSTR message);
+
+ bool OnExternalCloseMessage();
+ void EnableErrorsControls(bool enable);
+
+ void ShowAfterMessages(HWND wndParent);
+
+ void CheckNeedClose();
+public:
+ CProgressSync Sync;
+ bool CompressingMode;
+ bool WaitMode;
+ bool ShowCompressionInfo;
+ bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages.
+ int IconID;
+
+ HWND MainWindow;
+ #ifndef _SFX
+ UString MainTitle;
+ UString MainAddTitle;
+ ~CProgressDialog();
+ #endif
+
+ CProgressDialog();
+ void WaitCreating()
+ {
+ _createDialogEvent.Set();
+ _dialogCreatedEvent.Lock();
+ }
+
+ INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0);
+
+ void ProcessWasFinished();
+};
+
+
+class CProgressCloser
+{
+ CProgressDialog *_p;
+public:
+ CProgressCloser(CProgressDialog &p) : _p(&p) {}
+ ~CProgressCloser() { _p->ProcessWasFinished(); }
+};
+
+class CProgressThreadVirt
+{
+protected:
+ FStringVector ErrorPaths;
+ CProgressFinalMessage FinalMessage;
+
+ // 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 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);
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.rc b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.rc
new file mode 100644
index 00000000000..4d0e0c7bfe0
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.rc
@@ -0,0 +1,40 @@
+#include "ProgressDialog2Res.h"
+#include "../../GuiCommon.rc"
+
+#undef DIALOG_ID
+#define DIALOG_ID IDD_PROGRESS
+#define xc 360
+#define k 11
+#define z1s 16
+
+#include "ProgressDialog2a.rc"
+
+#ifdef UNDER_CE
+
+#include "../../GuiCommon.rc"
+
+
+#undef DIALOG_ID
+#undef m
+#undef k
+#undef z1s
+
+#define DIALOG_ID IDD_PROGRESS_2
+#define m 4
+#define k 8
+#define z1s 12
+
+#define xc 280
+
+#include "ProgressDialog2a.rc"
+
+#endif
+
+STRINGTABLE DISCARDABLE
+{
+ IDS_PROGRESS_PAUSED "Paused"
+ IDS_PROGRESS_FOREGROUND "&Foreground"
+ IDS_CONTINUE "&Continue"
+ IDS_PROGRESS_ASK_CANCEL "Are you sure you want to cancel?"
+ IDS_CLOSE "&Close"
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2Res.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2Res.h
new file mode 100644
index 00000000000..b45d7b49506
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2Res.h
@@ -0,0 +1,48 @@
+#define IDD_PROGRESS 97
+#define IDD_PROGRESS_2 10097
+
+#define IDS_CLOSE 408
+#define IDS_CONTINUE 411
+
+#define IDB_PROGRESS_BACKGROUND 444
+#define IDS_PROGRESS_FOREGROUND 445
+#define IDB_PAUSE 446
+#define IDS_PROGRESS_PAUSED 447
+#define IDS_PROGRESS_ASK_CANCEL 448
+
+#define IDT_PROGRESS_PACKED 1008
+#define IDT_PROGRESS_FILES 1032
+
+#define IDT_PROGRESS_ELAPSED 3900
+#define IDT_PROGRESS_REMAINING 3901
+#define IDT_PROGRESS_TOTAL 3902
+#define IDT_PROGRESS_SPEED 3903
+#define IDT_PROGRESS_PROCESSED 3904
+#define IDT_PROGRESS_RATIO 3905
+#define IDT_PROGRESS_ERRORS 3906
+
+#define IDC_PROGRESS1 100
+#define IDL_PROGRESS_MESSAGES 101
+#define IDT_PROGRESS_FILE_NAME 102
+#define IDT_PROGRESS_STATUS 103
+
+#define IDT_PROGRESS_PACKED_VAL 110
+#define IDT_PROGRESS_FILES_VAL 111
+
+#define IDT_PROGRESS_ELAPSED_VAL 120
+#define IDT_PROGRESS_REMAINING_VAL 121
+#define IDT_PROGRESS_TOTAL_VAL 122
+#define IDT_PROGRESS_SPEED_VAL 123
+#define IDT_PROGRESS_PROCESSED_VAL 124
+#define IDT_PROGRESS_RATIO_VAL 125
+#define IDT_PROGRESS_ERRORS_VAL 126
+
+
+#ifdef UNDER_CE
+#define MY_PROGRESS_VAL_UNITS 44
+#else
+#define MY_PROGRESS_VAL_UNITS 76
+#endif
+#define MY_PROGRESS_LABEL_UNITS_MIN 60
+#define MY_PROGRESS_LABEL_UNITS_START 90
+#define MY_PROGRESS_PAD_UNITS 4
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2a.rc b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2a.rc
new file mode 100644
index 00000000000..e9713930be1
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2a.rc
@@ -0,0 +1,80 @@
+#undef bxs
+#define bxs 80
+
+#define x0s MY_PROGRESS_LABEL_UNITS_START
+#define x1s MY_PROGRESS_VAL_UNITS
+#define x2s MY_PROGRESS_LABEL_UNITS_START
+#define x3s MY_PROGRESS_VAL_UNITS
+
+#define x1 (m + x0s)
+#define x3 (xs - m - x3s)
+#define x2 (x3 - x2s)
+
+#undef y0
+#undef y1
+#undef y2
+#undef y3
+#undef y4
+
+#undef z0
+#undef z1
+#undef z2
+#undef z3
+
+#define y0 m
+#define y1 (y0 + k)
+#define y2 (y1 + k)
+#define y3 (y2 + k)
+#define y4 (y3 + k)
+
+#define z3 (y4 + k + 1)
+
+#define z2 (z3 + k + 1)
+#define z2s 24
+
+#define z1 (z2 + z2s)
+
+#define z0 (z1 + z1s + m)
+#define z0s 48
+
+#define yc (z0 + z0s + bys)
+
+
+DIALOG_ID DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT
+CAPTION "Progress"
+{
+ DEFPUSHBUTTON "&Background", IDB_PROGRESS_BACKGROUND, bx3, by, bxs, bys
+ PUSHBUTTON "&Pause", IDB_PAUSE bx2, by, bxs, bys
+ PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
+
+ LTEXT "Elapsed time:", IDT_PROGRESS_ELAPSED, m, y0, x0s, 8
+ LTEXT "Remaining time:", IDT_PROGRESS_REMAINING, m, y1, x0s, 8
+ LTEXT "Files:", IDT_PROGRESS_FILES, m, y2, x0s, 8
+ LTEXT "Compression ratio:", IDT_PROGRESS_RATIO, m, y3, x0s, 8
+ LTEXT "Errors:", IDT_PROGRESS_ERRORS, m, y4, x0s, 8
+
+ LTEXT "Total size:", IDT_PROGRESS_TOTAL, x2, y0, x2s, 8
+ LTEXT "Speed:", IDT_PROGRESS_SPEED, x2, y1, x2s, 8
+ LTEXT "Processed:", IDT_PROGRESS_PROCESSED,x2, y2, x2s, 8
+ LTEXT "Compressed size:" , IDT_PROGRESS_PACKED, x2, y3, x2s, 8
+
+ RTEXT "", IDT_PROGRESS_ELAPSED_VAL, x1, y0, x1s, MY_TEXT_NOPREFIX
+ RTEXT "", IDT_PROGRESS_REMAINING_VAL, x1, y1, x1s, MY_TEXT_NOPREFIX
+ RTEXT "", IDT_PROGRESS_FILES_VAL, x1, y2, x1s, MY_TEXT_NOPREFIX
+ RTEXT "", IDT_PROGRESS_RATIO_VAL, x1, y3, x1s, MY_TEXT_NOPREFIX
+ RTEXT "", IDT_PROGRESS_ERRORS_VAL, x1, y4, x1s, MY_TEXT_NOPREFIX
+
+ RTEXT "", IDT_PROGRESS_TOTAL_VAL, x3, y0, x3s, MY_TEXT_NOPREFIX
+ RTEXT "", IDT_PROGRESS_SPEED_VAL, x3, y1, x3s, MY_TEXT_NOPREFIX
+ RTEXT "", IDT_PROGRESS_PROCESSED_VAL, x3, y2, x3s, MY_TEXT_NOPREFIX
+ RTEXT "", IDT_PROGRESS_PACKED_VAL, x3, y3, x3s, MY_TEXT_NOPREFIX
+
+ LTEXT "", IDT_PROGRESS_STATUS, m, z3, xc, MY_TEXT_NOPREFIX
+ CONTROL "", IDT_PROGRESS_FILE_NAME, "Static", SS_NOPREFIX | SS_LEFTNOWORDWRAP, m, z2, xc, z2s
+
+ CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, m, z1, xc, z1s
+
+ CONTROL "List1", IDL_PROGRESS_MESSAGES, "SysListView32",
+ LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,
+ m, z0, xc, z0s
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialogRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialogRes.h
new file mode 100644
index 00000000000..cbf3beb2179
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialogRes.h
@@ -0,0 +1,3 @@
+#define IDD_PROGRESS 97
+
+#define IDC_PROGRESS1 100
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.cpp
new file mode 100644
index 00000000000..838b6e3f63c
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.cpp
@@ -0,0 +1,23 @@
+// PropertyName.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/IntToString.h"
+
+#include "LangUtils.h"
+#include "PropertyName.h"
+
+UString GetNameOfProperty(PROPID propID, const wchar_t *name)
+{
+ if (propID < 1000)
+ {
+ UString s = LangString(1000 + propID);
+ if (!s.IsEmpty())
+ return s;
+ }
+ if (name)
+ return name;
+ wchar_t temp[16];
+ ConvertUInt32ToString(propID, temp);
+ return temp;
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.h
new file mode 100644
index 00000000000..4f0d6dc11d9
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.h
@@ -0,0 +1,10 @@
+// PropertyName.h
+
+#ifndef __PROPERTY_NAME_H
+#define __PROPERTY_NAME_H
+
+#include "../../../Common/MyString.h"
+
+UString GetNameOfProperty(PROPID propID, const wchar_t *name);
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyNameRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyNameRes.h
new file mode 100644
index 00000000000..67f339028fe
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyNameRes.h
@@ -0,0 +1,95 @@
+
+
+#define IDS_PROP_PATH 1003
+#define IDS_PROP_NAME 1004
+#define IDS_PROP_EXTENSION 1005
+#define IDS_PROP_IS_FOLDER 1006
+#define IDS_PROP_SIZE 1007
+#define IDS_PROP_PACKED_SIZE 1008
+#define IDS_PROP_ATTRIBUTES 1009
+#define IDS_PROP_CTIME 1010
+#define IDS_PROP_ATIME 1011
+#define IDS_PROP_MTIME 1012
+#define IDS_PROP_SOLID 1013
+#define IDS_PROP_C0MMENTED 1014
+#define IDS_PROP_ENCRYPTED 1015
+#define IDS_PROP_SPLIT_BEFORE 1016
+#define IDS_PROP_SPLIT_AFTER 1017
+#define IDS_PROP_DICTIONARY_SIZE 1018
+#define IDS_PROP_CRC 1019
+#define IDS_PROP_FILE_TYPE 1020
+#define IDS_PROP_ANTI 1021
+#define IDS_PROP_METHOD 1022
+#define IDS_PROP_HOST_OS 1023
+#define IDS_PROP_FILE_SYSTEM 1024
+#define IDS_PROP_USER 1025
+#define IDS_PROP_GROUP 1026
+#define IDS_PROP_BLOCK 1027
+#define IDS_PROP_COMMENT 1028
+#define IDS_PROP_POSITION 1029
+#define IDS_PROP_PREFIX 1030
+#define IDS_PROP_FOLDERS 1031
+#define IDS_PROP_FILES 1032
+#define IDS_PROP_VERSION 1033
+#define IDS_PROP_VOLUME 1034
+#define IDS_PROP_IS_VOLUME 1035
+#define IDS_PROP_OFFSET 1036
+#define IDS_PROP_LINKS 1037
+#define IDS_PROP_NUM_BLOCKS 1038
+#define IDS_PROP_NUM_VOLUMES 1039
+
+#define IDS_PROP_BIT64 1041
+#define IDS_PROP_BIG_ENDIAN 1042
+#define IDS_PROP_CPU 1043
+#define IDS_PROP_PHY_SIZE 1044
+#define IDS_PROP_HEADERS_SIZE 1045
+#define IDS_PROP_CHECKSUM 1046
+#define IDS_PROP_CHARACTS 1047
+#define IDS_PROP_VA 1048
+#define IDS_PROP_ID 1049
+#define IDS_PROP_SHORT_NAME 1050
+#define IDS_PROP_CREATOR_APP 1051
+#define IDS_PROP_SECTOR_SIZE 1052
+#define IDS_PROP_POSIX_ATTRIB 1053
+#define IDS_PROP_SYM_LINK 1054
+#define IDS_PROP_ERROR 1055
+#define IDS_PROP_TOTAL_SIZE 1056
+#define IDS_PROP_FREE_SPACE 1057
+#define IDS_PROP_CLUSTER_SIZE 1058
+#define IDS_PROP_VOLUME_NAME 1059
+#define IDS_PROP_LOCAL_NAME 1060
+#define IDS_PROP_PROVIDER 1061
+#define IDS_PROP_NT_SECURITY 1062
+#define IDS_PROP_ALT_STREAM 1063
+#define IDS_PROP_AUX 1064
+#define IDS_PROP_DELETED 1065
+#define IDS_PROP_IS_TREE 1066
+#define IDS_PROP_SHA1 1067
+#define IDS_PROP_SHA256 1068
+#define IDS_PROP_ERROR_TYPE 1069
+#define IDS_PROP_NUM_ERRORS 1070
+#define IDS_PROP_ERROR_FLAGS 1071
+#define IDS_PROP_WARNING_FLAGS 1072
+#define IDS_PROP_WARNING 1073
+#define IDS_PROP_NUM_STREAMS 1074
+#define IDS_PROP_NUM_ALT_STREAMS 1075
+#define IDS_PROP_ALT_STREAMS_SIZE 1076
+#define IDS_PROP_VIRTUAL_SIZE 1077
+#define IDS_PROP_UNPACK_SIZE 1078
+#define IDS_PROP_TOTAL_PHY_SIZE 1079
+#define IDS_PROP_VOLUME_INDEX 1080
+#define IDS_PROP_SUBTYPE 1081
+#define IDS_PROP_SHORT_COMMENT 1082
+#define IDS_PROP_CODE_PAGE 1083
+#define IDS_PROP_IS_NOT_ARC_TYPE 1084
+#define IDS_PROP_PHY_SIZE_CANT_BE_DETECTED 1085
+#define IDS_PROP_ZEROS_TAIL_IS_ALLOWED 1086
+#define IDS_PROP_TAIL_SIZE 1087
+#define IDS_PROP_EMB_STUB_SIZE 1088
+#define IDS_PROP_NT_REPARSE 1089
+#define IDS_PROP_HARD_LINK 1090
+#define IDS_PROP_INODE 1091
+#define IDS_PROP_STREAM_ID 1092
+#define IDS_PROP_READ_ONLY 1093
+#define IDS_PROP_OUT_NAME 1094
+#define IDS_PROP_COPY_LINK 1095
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.cpp
new file mode 100644
index 00000000000..c8ea8b95aef
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.cpp
@@ -0,0 +1,255 @@
+// SysIconUtils.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "../../../Common/StringConvert.h"
+#endif
+
+#include "../../../Windows/FileDir.h"
+
+#include "SysIconUtils.h"
+
+#include <ShlObj.h>
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+int GetIconIndexForCSIDL(int csidl)
+{
+ LPITEMIDLIST pidl = 0;
+ SHGetSpecialFolderLocation(NULL, csidl, &pidl);
+ if (pidl)
+ {
+ SHFILEINFO shellInfo;
+ SHGetFileInfo(LPCTSTR(pidl), FILE_ATTRIBUTE_NORMAL,
+ &shellInfo, sizeof(shellInfo),
+ SHGFI_PIDL | SHGFI_SYSICONINDEX);
+ IMalloc *pMalloc;
+ SHGetMalloc(&pMalloc);
+ if (pMalloc)
+ {
+ pMalloc->Free(pidl);
+ pMalloc->Release();
+ }
+ return shellInfo.iIcon;
+ }
+ return 0;
+}
+
+#ifndef _UNICODE
+typedef int (WINAPI * SHGetFileInfoWP)(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags);
+
+struct CSHGetFileInfoInit
+{
+ SHGetFileInfoWP shGetFileInfoW;
+ CSHGetFileInfoInit()
+ {
+ shGetFileInfoW = (SHGetFileInfoWP)
+ ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetFileInfoW");
+ }
+} g_SHGetFileInfoInit;
+#endif
+
+static DWORD_PTR MySHGetFileInfoW(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags)
+{
+ #ifdef _UNICODE
+ return SHGetFileInfo
+ #else
+ if (g_SHGetFileInfoInit.shGetFileInfoW == 0)
+ return 0;
+ return g_SHGetFileInfoInit.shGetFileInfoW
+ #endif
+ (pszPath, attrib, psfi, cbFileInfo, uFlags);
+}
+
+DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ SHFILEINFO shellInfo;
+ DWORD_PTR res = ::SHGetFileInfo(fs2fas(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo,
+ sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
+ iconIndex = shellInfo.iIcon;
+ return res;
+ }
+ else
+ #endif
+ {
+ SHFILEINFOW shellInfo;
+ DWORD_PTR res = ::MySHGetFileInfoW(fs2us(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo,
+ sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
+ iconIndex = shellInfo.iIcon;
+ return res;
+ }
+}
+
+/*
+DWORD_PTR GetRealIconIndex(const UString &fileName, DWORD attrib, int &iconIndex, UString *typeName)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ SHFILEINFO shellInfo;
+ shellInfo.szTypeName[0] = 0;
+ DWORD_PTR res = ::SHGetFileInfoA(GetSystemString(fileName), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo,
+ sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
+ if (typeName)
+ *typeName = GetUnicodeString(shellInfo.szTypeName);
+ iconIndex = shellInfo.iIcon;
+ return res;
+ }
+ else
+ #endif
+ {
+ SHFILEINFOW shellInfo;
+ shellInfo.szTypeName[0] = 0;
+ DWORD_PTR res = ::MySHGetFileInfoW(fileName, FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo,
+ sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
+ if (typeName)
+ *typeName = shellInfo.szTypeName;
+ iconIndex = shellInfo.iIcon;
+ return res;
+ }
+}
+*/
+
+static int FindInSorted_Attrib(const CRecordVector<CAttribIconPair> &vect, DWORD attrib, int &insertPos)
+{
+ unsigned left = 0, right = vect.Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ DWORD midAttrib = vect[mid].Attrib;
+ if (attrib == midAttrib)
+ return mid;
+ if (attrib < midAttrib)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ insertPos = left;
+ return -1;
+}
+
+static int FindInSorted_Ext(const CObjectVector<CExtIconPair> &vect, const wchar_t *ext, int &insertPos)
+{
+ unsigned left = 0, right = vect.Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ int compare = MyStringCompareNoCase(ext, vect[mid].Ext);
+ if (compare == 0)
+ return mid;
+ if (compare < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ insertPos = left;
+ return -1;
+}
+
+int CExtToIconMap::GetIconIndex(DWORD attrib, const wchar_t *fileName /*, UString *typeName */)
+{
+ int dotPos = -1;
+ unsigned i;
+ for (i = 0;; i++)
+ {
+ wchar_t c = fileName[i];
+ if (c == 0)
+ break;
+ if (c == '.')
+ dotPos = i;
+ }
+
+ /*
+ if (MyStringCompareNoCase(fileName, L"$Recycle.Bin") == 0)
+ {
+ char s[256];
+ sprintf(s, "SPEC i = %3d, attr = %7x", _attribMap.Size(), attrib);
+ OutputDebugStringA(s);
+ OutputDebugStringW(fileName);
+ }
+ */
+
+ if ((attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 || dotPos < 0)
+ {
+ int insertPos = 0;
+ int index = FindInSorted_Attrib(_attribMap, attrib, insertPos);
+ if (index >= 0)
+ {
+ // if (typeName) *typeName = _attribMap[index].TypeName;
+ return _attribMap[index].IconIndex;
+ }
+ CAttribIconPair pair;
+ GetRealIconIndex(
+ #ifdef UNDER_CE
+ FTEXT("\\")
+ #endif
+ FTEXT("__DIR__")
+ , attrib, pair.IconIndex
+ // , pair.TypeName
+ );
+
+ /*
+ char s[256];
+ sprintf(s, "i = %3d, attr = %7x", _attribMap.Size(), attrib);
+ OutputDebugStringA(s);
+ */
+
+ pair.Attrib = attrib;
+ _attribMap.Insert(insertPos, pair);
+ // if (typeName) *typeName = pair.TypeName;
+ return pair.IconIndex;
+ }
+
+ const wchar_t *ext = fileName + dotPos + 1;
+ int insertPos = 0;
+ int index = FindInSorted_Ext(_extMap, ext, insertPos);
+ if (index >= 0)
+ {
+ const CExtIconPair &pa = _extMap[index];
+ // if (typeName) *typeName = pa.TypeName;
+ return pa.IconIndex;
+ }
+
+ for (i = 0;; i++)
+ {
+ wchar_t c = ext[i];
+ if (c == 0)
+ break;
+ if (c < L'0' || c > L'9')
+ break;
+ }
+ if (i != 0 && ext[i] == 0)
+ {
+ // GetRealIconIndex is too slow for big number of split extensions: .001, .002, .003
+ if (!SplitIconIndex_Defined)
+ {
+ GetRealIconIndex(
+ #ifdef UNDER_CE
+ FTEXT("\\")
+ #endif
+ FTEXT("__FILE__.001"), 0, SplitIconIndex);
+ SplitIconIndex_Defined = true;
+ }
+ return SplitIconIndex;
+ }
+
+ CExtIconPair pair;
+ pair.Ext = ext;
+ GetRealIconIndex(us2fs(fileName + dotPos), attrib, pair.IconIndex);
+ _extMap.Insert(insertPos, pair);
+ // if (typeName) *typeName = pair.TypeName;
+ return pair.IconIndex;
+}
+
+/*
+int CExtToIconMap::GetIconIndex(DWORD attrib, const UString &fileName)
+{
+ return GetIconIndex(attrib, fileName, NULL);
+}
+*/
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.h
new file mode 100644
index 00000000000..f1b27fa1541
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.h
@@ -0,0 +1,62 @@
+// SysIconUtils.h
+
+#ifndef __SYS_ICON_UTILS_H
+#define __SYS_ICON_UTILS_H
+
+#include "../../../Common/MyWindows.h"
+
+#include <commctrl.h>
+
+#include "../../../Common/MyString.h"
+
+struct CExtIconPair
+{
+ UString Ext;
+ int IconIndex;
+ // UString TypeName;
+
+ // int Compare(const CExtIconPair &a) const { return MyStringCompareNoCase(Ext, a.Ext); }
+};
+
+struct CAttribIconPair
+{
+ DWORD Attrib;
+ int IconIndex;
+ // UString TypeName;
+
+ // int Compare(const CAttribIconPair &a) const { return Ext.Compare(a.Ext); }
+};
+
+class CExtToIconMap
+{
+public:
+ CRecordVector<CAttribIconPair> _attribMap;
+ CObjectVector<CExtIconPair> _extMap;
+ int SplitIconIndex;
+ int SplitIconIndex_Defined;
+
+ CExtToIconMap(): SplitIconIndex_Defined(false) {}
+
+ void Clear()
+ {
+ SplitIconIndex_Defined = false;
+ _extMap.Clear();
+ _attribMap.Clear();
+ }
+ int GetIconIndex(DWORD attrib, const wchar_t *fileName /* , UString *typeName */);
+ // int GetIconIndex(DWORD attrib, const UString &fileName);
+};
+
+DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex);
+int GetIconIndexForCSIDL(int csidl);
+
+inline HIMAGELIST GetSysImageList(bool smallIcons)
+{
+ SHFILEINFO shellInfo;
+ return (HIMAGELIST)SHGetFileInfo(TEXT(""),
+ FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY,
+ &shellInfo, sizeof(shellInfo),
+ SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | (smallIcons ? SHGFI_SMALLICON : SHGFI_ICON));
+}
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/resource.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/resource.h
new file mode 100644
index 00000000000..b7ca17f1b22
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/resource.h
@@ -0,0 +1,175 @@
+#include "resourceGui.h"
+
+#define IDR_MENUBAR1 70
+#define IDM_MENU 71
+#define IDR_ACCELERATOR1 72
+
+#define IDB_ADD 100
+#define IDB_EXTRACT 101
+#define IDB_TEST 102
+#define IDB_COPY 103
+#define IDB_MOVE 104
+#define IDB_DELETE 105
+#define IDB_INFO 106
+
+#define IDB_ADD2 150
+#define IDB_EXTRACT2 151
+#define IDB_TEST2 152
+#define IDB_COPY2 153
+#define IDB_MOVE2 154
+#define IDB_DELETE2 155
+#define IDB_INFO2 156
+
+#define IDM_HASH_ALL 101
+#define IDM_CRC32 102
+#define IDM_CRC64 103
+#define IDM_SHA1 104
+#define IDM_SHA256 105
+
+#define IDM_OPEN 540
+#define IDM_OPEN_INSIDE 541
+#define IDM_OPEN_OUTSIDE 542
+#define IDM_FILE_VIEW 543
+#define IDM_FILE_EDIT 544
+#define IDM_RENAME 545
+#define IDM_COPY_TO 546
+#define IDM_MOVE_TO 547
+#define IDM_DELETE 548
+#define IDM_SPLIT 549
+#define IDM_COMBINE 550
+#define IDM_PROPERTIES 551
+#define IDM_COMMENT 552
+#define IDM_CRC 553
+#define IDM_DIFF 554
+#define IDM_CREATE_FOLDER 555
+#define IDM_CREATE_FILE 556
+// #define IDM_EXIT 557
+#define IDM_LINK 558
+#define IDM_ALT_STREAMS 559
+
+#define IDM_OPEN_INSIDE_ONE 590
+#define IDM_OPEN_INSIDE_PARSER 591
+
+#define IDM_SELECT_ALL 600
+#define IDM_DESELECT_ALL 601
+#define IDM_INVERT_SELECTION 602
+#define IDM_SELECT 603
+#define IDM_DESELECT 604
+#define IDM_SELECT_BY_TYPE 605
+#define IDM_DESELECT_BY_TYPE 606
+
+#define IDM_VIEW_LARGE_ICONS 700
+#define IDM_VIEW_SMALL_ICONS 701
+#define IDM_VIEW_LIST 702
+#define IDM_VIEW_DETAILS 703
+
+#define IDM_VIEW_ARANGE_BY_NAME 710
+#define IDM_VIEW_ARANGE_BY_TYPE 711
+#define IDM_VIEW_ARANGE_BY_DATE 712
+#define IDM_VIEW_ARANGE_BY_SIZE 713
+
+#define IDM_VIEW_ARANGE_NO_SORT 730
+#define IDM_VIEW_FLAT_VIEW 731
+#define IDM_VIEW_TWO_PANELS 732
+#define IDM_VIEW_TOOLBARS 733
+#define IDM_OPEN_ROOT_FOLDER 734
+#define IDM_OPEN_PARENT_FOLDER 735
+#define IDM_FOLDERS_HISTORY 736
+#define IDM_VIEW_REFRESH 737
+#define IDM_VIEW_AUTO_REFRESH 738
+// #define IDM_VIEW_SHOW_DELETED 739
+// #define IDM_VIEW_SHOW_STREAMS 740
+
+#define IDM_VIEW_ARCHIVE_TOOLBAR 750
+#define IDM_VIEW_STANDARD_TOOLBAR 751
+#define IDM_VIEW_TOOLBARS_LARGE_BUTTONS 752
+#define IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT 753
+
+#define IDS_BOOKMARK 801
+
+#define IDM_OPTIONS 900
+#define IDM_BENCHMARK 901
+#define IDM_BENCHMARK2 902
+
+#define IDM_HELP_CONTENTS 960
+#define IDM_ABOUT 961
+
+#define IDS_OPTIONS 2100
+
+#define IDS_N_SELECTED_ITEMS 3002
+
+#define IDS_FILE_EXIST 3008
+#define IDS_WANT_UPDATE_MODIFIED_FILE 3009
+#define IDS_CANNOT_UPDATE_FILE 3010
+#define IDS_CANNOT_START_EDITOR 3011
+#define IDS_VIRUS 3012
+#define IDS_MESSAGE_UNSUPPORTED_OPERATION_FOR_LONG_PATH_FOLDER 3013
+#define IDS_SELECT_ONE_FILE 3014
+#define IDS_SELECT_FILES 3015
+#define IDS_TOO_MANY_ITEMS 3016
+
+#define IDS_COPY 6000
+#define IDS_MOVE 6001
+#define IDS_COPY_TO 6002
+#define IDS_MOVE_TO 6003
+#define IDS_COPYING 6004
+#define IDS_MOVING 6005
+#define IDS_RENAMING 6006
+
+#define IDS_OPERATION_IS_NOT_SUPPORTED 6008
+#define IDS_ERROR_RENAMING 6009
+#define IDS_CONFIRM_FILE_COPY 6010
+#define IDS_WANT_TO_COPY_FILES 6011
+
+#define IDS_CONFIRM_FILE_DELETE 6100
+#define IDS_CONFIRM_FOLDER_DELETE 6101
+#define IDS_CONFIRM_ITEMS_DELETE 6102
+#define IDS_WANT_TO_DELETE_FILE 6103
+#define IDS_WANT_TO_DELETE_FOLDER 6104
+#define IDS_WANT_TO_DELETE_ITEMS 6105
+#define IDS_DELETING 6106
+#define IDS_ERROR_DELETING 6107
+#define IDS_ERROR_LONG_PATH_TO_RECYCLE 6108
+
+#define IDS_CREATE_FOLDER 6300
+#define IDS_CREATE_FILE 6301
+#define IDS_CREATE_FOLDER_NAME 6302
+#define IDS_CREATE_FILE_NAME 6303
+#define IDS_CREATE_FOLDER_DEFAULT_NAME 6304
+#define IDS_CREATE_FILE_DEFAULT_NAME 6305
+#define IDS_CREATE_FOLDER_ERROR 6306
+#define IDS_CREATE_FILE_ERROR 6307
+
+#define IDS_COMMENT 6400
+#define IDS_COMMENT2 6401
+#define IDS_SELECT 6402
+#define IDS_DESELECT 6403
+#define IDS_SELECT_MASK 6404
+
+#define IDS_PROPERTIES 6600
+#define IDS_FOLDERS_HISTORY 6601
+
+#define IDS_COMPUTER 7100
+#define IDS_NETWORK 7101
+#define IDS_DOCUMENTS 7102
+#define IDS_SYSTEM 7103
+
+#define IDS_ADD 7200
+#define IDS_EXTRACT 7201
+#define IDS_TEST 7202
+#define IDS_BUTTON_COPY 7203
+#define IDS_BUTTON_MOVE 7204
+#define IDS_BUTTON_DELETE 7205
+#define IDS_BUTTON_INFO 7206
+
+#define IDS_SPLITTING 7303
+#define IDS_SPLIT_CONFIRM_TITLE 7304
+#define IDS_SPLIT_CONFIRM_MESSAGE 7305
+#define IDS_SPLIT_VOL_MUST_BE_SMALLER 7306
+
+#define IDS_COMBINE 7400
+#define IDS_COMBINE_TO 7401
+#define IDS_COMBINING 7402
+#define IDS_COMBINE_SELECT_ONE_FILE 7403
+#define IDS_COMBINE_CANT_DETECT_SPLIT_FILE 7404
+#define IDS_COMBINE_CANT_FIND_MORE_THAN_ONE_PART 7405
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/resourceGui.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/resourceGui.h
new file mode 100644
index 00000000000..7c1b40e430b
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/resourceGui.h
@@ -0,0 +1,15 @@
+#define IDI_ICON 1
+
+#define IDS_MESSAGE_NO_ERRORS 3001
+
+#define IDS_PROGRESS_TESTING 3302
+#define IDS_OPENNING 3303
+#define IDS_SCANNING 3304
+
+#define IDS_CHECKSUM_CALCULATING 7500
+#define IDS_CHECKSUM_INFORMATION 7501
+#define IDS_CHECKSUM_CRC_DATA 7502
+#define IDS_CHECKSUM_CRC_DATA_NAMES 7503
+#define IDS_CHECKSUM_CRC_STREAMS_NAMES 7504
+
+#define IDS_INCORRECT_VOLUME_SIZE 7307
diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/Extract.rc b/3rdparty/lzma/CPP/7zip/UI/GUI/Extract.rc
new file mode 100644
index 00000000000..f75b2e6fcb3
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/GUI/Extract.rc
@@ -0,0 +1,59 @@
+#include "ExtractRes.h"
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_MEM_ERROR "The system cannot allocate the required amount of memory"
+ IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'"
+ IDS_UPDATE_NOT_SUPPORTED "Update operations are not supported for this archive."
+ IDS_CANT_OPEN_ARCHIVE "Can not open file '{0}' as archive"
+ IDS_CANT_OPEN_ENCRYPTED_ARCHIVE "Can not open encrypted archive '{0}'. Wrong password?"
+ IDS_UNSUPPORTED_ARCHIVE_TYPE "Unsupported archive type"
+
+ IDS_CANT_OPEN_AS_TYPE "Can not open the file as {0} archive"
+ IDS_IS_OPEN_AS_TYPE "The file is open as {0} archive"
+ IDS_IS_OPEN_WITH_OFFSET "The archive is open with offset"
+
+ IDS_PROGRESS_EXTRACTING "Extracting"
+
+ IDS_PROGRESS_SKIPPING "Skipping"
+
+ IDS_EXTRACT_SET_FOLDER "Specify a location for extracted files."
+
+ IDS_EXTRACT_PATHS_FULL "Full pathnames"
+ IDS_EXTRACT_PATHS_NO "No pathnames"
+ IDS_EXTRACT_PATHS_ABS "Absolute pathnames"
+ IDS_PATH_MODE_RELAT "Relative pathnames"
+
+ IDS_EXTRACT_OVERWRITE_ASK "Ask before overwrite"
+ IDS_EXTRACT_OVERWRITE_WITHOUT_PROMPT "Overwrite without prompt"
+ IDS_EXTRACT_OVERWRITE_SKIP_EXISTING "Skip existing files"
+ IDS_EXTRACT_OVERWRITE_RENAME "Auto rename"
+ IDS_EXTRACT_OVERWRITE_RENAME_EXISTING "Auto rename existing files"
+
+ IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD "Unsupported compression method for '{0}'."
+ IDS_EXTRACT_MESSAGE_DATA_ERROR "Data error in '{0}'. File is broken"
+ IDS_EXTRACT_MESSAGE_CRC_ERROR "CRC failed in '{0}'. File is broken."
+ IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED "Data error in encrypted file '{0}'. Wrong password?"
+ IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED "CRC failed in encrypted file '{0}'. Wrong password?"
+
+ IDS_EXTRACT_MSG_WRONG_PSW_GUESS "Wrong password?"
+ // IDS_EXTRACT_MSG_ENCRYPTED "Encrypted file"
+
+ IDS_EXTRACT_MSG_UNSUPPORTED_METHOD "Unsupported compression method"
+ IDS_EXTRACT_MSG_DATA_ERROR "Data error"
+ IDS_EXTRACT_MSG_CRC_ERROR "CRC failed"
+ IDS_EXTRACT_MSG_UNAVAILABLE_DATA "Unavailable data"
+ IDS_EXTRACT_MSG_UEXPECTED_END "Unexpected end of data";
+ IDS_EXTRACT_MSG_DATA_AFTER_END "There are some data after the end of the payload data"
+ IDS_EXTRACT_MSG_IS_NOT_ARC "Is not archive"
+ IDS_EXTRACT_MSG_HEADERS_ERROR "Headers Error"
+ IDS_EXTRACT_MSG_WRONG_PSW_CLAIM "Wrong password"
+
+ IDS_OPEN_MSG_UNAVAILABLE_START "Unavailable start of archive"
+ IDS_OPEN_MSG_UNCONFIRMED_START "Unconfirmed start of archive"
+ // IDS_OPEN_MSG_ERROR_FLAGS + 5 "Unexpected end of archive"
+ // IDS_OPEN_MSG_ERROR_FLAGS + 6 "There are data after the end of archive"
+ IDS_OPEN_MSG_UNSUPPORTED_FEATURE "Unsupported feature"
+END
diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.cpp
new file mode 100644
index 00000000000..af47fc2d205
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.cpp
@@ -0,0 +1,418 @@
+// ExtractDialog.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/ResourceString.h"
+
+#ifndef NO_REGISTRY
+#include "../FileManager/HelpUtils.h"
+#endif
+
+
+#include "../FileManager/BrowseDialog.h"
+#include "../FileManager/LangUtils.h"
+#include "../FileManager/resourceGui.h"
+
+#include "ExtractDialog.h"
+#include "ExtractDialogRes.h"
+#include "ExtractRes.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
+extern HINSTANCE g_hInstance;
+
+static const UInt32 kPathMode_IDs[] =
+{
+ IDS_EXTRACT_PATHS_FULL,
+ IDS_EXTRACT_PATHS_NO,
+ IDS_EXTRACT_PATHS_ABS
+};
+
+static const UInt32 kOverwriteMode_IDs[] =
+{
+ IDS_EXTRACT_OVERWRITE_ASK,
+ IDS_EXTRACT_OVERWRITE_WITHOUT_PROMPT,
+ IDS_EXTRACT_OVERWRITE_SKIP_EXISTING,
+ IDS_EXTRACT_OVERWRITE_RENAME,
+ IDS_EXTRACT_OVERWRITE_RENAME_EXISTING
+};
+
+#ifndef _SFX
+
+static const
+ // NExtract::NPathMode::EEnum
+ int
+ kPathModeButtonsVals[] =
+{
+ NExtract::NPathMode::kFullPaths,
+ NExtract::NPathMode::kNoPaths,
+ NExtract::NPathMode::kAbsPaths
+};
+
+static const
+ int
+ // NExtract::NOverwriteMode::EEnum
+ kOverwriteButtonsVals[] =
+{
+ NExtract::NOverwriteMode::kAsk,
+ NExtract::NOverwriteMode::kOverwrite,
+ NExtract::NOverwriteMode::kSkip,
+ NExtract::NOverwriteMode::kRename,
+ NExtract::NOverwriteMode::kRenameExisting
+};
+
+#endif
+
+#ifdef LANG
+
+static const UInt32 kLangIDs[] =
+{
+ IDT_EXTRACT_EXTRACT_TO,
+ IDT_EXTRACT_PATH_MODE,
+ IDT_EXTRACT_OVERWRITE_MODE,
+ // IDX_EXTRACT_ALT_STREAMS,
+ IDX_EXTRACT_NT_SECUR,
+ IDX_EXTRACT_ELIM_DUP,
+ IDG_PASSWORD,
+ IDX_PASSWORD_SHOW
+};
+#endif
+
+// static const int kWildcardsButtonIndex = 2;
+
+#ifndef NO_REGISTRY
+static const unsigned kHistorySize = 16;
+#endif
+
+#ifndef _SFX
+
+// it's used in CompressDialog also
+void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal)
+{
+ int curSel = 0;
+ for (unsigned i = 0; i < numItems; i++)
+ {
+ UString s = LangString(langIDs[i]);
+ s.RemoveChar(L'&');
+ int index = (int)combo.AddString(s);
+ combo.SetItemData(index, i);
+ if (values[i] == curVal)
+ curSel = i;
+ }
+ combo.SetCurSel(curSel);
+}
+
+// it's used in CompressDialog also
+bool GetBoolsVal(const CBoolPair &b1, const CBoolPair &b2)
+{
+ if (b1.Def) return b1.Val;
+ if (b2.Def) return b2.Val;
+ return b1.Val;
+}
+
+void CExtractDialog::CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2)
+{
+ CheckButton(id, GetBoolsVal(b1, b2));
+}
+
+void CExtractDialog::GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2)
+{
+ bool val = IsButtonCheckedBool(id);
+ bool oldVal = GetBoolsVal(b1, b2);
+ if (val != oldVal)
+ b1.Def = b2.Def = true;
+ b1.Val = b2.Val = val;
+}
+
+#endif
+
+bool CExtractDialog::OnInit()
+{
+ #ifdef LANG
+ {
+ UString s;
+ LangString_OnlyFromLangFile(IDD_EXTRACT, s);
+ if (s.IsEmpty())
+ GetText(s);
+ if (!ArcPath.IsEmpty())
+ {
+ s.AddAscii(" : ");
+ s += ArcPath;
+ }
+ SetText(s);
+ // LangSetWindowText(*this, IDD_EXTRACT);
+ LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
+ }
+ #endif
+
+ #ifndef _SFX
+ _passwordControl.Attach(GetItem(IDE_EXTRACT_PASSWORD));
+ _passwordControl.SetText(Password);
+ _passwordControl.SetPasswordChar(TEXT('*'));
+ _pathName.Attach(GetItem(IDE_EXTRACT_NAME));
+ #endif
+
+ #ifdef NO_REGISTRY
+
+ PathMode = NExtract::NPathMode::kFullPaths;
+ OverwriteMode = NExtract::NOverwriteMode::kAsk;
+
+ #else
+
+ _info.Load();
+
+ if (_info.PathMode == NExtract::NPathMode::kCurPaths)
+ _info.PathMode = NExtract::NPathMode::kFullPaths;
+
+ if (!PathMode_Force && _info.PathMode_Force)
+ PathMode = _info.PathMode;
+ if (!OverwriteMode_Force && _info.OverwriteMode_Force)
+ OverwriteMode = _info.OverwriteMode;
+
+ // CheckButton_TwoBools(IDX_EXTRACT_ALT_STREAMS, AltStreams, _info.AltStreams);
+ CheckButton_TwoBools(IDX_EXTRACT_NT_SECUR, NtSecurity, _info.NtSecurity);
+ CheckButton_TwoBools(IDX_EXTRACT_ELIM_DUP, ElimDup, _info.ElimDup);
+
+ CheckButton(IDX_PASSWORD_SHOW, _info.ShowPassword.Val);
+ UpdatePasswordControl();
+
+ #endif
+
+ _path.Attach(GetItem(IDC_EXTRACT_PATH));
+
+ UString pathPrefix = DirPath;
+
+ #ifndef _SFX
+
+ if (_info.SplitDest.Val)
+ {
+ CheckButton(IDX_EXTRACT_NAME_ENABLE, true);
+ UString pathName;
+ SplitPathToParts_Smart(DirPath, pathPrefix, pathName);
+ if (pathPrefix.IsEmpty())
+ pathPrefix = pathName;
+ else
+ _pathName.SetText(pathName);
+ }
+ else
+ ShowItem_Bool(IDE_EXTRACT_NAME, false);
+
+ #endif
+
+ _path.SetText(pathPrefix);
+
+ #ifndef NO_REGISTRY
+ for (unsigned i = 0; i < _info.Paths.Size() && i < kHistorySize; i++)
+ _path.AddString(_info.Paths[i]);
+ #endif
+
+ /*
+ if (_info.Paths.Size() > 0)
+ _path.SetCurSel(0);
+ else
+ _path.SetCurSel(-1);
+ */
+
+ #ifndef _SFX
+
+ _pathMode.Attach(GetItem(IDC_EXTRACT_PATH_MODE));
+ _overwriteMode.Attach(GetItem(IDC_EXTRACT_OVERWRITE_MODE));
+
+ AddComboItems(_pathMode, kPathMode_IDs, ARRAY_SIZE(kPathMode_IDs), kPathModeButtonsVals, PathMode);
+ AddComboItems(_overwriteMode, kOverwriteMode_IDs, ARRAY_SIZE(kOverwriteMode_IDs), kOverwriteButtonsVals, OverwriteMode);
+
+ #endif
+
+ HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON));
+ SetIcon(ICON_BIG, icon);
+
+ // CWindow filesWindow = GetItem(IDC_EXTRACT_RADIO_FILES);
+ // filesWindow.Enable(_enableFilesButton);
+
+ NormalizePosition();
+
+ return CModalDialog::OnInit();
+}
+
+#ifndef _SFX
+void CExtractDialog::UpdatePasswordControl()
+{
+ _passwordControl.SetPasswordChar(IsShowPasswordChecked() ? 0 : TEXT('*'));
+ UString password;
+ _passwordControl.GetText(password);
+ _passwordControl.SetText(password);
+}
+#endif
+
+bool CExtractDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch (buttonID)
+ {
+ case IDB_EXTRACT_SET_PATH:
+ OnButtonSetPath();
+ return true;
+ #ifndef _SFX
+ case IDX_EXTRACT_NAME_ENABLE:
+ ShowItem_Bool(IDE_EXTRACT_NAME, IsButtonCheckedBool(IDX_EXTRACT_NAME_ENABLE));
+ return true;
+ case IDX_PASSWORD_SHOW:
+ {
+ UpdatePasswordControl();
+ return true;
+ }
+ #endif
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
+
+void CExtractDialog::OnButtonSetPath()
+{
+ UString currentPath;
+ _path.GetText(currentPath);
+ UString title = LangString(IDS_EXTRACT_SET_FOLDER);
+ UString resultPath;
+ if (!MyBrowseForFolder(*this, title, currentPath, resultPath))
+ return;
+ #ifndef NO_REGISTRY
+ _path.SetCurSel(-1);
+ #endif
+ _path.SetText(resultPath);
+}
+
+void AddUniqueString(UStringVector &list, const UString &s)
+{
+ FOR_VECTOR (i, list)
+ if (s.IsEqualTo_NoCase(list[i]))
+ return;
+ list.Add(s);
+}
+
+void CExtractDialog::OnOK()
+{
+ #ifndef _SFX
+ int pathMode2 = kPathModeButtonsVals[_pathMode.GetCurSel()];
+ if (PathMode != NExtract::NPathMode::kCurPaths ||
+ pathMode2 != NExtract::NPathMode::kFullPaths)
+ PathMode = (NExtract::NPathMode::EEnum)pathMode2;
+
+ OverwriteMode = (NExtract::NOverwriteMode::EEnum)kOverwriteButtonsVals[_overwriteMode.GetCurSel()];
+
+ // _filesMode = (NExtractionDialog::NFilesMode::EEnum)GetFilesMode();
+
+ _passwordControl.GetText(Password);
+
+ #endif
+
+ #ifndef NO_REGISTRY
+
+ // GetButton_Bools(IDX_EXTRACT_ALT_STREAMS, AltStreams, _info.AltStreams);
+ GetButton_Bools(IDX_EXTRACT_NT_SECUR, NtSecurity, _info.NtSecurity);
+ GetButton_Bools(IDX_EXTRACT_ELIM_DUP, ElimDup, _info.ElimDup);
+
+ bool showPassword = IsShowPasswordChecked();
+ if (showPassword != _info.ShowPassword.Val)
+ {
+ _info.ShowPassword.Def = true;
+ _info.ShowPassword.Val = showPassword;
+ }
+
+ if (_info.PathMode != pathMode2)
+ {
+ _info.PathMode_Force = true;
+ _info.PathMode = (NExtract::NPathMode::EEnum)pathMode2;
+ /*
+ // we allow kAbsPaths in registry.
+ if (_info.PathMode == NExtract::NPathMode::kAbsPaths)
+ _info.PathMode = NExtract::NPathMode::kFullPaths;
+ */
+ }
+
+ if (!OverwriteMode_Force && _info.OverwriteMode != OverwriteMode)
+ _info.OverwriteMode_Force = true;
+ _info.OverwriteMode = OverwriteMode;
+
+
+ #else
+
+ ElimDup.Val = IsButtonCheckedBool(IDX_EXTRACT_ELIM_DUP);
+
+ #endif
+
+ UString s;
+
+ #ifdef NO_REGISTRY
+
+ _path.GetText(s);
+
+ #else
+
+ int currentItem = _path.GetCurSel();
+ if (currentItem == CB_ERR)
+ {
+ _path.GetText(s);
+ if (_path.GetCount() >= kHistorySize)
+ currentItem = _path.GetCount() - 1;
+ }
+ else
+ _path.GetLBText(currentItem, s);
+
+ #endif
+
+ s.Trim();
+ NName::NormalizeDirPathPrefix(s);
+
+ #ifndef _SFX
+
+ bool splitDest = IsButtonCheckedBool(IDX_EXTRACT_NAME_ENABLE);
+ if (splitDest)
+ {
+ UString pathName;
+ _pathName.GetText(pathName);
+ pathName.Trim();
+ s += pathName;
+ NName::NormalizeDirPathPrefix(s);
+ }
+ if (splitDest != _info.SplitDest.Val)
+ {
+ _info.SplitDest.Def = true;
+ _info.SplitDest.Val = splitDest;
+ }
+
+ #endif
+
+ DirPath = s;
+
+ #ifndef NO_REGISTRY
+ _info.Paths.Clear();
+ #ifndef _SFX
+ AddUniqueString(_info.Paths, s);
+ #endif
+ for (int i = 0; i < _path.GetCount(); i++)
+ if (i != currentItem)
+ {
+ UString sTemp;
+ _path.GetLBText(i, sTemp);
+ sTemp.Trim();
+ AddUniqueString(_info.Paths, sTemp);
+ }
+ _info.Save();
+ #endif
+
+ CModalDialog::OnOK();
+}
+
+#ifndef NO_REGISTRY
+static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/extract.htm";
+void CExtractDialog::OnHelp()
+{
+ ShowHelpWindow(NULL, kHelpTopic);
+ CModalDialog::OnHelp();
+}
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.h b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.h
new file mode 100644
index 00000000000..33349ffc615
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.h
@@ -0,0 +1,113 @@
+// ExtractDialog.h
+
+#ifndef __EXTRACT_DIALOG_H
+#define __EXTRACT_DIALOG_H
+
+#include "ExtractDialogRes.h"
+
+#include "../../../Windows/Control/ComboBox.h"
+#include "../../../Windows/Control/Edit.h"
+
+#include "../Common/ExtractMode.h"
+
+#include "../FileManager/DialogSize.h"
+
+#ifndef NO_REGISTRY
+#include "../Common/ZipRegistry.h"
+#endif
+
+namespace NExtractionDialog
+{
+ /*
+ namespace NFilesMode
+ {
+ enum EEnum
+ {
+ kSelected,
+ kAll,
+ kSpecified
+ };
+ }
+ */
+}
+
+class CExtractDialog: public NWindows::NControl::CModalDialog
+{
+ #ifdef NO_REGISTRY
+ NWindows::NControl::CDialogChildControl _path;
+ #else
+ NWindows::NControl::CComboBox _path;
+ #endif
+
+ #ifndef _SFX
+ NWindows::NControl::CEdit _pathName;
+ NWindows::NControl::CEdit _passwordControl;
+ NWindows::NControl::CComboBox _pathMode;
+ NWindows::NControl::CComboBox _overwriteMode;
+ #endif
+
+ #ifndef _SFX
+ // int GetFilesMode() const;
+ void UpdatePasswordControl();
+ #endif
+
+ void OnButtonSetPath();
+
+ void CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2);
+ void GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2);
+ virtual bool OnInit();
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnOK();
+
+ #ifndef NO_REGISTRY
+
+ virtual void OnHelp();
+
+ NExtract::CInfo _info;
+
+ #endif
+
+ bool IsShowPasswordChecked() const { return IsButtonCheckedBool(IDX_PASSWORD_SHOW); }
+public:
+ // bool _enableSelectedFilesButton;
+ // bool _enableFilesButton;
+ // NExtractionDialog::NFilesMode::EEnum FilesMode;
+
+ UString DirPath;
+ UString ArcPath;
+
+ #ifndef _SFX
+ UString Password;
+ #endif
+ bool PathMode_Force;
+ bool OverwriteMode_Force;
+ NExtract::NPathMode::EEnum PathMode;
+ NExtract::NOverwriteMode::EEnum OverwriteMode;
+
+ #ifndef _SFX
+ // CBoolPair AltStreams;
+ CBoolPair NtSecurity;
+ #endif
+
+ CBoolPair ElimDup;
+
+ INT_PTR Create(HWND aWndParent = 0)
+ {
+ #ifdef _SFX
+ BIG_DIALOG_SIZE(240, 64);
+ #else
+ BIG_DIALOG_SIZE(300, 160);
+ #endif
+ return CModalDialog::Create(SIZED_DIALOG(IDD_EXTRACT), aWndParent);
+ }
+
+ CExtractDialog():
+ PathMode_Force(false),
+ OverwriteMode_Force(false)
+ {
+ ElimDup.Val = true;
+ }
+
+};
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.rc b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.rc
new file mode 100644
index 00000000000..3728b96d289
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.rc
@@ -0,0 +1,98 @@
+#include "ExtractDialogRes.h"
+#include "../../GuiCommon.rc"
+
+#define xc 336
+#define yc 168
+
+#undef g1xs
+#undef g2x
+#undef g2x2
+#undef g2xs
+#undef g2xs2
+
+#define g1xs 160
+
+#define gSpace 20
+#define g2x (m + g1xs + gSpace)
+#define g2x2 (g2x + m)
+#define g2xs (xc - g1xs - gSpace)
+#define g2xs2 (g2xs - m - m)
+
+#undef GROUP_Y_SIZE
+#ifdef UNDER_CE
+#define GROUP_Y_SIZE 8
+#else
+#define GROUP_Y_SIZE 56
+#endif
+
+IDD_EXTRACT DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT
+CAPTION "Extract"
+BEGIN
+ LTEXT "E&xtract to:", IDT_EXTRACT_EXTRACT_TO, m, m, xc, 8
+ COMBOBOX IDC_EXTRACT_PATH, m, m + 12, xc - bxsDots - 12, 100, MY_COMBO_WITH_EDIT
+ PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, m + 12 - 2, bxsDots, bys, WS_GROUP
+
+ CONTROL "", IDX_EXTRACT_NAME_ENABLE, MY_CHECKBOX, m, m + 34, 12, 10
+ EDITTEXT IDE_EXTRACT_NAME, m + 12 + 2, m + 32, g1xs - 12 - 2, 14, ES_AUTOHSCROLL
+
+ LTEXT "Path mode:", IDT_EXTRACT_PATH_MODE, m, m + 52, g1xs, 8
+ COMBOBOX IDC_EXTRACT_PATH_MODE, m, m + 64, g1xs, 140, MY_COMBO
+
+ CONTROL "Eliminate duplication of root folder", IDX_EXTRACT_ELIM_DUP, MY_CHECKBOX,
+ m, m + 84, g1xs, 10
+
+ LTEXT "Overwrite mode:", IDT_EXTRACT_OVERWRITE_MODE, m, m + 104, g1xs, 8
+ COMBOBOX IDC_EXTRACT_OVERWRITE_MODE, m, m + 116, g1xs, 140, MY_COMBO
+
+
+ GROUPBOX "Password", IDG_PASSWORD, g2x, m + 36, g2xs, GROUP_Y_SIZE
+ EDITTEXT IDE_EXTRACT_PASSWORD, g2x2, m + 50, g2xs2, 14, ES_PASSWORD | ES_AUTOHSCROLL
+ CONTROL "Show Password", IDX_PASSWORD_SHOW, MY_CHECKBOX, g2x2, m + 72, g2xs2, 10
+
+// CONTROL "Restore alternate data streams", IDX_EXTRACT_ALT_STREAMS, MY_CHECKBOX,
+// g2x, m + 104, g2xs, 10
+ CONTROL "Restore file security", IDX_EXTRACT_NT_SECUR, MY_CHECKBOX,
+ g2x, m + 104, g2xs, 10
+
+ DEFPUSHBUTTON "OK", IDOK, bx3, by, bxs, bys, WS_GROUP
+ PUSHBUTTON "Cancel", IDCANCEL, bx2, by, bxs, bys
+ PUSHBUTTON "Help", IDHELP, bx1, by, bxs, bys
+END
+
+
+#ifdef UNDER_CE
+
+#undef m
+#define m 4
+
+#undef xc
+#undef yc
+
+#define xc 152
+#define yc 128
+
+#undef g1xs
+
+#define g1xs 64
+
+IDD_EXTRACT_2 DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT
+CAPTION "Extract"
+BEGIN
+ LTEXT "E&xtract to:", IDT_EXTRACT_EXTRACT_TO, m, m, xc - bxsDots - 8, 8
+ COMBOBOX IDC_EXTRACT_PATH, m, m + 12, xc - bxsDots - 8, 100, MY_COMBO_WITH_EDIT
+ PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, m + 12 - 3, bxsDots, bys, WS_GROUP
+
+ LTEXT "Path mode:", IDT_EXTRACT_PATH_MODE, m, m + 36, g1xs, 8
+ COMBOBOX IDC_EXTRACT_PATH_MODE, m + g1xs, m + 36, xc - g1xs, 100, MY_COMBO
+
+ LTEXT "Overwrite mode:", IDT_EXTRACT_OVERWRITE_MODE, m, m + 56, g1xs, 8
+ COMBOBOX IDC_EXTRACT_OVERWRITE_MODE, m + g1xs, m + 56, xc - g1xs, 100, MY_COMBO
+
+ LTEXT "Password", IDG_PASSWORD, m, m + 76, g1xs, 8
+ EDITTEXT IDE_EXTRACT_PASSWORD, m + g1xs, m + 76, xc - g1xs, 14, ES_PASSWORD | ES_AUTOHSCROLL
+ CONTROL "Show Password", IDX_PASSWORD_SHOW, MY_CHECKBOX, m, m + 92, xc, 10
+
+ OK_CANCEL
+END
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialogRes.h b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialogRes.h
new file mode 100644
index 00000000000..ed12bfb315f
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialogRes.h
@@ -0,0 +1,24 @@
+#define IDD_EXTRACT 3400
+#define IDD_EXTRACT_2 13400
+
+#define IDC_EXTRACT_PATH 100
+#define IDB_EXTRACT_SET_PATH 101
+#define IDC_EXTRACT_PATH_MODE 102
+#define IDC_EXTRACT_OVERWRITE_MODE 103
+
+#define IDE_EXTRACT_PASSWORD 120
+
+#define IDE_EXTRACT_NAME 130
+#define IDX_EXTRACT_NAME_ENABLE 131
+
+
+#define IDT_EXTRACT_EXTRACT_TO 3401
+#define IDT_EXTRACT_PATH_MODE 3410
+#define IDT_EXTRACT_OVERWRITE_MODE 3420
+
+#define IDX_EXTRACT_ELIM_DUP 3430
+#define IDX_EXTRACT_NT_SECUR 3431
+// #define IDX_EXTRACT_ALT_STREAMS 3432
+
+#define IDX_PASSWORD_SHOW 3803
+#define IDG_PASSWORD 3807
diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.cpp b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.cpp
new file mode 100644
index 00000000000..7fb843a15fc
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.cpp
@@ -0,0 +1,272 @@
+// ExtractGUI.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
+
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/Thread.h"
+
+#include "../FileManager/ExtractCallback.h"
+#include "../FileManager/FormatUtils.h"
+#include "../FileManager/LangUtils.h"
+#include "../FileManager/resourceGui.h"
+#include "../FileManager/OverwriteDialogRes.h"
+
+#include "../Common/ArchiveExtractCallback.h"
+#include "../Common/PropIDUtils.h"
+
+#include "../Explorer/MyMessages.h"
+
+#include "resource2.h"
+#include "ExtractRes.h"
+
+#include "ExtractDialog.h"
+#include "ExtractGUI.h"
+#include "HashGUI.h"
+
+#include "../FileManager/PropertyNameRes.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDir;
+
+static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path";
+
+#ifndef _SFX
+
+static void AddValuePair(UString &s, UINT resourceID, UInt64 value, bool addColon = true)
+{
+ AddLangString(s, resourceID);
+ if (addColon)
+ s += L':';
+ s.Add_Space();
+ char sz[32];
+ ConvertUInt64ToString(value, sz);
+ s.AddAscii(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.Add_LF();
+}
+
+#endif
+
+class CThreadExtracting: public CProgressThreadVirt
+{
+ HRESULT ProcessVirt();
+public:
+ CCodecs *codecs;
+ CExtractCallbackImp *ExtractCallbackSpec;
+ const CObjectVector<COpenType> *FormatIndices;
+ const CIntVector *ExcludedFormatIndices;
+
+ UStringVector *ArchivePaths;
+ UStringVector *ArchivePathsFull;
+ const NWildcard::CCensorNode *WildcardCensor;
+ const CExtractOptions *Options;
+ #ifndef _SFX
+ CHashBundle *HashBundle;
+ #endif
+ CMyComPtr<IExtractCallbackUI> ExtractCallback;
+ UString Title;
+};
+
+HRESULT CThreadExtracting::ProcessVirt()
+{
+ CDecompressStat Stat;
+ #ifndef _SFX
+ if (HashBundle)
+ HashBundle->Init();
+ #endif
+
+ HRESULT res = Extract(codecs,
+ *FormatIndices, *ExcludedFormatIndices,
+ *ArchivePaths, *ArchivePathsFull,
+ *WildcardCensor, *Options, ExtractCallbackSpec, ExtractCallback,
+ #ifndef _SFX
+ HashBundle,
+ #endif
+ FinalMessage.ErrorMessage.Message, Stat);
+ #ifndef _SFX
+ if (res == S_OK && Options->TestMode && ExtractCallbackSpec->IsOK())
+ {
+ UString s;
+
+ 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);
+ AddSizePair(s, IDS_PROP_SIZE, Stat.UnpackSize);
+ if (Stat.NumAltStreams != 0)
+ {
+ s.Add_LF();
+ 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());
+ }
+
+ 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,
+ const CIntVector &excludedFormatIndices,
+ UStringVector &archivePaths,
+ UStringVector &archivePathsFull,
+ const NWildcard::CCensorNode &wildcardCensor,
+ CExtractOptions &options,
+ #ifndef _SFX
+ CHashBundle *hb,
+ #endif
+ bool showDialog,
+ bool &messageWasDisplayed,
+ CExtractCallbackImp *extractCallback,
+ HWND hwndParent)
+{
+ messageWasDisplayed = false;
+
+ CThreadExtracting extracter;
+ extracter.codecs = codecs;
+ extracter.FormatIndices = &formatIndices;
+ extracter.ExcludedFormatIndices = &excludedFormatIndices;
+
+ if (!options.TestMode)
+ {
+ FString outputDir = options.OutputDir;
+ #ifndef UNDER_CE
+ if (outputDir.IsEmpty())
+ GetCurrentDir(outputDir);
+ #endif
+ if (showDialog)
+ {
+ CExtractDialog dialog;
+ FString outputDirFull;
+ if (!MyGetFullPathName(outputDir, outputDirFull))
+ {
+ ShowErrorMessage(kIncorrectOutDir);
+ messageWasDisplayed = true;
+ return E_FAIL;
+ }
+ NName::NormalizeDirPathPrefix(outputDirFull);
+
+ dialog.DirPath = fs2us(outputDirFull);
+
+ dialog.OverwriteMode = options.OverwriteMode;
+ dialog.OverwriteMode_Force = options.OverwriteMode_Force;
+ dialog.PathMode = options.PathMode;
+ dialog.PathMode_Force = options.PathMode_Force;
+ dialog.ElimDup = options.ElimDup;
+
+ if (archivePathsFull.Size() == 1)
+ dialog.ArcPath = archivePathsFull[0];
+
+ #ifndef _SFX
+ // dialog.AltStreams = options.NtOptions.AltStreams;
+ dialog.NtSecurity = options.NtOptions.NtSecurity;
+ if (extractCallback->PasswordIsDefined)
+ dialog.Password = extractCallback->Password;
+ #endif
+
+ if (dialog.Create(hwndParent) != IDOK)
+ return E_ABORT;
+
+ outputDir = us2fs(dialog.DirPath);
+
+ options.OverwriteMode = dialog.OverwriteMode;
+ options.PathMode = dialog.PathMode;
+ options.ElimDup = dialog.ElimDup;
+
+ #ifndef _SFX
+ // options.NtOptions.AltStreams = dialog.AltStreams;
+ options.NtOptions.NtSecurity = dialog.NtSecurity;
+ extractCallback->Password = dialog.Password;
+ extractCallback->PasswordIsDefined = !dialog.Password.IsEmpty();
+ #endif
+ }
+ if (!MyGetFullPathName(outputDir, options.OutputDir))
+ {
+ ShowErrorMessage(kIncorrectOutDir);
+ messageWasDisplayed = true;
+ return E_FAIL;
+ }
+ NName::NormalizeDirPathPrefix(options.OutputDir);
+
+ /*
+ if (!CreateComplexDirectory(options.OutputDir))
+ {
+ UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError()));
+ UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
+ #ifdef LANG
+ 0x02000603,
+ #endif
+ options.OutputDir);
+ s2.Add_LF();
+ s2 += s;
+ MyMessageBox(s2);
+ return E_FAIL;
+ }
+ */
+ }
+
+ UString title = LangString(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING);
+
+ extracter.Title = title;
+ extracter.ExtractCallbackSpec = extractCallback;
+ extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog;
+ extracter.ExtractCallback = extractCallback;
+ extracter.ExtractCallbackSpec->Init();
+
+ extracter.ProgressDialog.CompressingMode = false;
+
+ extracter.ArchivePaths = &archivePaths;
+ extracter.ArchivePathsFull = &archivePathsFull;
+ extracter.WildcardCensor = &wildcardCensor;
+ extracter.Options = &options;
+ #ifndef _SFX
+ extracter.HashBundle = hb;
+ #endif
+
+ extracter.ProgressDialog.IconID = IDI_ICON;
+
+ RINOK(extracter.Create(title, hwndParent));
+ messageWasDisplayed = extracter.ThreadFinishedOK &
+ extracter.ProgressDialog.MessagesDisplayed;
+ return extracter.Result;
+}
diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.h b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.h
new file mode 100644
index 00000000000..d55b30de15c
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.h
@@ -0,0 +1,38 @@
+// GUI/ExtractGUI.h
+
+#ifndef __EXTRACT_GUI_H
+#define __EXTRACT_GUI_H
+
+#include "../Common/Extract.h"
+
+#include "../FileManager/ExtractCallback.h"
+
+/*
+ RESULT can be S_OK, even if there are errors!!!
+ if RESULT == S_OK, check extractCallback->IsOK() after ExtractGUI().
+
+ RESULT = E_ABORT - user break.
+ RESULT != E_ABORT:
+ {
+ messageWasDisplayed = true - message was displayed already.
+ messageWasDisplayed = false - there was some internal error, so you must show error message.
+ }
+*/
+
+HRESULT ExtractGUI(
+ CCodecs *codecs,
+ const CObjectVector<COpenType> &formatIndices,
+ const CIntVector &excludedFormatIndices,
+ UStringVector &archivePaths,
+ UStringVector &archivePathsFull,
+ const NWildcard::CCensorNode &wildcardCensor,
+ CExtractOptions &options,
+ #ifndef _SFX
+ CHashBundle *hb,
+ #endif
+ bool showDialog,
+ bool &messageWasDisplayed,
+ CExtractCallbackImp *extractCallback,
+ HWND hwndParent = NULL);
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractRes.h b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractRes.h
new file mode 100644
index 00000000000..634ba6b5ff9
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractRes.h
@@ -0,0 +1,51 @@
+#define IDS_MEM_ERROR 3000
+
+#define IDS_CANNOT_CREATE_FOLDER 3003
+#define IDS_UPDATE_NOT_SUPPORTED 3004
+#define IDS_CANT_OPEN_ARCHIVE 3005
+#define IDS_CANT_OPEN_ENCRYPTED_ARCHIVE 3006
+#define IDS_UNSUPPORTED_ARCHIVE_TYPE 3007
+
+#define IDS_CANT_OPEN_AS_TYPE 3017
+#define IDS_IS_OPEN_AS_TYPE 3018
+#define IDS_IS_OPEN_WITH_OFFSET 3019
+
+#define IDS_PROGRESS_EXTRACTING 3300
+
+#define IDS_PROGRESS_SKIPPING 3325
+
+#define IDS_EXTRACT_SET_FOLDER 3402
+
+#define IDS_EXTRACT_PATHS_FULL 3411
+#define IDS_EXTRACT_PATHS_NO 3412
+#define IDS_EXTRACT_PATHS_ABS 3413
+#define IDS_PATH_MODE_RELAT 3414
+
+#define IDS_EXTRACT_OVERWRITE_ASK 3421
+#define IDS_EXTRACT_OVERWRITE_WITHOUT_PROMPT 3422
+#define IDS_EXTRACT_OVERWRITE_SKIP_EXISTING 3423
+#define IDS_EXTRACT_OVERWRITE_RENAME 3424
+#define IDS_EXTRACT_OVERWRITE_RENAME_EXISTING 3425
+
+#define IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD 3700
+#define IDS_EXTRACT_MESSAGE_DATA_ERROR 3701
+#define IDS_EXTRACT_MESSAGE_CRC_ERROR 3702
+#define IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED 3703
+#define IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED 3704
+
+#define IDS_EXTRACT_MSG_WRONG_PSW_GUESS 3710
+// #define IDS_EXTRACT_MSG_ENCRYPTED 3711
+
+#define IDS_EXTRACT_MSG_UNSUPPORTED_METHOD 3721
+#define IDS_EXTRACT_MSG_DATA_ERROR 3722
+#define IDS_EXTRACT_MSG_CRC_ERROR 3723
+#define IDS_EXTRACT_MSG_UNAVAILABLE_DATA 3724
+#define IDS_EXTRACT_MSG_UEXPECTED_END 3725
+#define IDS_EXTRACT_MSG_DATA_AFTER_END 3726
+#define IDS_EXTRACT_MSG_IS_NOT_ARC 3727
+#define IDS_EXTRACT_MSG_HEADERS_ERROR 3728
+#define IDS_EXTRACT_MSG_WRONG_PSW_CLAIM 3729
+
+#define IDS_OPEN_MSG_UNAVAILABLE_START 3763
+#define IDS_OPEN_MSG_UNCONFIRMED_START 3764
+#define IDS_OPEN_MSG_UNSUPPORTED_FEATURE 3768
diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/HashGUI.h b/3rdparty/lzma/CPP/7zip/UI/GUI/HashGUI.h
new file mode 100644
index 00000000000..40340365abe
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/GUI/HashGUI.h
@@ -0,0 +1,16 @@
+// HashGUI.h
+
+#ifndef __HASH_GUI_H
+#define __HASH_GUI_H
+
+#include "../Common/HashCalc.h"
+
+HRESULT HashCalcGUI(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const NWildcard::CCensor &censor,
+ const CHashOptions &options,
+ bool &messageWasDisplayed);
+
+void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName);
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/resource2.h b/3rdparty/lzma/CPP/7zip/UI/GUI/resource2.h
new file mode 100644
index 00000000000..cd8829245b1
--- /dev/null
+++ b/3rdparty/lzma/CPP/7zip/UI/GUI/resource2.h
@@ -0,0 +1,2 @@
+#define IDS_PROGRESS_COMPRESSING 3301
+#define IDS_ARCHIVES_COLON 3907
diff --git a/3rdparty/lzma/CPP/Build.mak b/3rdparty/lzma/CPP/Build.mak
index b3465d4410a..ef0ed0c4112 100644
--- a/3rdparty/lzma/CPP/Build.mak
+++ b/3rdparty/lzma/CPP/Build.mak
@@ -1,11 +1,10 @@
LIBS = $(LIBS) oleaut32.lib ole32.lib
-!IFDEF CPU
-!IFNDEF NO_BUFFEROVERFLOWU
-LIBS = $(LIBS) bufferoverflowU.lib
-!ENDIF
+!IFNDEF MY_NO_UNICODE
+CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE
!ENDIF
+# CFLAGS = $(CFLAGS) -FAsc -Fa$O/Asm/
!IFNDEF O
!IFDEF CPU
@@ -43,7 +42,7 @@ COMPL_ASM = $(MY_ML) $** $O/$(*B).obj
COMPL_ASM = $(MY_ML) -c -Fo$O/ $**
!ENDIF
-CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -WX -EHsc -Gy -GR-
+CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -W4 -WX -EHsc -Gy -GR- -GF
!IFDEF MY_STATIC_LINK
!IFNDEF MY_SINGLE_THREAD
@@ -54,9 +53,12 @@ CFLAGS = $(CFLAGS) -MD
!ENDIF
!IFDEF NEW_COMPILER
-CFLAGS = $(CFLAGS) -W4 -GS- -Zc:forScope
+CFLAGS = $(CFLAGS) -GS- -Zc:forScope
+!IFNDEF UNDER_CE
+CFLAGS = $(CFLAGS) -MP2
+!ENDIF
!ELSE
-CFLAGS = $(CFLAGS) -W3
+CFLAGS = $(CFLAGS)
!ENDIF
CFLAGS_O1 = $(CFLAGS) -O1
@@ -72,6 +74,13 @@ LFLAGS = $(LFLAGS) /LARGEADDRESSAWARE
LFLAGS = $(LFLAGS) -DLL -DEF:$(DEF_FILE)
!ENDIF
+MY_SUB_SYS_VER=6.0
+!IFDEF MY_CONSOLE
+# LFLAGS = $(LFLAGS) /SUBSYSTEM:console,$(MY_SUB_SYS_VER)
+!ELSE
+# LFLAGS = $(LFLAGS) /SUBSYSTEM:windows,$(MY_SUB_SYS_VER)
+!ENDIF
+
PROGPATH = $O\$(PROG)
COMPL_O1 = $(CC) $(CFLAGS_O1) $**
@@ -79,15 +88,27 @@ COMPL_O2 = $(CC) $(CFLAGS_O2) $**
COMPL_PCH = $(CC) $(CFLAGS_O1) -Yc"StdAfx.h" -Fp$O/a.pch $**
COMPL = $(CC) $(CFLAGS_O1) -Yu"StdAfx.h" -Fp$O/a.pch $**
+COMPLB = $(CC) $(CFLAGS_O1) -Yu"StdAfx.h" -Fp$O/a.pch $<
+# COMPLB_O2 = $(CC) $(CFLAGS_O2) -Yu"StdAfx.h" -Fp$O/a.pch $<
+COMPLB_O2 = $(CC) $(CFLAGS_O2) $<
+
+CCOMPL_PCH = $(CC) $(CFLAGS_O2) -Yc"Precomp.h" -Fp$O/a.pch $**
+CCOMPL_USE = $(CC) $(CFLAGS_O2) -Yu"Precomp.h" -Fp$O/a.pch $**
+CCOMPL = $(CC) $(CFLAGS_O2) $**
+CCOMPLB = $(CC) $(CFLAGS_O2) $<
+
+
all: $(PROGPATH)
clean:
- -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch
+ -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch $O\*.asm
$O:
if not exist "$O" mkdir "$O"
+$O/Asm:
+ if not exist "$O/Asm" mkdir "$O/Asm"
-$(PROGPATH): $O $(OBJS) $(DEF_FILE)
+$(PROGPATH): $O $O/Asm $(OBJS) $(DEF_FILE)
link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
!IFNDEF NO_DEFAULT_RES
diff --git a/3rdparty/lzma/CPP/Common/Buffer.h b/3rdparty/lzma/CPP/Common/Buffer.h
deleted file mode 100644
index 118fe11fced..00000000000
--- a/3rdparty/lzma/CPP/Common/Buffer.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Common/Buffer.h
-
-#ifndef __COMMON_BUFFER_H
-#define __COMMON_BUFFER_H
-
-#include "Defs.h"
-
-template <class T> class CBuffer
-{
-protected:
- size_t _capacity;
- T *_items;
-public:
- void Free()
- {
- delete []_items;
- _items = 0;
- _capacity = 0;
- }
- CBuffer(): _capacity(0), _items(0) {};
- CBuffer(const CBuffer &buffer): _capacity(0), _items(0) { *this = buffer; }
- CBuffer(size_t size): _items(0), _capacity(0) { SetCapacity(size); }
- virtual ~CBuffer() { delete []_items; }
- operator T *() { return _items; };
- operator const T *() const { return _items; };
- size_t GetCapacity() const { return _capacity; }
- void SetCapacity(size_t newCapacity)
- {
- if (newCapacity == _capacity)
- return;
- T *newBuffer;
- if (newCapacity > 0)
- {
- newBuffer = new T[newCapacity];
- if (_capacity > 0)
- memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T));
- }
- else
- newBuffer = 0;
- delete []_items;
- _items = newBuffer;
- _capacity = newCapacity;
- }
- CBuffer& operator=(const CBuffer &buffer)
- {
- Free();
- if (buffer._capacity > 0)
- {
- SetCapacity(buffer._capacity);
- memmove(_items, buffer._items, buffer._capacity * sizeof(T));
- }
- return *this;
- }
-};
-
-template <class T>
-bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)
-{
- if (b1.GetCapacity() != b2.GetCapacity())
- return false;
- for (size_t i = 0; i < b1.GetCapacity(); i++)
- if (b1[i] != b2[i])
- return false;
- return true;
-}
-
-template <class T>
-bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
-{
- return !(b1 == b2);
-}
-
-typedef CBuffer<char> CCharBuffer;
-typedef CBuffer<wchar_t> CWCharBuffer;
-typedef CBuffer<unsigned char> CByteBuffer;
-
-#endif
diff --git a/3rdparty/lzma/CPP/Common/C_FileIO.h b/3rdparty/lzma/CPP/Common/C_FileIO.h
index ff7a1a1166a..ff4ec162c59 100644
--- a/3rdparty/lzma/CPP/Common/C_FileIO.h
+++ b/3rdparty/lzma/CPP/Common/C_FileIO.h
@@ -6,12 +6,14 @@
#include <stdio.h>
#include <sys/types.h>
-#include "Types.h"
+#include "MyTypes.h"
#include "MyWindows.h"
#ifdef _WIN32
+#ifdef _MSC_VER
typedef size_t ssize_t;
#endif
+#endif
namespace NC {
namespace NFile {
diff --git a/3rdparty/lzma/CPP/Common/CommandLineParser.cpp b/3rdparty/lzma/CPP/Common/CommandLineParser.cpp
index 80b467fcb58..1c7f26547c8 100644
--- a/3rdparty/lzma/CPP/Common/CommandLineParser.cpp
+++ b/3rdparty/lzma/CPP/Common/CommandLineParser.cpp
@@ -4,6 +4,20 @@
#include "CommandLineParser.h"
+static bool IsString1PrefixedByString2_NoCase(const wchar_t *u, const char *a)
+{
+ for (;;)
+ {
+ char c = *a;
+ if (c == 0)
+ return true;
+ if ((unsigned char)MyCharLower_Ascii(c) != MyCharLower_Ascii(*u))
+ return false;
+ a++;
+ u++;
+ }
+}
+
namespace NCommandLineParser {
bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
@@ -11,13 +25,13 @@ bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
dest1.Empty();
dest2.Empty();
bool quoteMode = false;
- int i;
- for (i = 0; i < src.Length(); i++)
+ unsigned i;
+ for (i = 0; i < src.Len(); i++)
{
wchar_t c = src[i];
- if (c == L' ' && !quoteMode)
+ if ((c == L' ' || c == L'\t') && !quoteMode)
{
- dest2 = src.Mid(i + 1);
+ dest2 = src.Ptr(i + 1);
return i != 0;
}
if (c == L'\"')
@@ -45,21 +59,18 @@ void SplitCommandLine(const UString &s, UStringVector &parts)
}
-static const wchar_t kSwitchID1 = '-';
-// static const wchar_t kSwitchID2 = '/';
+static const char *kStopSwitchParsing = "--";
-static const wchar_t kSwitchMinus = '-';
-static const wchar_t *kStopSwitchParsing = L"--";
-
-static bool IsItSwitchChar(wchar_t c)
+static bool inline IsItSwitchChar(wchar_t c)
{
- return (c == kSwitchID1 /*|| c == kSwitchID2 */);
+ return (c == '-');
}
-CParser::CParser(int numSwitches):
- _numSwitches(numSwitches)
+CParser::CParser(unsigned numSwitches):
+ _numSwitches(numSwitches),
+ _switches(0)
{
- _switches = new CSwitchResult[_numSwitches];
+ _switches = new CSwitchResult[numSwitches];
}
CParser::~CParser()
@@ -67,163 +78,126 @@ CParser::~CParser()
delete []_switches;
}
-void CParser::ParseStrings(const CSwitchForm *switchForms,
- const UStringVector &commandStrings)
-{
- int numCommandStrings = commandStrings.Size();
- bool stopSwitch = false;
- for (int i = 0; i < numCommandStrings; i++)
- {
- const UString &s = commandStrings[i];
- if (stopSwitch)
- NonSwitchStrings.Add(s);
- else
- if (s == kStopSwitchParsing)
- stopSwitch = true;
- else
- if (!ParseString(s, switchForms))
- NonSwitchStrings.Add(s);
- }
-}
-// if string contains switch then function updates switch structures
-// out: (string is a switch)
+// if (s) contains switch then function updates switch structures
+// out: true, if (s) is a switch
bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
{
- int len = s.Length();
- if (len == 0)
- return false;
- int pos = 0;
- if (!IsItSwitchChar(s[pos]))
+ if (s.IsEmpty() || !IsItSwitchChar(s[0]))
return false;
- while (pos < len)
+
+ unsigned pos = 1;
+ unsigned switchIndex = 0;
+ int maxLen = -1;
+
+ for (unsigned i = 0; i < _numSwitches; i++)
{
- if (IsItSwitchChar(s[pos]))
- pos++;
- const int kNoLen = -1;
- int matchedSwitchIndex = 0; // GCC Warning
- int maxLen = kNoLen;
- for (int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)
+ const char *key = switchForms[i].Key;
+ unsigned switchLen = MyStringLen(key);
+ if ((int)switchLen <= maxLen || pos + switchLen > s.Len())
+ continue;
+ if (IsString1PrefixedByString2_NoCase((const wchar_t *)s + pos, key))
{
- int switchLen = MyStringLen(switchForms[switchIndex].IDString);
- if (switchLen <= maxLen || pos + switchLen > len)
- continue;
+ switchIndex = i;
+ maxLen = switchLen;
+ }
+ }
+
+ if (maxLen < 0)
+ {
+ ErrorMessage = "Unknown switch:";
+ return false;
+ }
- UString temp = s + pos;
- temp = temp.Left(switchLen);
- if (temp.CompareNoCase(switchForms[switchIndex].IDString) == 0)
- // if (_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0)
+ pos += maxLen;
+
+ CSwitchResult &sw = _switches[switchIndex];
+ const CSwitchForm &form = switchForms[switchIndex];
+
+ if (!form.Multi && sw.ThereIs)
+ {
+ ErrorMessage = "Multiple instances for switch:";
+ return false;
+ }
+
+ sw.ThereIs = true;
+
+ int rem = s.Len() - pos;
+ if (rem < form.MinLen)
+ {
+ ErrorMessage = "Too short switch:";
+ return false;
+ }
+
+ sw.WithMinus = false;
+ sw.PostCharIndex = -1;
+
+ switch (form.Type)
+ {
+ case NSwitchType::kMinus:
+ if (rem == 1)
{
- matchedSwitchIndex = switchIndex;
- maxLen = switchLen;
+ sw.WithMinus = (s[pos] == '-');
+ if (sw.WithMinus)
+ return true;
+ ErrorMessage = "Incorrect switch postfix:";
+ return false;
}
- }
- if (maxLen == kNoLen)
- throw "maxLen == kNoLen";
- CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];
- const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];
- if ((!switchForm.Multi) && matchedSwitch.ThereIs)
- throw "switch must be single";
- matchedSwitch.ThereIs = true;
- pos += maxLen;
- int tailSize = len - pos;
- NSwitchType::EEnum type = switchForm.Type;
- switch(type)
- {
- case NSwitchType::kPostMinus:
- {
- if (tailSize == 0)
- matchedSwitch.WithMinus = false;
- else
- {
- matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);
- if (matchedSwitch.WithMinus)
- pos++;
- }
- break;
- }
- case NSwitchType::kPostChar:
- {
- if (tailSize < switchForm.MinLen)
- throw "switch is not full";
- UString set = switchForm.PostCharSet;
- const int kEmptyCharValue = -1;
- if (tailSize == 0)
- matchedSwitch.PostCharIndex = kEmptyCharValue;
- else
- {
- int index = set.Find(s[pos]);
- if (index < 0)
- matchedSwitch.PostCharIndex = kEmptyCharValue;
- else
- {
- matchedSwitch.PostCharIndex = index;
- pos++;
- }
- }
- break;
- }
- case NSwitchType::kLimitedPostString:
- case NSwitchType::kUnLimitedPostString:
+ break;
+
+ case NSwitchType::kChar:
+ if (rem == 1)
+ {
+ wchar_t c = s[pos];
+ if (c <= 0x7F)
{
- int minLen = switchForm.MinLen;
- if (tailSize < minLen)
- throw "switch is not full";
- if (type == NSwitchType::kUnLimitedPostString)
- {
- matchedSwitch.PostStrings.Add(s.Mid(pos));
+ sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c);
+ if (sw.PostCharIndex >= 0)
return true;
- }
- int maxLen = switchForm.MaxLen;
- UString stringSwitch = s.Mid(pos, minLen);
- pos += minLen;
- for (int i = minLen; i < maxLen && pos < len; i++, pos++)
- {
- wchar_t c = s[pos];
- if (IsItSwitchChar(c))
- break;
- stringSwitch += c;
- }
- matchedSwitch.PostStrings.Add(stringSwitch);
- break;
}
- case NSwitchType::kSimple:
- break;
- }
+ ErrorMessage = "Incorrect switch postfix:";
+ return false;
+ }
+ break;
+
+ case NSwitchType::kString:
+ sw.PostStrings.Add((const wchar_t *)s + pos);
+ return true;
}
- return true;
-}
-const CSwitchResult& CParser::operator[](size_t index) const
-{
- return _switches[index];
+ if (pos != s.Len())
+ {
+ ErrorMessage = "Too long switch:";
+ return false;
+ }
+ return true;
}
-/////////////////////////////////
-// Command parsing procedures
-
-int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
- const UString &commandString, UString &postString)
+bool CParser::ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings)
{
- for (int i = 0; i < numCommandForms; i++)
+ ErrorLine.Empty();
+ bool stopSwitch = false;
+ FOR_VECTOR (i, commandStrings)
{
- const UString id = commandForms[i].IDString;
- if (commandForms[i].PostStringMode)
+ const UString &s = commandStrings[i];
+ if (!stopSwitch)
{
- if (commandString.Find(id) == 0)
+ if (s.IsEqualTo(kStopSwitchParsing))
{
- postString = commandString.Mid(id.Length());
- return i;
+ stopSwitch = true;
+ continue;
}
- }
- else
- if (commandString == id)
+ if (!s.IsEmpty() && IsItSwitchChar(s[0]))
{
- postString.Empty();
- return i;
+ if (ParseString(s, switchForms))
+ continue;
+ ErrorLine = s;
+ return false;
}
+ }
+ NonSwitchStrings.Add(s);
}
- return -1;
+ return true;
}
-
+
}
diff --git a/3rdparty/lzma/CPP/Common/CommandLineParser.h b/3rdparty/lzma/CPP/Common/CommandLineParser.h
index 3d0b41dd47b..c9fd2956186 100644
--- a/3rdparty/lzma/CPP/Common/CommandLineParser.h
+++ b/3rdparty/lzma/CPP/Common/CommandLineParser.h
@@ -10,63 +10,54 @@ namespace NCommandLineParser {
bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2);
void SplitCommandLine(const UString &s, UStringVector &parts);
-namespace NSwitchType {
+namespace NSwitchType
+{
enum EEnum
{
kSimple,
- kPostMinus,
- kLimitedPostString,
- kUnLimitedPostString,
- kPostChar
+ kMinus,
+ kString,
+ kChar
};
}
struct CSwitchForm
{
- const wchar_t *IDString;
- NSwitchType::EEnum Type;
+ const char *Key;
+ Byte Type;
bool Multi;
- int MinLen;
- int MaxLen;
- const wchar_t *PostCharSet;
+ Byte MinLen;
+ // int MaxLen;
+ const char *PostCharSet;
};
struct CSwitchResult
{
bool ThereIs;
bool WithMinus;
- UStringVector PostStrings;
int PostCharIndex;
+ UStringVector PostStrings;
+
CSwitchResult(): ThereIs(false) {};
};
class CParser
{
- int _numSwitches;
+ unsigned _numSwitches;
CSwitchResult *_switches;
+
bool ParseString(const UString &s, const CSwitchForm *switchForms);
public:
UStringVector NonSwitchStrings;
- CParser(int numSwitches);
+ AString ErrorMessage;
+ UString ErrorLine;
+
+ CParser(unsigned numSwitches);
~CParser();
- void ParseStrings(const CSwitchForm *switchForms,
- const UStringVector &commandStrings);
- const CSwitchResult& operator[](size_t index) const;
+ bool ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings);
+ const CSwitchResult& operator[](size_t index) const { return _switches[index]; }
};
-/////////////////////////////////
-// Command parsing procedures
-
-struct CCommandForm
-{
- const wchar_t *IDString;
- bool PostStringMode;
-};
-
-// Returns: Index of form and postString; -1, if there is no match
-int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
- const UString &commandString, UString &postString);
-
}
#endif
diff --git a/3rdparty/lzma/CPP/Common/Common.h b/3rdparty/lzma/CPP/Common/Common.h
new file mode 100644
index 00000000000..9dd30f4bef2
--- /dev/null
+++ b/3rdparty/lzma/CPP/Common/Common.h
@@ -0,0 +1,13 @@
+// Common.h
+
+#ifndef __COMMON_COMMON_H
+#define __COMMON_COMMON_H
+
+#include "../../C/Compiler.h"
+
+#include "MyWindows.h"
+#include "NewHandler.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[1]))
+
+#endif
diff --git a/3rdparty/lzma/CPP/Common/CrcReg.cpp b/3rdparty/lzma/CPP/Common/CrcReg.cpp
new file mode 100644
index 00000000000..2c343b3108a
--- /dev/null
+++ b/3rdparty/lzma/CPP/Common/CrcReg.cpp
@@ -0,0 +1,98 @@
+// CrcReg.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/7zCrc.h"
+#include "../../C/CpuArch.h"
+
+#include "../Common/MyCom.h"
+
+#include "../7zip/Common/RegisterCodec.h"
+
+EXTERN_C_BEGIN
+
+typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
+
+UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table);
+
+extern CRC_FUNC g_CrcUpdate;
+extern CRC_FUNC g_CrcUpdateT8;
+extern CRC_FUNC g_CrcUpdateT4;
+
+EXTERN_C_END
+
+class CCrcHasher:
+ public IHasher,
+ public ICompressSetCoderProperties,
+ public CMyUnknownImp
+{
+ UInt32 _crc;
+ CRC_FUNC _updateFunc;
+ Byte mtDummy[1 << 7];
+
+ bool SetFunctions(UInt32 tSize);
+public:
+ CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); }
+
+ MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
+ INTERFACE_IHasher(;)
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+};
+
+bool CCrcHasher::SetFunctions(UInt32 tSize)
+{
+ _updateFunc = g_CrcUpdate;
+
+ if (tSize == 1)
+ _updateFunc = CrcUpdateT1;
+ else if (tSize == 4)
+ {
+ if (g_CrcUpdateT4)
+ _updateFunc = g_CrcUpdateT4;
+ else
+ return false;
+ }
+ else if (tSize == 8)
+ {
+ if (g_CrcUpdateT8)
+ _updateFunc = g_CrcUpdateT8;
+ else
+ return false;
+ }
+
+ return true;
+}
+
+STDMETHODIMP CCrcHasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ if (propIDs[i] == NCoderPropID::kDefaultProp)
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ if (!SetFunctions(prop.ulVal))
+ return E_NOTIMPL;
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP_(void) CCrcHasher::Init() throw()
+{
+ _crc = CRC_INIT_VAL;
+}
+
+STDMETHODIMP_(void) CCrcHasher::Update(const void *data, UInt32 size) throw()
+{
+ _crc = _updateFunc(_crc, data, size, g_CrcTable);
+}
+
+STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest) throw()
+{
+ UInt32 val = CRC_GET_DIGEST(_crc);
+ SetUi32(digest, val);
+}
+
+REGISTER_HASHER(CCrcHasher, 0x1, "CRC32", 4)
diff --git a/3rdparty/lzma/CPP/Common/Defs.h b/3rdparty/lzma/CPP/Common/Defs.h
index dad3ae8f11d..1fbd78bda7f 100644
--- a/3rdparty/lzma/CPP/Common/Defs.h
+++ b/3rdparty/lzma/CPP/Common/Defs.h
@@ -3,18 +3,13 @@
#ifndef __COMMON_DEFS_H
#define __COMMON_DEFS_H
-template <class T> inline T MyMin(T a, T b)
- { return a < b ? a : b; }
-template <class T> inline T MyMax(T a, T b)
- { return a > b ? a : b; }
+template <class T> inline T MyMin(T a, T b) { return a < b ? a : b; }
+template <class T> inline T MyMax(T a, T b) { return a > b ? a : b; }
template <class T> inline int MyCompare(T a, T b)
- { return a < b ? -1 : (a == b ? 0 : 1); }
+ { return a == b ? 0 : (a < b ? -1 : 1); }
-inline int BoolToInt(bool value)
- { return (value ? 1: 0); }
-
-inline bool IntToBool(int value)
- { return (value != 0); }
+inline int BoolToInt(bool v) { return (v ? 1 : 0); }
+inline bool IntToBool(int v) { return (v != 0); }
#endif
diff --git a/3rdparty/lzma/CPP/Common/DynamicBuffer.h b/3rdparty/lzma/CPP/Common/DynamicBuffer.h
index bf52a7425a8..44e3df7fd4a 100644
--- a/3rdparty/lzma/CPP/Common/DynamicBuffer.h
+++ b/3rdparty/lzma/CPP/Common/DynamicBuffer.h
@@ -3,48 +3,62 @@
#ifndef __COMMON_DYNAMIC_BUFFER_H
#define __COMMON_DYNAMIC_BUFFER_H
-#include "Buffer.h"
-
-template <class T> class CDynamicBuffer: public CBuffer<T>
+template <class T> class CDynamicBuffer
{
- void GrowLength(size_t size)
+ T *_items;
+ size_t _size;
+ size_t _pos;
+
+ CDynamicBuffer(const CDynamicBuffer &buffer);
+ void operator=(const CDynamicBuffer &buffer);
+
+ void Grow(size_t size)
{
- size_t delta;
- if (this->_capacity > 64)
- delta = this->_capacity / 4;
- else if (this->_capacity > 8)
- delta = 16;
- else
- delta = 4;
- delta = MyMax(delta, size);
- size_t newCap = this->_capacity + delta;
+ size_t delta = _size >= 64 ? _size : 64;
+ if (delta < size)
+ delta = size;
+ size_t newCap = _size + delta;
if (newCap < delta)
- newCap = this->_capacity + size;
- SetCapacity(newCap);
+ {
+ newCap = _size + size;
+ if (newCap < size)
+ throw 20120116;
+ }
+
+ T *newBuffer = new T[newCap];
+ if (_pos != 0)
+ memcpy(newBuffer, _items, _pos * sizeof(T));
+ delete []_items;
+ _items = newBuffer;
+ _size = newCap;
}
+
public:
- CDynamicBuffer(): CBuffer<T>() {};
- CDynamicBuffer(const CDynamicBuffer &buffer): CBuffer<T>(buffer) {};
- CDynamicBuffer(size_t size): CBuffer<T>(size) {};
- CDynamicBuffer& operator=(const CDynamicBuffer &buffer)
+ CDynamicBuffer(): _items(0), _size(0), _pos(0) {}
+ // operator T *() { return _items; }
+ operator const T *() const { return _items; }
+ ~CDynamicBuffer() { delete []_items; }
+
+ T *GetCurPtrAndGrow(size_t addSize)
{
- this->Free();
- if (buffer._capacity > 0)
- {
- SetCapacity(buffer._capacity);
- memmove(this->_items, buffer._items, buffer._capacity * sizeof(T));
- }
- return *this;
+ size_t rem = _size - _pos;
+ if (rem < addSize)
+ Grow(addSize - rem);
+ T *res = _items + _pos;
+ _pos += addSize;
+ return res;
}
- void EnsureCapacity(size_t capacity)
+
+ void AddData(const T *data, size_t size)
{
- if (this->_capacity < capacity)
- GrowLength(capacity - this->_capacity);
+ memcpy(GetCurPtrAndGrow(size), data, size * sizeof(T));
}
+
+ const size_t GetPos() const { return _pos; }
+
+ // void Empty() { _pos = 0; }
};
-typedef CDynamicBuffer<char> CCharDynamicBuffer;
-typedef CDynamicBuffer<wchar_t> CWCharDynamicBuffer;
typedef CDynamicBuffer<unsigned char> CByteDynamicBuffer;
#endif
diff --git a/3rdparty/lzma/CPP/Common/IntToString.cpp b/3rdparty/lzma/CPP/Common/IntToString.cpp
index 013fee5277f..ed217c72c0a 100644
--- a/3rdparty/lzma/CPP/Common/IntToString.cpp
+++ b/3rdparty/lzma/CPP/Common/IntToString.cpp
@@ -4,74 +4,143 @@
#include "IntToString.h"
-void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base)
+#define CONVERT_INT_TO_STR(charType, tempSize) \
+ unsigned char temp[tempSize]; unsigned i = 0; \
+ while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
+ *s++ = (charType)('0' + (unsigned)val); \
+ while (i != 0) { i--; *s++ = temp[i]; } \
+ *s = 0;
+
+void ConvertUInt32ToString(UInt32 val, char *s) throw()
{
- if (base < 2 || base > 36)
+ CONVERT_INT_TO_STR(char, 16);
+}
+
+void ConvertUInt64ToString(UInt64 val, char *s) throw()
+{
+ if (val <= (UInt32)0xFFFFFFFF)
{
- *s = '\0';
+ ConvertUInt32ToString((UInt32)val, s);
return;
}
- char temp[72];
- int pos = 0;
- do
+ CONVERT_INT_TO_STR(char, 24);
+}
+
+void ConvertUInt64ToOct(UInt64 val, char *s) throw()
+{
+ UInt64 v = val;
+ unsigned i;
+ for (i = 1;; i++)
{
- int delta = (int)(value % base);
- temp[pos++] = (char)((delta < 10) ? ('0' + delta) : ('a' + (delta - 10)));
- value /= base;
+ v >>= 3;
+ if (v == 0)
+ break;
}
- while (value != 0);
+ s[i] = 0;
do
- *s++ = temp[--pos];
- while (pos > 0);
- *s = '\0';
+ {
+ unsigned t = (unsigned)(val & 0x7);
+ val >>= 3;
+ s[--i] = (char)('0' + t);
+ }
+ while (i);
}
-void ConvertUInt64ToString(UInt64 value, wchar_t *s)
+void ConvertUInt32ToHex(UInt32 val, char *s) throw()
{
- wchar_t temp[32];
- int pos = 0;
+ UInt32 v = val;
+ unsigned i;
+ for (i = 1;; i++)
+ {
+ v >>= 4;
+ if (v == 0)
+ break;
+ }
+ s[i] = 0;
do
{
- temp[pos++] = (wchar_t)(L'0' + (int)(value % 10));
- value /= 10;
+ unsigned t = (unsigned)((val & 0xF));
+ val >>= 4;
+ s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
- while (value != 0);
+ while (i);
+}
+
+void ConvertUInt64ToHex(UInt64 val, char *s) throw()
+{
+ UInt64 v = val;
+ unsigned i;
+ for (i = 1;; i++)
+ {
+ v >>= 4;
+ if (v == 0)
+ break;
+ }
+ s[i] = 0;
do
- *s++ = temp[--pos];
- while (pos > 0);
- *s = L'\0';
+ {
+ unsigned t = (unsigned)((val & 0xF));
+ val >>= 4;
+ s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ }
+ while (i);
}
-void ConvertUInt32ToString(UInt32 value, char *s) { ConvertUInt64ToString(value, s); }
-void ConvertUInt32ToString(UInt32 value, wchar_t *s) { ConvertUInt64ToString(value, s); }
+void ConvertUInt32ToHex8Digits(UInt32 val, char *s) throw()
+{
+ s[8] = 0;
+ for (int i = 7; i >= 0; i--)
+ {
+ unsigned t = val & 0xF;
+ val >>= 4;
+ s[i] = (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10))));
+ }
+}
-void ConvertInt64ToString(Int64 value, char *s)
+/*
+void ConvertUInt32ToHex8Digits(UInt32 val, wchar_t *s)
{
- if (value < 0)
+ s[8] = 0;
+ for (int i = 7; i >= 0; i--)
{
- *s++ = '-';
- value = -value;
+ unsigned t = val & 0xF;
+ val >>= 4;
+ s[i] = (wchar_t)(((t < 10) ? ('0' + t) : ('A' + (t - 10))));
+ }
+}
+*/
+
+void ConvertUInt32ToString(UInt32 val, wchar_t *s) throw()
+{
+ CONVERT_INT_TO_STR(wchar_t, 16);
+}
+
+void ConvertUInt64ToString(UInt64 val, wchar_t *s) throw()
+{
+ if (val <= (UInt32)0xFFFFFFFF)
+ {
+ ConvertUInt32ToString((UInt32)val, s);
+ return;
}
- ConvertUInt64ToString(value, s);
+ CONVERT_INT_TO_STR(wchar_t, 24);
}
-void ConvertInt64ToString(Int64 value, wchar_t *s)
+void ConvertInt64ToString(Int64 val, char *s) throw()
{
- if (value < 0)
+ if (val < 0)
{
- *s++ = L'-';
- value = -value;
+ *s++ = '-';
+ val = -val;
}
- ConvertUInt64ToString(value, s);
+ ConvertUInt64ToString(val, s);
}
-void ConvertUInt32ToHexWithZeros(UInt32 value, char *s)
+void ConvertInt64ToString(Int64 val, wchar_t *s) throw()
{
- for (int i = 0; i < 8; i++)
+ if (val < 0)
{
- int t = value & 0xF;
- value >>= 4;
- s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ *s++ = L'-';
+ val = -val;
}
- s[8] = '\0';
+ ConvertUInt64ToString(val, s);
}
diff --git a/3rdparty/lzma/CPP/Common/IntToString.h b/3rdparty/lzma/CPP/Common/IntToString.h
index 782f930c56e..69605ab76ce 100644
--- a/3rdparty/lzma/CPP/Common/IntToString.h
+++ b/3rdparty/lzma/CPP/Common/IntToString.h
@@ -3,17 +3,22 @@
#ifndef __COMMON_INT_TO_STRING_H
#define __COMMON_INT_TO_STRING_H
-#include <stddef.h>
-#include "Types.h"
+#include "MyTypes.h"
-void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base = 10);
-void ConvertUInt64ToString(UInt64 value, wchar_t *s);
-void ConvertInt64ToString(Int64 value, char *s);
-void ConvertInt64ToString(Int64 value, wchar_t *s);
+void ConvertUInt32ToString(UInt32 value, char *s) throw();
+void ConvertUInt64ToString(UInt64 value, char *s) throw();
-void ConvertUInt32ToString(UInt32 value, char *s);
-void ConvertUInt32ToString(UInt32 value, wchar_t *s);
+void ConvertUInt32ToString(UInt32 value, wchar_t *s) throw();
+void ConvertUInt64ToString(UInt64 value, wchar_t *s) throw();
-void ConvertUInt32ToHexWithZeros(UInt32 value, char *s);
+void ConvertUInt64ToOct(UInt64 value, char *s) throw();
+
+void ConvertUInt32ToHex(UInt32 value, char *s) throw();
+void ConvertUInt64ToHex(UInt64 value, char *s) throw();
+void ConvertUInt32ToHex8Digits(UInt32 value, char *s) throw();
+// void ConvertUInt32ToHex8Digits(UInt32 value, wchar_t *s) throw();
+
+void ConvertInt64ToString(Int64 value, char *s) throw();
+void ConvertInt64ToString(Int64 value, wchar_t *s) throw();
#endif
diff --git a/3rdparty/lzma/CPP/Common/Lang.h b/3rdparty/lzma/CPP/Common/Lang.h
new file mode 100644
index 00000000000..22e42574eaa
--- /dev/null
+++ b/3rdparty/lzma/CPP/Common/Lang.h
@@ -0,0 +1,23 @@
+// Common/Lang.h
+
+#ifndef __COMMON_LANG_H
+#define __COMMON_LANG_H
+
+#include "MyString.h"
+
+class CLang
+{
+ wchar_t *_text;
+ CRecordVector<UInt32> _ids;
+ CRecordVector<UInt32> _offsets;
+
+ bool OpenFromString(const AString &s);
+public:
+ CLang(): _text(0) {}
+ ~CLang() { Clear(); }
+ bool Open(CFSTR fileName, const wchar_t *id);
+ void Clear() throw();
+ const wchar_t *Get(UInt32 id) const throw();
+};
+
+#endif
diff --git a/3rdparty/lzma/CPP/Common/ListFileUtils.cpp b/3rdparty/lzma/CPP/Common/ListFileUtils.cpp
index f9bd18ed3c3..3bf4ec29d9f 100644
--- a/3rdparty/lzma/CPP/Common/ListFileUtils.cpp
+++ b/3rdparty/lzma/CPP/Common/ListFileUtils.cpp
@@ -2,75 +2,116 @@
#include "StdAfx.h"
-#include "MyWindows.h"
+#include "../../C/CpuArch.h"
+
#include "../Windows/FileIO.h"
#include "ListFileUtils.h"
+#include "MyBuffer.h"
#include "StringConvert.h"
#include "UTFConvert.h"
static const char kQuoteChar = '\"';
-static void RemoveQuote(UString &s)
+static void AddName(UStringVector &strings, UString &s)
{
- if (s.Length() >= 2)
- if (s[0] == kQuoteChar && s.Back() == kQuoteChar)
- s = s.Mid(1, s.Length() - 2);
+ s.Trim();
+ if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar)
+ {
+ s.DeleteBack();
+ s.Delete(0);
+ }
+ if (!s.IsEmpty())
+ strings.Add(s);
}
-bool ReadNamesFromListFile(CFSTR fileName, UStringVector &resultStrings, UINT codePage)
+bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage)
{
NWindows::NFile::NIO::CInFile file;
if (!file.Open(fileName))
return false;
- UInt64 length;
- if (!file.GetLength(length))
- return false;
- if (length > ((UInt32)1 << 31))
+ UInt64 fileSize;
+ if (!file.GetLength(fileSize))
return false;
- AString s;
- char *p = s.GetBuffer((int)length + 1);
- UInt32 processed;
- if (!file.Read(p, (UInt32)length, processed))
+ if (fileSize >= ((UInt32)1 << 31) - 32)
return false;
- p[(UInt32)length] = 0;
- s.ReleaseBuffer();
- file.Close();
-
UString u;
- #ifdef CP_UTF8
- if (codePage == CP_UTF8)
+ if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE)
{
- if (!ConvertUTF8ToUnicode(s, u))
+ if ((fileSize & 1) != 0)
+ return false;
+ CByteArr buf((size_t)fileSize);
+ UInt32 processed;
+ if (!file.Read(buf, (UInt32)fileSize, processed))
return false;
+ if (processed != fileSize)
+ return false;
+ file.Close();
+ unsigned num = (unsigned)fileSize / 2;
+ wchar_t *p = u.GetBuf(num);
+ if (codePage == MY__CP_UTF16)
+ for (unsigned i = 0; i < num; i++)
+ {
+ wchar_t c = GetUi16(buf + i * 2);
+ if (c == 0)
+ return false;
+ p[i] = c;
+ }
+ else
+ for (unsigned i = 0; i < num; i++)
+ {
+ wchar_t c = (wchar_t)GetBe16(buf + i * 2);
+ if (c == 0)
+ return false;
+ p[i] = c;
+ }
+ p[num] = 0;
+ u.ReleaseBuf_SetLen(num);
}
else
- #endif
- u = MultiByteToUnicodeString(s, codePage);
- if (!u.IsEmpty())
{
- if (u[0] == 0xFEFF)
- u.Delete(0);
+ AString s;
+ char *p = s.GetBuf((unsigned)fileSize);
+ UInt32 processed;
+ if (!file.Read(p, (UInt32)fileSize, processed))
+ return false;
+ if (processed != fileSize)
+ return false;
+ file.Close();
+ s.ReleaseBuf_CalcLen((unsigned)processed);
+ if (s.Len() != processed)
+ return false;
+
+ // #ifdef CP_UTF8
+ if (codePage == CP_UTF8)
+ {
+ if (!ConvertUTF8ToUnicode(s, u))
+ return false;
+ }
+ else
+ // #endif
+ MultiByteToUnicodeString2(u, s, codePage);
}
- UString t;
- for (int i = 0; i < u.Length(); i++)
+ const wchar_t kGoodBOM = 0xFEFF;
+ const wchar_t kBadBOM = 0xFFFE;
+
+ UString s;
+ unsigned i = 0;
+ for (; i < u.Len() && u[i] == kGoodBOM; i++);
+ for (; i < u.Len(); i++)
{
wchar_t c = u[i];
+ if (c == kGoodBOM || c == kBadBOM)
+ return false;
if (c == L'\n' || c == 0xD)
{
- t.Trim();
- RemoveQuote(t);
- if (!t.IsEmpty())
- resultStrings.Add(t);
- t.Empty();
+ AddName(strings, s);
+ s.Empty();
}
else
- t += c;
+ s += c;
}
- t.Trim();
- RemoveQuote(t);
- if (!t.IsEmpty())
- resultStrings.Add(t);
+ AddName(strings, s);
return true;
}
diff --git a/3rdparty/lzma/CPP/Common/ListFileUtils.h b/3rdparty/lzma/CPP/Common/ListFileUtils.h
index d43bfdfc140..e8d833fdb8c 100644
--- a/3rdparty/lzma/CPP/Common/ListFileUtils.h
+++ b/3rdparty/lzma/CPP/Common/ListFileUtils.h
@@ -4,7 +4,10 @@
#define __COMMON_LIST_FILE_UTILS_H
#include "MyString.h"
-#include "Types.h"
+#include "MyTypes.h"
+
+#define MY__CP_UTF16 1200
+#define MY__CP_UTF16BE 1201
bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP);
diff --git a/3rdparty/lzma/CPP/Common/MyBuffer.h b/3rdparty/lzma/CPP/Common/MyBuffer.h
new file mode 100644
index 00000000000..d0378057a95
--- /dev/null
+++ b/3rdparty/lzma/CPP/Common/MyBuffer.h
@@ -0,0 +1,244 @@
+// Common/MyBuffer.h
+
+#ifndef __COMMON_MY_BUFFER_H
+#define __COMMON_MY_BUFFER_H
+
+#include "Defs.h"
+
+template <class T> class CBuffer
+{
+ T *_items;
+ size_t _size;
+
+public:
+ void Free()
+ {
+ if (_items)
+ {
+ delete []_items;
+ _items = 0;
+ }
+ _size = 0;
+ }
+
+ CBuffer(): _items(0), _size(0) {};
+ CBuffer(size_t size): _items(0), _size(0) { _items = new T[size]; _size = size; }
+ CBuffer(const CBuffer &buffer): _items(0), _size(0)
+ {
+ size_t size = buffer._size;
+ if (size != 0)
+ {
+ _items = new T[size];
+ memcpy(_items, buffer._items, size * sizeof(T));
+ _size = size;
+ }
+ }
+
+ ~CBuffer() { delete []_items; }
+
+ operator T *() { return _items; }
+ operator const T *() const { return _items; }
+ size_t Size() const { return _size; }
+
+ void Alloc(size_t size)
+ {
+ if (size != _size)
+ {
+ Free();
+ if (size != 0)
+ {
+ _items = new T[size];
+ _size = size;
+ }
+ }
+ }
+
+ void AllocAtLeast(size_t size)
+ {
+ if (size > _size)
+ {
+ Free();
+ _items = new T[size];
+ _size = size;
+ }
+ }
+
+ void CopyFrom(const T *data, size_t size)
+ {
+ Alloc(size);
+ if (size != 0)
+ memcpy(_items, data, size * sizeof(T));
+ }
+
+ void ChangeSize_KeepData(size_t newSize, size_t keepSize)
+ {
+ if (newSize == _size)
+ return;
+ T *newBuffer = NULL;
+ if (newSize != 0)
+ {
+ newBuffer = new T[newSize];
+ if (keepSize > _size)
+ keepSize = _size;
+ if (keepSize != 0)
+ memcpy(newBuffer, _items, MyMin(keepSize, newSize) * sizeof(T));
+ }
+ delete []_items;
+ _items = newBuffer;
+ _size = newSize;
+ }
+
+ CBuffer& operator=(const CBuffer &buffer)
+ {
+ if (&buffer != this)
+ CopyFrom(buffer, buffer._size);
+ return *this;
+ }
+};
+
+template <class T>
+bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ size_t size1 = b1.Size();
+ if (size1 != b2.Size())
+ return false;
+ if (size1 == 0)
+ return true;
+ return memcmp(b1, b2, size1 * sizeof(T)) == 0;
+}
+
+template <class T>
+bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ size_t size1 = b1.Size();
+ if (size1 != b2.Size())
+ return true;
+ if (size1 == 0)
+ return false;
+ return memcmp(b1, b2, size1 * sizeof(T)) != 0;
+}
+
+
+typedef CBuffer<char> CCharBuffer;
+// typedef CBuffer<wchar_t> CWCharBuffer;
+typedef CBuffer<unsigned char> CByteBuffer;
+
+
+template <class T> class CObjArray
+{
+protected:
+ T *_items;
+private:
+ // we disable constructors
+ CObjArray(const CObjArray &buffer);
+ void operator=(const CObjArray &buffer);
+public:
+ void Free()
+ {
+ delete []_items;
+ _items = 0;
+ }
+ CObjArray(size_t size): _items(0) { if (size != 0) _items = new T[size]; }
+ CObjArray(): _items(0) {};
+ ~CObjArray() { delete []_items; }
+
+ operator T *() { return _items; }
+ operator const T *() const { return _items; }
+
+ void Alloc(size_t newSize)
+ {
+ delete []_items;
+ _items = 0;
+ _items = new T[newSize];
+ }
+};
+
+typedef CObjArray<unsigned char> CByteArr;
+typedef CObjArray<bool> CBoolArr;
+typedef CObjArray<int> CIntArr;
+typedef CObjArray<unsigned> CUIntArr;
+
+
+template <class T> class CObjArray2
+{
+ T *_items;
+ unsigned _size;
+
+ CObjArray2(const CObjArray2 &buffer);
+ void operator=(const CObjArray2 &buffer);
+public:
+
+ void Free()
+ {
+ delete []_items;
+ _items = 0;
+ _size = 0;
+ }
+ CObjArray2(): _items(0), _size(0) {};
+ /*
+ CObjArray2(const CObjArray2 &buffer): _items(0), _size(0)
+ {
+ size_t newSize = buffer._size;
+ if (newSize != 0)
+ {
+ T *newBuffer = new T[newSize];;
+ _items = newBuffer;
+ _size = newSize;
+ const T *src = buffer;
+ for (size_t i = 0; i < newSize; i++)
+ newBuffer[i] = src[i];
+ }
+ }
+ */
+ /*
+ CObjArray2(size_t size): _items(0), _size(0)
+ {
+ if (size != 0)
+ {
+ _items = new T[size];
+ _size = size;
+ }
+ }
+ */
+
+ ~CObjArray2() { delete []_items; }
+
+ operator T *() { return _items; }
+ operator const T *() const { return _items; }
+
+ unsigned Size() const { return (unsigned)_size; }
+ bool IsEmpty() const { return _size == 0; }
+
+ // SetSize doesn't keep old items. It allocates new array if size is not equal
+ void SetSize(unsigned size)
+ {
+ if (size == _size)
+ return;
+ T *newBuffer = NULL;
+ if (size != 0)
+ newBuffer = new T[size];
+ delete []_items;
+ _items = newBuffer;
+ _size = size;
+ }
+
+ /*
+ CObjArray2& operator=(const CObjArray2 &buffer)
+ {
+ Free();
+ size_t newSize = buffer._size;
+ if (newSize != 0)
+ {
+ T *newBuffer = new T[newSize];;
+ _items = newBuffer;
+ _size = newSize;
+ const T *src = buffer;
+ for (size_t i = 0; i < newSize; i++)
+ newBuffer[i] = src[i];
+ }
+ return *this;
+ }
+ */
+};
+
+#endif
diff --git a/3rdparty/lzma/CPP/Common/MyCom.h b/3rdparty/lzma/CPP/Common/MyCom.h
index 2f00c258f22..7c725c9136e 100644
--- a/3rdparty/lzma/CPP/Common/MyCom.h
+++ b/3rdparty/lzma/CPP/Common/MyCom.h
@@ -1,9 +1,10 @@
// MyCom.h
-#ifndef __MYCOM_H
-#define __MYCOM_H
+#ifndef __MY_COM_H
+#define __MY_COM_H
#include "MyWindows.h"
+#include "NewHandler.h"
#ifndef RINOK
#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; }
@@ -14,14 +15,9 @@ class CMyComPtr
{
T* _p;
public:
- // typedef T _PtrClass;
- CMyComPtr() { _p = NULL;}
- CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
- CMyComPtr(const CMyComPtr<T>& lp)
- {
- if ((_p = lp._p) != NULL)
- _p->AddRef();
- }
+ CMyComPtr(): _p(NULL) {}
+ CMyComPtr(T* p) throw() { if ((_p = p) != NULL) p->AddRef(); }
+ CMyComPtr(const CMyComPtr<T>& lp) throw() { if ((_p = lp._p) != NULL) _p->AddRef(); }
~CMyComPtr() { if (_p) _p->Release(); }
void Release() { if (_p) { _p->Release(); _p = NULL; } }
operator T*() const { return (T*)_p; }
@@ -30,7 +26,7 @@ public:
T* operator->() const { return _p; }
T* operator=(T* p)
{
- if (p != 0)
+ if (p)
p->AddRef();
if (_p)
_p->Release();
@@ -40,7 +36,6 @@ public:
T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
bool operator!() const { return (_p == NULL); }
// bool operator==(T* pT) const { return _p == pT; }
- // Compare two objects for equivalence
void Attach(T* p2)
{
Release();
@@ -70,7 +65,7 @@ public:
}
*/
template <class Q>
- HRESULT QueryInterface(REFGUID iid, Q** pp) const
+ HRESULT QueryInterface(REFGUID iid, Q** pp) const throw()
{
return _p->QueryInterface(iid, (void**)pp);
}
@@ -81,18 +76,28 @@ public:
inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr)
{
*bstr = ::SysAllocString(src);
- return (*bstr != 0) ? S_OK : E_OUTOFMEMORY;
+ return (*bstr) ? S_OK : E_OUTOFMEMORY;
}
class CMyComBSTR
{
-public:
BSTR m_str;
+
+public:
CMyComBSTR(): m_str(NULL) {}
+ ~CMyComBSTR() { ::SysFreeString(m_str); }
+ BSTR* operator&() { return &m_str; }
+ operator LPCOLESTR() const { return m_str; }
+ // operator bool() const { return m_str != NULL; }
+ // bool operator!() const { return m_str == NULL; }
+private:
+ // operator BSTR() const { return m_str; }
+
CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); }
// CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
// CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
+
/*
CMyComBSTR(REFGUID src)
{
@@ -102,7 +107,7 @@ public:
CoTaskMemFree(szGuid);
}
*/
- ~CMyComBSTR() { ::SysFreeString(m_str); }
+
CMyComBSTR& operator=(const CMyComBSTR& src)
{
if (m_str != src.m_str)
@@ -113,22 +118,29 @@ public:
}
return *this;
}
+
CMyComBSTR& operator=(LPCOLESTR src)
{
::SysFreeString(m_str);
m_str = ::SysAllocString(src);
return *this;
}
- unsigned int Length() const { return ::SysStringLen(m_str); }
- operator BSTR() const { return m_str; }
- BSTR* operator&() { return &m_str; }
+
+ unsigned Len() const { return ::SysStringLen(m_str); }
+
BSTR MyCopy() const
{
- int byteLen = ::SysStringByteLen(m_str);
+ // We don't support Byte BSTRs here
+ return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
+ /*
+ UINT byteLen = ::SysStringByteLen(m_str);
BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
- memcpy(res, m_str, byteLen);
+ if (res && byteLen != 0 && m_str)
+ memcpy(res, m_str, byteLen);
return res;
+ */
}
+
/*
void Attach(BSTR src) { m_str = src; }
BSTR Detach()
@@ -138,12 +150,12 @@ public:
return s;
}
*/
+
void Empty()
{
::SysFreeString(m_str);
m_str = NULL;
}
- bool operator!() const { return (m_str == NULL); }
};
//////////////////////////////////////////////////////////
@@ -153,25 +165,27 @@ class CMyUnknownImp
public:
ULONG __m_RefCount;
CMyUnknownImp(): __m_RefCount(0) {}
+
+ // virtual ~CMyUnknownImp() {};
};
#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
- (REFGUID iid, void **outObject) {
+(REFGUID iid, void **outObject) throw() { *outObject = NULL;
-#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
- { *outObject = (void *)(i *)this; AddRef(); return S_OK; }
+#define MY_QUERYINTERFACE_ENTRY(i) else if (iid == IID_ ## i) \
+ { *outObject = (void *)(i *)this; }
#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \
- { *outObject = (void *)(IUnknown *)(i *)this; AddRef(); return S_OK; }
+ { *outObject = (void *)(IUnknown *)(i *)this; }
#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
MY_QUERYINTERFACE_ENTRY(i)
-#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
+#define MY_QUERYINTERFACE_END else return E_NOINTERFACE; ++__m_RefCount; /* AddRef(); */ return S_OK; }
#define MY_ADDREF_RELEASE \
-STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
+STDMETHOD_(ULONG, AddRef)() throw() { return ++__m_RefCount; } \
STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
return __m_RefCount; delete this; return 0; }
@@ -222,4 +236,27 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
MY_QUERYINTERFACE_ENTRY(i5) \
)
+#define MY_UNKNOWN_IMP6(i1, i2, i3, i4, i5, i6) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ MY_QUERYINTERFACE_ENTRY(i6) \
+ )
+
+#define MY_UNKNOWN_IMP7(i1, i2, i3, i4, i5, i6, i7) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ MY_QUERYINTERFACE_ENTRY(i6) \
+ MY_QUERYINTERFACE_ENTRY(i7) \
+ )
+
+const HRESULT k_My_HRESULT_WritingWasCut = 0x20000010;
+
#endif
diff --git a/3rdparty/lzma/CPP/Common/MyGuidDef.h b/3rdparty/lzma/CPP/Common/MyGuidDef.h
index 3c52cc07dc0..68745870ee3 100644
--- a/3rdparty/lzma/CPP/Common/MyGuidDef.h
+++ b/3rdparty/lzma/CPP/Common/MyGuidDef.h
@@ -3,7 +3,7 @@
#ifndef GUID_DEFINED
#define GUID_DEFINED
-#include "Types.h"
+#include "MyTypes.h"
typedef struct {
UInt32 Data1;
diff --git a/3rdparty/lzma/CPP/Common/MyInitGuid.h b/3rdparty/lzma/CPP/Common/MyInitGuid.h
index d6a4869806a..279fba5d612 100644
--- a/3rdparty/lzma/CPP/Common/MyInitGuid.h
+++ b/3rdparty/lzma/CPP/Common/MyInitGuid.h
@@ -3,20 +3,43 @@
#ifndef __COMMON_MY_INITGUID_H
#define __COMMON_MY_INITGUID_H
+/*
+This file must be included only to one C++ file in project before
+declarations of COM interfaces with DEFINE_GUID macro.
+
+Each GUID must be initialized exactly once in project.
+There are two different versions of the DEFINE_GUID macro in guiddef.h (MyGuidDef.h):
+ - if INITGUID is not defined: DEFINE_GUID declares an external reference to the symbol name.
+ - if INITGUID is defined: DEFINE_GUID initializes the symbol name to the value of the GUID.
+
+Also we need IID_IUnknown that is initialized in some file for linking:
+ MSVC: by default the linker uses some lib file that contains IID_IUnknown
+ MinGW: add -luuid switch for linker
+ WinCE: we define IID_IUnknown in this file
+ Other: we define IID_IUnknown in this file
+*/
+
#ifdef _WIN32
+
#ifdef UNDER_CE
#include <basetyps.h>
#endif
+
#include <initguid.h>
+
#ifdef UNDER_CE
DEFINE_GUID(IID_IUnknown,
0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
#endif
+
#else
+
#define INITGUID
#include "MyGuidDef.h"
DEFINE_GUID(IID_IUnknown,
0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+
#endif
+
#endif
diff --git a/3rdparty/lzma/CPP/Common/MyLinux.h b/3rdparty/lzma/CPP/Common/MyLinux.h
new file mode 100644
index 00000000000..1a918993527
--- /dev/null
+++ b/3rdparty/lzma/CPP/Common/MyLinux.h
@@ -0,0 +1,42 @@
+// MyLinux.h
+
+#ifndef __MY_LIN_LINUX_H
+#define __MY_LIN_LINUX_H
+
+#define MY_LIN_S_IFMT 00170000
+#define MY_LIN_S_IFSOCK 0140000
+#define MY_LIN_S_IFLNK 0120000
+#define MY_LIN_S_IFREG 0100000
+#define MY_LIN_S_IFBLK 0060000
+#define MY_LIN_S_IFDIR 0040000
+#define MY_LIN_S_IFCHR 0020000
+#define MY_LIN_S_IFIFO 0010000
+
+#define MY_LIN_S_ISLNK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFLNK)
+#define MY_LIN_S_ISREG(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFREG)
+#define MY_LIN_S_ISDIR(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFDIR)
+#define MY_LIN_S_ISCHR(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFCHR)
+#define MY_LIN_S_ISBLK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFBLK)
+#define MY_LIN_S_ISFIFO(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFIFO)
+#define MY_LIN_S_ISSOCK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFSOCK)
+
+#define MY_LIN_S_ISUID 0004000
+#define MY_LIN_S_ISGID 0002000
+#define MY_LIN_S_ISVTX 0001000
+
+#define MY_LIN_S_IRWXU 00700
+#define MY_LIN_S_IRUSR 00400
+#define MY_LIN_S_IWUSR 00200
+#define MY_LIN_S_IXUSR 00100
+
+#define MY_LIN_S_IRWXG 00070
+#define MY_LIN_S_IRGRP 00040
+#define MY_LIN_S_IWGRP 00020
+#define MY_LIN_S_IXGRP 00010
+
+#define MY_LIN_S_IRWXO 00007
+#define MY_LIN_S_IROTH 00004
+#define MY_LIN_S_IWOTH 00002
+#define MY_LIN_S_IXOTH 00001
+
+#endif
diff --git a/3rdparty/lzma/CPP/Common/MyString.cpp b/3rdparty/lzma/CPP/Common/MyString.cpp
index dc254eaf831..a2d4cc4e6d0 100644
--- a/3rdparty/lzma/CPP/Common/MyString.cpp
+++ b/3rdparty/lzma/CPP/Common/MyString.cpp
@@ -3,18 +3,22 @@
#include "StdAfx.h"
#ifdef _WIN32
-#include <windows.h>
+#include <wchar.h>
#else
#include <ctype.h>
#endif
-#ifndef _UNICODE
+#if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING)
#include "StringConvert.h"
#endif
#include "MyString.h"
-const char* MyStringGetNextCharPointer(const char *p)
+#define MY_STRING_NEW(_T_, _size_) new _T_[_size_]
+// #define MY_STRING_NEW(_T_, _size_) ((_T_ *)my_new((size_t)(_size_) * sizeof(_T_)))
+
+/*
+inline const char* MyStringGetNextCharPointer(const char *p) throw()
{
#if defined(_WIN32) && !defined(UNDER_CE)
return CharNextA(p);
@@ -22,20 +26,21 @@ const char* MyStringGetNextCharPointer(const char *p)
return p + 1;
#endif
}
+*/
-int FindCharPosInString(const char *s, char c)
+int FindCharPosInString(const char *s, char c) throw()
{
- for (const char *p = s;;)
+ for (const char *p = s;; p++)
{
if (*p == c)
return (int)(p - s);
if (*p == 0)
return -1;
- p = MyStringGetNextCharPointer(p);
+ // MyStringGetNextCharPointer(p);
}
}
-int FindCharPosInString(const wchar_t *s, wchar_t c)
+int FindCharPosInString(const wchar_t *s, wchar_t c) throw()
{
for (const wchar_t *p = s;; p++)
{
@@ -46,55 +51,65 @@ int FindCharPosInString(const wchar_t *s, wchar_t c)
}
}
-#ifdef _WIN32
-
-#ifdef _UNICODE
+/*
+void MyStringUpper_Ascii(wchar_t *s)
+{
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharUpper_Ascii(c);
+ }
+}
+*/
-wchar_t MyCharUpper(wchar_t c)
+void MyStringLower_Ascii(char *s) throw()
{
- return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c);
+ for (;;)
+ {
+ char c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharLower_Ascii(c);
+ }
}
-/*
-wchar_t MyCharLower(wchar_t c)
+void MyStringLower_Ascii(wchar_t *s) throw()
{
- return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c);
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharLower_Ascii(c);
+ }
}
-char MyCharLower(char c)
-#ifdef UNDER_CE
- { return (char)MyCharLower((wchar_t)c); }
-#else
- { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
-#endif
-*/
+#ifdef _WIN32
-wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
-wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
+#ifdef _UNICODE
+// wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
+// wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
// for WinCE - FString - char
-const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p)
-{
- return p - 1;
-}
+// const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p) { return p - 1; }
#else
-const char * MyStringGetPrevCharPointer(const char *base, const char *p) { return CharPrevA(base, p); }
-char * MyStringUpper(char *s) { return CharUpperA(s); }
-char * MyStringLower(char *s) { return CharLowerA(s); }
+// const char * MyStringGetPrevCharPointer(const char *base, const char *p) throw() { return CharPrevA(base, p); }
+// char * MyStringUpper(char *s) { return CharUpperA(s); }
+// char * MyStringLower(char *s) { return CharLowerA(s); }
-wchar_t MyCharUpper(wchar_t c)
+wchar_t MyCharUpper_WIN(wchar_t c) throw()
{
- if (c == 0)
- return 0;
- wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c);
+ wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
- return (wchar_t)(unsigned int)(UINT_PTR)res;
- const int kBufferSize = 4;
- char s[kBufferSize + 1];
- int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
- if (numChars == 0 || numChars > kBufferSize)
+ return (wchar_t)(unsigned)(UINT_PTR)res;
+ const int kBufSize = 4;
+ char s[kBufSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);
+ if (numChars == 0 || numChars > kBufSize)
return c;
s[numChars] = 0;
::CharUpperA(s);
@@ -102,24 +117,25 @@ wchar_t MyCharUpper(wchar_t c)
return c;
}
-wchar_t MyCharLower(wchar_t c)
+/*
+wchar_t MyCharLower_WIN(wchar_t c)
{
- if (c == 0)
- return 0;
- wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c);
+ wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
- return (wchar_t)(unsigned int)(UINT_PTR)res;
- const int kBufferSize = 4;
- char s[kBufferSize + 1];
- int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
- if (numChars == 0 || numChars > kBufferSize)
+ return (wchar_t)(unsigned)(UINT_PTR)res;
+ const int kBufSize = 4;
+ char s[kBufSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);
+ if (numChars == 0 || numChars > kBufSize)
return c;
s[numChars] = 0;
::CharLowerA(s);
::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
return c;
}
+*/
+/*
wchar_t * MyStringUpper(wchar_t *s)
{
if (s == 0)
@@ -132,7 +148,9 @@ wchar_t * MyStringUpper(wchar_t *s)
MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
return s;
}
+*/
+/*
wchar_t * MyStringLower(wchar_t *s)
{
if (s == 0)
@@ -145,71 +163,158 @@ wchar_t * MyStringLower(wchar_t *s)
MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
return s;
}
+*/
#endif
-#else
+#endif
-wchar_t MyCharUpper(wchar_t c)
+bool IsString1PrefixedByString2(const char *s1, const char *s2) throw()
{
- return toupper(c);
+ for (;;)
+ {
+ unsigned char c2 = (unsigned char)*s2++; if (c2 == 0) return true;
+ unsigned char c1 = (unsigned char)*s1++; if (c1 != c2) return false;
+ }
}
-wchar_t * MyStringUpper(wchar_t *s)
+bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw()
{
- if (s == 0)
- return 0;
- for (wchar_t *p = s; *p != 0; p++)
- *p = MyCharUpper(*p);
- return s;
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false;
+ if (c1 == 0) return true;
+ }
}
-/*
-int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+// ---------- ASCII ----------
+
+bool AString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw()
+{
+ const char *s1 = _chars;
+ for (;;)
+ {
+ char c2 = *s++;
+ if (c2 == 0)
+ return true;
+ char c1 = *s1++;
+ if (MyCharLower_Ascii(c1) !=
+ MyCharLower_Ascii(c2))
+ return false;
+ }
+}
+
+bool UString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw()
+{
+ const wchar_t *s1 = _chars;
+ for (;;)
+ {
+ char c2 = *s++;
+ if (c2 == 0)
+ return true;
+ wchar_t c1 = *s1++;
+ if (MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))
+ return false;
+ }
+}
+
+bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw()
+{
+ for (;;)
+ {
+ unsigned char c = *a;
+ if (c != *u)
+ return false;
+ if (c == 0)
+ return true;
+ a++;
+ u++;
+ }
+}
+
+bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw()
+{
+ for (;;)
+ {
+ char c1 = *s1++;
+ char c2 = *s2++;
+ if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
+ return false;
+ if (c1 == 0)
+ return true;
+ }
+}
+
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
wchar_t c1 = *s1++;
wchar_t c2 = *s2++;
- wchar_t u1 = MyCharUpper(c1);
- wchar_t u2 = MyCharUpper(c2);
+ if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
+ return false;
+ if (c1 == 0)
+ return true;
+ }
+}
- if (u1 < u2) return -1;
- if (u1 > u2) return 1;
- if (u1 == 0) return 0;
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw()
+{
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ char c2 = *s2++;
+ if (c1 != (unsigned char)c2 && (c1 > 0x7F || MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2)))
+ return false;
+ if (c1 == 0)
+ return true;
}
}
-*/
-#endif
+bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw()
+{
+ for (;;)
+ {
+ wchar_t c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++; if (c1 != c2) return false;
+ }
+}
-int MyStringCompare(const char *s1, const char *s2)
+bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
- unsigned char c1 = (unsigned char)*s1++;
- unsigned char c2 = (unsigned char)*s2++;
- if (c1 < c2) return -1;
- if (c1 > c2) return 1;
- if (c1 == 0) return 0;
+ wchar_t c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++;
+ if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2))
+ return false;
}
}
-int MyStringCompare(const wchar_t *s1, const wchar_t *s2)
+// NTFS order: uses upper case
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
wchar_t c1 = *s1++;
wchar_t c2 = *s2++;
- if (c1 < c2) return -1;
- if (c1 > c2) return 1;
+ if (c1 != c2)
+ {
+ wchar_t u1 = MyCharUpper(c1);
+ wchar_t u2 = MyCharUpper(c2);
+ if (u1 < u2) return -1;
+ if (u1 > u2) return 1;
+ }
if (c1 == 0) return 0;
}
}
-int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)
+/*
+int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num)
{
- for (;;)
+ for (; num != 0; num--)
{
wchar_t c1 = *s1++;
wchar_t c2 = *s2++;
@@ -222,19 +327,1206 @@ int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)
}
if (c1 == 0) return 0;
}
+ return 0;
+}
+*/
+
+// ---------- AString ----------
+
+void AString::InsertSpace(unsigned &index, unsigned size)
+{
+ Grow(size);
+ MoveItems(index + size, index);
+}
+
+#define k_Alloc_Len_Limit 0x40000000
+
+void AString::ReAlloc(unsigned newLimit)
+{
+ if (newLimit < _len || newLimit >= k_Alloc_Len_Limit) throw 20130220;
+ // MY_STRING_REALLOC(_chars, char, newLimit + 1, _len + 1);
+ char *newBuf = MY_STRING_NEW(char, newLimit + 1);
+ memcpy(newBuf, _chars, (size_t)(_len + 1)); \
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = newLimit;
+}
+
+void AString::ReAlloc2(unsigned newLimit)
+{
+ if (newLimit >= k_Alloc_Len_Limit) throw 20130220;
+ // MY_STRING_REALLOC(_chars, char, newLimit + 1, 0);
+ char *newBuf = MY_STRING_NEW(char, newLimit + 1);
+ newBuf[0] = 0;
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = newLimit;
+}
+
+void AString::SetStartLen(unsigned len)
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(char, len + 1);
+ _len = len;
+ _limit = len;
+}
+
+void AString::Grow_1()
+{
+ unsigned next = _len;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+void AString::Grow(unsigned n)
+{
+ unsigned freeSize = _limit - _len;
+ if (n <= freeSize)
+ return;
+
+ unsigned next = _len + n;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+/*
+AString::AString(unsigned num, const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (num > len)
+ num = len;
+ SetStartLen(num);
+ memcpy(_chars, s, num);
+ _chars[num] = 0;
+}
+*/
+
+AString::AString(unsigned num, const AString &s)
+{
+ if (num > s._len)
+ num = s._len;
+ SetStartLen(num);
+ memcpy(_chars, s._chars, num);
+ _chars[num] = 0;
+}
+
+AString::AString(const AString &s, char c)
+{
+ SetStartLen(s.Len() + 1);
+ char *chars = _chars;
+ unsigned len = s.Len();
+ memcpy(chars, s, len);
+ chars[len] = c;
+ chars[len + 1] = 0;
+}
+
+AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2)
+{
+ SetStartLen(num1 + num2);
+ char *chars = _chars;
+ memcpy(chars, s1, num1);
+ memcpy(chars + num1, s2, num2 + 1);
+}
+
+AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); }
+AString operator+(const AString &s1, const char *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); }
+AString operator+(const char *s1, const AString &s2) { return AString(s1, MyStringLen(s1), s2, s2.Len()); }
+
+AString::AString()
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(char, 4);
+ _len = 0;
+ _limit = 4 - 1;
+ _chars[0] = 0;
+}
+
+AString::AString(char c)
+{
+ SetStartLen(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+}
+
+AString::AString(const char *s)
+{
+ SetStartLen(MyStringLen(s));
+ MyStringCopy(_chars, s);
+}
+
+AString::AString(const AString &s)
+{
+ SetStartLen(s._len);
+ MyStringCopy(_chars, s._chars);
+}
+
+AString &AString::operator=(char c)
+{
+ if (1 > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, 1 + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = 1;
+ }
+ _len = 1;
+ _chars[0] = c;
+ _chars[1] = 0;
+ return *this;
}
-UString MultiByteToUnicodeString(const AString &srcString, UINT codePage);
-AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage);
+AString &AString::operator=(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ MyStringCopy(_chars, s);
+ return *this;
+}
+
+AString &AString::operator=(const AString &s)
+{
+ if (&s == this)
+ return *this;
+ unsigned len = s._len;
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ MyStringCopy(_chars, s._chars);
+ return *this;
+}
+
+void AString::SetFromWStr_if_Ascii(const wchar_t *s)
+{
+ unsigned len = 0;
+ {
+ for (;; len++)
+ {
+ wchar_t c = s[len];
+ if (c == 0)
+ break;
+ if (c >= 0x80)
+ return;
+ }
+ }
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ char *dest = _chars;
+ unsigned i;
+ for (i = 0; i < len; i++)
+ dest[i] = (char)s[i];
+ dest[i] = 0;
+}
+
+/*
+void AString::SetFromBstr_if_Ascii(BSTR s)
+{
+ unsigned len = ::SysStringLen(s);
+ {
+ for (unsigned i = 0; i < len; i++)
+ if (s[i] <= 0 || s[i] >= 0x80)
+ return;
+ }
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ char *dest = _chars;
+ unsigned i;
+ for (i = 0; i < len; i++)
+ dest[i] = (char)s[i];
+ dest[i] = 0;
+}
+*/
+
+void AString::Add_Space() { operator+=(' '); }
+void AString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
+void AString::Add_LF() { operator+=('\n'); }
+
+AString &AString::operator+=(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ Grow(len);
+ MyStringCopy(_chars + _len, s);
+ _len += len;
+ return *this;
+}
+
+AString &AString::operator+=(const AString &s)
+{
+ Grow(s._len);
+ MyStringCopy(_chars + _len, s._chars);
+ _len += s._len;
+ return *this;
+}
+
+void AString::SetFrom(const char *s, unsigned len) // no check
+{
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ if (len != 0)
+ memcpy(_chars, s, len);
+ _chars[len] = 0;
+ _len = len;
+}
+
+void AString::SetFrom_CalcLen(const char *s, unsigned len) // no check
+{
+ unsigned i;
+ for (i = 0; i < len; i++)
+ if (s[i] == 0)
+ break;
+ SetFrom(s, i);
+}
+
+int AString::Find(const char *s, unsigned startIndex) const throw()
+{
+ const char *fs = strstr(_chars + startIndex, s);
+ if (!fs)
+ return -1;
+ return (int)(fs - _chars);
+
+ /*
+ if (s[0] == 0)
+ return startIndex;
+ unsigned len = MyStringLen(s);
+ const char *p = _chars + startIndex;
+ for (;; p++)
+ {
+ const char c = *p;
+ if (c != s[0])
+ {
+ if (c == 0)
+ return -1;
+ continue;
+ }
+ unsigned i;
+ for (i = 1; i < len; i++)
+ if (p[i] != s[i])
+ break;
+ if (i == len)
+ return (int)(p - _chars);
+ }
+ */
+}
+
+int AString::ReverseFind(char c) const throw()
+{
+ if (_len == 0)
+ return -1;
+ const char *p = _chars + _len - 1;
+ for (;;)
+ {
+ if (*p == c)
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p--; // p = GetPrevCharPointer(_chars, p);
+ }
+}
+
+int AString::ReverseFind_PathSepar() const throw()
+{
+ if (_len == 0)
+ return -1;
+ const char *p = _chars + _len - 1;
+ for (;;)
+ {
+ char c = *p;
+ if (IS_PATH_SEPAR(c))
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p--;
+ }
+}
+
+void AString::TrimLeft() throw()
+{
+ const char *p = _chars;
+ for (;; p++)
+ {
+ char c = *p;
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ unsigned pos = (unsigned)(p - _chars);
+ if (pos != 0)
+ {
+ MoveItems(0, pos);
+ _len -= pos;
+ }
+}
+
+void AString::TrimRight() throw()
+{
+ const char *p = _chars;
+ unsigned i;
+ for (i = _len; i != 0; i--)
+ {
+ char c = p[i - 1];
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ if (i != _len)
+ {
+ _chars[i] = 0;
+ _len = i;
+ }
+}
+
+void AString::InsertAtFront(char c)
+{
+ if (_limit == _len)
+ Grow_1();
+ MoveItems(1, 0);
+ _chars[0] = c;
+ _len++;
+}
+
+/*
+void AString::Insert(unsigned index, char c)
+{
+ InsertSpace(index, 1);
+ _chars[index] = c;
+ _len++;
+}
+*/
+
+void AString::Insert(unsigned index, const char *s)
+{
+ unsigned num = MyStringLen(s);
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ memcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void AString::Insert(unsigned index, const AString &s)
+{
+ unsigned num = s.Len();
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ memcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void AString::RemoveChar(char ch) throw()
+{
+ char *src = _chars;
+
+ for (;;)
+ {
+ char c = *src++;
+ if (c == 0)
+ return;
+ if (c == ch)
+ break;
+ }
+
+ char *dest = src - 1;
+
+ for (;;)
+ {
+ char c = *src++;
+ if (c == 0)
+ break;
+ if (c != ch)
+ *dest++ = c;
+ }
+
+ *dest = 0;
+ _len = (unsigned)(dest - _chars);
+}
+
+// !!!!!!!!!!!!!!! test it if newChar = '\0'
+void AString::Replace(char oldChar, char newChar) throw()
+{
+ if (oldChar == newChar)
+ return; // 0;
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldChar, pos);
+ if (pos < 0)
+ break;
+ _chars[(unsigned)pos] = newChar;
+ pos++;
+ // number++;
+ }
+ return; // number;
+}
+
+void AString::Replace(const AString &oldString, const AString &newString)
+{
+ if (oldString.IsEmpty())
+ return; // 0;
+ if (oldString == newString)
+ return; // 0;
+ unsigned oldLen = oldString.Len();
+ unsigned newLen = newString.Len();
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldString, pos);
+ if (pos < 0)
+ break;
+ Delete(pos, oldLen);
+ Insert(pos, newString);
+ pos += newLen;
+ // number++;
+ }
+ // return number;
+}
+
+void AString::Delete(unsigned index) throw()
+{
+ MoveItems(index, index + 1);
+ _len--;
+}
+void AString::Delete(unsigned index, unsigned count) throw()
+{
+ if (index + count > _len)
+ count = _len - index;
+ if (count > 0)
+ {
+ MoveItems(index, index + count);
+ _len -= count;
+ }
+}
+
+void AString::DeleteFrontal(unsigned num) throw()
+{
+ if (num != 0)
+ {
+ MoveItems(0, num);
+ _len -= num;
+ }
+}
+
+/*
+AString operator+(const AString &s1, const AString &s2)
+{
+ AString result(s1);
+ result += s2;
+ return result;
+}
+
+AString operator+(const AString &s, const char *chars)
+{
+ AString result(s);
+ result += chars;
+ return result;
+}
+
+AString operator+(const char *chars, const AString &s)
+{
+ AString result(chars);
+ result += s;
+ return result;
+}
+
+AString operator+(const AString &s, char c)
+{
+ AString result(s);
+ result += c;
+ return result;
+}
+*/
+
+/*
+AString operator+(char c, const AString &s)
+{
+ AString result(c);
+ result += s;
+ return result;
+}
+*/
+
+
+
+
+// ---------- UString ----------
+
+void UString::InsertSpace(unsigned index, unsigned size)
+{
+ Grow(size);
+ MoveItems(index + size, index);
+}
+
+void UString::ReAlloc(unsigned newLimit)
+{
+ if (newLimit < _len || newLimit >= k_Alloc_Len_Limit) throw 20130221;
+ // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, _len + 1);
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, newLimit + 1);
+ wmemcpy(newBuf, _chars, _len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = newLimit;
+}
+
+void UString::ReAlloc2(unsigned newLimit)
+{
+ if (newLimit >= k_Alloc_Len_Limit) throw 20130221;
+ // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0);
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, newLimit + 1);
+ newBuf[0] = 0;
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = newLimit;
+}
+
+void UString::SetStartLen(unsigned len)
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(wchar_t, len + 1);
+ _len = len;
+ _limit = len;
+}
+
+void UString::Grow_1()
+{
+ unsigned next = _len;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+void UString::Grow(unsigned n)
+{
+ unsigned freeSize = _limit - _len;
+ if (n <= freeSize)
+ return;
+
+ unsigned next = _len + n;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+
+UString::UString(unsigned num, const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ if (num > len)
+ num = len;
+ SetStartLen(num);
+ wmemcpy(_chars, s, num);
+ _chars[num] = 0;
+}
+
+
+UString::UString(unsigned num, const UString &s)
+{
+ if (num > s._len)
+ num = s._len;
+ SetStartLen(num);
+ wmemcpy(_chars, s._chars, num);
+ _chars[num] = 0;
+}
+
+UString::UString(const UString &s, wchar_t c)
+{
+ SetStartLen(s.Len() + 1);
+ wchar_t *chars = _chars;
+ unsigned len = s.Len();
+ wmemcpy(chars, s, len);
+ chars[len] = c;
+ chars[len + 1] = 0;
+}
+
+UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2)
+{
+ SetStartLen(num1 + num2);
+ wchar_t *chars = _chars;
+ wmemcpy(chars, s1, num1);
+ wmemcpy(chars + num1, s2, num2 + 1);
+}
+
+UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); }
+UString operator+(const UString &s1, const wchar_t *s2) { return UString(s1, s1.Len(), s2, MyStringLen(s2)); }
+UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); }
+
+UString::UString()
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(wchar_t, 4);
+ _len = 0;
+ _limit = 4 - 1;
+ _chars[0] = 0;
+}
+
+UString::UString(wchar_t c)
+{
+ SetStartLen(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+}
+
+UString::UString(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ SetStartLen(len);
+ wmemcpy(_chars, s, len + 1);
+}
+
+UString::UString(const UString &s)
+{
+ SetStartLen(s._len);
+ wmemcpy(_chars, s._chars, s._len + 1);
+}
+
+UString &UString::operator=(wchar_t c)
+{
+ if (1 > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = 1;
+ }
+ _len = 1;
+ _chars[0] = c;
+ _chars[1] = 0;
+ return *this;
+}
+
+UString &UString::operator=(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ wmemcpy(_chars, s, len + 1);
+ return *this;
+}
+
+UString &UString::operator=(const UString &s)
+{
+ if (&s == this)
+ return *this;
+ unsigned len = s._len;
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ wmemcpy(_chars, s._chars, len + 1);
+ return *this;
+}
+
+void UString::SetFromBstr(BSTR s)
+{
+ unsigned len = ::SysStringLen(s);
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ // if (s)
+ wmemcpy(_chars, s, len + 1);
+}
+
+void UString::Add_Space() { operator+=(L' '); }
+void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
+
+void UString::Add_LF()
+{
+ if (_limit == _len)
+ Grow_1();
+ unsigned len = _len;
+ wchar_t *chars = _chars;
+ chars[len++] = L'\n';
+ chars[len] = 0;
+ _len = len;
+}
+
+UString &UString::operator+=(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ Grow(len);
+ wmemcpy(_chars + _len, s, len + 1);
+ _len += len;
+ return *this;
+}
+
+UString &UString::operator+=(const UString &s)
+{
+ Grow(s._len);
+ wmemcpy(_chars + _len, s._chars, s._len + 1);
+ _len += s._len;
+ return *this;
+}
+
+void UString::SetFrom(const wchar_t *s, unsigned len) // no check
+{
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ if (len != 0)
+ wmemcpy(_chars, s, len);
+ _chars[len] = 0;
+ _len = len;
+}
+
+void UString::SetFromAscii(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ wchar_t *chars = _chars;
+ for (unsigned i = 0; i < len; i++)
+ chars[i] = (unsigned char)s[i];
+ chars[len] = 0;
+ _len = len;
+}
+
+void UString::AddAscii(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ Grow(len);
+ wchar_t *chars = _chars + _len;
+ for (unsigned i = 0; i < len; i++)
+ chars[i] = (unsigned char)s[i];
+ chars[len] = 0;
+ _len += len;
+}
+
+
+
+int UString::Find(const wchar_t *s, unsigned startIndex) const throw()
+{
+ const wchar_t *fs = wcsstr(_chars + startIndex, s);
+ if (!fs)
+ return -1;
+ return (int)(fs - _chars);
+
+ /*
+ if (s[0] == 0)
+ return startIndex;
+ unsigned len = MyStringLen(s);
+ const wchar_t *p = _chars + startIndex;
+ for (;; p++)
+ {
+ const wchar_t c = *p;
+ if (c != s[0])
+ {
+ if (c == 0)
+ return -1;
+ continue;
+ }
+ unsigned i;
+ for (i = 1; i < len; i++)
+ if (p[i] != s[i])
+ break;
+ if (i == len)
+ return (int)(p - _chars);
+ }
+ */
+}
+
+int UString::ReverseFind(wchar_t c) const throw()
+{
+ if (_len == 0)
+ return -1;
+ const wchar_t *p = _chars + _len - 1;
+ for (;;)
+ {
+ if (*p == c)
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p--;
+ }
+}
+
+int UString::ReverseFind_PathSepar() const throw()
+{
+ if (_len == 0)
+ return -1;
+ const wchar_t *p = _chars + _len - 1;
+ for (;;)
+ {
+ wchar_t c = *p;
+ if (IS_PATH_SEPAR(c))
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p--;
+ }
+}
+
+void UString::TrimLeft() throw()
+{
+ const wchar_t *p = _chars;
+ for (;; p++)
+ {
+ wchar_t c = *p;
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ unsigned pos = (unsigned)(p - _chars);
+ if (pos != 0)
+ {
+ MoveItems(0, pos);
+ _len -= pos;
+ }
+}
+
+void UString::TrimRight() throw()
+{
+ const wchar_t *p = _chars;
+ unsigned i;
+ for (i = _len; i != 0; i--)
+ {
+ wchar_t c = p[i - 1];
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ if (i != _len)
+ {
+ _chars[i] = 0;
+ _len = i;
+ }
+}
+
+void UString::InsertAtFront(wchar_t c)
+{
+ if (_limit == _len)
+ Grow_1();
+ MoveItems(1, 0);
+ _chars[0] = c;
+ _len++;
+}
+
+/*
+void UString::Insert(unsigned index, wchar_t c)
+{
+ InsertSpace(index, 1);
+ _chars[index] = c;
+ _len++;
+}
+*/
+
+void UString::Insert(unsigned index, const wchar_t *s)
+{
+ unsigned num = MyStringLen(s);
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ wmemcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void UString::Insert(unsigned index, const UString &s)
+{
+ unsigned num = s.Len();
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ wmemcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void UString::RemoveChar(wchar_t ch) throw()
+{
+ wchar_t *src = _chars;
+
+ for (;;)
+ {
+ wchar_t c = *src++;
+ if (c == 0)
+ return;
+ if (c == ch)
+ break;
+ }
+
+ wchar_t *dest = src - 1;
+
+ for (;;)
+ {
+ wchar_t c = *src++;
+ if (c == 0)
+ break;
+ if (c != ch)
+ *dest++ = c;
+ }
+
+ *dest = 0;
+ _len = (unsigned)(dest - _chars);
+}
+
+// !!!!!!!!!!!!!!! test it if newChar = '\0'
+void UString::Replace(wchar_t oldChar, wchar_t newChar) throw()
+{
+ if (oldChar == newChar)
+ return; // 0;
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldChar, pos);
+ if (pos < 0)
+ break;
+ _chars[(unsigned)pos] = newChar;
+ pos++;
+ // number++;
+ }
+ return; // number;
+}
+
+void UString::Replace(const UString &oldString, const UString &newString)
+{
+ if (oldString.IsEmpty())
+ return; // 0;
+ if (oldString == newString)
+ return; // 0;
+ unsigned oldLen = oldString.Len();
+ unsigned newLen = newString.Len();
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldString, pos);
+ if (pos < 0)
+ break;
+ Delete(pos, oldLen);
+ Insert(pos, newString);
+ pos += newLen;
+ // number++;
+ }
+ // return number;
+}
+
+void UString::Delete(unsigned index) throw()
+{
+ MoveItems(index, index + 1);
+ _len--;
+}
+
+void UString::Delete(unsigned index, unsigned count) throw()
+{
+ if (index + count > _len)
+ count = _len - index;
+ if (count > 0)
+ {
+ MoveItems(index, index + count);
+ _len -= count;
+ }
+}
+
+void UString::DeleteFrontal(unsigned num) throw()
+{
+ if (num != 0)
+ {
+ MoveItems(0, num);
+ _len -= num;
+ }
+}
+
+
+// ---------- UString2 ----------
+
+void UString2::ReAlloc2(unsigned newLimit)
+{
+ if (newLimit >= k_Alloc_Len_Limit) throw 20130221;
+ // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0);
+ _chars = MY_STRING_NEW(wchar_t, newLimit + 1);
+}
+
+void UString2::SetStartLen(unsigned len)
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(wchar_t, len + 1);
+ _len = len;
+}
+
+
+/*
+UString2::UString2(wchar_t c)
+{
+ SetStartLen(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+}
+*/
+
+UString2::UString2(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ SetStartLen(len);
+ wmemcpy(_chars, s, len + 1);
+}
+
+UString2::UString2(const UString2 &s): _chars(NULL), _len(0)
+{
+ if (s._chars)
+ {
+ SetStartLen(s._len);
+ wmemcpy(_chars, s._chars, s._len + 1);
+ }
+}
+
+/*
+UString2 &UString2::operator=(wchar_t c)
+{
+ if (1 > _len)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1);
+ if (_chars)
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ }
+ _len = 1;
+ _chars[0] = c;
+ _chars[1] = 0;
+ return *this;
+}
+*/
+
+UString2 &UString2::operator=(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _len)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ if (_chars)
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ }
+ _len = len;
+ MyStringCopy(_chars, s);
+ return *this;
+}
+
+void UString2::SetFromAscii(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _len)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ if (_chars)
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ }
+ wchar_t *chars = _chars;
+ for (unsigned i = 0; i < len; i++)
+ chars[i] = (unsigned char)s[i];
+ chars[len] = 0;
+ _len = len;
+}
+
+UString2 &UString2::operator=(const UString2 &s)
+{
+ if (&s == this)
+ return *this;
+ unsigned len = s._len;
+ if (len > _len)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ if (_chars)
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ }
+ _len = len;
+ MyStringCopy(_chars, s._chars);
+ return *this;
+}
+
+bool operator==(const UString2 &s1, const UString2 &s2)
+{
+ return s1.Len() == s2.Len() && (s1.IsEmpty() || wcscmp(s1.GetRawPtr(), s2.GetRawPtr()) == 0);
+}
+
+bool operator==(const UString2 &s1, const wchar_t *s2)
+{
+ if (s1.IsEmpty())
+ return (*s2 == 0);
+ return wcscmp(s1.GetRawPtr(), s2) == 0;
+}
+
+bool operator==(const wchar_t *s1, const UString2 &s2)
+{
+ if (s2.IsEmpty())
+ return (*s1 == 0);
+ return wcscmp(s1, s2.GetRawPtr()) == 0;
+}
+
+
+
+// ----------------------------------------
+
+/*
int MyStringCompareNoCase(const char *s1, const char *s2)
{
- return MyStringCompareNoCase(MultiByteToUnicodeString(s1, CP_ACP), MultiByteToUnicodeString(s2, CP_ACP));
+ return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2));
}
+*/
static inline UINT GetCurrentCodePage()
{
- #if defined(UNDER_CE) || !defined(defined)
+ #if defined(UNDER_CE) || !defined(_WIN32)
return CP_ACP;
#else
return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP;
@@ -243,6 +1535,8 @@ static inline UINT GetCurrentCodePage()
#ifdef USE_UNICODE_FSTRING
+#ifndef _UNICODE
+
AString fs2fas(CFSTR s)
{
return UnicodeStringToMultiByte(s, GetCurrentCodePage());
@@ -253,6 +1547,8 @@ FString fas2fs(const AString &s)
return MultiByteToUnicodeString(s, GetCurrentCodePage());
}
+#endif
+
#else
UString fs2us(const FString &s)
diff --git a/3rdparty/lzma/CPP/Common/MyString.h b/3rdparty/lzma/CPP/Common/MyString.h
index 0312bac6d72..02308555a38 100644
--- a/3rdparty/lzma/CPP/Common/MyString.h
+++ b/3rdparty/lzma/CPP/Common/MyString.h
@@ -5,552 +5,727 @@
#include <string.h>
-#include "Types.h"
+#ifndef _WIN32
+#include <wctype.h>
+#include <wchar.h>
+#endif
+
+#include "MyWindows.h"
+#include "MyTypes.h"
#include "MyVector.h"
-template <class T>
-inline int MyStringLen(const T *s)
+#ifdef _WIN32
+#define IS_PATH_SEPAR(c) ((c) == '\\' || (c) == '/')
+#else
+#define IS_PATH_SEPAR(c) ((c) == CHAR_PATH_SEPARATOR)
+#endif
+
+inline bool IsPathSepar(char c) { return IS_PATH_SEPAR(c); }
+inline bool IsPathSepar(wchar_t c) { return IS_PATH_SEPAR(c); }
+
+inline unsigned MyStringLen(const char *s)
{
- int i;
- for (i = 0; s[i] != '\0'; i++);
+ unsigned i;
+ for (i = 0; s[i] != 0; i++);
return i;
}
-template <class T>
-inline void MyStringCopy(T *dest, const T *src)
+inline void MyStringCopy(char *dest, const char *src)
{
while ((*dest++ = *src++) != 0);
}
-int FindCharPosInString(const char *s, char c);
-int FindCharPosInString(const wchar_t *s, wchar_t c);
+inline char *MyStpCpy(char *dest, const char *src)
+{
+ for (;;)
+ {
+ char c = *src;
+ *dest = c;
+ if (c == 0)
+ return dest;
+ src++;
+ dest++;
+ }
+}
-inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
- { return (p + 1); }
-inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
- { return (p + 1); }
-inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
- { return (p - 1); }
-inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
- { return (p - 1); }
+inline unsigned MyStringLen(const wchar_t *s)
+{
+ unsigned i;
+ for (i = 0; s[i] != 0; i++);
+ return i;
+}
-wchar_t MyCharUpper(wchar_t c);
-// wchar_t MyCharLower(wchar_t c);
+inline void MyStringCopy(wchar_t *dest, const wchar_t *src)
+{
+ while ((*dest++ = *src++) != 0);
+}
-char *MyStringUpper(char *s);
-char *MyStringLower(char *s);
+/*
+inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src)
+{
+ for (;;)
+ {
+ wchar_t c = *src;
+ *dest = c;
+ if (c == 0)
+ return dest;
+ src++;
+ dest++;
+ }
+}
+*/
-wchar_t *MyStringUpper(wchar_t *s);
-wchar_t *MyStringLower(wchar_t *s);
+int FindCharPosInString(const char *s, char c) throw();
+int FindCharPosInString(const wchar_t *s, wchar_t c) throw();
-const char* MyStringGetNextCharPointer(const char *p);
-const char* MyStringGetPrevCharPointer(const char *base, const char *p);
+#ifdef _WIN32
+ #ifndef _UNICODE
+ #define STRING_UNICODE_THROW
+ #endif
+#endif
-//////////////////////////////////////
-// Compare
+#ifndef STRING_UNICODE_THROW
+ #define STRING_UNICODE_THROW throw()
+#endif
-int MyStringCompare(const char *s1, const char *s2);
-int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
+/*
+inline char MyCharUpper_Ascii(char c)
+{
+ if (c >= 'a' && c <= 'z')
+ return (char)(c - 0x20);
+ return c;
+}
+inline wchar_t MyCharUpper_Ascii(wchar_t c)
+{
+ if (c >= 'a' && c <= 'z')
+ return (wchar_t)(c - 0x20);
+ return c;
+}
+*/
-int MyStringCompareNoCase(const char *s1, const char *s2);
-int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
+inline char MyCharLower_Ascii(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return (char)((unsigned char)c + 0x20);
+ return c;
+}
-template <class T>
-class CStringBase
+inline wchar_t MyCharLower_Ascii(wchar_t c)
{
- void TrimLeftWithCharSet(const CStringBase &charSet)
- {
- const T *p = _chars;
- while (charSet.Find(*p) >= 0 && (*p != 0))
- p = GetNextCharPointer(p);
- Delete(0, (int)(p - _chars));
- }
- void TrimRightWithCharSet(const CStringBase &charSet)
- {
- const T *p = _chars;
- const T *pLast = NULL;
- while (*p != 0)
- {
- if (charSet.Find(*p) >= 0)
- {
- if (pLast == NULL)
- pLast = p;
- }
- else
- pLast = NULL;
- p = GetNextCharPointer(p);
- }
- if (pLast != NULL)
- {
- int i = (int)(pLast - _chars);
- Delete(i, _length - i);
- }
+ if (c >= 'A' && c <= 'Z')
+ return (wchar_t)(c + 0x20);
+ return c;
+}
- }
- void MoveItems(int destIndex, int srcIndex)
- {
- memmove(_chars + destIndex, _chars + srcIndex,
- sizeof(T) * (_length - srcIndex + 1));
- }
-
- void InsertSpace(int &index, int size)
- {
- CorrectIndex(index);
- GrowLength(size);
- MoveItems(index + size, index);
- }
+wchar_t MyCharUpper_WIN(wchar_t c) throw();
- static const T *GetNextCharPointer(const T *p)
- { return MyStringGetNextCharPointer(p); }
- static const T *GetPrevCharPointer(const T *base, const T *p)
- { return MyStringGetPrevCharPointer(base, p); }
-protected:
- T *_chars;
- int _length;
- int _capacity;
-
- void SetCapacity(int newCapacity)
- {
- int realCapacity = newCapacity + 1;
- if (realCapacity == _capacity)
- return;
- /*
- const int kMaxStringSize = 0x20000000;
- if (newCapacity > kMaxStringSize || newCapacity < _length)
- throw 1052337;
- */
- T *newBuffer = new T[realCapacity];
- if (_capacity > 0)
- {
- for (int i = 0; i < _length; i++)
- newBuffer[i] = _chars[i];
- delete []_chars;
- }
- _chars = newBuffer;
- _chars[_length] = 0;
- _capacity = realCapacity;
- }
+inline wchar_t MyCharUpper(wchar_t c) throw()
+{
+ if (c < 'a') return c;
+ if (c <= 'z') return (wchar_t)(c - 0x20);
+ if (c <= 0x7F) return c;
+ #ifdef _WIN32
+ #ifdef _UNICODE
+ return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
+ #else
+ return (wchar_t)MyCharUpper_WIN(c);
+ #endif
+ #else
+ return (wchar_t)towupper(c);
+ #endif
+}
- void GrowLength(int n)
- {
- int freeSize = _capacity - _length - 1;
- if (n <= freeSize)
- return;
- int delta;
- if (_capacity > 64)
- delta = _capacity / 2;
- else if (_capacity > 8)
- delta = 16;
- else
- delta = 4;
- if (freeSize + delta < n)
- delta = n - freeSize;
- SetCapacity(_capacity + delta);
- }
+/*
+wchar_t MyCharLower_WIN(wchar_t c) throw();
- void CorrectIndex(int &index) const
- {
- if (index > _length)
- index = _length;
- }
+inline wchar_t MyCharLower(wchar_t c) throw()
+{
+ if (c < 'A') return c;
+ if (c <= 'Z') return (wchar_t)(c + 0x20);
+ if (c <= 0x7F) return c;
+ #ifdef _WIN32
+ #ifdef _UNICODE
+ return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
+ #else
+ return (wchar_t)MyCharLower_WIN(c);
+ #endif
+ #else
+ return (wchar_t)tolower(c);
+ #endif
+}
+*/
-public:
- CStringBase(): _chars(0), _length(0), _capacity(0) { SetCapacity(3); }
- CStringBase(T c): _chars(0), _length(0), _capacity(0)
- {
- SetCapacity(1);
- _chars[0] = c;
- _chars[1] = 0;
- _length = 1;
- }
- CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)
- {
- int length = MyStringLen(chars);
- SetCapacity(length);
- MyStringCopy(_chars, chars); // can be optimized by memove()
- _length = length;
- }
- CStringBase(const CStringBase &s): _chars(0), _length(0), _capacity(0)
- {
- SetCapacity(s._length);
- MyStringCopy(_chars, s._chars);
- _length = s._length;
- }
- ~CStringBase() { delete []_chars; }
+// char *MyStringUpper(char *s) throw();
+// char *MyStringLower(char *s) throw();
- operator const T*() const { return _chars;}
+// void MyStringUpper_Ascii(wchar_t *s) throw();
+void MyStringLower_Ascii(char *s) throw();
+void MyStringLower_Ascii(wchar_t *s) throw();
+// wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW;
+// wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW;
- T Back() const { return _chars[_length - 1]; }
+bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw();
- // The minimum size of the character buffer in characters.
- // This value does not include space for a null terminator.
- T* GetBuffer(int minBufLength)
+bool IsString1PrefixedByString2(const char *s1, const char *s2) throw();
+bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw();
+bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw();
+
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw();
+// int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw();
+
+// ---------- ASCII ----------
+// char values in ASCII strings must be less then 128
+bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw();
+bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw();
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw();
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw();
+
+#define MY_STRING_DELETE(_p_) delete []_p_;
+// #define MY_STRING_DELETE(_p_) my_delete(_p_);
+
+class AString
+{
+ char *_chars;
+ unsigned _len;
+ unsigned _limit;
+
+ void MoveItems(unsigned dest, unsigned src)
{
- if (minBufLength >= _capacity)
- SetCapacity(minBufLength);
+ memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char));
+ }
+
+ void InsertSpace(unsigned &index, unsigned size);
+
+ void ReAlloc(unsigned newLimit);
+ void ReAlloc2(unsigned newLimit);
+ void SetStartLen(unsigned len);
+ void Grow_1();
+ void Grow(unsigned n);
+
+ // AString(unsigned num, const char *s);
+ AString(unsigned num, const AString &s);
+ AString(const AString &s, char c); // it's for String + char
+ AString(const char *s1, unsigned num1, const char *s2, unsigned num2);
+
+ friend AString operator+(const AString &s, char c) { return AString(s, c); } ;
+ // friend AString operator+(char c, const AString &s); // is not supported
+
+ friend AString operator+(const AString &s1, const AString &s2);
+ friend AString operator+(const AString &s1, const char *s2);
+ friend AString operator+(const char *s1, const AString &s2);
+
+ // ---------- forbidden functions ----------
+ AString &operator+=(wchar_t c);
+ AString &operator=(wchar_t c);
+ AString(wchar_t c);
+ void Find(wchar_t c) const;
+ void Find(wchar_t c, unsigned startIndex) const;
+ void ReverseFind(wchar_t c) const;
+ void InsertAtFront(wchar_t c);
+ void RemoveChar(wchar_t ch);
+ void Replace(wchar_t oldChar, wchar_t newChar);
+
+public:
+ AString();
+ AString(char c);
+ AString(const char *s);
+ AString(const AString &s);
+ ~AString() { MY_STRING_DELETE(_chars); }
+
+ unsigned Len() const { return _len; }
+ bool IsEmpty() const { return _len == 0; }
+ void Empty() { _len = 0; _chars[0] = 0; }
+
+ operator const char *() const { return _chars; }
+ const char *Ptr() const { return _chars; }
+ const char *Ptr(unsigned pos) const { return _chars + pos; }
+ const char *RightPtr(unsigned num) const { return _chars + _len - num; }
+ char Back() const { return _chars[_len - 1]; }
+
+ void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; }
+
+ /* GetBuf(minLen): provides the buffer that can store
+ at least (minLen) characters and additional null terminator.
+ 9.35: GetBuf doesn't preserve old characters and terminator */
+ char *GetBuf(unsigned minLen)
+ {
+ if (minLen > _limit)
+ ReAlloc2(minLen);
return _chars;
}
- void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
- void ReleaseBuffer(int newLength)
+ char *GetBuf_SetEnd(unsigned minLen)
{
- /*
- if (newLength >= _capacity)
- throw 282217;
- */
- _chars[newLength] = 0;
- _length = newLength;
+ if (minLen > _limit)
+ ReAlloc2(minLen);
+ char *chars = _chars;
+ chars[minLen] = 0;
+ _len = minLen;
+ return chars;
}
- CStringBase& operator=(T c)
- {
- Empty();
- SetCapacity(1);
- _chars[0] = c;
- _chars[1] = 0;
- _length = 1;
- return *this;
- }
- CStringBase& operator=(const T *chars)
+ void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
+ void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
+ void ReleaseBuf_CalcLen(unsigned maxLen)
{
- Empty();
- int length = MyStringLen(chars);
- SetCapacity(length);
- MyStringCopy(_chars, chars);
- _length = length;
- return *this;
+ char *chars = _chars;
+ chars[maxLen] = 0;
+ _len = MyStringLen(chars);
}
- CStringBase& operator=(const CStringBase& s)
+
+ AString &operator=(char c);
+ AString &operator=(const char *s);
+ AString &operator=(const AString &s);
+ void SetFromWStr_if_Ascii(const wchar_t *s);
+ // void SetFromBstr_if_Ascii(BSTR s);
+
+ AString &operator+=(char c)
{
- if (&s == this)
- return *this;
- Empty();
- SetCapacity(s._length);
- MyStringCopy(_chars, s._chars);
- _length = s._length;
+ if (_limit == _len)
+ Grow_1();
+ unsigned len = _len;
+ char *chars = _chars;
+ chars[len++] = c;
+ chars[len] = 0;
+ _len = len;
return *this;
}
- CStringBase& operator+=(T c)
+ void Add_Space();
+ void Add_Space_if_NotEmpty();
+ void Add_LF();
+ void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); }
+
+ AString &operator+=(const char *s);
+ AString &operator+=(const AString &s);
+ void AddAscii(const char *s) { operator+=(s); }
+
+ void SetFrom(const char *s, unsigned len); // no check
+ void SetFrom_CalcLen(const char *s, unsigned len);
+ // void SetFromAscii(const char *s) { operator+=(s); }
+
+ AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
+ AString Left(unsigned count) const { return AString(count, *this); }
+
+ // void MakeUpper() { MyStringUpper(_chars); }
+ // void MakeLower() { MyStringLower(_chars); }
+ void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
+
+
+ bool IsEqualTo(const char *s) const { return strcmp(_chars, s) == 0; }
+ bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
+ // int Compare(const char *s) const { return MyStringCompare(_chars, s); }
+ // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); }
+ // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); }
+ // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
+ bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); }
+ bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
+
+ bool IsAscii() const
+ {
+ unsigned len = Len();
+ const char *s = _chars;
+ for (unsigned i = 0; i < len; i++)
+ if ((unsigned char)s[i] >= 0x80)
+ return false;
+ return true;
+ }
+ int Find(char c) const { return FindCharPosInString(_chars, c); }
+ int Find(char c, unsigned startIndex) const
{
- GrowLength(1);
- _chars[_length] = c;
- _chars[++_length] = 0;
- return *this;
- }
- CStringBase& operator+=(const T *s)
- {
- int len = MyStringLen(s);
- GrowLength(len);
- MyStringCopy(_chars + _length, s);
- _length += len;
- return *this;
- }
- CStringBase& operator+=(const CStringBase &s)
- {
- GrowLength(s._length);
- MyStringCopy(_chars + _length, s._chars);
- _length += s._length;
- return *this;
- }
- void Empty()
- {
- _length = 0;
- _chars[0] = 0;
+ int pos = FindCharPosInString(_chars + startIndex, c);
+ return pos < 0 ? -1 : (int)startIndex + pos;
}
- int Length() const { return _length; }
- bool IsEmpty() const { return (_length == 0); }
+
+ int ReverseFind(char c) const throw();
+ int ReverseFind_Dot() const throw() { return ReverseFind('.'); }
+ int ReverseFind_PathSepar() const throw();
- CStringBase Mid(int startIndex) const
- { return Mid(startIndex, _length - startIndex); }
- CStringBase Mid(int startIndex, int count) const
+ int Find(const char *s) const { return Find(s, 0); }
+ int Find(const char *s, unsigned startIndex) const throw();
+
+ void TrimLeft() throw();
+ void TrimRight() throw();
+ void Trim()
{
- if (startIndex + count > _length)
- count = _length - startIndex;
-
- if (startIndex == 0 && startIndex + count == _length)
- return *this;
-
- CStringBase<T> result;
- result.SetCapacity(count);
- // MyStringNCopy(result._chars, _chars + startIndex, count);
- for (int i = 0; i < count; i++)
- result._chars[i] = _chars[startIndex + i];
- result._chars[count] = 0;
- result._length = count;
- return result;
+ TrimRight();
+ TrimLeft();
}
- CStringBase Left(int count) const
- { return Mid(0, count); }
- CStringBase Right(int count) const
+
+ void InsertAtFront(char c);
+ // void Insert(unsigned index, char c);
+ void Insert(unsigned index, const char *s);
+ void Insert(unsigned index, const AString &s);
+
+ void RemoveChar(char ch) throw();
+
+ void Replace(char oldChar, char newChar) throw();
+ void Replace(const AString &oldString, const AString &newString);
+
+ void Delete(unsigned index) throw();
+ void Delete(unsigned index, unsigned count) throw();
+ void DeleteFrontal(unsigned num) throw();
+ void DeleteBack() { _chars[--_len] = 0; }
+ void DeleteFrom(unsigned index)
{
- if (count > _length)
- count = _length;
- return Mid(_length - count, count);
+ if (index < _len)
+ {
+ _len = index;
+ _chars[index] = 0;
+ }
}
+};
- void MakeUpper() { MyStringUpper(_chars); }
- void MakeLower() { MyStringLower(_chars); }
+bool operator<(const AString &s1, const AString &s2);
+bool operator>(const AString &s1, const AString &s2);
- int Compare(const CStringBase& s) const
- { return MyStringCompare(_chars, s._chars); }
+/*
+bool operator==(const AString &s1, const AString &s2);
+bool operator==(const AString &s1, const char *s2);
+bool operator==(const char *s1, const AString &s2);
- int Compare(const T *s) const
- { return MyStringCompare(_chars, s); }
+bool operator!=(const AString &s1, const AString &s2);
+bool operator!=(const AString &s1, const char *s2);
+bool operator!=(const char *s1, const AString &s2);
+*/
- int CompareNoCase(const CStringBase& s) const
- { return MyStringCompareNoCase(_chars, s._chars); }
+inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; }
+inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; }
+inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; }
- int CompareNoCase(const T *s) const
- { return MyStringCompareNoCase(_chars, s); }
+inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; }
+inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; }
+inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; }
- /*
- int Collate(const CStringBase& s) const
- { return MyStringCollate(_chars, s._chars); }
- int CollateNoCase(const CStringBase& s) const
- { return MyStringCollateNoCase(_chars, s._chars); }
- */
+// ---------- forbidden functions ----------
- int Find(T c) const { return FindCharPosInString(_chars, c); }
- int Find(T c, int startIndex) const
- {
- int pos = FindCharPosInString(_chars + startIndex, c);
- return pos < 0 ? -1 : pos + startIndex;
- }
- int Find(const CStringBase &s) const { return Find(s, 0); }
- int Find(const CStringBase &s, int startIndex) const
+void operator==(char c1, const AString &s2);
+void operator==(const AString &s1, char c2);
+
+void operator+(char c, const AString &s); // this function can be OK, but we don't use it
+
+void operator+(const AString &s, int c);
+void operator+(const AString &s, unsigned c);
+void operator+(int c, const AString &s);
+void operator+(unsigned c, const AString &s);
+void operator-(const AString &s, int c);
+void operator-(const AString &s, unsigned c);
+
+
+class UString
+{
+ wchar_t *_chars;
+ unsigned _len;
+ unsigned _limit;
+
+ void MoveItems(unsigned dest, unsigned src)
{
- if (s.IsEmpty())
- return startIndex;
- for (; startIndex < _length; startIndex++)
- {
- int j;
- for (j = 0; j < s._length && startIndex + j < _length; j++)
- if (_chars[startIndex+j] != s._chars[j])
- break;
- if (j == s._length)
- return startIndex;
- }
- return -1;
+ memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t));
}
- int ReverseFind(T c) const
+
+ void InsertSpace(unsigned index, unsigned size);
+
+ void ReAlloc(unsigned newLimit);
+ void ReAlloc2(unsigned newLimit);
+ void SetStartLen(unsigned len);
+ void Grow_1();
+ void Grow(unsigned n);
+
+ UString(unsigned num, const wchar_t *s); // for Mid
+ UString(unsigned num, const UString &s); // for Left
+ UString(const UString &s, wchar_t c); // it's for String + char
+ UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2);
+
+ friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ;
+ // friend UString operator+(wchar_t c, const UString &s); // is not supported
+
+ friend UString operator+(const UString &s1, const UString &s2);
+ friend UString operator+(const UString &s1, const wchar_t *s2);
+ friend UString operator+(const wchar_t *s1, const UString &s2);
+
+ // ---------- forbidden functions ----------
+
+ UString &operator+=(char c);
+ UString &operator+=(unsigned char c);
+ UString &operator=(char c);
+ UString &operator=(unsigned char c);
+ UString(char c);
+ UString(unsigned char c);
+ void Find(char c) const;
+ void Find(unsigned char c) const;
+ void Find(char c, unsigned startIndex) const;
+ void Find(unsigned char c, unsigned startIndex) const;
+ void ReverseFind(char c) const;
+ void ReverseFind(unsigned char c) const;
+ void InsertAtFront(char c);
+ void InsertAtFront(unsigned char c);
+ void RemoveChar(char ch);
+ void RemoveChar(unsigned char ch);
+ void Replace(char oldChar, char newChar);
+ void Replace(unsigned char oldChar, unsigned char newChar);
+
+public:
+ UString();
+ UString(wchar_t c);
+ UString(const wchar_t *s);
+ UString(const UString &s);
+ ~UString() { MY_STRING_DELETE(_chars); }
+
+ unsigned Len() const { return _len; }
+ bool IsEmpty() const { return _len == 0; }
+ void Empty() { _len = 0; _chars[0] = 0; }
+
+ operator const wchar_t *() const { return _chars; }
+ const wchar_t *Ptr() const { return _chars; }
+ const wchar_t *Ptr(unsigned pos) const { return _chars + pos; }
+ const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; }
+ wchar_t Back() const { return _chars[_len - 1]; }
+
+ void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
+
+ wchar_t *GetBuf(unsigned minLen)
{
- if (_length == 0)
- return -1;
- const T *p = _chars + _length - 1;
- for (;;)
- {
- if (*p == c)
- return (int)(p - _chars);
- if (p == _chars)
- return -1;
- p = GetPrevCharPointer(_chars, p);
- }
+ if (minLen > _limit)
+ ReAlloc2(minLen);
+ return _chars;
}
- int FindOneOf(const CStringBase &s) const
+ wchar_t *GetBuf_SetEnd(unsigned minLen)
{
- for (int i = 0; i < _length; i++)
- if (s.Find(_chars[i]) >= 0)
- return i;
- return -1;
+ if (minLen > _limit)
+ ReAlloc2(minLen);
+ wchar_t *chars = _chars;
+ chars[minLen] = 0;
+ _len = minLen;
+ return chars;
}
- void TrimLeft(T c)
+ void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
+ void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
+ void ReleaseBuf_CalcLen(unsigned maxLen)
{
- const T *p = _chars;
- while (c == *p)
- p = GetNextCharPointer(p);
- Delete(0, p - _chars);
+ wchar_t *chars = _chars;
+ chars[maxLen] = 0;
+ _len = MyStringLen(chars);
}
- private:
- CStringBase GetTrimDefaultCharSet()
- {
- CStringBase<T> charSet;
- charSet += (T)' ';
- charSet += (T)'\n';
- charSet += (T)'\t';
- return charSet;
- }
- public:
- void TrimLeft()
+ UString &operator=(wchar_t c);
+ UString &operator=(const wchar_t *s);
+ UString &operator=(const UString &s);
+ void SetFromBstr(BSTR s);
+
+ UString &operator+=(wchar_t c)
{
- TrimLeftWithCharSet(GetTrimDefaultCharSet());
+ if (_limit == _len)
+ Grow_1();
+ unsigned len = _len;
+ wchar_t *chars = _chars;
+ chars[len++] = c;
+ chars[len] = 0;
+ _len = len;
+ return *this;
}
- void TrimRight()
+
+ void Add_Space();
+ void Add_Space_if_NotEmpty();
+ void Add_LF();
+ void Add_PathSepar() { operator+=(WCHAR_PATH_SEPARATOR); }
+
+ UString &operator+=(const wchar_t *s);
+ UString &operator+=(const UString &s);
+
+ void SetFrom(const wchar_t *s, unsigned len); // no check
+
+ void SetFromAscii(const char *s);
+ void AddAscii(const char *s);
+
+ UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); }
+ UString Left(unsigned count) const { return UString(count, *this); }
+
+ // void MakeUpper() { MyStringUpper(_chars); }
+ // void MakeUpper() { MyStringUpper_Ascii(_chars); }
+ // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); }
+ void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
+
+ bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); }
+ bool IsEqualTo_NoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); }
+ bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
+ int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
+ // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); }
+ // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); }
+ // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
+ bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); }
+ bool IsPrefixedBy_NoCase(const wchar_t *s) const { return IsString1PrefixedByString2_NoCase(_chars, s); }
+ bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
+
+ bool IsAscii() const
{
- TrimRightWithCharSet(GetTrimDefaultCharSet());
+ unsigned len = Len();
+ const wchar_t *s = _chars;
+ for (unsigned i = 0; i < len; i++)
+ if (s[i] >= 0x80)
+ return false;
+ return true;
}
- void TrimRight(T c)
+ int Find(wchar_t c) const { return FindCharPosInString(_chars, c); }
+ int Find(wchar_t c, unsigned startIndex) const
{
- const T *p = _chars;
- const T *pLast = NULL;
- while (*p != 0)
- {
- if (*p == c)
- {
- if (pLast == NULL)
- pLast = p;
- }
- else
- pLast = NULL;
- p = GetNextCharPointer(p);
- }
- if (pLast != NULL)
- {
- int i = pLast - _chars;
- Delete(i, _length - i);
- }
+ int pos = FindCharPosInString(_chars + startIndex, c);
+ return pos < 0 ? -1 : (int)startIndex + pos;
}
+
+ int ReverseFind(wchar_t c) const throw();
+ int ReverseFind_Dot() const throw() { return ReverseFind(L'.'); }
+ int ReverseFind_PathSepar() const throw();
+
+ int Find(const wchar_t *s) const { return Find(s, 0); }
+ int Find(const wchar_t *s, unsigned startIndex) const throw();
+
+ void TrimLeft() throw();
+ void TrimRight() throw();
void Trim()
{
TrimRight();
TrimLeft();
}
- int Insert(int index, T c)
- {
- InsertSpace(index, 1);
- _chars[index] = c;
- _length++;
- return _length;
- }
- int Insert(int index, const CStringBase &s)
- {
- CorrectIndex(index);
- if (s.IsEmpty())
- return _length;
- int numInsertChars = s.Length();
- InsertSpace(index, numInsertChars);
- for (int i = 0; i < numInsertChars; i++)
- _chars[index + i] = s[i];
- _length += numInsertChars;
- return _length;
- }
+ void InsertAtFront(wchar_t c);
+ // void Insert(unsigned index, wchar_t c);
+ void Insert(unsigned index, const wchar_t *s);
+ void Insert(unsigned index, const UString &s);
- // !!!!!!!!!!!!!!! test it if newChar = '\0'
- int Replace(T oldChar, T newChar)
- {
- if (oldChar == newChar)
- return 0;
- int number = 0;
- int pos = 0;
- while (pos < Length())
- {
- pos = Find(oldChar, pos);
- if (pos < 0)
- break;
- _chars[pos] = newChar;
- pos++;
- number++;
- }
- return number;
- }
- int Replace(const CStringBase &oldString, const CStringBase &newString)
- {
- if (oldString.IsEmpty())
- return 0;
- if (oldString == newString)
- return 0;
- int oldStringLength = oldString.Length();
- int newStringLength = newString.Length();
- int number = 0;
- int pos = 0;
- while (pos < _length)
- {
- pos = Find(oldString, pos);
- if (pos < 0)
- break;
- Delete(pos, oldStringLength);
- Insert(pos, newString);
- pos += newStringLength;
- number++;
- }
- return number;
- }
- int Delete(int index, int count = 1)
+ void RemoveChar(wchar_t ch) throw();
+
+ void Replace(wchar_t oldChar, wchar_t newChar) throw();
+ void Replace(const UString &oldString, const UString &newString);
+
+ void Delete(unsigned index) throw();
+ void Delete(unsigned index, unsigned count) throw();
+ void DeleteFrontal(unsigned num) throw();
+ void DeleteBack() { _chars[--_len] = 0; }
+ void DeleteFrom(unsigned index)
{
- if (index + count > _length)
- count = _length - index;
- if (count > 0)
+ if (index < _len)
{
- MoveItems(index, index + count);
- _length -= count;
+ _len = index;
+ _chars[index] = 0;
}
- return _length;
}
- void DeleteBack() { Delete(_length - 1); }
};
-template <class T>
-CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
-{
- CStringBase<T> result(s1);
- result += s2;
- return result;
-}
+bool operator<(const UString &s1, const UString &s2);
+bool operator>(const UString &s1, const UString &s2);
+
+inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; }
+inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; }
+inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; }
+
+inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; }
+inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; }
+inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; }
+
+
+// ---------- forbidden functions ----------
+
+void operator==(wchar_t c1, const UString &s2);
+void operator==(const UString &s1, wchar_t c2);
+
+void operator+(wchar_t c, const UString &s); // this function can be OK, but we don't use it
+
+void operator+(const UString &s, char c);
+void operator+(const UString &s, unsigned char c);
+void operator+(char c, const UString &s);
+void operator+(unsigned char c, const UString &s);
+void operator-(const UString &s1, wchar_t c);
+
+#ifdef _WIN32
+// can we forbid these functions, if wchar_t is 32-bit ?
+void operator+(const UString &s, int c);
+void operator+(const UString &s, unsigned c);
+void operator+(int c, const UString &s);
+void operator+(unsigned c, const UString &s);
+void operator-(const UString &s1, int c);
+void operator-(const UString &s1, unsigned c);
+#endif
+
+
-template <class T>
-CStringBase<T> operator+(const CStringBase<T>& s, T c)
-{
- CStringBase<T> result(s);
- result += c;
- return result;
-}
-template <class T>
-CStringBase<T> operator+(T c, const CStringBase<T>& s)
-{
- CStringBase<T> result(c);
- result += s;
- return result;
-}
-template <class T>
-CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)
-{
- CStringBase<T> result(s);
- result += chars;
- return result;
-}
-template <class T>
-CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)
+
+class UString2
{
- CStringBase<T> result(chars);
- result += s;
- return result;
-}
+ wchar_t *_chars;
+ unsigned _len;
+
+ void ReAlloc2(unsigned newLimit);
+ void SetStartLen(unsigned len);
+
+ // ---------- forbidden functions ----------
+
+ UString2 &operator=(char c);
+ UString2 &operator=(unsigned char c);
+ UString2 &operator=(wchar_t c);
+ UString2(char c);
+ UString2(unsigned char c);
+
+public:
+ UString2(): _chars(NULL), _len(0) {}
+ // UString2(wchar_t c);
+ UString2(const wchar_t *s);
+ UString2(const UString2 &s);
+ ~UString2() { if (_chars) MY_STRING_DELETE(_chars); }
+
+ unsigned Len() const { return _len; }
+ bool IsEmpty() const { return _len == 0; }
+ // void Empty() { _len = 0; _chars[0] = 0; }
+
+ // operator const wchar_t *() const { return _chars; }
+ const wchar_t *GetRawPtr() const { return _chars; }
+
+ wchar_t *GetBuf(unsigned minLen)
+ {
+ if (!_chars || minLen > _len)
+ ReAlloc2(minLen);
+ return _chars;
+ }
+ void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
+
+ UString2 &operator=(const wchar_t *s);
+ UString2 &operator=(const UString2 &s);
+ void SetFromAscii(const char *s);
+};
+
+bool operator==(const UString2 &s1, const UString2 &s2);
+bool operator==(const UString2 &s1, const wchar_t *s2);
+bool operator==(const wchar_t *s1, const UString2 &s2);
+
+inline bool operator!=(const UString2 &s1, const UString2 &s2) { return !(s1 == s2); }
+inline bool operator!=(const UString2 &s1, const wchar_t *s2) { return !(s1 == s2); }
+inline bool operator!=(const wchar_t *s1, const UString2 &s2) { return !(s1 == s2); }
+
-template <class T>
-bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)
- { return (s1.Compare(s2) == 0); }
+// ---------- forbidden functions ----------
-template <class T>
-bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)
- { return (s1.Compare(s2) < 0); }
+void operator==(wchar_t c1, const UString2 &s2);
+void operator==(const UString2 &s1, wchar_t c2);
+bool operator<(const UString2 &s1, const UString2 &s2);
+bool operator>(const UString2 &s1, const UString2 &s2);
-template <class T>
-bool operator==(const T *s1, const CStringBase<T>& s2)
- { return (s2.Compare(s1) == 0); }
+void operator+(const UString2 &s1, const UString2 &s2);
+void operator+(const UString2 &s1, const wchar_t *s2);
+void operator+(const wchar_t *s1, const UString2 &s2);
+void operator+(wchar_t c, const UString2 &s);
+void operator+(const UString2 &s, wchar_t c);
+void operator+(const UString2 &s, char c);
+void operator+(const UString2 &s, unsigned char c);
+void operator+(char c, const UString2 &s);
+void operator+(unsigned char c, const UString2 &s);
+void operator-(const UString2 &s1, wchar_t c);
-template <class T>
-bool operator==(const CStringBase<T>& s1, const T *s2)
- { return (s1.Compare(s2) == 0); }
-template <class T>
-bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)
- { return (s1.Compare(s2) != 0); }
-template <class T>
-bool operator!=(const T *s1, const CStringBase<T>& s2)
- { return (s2.Compare(s1) != 0); }
-template <class T>
-bool operator!=(const CStringBase<T>& s1, const T *s2)
- { return (s1.Compare(s2) != 0); }
-typedef CStringBase<char> AString;
-typedef CStringBase<wchar_t> UString;
typedef CObjectVector<AString> AStringVector;
typedef CObjectVector<UString> UStringVector;
diff --git a/3rdparty/lzma/CPP/Common/MyTypes.h b/3rdparty/lzma/CPP/Common/MyTypes.h
new file mode 100644
index 00000000000..75806f37dcf
--- /dev/null
+++ b/3rdparty/lzma/CPP/Common/MyTypes.h
@@ -0,0 +1,35 @@
+// Common/MyTypes.h
+
+#ifndef __COMMON_MY_TYPES_H
+#define __COMMON_MY_TYPES_H
+
+#include "../../C/7zTypes.h"
+
+typedef int HRes;
+
+struct CBoolPair
+{
+ bool Val;
+ bool Def;
+
+ CBoolPair(): Val(false), Def(false) {}
+
+ void Init()
+ {
+ Val = false;
+ Def = false;
+ }
+
+ void SetTrueTrue()
+ {
+ Val = true;
+ Def = true;
+ }
+};
+
+#define CLASS_NO_COPY(cls) \
+ private: \
+ cls(const cls &); \
+ cls &operator=(const cls &);
+
+#endif
diff --git a/3rdparty/lzma/CPP/Common/MyUnknown.h b/3rdparty/lzma/CPP/Common/MyUnknown.h
index e9e8666b920..ff025cb538d 100644
--- a/3rdparty/lzma/CPP/Common/MyUnknown.h
+++ b/3rdparty/lzma/CPP/Common/MyUnknown.h
@@ -3,11 +3,15 @@
#ifndef __MY_UNKNOWN_H
#define __MY_UNKNOWN_H
+#include "MyWindows.h"
+
+/*
#ifdef _WIN32
#include <basetyps.h>
#include <unknwn.h>
#else
#include "MyWindows.h"
#endif
+*/
#endif
diff --git a/3rdparty/lzma/CPP/Common/MyVector.cpp b/3rdparty/lzma/CPP/Common/MyVector.cpp
index 3b531768847..0b1baf45cc6 100644
--- a/3rdparty/lzma/CPP/Common/MyVector.cpp
+++ b/3rdparty/lzma/CPP/Common/MyVector.cpp
@@ -1,87 +1,3 @@
// Common/MyVector.cpp
#include "StdAfx.h"
-
-#include <string.h>
-
-#include "MyVector.h"
-
-CBaseRecordVector::~CBaseRecordVector() { ClearAndFree(); }
-
-void CBaseRecordVector::ClearAndFree()
-{
- Clear();
- delete []((unsigned char *)_items);
- _capacity = 0;
- _size = 0;
- _items = 0;
-}
-
-void CBaseRecordVector::Clear() { DeleteFrom(0); }
-void CBaseRecordVector::DeleteBack() { Delete(_size - 1); }
-void CBaseRecordVector::DeleteFrom(int index) { Delete(index, _size - index); }
-
-void CBaseRecordVector::ReserveOnePosition()
-{
- if (_size != _capacity)
- return;
- unsigned delta = 1;
- if (_capacity >= 64)
- delta = (unsigned)_capacity / 4;
- else if (_capacity >= 8)
- delta = 8;
- Reserve(_capacity + (int)delta);
-}
-
-void CBaseRecordVector::Reserve(int newCapacity)
-{
- // if (newCapacity <= _capacity)
- if (newCapacity == _capacity)
- return;
- if ((unsigned)newCapacity >= ((unsigned)1 << (sizeof(unsigned) * 8 - 1)))
- throw 1052353;
- size_t newSize = (size_t)(unsigned)newCapacity * _itemSize;
- if (newSize / _itemSize != (size_t)(unsigned)newCapacity)
- throw 1052354;
- unsigned char *p = NULL;
- if (newSize > 0)
- {
- p = new unsigned char[newSize];
- if (p == 0)
- throw 1052355;
- int numRecordsToMove = (_size < newCapacity ? _size : newCapacity);
- memcpy(p, _items, _itemSize * numRecordsToMove);
- }
- delete [](unsigned char *)_items;
- _items = p;
- _capacity = newCapacity;
-}
-
-void CBaseRecordVector::ReserveDown()
-{
- Reserve(_size);
-}
-
-void CBaseRecordVector::MoveItems(int destIndex, int srcIndex)
-{
- memmove(((unsigned char *)_items) + destIndex * _itemSize,
- ((unsigned char *)_items) + srcIndex * _itemSize,
- _itemSize * (_size - srcIndex));
-}
-
-void CBaseRecordVector::InsertOneItem(int index)
-{
- ReserveOnePosition();
- MoveItems(index + 1, index);
- _size++;
-}
-
-void CBaseRecordVector::Delete(int index, int num)
-{
- TestIndexAndCorrectNum(index, num);
- if (num > 0)
- {
- MoveItems(index, index + num);
- _size -= num;
- }
-}
diff --git a/3rdparty/lzma/CPP/Common/MyVector.h b/3rdparty/lzma/CPP/Common/MyVector.h
index 781b648bc87..14f7b11a1a7 100644
--- a/3rdparty/lzma/CPP/Common/MyVector.h
+++ b/3rdparty/lzma/CPP/Common/MyVector.h
@@ -1,92 +1,256 @@
-// Common/Vector.h
+// Common/MyVector.h
-#ifndef __COMMON_VECTOR_H
-#define __COMMON_VECTOR_H
+#ifndef __COMMON_MY_VECTOR_H
+#define __COMMON_MY_VECTOR_H
-#include "Defs.h"
+#include <string.h>
-class CBaseRecordVector
+template <class T>
+class CRecordVector
{
- void MoveItems(int destIndex, int srcIndex);
-protected:
- int _capacity;
- int _size;
- void *_items;
- size_t _itemSize;
+ T *_items;
+ unsigned _size;
+ unsigned _capacity;
- void ReserveOnePosition();
- void InsertOneItem(int index);
- void TestIndexAndCorrectNum(int index, int &num) const
- { if (index + num > _size) num = _size - index; }
-public:
- CBaseRecordVector(size_t itemSize): _capacity(0), _size(0), _items(0), _itemSize(itemSize) {}
- virtual ~CBaseRecordVector();
- void ClearAndFree();
- int Size() const { return _size; }
- bool IsEmpty() const { return (_size == 0); }
- void Reserve(int newCapacity);
- void ReserveDown();
- virtual void Delete(int index, int num = 1);
- void Clear();
- void DeleteFrom(int index);
- void DeleteBack();
-};
+ void MoveItems(unsigned destIndex, unsigned srcIndex)
+ {
+ memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T));
+ }
+
+ void ReserveOnePosition()
+ {
+ if (_size == _capacity)
+ {
+ unsigned newCapacity = _capacity + (_capacity >> 2) + 1;
+ T *p = new T[newCapacity];
+ if (_size != 0)
+ memcpy(p, _items, (size_t)_size * sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newCapacity;
+ }
+ }
-template <class T>
-class CRecordVector: public CBaseRecordVector
-{
public:
- CRecordVector(): CBaseRecordVector(sizeof(T)){};
- CRecordVector(const CRecordVector &v): CBaseRecordVector(sizeof(T)) { *this = v; }
- CRecordVector& operator=(const CRecordVector &v)
+
+ CRecordVector(): _items(0), _size(0), _capacity(0) {}
+
+ CRecordVector(const CRecordVector &v): _items(0), _size(0), _capacity(0)
+ {
+ unsigned size = v.Size();
+ if (size != 0)
+ {
+ _items = new T[size];
+ _size = size;
+ _capacity = size;
+ memcpy(_items, v._items, (size_t)size * sizeof(T));
+ }
+ }
+
+ unsigned Size() const { return _size; }
+ bool IsEmpty() const { return _size == 0; }
+
+ void ConstructReserve(unsigned size)
+ {
+ if (size != 0)
+ {
+ _items = new T[size];
+ _capacity = size;
+ }
+ }
+
+ void Reserve(unsigned newCapacity)
+ {
+ if (newCapacity > _capacity)
+ {
+ T *p = new T[newCapacity];
+ if (_size != 0)
+ memcpy(p, _items, (size_t)_size * sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newCapacity;
+ }
+ }
+
+ void ClearAndReserve(unsigned newCapacity)
{
Clear();
- return (*this += v);
+ if (newCapacity > _capacity)
+ {
+ delete []_items;
+ _items = NULL;
+ _capacity = 0;
+ _items = new T[newCapacity];
+ _capacity = newCapacity;
+ }
+ }
+
+ void ClearAndSetSize(unsigned newSize)
+ {
+ ClearAndReserve(newSize);
+ _size = newSize;
+ }
+
+ void ChangeSize_KeepData(unsigned newSize)
+ {
+ if (newSize > _capacity)
+ {
+ T *p = new T[newSize];
+ if (_size != 0)
+ memcpy(p, _items, (size_t)_size * sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newSize;
+ }
+ _size = newSize;
+ }
+
+ void ReserveDown()
+ {
+ if (_size == _capacity)
+ return;
+ T *p = NULL;
+ if (_size != 0)
+ {
+ p = new T[_size];
+ memcpy(p, _items, (size_t)_size * sizeof(T));
+ }
+ delete []_items;
+ _items = p;
+ _capacity = _size;
+ }
+
+ ~CRecordVector() { delete []_items; }
+
+ void ClearAndFree()
+ {
+ delete []_items;
+ _items = NULL;
+ _size = 0;
+ _capacity = 0;
+ }
+
+ void Clear() { _size = 0; }
+
+ void DeleteBack() { _size--; }
+
+ void DeleteFrom(unsigned index)
+ {
+ // if (index <= _size)
+ _size = index;
+ }
+
+ void DeleteFrontal(unsigned num)
+ {
+ if (num != 0)
+ {
+ MoveItems(0, num);
+ _size -= num;
+ }
+ }
+
+ void Delete(unsigned index)
+ {
+ MoveItems(index, index + 1);
+ _size -= 1;
+ }
+
+ /*
+ void Delete(unsigned index, unsigned num)
+ {
+ if (num > 0)
+ {
+ MoveItems(index, index + num);
+ _size -= num;
+ }
+ }
+ */
+
+ CRecordVector& operator=(const CRecordVector &v)
+ {
+ if (&v == this)
+ return *this;
+ unsigned size = v.Size();
+ if (size > _capacity)
+ {
+ delete []_items;
+ _capacity = 0;
+ _size = 0;
+ _items = NULL;
+ _items = new T[size];
+ _capacity = size;
+ }
+ _size = size;
+ if (size != 0)
+ memcpy(_items, v._items, (size_t)size * sizeof(T));
+ return *this;
}
+
CRecordVector& operator+=(const CRecordVector &v)
{
- int size = v.Size();
- Reserve(Size() + size);
- for (int i = 0; i < size; i++)
- Add(v[i]);
+ unsigned size = v.Size();
+ Reserve(_size + size);
+ if (size != 0)
+ memcpy(_items + _size, v._items, (size_t)size * sizeof(T));
+ _size += size;
return *this;
}
- int Add(T item)
+
+ unsigned Add(const T item)
{
ReserveOnePosition();
- ((T *)_items)[_size] = item;
+ _items[_size] = item;
return _size++;
}
- void Insert(int index, T item)
+
+ void AddInReserved(const T item)
{
- InsertOneItem(index);
- ((T *)_items)[index] = item;
+ _items[_size++] = item;
}
- // T* GetPointer() const { return (T*)_items; }
- // operator const T *() const { return _items; };
- const T& operator[](int index) const { return ((T *)_items)[index]; }
- T& operator[](int index) { return ((T *)_items)[index]; }
- const T& Front() const { return operator[](0); }
- T& Front() { return operator[](0); }
- const T& Back() const { return operator[](_size - 1); }
- T& Back() { return operator[](_size - 1); }
- void Swap(int i, int j)
+ void Insert(unsigned index, const T item)
{
- T temp = operator[](i);
- operator[](i) = operator[](j);
- operator[](j) = temp;
+ ReserveOnePosition();
+ MoveItems(index + 1, index);
+ _items[index] = item;
+ _size++;
}
- int FindInSorted(const T& item, int left, int right) const
+ void MoveToFront(unsigned index)
+ {
+ if (index != 0)
+ {
+ T temp = _items[index];
+ memmove(_items + 1, _items, (size_t)index * sizeof(T));
+ _items[0] = temp;
+ }
+ }
+
+ const T& operator[](unsigned index) const { return _items[index]; }
+ T& operator[](unsigned index) { return _items[index]; }
+ const T& Front() const { return _items[0]; }
+ T& Front() { return _items[0]; }
+ const T& Back() const { return _items[_size - 1]; }
+ T& Back() { return _items[_size - 1]; }
+
+ /*
+ void Swap(unsigned i, unsigned j)
+ {
+ T temp = _items[i];
+ _items[i] = _items[j];
+ _items[j] = temp;
+ }
+ */
+
+ int FindInSorted(const T item, unsigned left, unsigned right) const
{
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T midVal = (*this)[mid];
+ if (item == midVal)
return mid;
- if (item < midValue)
+ if (item < midVal)
right = mid;
else
left = mid + 1;
@@ -94,16 +258,16 @@ public:
return -1;
}
- int FindInSorted(const T& item) const
+ int FindInSorted2(const T &item, unsigned left, unsigned right) const
{
- int left = 0, right = Size();
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
return mid;
- if (item < midValue)
+ if (comp < 0)
right = mid;
else
left = mid + 1;
@@ -111,16 +275,26 @@ public:
return -1;
}
- int AddToUniqueSorted(const T& item)
+ int FindInSorted(const T item) const
+ {
+ return FindInSorted(item, 0, _size);
+ }
+
+ int FindInSorted2(const T &item) const
{
- int left = 0, right = Size();
+ return FindInSorted2(item, 0, _size);
+ }
+
+ unsigned AddToUniqueSorted(const T item)
+ {
+ unsigned left = 0, right = _size;
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T midVal = (*this)[mid];
+ if (item == midVal)
return mid;
- if (item < midValue)
+ if (item < midVal)
right = mid;
else
left = mid + 1;
@@ -129,12 +303,31 @@ public:
return right;
}
- static void SortRefDown(T* p, int k, int size, int (*compare)(const T*, const T*, void *), void *param)
+ unsigned AddToUniqueSorted2(const T &item)
+ {
+ unsigned left = 0, right = _size;
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
+ return mid;
+ if (comp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+
+ static void SortRefDown(T* p, unsigned k, unsigned size, int (*compare)(const T*, const T*, void *), void *param)
{
T temp = p[k];
for (;;)
{
- int s = (k << 1);
+ unsigned s = (k << 1);
if (s > size)
break;
if (s < size && compare(p + s + 1, p + s, param) > 0)
@@ -149,12 +342,12 @@ public:
void Sort(int (*compare)(const T*, const T*, void *), void *param)
{
- int size = _size;
+ unsigned size = _size;
if (size <= 1)
return;
T* p = (&Front()) - 1;
{
- int i = size / 2;
+ unsigned i = size >> 1;
do
SortRefDown(p, i, size, compare, param);
while (--i != 0);
@@ -168,6 +361,46 @@ public:
}
while (size > 1);
}
+
+ static void SortRefDown2(T* p, unsigned k, unsigned size)
+ {
+ T temp = p[k];
+ for (;;)
+ {
+ unsigned s = (k << 1);
+ if (s > size)
+ break;
+ if (s < size && p[s + 1].Compare(p[s]) > 0)
+ s++;
+ if (temp.Compare(p[s]) >= 0)
+ break;
+ p[k] = p[s];
+ k = s;
+ }
+ p[k] = temp;
+ }
+
+ void Sort2()
+ {
+ unsigned size = _size;
+ if (size <= 1)
+ return;
+ T* p = (&Front()) - 1;
+ {
+ unsigned i = size >> 1;
+ do
+ SortRefDown2(p, i, size);
+ while (--i != 0);
+ }
+ do
+ {
+ T temp = p[size];
+ p[size--] = p[1];
+ p[1] = temp;
+ SortRefDown2(p, 1, size);
+ }
+ while (size > 1);
+ }
};
typedef CRecordVector<int> CIntVector;
@@ -177,76 +410,199 @@ typedef CRecordVector<unsigned char> CByteVector;
typedef CRecordVector<void *> CPointerVector;
template <class T>
-class CObjectVector: public CPointerVector
+class CObjectVector
{
+ CPointerVector _v;
public:
+ unsigned Size() const { return _v.Size(); }
+ bool IsEmpty() const { return _v.IsEmpty(); }
+ void ReserveDown() { _v.ReserveDown(); }
+ // void Reserve(unsigned newCapacity) { _v.Reserve(newCapacity); }
+ void ClearAndReserve(unsigned newCapacity) { Clear(); _v.ClearAndReserve(newCapacity); }
+
CObjectVector() {};
- ~CObjectVector() { Clear(); };
- CObjectVector(const CObjectVector &v): CPointerVector() { *this = v; }
+ CObjectVector(const CObjectVector &v)
+ {
+ unsigned size = v.Size();
+ _v.ConstructReserve(size);
+ for (unsigned i = 0; i < size; i++)
+ _v.AddInReserved(new T(v[i]));
+ }
CObjectVector& operator=(const CObjectVector &v)
{
+ if (&v == this)
+ return *this;
Clear();
- return (*this += v);
+ unsigned size = v.Size();
+ _v.Reserve(size);
+ for (unsigned i = 0; i < size; i++)
+ _v.AddInReserved(new T(v[i]));
+ return *this;
}
+
CObjectVector& operator+=(const CObjectVector &v)
{
- int size = v.Size();
- Reserve(Size() + size);
- for (int i = 0; i < size; i++)
- Add(v[i]);
+ unsigned size = v.Size();
+ _v.Reserve(Size() + size);
+ for (unsigned i = 0; i < size; i++)
+ _v.AddInReserved(new T(v[i]));
return *this;
}
- const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); }
- T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); }
- T& Front() { return operator[](0); }
+
+ const T& operator[](unsigned index) const { return *((T *)_v[index]); }
+ T& operator[](unsigned index) { return *((T *)_v[index]); }
const T& Front() const { return operator[](0); }
- T& Back() { return operator[](_size - 1); }
- const T& Back() const { return operator[](_size - 1); }
- int Add(const T& item) { return CPointerVector::Add(new T(item)); }
- void Insert(int index, const T& item) { CPointerVector::Insert(index, new T(item)); }
- virtual void Delete(int index, int num = 1)
+ T& Front() { return operator[](0); }
+ const T& Back() const { return operator[](_v.Size() - 1); }
+ T& Back() { return operator[](_v.Size() - 1); }
+
+ void MoveToFront(unsigned index) { _v.MoveToFront(index); }
+
+ unsigned Add(const T& item) { return _v.Add(new T(item)); }
+
+ void AddInReserved(const T& item) { _v.AddInReserved(new T(item)); }
+
+ T& AddNew()
{
- TestIndexAndCorrectNum(index, num);
- for (int i = 0; i < num; i++)
- delete (T *)(((void **)_items)[index + i]);
- CPointerVector::Delete(index, num);
+ T *p = new T;
+ _v.Add(p);
+ return *p;
}
+
+ T& AddNewInReserved()
+ {
+ T *p = new T;
+ _v.AddInReserved(p);
+ return *p;
+ }
+
+ void Insert(unsigned index, const T& item) { _v.Insert(index, new T(item)); }
+
+ T& InsertNew(unsigned index)
+ {
+ T *p = new T;
+ _v.Insert(index, p);
+ return *p;
+ }
+
+ ~CObjectVector()
+ {
+ for (unsigned i = _v.Size(); i != 0;)
+ delete (T *)_v[--i];
+ }
+
+ void ClearAndFree()
+ {
+ Clear();
+ _v.ClearAndFree();
+ }
+
+ void Clear()
+ {
+ for (unsigned i = _v.Size(); i != 0;)
+ delete (T *)_v[--i];
+ _v.Clear();
+ }
+
+ void DeleteFrom(unsigned index)
+ {
+ unsigned size = _v.Size();
+ for (unsigned i = index; i < size; i++)
+ delete (T *)_v[i];
+ _v.DeleteFrom(index);
+ }
+
+ void DeleteFrontal(unsigned num)
+ {
+ for (unsigned i = 0; i < num; i++)
+ delete (T *)_v[i];
+ _v.DeleteFrontal(num);
+ }
+
+ void DeleteBack()
+ {
+ delete (T *)_v[_v.Size() - 1];
+ _v.DeleteBack();
+ }
+
+ void Delete(unsigned index)
+ {
+ delete (T *)_v[index];
+ _v.Delete(index);
+ }
+
+ /*
+ void Delete(unsigned index, unsigned num)
+ {
+ for (unsigned i = 0; i < num; i++)
+ delete (T *)_v[index + i];
+ _v.Delete(index, num);
+ }
+ */
+
+ /*
int Find(const T& item) const
{
- for (int i = 0; i < Size(); i++)
+ unsigned size = Size();
+ for (unsigned i = 0; i < size; i++)
if (item == (*this)[i])
return i;
return -1;
}
+ */
+
int FindInSorted(const T& item) const
{
- int left = 0, right = Size();
+ unsigned left = 0, right = Size();
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
return mid;
- if (item < midValue)
+ if (comp < 0)
right = mid;
else
left = mid + 1;
}
return -1;
}
- int AddToSorted(const T& item)
+
+ unsigned AddToUniqueSorted(const T& item)
+ {
+ unsigned left = 0, right = Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
+ return mid;
+ if (comp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+
+ /*
+ unsigned AddToSorted(const T& item)
{
- int left = 0, right = Size();
+ unsigned left = 0, right = Size();
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
{
right = mid + 1;
break;
}
- if (item < midValue)
+ if (comp < 0)
right = mid;
else
left = mid + 1;
@@ -254,13 +610,17 @@ public:
Insert(right, item);
return right;
}
+ */
void Sort(int (*compare)(void *const *, void *const *, void *), void *param)
- { CPointerVector::Sort(compare, param); }
+ { _v.Sort(compare, param); }
static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */)
- { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); }
- void Sort() { CPointerVector::Sort(CompareObjectItems, 0); }
+ { return (*(*((const T **)a1))).Compare(*(*((const T **)a2))); }
+
+ void Sort() { _v.Sort(CompareObjectItems, 0); }
};
+#define FOR_VECTOR(_i_, _v_) for (unsigned _i_ = 0; _i_ < (_v_).Size(); _i_++)
+
#endif
diff --git a/3rdparty/lzma/CPP/Common/MyWindows.cpp b/3rdparty/lzma/CPP/Common/MyWindows.cpp
index f940fc8aee2..463c77c4a37 100644
--- a/3rdparty/lzma/CPP/Common/MyWindows.cpp
+++ b/3rdparty/lzma/CPP/Common/MyWindows.cpp
@@ -4,71 +4,104 @@
#ifndef _WIN32
+#include <stdlib.h>
+
#include "MyWindows.h"
-#include "Types.h"
-#include <malloc.h>
static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); }
static inline void FreeForBSTR(void *pv) { ::free(pv);}
-static UINT MyStringLen(const wchar_t *s)
+/* Win32 uses DWORD (32-bit) type to store size of string before (OLECHAR *) string.
+ We must select CBstrSizeType for another systems (not Win32):
+
+ if (CBstrSizeType is UINT32),
+ then we support only strings smaller than 4 GB.
+ Win32 version always has that limitation.
+
+ if (CBstrSizeType is UINT),
+ (UINT can be 16/32/64-bit)
+ We can support strings larger than 4 GB (if UINT is 64-bit),
+ but sizeof(UINT) can be different in parts compiled by
+ different compilers/settings,
+ and we can't send such BSTR strings between such parts.
+*/
+
+typedef UINT32 CBstrSizeType;
+// typedef UINT CBstrSizeType;
+
+#define k_BstrSize_Max 0xFFFFFFFF
+// #define k_BstrSize_Max UINT_MAX
+// #define k_BstrSize_Max ((UINT)(INT)-1)
+
+BSTR SysAllocStringByteLen(LPCSTR s, UINT len)
{
- UINT i;
- for (i = 0; s[i] != '\0'; i++);
- return i;
+ /* Original SysAllocStringByteLen in Win32 maybe fills only unaligned null OLECHAR at the end.
+ We provide also aligned null OLECHAR at the end. */
+
+ if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(OLECHAR) - sizeof(CBstrSizeType)))
+ return NULL;
+
+ UINT size = (len + sizeof(OLECHAR) + sizeof(OLECHAR) - 1) & ~(sizeof(OLECHAR) - 1);
+ void *p = AllocateForBSTR(size + sizeof(CBstrSizeType));
+ if (!p)
+ return NULL;
+ *(CBstrSizeType *)p = (CBstrSizeType)len;
+ BSTR bstr = (BSTR)((CBstrSizeType *)p + 1);
+ if (s)
+ memcpy(bstr, s, len);
+ for (; len < size; len++)
+ ((Byte *)bstr)[len] = 0;
+ return bstr;
}
-BSTR SysAllocStringByteLen(LPCSTR psz, UINT len)
+BSTR SysAllocStringLen(const OLECHAR *s, UINT len)
{
- int realLen = len + sizeof(UINT) + sizeof(OLECHAR) + sizeof(OLECHAR);
- void *p = AllocateForBSTR(realLen);
- if (p == 0)
- return 0;
- *(UINT *)p = len;
- BSTR bstr = (BSTR)((UINT *)p + 1);
- if (psz)
- {
- memmove(bstr, psz, len);
- Byte *pb = ((Byte *)bstr) + len;
- for (unsigned i = 0; i < sizeof(OLECHAR) * 2; i++)
- pb[i] = 0;
- }
+ if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(CBstrSizeType)) / sizeof(OLECHAR))
+ return NULL;
+
+ UINT size = len * sizeof(OLECHAR);
+ void *p = AllocateForBSTR(size + sizeof(CBstrSizeType) + sizeof(OLECHAR));
+ if (!p)
+ return NULL;
+ *(CBstrSizeType *)p = (CBstrSizeType)size;
+ BSTR bstr = (BSTR)((CBstrSizeType *)p + 1);
+ if (s)
+ memcpy(bstr, s, size);
+ bstr[len] = 0;
return bstr;
}
-BSTR SysAllocString(const OLECHAR *sz)
+BSTR SysAllocString(const OLECHAR *s)
{
- if (sz == 0)
+ if (!s)
return 0;
- UINT strLen = MyStringLen(sz);
- UINT len = (strLen + 1) * sizeof(OLECHAR);
- void *p = AllocateForBSTR(len + sizeof(UINT));
- if (p == 0)
- return 0;
- *(UINT *)p = strLen;
- BSTR bstr = (BSTR)((UINT *)p + 1);
- memmove(bstr, sz, len);
- return bstr;
+ const OLECHAR *s2 = s;
+ while (*s2 != 0)
+ s2++;
+ return SysAllocStringLen(s, (UINT)(s2 - s));
}
void SysFreeString(BSTR bstr)
{
- if (bstr != 0)
- FreeForBSTR((UINT *)bstr - 1);
+ if (bstr)
+ FreeForBSTR((CBstrSizeType *)bstr - 1);
}
UINT SysStringByteLen(BSTR bstr)
{
- if (bstr == 0)
+ if (!bstr)
return 0;
- return *((UINT *)bstr - 1);
+ return *((CBstrSizeType *)bstr - 1);
}
UINT SysStringLen(BSTR bstr)
{
- return SysStringByteLen(bstr) / sizeof(OLECHAR);
+ if (!bstr)
+ return 0;
+ return *((CBstrSizeType *)bstr - 1) / sizeof(OLECHAR);
}
+
HRESULT VariantClear(VARIANTARG *prop)
{
if (prop->vt == VT_BSTR)
@@ -77,7 +110,7 @@ HRESULT VariantClear(VARIANTARG *prop)
return S_OK;
}
-HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src)
+HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src)
{
HRESULT res = ::VariantClear(dest);
if (res != S_OK)
@@ -86,7 +119,7 @@ HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src)
{
dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal,
SysStringByteLen(src->bstrVal));
- if (dest->bstrVal == 0)
+ if (!dest->bstrVal)
return E_OUTOFMEMORY;
dest->vt = VT_BSTR;
}
diff --git a/3rdparty/lzma/CPP/Common/MyWindows.h b/3rdparty/lzma/CPP/Common/MyWindows.h
index 780e1f5d526..139a4e8b976 100644
--- a/3rdparty/lzma/CPP/Common/MyWindows.h
+++ b/3rdparty/lzma/CPP/Common/MyWindows.h
@@ -7,6 +7,11 @@
#include <windows.h>
+#ifdef UNDER_CE
+ #undef VARIANT_TRUE
+ #define VARIANT_TRUE ((VARIANT_BOOL)-1)
+#endif
+
#else
#include <stddef.h> // for wchar_t
@@ -14,6 +19,8 @@
#include "MyGuidDef.h"
+#define WINAPI
+
typedef char CHAR;
typedef unsigned char UCHAR;
@@ -145,8 +152,6 @@ typedef WORD PROPVAR_PAD1;
typedef WORD PROPVAR_PAD2;
typedef WORD PROPVAR_PAD3;
-#ifdef __cplusplus
-
typedef struct tagPROPVARIANT
{
VARTYPE vt;
@@ -177,7 +182,7 @@ typedef tagVARIANT VARIANT;
typedef VARIANT VARIANTARG;
MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
-MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
+MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src);
typedef struct tagSTATPROPSTG
{
@@ -186,9 +191,8 @@ typedef struct tagSTATPROPSTG
VARTYPE vt;
} STATPROPSTG;
-#endif
-
MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
+MY_EXTERN_C BSTR SysAllocStringLen(const OLECHAR *sz, UINT len);
MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
MY_EXTERN_C void SysFreeString(BSTR bstr);
MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
@@ -199,6 +203,7 @@ MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
#define CP_ACP 0
#define CP_OEMCP 1
+#define CP_UTF8 65001
typedef enum tagSTREAM_SEEK
{
diff --git a/3rdparty/lzma/CPP/Common/NewHandler.cpp b/3rdparty/lzma/CPP/Common/NewHandler.cpp
index aad6e7d1693..522c2a75390 100644
--- a/3rdparty/lzma/CPP/Common/NewHandler.cpp
+++ b/3rdparty/lzma/CPP/Common/NewHandler.cpp
@@ -11,6 +11,33 @@
#ifndef DEBUG_MEMORY_LEAK
#ifdef _WIN32
+
+/*
+void * my_new(size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
+ if (p == 0)
+ throw CNewException();
+ return p;
+}
+
+void my_delete(void *p) throw()
+{
+ // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
+ ::free(p);
+}
+
+void * my_Realloc(void *p, size_t newSize, size_t oldSize)
+{
+ void *newBuf = my_new(newSize);
+ if (oldSize != 0)
+ memcpy(newBuf, p, oldSize);
+ my_delete(p);
+ return newBuf;
+}
+*/
+
void *
#ifdef _MSC_VER
__cdecl
@@ -30,18 +57,42 @@ __cdecl
#endif
operator delete(void *p) throw()
{
- /*
+ // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
+ ::free(p);
+}
+
+/*
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new[](size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
if (p == 0)
- return;
- ::HeapFree(::GetProcessHeap(), 0, p);
- */
+ throw CNewException();
+ return p;
+}
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete[](void *p) throw()
+{
+ // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
::free(p);
}
+*/
+
#endif
#else
-#pragma init_seg(lib)
+#include <stdio.h>
+
+// #pragma init_seg(lib)
const int kDebugSize = 1000000;
static void *a[kDebugSize];
static int index = 0;
@@ -51,10 +102,6 @@ void * __cdecl operator new(size_t size)
{
numAllocs++;
void *p = HeapAlloc(GetProcessHeap(), 0, size);
- if (index == 40)
- {
- int t = 1;
- }
if (index < kDebugSize)
{
a[index] = p;
@@ -62,7 +109,7 @@ void * __cdecl operator new(size_t size)
}
if (p == 0)
throw CNewException();
- printf("Alloc %6d, size = %8d\n", numAllocs, size);
+ printf("Alloc %6d, size = %8u\n", numAllocs, (unsigned)size);
return p;
}
diff --git a/3rdparty/lzma/CPP/Common/NewHandler.h b/3rdparty/lzma/CPP/Common/NewHandler.h
index 215ba05f103..dcad56886db 100644
--- a/3rdparty/lzma/CPP/Common/NewHandler.h
+++ b/3rdparty/lzma/CPP/Common/NewHandler.h
@@ -1,16 +1,69 @@
// Common/NewHandler.h
-#ifndef __COMMON_NEWHANDLER_H
-#define __COMMON_NEWHANDLER_H
+#ifndef __COMMON_NEW_HANDLER_H
+#define __COMMON_NEW_HANDLER_H
+
+/*
+This file must be included before any code that uses operators "delete" or "new".
+Also you must compile and link "NewHandler.cpp", if you use MSVC 6.0.
+The operator "new" in MSVC 6.0 doesn't throw exception "bad_alloc".
+So we define another version of operator "new" that throws "CNewException" on failure.
+
+If you use compiler that throws exception in "new" operator (GCC or new version of MSVC),
+you can compile without "NewHandler.cpp". So standard exception "bad_alloc" will be used.
+
+It's still allowed to use redefined version of operator "new" from "NewHandler.cpp"
+with any compiler. 7-Zip's code can work with "bad_alloc" and "CNewException" exceptions.
+But if you use some additional code (outside of 7-Zip's code), you must check
+that redefined version of operator "new" (that throws CNewException) is not
+problem for your code.
+
+Also we declare delete(void *p) throw() that creates smaller code.
+*/
+
+#include <stddef.h>
class CNewException {};
+#ifdef WIN32
+// We can compile my_new and my_delete with _fastcall
+/*
+void * my_new(size_t size);
+void my_delete(void *p) throw();
+// void * my_Realloc(void *p, size_t newSize, size_t oldSize);
+*/
+#endif
+
#ifdef _WIN32
+
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new(size_t size);
+
void
#ifdef _MSC_VER
__cdecl
#endif
operator delete(void *p) throw();
+
+#endif
+
+/*
+#ifdef _WIN32
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new[](size_t size);
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete[](void *p) throw();
#endif
+*/
#endif
diff --git a/3rdparty/lzma/CPP/Common/Sha256Reg.cpp b/3rdparty/lzma/CPP/Common/Sha256Reg.cpp
new file mode 100644
index 00000000000..6c822cc7b8e
--- /dev/null
+++ b/3rdparty/lzma/CPP/Common/Sha256Reg.cpp
@@ -0,0 +1,40 @@
+// Sha256Reg.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/Sha256.h"
+
+#include "../Common/MyCom.h"
+
+#include "../7zip/Common/RegisterCodec.h"
+
+class CSha256Hasher:
+ public IHasher,
+ public CMyUnknownImp
+{
+ CSha256 _sha;
+ Byte mtDummy[1 << 7];
+
+public:
+ CSha256Hasher() { Sha256_Init(&_sha); }
+
+ MY_UNKNOWN_IMP
+ INTERFACE_IHasher(;)
+};
+
+STDMETHODIMP_(void) CSha256Hasher::Init() throw()
+{
+ Sha256_Init(&_sha);
+}
+
+STDMETHODIMP_(void) CSha256Hasher::Update(const void *data, UInt32 size) throw()
+{
+ Sha256_Update(&_sha, (const Byte *)data, size);
+}
+
+STDMETHODIMP_(void) CSha256Hasher::Final(Byte *digest) throw()
+{
+ Sha256_Final(&_sha, digest);
+}
+
+REGISTER_HASHER(CSha256Hasher, 0xA, "SHA256", SHA256_DIGEST_SIZE)
diff --git a/3rdparty/lzma/CPP/Common/StdAfx.h b/3rdparty/lzma/CPP/Common/StdAfx.h
index b8ba1d5c4c9..420f5c3267f 100644
--- a/3rdparty/lzma/CPP/Common/StdAfx.h
+++ b/3rdparty/lzma/CPP/Common/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-// #include "MyWindows.h"
-#include "NewHandler.h"
+#include "Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/Common/StdInStream.cpp b/3rdparty/lzma/CPP/Common/StdInStream.cpp
index f3dcb85f53a..c35747bbe69 100644
--- a/3rdparty/lzma/CPP/Common/StdInStream.cpp
+++ b/3rdparty/lzma/CPP/Common/StdInStream.cpp
@@ -8,12 +8,6 @@
#include "StringConvert.h"
#include "UTFConvert.h"
-#ifdef _MSC_VER
-// "was declared deprecated" disabling
-#pragma warning(disable : 4996 )
-#endif
-
-static const char kIllegalChar = '\0';
static const char kNewLineChar = '\n';
static const char *kEOFMessage = "Unexpected end of input stream";
@@ -26,7 +20,7 @@ extern int g_CodePage;
CStdInStream g_StdIn(stdin);
-bool CStdInStream::Open(LPCTSTR fileName)
+bool CStdInStream::Open(LPCTSTR fileName) throw()
{
Close();
_stream = _tfopen(fileName, kFileOpenMode);
@@ -34,7 +28,7 @@ bool CStdInStream::Open(LPCTSTR fileName)
return _streamIsOpen;
}
-bool CStdInStream::Close()
+bool CStdInStream::Close() throw()
{
if (!_streamIsOpen)
return true;
@@ -42,11 +36,6 @@ bool CStdInStream::Close()
return !_streamIsOpen;
}
-CStdInStream::~CStdInStream()
-{
- Close();
-}
-
AString CStdInStream::ScanStringUntilNewLine(bool allowEOF)
{
AString s;
@@ -59,8 +48,8 @@ AString CStdInStream::ScanStringUntilNewLine(bool allowEOF)
break;
throw kEOFMessage;
}
- char c = char(intChar);
- if (c == kIllegalChar)
+ char c = (char)intChar;
+ if (c == 0)
throw kIllegalCharMessage;
if (c == kNewLineChar)
break;
@@ -88,10 +77,10 @@ void CStdInStream::ReadToString(AString &resultString)
resultString.Empty();
int c;
while ((c = GetChar()) != EOF)
- resultString += char(c);
+ resultString += (char)c;
}
-bool CStdInStream::Eof()
+bool CStdInStream::Eof() throw()
{
return (feof(_stream) != 0);
}
@@ -103,5 +92,3 @@ int CStdInStream::GetChar()
throw kReadErrorMessage;
return c;
}
-
-
diff --git a/3rdparty/lzma/CPP/Common/StdInStream.h b/3rdparty/lzma/CPP/Common/StdInStream.h
index 0d182cc3c8b..6d9ed67040d 100644
--- a/3rdparty/lzma/CPP/Common/StdInStream.h
+++ b/3rdparty/lzma/CPP/Common/StdInStream.h
@@ -1,29 +1,30 @@
// Common/StdInStream.h
-#ifndef __COMMON_STDINSTREAM_H
-#define __COMMON_STDINSTREAM_H
+#ifndef __COMMON_STD_IN_STREAM_H
+#define __COMMON_STD_IN_STREAM_H
#include <stdio.h>
#include "MyString.h"
-#include "Types.h"
+#include "MyTypes.h"
class CStdInStream
{
- bool _streamIsOpen;
FILE *_stream;
+ bool _streamIsOpen;
public:
- CStdInStream(): _streamIsOpen(false) {};
- CStdInStream(FILE *stream): _streamIsOpen(false), _stream(stream) {};
- ~CStdInStream();
- bool Open(LPCTSTR fileName);
- bool Close();
+ CStdInStream(): _stream(0), _streamIsOpen(false) {};
+ CStdInStream(FILE *stream): _stream(stream), _streamIsOpen(false) {};
+ ~CStdInStream() { Close(); }
+
+ bool Open(LPCTSTR fileName) throw();
+ bool Close() throw();
AString ScanStringUntilNewLine(bool allowEOF = false);
void ReadToString(AString &resultString);
UString ScanUStringUntilNewLine();
- bool Eof();
+ bool Eof() throw();
int GetChar();
};
diff --git a/3rdparty/lzma/CPP/Common/StdOutStream.cpp b/3rdparty/lzma/CPP/Common/StdOutStream.cpp
index 061a760631b..6aed31a3143 100644
--- a/3rdparty/lzma/CPP/Common/StdOutStream.cpp
+++ b/3rdparty/lzma/CPP/Common/StdOutStream.cpp
@@ -9,21 +9,16 @@
#include "StringConvert.h"
#include "UTFConvert.h"
-#ifdef _MSC_VER
-// "was declared deprecated" disabling
-#pragma warning(disable : 4996 )
-#endif
-
static const char kNewLineChar = '\n';
static const char *kFileOpenMode = "wt";
extern int g_CodePage;
-CStdOutStream g_StdOut(stdout);
-CStdOutStream g_StdErr(stderr);
+CStdOutStream g_StdOut(stdout);
+CStdOutStream g_StdErr(stderr);
-bool CStdOutStream::Open(const char *fileName)
+bool CStdOutStream::Open(const char *fileName) throw()
{
Close();
_stream = fopen(fileName, kFileOpenMode);
@@ -31,7 +26,7 @@ bool CStdOutStream::Open(const char *fileName)
return _streamIsOpen;
}
-bool CStdOutStream::Close()
+bool CStdOutStream::Close() throw()
{
if (!_streamIsOpen)
return true;
@@ -42,33 +37,16 @@ bool CStdOutStream::Close()
return true;
}
-bool CStdOutStream::Flush()
+bool CStdOutStream::Flush() throw()
{
return (fflush(_stream) == 0);
}
-CStdOutStream::~CStdOutStream ()
-{
- Close();
-}
-
-CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*aFunction)(CStdOutStream &))
-{
- (*aFunction)(*this);
- return *this;
-}
-
-CStdOutStream & endl(CStdOutStream & outStream)
+CStdOutStream & endl(CStdOutStream & outStream) throw()
{
return outStream << kNewLineChar;
}
-CStdOutStream & CStdOutStream::operator<<(const char *s)
-{
- fputs(s, _stream);
- return *this;
-}
-
CStdOutStream & CStdOutStream::operator<<(const wchar_t *s)
{
int codePage = g_CodePage;
@@ -78,27 +56,51 @@ CStdOutStream & CStdOutStream::operator<<(const wchar_t *s)
if (codePage == CP_UTF8)
ConvertUnicodeToUTF8(s, dest);
else
- dest = UnicodeStringToMultiByte(s, (UINT)codePage);
- *this << (const char *)dest;
- return *this;
+ UnicodeStringToMultiByte2(dest, s, (UINT)codePage);
+ return operator<<((const char *)dest);
+}
+
+void StdOut_Convert_UString_to_AString(const UString &s, AString &temp)
+{
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8(s, temp);
+ else
+ UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
+}
+
+void CStdOutStream::PrintUString(const UString &s, AString &temp)
+{
+ StdOut_Convert_UString_to_AString(s, temp);
+ *this << (const char *)temp;
+}
+
+CStdOutStream & CStdOutStream::operator<<(Int32 number) throw()
+{
+ char s[32];
+ ConvertInt64ToString(number, s);
+ return operator<<(s);
}
-CStdOutStream & CStdOutStream::operator<<(char c)
+CStdOutStream & CStdOutStream::operator<<(Int64 number) throw()
{
- fputc(c, _stream);
- return *this;
+ char s[32];
+ ConvertInt64ToString(number, s);
+ return operator<<(s);
}
-CStdOutStream & CStdOutStream::operator<<(int number)
+CStdOutStream & CStdOutStream::operator<<(UInt32 number) throw()
{
- char textString[32];
- ConvertInt64ToString(number, textString);
- return operator<<(textString);
+ char s[16];
+ ConvertUInt32ToString(number, s);
+ return operator<<(s);
}
-CStdOutStream & CStdOutStream::operator<<(UInt64 number)
+CStdOutStream & CStdOutStream::operator<<(UInt64 number) throw()
{
- char textString[32];
- ConvertUInt64ToString(number, textString);
- return operator<<(textString);
+ char s[32];
+ ConvertUInt64ToString(number, s);
+ return operator<<(s);
}
diff --git a/3rdparty/lzma/CPP/Common/StdOutStream.h b/3rdparty/lzma/CPP/Common/StdOutStream.h
index b0b2c615c7f..1837bfb0adc 100644
--- a/3rdparty/lzma/CPP/Common/StdOutStream.h
+++ b/3rdparty/lzma/CPP/Common/StdOutStream.h
@@ -1,35 +1,62 @@
// Common/StdOutStream.h
-#ifndef __COMMON_STDOUTSTREAM_H
-#define __COMMON_STDOUTSTREAM_H
+#ifndef __COMMON_STD_OUT_STREAM_H
+#define __COMMON_STD_OUT_STREAM_H
#include <stdio.h>
-#include "Types.h"
+#include "MyString.h"
+#include "MyTypes.h"
class CStdOutStream
{
- bool _streamIsOpen;
FILE *_stream;
+ bool _streamIsOpen;
public:
- CStdOutStream (): _streamIsOpen(false), _stream(0) {};
- CStdOutStream (FILE *stream): _streamIsOpen(false), _stream(stream) {};
- ~CStdOutStream ();
+ CStdOutStream(): _stream(0), _streamIsOpen(false) {};
+ CStdOutStream(FILE *stream): _stream(stream), _streamIsOpen(false) {};
+ ~CStdOutStream() { Close(); }
+
+ // void AttachStdStream(FILE *stream) { _stream = stream; _streamIsOpen = false; }
+ // bool IsDefined() const { return _stream != NULL; }
+
operator FILE *() { return _stream; }
- bool Open(const char *fileName);
- bool Close();
- bool Flush();
- CStdOutStream & operator<<(CStdOutStream & (* aFunction)(CStdOutStream &));
- CStdOutStream & operator<<(const char *string);
- CStdOutStream & operator<<(const wchar_t *string);
- CStdOutStream & operator<<(char c);
- CStdOutStream & operator<<(int number);
- CStdOutStream & operator<<(UInt64 number);
+ bool Open(const char *fileName) throw();
+ bool Close() throw();
+ bool Flush() throw();
+
+ CStdOutStream & operator<<(CStdOutStream & (* func)(CStdOutStream &))
+ {
+ (*func)(*this);
+ return *this;
+ }
+
+ CStdOutStream & operator<<(const char *s) throw()
+ {
+ fputs(s, _stream);
+ return *this;
+ }
+
+ CStdOutStream & operator<<(char c) throw()
+ {
+ fputc((unsigned char)c, _stream);
+ return *this;
+ }
+
+ CStdOutStream & operator<<(Int32 number) throw();
+ CStdOutStream & operator<<(Int64 number) throw();
+ CStdOutStream & operator<<(UInt32 number) throw();
+ CStdOutStream & operator<<(UInt64 number) throw();
+
+ CStdOutStream & operator<<(const wchar_t *s);
+ void PrintUString(const UString &s, AString &temp);
};
-CStdOutStream & endl(CStdOutStream & outStream);
+CStdOutStream & endl(CStdOutStream & outStream) throw();
extern CStdOutStream g_StdOut;
extern CStdOutStream g_StdErr;
+void StdOut_Convert_UString_to_AString(const UString &s, AString &temp);
+
#endif
diff --git a/3rdparty/lzma/CPP/Common/StringConvert.cpp b/3rdparty/lzma/CPP/Common/StringConvert.cpp
index 681895b7125..30d95aa7b56 100644
--- a/3rdparty/lzma/CPP/Common/StringConvert.cpp
+++ b/3rdparty/lzma/CPP/Common/StringConvert.cpp
@@ -8,90 +8,306 @@
#include <stdlib.h>
#endif
+static const char k_DefultChar = '_';
+
#ifdef _WIN32
-UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
+
+/*
+MultiByteToWideChar(CodePage, DWORD dwFlags,
+ LPCSTR lpMultiByteStr, int cbMultiByte,
+ LPWSTR lpWideCharStr, int cchWideChar)
+
+ if (cbMultiByte == 0)
+ return: 0. ERR: ERROR_INVALID_PARAMETER
+
+ if (cchWideChar == 0)
+ return: the required buffer size in characters.
+
+ if (supplied buffer size was not large enough)
+ return: 0. ERR: ERROR_INSUFFICIENT_BUFFER
+ The number of filled characters in lpWideCharStr can be smaller than cchWideChar (if last character is complex)
+
+ If there are illegal characters:
+ if MB_ERR_INVALID_CHARS is set in dwFlags:
+ - the function stops conversion on illegal character.
+ - Return: 0. ERR: ERROR_NO_UNICODE_TRANSLATION.
+
+ if MB_ERR_INVALID_CHARS is NOT set in dwFlags:
+ before Vista: illegal character is dropped (skipped). WinXP-64: GetLastError() returns 0.
+ in Vista+: illegal character is not dropped (MSDN). Undocumented: illegal
+ character is converted to U+FFFD, which is REPLACEMENT CHARACTER.
+*/
+
+
+void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT codePage)
{
- UString resultString;
- if (!srcString.IsEmpty())
+ dest.Empty();
+ if (src.IsEmpty())
+ return;
{
- int numChars = MultiByteToWideChar(codePage, 0, srcString,
- srcString.Length(), resultString.GetBuffer(srcString.Length()),
- srcString.Length() + 1);
- if (numChars == 0)
- throw 282228;
- resultString.ReleaseBuffer(numChars);
+ /*
+ wchar_t *d = dest.GetBuf(src.Len());
+ const char *s = (const char *)src;
+ unsigned i;
+
+ for (i = 0;;)
+ {
+ Byte c = (Byte)s[i];
+ if (c >= 0x80 || c == 0)
+ break;
+ d[i++] = (wchar_t)c;
+ }
+
+ if (i != src.Len())
+ {
+ unsigned len = MultiByteToWideChar(codePage, 0, s + i,
+ src.Len() - i, d + i,
+ src.Len() + 1 - i);
+ if (len == 0)
+ throw 282228;
+ i += len;
+ }
+
+ d[i] = 0;
+ dest.ReleaseBuf_SetLen(i);
+ */
+ unsigned len = MultiByteToWideChar(codePage, 0, src, src.Len(), NULL, 0);
+ if (len == 0)
+ {
+ if (GetLastError() != 0)
+ throw 282228;
+ }
+ else
+ {
+ len = MultiByteToWideChar(codePage, 0, src, src.Len(), dest.GetBuf(len), len);
+ if (len == 0)
+ throw 282228;
+ dest.ReleaseBuf_SetEnd(len);
+ }
}
- return resultString;
}
-AString UnicodeStringToMultiByte(const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
+/*
+ int WideCharToMultiByte(
+ UINT CodePage, DWORD dwFlags,
+ LPCWSTR lpWideCharStr, int cchWideChar,
+ LPSTR lpMultiByteStr, int cbMultiByte,
+ LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);
+
+if (lpDefaultChar == NULL),
+ - it uses system default value.
+
+if (CodePage == CP_UTF7 || CodePage == CP_UTF8)
+ if (lpDefaultChar != NULL || lpUsedDefaultChar != NULL)
+ return: 0. ERR: ERROR_INVALID_PARAMETER.
+
+The function operates most efficiently, if (lpDefaultChar == NULL && lpUsedDefaultChar == NULL)
+
+*/
+
+static void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
{
- AString dest;
+ dest.Empty();
defaultCharWasUsed = false;
- if (!s.IsEmpty())
+ if (src.IsEmpty())
+ return;
{
- int numRequiredBytes = s.Length() * 2;
- BOOL defUsed;
- int numChars = WideCharToMultiByte(codePage, 0, s, s.Length(),
- dest.GetBuffer(numRequiredBytes), numRequiredBytes + 1,
- &defaultChar, &defUsed);
- defaultCharWasUsed = (defUsed != FALSE);
- if (numChars == 0)
- throw 282229;
- dest.ReleaseBuffer(numChars);
- }
- return dest;
-}
+ /*
+ unsigned numRequiredBytes = src.Len() * 2;
+ char *d = dest.GetBuf(numRequiredBytes);
+ const wchar_t *s = (const wchar_t *)src;
+ unsigned i;
+
+ for (i = 0;;)
+ {
+ wchar_t c = s[i];
+ if (c >= 0x80 || c == 0)
+ break;
+ d[i++] = (char)c;
+ }
+
+ if (i != src.Len())
+ {
+ BOOL defUsed = FALSE;
+ defaultChar = defaultChar;
-AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
-{
- bool defaultCharWasUsed;
- return UnicodeStringToMultiByte(srcString, codePage, '_', defaultCharWasUsed);
+ bool isUtf = (codePage == CP_UTF8 || codePage == CP_UTF7);
+ unsigned len = WideCharToMultiByte(codePage, 0, s + i, src.Len() - i,
+ d + i, numRequiredBytes + 1 - i,
+ (isUtf ? NULL : &defaultChar),
+ (isUtf ? NULL : &defUsed));
+ defaultCharWasUsed = (defUsed != FALSE);
+ if (len == 0)
+ throw 282229;
+ i += len;
+ }
+
+ d[i] = 0;
+ dest.ReleaseBuf_SetLen(i);
+ */
+
+ /*
+ if (codePage != CP_UTF7)
+ {
+ const wchar_t *s = (const wchar_t *)src;
+ unsigned i;
+ for (i = 0;; i++)
+ {
+ wchar_t c = s[i];
+ if (c >= 0x80 || c == 0)
+ break;
+ }
+
+ if (s[i] == 0)
+ {
+ char *d = dest.GetBuf(src.Len());
+ for (i = 0;;)
+ {
+ wchar_t c = s[i];
+ if (c == 0)
+ break;
+ d[i++] = (char)c;
+ }
+ d[i] = 0;
+ dest.ReleaseBuf_SetLen(i);
+ return;
+ }
+ }
+ */
+
+ unsigned len = WideCharToMultiByte(codePage, 0, src, src.Len(), NULL, 0, NULL, NULL);
+ if (len == 0)
+ {
+ if (GetLastError() != 0)
+ throw 282228;
+ }
+ else
+ {
+ BOOL defUsed = FALSE;
+ bool isUtf = (codePage == CP_UTF8 || codePage == CP_UTF7);
+ // defaultChar = defaultChar;
+ len = WideCharToMultiByte(codePage, 0, src, src.Len(),
+ dest.GetBuf(len), len,
+ (isUtf ? NULL : &defaultChar),
+ (isUtf ? NULL : &defUsed)
+ );
+ if (!isUtf)
+ defaultCharWasUsed = (defUsed != FALSE);
+ if (len == 0)
+ throw 282228;
+ dest.ReleaseBuf_SetEnd(len);
+ }
+ }
}
+/*
#ifndef UNDER_CE
-AString SystemStringToOemString(const CSysString &srcString)
+AString SystemStringToOemString(const CSysString &src)
{
- AString result;
- CharToOem(srcString, result.GetBuffer(srcString.Length() * 2));
- result.ReleaseBuffer();
- return result;
+ AString dest;
+ const unsigned len = src.Len() * 2;
+ CharToOem(src, dest.GetBuf(len));
+ dest.ReleaseBuf_CalcLen(len);
+ return dest;
}
#endif
+*/
#else
-UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
+void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT /* codePage */)
{
- UString resultString;
- for (int i = 0; i < srcString.Length(); i++)
- resultString += wchar_t(srcString[i]);
- /*
- if (!srcString.IsEmpty())
+ dest.Empty();
+ if (src.IsEmpty())
+ return;
+
+ size_t limit = ((size_t)src.Len() + 1) * 2;
+ wchar_t *d = dest.GetBuf((unsigned)limit);
+ size_t len = mbstowcs(d, src, limit);
+ if (len != (size_t)-1)
{
- int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1);
- if (numChars < 0) throw "Your environment does not support UNICODE";
- resultString.ReleaseBuffer(numChars);
+ dest.ReleaseBuf_SetEnd((unsigned)len);
+ return;
+ }
+
+ {
+ unsigned i;
+ const char *s = (const char *)src;
+ for (i = 0;;)
+ {
+ Byte c = (Byte)s[i];
+ if (c == 0)
+ break;
+ d[i++] = (wchar_t)c;
+ }
+ d[i] = 0;
+ dest.ReleaseBuf_SetLen(i);
}
- */
- return resultString;
}
-AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
+static void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT /* codePage */, char defaultChar, bool &defaultCharWasUsed)
{
- AString resultString;
- for (int i = 0; i < srcString.Length(); i++)
- resultString += char(srcString[i]);
- /*
- if (!srcString.IsEmpty())
+ dest.Empty();
+ defaultCharWasUsed = false;
+ if (src.IsEmpty())
+ return;
+
+ size_t limit = ((size_t)src.Len() + 1) * 6;
+ char *d = dest.GetBuf((unsigned)limit);
+ size_t len = wcstombs(d, src, limit);
+ if (len != (size_t)-1)
+ {
+ dest.ReleaseBuf_SetEnd((unsigned)len);
+ return;
+ }
+
{
- int numRequiredBytes = srcString.Length() * 6 + 1;
- int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes);
- if (numChars < 0) throw "Your environment does not support UNICODE";
- resultString.ReleaseBuffer(numChars);
+ const wchar_t *s = (const wchar_t *)src;
+ unsigned i;
+ for (i = 0;;)
+ {
+ wchar_t c = s[i];
+ if (c == 0)
+ break;
+ if (c >= 0x100)
+ {
+ c = defaultChar;
+ defaultCharWasUsed = true;
+ }
+ d[i++] = (char)c;
+ }
+ d[i] = 0;
+ dest.ReleaseBuf_SetLen(i);
}
- */
- return resultString;
}
#endif
+
+
+UString MultiByteToUnicodeString(const AString &src, UINT codePage)
+{
+ UString dest;
+ MultiByteToUnicodeString2(dest, src, codePage);
+ return dest;
+}
+
+void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage)
+{
+ bool defaultCharWasUsed;
+ UnicodeStringToMultiByte2(dest, src, codePage, k_DefultChar, defaultCharWasUsed);
+}
+
+AString UnicodeStringToMultiByte(const UString &src, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
+{
+ AString dest;
+ UnicodeStringToMultiByte2(dest, src, codePage, defaultChar, defaultCharWasUsed);
+ return dest;
+}
+
+AString UnicodeStringToMultiByte(const UString &src, UINT codePage)
+{
+ AString dest;
+ bool defaultCharWasUsed;
+ UnicodeStringToMultiByte2(dest, src, codePage, k_DefultChar, defaultCharWasUsed);
+ return dest;
+}
diff --git a/3rdparty/lzma/CPP/Common/StringConvert.h b/3rdparty/lzma/CPP/Common/StringConvert.h
index cd737becbf5..924012450c6 100644
--- a/3rdparty/lzma/CPP/Common/StringConvert.h
+++ b/3rdparty/lzma/CPP/Common/StringConvert.h
@@ -3,15 +3,19 @@
#ifndef __COMMON_STRING_CONVERT_H
#define __COMMON_STRING_CONVERT_H
-#include "MyWindows.h"
#include "MyString.h"
-#include "Types.h"
+#include "MyWindows.h"
UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP);
+
+// optimized versions that work faster for ASCII strings
+void MultiByteToUnicodeString2(UString &dest, const AString &srcString, UINT codePage = CP_ACP);
+// void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
+void UnicodeStringToMultiByte2(AString &dest, const UString &srcString, UINT codePage);
+
AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP);
-
inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString)
{ return unicodeString; }
inline const UString& GetUnicodeString(const UString &unicodeString)
diff --git a/3rdparty/lzma/CPP/Common/StringToInt.cpp b/3rdparty/lzma/CPP/Common/StringToInt.cpp
index 15474a4223d..dfa5cc3bff4 100644
--- a/3rdparty/lzma/CPP/Common/StringToInt.cpp
+++ b/3rdparty/lzma/CPP/Common/StringToInt.cpp
@@ -4,94 +4,141 @@
#include "StringToInt.h"
-UInt64 ConvertStringToUInt64(const char *s, const char **end)
+static const UInt32 k_UInt32_max = 0xFFFFFFFF;
+static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF);
+// static const UInt64 k_UInt64_max = (UInt64)(Int64)-1;
+
+#define CONVERT_STRING_TO_UINT_FUNC(uintType, charType, charTypeUnsigned) \
+ uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \
+ if (end) *end = s; \
+ uintType res = 0; \
+ for (;; s++) { \
+ charTypeUnsigned c = (charTypeUnsigned)*s; \
+ if (c < '0' || c > '9') { if (end) *end = s; return res; } \
+ if (res > (k_ ## uintType ## _max) / 10) return 0; \
+ res *= 10; \
+ unsigned v = (c - '0'); \
+ if (res > (k_ ## uintType ## _max) - v) return 0; \
+ res += v; }}
+
+CONVERT_STRING_TO_UINT_FUNC(UInt32, char, Byte)
+CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t, wchar_t)
+CONVERT_STRING_TO_UINT_FUNC(UInt64, char, Byte)
+CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t, wchar_t)
+
+Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw()
{
- UInt64 result = 0;
- for (;;)
+ if (end)
+ *end = s;
+ const wchar_t *s2 = s;
+ if (*s == '-')
+ s2++;
+ if (*s2 == 0)
+ return 0;
+ const wchar_t *end2;
+ UInt32 res = ConvertStringToUInt32(s2, &end2);
+ if (*s == '-')
{
- char c = *s;
- if (c < '0' || c > '9')
+ if (res > ((UInt32)1 << (32 - 1)))
+ return 0;
+ }
+ else if ((res & ((UInt32)1 << (32 - 1))) != 0)
+ return 0;
+ if (end)
+ *end = end2;
+ if (*s == '-')
+ return -(Int32)res;
+ return (Int32)res;
+}
+
+UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw()
+{
+ if (end)
+ *end = s;
+ UInt32 res = 0;
+ for (;; s++)
+ {
+ unsigned c = (unsigned char)*s;
+ if (c < '0' || c > '7')
{
- if (end != NULL)
+ if (end)
*end = s;
- return result;
+ return res;
}
- result *= 10;
- result += (c - '0');
- s++;
+ if ((res & (UInt32)7 << (32 - 3)) != 0)
+ return 0;
+ res <<= 3;
+ res |= (unsigned)(c - '0');
}
}
-UInt64 ConvertOctStringToUInt64(const char *s, const char **end)
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw()
{
- UInt64 result = 0;
- for (;;)
+ if (end)
+ *end = s;
+ UInt64 res = 0;
+ for (;; s++)
{
- char c = *s;
+ unsigned c = (unsigned char)*s;
if (c < '0' || c > '7')
{
- if (end != NULL)
+ if (end)
*end = s;
- return result;
+ return res;
}
- result <<= 3;
- result += (c - '0');
- s++;
+ if ((res & (UInt64)7 << (64 - 3)) != 0)
+ return 0;
+ res <<= 3;
+ res |= (unsigned)(c - '0');
}
}
-UInt64 ConvertHexStringToUInt64(const char *s, const char **end)
+UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw()
{
- UInt64 result = 0;
- for (;;)
+ if (end)
+ *end = s;
+ UInt32 res = 0;
+ for (;; s++)
{
- char c = *s;
- UInt32 v;
+ unsigned c = (Byte)*s;
+ unsigned v;
if (c >= '0' && c <= '9') v = (c - '0');
else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
else
{
- if (end != NULL)
+ if (end)
*end = s;
- return result;
+ return res;
}
- result <<= 4;
- result |= v;
- s++;
+ if ((res & (UInt32)0xF << (32 - 4)) != 0)
+ return 0;
+ res <<= 4;
+ res |= v;
}
}
-
-UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end)
+UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw()
{
- UInt64 result = 0;
- for (;;)
+ if (end)
+ *end = s;
+ UInt64 res = 0;
+ for (;; s++)
{
- wchar_t c = *s;
- if (c < '0' || c > '9')
+ unsigned c = (Byte)*s;
+ unsigned v;
+ if (c >= '0' && c <= '9') v = (c - '0');
+ else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
+ else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
+ else
{
- if (end != NULL)
+ if (end)
*end = s;
- return result;
+ return res;
}
- result *= 10;
- result += (c - '0');
- s++;
+ if ((res & (UInt64)0xF << (64 - 4)) != 0)
+ return 0;
+ res <<= 4;
+ res |= v;
}
}
-
-
-Int64 ConvertStringToInt64(const char *s, const char **end)
-{
- if (*s == '-')
- return -(Int64)ConvertStringToUInt64(s + 1, end);
- return ConvertStringToUInt64(s, end);
-}
-
-Int64 ConvertStringToInt64(const wchar_t *s, const wchar_t **end)
-{
- if (*s == L'-')
- return -(Int64)ConvertStringToUInt64(s + 1, end);
- return ConvertStringToUInt64(s, end);
-}
diff --git a/3rdparty/lzma/CPP/Common/StringToInt.h b/3rdparty/lzma/CPP/Common/StringToInt.h
index cd99f17e6a0..5c5d7d7fe75 100644
--- a/3rdparty/lzma/CPP/Common/StringToInt.h
+++ b/3rdparty/lzma/CPP/Common/StringToInt.h
@@ -3,14 +3,19 @@
#ifndef __COMMON_STRING_TO_INT_H
#define __COMMON_STRING_TO_INT_H
-#include "Types.h"
+#include "MyTypes.h"
-UInt64 ConvertStringToUInt64(const char *s, const char **end);
-UInt64 ConvertOctStringToUInt64(const char *s, const char **end);
-UInt64 ConvertHexStringToUInt64(const char *s, const char **end);
-UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end);
+UInt32 ConvertStringToUInt32(const char *s, const char **end) throw();
+UInt64 ConvertStringToUInt64(const char *s, const char **end) throw();
+UInt32 ConvertStringToUInt32(const wchar_t *s, const wchar_t **end) throw();
+UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) throw();
-Int64 ConvertStringToInt64(const char *s, const char **end);
-Int64 ConvertStringToInt64(const wchar_t *s, const wchar_t **end);
+Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw();
+
+UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw();
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw();
+
+UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw();
+UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw();
#endif
diff --git a/3rdparty/lzma/CPP/Common/TextConfig.cpp b/3rdparty/lzma/CPP/Common/TextConfig.cpp
new file mode 100644
index 00000000000..7606ee7b47e
--- /dev/null
+++ b/3rdparty/lzma/CPP/Common/TextConfig.cpp
@@ -0,0 +1,124 @@
+// Common/TextConfig.cpp
+
+#include "StdAfx.h"
+
+#include "TextConfig.h"
+#include "UTFConvert.h"
+
+static inline bool IsDelimitChar(char c)
+{
+ return (c == ' ' || c == 0x0A || c == 0x0D || c == '\0' || c == '\t');
+}
+
+static AString GetIDString(const char *s, unsigned &finishPos)
+{
+ AString result;
+ for (finishPos = 0; ; finishPos++)
+ {
+ char c = s[finishPos];
+ if (IsDelimitChar(c) || c == '=')
+ break;
+ result += c;
+ }
+ return result;
+}
+
+static bool WaitNextLine(const AString &s, unsigned &pos)
+{
+ for (; pos < s.Len(); pos++)
+ if (s[pos] == 0x0A)
+ return true;
+ return false;
+}
+
+static bool SkipSpaces(const AString &s, unsigned &pos)
+{
+ for (; pos < s.Len(); pos++)
+ {
+ char c = s[pos];
+ if (!IsDelimitChar(c))
+ {
+ if (c != ';')
+ return true;
+ if (!WaitNextLine(s, pos))
+ return false;
+ }
+ }
+ return false;
+}
+
+bool GetTextConfig(const AString &s, CObjectVector<CTextConfigPair> &pairs)
+{
+ pairs.Clear();
+ unsigned pos = 0;
+
+ /////////////////////
+ // read strings
+
+ for (;;)
+ {
+ if (!SkipSpaces(s, pos))
+ break;
+ CTextConfigPair pair;
+ unsigned finishPos;
+ AString temp = GetIDString(((const char *)s) + pos, finishPos);
+ if (!ConvertUTF8ToUnicode(temp, pair.ID))
+ return false;
+ if (finishPos == 0)
+ return false;
+ pos += finishPos;
+ if (!SkipSpaces(s, pos))
+ return false;
+ if (s[pos] != '=')
+ return false;
+ pos++;
+ if (!SkipSpaces(s, pos))
+ return false;
+ if (s[pos] != '\"')
+ return false;
+ pos++;
+ AString message;
+ for (;;)
+ {
+ if (pos >= s.Len())
+ return false;
+ char c = s[pos++];
+ if (c == '\"')
+ break;
+ if (c == '\\')
+ {
+ char c = s[pos++];
+ switch (c)
+ {
+ case 'n': message += '\n'; break;
+ case 't': message += '\t'; break;
+ case '\\': message += '\\'; break;
+ case '\"': message += '\"'; break;
+ default: message += '\\'; message += c; break;
+ }
+ }
+ else
+ message += c;
+ }
+ if (!ConvertUTF8ToUnicode(message, pair.String))
+ return false;
+ pairs.Add(pair);
+ }
+ return true;
+}
+
+int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id) throw()
+{
+ FOR_VECTOR (i, pairs)
+ if (pairs[i].ID == id)
+ return i;
+ return -1;
+}
+
+UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id)
+{
+ int index = FindTextConfigItem(pairs, id);
+ if (index < 0)
+ return UString();
+ return pairs[index].String;
+}
diff --git a/3rdparty/lzma/CPP/Common/TextConfig.h b/3rdparty/lzma/CPP/Common/TextConfig.h
new file mode 100644
index 00000000000..0129ad963a1
--- /dev/null
+++ b/3rdparty/lzma/CPP/Common/TextConfig.h
@@ -0,0 +1,19 @@
+// Common/TextConfig.h
+
+#ifndef __COMMON_TEXT_CONFIG_H
+#define __COMMON_TEXT_CONFIG_H
+
+#include "MyString.h"
+
+struct CTextConfigPair
+{
+ UString ID;
+ UString String;
+};
+
+bool GetTextConfig(const AString &text, CObjectVector<CTextConfigPair> &pairs);
+
+int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id) throw();
+UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id);
+
+#endif
diff --git a/3rdparty/lzma/CPP/Common/Types.h b/3rdparty/lzma/CPP/Common/Types.h
deleted file mode 100644
index 9365b327f6e..00000000000
--- a/3rdparty/lzma/CPP/Common/Types.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Common/Types.h
-
-#ifndef __COMMON_TYPES_H
-#define __COMMON_TYPES_H
-
-#include "../../C/Types.h"
-
-typedef int HRes;
-
-#endif
-
diff --git a/3rdparty/lzma/CPP/Common/UTFConvert.cpp b/3rdparty/lzma/CPP/Common/UTFConvert.cpp
index 95362430a94..b772164aab4 100644
--- a/3rdparty/lzma/CPP/Common/UTFConvert.cpp
+++ b/3rdparty/lzma/CPP/Common/UTFConvert.cpp
@@ -2,24 +2,94 @@
#include "StdAfx.h"
+#include "MyTypes.h"
#include "UTFConvert.h"
-#include "Types.h"
-static const Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+#ifdef _WIN32
+#define _WCHART_IS_16BIT 1
+#endif
-static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_t srcLen)
+/*
+ _UTF8_START(n) - is a base value for start byte (head), if there are (n) additional bytes after start byte
+
+ n : _UTF8_START(n) : Bits of code point
+
+ 0 : 0x80 : : unused
+ 1 : 0xC0 : 11 :
+ 2 : 0xE0 : 16 : Basic Multilingual Plane
+ 3 : 0xF0 : 21 : Unicode space
+ 3 : 0xF8 : 26 :
+ 5 : 0xFC : 31 : UCS-4
+ 6 : 0xFE : 36 : We can use it, if we want to encode any 32-bit value
+ 7 : 0xFF :
+*/
+
+#define _UTF8_START(n) (0x100 - (1 << (7 - (n))))
+
+#define _UTF8_HEAD_PARSE2(n) if (c < _UTF8_START((n) + 1)) { numBytes = (n); c -= _UTF8_START(n); }
+
+#define _UTF8_HEAD_PARSE \
+ _UTF8_HEAD_PARSE2(1) \
+ else _UTF8_HEAD_PARSE2(2) \
+ else _UTF8_HEAD_PARSE2(3) \
+ else _UTF8_HEAD_PARSE2(4) \
+ else _UTF8_HEAD_PARSE2(5) \
+
+ // else _UTF8_HEAD_PARSE2(6)
+
+bool CheckUTF8(const char *src, bool allowReduced) throw()
+{
+ for (;;)
+ {
+ Byte c = *src++;
+ if (c == 0)
+ return true;
+
+ if (c < 0x80)
+ continue;
+ if (c < 0xC0) // (c < 0xC0 + 2) // if we support only optimal encoding chars
+ return false;
+
+ unsigned numBytes;
+ _UTF8_HEAD_PARSE
+ else
+ return false;
+
+ UInt32 val = c;
+
+ do
+ {
+ Byte c2 = *src++;
+ if (c2 < 0x80 || c2 >= 0xC0)
+ return allowReduced && c2 == 0;
+ val <<= 6;
+ val |= (c2 - 0x80);
+ }
+ while (--numBytes);
+
+ if (val >= 0x110000)
+ return false;
+ }
+}
+
+
+#define _ERROR_UTF8 \
+ { if (dest) dest[destPos] = (wchar_t)0xFFFD; destPos++; ok = false; continue; }
+
+static bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, const char *srcLim) throw()
{
- size_t destPos = 0, srcPos = 0;
+ size_t destPos = 0;
+ bool ok = true;
+
for (;;)
{
Byte c;
- int numAdds;
- if (srcPos == srcLen)
+ if (src == srcLim)
{
*destLen = destPos;
- return True;
+ return ok;
}
- c = (Byte)src[srcPos++];
+ c = *src++;
if (c < 0x80)
{
@@ -29,117 +99,190 @@ static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_
continue;
}
if (c < 0xC0)
- break;
- for (numAdds = 1; numAdds < 5; numAdds++)
- if (c < kUtf8Limits[numAdds])
- break;
- UInt32 value = (c - kUtf8Limits[numAdds - 1]);
+ _ERROR_UTF8
+
+ unsigned numBytes;
+ _UTF8_HEAD_PARSE
+ else
+ _ERROR_UTF8
+
+ UInt32 val = c;
do
{
Byte c2;
- if (srcPos == srcLen)
+ if (src == srcLim)
break;
- c2 = (Byte)src[srcPos++];
+ c2 = *src;
if (c2 < 0x80 || c2 >= 0xC0)
break;
- value <<= 6;
- value |= (c2 - 0x80);
+ src++;
+ val <<= 6;
+ val |= (c2 - 0x80);
}
- while (--numAdds != 0);
-
- if (value < 0x10000)
+ while (--numBytes);
+
+ if (numBytes != 0)
+ _ERROR_UTF8
+
+ if (val < 0x10000)
{
if (dest)
- dest[destPos] = (wchar_t)value;
+ dest[destPos] = (wchar_t)val;
destPos++;
}
else
{
- value -= 0x10000;
- if (value >= 0x100000)
- break;
+ val -= 0x10000;
+ if (val >= 0x100000)
+ _ERROR_UTF8
if (dest)
{
- dest[destPos + 0] = (wchar_t)(0xD800 + (value >> 10));
- dest[destPos + 1] = (wchar_t)(0xDC00 + (value & 0x3FF));
+ dest[destPos + 0] = (wchar_t)(0xD800 + (val >> 10));
+ dest[destPos + 1] = (wchar_t)(0xDC00 + (val & 0x3FF));
}
destPos += 2;
}
}
- *destLen = destPos;
- return False;
}
-static Bool Utf16_To_Utf8(char *dest, size_t *destLen, const wchar_t *src, size_t srcLen)
+#define _UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6))
+
+#define _UTF8_HEAD(n, val) ((char)(_UTF8_START(n) + (val >> (6 * (n)))))
+#define _UTF8_CHAR(n, val) ((char)(0x80 + (((val) >> (6 * (n))) & 0x3F)))
+
+static size_t Utf16_To_Utf8_Calc(const wchar_t *src, const wchar_t *srcLim)
{
- size_t destPos = 0, srcPos = 0;
+ size_t size = srcLim - src;
for (;;)
{
- unsigned numAdds;
- UInt32 value;
- if (srcPos == srcLen)
+ if (src == srcLim)
+ return size;
+
+ UInt32 val = *src++;
+
+ if (val < 0x80)
+ continue;
+
+ if (val < _UTF8_RANGE(1))
{
- *destLen = destPos;
- return True;
+ size++;
+ continue;
}
- value = src[srcPos++];
- if (value < 0x80)
+
+ if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
{
- if (dest)
- dest[destPos] = (char)value;
- destPos++;
+ UInt32 c2 = *src;
+ if (c2 >= 0xDC00 && c2 < 0xE000)
+ {
+ src++;
+ size += 2;
+ continue;
+ }
+ }
+
+ #ifdef _WCHART_IS_16BIT
+
+ size += 2;
+
+ #else
+
+ if (val < _UTF8_RANGE(2)) size += 2;
+ else if (val < _UTF8_RANGE(3)) size += 3;
+ else if (val < _UTF8_RANGE(4)) size += 4;
+ else if (val < _UTF8_RANGE(5)) size += 5;
+ else size += 6;
+
+ #endif
+ }
+}
+
+static char *Utf16_To_Utf8(char *dest, const wchar_t *src, const wchar_t *srcLim)
+{
+ for (;;)
+ {
+ if (src == srcLim)
+ return dest;
+
+ UInt32 val = *src++;
+
+ if (val < 0x80)
+ {
+ *dest++ = (char)val;
+ continue;
+ }
+
+ if (val < _UTF8_RANGE(1))
+ {
+ dest[0] = _UTF8_HEAD(1, val);
+ dest[1] = _UTF8_CHAR(0, val);
+ dest += 2;
continue;
}
- if (value >= 0xD800 && value < 0xE000)
+
+ if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
{
- UInt32 c2;
- if (value >= 0xDC00 || srcPos == srcLen)
- break;
- c2 = src[srcPos++];
- if (c2 < 0xDC00 || c2 >= 0xE000)
- break;
- value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
+ UInt32 c2 = *src;
+ if (c2 >= 0xDC00 && c2 < 0xE000)
+ {
+ src++;
+ val = (((val - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
+ dest[0] = _UTF8_HEAD(3, val);
+ dest[1] = _UTF8_CHAR(2, val);
+ dest[2] = _UTF8_CHAR(1, val);
+ dest[3] = _UTF8_CHAR(0, val);
+ dest += 4;
+ continue;
+ }
}
- for (numAdds = 1; numAdds < 5; numAdds++)
- if (value < (((UInt32)1) << (numAdds * 5 + 6)))
- break;
- if (dest)
- dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
- destPos++;
+
+ #ifndef _WCHART_IS_16BIT
+ if (val < _UTF8_RANGE(2))
+ #endif
+ {
+ dest[0] = _UTF8_HEAD(2, val);
+ dest[1] = _UTF8_CHAR(1, val);
+ dest[2] = _UTF8_CHAR(0, val);
+ dest += 3;
+ continue;
+ }
+
+ #ifndef _WCHART_IS_16BIT
+
+ UInt32 b;
+ unsigned numBits;
+ if (val < _UTF8_RANGE(3)) { numBits = 6 * 3; b = _UTF8_HEAD(3, val); }
+ else if (val < _UTF8_RANGE(4)) { numBits = 6 * 4; b = _UTF8_HEAD(4, val); }
+ else if (val < _UTF8_RANGE(5)) { numBits = 6 * 5; b = _UTF8_HEAD(5, val); }
+ else { numBits = 6 * 6; b = _UTF8_START(6); }
+
+ *dest++ = (Byte)b;
+
do
{
- numAdds--;
- if (dest)
- dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
- destPos++;
+ numBits -= 6;
+ *dest++ = (char)(0x80 + ((val >> numBits) & 0x3F));
}
- while (numAdds != 0);
+ while (numBits != 0);
+
+ #endif
}
- *destLen = destPos;
- return False;
}
bool ConvertUTF8ToUnicode(const AString &src, UString &dest)
{
dest.Empty();
size_t destLen = 0;
- Utf8_To_Utf16(NULL, &destLen, src, src.Length());
- wchar_t *p = dest.GetBuffer((int)destLen);
- Bool res = Utf8_To_Utf16(p, &destLen, src, src.Length());
- p[destLen] = 0;
- dest.ReleaseBuffer();
- return res ? true : false;
+ Utf8_To_Utf16(NULL, &destLen, src, src.Ptr(src.Len()));
+ bool res = Utf8_To_Utf16(dest.GetBuf((unsigned)destLen), &destLen, src, src.Ptr(src.Len()));
+ dest.ReleaseBuf_SetEnd((unsigned)destLen);
+ return res;
}
-bool ConvertUnicodeToUTF8(const UString &src, AString &dest)
+void ConvertUnicodeToUTF8(const UString &src, AString &dest)
{
dest.Empty();
- size_t destLen = 0;
- Utf16_To_Utf8(NULL, &destLen, src, src.Length());
- char *p = dest.GetBuffer((int)destLen);
- Bool res = Utf16_To_Utf8(p, &destLen, src, src.Length());
- p[destLen] = 0;
- dest.ReleaseBuffer();
- return res ? true : false;
+ size_t destLen = Utf16_To_Utf8_Calc(src, src.Ptr(src.Len()));
+ Utf16_To_Utf8(dest.GetBuf((unsigned)destLen), src, src.Ptr(src.Len()));
+ dest.ReleaseBuf_SetEnd((unsigned)destLen);
}
diff --git a/3rdparty/lzma/CPP/Common/UTFConvert.h b/3rdparty/lzma/CPP/Common/UTFConvert.h
index 2a14600d9e0..827f3dcfe19 100644
--- a/3rdparty/lzma/CPP/Common/UTFConvert.h
+++ b/3rdparty/lzma/CPP/Common/UTFConvert.h
@@ -1,11 +1,12 @@
// Common/UTFConvert.h
-#ifndef __COMMON_UTFCONVERT_H
-#define __COMMON_UTFCONVERT_H
+#ifndef __COMMON_UTF_CONVERT_H
+#define __COMMON_UTF_CONVERT_H
#include "MyString.h"
+bool CheckUTF8(const char *src, bool allowReduced = false) throw();
bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString);
-bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
+void ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
#endif
diff --git a/3rdparty/lzma/CPP/Common/Wildcard.cpp b/3rdparty/lzma/CPP/Common/Wildcard.cpp
index 87d449714bc..a83f9f104c0 100644
--- a/3rdparty/lzma/CPP/Common/Wildcard.cpp
+++ b/3rdparty/lzma/CPP/Common/Wildcard.cpp
@@ -2,8 +2,6 @@
#include "StdAfx.h"
-#include "../../C/Types.h"
-
#include "Wildcard.h"
bool g_CaseSensitive =
@@ -13,37 +11,29 @@ bool g_CaseSensitive =
true;
#endif
-static const wchar_t kAnyCharsChar = L'*';
-static const wchar_t kAnyCharChar = L'?';
-
-#ifdef _WIN32
-static const wchar_t kDirDelimiter1 = L'\\';
-#endif
-static const wchar_t kDirDelimiter2 = L'/';
-
-static const UString kWildCardCharSet = L"?*";
-
-static const UString kIllegalWildCardFileNameChars=
- L"\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF"
- L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
- L"\"/:<>\\|";
+bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2)
+{
+ if (g_CaseSensitive)
+ return IsString1PrefixedByString2(s1, s2);
+ return IsString1PrefixedByString2_NoCase(s1, s2);
+}
-static inline bool IsCharDirLimiter(wchar_t c)
+int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW
{
- return (
- #ifdef _WIN32
- c == kDirDelimiter1 ||
- #endif
- c == kDirDelimiter2);
+ if (g_CaseSensitive)
+ return wcscmp(s1, s2);
+ return MyStringCompareNoCase(s1, s2);
}
-int CompareFileNames(const UString &s1, const UString &s2)
+#ifndef USE_UNICODE_FSTRING
+int CompareFileNames(const char *s1, const char *s2)
{
if (g_CaseSensitive)
- return s1.Compare(s2);
- return s1.CompareNoCase(s2);
+ return wcscmp(fs2us(s1), fs2us(s2));
+ return MyStringCompareNoCase(fs2us(s1), fs2us(s2));
}
+#endif
// -----------------------------------------
// this function compares name with mask
@@ -58,7 +48,7 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
wchar_t c = *name;
if (m == 0)
return (c == 0);
- if (m == kAnyCharsChar)
+ if (m == '*')
{
if (EnhancedMaskTest(mask + 1, name))
return true;
@@ -67,7 +57,7 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
}
else
{
- if (m == kAnyCharChar)
+ if (m == '?')
{
if (c == 0)
return false;
@@ -87,61 +77,84 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
void SplitPathToParts(const UString &path, UStringVector &pathParts)
{
pathParts.Clear();
- UString name;
- int len = path.Length();
+ unsigned len = path.Len();
if (len == 0)
return;
- for (int i = 0; i < len; i++)
- {
- wchar_t c = path[i];
- if (IsCharDirLimiter(c))
+ UString name;
+ unsigned prev = 0;
+ for (unsigned i = 0; i < len; i++)
+ if (IsPathSepar(path[i]))
{
+ name.SetFrom(path.Ptr(prev), i - prev);
pathParts.Add(name);
- name.Empty();
+ prev = i + 1;
}
- else
- name += c;
- }
+ name.SetFrom(path.Ptr(prev), len - prev);
pathParts.Add(name);
}
-void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name)
+void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name)
{
- int i;
- for (i = path.Length() - 1; i >= 0; i--)
- if (IsCharDirLimiter(path[i]))
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ for (; p != start; p--)
+ if (IsPathSepar(*(p - 1)))
break;
- dirPrefix = path.Left(i + 1);
- name = path.Mid(i + 1);
+ dirPrefix.SetFrom(path, (unsigned)(p - start));
+ name = p;
+}
+
+void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name)
+{
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ if (p != start)
+ {
+ if (IsPathSepar(*(p - 1)))
+ p--;
+ for (; p != start; p--)
+ if (IsPathSepar(*(p - 1)))
+ break;
+ }
+ dirPrefix.SetFrom(path, (unsigned)(p - start));
+ name = p;
}
UString ExtractDirPrefixFromPath(const UString &path)
{
- int i;
- for (i = path.Length() - 1; i >= 0; i--)
- if (IsCharDirLimiter(path[i]))
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ for (; p != start; p--)
+ if (IsPathSepar(*(p - 1)))
break;
- return path.Left(i + 1);
+ return path.Left((unsigned)(p - start));
}
UString ExtractFileNameFromPath(const UString &path)
{
- int i;
- for (i = path.Length() - 1; i >= 0; i--)
- if (IsCharDirLimiter(path[i]))
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ for (; p != start; p--)
+ if (IsPathSepar(*(p - 1)))
break;
- return path.Mid(i + 1);
+ return p;
}
-bool CompareWildCardWithName(const UString &mask, const UString &name)
+bool DoesWildcardMatchName(const UString &mask, const UString &name)
{
return EnhancedMaskTest(mask, name);
}
-bool DoesNameContainWildCard(const UString &path)
+bool DoesNameContainWildcard(const UString &path)
{
- return (path.FindOneOf(kWildCardCharSet) >= 0);
+ for (unsigned i = 0; i < path.Len(); i++)
+ {
+ wchar_t c = path[i];
+ if (c == '*' || c == '?')
+ return true;
+ }
+ return false;
}
@@ -150,62 +163,106 @@ bool DoesNameContainWildCard(const UString &path)
namespace NWildcard {
-
/*
+
M = MaskParts.Size();
N = TestNameParts.Size();
File Dir
-ForFile req M<=N [N-M, N) -
- nonreq M=N [0, M) -
+ForFile rec M<=N [N-M, N) -
+!ForDir nonrec M=N [0, M) -
-ForDir req M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File
- nonreq [0, M) same as ForBoth-File
+ForDir rec M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File
+!ForFile nonrec [0, M) same as ForBoth-File
-ForBoth req m<=N [0, M) ... [N-M, N) same as ForBoth-File
- nonreq [0, M) same as ForBoth-File
+ForFile rec m<=N [0, M) ... [N-M, N) same as ForBoth-File
+ForDir nonrec [0, M) same as ForBoth-File
*/
+bool CItem::AreAllAllowed() const
+{
+ return ForFile && ForDir && WildcardMatching && PathParts.Size() == 1 && PathParts.Front() == L"*";
+}
+
bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
{
if (!isFile && !ForDir)
return false;
+
+ /*
+ if (PathParts.IsEmpty())
+ {
+ // PathParts.IsEmpty() means all items (universal wildcard)
+ if (!isFile)
+ return true;
+ if (pathParts.Size() <= 1)
+ return ForFile;
+ return (ForDir || Recursive && ForFile);
+ }
+ */
+
int delta = (int)pathParts.Size() - (int)PathParts.Size();
if (delta < 0)
return false;
int start = 0;
int finish = 0;
+
if (isFile)
{
- if (!ForDir && !Recursive && delta !=0)
- return false;
+ if (!ForDir)
+ {
+ if (Recursive)
+ start = delta;
+ else if (delta !=0)
+ return false;
+ }
if (!ForFile && delta == 0)
return false;
- if (!ForDir && Recursive)
- start = delta;
}
+
if (Recursive)
{
finish = delta;
if (isFile && !ForFile)
finish = delta - 1;
}
+
for (int d = start; d <= finish; d++)
{
- int i;
+ unsigned i;
for (i = 0; i < PathParts.Size(); i++)
- if (!CompareWildCardWithName(PathParts[i], pathParts[i + d]))
- break;
+ {
+ if (WildcardMatching)
+ {
+ if (!DoesWildcardMatchName(PathParts[i], pathParts[i + d]))
+ break;
+ }
+ else
+ {
+ if (CompareFileNames(PathParts[i], pathParts[i + d]) != 0)
+ break;
+ }
+ }
if (i == PathParts.Size())
return true;
}
return false;
}
+bool CCensorNode::AreAllAllowed() const
+{
+ if (!Name.IsEmpty() ||
+ !SubNodes.IsEmpty() ||
+ !ExcludeItems.IsEmpty() ||
+ IncludeItems.Size() != 1)
+ return false;
+ return IncludeItems.Front().AreAllAllowed();
+}
+
int CCensorNode::FindSubNode(const UString &name) const
{
- for (int i = 0; i < SubNodes.Size(); i++)
+ FOR_VECTOR (i, SubNodes)
if (CompareFileNames(SubNodes[i].Name, name) == 0)
return i;
return -1;
@@ -219,15 +276,24 @@ void CCensorNode::AddItemSimple(bool include, CItem &item)
ExcludeItems.Add(item);
}
-void CCensorNode::AddItem(bool include, CItem &item)
+void CCensorNode::AddItem(bool include, CItem &item, int ignoreWildcardIndex)
{
if (item.PathParts.Size() <= 1)
{
+ if (item.PathParts.Size() != 0 && item.WildcardMatching)
+ {
+ if (!DoesNameContainWildcard(item.PathParts.Front()))
+ item.WildcardMatching = false;
+ }
AddItemSimple(include, item);
return;
}
const UString &front = item.PathParts.Front();
- if (DoesNameContainWildCard(front))
+
+ // WIN32 doesn't support wildcards in file names
+ if (item.WildcardMatching
+ && ignoreWildcardIndex != 0
+ && DoesNameContainWildcard(front))
{
AddItemSimple(include, item);
return;
@@ -236,22 +302,23 @@ void CCensorNode::AddItem(bool include, CItem &item)
if (index < 0)
index = SubNodes.Add(CCensorNode(front, this));
item.PathParts.Delete(0);
- SubNodes[index].AddItem(include, item);
+ SubNodes[index].AddItem(include, item, ignoreWildcardIndex - 1);
}
-void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir)
+void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching)
{
CItem item;
SplitPathToParts(path, item.PathParts);
item.Recursive = recursive;
item.ForFile = forFile;
item.ForDir = forDir;
+ item.WildcardMatching = wildcardMatching;
AddItem(include, item);
}
bool CCensorNode::NeedCheckSubDirs() const
{
- for (int i = 0; i < IncludeItems.Size(); i++)
+ FOR_VECTOR (i, IncludeItems)
{
const CItem &item = IncludeItems[i];
if (item.Recursive || item.PathParts.Size() > 1)
@@ -264,7 +331,7 @@ bool CCensorNode::AreThereIncludeItems() const
{
if (IncludeItems.Size() > 0)
return true;
- for (int i = 0; i < SubNodes.Size(); i++)
+ FOR_VECTOR (i, SubNodes)
if (SubNodes[i].AreThereIncludeItems())
return true;
return false;
@@ -273,13 +340,13 @@ bool CCensorNode::AreThereIncludeItems() const
bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const
{
const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems;
- for (int i = 0; i < items.Size(); i++)
+ FOR_VECTOR (i, items)
if (items[i].CheckPath(pathParts, isFile))
return true;
return false;
}
-bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const
+bool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const
{
if (CheckPathCurrent(false, pathParts, isFile))
{
@@ -288,33 +355,50 @@ bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include
}
include = true;
bool finded = CheckPathCurrent(true, pathParts, isFile);
- if (pathParts.Size() == 1)
+ if (pathParts.Size() <= 1)
return finded;
int index = FindSubNode(pathParts.Front());
if (index >= 0)
{
UStringVector pathParts2 = pathParts;
pathParts2.Delete(0);
- if (SubNodes[index].CheckPath(pathParts2, isFile, include))
+ if (SubNodes[index].CheckPathVect(pathParts2, isFile, include))
return true;
}
return finded;
}
-bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const
+/*
+bool CCensorNode::CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const
{
UStringVector pathParts;
SplitPathToParts(path, pathParts);
- return CheckPath(pathParts, isFile, include);
+ if (CheckPathVect(pathParts, isFile, include))
+ {
+ if (!include || !isAltStream)
+ return true;
+ }
+ if (isAltStream && !pathParts.IsEmpty())
+ {
+ UString &back = pathParts.Back();
+ int pos = back.Find(L':');
+ if (pos > 0)
+ {
+ back.DeleteFrom(pos);
+ return CheckPathVect(pathParts, isFile, include);
+ }
+ }
+ return false;
}
-bool CCensorNode::CheckPath(const UString &path, bool isFile) const
+bool CCensorNode::CheckPath(bool isAltStream, const UString &path, bool isFile) const
{
bool include;
- if (CheckPath(path, isFile, include))
+ if (CheckPath2(isAltStream, path, isFile, include))
return include;
return false;
}
+*/
bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const
{
@@ -335,25 +419,25 @@ bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile
}
*/
-void CCensorNode::AddItem2(bool include, const UString &path, bool recursive)
+void CCensorNode::AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching)
{
if (path.IsEmpty())
return;
bool forFile = true;
bool forFolder = true;
UString path2 = path;
- if (IsCharDirLimiter(path.Back()))
+ if (IsPathSepar(path.Back()))
{
path2.DeleteBack();
forFile = false;
}
- AddItem(include, path2, recursive, forFile, forFolder);
+ AddItem(include, path2, recursive, forFile, forFolder, wildcardMatching);
}
void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
{
ExcludeItems += fromNodes.ExcludeItems;
- for (int i = 0; i < fromNodes.SubNodes.Size(); i++)
+ FOR_VECTOR (i, fromNodes.SubNodes)
{
const CCensorNode &node = fromNodes.SubNodes[i];
int subNodeIndex = FindSubNode(node.Name);
@@ -365,77 +449,193 @@ void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
int CCensor::FindPrefix(const UString &prefix) const
{
- for (int i = 0; i < Pairs.Size(); i++)
+ FOR_VECTOR (i, Pairs)
if (CompareFileNames(Pairs[i].Prefix, prefix) == 0)
return i;
return -1;
}
-void CCensor::AddItem(bool include, const UString &path, bool recursive)
+#ifdef _WIN32
+
+bool IsDriveColonName(const wchar_t *s)
+{
+ wchar_t c = s[0];
+ return c != 0 && s[1] == ':' && s[2] == 0 && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
+}
+
+unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts)
+{
+ if (pathParts.IsEmpty())
+ return 0;
+
+ unsigned testIndex = 0;
+ if (pathParts[0].IsEmpty())
+ {
+ if (pathParts.Size() < 4
+ || !pathParts[1].IsEmpty()
+ || pathParts[2] != L"?")
+ return 0;
+ testIndex = 3;
+ }
+ if (NWildcard::IsDriveColonName(pathParts[testIndex]))
+ return testIndex + 1;
+ return 0;
+}
+
+#endif
+
+static unsigned GetNumPrefixParts(const UStringVector pathParts)
+{
+ if (pathParts.IsEmpty())
+ return 0;
+
+ #ifdef _WIN32
+
+ if (IsDriveColonName(pathParts[0]))
+ return 1;
+ if (!pathParts[0].IsEmpty())
+ return 0;
+
+ if (pathParts.Size() == 1)
+ return 1;
+ if (!pathParts[1].IsEmpty())
+ return 1;
+ if (pathParts.Size() == 2)
+ return 2;
+ if (pathParts[2] == L".")
+ return 3;
+
+ unsigned networkParts = 2;
+ if (pathParts[2] == L"?")
+ {
+ if (pathParts.Size() == 3)
+ return 3;
+ if (IsDriveColonName(pathParts[3]))
+ return 4;
+ if (!pathParts[3].IsEqualTo_Ascii_NoCase("UNC"))
+ return 3;
+ networkParts = 4;
+ }
+
+ networkParts +=
+ // 2; // server/share
+ 1; // server
+ if (pathParts.Size() <= networkParts)
+ return pathParts.Size();
+ return networkParts;
+
+ #else
+
+ return pathParts[0].IsEmpty() ? 1 : 0;
+
+ #endif
+}
+
+void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching)
{
- UStringVector pathParts;
if (path.IsEmpty())
throw "Empty file path";
+
+ UStringVector pathParts;
SplitPathToParts(path, pathParts);
+
bool forFile = true;
if (pathParts.Back().IsEmpty())
{
forFile = false;
pathParts.DeleteBack();
}
- const UString &front = pathParts.Front();
- bool isAbs = false;
- if (front.IsEmpty())
- isAbs = true;
- else if (front.Length() == 2 && front[1] == L':')
- isAbs = true;
- else
+
+ UString prefix;
+
+ int ignoreWildcardIndex = -1;
+
+ // #ifdef _WIN32
+ // we ignore "?" wildcard in "\\?\" prefix.
+ if (pathParts.Size() >= 3
+ && pathParts[0].IsEmpty()
+ && pathParts[1].IsEmpty()
+ && pathParts[2] == L"?")
+ ignoreWildcardIndex = 2;
+ // #endif
+
+ if (pathMode != k_AbsPath)
{
- for (int i = 0; i < pathParts.Size(); i++)
+ ignoreWildcardIndex = -1;
+
+ const unsigned numPrefixParts = GetNumPrefixParts(pathParts);
+ unsigned numSkipParts = numPrefixParts;
+
+ if (pathMode != k_FullPath)
+ {
+ if (numPrefixParts != 0 && pathParts.Size() > numPrefixParts)
+ numSkipParts = pathParts.Size() - 1;
+ }
{
- const UString &part = pathParts[i];
- if (part == L".." || part == L".")
+ int dotsIndex = -1;
+ for (unsigned i = numPrefixParts; i < pathParts.Size(); i++)
{
- isAbs = true;
- break;
+ const UString &part = pathParts[i];
+ if (part == L".." || part == L".")
+ dotsIndex = i;
}
+
+ if (dotsIndex >= 0)
+ if (dotsIndex == (int)pathParts.Size() - 1)
+ numSkipParts = pathParts.Size();
+ else
+ numSkipParts = pathParts.Size() - 1;
+ }
+
+ for (unsigned i = 0; i < numSkipParts; i++)
+ {
+ {
+ const UString &front = pathParts.Front();
+ // WIN32 doesn't support wildcards in file names
+ if (wildcardMatching)
+ if (i >= numPrefixParts && DoesNameContainWildcard(front))
+ break;
+ prefix += front;
+ prefix.Add_PathSepar();
+ }
+ pathParts.Delete(0);
}
}
- int numAbsParts = 0;
- if (isAbs)
- if (pathParts.Size() > 1)
- numAbsParts = pathParts.Size() - 1;
- else
- numAbsParts = 1;
- UString prefix;
- for (int i = 0; i < numAbsParts; i++)
- {
- const UString &front = pathParts.Front();
- if (DoesNameContainWildCard(front))
- break;
- prefix += front;
- prefix += WCHAR_PATH_SEPARATOR;
- pathParts.Delete(0);
- }
+
int index = FindPrefix(prefix);
if (index < 0)
index = Pairs.Add(CPair(prefix));
+ if (pathMode != k_AbsPath)
+ {
+ if (pathParts.IsEmpty() || pathParts.Size() == 1 && pathParts[0].IsEmpty())
+ {
+ // we create universal item, if we skip all parts as prefix (like \ or L:\ )
+ pathParts.Clear();
+ pathParts.Add(L"*");
+ forFile = true;
+ wildcardMatching = true;
+ recursive = false;
+ }
+ }
+
CItem item;
item.PathParts = pathParts;
item.ForDir = true;
item.ForFile = forFile;
item.Recursive = recursive;
- Pairs[index].Head.AddItem(include, item);
+ item.WildcardMatching = wildcardMatching;
+ Pairs[index].Head.AddItem(include, item, ignoreWildcardIndex);
}
-bool CCensor::CheckPath(const UString &path, bool isFile) const
+/*
+bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) const
{
bool finded = false;
- for (int i = 0; i < Pairs.Size(); i++)
+ FOR_VECTOR (i, Pairs)
{
bool include;
- if (Pairs[i].Head.CheckPath(path, isFile, include))
+ if (Pairs[i].Head.CheckPath2(isAltStream, path, isFile, include))
{
if (!include)
return false;
@@ -444,19 +644,39 @@ bool CCensor::CheckPath(const UString &path, bool isFile) const
}
return finded;
}
+*/
void CCensor::ExtendExclude()
{
- int i;
+ unsigned i;
for (i = 0; i < Pairs.Size(); i++)
if (Pairs[i].Prefix.IsEmpty())
break;
if (i == Pairs.Size())
return;
- int index = i;
+ unsigned index = i;
for (i = 0; i < Pairs.Size(); i++)
if (index != i)
Pairs[i].Head.ExtendExclude(Pairs[index].Head);
}
+void CCensor::AddPathsToCensor(ECensorPathMode censorPathMode)
+{
+ FOR_VECTOR(i, CensorPaths)
+ {
+ const CCensorPath &cp = CensorPaths[i];
+ AddItem(censorPathMode, cp.Include, cp.Path, cp.Recursive, cp.WildcardMatching);
+ }
+ CensorPaths.Clear();
+}
+
+void CCensor::AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching)
+{
+ CCensorPath &cp = CensorPaths.AddNew();
+ cp.Path = path;
+ cp.Include = include;
+ cp.Recursive = recursive;
+ cp.WildcardMatching = wildcardMatching;
+}
+
}
diff --git a/3rdparty/lzma/CPP/Common/Wildcard.h b/3rdparty/lzma/CPP/Common/Wildcard.h
index 6d4cbcece44..512687d1e67 100644
--- a/3rdparty/lzma/CPP/Common/Wildcard.h
+++ b/3rdparty/lzma/CPP/Common/Wildcard.h
@@ -5,51 +5,82 @@
#include "MyString.h"
-int CompareFileNames(const UString &s1, const UString &s2);
+int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW;
+#ifndef USE_UNICODE_FSTRING
+ int CompareFileNames(const char *s1, const char *s2);
+#endif
+
+bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2);
void SplitPathToParts(const UString &path, UStringVector &pathParts);
-void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name);
+void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name);
+void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name); // ignores dir delimiter at the end of (path)
+
UString ExtractDirPrefixFromPath(const UString &path);
UString ExtractFileNameFromPath(const UString &path);
-bool DoesNameContainWildCard(const UString &path);
-bool CompareWildCardWithName(const UString &mask, const UString &name);
+
+bool DoesNameContainWildcard(const UString &path);
+bool DoesWildcardMatchName(const UString &mask, const UString &name);
namespace NWildcard {
+#ifdef _WIN32
+// returns true, if name is like "a:", "c:", ...
+bool IsDriveColonName(const wchar_t *s);
+unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts);
+#endif
+
struct CItem
{
UStringVector PathParts;
bool Recursive;
bool ForFile;
bool ForDir;
+ bool WildcardMatching;
+
+ #ifdef _WIN32
+ bool IsDriveItem() const
+ {
+ return PathParts.Size() == 1 && !ForFile && ForDir && IsDriveColonName(PathParts[0]);
+ }
+ #endif
+
+ // CItem(): WildcardMatching(true) {}
+
+ bool AreAllAllowed() const;
bool CheckPath(const UStringVector &pathParts, bool isFile) const;
};
class CCensorNode
{
CCensorNode *Parent;
+
bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const;
void AddItemSimple(bool include, CItem &item);
- bool CheckPath(UStringVector &pathParts, bool isFile, bool &include) const;
public:
+ bool CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const;
+
CCensorNode(): Parent(0) { };
CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { };
- UString Name;
+
+ UString Name; // WIN32 doesn't support wildcards in file names
CObjectVector<CCensorNode> SubNodes;
CObjectVector<CItem> IncludeItems;
CObjectVector<CItem> ExcludeItems;
+ bool AreAllAllowed() const;
+
int FindSubNode(const UString &path) const;
- void AddItem(bool include, CItem &item);
- void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir);
- void AddItem2(bool include, const UString &path, bool recursive);
+ void AddItem(bool include, CItem &item, int ignoreWildcardIndex = -1);
+ void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching);
+ void AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching);
bool NeedCheckSubDirs() const;
bool AreThereIncludeItems() const;
- bool CheckPath(const UString &path, bool isFile, bool &include) const;
- bool CheckPath(const UString &path, bool isFile) const;
+ // bool CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const;
+ // bool CheckPath(bool isAltStream, const UString &path, bool isFile) const;
bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const;
// bool CheckPathToRoot(const UString &path, bool isFile, bool include) const;
@@ -60,21 +91,59 @@ struct CPair
{
UString Prefix;
CCensorNode Head;
+
CPair(const UString &prefix): Prefix(prefix) { };
};
+enum ECensorPathMode
+{
+ k_RelatPath, // absolute prefix as Prefix, remain path in Tree
+ k_FullPath, // drive prefix as Prefix, remain path in Tree
+ k_AbsPath // full path in Tree
+};
+
+struct CCensorPath
+{
+ UString Path;
+ bool Include;
+ bool Recursive;
+ bool WildcardMatching;
+
+ CCensorPath():
+ Include(true),
+ Recursive(false),
+ WildcardMatching(true)
+ {}
+};
+
class CCensor
{
int FindPrefix(const UString &prefix) const;
public:
CObjectVector<CPair> Pairs;
+
+ CObjectVector<NWildcard::CCensorPath> CensorPaths;
+
bool AllAreRelative() const
{ return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); }
- void AddItem(bool include, const UString &path, bool recursive);
- bool CheckPath(const UString &path, bool isFile) const;
+
+ void AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching);
+ // bool CheckPath(bool isAltStream, const UString &path, bool isFile) const;
void ExtendExclude();
+
+ void AddPathsToCensor(NWildcard::ECensorPathMode censorPathMode);
+ void AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching);
+ void AddPreItem(const UString &path)
+ {
+ AddPreItem(true, path, false, false);
+ }
+ void AddPreItem_Wildcard()
+ {
+ AddPreItem(true, L"*", false, true);
+ }
};
+
}
#endif
diff --git a/3rdparty/lzma/CPP/Common/XzCrc64Reg.cpp b/3rdparty/lzma/CPP/Common/XzCrc64Reg.cpp
new file mode 100644
index 00000000000..d1a51338646
--- /dev/null
+++ b/3rdparty/lzma/CPP/Common/XzCrc64Reg.cpp
@@ -0,0 +1,42 @@
+// XzCrc64Reg.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/CpuArch.h"
+#include "../../C/XzCrc64.h"
+
+#include "../Common/MyCom.h"
+
+#include "../7zip/Common/RegisterCodec.h"
+
+class CXzCrc64Hasher:
+ public IHasher,
+ public CMyUnknownImp
+{
+ UInt64 _crc;
+ Byte mtDummy[1 << 7];
+
+public:
+ CXzCrc64Hasher(): _crc(CRC64_INIT_VAL) {}
+
+ MY_UNKNOWN_IMP
+ INTERFACE_IHasher(;)
+};
+
+STDMETHODIMP_(void) CXzCrc64Hasher::Init() throw()
+{
+ _crc = CRC64_INIT_VAL;
+}
+
+STDMETHODIMP_(void) CXzCrc64Hasher::Update(const void *data, UInt32 size) throw()
+{
+ _crc = Crc64Update(_crc, data, size);
+}
+
+STDMETHODIMP_(void) CXzCrc64Hasher::Final(Byte *digest) throw()
+{
+ UInt64 val = CRC64_GET_DIGEST(_crc);
+ SetUi64(digest, val);
+}
+
+REGISTER_HASHER(CXzCrc64Hasher, 0x4, "CRC64", 8)
diff --git a/3rdparty/lzma/CPP/Windows/COM.h b/3rdparty/lzma/CPP/Windows/COM.h
new file mode 100644
index 00000000000..cee7f702d6f
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/COM.h
@@ -0,0 +1,70 @@
+// Windows/COM.h
+
+#ifndef __WINDOWS_COM_H
+#define __WINDOWS_COM_H
+
+#include "../Common/MyString.h"
+
+namespace NWindows {
+namespace NCOM {
+
+#ifdef _WIN32
+
+class CComInitializer
+{
+public:
+ CComInitializer()
+ {
+ #ifdef UNDER_CE
+ CoInitializeEx(NULL, COINIT_MULTITHREADED);
+ #else
+ // it's single thread. Do we need multithread?
+ CoInitialize(NULL);
+ #endif
+ };
+ ~CComInitializer() { CoUninitialize(); }
+};
+
+class CStgMedium
+{
+ STGMEDIUM _object;
+public:
+ bool _mustBeReleased;
+ CStgMedium(): _mustBeReleased(false) {}
+ ~CStgMedium() { Free(); }
+ void Free()
+ {
+ if (_mustBeReleased)
+ ReleaseStgMedium(&_object);
+ _mustBeReleased = false;
+ }
+ const STGMEDIUM* operator->() const { return &_object;}
+ STGMEDIUM* operator->() { return &_object;}
+ STGMEDIUM* operator&() { return &_object; }
+};
+
+#endif
+
+/*
+//////////////////////////////////
+// GUID <--> String Conversions
+UString GUIDToStringW(REFGUID guid);
+AString GUIDToStringA(REFGUID guid);
+#ifdef UNICODE
+ #define GUIDToString GUIDToStringW
+#else
+ #define GUIDToString GUIDToStringA
+#endif
+
+HRESULT StringToGUIDW(const wchar_t *string, GUID &classID);
+HRESULT StringToGUIDA(const char *string, GUID &classID);
+#ifdef UNICODE
+ #define StringToGUID StringToGUIDW
+#else
+ #define StringToGUID StringToGUIDA
+#endif
+*/
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/CommonDialog.cpp b/3rdparty/lzma/CPP/Windows/CommonDialog.cpp
new file mode 100644
index 00000000000..8f4f56d39a4
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/CommonDialog.cpp
@@ -0,0 +1,185 @@
+// Windows/CommonDialog.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/MyWindows.h"
+
+#ifdef UNDER_CE
+#include <commdlg.h>
+#endif
+
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#include "CommonDialog.h"
+#include "Defs.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+
+#ifndef _UNICODE
+
+class CDoubleZeroStringListA
+{
+ LPTSTR Buf;
+ unsigned Size;
+public:
+ CDoubleZeroStringListA(LPSTR buf, unsigned size): Buf(buf), Size(size) {}
+ bool Add(LPCSTR s) throw();
+ void Finish() { *Buf = 0; }
+};
+
+bool CDoubleZeroStringListA::Add(LPCSTR s) throw()
+{
+ unsigned len = MyStringLen(s) + 1;
+ if (len >= Size)
+ return false;
+ MyStringCopy(Buf, s);
+ Buf += len;
+ Size -= len;
+ return true;
+}
+
+#endif
+
+class CDoubleZeroStringListW
+{
+ LPWSTR Buf;
+ unsigned Size;
+public:
+ CDoubleZeroStringListW(LPWSTR buf, unsigned size): Buf(buf), Size(size) {}
+ bool Add(LPCWSTR s) throw();
+ void Finish() { *Buf = 0; }
+};
+
+bool CDoubleZeroStringListW::Add(LPCWSTR s) throw()
+{
+ unsigned len = MyStringLen(s) + 1;
+ if (len >= Size)
+ return false;
+ MyStringCopy(Buf, s);
+ Buf += len;
+ Size -= len;
+ return true;
+}
+
+#define MY__OFN_PROJECT 0x00400000
+#define MY__OFN_SHOW_ALL 0x01000000
+
+/* if (lpstrFilter == NULL && nFilterIndex == 0)
+ MSDN : "the system doesn't show any files",
+ but WinXP-64 shows all files. Why ??? */
+
+/*
+structures
+ OPENFILENAMEW
+ OPENFILENAMEA
+contain additional members:
+#if (_WIN32_WINNT >= 0x0500)
+ void *pvReserved;
+ DWORD dwReserved;
+ DWORD FlagsEx;
+#endif
+
+If we compile the source code with (_WIN32_WINNT >= 0x0500), some functions
+will not work at NT 4.0, if we use sizeof(OPENFILENAME*).
+So we use size of old version of structure. */
+
+#if defined(UNDER_CE) || defined(_WIN64) || (_WIN32_WINNT < 0x0500)
+// || !defined(WINVER)
+ #define my_compatib_OPENFILENAMEA_size sizeof(OPENFILENAMEA)
+ #define my_compatib_OPENFILENAMEW_size sizeof(OPENFILENAMEW)
+#else
+ #define my_compatib_OPENFILENAMEA_size OPENFILENAME_SIZE_VERSION_400A
+ #define my_compatib_OPENFILENAMEW_size OPENFILENAME_SIZE_VERSION_400W
+#endif
+
+#define CONV_U_To_A(dest, src, temp) AString temp; if (src) { temp = GetSystemString(src); dest = temp; }
+
+bool MyGetOpenFileName(HWND hwnd, LPCWSTR title,
+ LPCWSTR initialDir,
+ LPCWSTR filePath,
+ LPCWSTR filterDescription,
+ LPCWSTR filter,
+ UString &resPath
+ #ifdef UNDER_CE
+ , bool openFolder
+ #endif
+ )
+{
+ const unsigned kBufSize = MAX_PATH * 2;
+ const unsigned kFilterBufSize = MAX_PATH;
+ if (!filter)
+ filter = L"*.*";
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ CHAR buf[kBufSize];
+ MyStringCopy(buf, (const char *)GetSystemString(filePath));
+ // OPENFILENAME_NT4A
+ OPENFILENAMEA p;
+ memset(&p, 0, sizeof(p));
+ p.lStructSize = my_compatib_OPENFILENAMEA_size;
+ p.hwndOwner = hwnd;
+ CHAR filterBuf[kFilterBufSize];
+ {
+ CDoubleZeroStringListA dz(filterBuf, kFilterBufSize);
+ dz.Add(GetSystemString(filterDescription ? filterDescription : filter));
+ dz.Add(GetSystemString(filter));
+ dz.Finish();
+ p.lpstrFilter = filterBuf;
+ p.nFilterIndex = 1;
+ }
+
+ p.lpstrFile = buf;
+ p.nMaxFile = kBufSize;
+ CONV_U_To_A(p.lpstrInitialDir, initialDir, initialDirA);
+ CONV_U_To_A(p.lpstrTitle, title, titleA);
+ p.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
+
+ bool res = BOOLToBool(::GetOpenFileNameA(&p));
+ resPath = GetUnicodeString(buf);
+ return res;
+ }
+ else
+ #endif
+ {
+ WCHAR buf[kBufSize];
+ MyStringCopy(buf, filePath);
+ // OPENFILENAME_NT4W
+ OPENFILENAMEW p;
+ memset(&p, 0, sizeof(p));
+ p.lStructSize = my_compatib_OPENFILENAMEW_size;
+ p.hwndOwner = hwnd;
+
+ WCHAR filterBuf[kFilterBufSize];
+ {
+ CDoubleZeroStringListW dz(filterBuf, kFilterBufSize);
+ dz.Add(filterDescription ? filterDescription : filter);
+ dz.Add(filter);
+ dz.Finish();
+ p.lpstrFilter = filterBuf;
+ p.nFilterIndex = 1;
+ }
+
+ p.lpstrFile = buf;
+ p.nMaxFile = kBufSize;
+ p.lpstrInitialDir = initialDir;
+ p.lpstrTitle = title;
+ p.Flags = OFN_EXPLORER | OFN_HIDEREADONLY
+ #ifdef UNDER_CE
+ | (openFolder ? (MY__OFN_PROJECT | MY__OFN_SHOW_ALL) : 0)
+ #endif
+ ;
+
+ bool res = BOOLToBool(::GetOpenFileNameW(&p));
+ resPath = buf;
+ return res;
+ }
+}
+
+}
diff --git a/3rdparty/lzma/CPP/Windows/CommonDialog.h b/3rdparty/lzma/CPP/Windows/CommonDialog.h
new file mode 100644
index 00000000000..aaf17ac57ce
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/CommonDialog.h
@@ -0,0 +1,23 @@
+// Windows/CommonDialog.h
+
+#ifndef __WINDOWS_COMMON_DIALOG_H
+#define __WINDOWS_COMMON_DIALOG_H
+
+#include "../Common/MyString.h"
+
+namespace NWindows {
+
+bool MyGetOpenFileName(HWND hwnd, LPCWSTR title,
+ LPCWSTR initialDir, // can be NULL, so dir prefix in filePath will be used
+ LPCWSTR filePath, // full path
+ LPCWSTR filterDescription, // like "All files (*.*)"
+ LPCWSTR filter, // like "*.exe"
+ UString &resPath
+ #ifdef UNDER_CE
+ , bool openFolder = false
+ #endif
+);
+
+}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/ComboBox.cpp b/3rdparty/lzma/CPP/Windows/Control/ComboBox.cpp
new file mode 100644
index 00000000000..c6d5a8d688b
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/ComboBox.cpp
@@ -0,0 +1,66 @@
+// Windows/Control/ComboBox.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "../../Common/StringConvert.h"
+#endif
+
+#include "ComboBox.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NControl {
+
+LRESULT CComboBox::GetLBText(int index, CSysString &s)
+{
+ s.Empty();
+ LRESULT len = GetLBTextLen(index); // length, excluding the terminating null character
+ if (len == CB_ERR)
+ return len;
+ LRESULT len2 = GetLBText(index, s.GetBuf((unsigned)len));
+ if (len2 == CB_ERR)
+ return len;
+ if (len > len2)
+ len = len2;
+ s.ReleaseBuf_CalcLen((unsigned)len);
+ return len;
+}
+
+#ifndef _UNICODE
+LRESULT CComboBox::AddString(LPCWSTR s)
+{
+ if (g_IsNT)
+ return SendMsgW(CB_ADDSTRING, 0, (LPARAM)s);
+ return AddString(GetSystemString(s));
+}
+
+LRESULT CComboBox::GetLBText(int index, UString &s)
+{
+ s.Empty();
+ if (g_IsNT)
+ {
+ LRESULT len = SendMsgW(CB_GETLBTEXTLEN, index, 0);
+ if (len == CB_ERR)
+ return len;
+ LRESULT len2 = SendMsgW(CB_GETLBTEXT, index, (LPARAM)s.GetBuf((unsigned)len));
+ if (len2 == CB_ERR)
+ return len;
+ if (len > len2)
+ len = len2;
+ s.ReleaseBuf_CalcLen(len);
+ return len;
+ }
+ AString sa;
+ LRESULT len = GetLBText(index, sa);
+ if (len == CB_ERR)
+ return len;
+ s = GetUnicodeString(sa);
+ return s.Len();
+}
+#endif
+
+}}
diff --git a/3rdparty/lzma/CPP/Windows/Control/ComboBox.h b/3rdparty/lzma/CPP/Windows/Control/ComboBox.h
new file mode 100644
index 00000000000..1d5a482134c
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/ComboBox.h
@@ -0,0 +1,65 @@
+// Windows/Control/ComboBox.h
+
+#ifndef __WINDOWS_CONTROL_COMBOBOX_H
+#define __WINDOWS_CONTROL_COMBOBOX_H
+
+#include "../../Common/MyWindows.h"
+
+#include <commctrl.h>
+
+#include "../Window.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CComboBox: public CWindow
+{
+public:
+ void ResetContent() { SendMsg(CB_RESETCONTENT, 0, 0); }
+ LRESULT AddString(LPCTSTR s) { return SendMsg(CB_ADDSTRING, 0, (LPARAM)s); }
+ #ifndef _UNICODE
+ LRESULT AddString(LPCWSTR s);
+ #endif
+ LRESULT SetCurSel(int index) { return SendMsg(CB_SETCURSEL, index, 0); }
+ int GetCurSel() { return (int)SendMsg(CB_GETCURSEL, 0, 0); }
+ int GetCount() { return (int)SendMsg(CB_GETCOUNT, 0, 0); }
+
+ LRESULT GetLBTextLen(int index) { return SendMsg(CB_GETLBTEXTLEN, index, 0); }
+ LRESULT GetLBText(int index, LPTSTR s) { return SendMsg(CB_GETLBTEXT, index, (LPARAM)s); }
+ LRESULT GetLBText(int index, CSysString &s);
+ #ifndef _UNICODE
+ LRESULT GetLBText(int index, UString &s);
+ #endif
+
+ LRESULT SetItemData(int index, LPARAM lParam) { return SendMsg(CB_SETITEMDATA, index, lParam); }
+ LRESULT GetItemData(int index) { return SendMsg(CB_GETITEMDATA, index, 0); }
+
+ LRESULT GetItemData_of_CurSel() { return GetItemData(GetCurSel()); }
+
+ void ShowDropDown(bool show = true) { SendMsg(CB_SHOWDROPDOWN, show ? TRUE : FALSE, 0); }
+};
+
+#ifndef UNDER_CE
+
+class CComboBoxEx: public CComboBox
+{
+public:
+ bool SetUnicodeFormat(bool fUnicode) { return LRESULTToBool(SendMsg(CBEM_SETUNICODEFORMAT, BOOLToBool(fUnicode), 0)); }
+
+ LRESULT DeleteItem(int index) { return SendMsg(CBEM_DELETEITEM, index, 0); }
+ LRESULT InsertItem(COMBOBOXEXITEM *item) { return SendMsg(CBEM_INSERTITEM, 0, (LPARAM)item); }
+ #ifndef _UNICODE
+ LRESULT InsertItem(COMBOBOXEXITEMW *item) { return SendMsg(CBEM_INSERTITEMW, 0, (LPARAM)item); }
+ #endif
+
+ LRESULT SetItem(COMBOBOXEXITEM *item) { return SendMsg(CBEM_SETITEM, 0, (LPARAM)item); }
+ DWORD SetExtendedStyle(DWORD exMask, DWORD exStyle) { return (DWORD)SendMsg(CBEM_SETEXTENDEDSTYLE, exMask, exStyle); }
+ HWND GetEditControl() { return (HWND)SendMsg(CBEM_GETEDITCONTROL, 0, 0); }
+ HIMAGELIST SetImageList(HIMAGELIST imageList) { return (HIMAGELIST)SendMsg(CBEM_SETIMAGELIST, 0, (LPARAM)imageList); }
+};
+
+#endif
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/CommandBar.h b/3rdparty/lzma/CPP/Windows/Control/CommandBar.h
new file mode 100644
index 00000000000..a6197447a40
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/CommandBar.h
@@ -0,0 +1,52 @@
+// Windows/Control/CommandBar.h
+
+#ifndef __WINDOWS_CONTROL_COMMANDBAR_H
+#define __WINDOWS_CONTROL_COMMANDBAR_H
+
+#ifdef UNDER_CE
+
+#include "../../Common/MyWindows.h"
+
+#include <commctrl.h>
+
+#include "../Window.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CCommandBar: public NWindows::CWindow
+{
+public:
+ bool Create(HINSTANCE hInst, HWND hwndParent, int idCmdBar)
+ {
+ _window = ::CommandBar_Create(hInst, hwndParent, idCmdBar);
+ return (_window != NULL);
+ }
+
+ // Macros
+ // void Destroy() { CommandBar_Destroy(_window); }
+ // bool AddButtons(UINT numButtons, LPTBBUTTON buttons) { return BOOLToBool(SendMsg(TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)buttons)); }
+ bool InsertButton(int iButton, LPTBBUTTON button) { return BOOLToBool(SendMsg(TB_INSERTBUTTON, (WPARAM)iButton, (LPARAM)button)); }
+ BOOL AddToolTips(UINT numToolTips, LPTSTR toolTips) { return BOOLToBool(SendMsg(TB_SETTOOLTIPS, (WPARAM)numToolTips, (LPARAM)toolTips)); }
+ void AutoSize() { SendMsg(TB_AUTOSIZE, 0, 0); }
+
+ bool AddAdornments(DWORD dwFlags) { return BOOLToBool(::CommandBar_AddAdornments(_window, dwFlags, 0)); }
+ int AddBitmap(HINSTANCE hInst, int idBitmap, int iNumImages, int iImageWidth, int iImageHeight) { return ::CommandBar_AddBitmap(_window, hInst, idBitmap, iNumImages, iImageWidth, iImageHeight); }
+ bool DrawMenuBar(WORD iButton) { return BOOLToBool(::CommandBar_DrawMenuBar(_window, iButton)); }
+ HMENU GetMenu(WORD iButton) { return ::CommandBar_GetMenu(_window, iButton); }
+ int Height() { return CommandBar_Height(_window); }
+ HWND InsertComboBox(HINSTANCE hInst, int iWidth, UINT dwStyle, WORD idComboBox, WORD iButton) { return ::CommandBar_InsertComboBox(_window, hInst, iWidth, dwStyle, idComboBox, iButton); }
+ bool InsertMenubar(HINSTANCE hInst, WORD idMenu, WORD iButton) { return BOOLToBool(::CommandBar_InsertMenubar(_window, hInst, idMenu, iButton)); }
+ bool InsertMenubarEx(HINSTANCE hInst, LPTSTR pszMenu, WORD iButton) { return BOOLToBool(::CommandBar_InsertMenubarEx(_window, hInst, pszMenu, iButton)); }
+ bool Show(bool cmdShow) { return BOOLToBool(::CommandBar_Show(_window, BoolToBOOL(cmdShow))); }
+
+
+ // CE 4.0
+ void AlignAdornments() { CommandBar_AlignAdornments(_window); }
+};
+
+}}
+
+#endif
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/Dialog.cpp b/3rdparty/lzma/CPP/Windows/Control/Dialog.cpp
new file mode 100644
index 00000000000..9df3ef5ef24
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/Dialog.cpp
@@ -0,0 +1,250 @@
+// Windows/Control/Dialog.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "../../Common/StringConvert.h"
+#endif
+
+#include "Dialog.h"
+
+extern HINSTANCE g_hInstance;
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NControl {
+
+static INT_PTR APIENTRY DialogProcedure(HWND dialogHWND, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ CWindow tempDialog(dialogHWND);
+ if (message == WM_INITDIALOG)
+ tempDialog.SetUserDataLongPtr(lParam);
+ CDialog *dialog = (CDialog *)(tempDialog.GetUserDataLongPtr());
+ if (dialog == NULL)
+ return FALSE;
+ if (message == WM_INITDIALOG)
+ dialog->Attach(dialogHWND);
+ try { return BoolToBOOL(dialog->OnMessage(message, wParam, lParam)); }
+ catch(...) { return TRUE; }
+}
+
+bool CDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_INITDIALOG: return OnInit();
+ case WM_COMMAND: return OnCommand(wParam, lParam);
+ case WM_NOTIFY: return OnNotify((UINT)wParam, (LPNMHDR) lParam);
+ case WM_TIMER: return OnTimer(wParam, lParam);
+ case WM_SIZE: return OnSize(wParam, LOWORD(lParam), HIWORD(lParam));
+ case WM_HELP: OnHelp(); return true;
+ /*
+ OnHelp(
+ #ifdef UNDER_CE
+ (void *)
+ #else
+ (LPHELPINFO)
+ #endif
+ lParam);
+ return true;
+ */
+ default: return false;
+ }
+}
+
+bool CDialog::OnCommand(WPARAM wParam, LPARAM lParam)
+{
+ return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam);
+}
+
+bool CDialog::OnCommand(int code, int itemID, LPARAM lParam)
+{
+ if (code == BN_CLICKED)
+ return OnButtonClicked(itemID, (HWND)lParam);
+ return false;
+}
+
+bool CDialog::OnButtonClicked(int buttonID, HWND /* buttonHWND */)
+{
+ switch (buttonID)
+ {
+ case IDOK: OnOK(); break;
+ case IDCANCEL: OnCancel(); break;
+ case IDHELP: OnHelp(); break;
+ default: return false;
+ }
+ return true;
+}
+
+static bool GetWorkAreaRect(RECT *rect)
+{
+ // use another function for multi-monitor.
+ return BOOLToBool(::SystemParametersInfo(SPI_GETWORKAREA, 0, rect, 0));
+}
+
+bool IsDialogSizeOK(int xSize, int ySize)
+{
+ // it returns for system font. Real font uses another values
+ LONG v = GetDialogBaseUnits();
+ int x = LOWORD(v);
+ int y = HIWORD(v);
+
+ RECT rect;
+ GetWorkAreaRect(&rect);
+ int wx = RECT_SIZE_X(rect);
+ int wy = RECT_SIZE_Y(rect);
+ return
+ xSize / 4 * x <= wx &&
+ ySize / 8 * y <= wy;
+}
+
+bool CDialog::GetMargins(int margin, int &x, int &y)
+{
+ x = margin;
+ y = margin;
+ RECT rect;
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = margin;
+ rect.bottom = margin;
+ if (!MapRect(&rect))
+ return false;
+ x = rect.right - rect.left;
+ y = rect.bottom - rect.top;
+ return true;
+}
+
+int CDialog::Units_To_Pixels_X(int units)
+{
+ RECT rect;
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = units;
+ rect.bottom = units;
+ if (!MapRect(&rect))
+ return units * 3 / 2;
+ return rect.right - rect.left;
+}
+
+bool CDialog::GetItemSizes(int id, int &x, int &y)
+{
+ RECT rect;
+ if (!::GetWindowRect(GetItem(id), &rect))
+ return false;
+ x = RECT_SIZE_X(rect);
+ y = RECT_SIZE_Y(rect);
+ return true;
+}
+
+void CDialog::GetClientRectOfItem(int id, RECT &rect)
+{
+ ::GetWindowRect(GetItem(id), &rect);
+ ScreenToClient(&rect);
+}
+
+bool CDialog::MoveItem(int id, int x, int y, int width, int height, bool repaint)
+{
+ return BOOLToBool(::MoveWindow(GetItem(id), x, y, width, height, BoolToBOOL(repaint)));
+}
+
+void CDialog::NormalizeSize(bool fullNormalize)
+{
+ RECT workRect;
+ GetWorkAreaRect(&workRect);
+ int xSize = RECT_SIZE_X(workRect);
+ int ySize = RECT_SIZE_Y(workRect);
+ RECT rect;
+ GetWindowRect(&rect);
+ int xSize2 = RECT_SIZE_X(rect);
+ int ySize2 = RECT_SIZE_Y(rect);
+ bool needMove = (xSize2 > xSize || ySize2 > ySize);
+ if (xSize2 > xSize || (needMove && fullNormalize))
+ {
+ rect.left = workRect.left;
+ rect.right = workRect.right;
+ xSize2 = xSize;
+ }
+ if (ySize2 > ySize || (needMove && fullNormalize))
+ {
+ rect.top = workRect.top;
+ rect.bottom = workRect.bottom;
+ ySize2 = ySize;
+ }
+ if (needMove)
+ {
+ if (fullNormalize)
+ Show(SW_SHOWMAXIMIZED);
+ else
+ Move(rect.left, rect.top, xSize2, ySize2, true);
+ }
+}
+
+void CDialog::NormalizePosition()
+{
+ RECT workRect, rect;
+ GetWorkAreaRect(&workRect);
+ GetWindowRect(&rect);
+ if (rect.bottom > workRect.bottom && rect.top > workRect.top)
+ Move(rect.left, workRect.top, RECT_SIZE_X(rect), RECT_SIZE_Y(rect), true);
+}
+
+bool CModelessDialog::Create(LPCTSTR templateName, HWND parentWindow)
+{
+ HWND aHWND = CreateDialogParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
+ if (aHWND == 0)
+ return false;
+ Attach(aHWND);
+ return true;
+}
+
+INT_PTR CModalDialog::Create(LPCTSTR templateName, HWND parentWindow)
+{
+ return DialogBoxParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
+}
+
+#ifndef _UNICODE
+
+bool CModelessDialog::Create(LPCWSTR templateName, HWND parentWindow)
+{
+ HWND aHWND;
+ if (g_IsNT)
+ aHWND = CreateDialogParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
+ else
+ {
+ AString name;
+ LPCSTR templateNameA;
+ if (IS_INTRESOURCE(templateName))
+ templateNameA = (LPCSTR)templateName;
+ else
+ {
+ name = GetSystemString(templateName);
+ templateNameA = name;
+ }
+ aHWND = CreateDialogParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this);
+ }
+ if (aHWND == 0)
+ return false;
+ Attach(aHWND);
+ return true;
+}
+
+INT_PTR CModalDialog::Create(LPCWSTR templateName, HWND parentWindow)
+{
+ if (g_IsNT)
+ return DialogBoxParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
+ AString name;
+ LPCSTR templateNameA;
+ if (IS_INTRESOURCE(templateName))
+ templateNameA = (LPCSTR)templateName;
+ else
+ {
+ name = GetSystemString(templateName);
+ templateNameA = name;
+ }
+ return DialogBoxParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this);
+}
+#endif
+
+}}
diff --git a/3rdparty/lzma/CPP/Windows/Control/Dialog.h b/3rdparty/lzma/CPP/Windows/Control/Dialog.h
new file mode 100644
index 00000000000..59b9f41935c
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/Dialog.h
@@ -0,0 +1,167 @@
+// Windows/Control/Dialog.h
+
+#ifndef __WINDOWS_CONTROL_DIALOG_H
+#define __WINDOWS_CONTROL_DIALOG_H
+
+#include "../Window.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CDialog: public CWindow
+{
+public:
+ CDialog(HWND wnd = NULL): CWindow(wnd){};
+ virtual ~CDialog() {};
+
+ HWND GetItem(int itemID) const
+ { return GetDlgItem(_window, itemID); }
+
+ bool EnableItem(int itemID, bool enable) const
+ { return BOOLToBool(::EnableWindow(GetItem(itemID), BoolToBOOL(enable))); }
+
+ bool ShowItem(int itemID, int cmdShow) const
+ { return BOOLToBool(::ShowWindow(GetItem(itemID), cmdShow)); }
+
+ bool ShowItem_Bool(int itemID, bool show) const
+ { return ShowItem(itemID, show ? SW_SHOW: SW_HIDE); }
+
+ bool HideItem(int itemID) const { return ShowItem(itemID, SW_HIDE); }
+
+ bool SetItemText(int itemID, LPCTSTR s)
+ { return BOOLToBool(SetDlgItemText(_window, itemID, s)); }
+
+ #ifndef _UNICODE
+ bool SetItemText(int itemID, LPCWSTR s)
+ {
+ CWindow window(GetItem(itemID));
+ return window.SetText(s);
+ }
+ #endif
+
+ UINT GetItemText(int itemID, LPTSTR string, int maxCount)
+ { return GetDlgItemText(_window, itemID, string, maxCount); }
+ #ifndef _UNICODE
+ /*
+ bool GetItemText(int itemID, LPWSTR string, int maxCount)
+ {
+ CWindow window(GetItem(itemID));
+ return window.GetText(string, maxCount);
+ }
+ */
+ #endif
+
+ bool SetItemInt(int itemID, UINT value, bool isSigned)
+ { return BOOLToBool(SetDlgItemInt(_window, itemID, value, BoolToBOOL(isSigned))); }
+ bool GetItemInt(int itemID, bool isSigned, UINT &value)
+ {
+ BOOL result;
+ value = GetDlgItemInt(_window, itemID, &result, BoolToBOOL(isSigned));
+ return BOOLToBool(result);
+ }
+
+ HWND GetNextGroupItem(HWND control, bool previous)
+ { return GetNextDlgGroupItem(_window, control, BoolToBOOL(previous)); }
+ HWND GetNextTabItem(HWND control, bool previous)
+ { return GetNextDlgTabItem(_window, control, BoolToBOOL(previous)); }
+
+ bool MapRect(LPRECT rect)
+ { return BOOLToBool(MapDialogRect(_window, rect)); }
+
+ bool IsMessage(LPMSG message)
+ { return BOOLToBool(IsDialogMessage(_window, message)); }
+
+ LRESULT SendItemMessage(int itemID, UINT message, WPARAM wParam, LPARAM lParam)
+ { return SendDlgItemMessage(_window, itemID, message, wParam, lParam); }
+
+ bool CheckButton(int buttonID, UINT checkState)
+ { return BOOLToBool(CheckDlgButton(_window, buttonID, checkState)); }
+ bool CheckButton(int buttonID, bool checkState)
+ { return CheckButton(buttonID, UINT(checkState ? BST_CHECKED : BST_UNCHECKED)); }
+
+ UINT IsButtonChecked(int buttonID) const
+ { return IsDlgButtonChecked(_window, buttonID); }
+ bool IsButtonCheckedBool(int buttonID) const
+ { return (IsButtonChecked(buttonID) == BST_CHECKED); }
+
+ bool CheckRadioButton(int firstButtonID, int lastButtonID, int checkButtonID)
+ { return BOOLToBool(::CheckRadioButton(_window, firstButtonID, lastButtonID, checkButtonID)); }
+
+ virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+ virtual bool OnInit() { return true; }
+ virtual bool OnCommand(WPARAM wParam, LPARAM lParam);
+ virtual bool OnCommand(int code, int itemID, LPARAM lParam);
+ virtual bool OnSize(WPARAM /* wParam */, int /* xSize */, int /* ySize */) { return false; }
+
+ /*
+ #ifdef UNDER_CE
+ virtual void OnHelp(void *) { OnHelp(); }
+ #else
+ virtual void OnHelp(LPHELPINFO) { OnHelp(); }
+ #endif
+ */
+ virtual void OnHelp() {};
+
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnOK() {};
+ virtual void OnCancel() {};
+ virtual bool OnNotify(UINT /* controlID */, LPNMHDR /* lParam */) { return false; }
+ virtual bool OnTimer(WPARAM /* timerID */, LPARAM /* callback */) { return false; }
+
+ LONG_PTR SetMsgResult(LONG_PTR newLongPtr )
+ { return SetLongPtr(DWLP_MSGRESULT, newLongPtr); }
+ LONG_PTR GetMsgResult() const
+ { return GetLongPtr(DWLP_MSGRESULT); }
+
+ bool GetMargins(int margin, int &x, int &y);
+ int Units_To_Pixels_X(int units);
+ bool GetItemSizes(int id, int &x, int &y);
+ void GetClientRectOfItem(int id, RECT &rect);
+ bool MoveItem(int id, int x, int y, int width, int height, bool repaint = true);
+
+ void NormalizeSize(bool fullNormalize = false);
+ void NormalizePosition();
+};
+
+class CModelessDialog: public CDialog
+{
+public:
+ bool Create(LPCTSTR templateName, HWND parentWindow);
+ bool Create(UINT resID, HWND parentWindow) { return Create(MAKEINTRESOURCEW(resID), parentWindow); }
+ #ifndef _UNICODE
+ bool Create(LPCWSTR templateName, HWND parentWindow);
+ #endif
+ virtual void OnOK() { Destroy(); }
+ virtual void OnCancel() { Destroy(); }
+};
+
+class CModalDialog: public CDialog
+{
+public:
+ INT_PTR Create(LPCTSTR templateName, HWND parentWindow);
+ INT_PTR Create(UINT resID, HWND parentWindow) { return Create(MAKEINTRESOURCEW(resID), parentWindow); }
+ #ifndef _UNICODE
+ INT_PTR Create(LPCWSTR templateName, HWND parentWindow);
+ #endif
+
+ bool End(INT_PTR result) { return BOOLToBool(::EndDialog(_window, result)); }
+ virtual void OnOK() { End(IDOK); }
+ virtual void OnCancel() { End(IDCANCEL); }
+};
+
+class CDialogChildControl: public NWindows::CWindow
+{
+ int m_ID;
+public:
+ void Init(const NWindows::NControl::CDialog &parentDialog, int id)
+ {
+ m_ID = id;
+ Attach(parentDialog.GetItem(id));
+ }
+};
+
+bool IsDialogSizeOK(int xSize, int ySize);
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/Edit.h b/3rdparty/lzma/CPP/Windows/Control/Edit.h
new file mode 100644
index 00000000000..51a22c53740
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/Edit.h
@@ -0,0 +1,19 @@
+// Windows/Control/Edit.h
+
+#ifndef __WINDOWS_CONTROL_EDIT_H
+#define __WINDOWS_CONTROL_EDIT_H
+
+#include "../Window.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CEdit: public CWindow
+{
+public:
+ void SetPasswordChar(WPARAM c) { SendMsg(EM_SETPASSWORDCHAR, c); }
+};
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/ImageList.cpp b/3rdparty/lzma/CPP/Windows/Control/ImageList.cpp
new file mode 100644
index 00000000000..3e22b956ed2
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/ImageList.cpp
@@ -0,0 +1,10 @@
+// Windows/Control/ImageList.cpp
+
+#include "StdAfx.h"
+
+#include "ImageList.h"
+
+namespace NWindows {
+namespace NControl {
+
+}}
diff --git a/3rdparty/lzma/CPP/Windows/Control/ImageList.h b/3rdparty/lzma/CPP/Windows/Control/ImageList.h
new file mode 100644
index 00000000000..0d9c9313103
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/ImageList.h
@@ -0,0 +1,87 @@
+// Windows/Control/ImageList.h
+
+#ifndef __WINDOWS_CONTROL_IMAGE_LIST_H
+#define __WINDOWS_CONTROL_IMAGE_LIST_H
+
+#include <commctrl.h>
+
+#include "../Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CImageList
+{
+ HIMAGELIST m_Object;
+public:
+ operator HIMAGELIST() const {return m_Object; }
+ CImageList(): m_Object(NULL) {}
+ bool Attach(HIMAGELIST imageList)
+ {
+ if (imageList == NULL)
+ return false;
+ m_Object = imageList;
+ return true;
+ }
+
+ HIMAGELIST Detach()
+ {
+ HIMAGELIST imageList = m_Object;
+ m_Object = NULL;
+ return imageList;
+ }
+
+ bool Create(int width, int height, UINT flags, int initialNumber, int grow)
+ {
+ HIMAGELIST a = ImageList_Create(width, height, flags,
+ initialNumber, grow);
+ if (a == NULL)
+ return false;
+ return Attach(a);
+ }
+
+ bool Destroy() // DeleteImageList() in MFC
+ {
+ if (m_Object == NULL)
+ return false;
+ return BOOLToBool(ImageList_Destroy(Detach()));
+ }
+
+ ~CImageList()
+ { Destroy(); }
+
+ int GetImageCount() const
+ { return ImageList_GetImageCount(m_Object); }
+
+ bool GetImageInfo(int index, IMAGEINFO* imageInfo) const
+ { return BOOLToBool(ImageList_GetImageInfo(m_Object, index, imageInfo)); }
+
+ int Add(HBITMAP hbmImage, HBITMAP hbmMask = 0)
+ { return ImageList_Add(m_Object, hbmImage, hbmMask); }
+ int AddMasked(HBITMAP hbmImage, COLORREF mask)
+ { return ImageList_AddMasked(m_Object, hbmImage, mask); }
+ int AddIcon(HICON icon)
+ { return ImageList_AddIcon(m_Object, icon); }
+ int Replace(int index, HICON icon)
+ { return ImageList_ReplaceIcon(m_Object, index, icon); }
+
+ // If index is -1, the function removes all images.
+ bool Remove(int index)
+ { return BOOLToBool(ImageList_Remove(m_Object, index)); }
+ bool RemoveAll()
+ { return BOOLToBool(ImageList_RemoveAll(m_Object)); }
+
+ HICON ExtractIcon(int index)
+ { return ImageList_ExtractIcon(NULL, m_Object, index); }
+ HICON GetIcon(int index, UINT flags)
+ { return ImageList_GetIcon(m_Object, index, flags); }
+
+ bool GetIconSize(int &width, int &height) const
+ { return BOOLToBool(ImageList_GetIconSize(m_Object, &width, &height)); }
+ bool SetIconSize(int width, int height)
+ { return BOOLToBool(ImageList_SetIconSize(m_Object, width, height)); }
+};
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/ListView.cpp b/3rdparty/lzma/CPP/Windows/Control/ListView.cpp
new file mode 100644
index 00000000000..6d916591a51
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/ListView.cpp
@@ -0,0 +1,155 @@
+// Windows/Control/ListView.cpp
+
+#include "StdAfx.h"
+
+#include "ListView.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NControl {
+
+bool CListView::CreateEx(DWORD exStyle, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+{
+ return CWindow::CreateEx(exStyle, WC_LISTVIEW, TEXT(""), style, x, y, width,
+ height, parentWindow, idOrHMenu, instance, createParam);
+}
+
+bool CListView::GetItemParam(int index, LPARAM &param) const
+{
+ LVITEM item;
+ item.iItem = index;
+ item.iSubItem = 0;
+ item.mask = LVIF_PARAM;
+ bool aResult = GetItem(&item);
+ param = item.lParam;
+ return aResult;
+}
+
+int CListView::InsertColumn(int columnIndex, LPCTSTR text, int width)
+{
+ LVCOLUMN ci;
+ ci.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
+ ci.pszText = (LPTSTR)text;
+ ci.iSubItem = columnIndex;
+ ci.cx = width;
+ return InsertColumn(columnIndex, &ci);
+}
+
+int CListView::InsertItem(int index, LPCTSTR text)
+{
+ LVITEM item;
+ item.mask = LVIF_TEXT | LVIF_PARAM;
+ item.iItem = index;
+ item.lParam = index;
+ item.pszText = (LPTSTR)text;
+ item.iSubItem = 0;
+ return InsertItem(&item);
+}
+
+int CListView::SetSubItem(int index, int subIndex, LPCTSTR text)
+{
+ LVITEM item;
+ item.mask = LVIF_TEXT;
+ item.iItem = index;
+ item.pszText = (LPTSTR)text;
+ item.iSubItem = subIndex;
+ return SetItem(&item);
+}
+
+#ifndef _UNICODE
+
+int CListView::InsertColumn(int columnIndex, LPCWSTR text, int width)
+{
+ LVCOLUMNW ci;
+ ci.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
+ ci.pszText = (LPWSTR)text;
+ ci.iSubItem = columnIndex;
+ ci.cx = width;
+ return InsertColumn(columnIndex, &ci);
+}
+
+int CListView::InsertItem(int index, LPCWSTR text)
+{
+ LVITEMW item;
+ item.mask = LVIF_TEXT | LVIF_PARAM;
+ item.iItem = index;
+ item.lParam = index;
+ item.pszText = (LPWSTR)text;
+ item.iSubItem = 0;
+ return InsertItem(&item);
+}
+
+int CListView::SetSubItem(int index, int subIndex, LPCWSTR text)
+{
+ LVITEMW item;
+ item.mask = LVIF_TEXT;
+ item.iItem = index;
+ item.pszText = (LPWSTR)text;
+ item.iSubItem = subIndex;
+ return SetItem(&item);
+}
+
+#endif
+
+static LRESULT APIENTRY ListViewSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ CWindow window(hwnd);
+ CListView2 *w = (CListView2 *)(window.GetUserDataLongPtr());
+ if (w == NULL)
+ return 0;
+ return w->OnMessage(message, wParam, lParam);
+}
+
+LRESULT CListView2::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ #ifndef _UNICODE
+ if (g_IsNT)
+ return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam);
+ else
+ #endif
+ return CallWindowProc(_origWindowProc, *this, message, wParam, lParam);
+}
+
+void CListView2::SetWindowProc()
+{
+ SetUserDataLongPtr((LONG_PTR)this);
+ #ifndef _UNICODE
+ if (g_IsNT)
+ _origWindowProc = (WNDPROC)SetLongPtrW(GWLP_WNDPROC, (LONG_PTR)ListViewSubclassProc);
+ else
+ #endif
+ _origWindowProc = (WNDPROC)SetLongPtr(GWLP_WNDPROC, (LONG_PTR)ListViewSubclassProc);
+}
+
+/*
+LRESULT CListView3::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT res = CListView2::OnMessage(message, wParam, lParam);
+ if (message == WM_GETDLGCODE)
+ {
+ // when user presses RETURN, windows sends default (first) button command to parent dialog.
+ // we disable this:
+ MSG *msg = (MSG *)lParam;
+ WPARAM key = wParam;
+ bool change = false;
+ if (msg)
+ {
+ if (msg->message == WM_KEYDOWN && msg->wParam == VK_RETURN)
+ change = true;
+ }
+ else if (wParam == VK_RETURN)
+ change = true;
+ if (change)
+ res |= DLGC_WANTALLKEYS;
+ }
+ return res;
+}
+*/
+
+}}
diff --git a/3rdparty/lzma/CPP/Windows/Control/ListView.h b/3rdparty/lzma/CPP/Windows/Control/ListView.h
new file mode 100644
index 00000000000..9a3abe70fa1
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/ListView.h
@@ -0,0 +1,146 @@
+// Windows/Control/ListView.h
+
+#ifndef __WINDOWS_CONTROL_LISTVIEW_H
+#define __WINDOWS_CONTROL_LISTVIEW_H
+
+#include "../../Common/MyWindows.h"
+
+#include <commctrl.h>
+
+#include "../Window.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CListView: public NWindows::CWindow
+{
+public:
+ bool CreateEx(DWORD exStyle, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam);
+
+ void SetUnicodeFormat()
+ {
+ #ifndef UNDER_CE
+ ListView_SetUnicodeFormat(_window, TRUE);
+ #endif
+ }
+
+ bool DeleteAllItems() { return BOOLToBool(ListView_DeleteAllItems(_window)); }
+ bool DeleteColumn(int columnIndex) { return BOOLToBool(ListView_DeleteColumn(_window, columnIndex)); }
+
+ int InsertColumn(int columnIndex, const LVCOLUMN *columnInfo) { return ListView_InsertColumn(_window, columnIndex, columnInfo); }
+ int InsertColumn(int columnIndex, LPCTSTR text, int width);
+ bool SetColumnOrderArray(int count, const int *columns) { return BOOLToBool(ListView_SetColumnOrderArray(_window, count, columns)); }
+
+ /*
+ int GetNumColumns()
+ {
+ HWND header = ListView_GetHeader(_window);
+ if (!header)
+ return -1;
+ return Header_GetItemCount(header);
+ }
+ */
+
+ int InsertItem(const LVITEM* item) { return ListView_InsertItem(_window, item); }
+ int InsertItem(int index, LPCTSTR text);
+ bool SetItem(const LVITEM* item) { return BOOLToBool(ListView_SetItem(_window, item)); }
+ int SetSubItem(int index, int subIndex, LPCTSTR text);
+
+ #ifndef _UNICODE
+
+ int InsertColumn(int columnIndex, const LVCOLUMNW *columnInfo) { return (int)SendMsg(LVM_INSERTCOLUMNW, (WPARAM)columnIndex, (LPARAM)columnInfo); }
+ int InsertColumn(int columnIndex, LPCWSTR text, int width);
+ int InsertItem(const LV_ITEMW* item) { return (int)SendMsg(LVM_INSERTITEMW, 0, (LPARAM)item); }
+ int InsertItem(int index, LPCWSTR text);
+ bool SetItem(const LV_ITEMW* item) { return BOOLToBool((BOOL)SendMsg(LVM_SETITEMW, 0, (LPARAM)item)); }
+ int SetSubItem(int index, int subIndex, LPCWSTR text);
+
+ #endif
+
+ bool DeleteItem(int itemIndex) { return BOOLToBool(ListView_DeleteItem(_window, itemIndex)); }
+
+ UINT GetSelectedCount() const { return ListView_GetSelectedCount(_window); }
+ int GetItemCount() const { return ListView_GetItemCount(_window); }
+
+ INT GetSelectionMark() const { return ListView_GetSelectionMark(_window); }
+
+ void SetItemCount(int numItems) { ListView_SetItemCount(_window, numItems); }
+ void SetItemCountEx(int numItems, DWORD flags) { ListView_SetItemCountEx(_window, numItems, flags); }
+
+ int GetNextItem(int startIndex, UINT flags) const { return ListView_GetNextItem(_window, startIndex, flags); }
+ int GetNextSelectedItem(int startIndex) const { return GetNextItem(startIndex, LVNI_SELECTED); }
+ int GetFocusedItem() const { return GetNextItem(-1, LVNI_FOCUSED); }
+
+ bool GetItem(LVITEM* item) const { return BOOLToBool(ListView_GetItem(_window, item)); }
+ bool GetItemParam(int itemIndex, LPARAM &param) const;
+ void GetItemText(int itemIndex, int subItemIndex, LPTSTR text, int textSizeMax) const
+ { ListView_GetItemText(_window, itemIndex, subItemIndex, text, textSizeMax); }
+ bool SortItems(PFNLVCOMPARE compareFunction, LPARAM dataParam)
+ { return BOOLToBool(ListView_SortItems(_window, compareFunction, dataParam)); }
+
+ void SetItemState(int index, UINT state, UINT mask) { ListView_SetItemState(_window, index, state, mask); }
+ void SetItemState_Selected(int index, bool select) { SetItemState(index, select ? LVIS_SELECTED : 0, LVIS_SELECTED); }
+ void SetItemState_Selected(int index) { SetItemState(index, LVIS_SELECTED, LVIS_SELECTED); }
+ void SelectAll() { SetItemState_Selected(-1); }
+ void SetItemState_FocusedSelected(int index) { SetItemState(index, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); }
+ UINT GetItemState(int index, UINT mask) const { return ListView_GetItemState(_window, index, mask); }
+ bool IsItemSelected(int index) const { return GetItemState(index, LVIS_SELECTED) == LVIS_SELECTED; }
+
+ bool GetColumn(int columnIndex, LVCOLUMN* columnInfo) const
+ { return BOOLToBool(ListView_GetColumn(_window, columnIndex, columnInfo)); }
+
+ HIMAGELIST SetImageList(HIMAGELIST imageList, int imageListType)
+ { return ListView_SetImageList(_window, imageList, imageListType); }
+
+ // version 4.70: NT5 | (NT4 + ie3) | w98 | (w95 + ie3)
+ DWORD GetExtendedListViewStyle() { return ListView_GetExtendedListViewStyle(_window); }
+ void SetExtendedListViewStyle(DWORD exStyle) { ListView_SetExtendedListViewStyle(_window, exStyle); }
+ void SetExtendedListViewStyle(DWORD exMask, DWORD exStyle) { ListView_SetExtendedListViewStyleEx(_window, exMask, exStyle); }
+
+ void SetCheckState(UINT index, bool checkState) { ListView_SetCheckState(_window, index, BoolToBOOL(checkState)); }
+ bool GetCheckState(UINT index) { return BOOLToBool(ListView_GetCheckState(_window, index)); }
+
+ bool EnsureVisible(int index, bool partialOK) { return BOOLToBool(ListView_EnsureVisible(_window, index, BoolToBOOL(partialOK))); }
+
+ bool GetItemRect(int index, RECT *rect, int code) { return BOOLToBool(ListView_GetItemRect(_window, index, rect, code)); }
+
+ HWND GetEditControl() { return ListView_GetEditControl(_window) ; }
+ HWND EditLabel(int itemIndex) { return ListView_EditLabel(_window, itemIndex) ; }
+
+ bool RedrawItems(int firstIndex, int lastIndex) { return BOOLToBool(ListView_RedrawItems(_window, firstIndex, lastIndex)); }
+ bool RedrawAllItems()
+ {
+ if (GetItemCount() > 0)
+ return RedrawItems(0, GetItemCount() - 1);
+ return true;
+ }
+ bool RedrawItem(int index) { return RedrawItems(index, index); }
+
+ int HitTest(LPLVHITTESTINFO info) { return ListView_HitTest(_window, info); }
+ COLORREF GetBkColor() { return ListView_GetBkColor(_window); }
+ bool SetColumnWidth(int iCol, int cx) { return BOOLToBool(ListView_SetColumnWidth(_window, iCol, cx)); }
+ bool SetColumnWidthAuto(int iCol) { return SetColumnWidth(iCol, LVSCW_AUTOSIZE); }
+};
+
+class CListView2: public CListView
+{
+ WNDPROC _origWindowProc;
+public:
+ void SetWindowProc();
+ virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+};
+
+/*
+class CListView3: public CListView2
+{
+public:
+ virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+};
+*/
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/ProgressBar.h b/3rdparty/lzma/CPP/Windows/Control/ProgressBar.h
new file mode 100644
index 00000000000..38ebcb6131b
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/ProgressBar.h
@@ -0,0 +1,35 @@
+// Windows/Control/ProgressBar.h
+
+#ifndef __WINDOWS_CONTROL_PROGRESSBAR_H
+#define __WINDOWS_CONTROL_PROGRESSBAR_H
+
+#include "../../Common/MyWindows.h"
+
+#include <commctrl.h>
+
+#include "../Window.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CProgressBar: public CWindow
+{
+public:
+ LRESULT SetPos(int pos) { return SendMsg(PBM_SETPOS, pos, 0); }
+ LRESULT DeltaPos(int increment) { return SendMsg(PBM_DELTAPOS, increment, 0); }
+ UINT GetPos() { return (UINT)SendMsg(PBM_GETPOS, 0, 0); }
+ LRESULT SetRange(unsigned short minValue, unsigned short maxValue) { return SendMsg(PBM_SETRANGE, 0, MAKELPARAM(minValue, maxValue)); }
+ DWORD SetRange32(int minValue, int maxValue) { return (DWORD)SendMsg(PBM_SETRANGE32, minValue, maxValue); }
+ int SetStep(int step) { return (int)SendMsg(PBM_SETSTEP, step, 0); }
+ LRESULT StepIt() { return SendMsg(PBM_STEPIT, 0, 0); }
+ INT GetRange(bool minValue, PPBRANGE range) { return (INT)SendMsg(PBM_GETRANGE, BoolToBOOL(minValue), (LPARAM)range); }
+
+ #ifndef UNDER_CE
+ COLORREF SetBarColor(COLORREF color) { return (COLORREF)SendMsg(PBM_SETBARCOLOR, 0, color); }
+ COLORREF SetBackgroundColor(COLORREF color) { return (COLORREF)SendMsg(PBM_SETBKCOLOR, 0, color); }
+ #endif
+};
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/PropertyPage.cpp b/3rdparty/lzma/CPP/Windows/Control/PropertyPage.cpp
new file mode 100644
index 00000000000..bbac74ad732
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/PropertyPage.cpp
@@ -0,0 +1,143 @@
+// Windows/Control/PropertyPage.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "../../Common/StringConvert.h"
+#endif
+
+#include "PropertyPage.h"
+
+extern HINSTANCE g_hInstance;
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NControl {
+
+static INT_PTR APIENTRY MyProperyPageProcedure(HWND dialogHWND, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ CWindow tempDialog(dialogHWND);
+ if (message == WM_INITDIALOG)
+ tempDialog.SetUserDataLongPtr(((PROPSHEETPAGE *)lParam)->lParam);
+ CDialog *dialog = (CDialog *)(tempDialog.GetUserDataLongPtr());
+ if (dialog == NULL)
+ return FALSE;
+ if (message == WM_INITDIALOG)
+ dialog->Attach(dialogHWND);
+ try { return BoolToBOOL(dialog->OnMessage(message, wParam, lParam)); }
+ catch(...) { return TRUE; }
+}
+
+bool CPropertyPage::OnNotify(UINT /* controlID */, LPNMHDR lParam)
+{
+ switch (lParam->code)
+ {
+ case PSN_APPLY: SetMsgResult(OnApply(LPPSHNOTIFY(lParam))); break;
+ case PSN_KILLACTIVE: SetMsgResult(BoolToBOOL(OnKillActive(LPPSHNOTIFY(lParam)))); break;
+ case PSN_SETACTIVE: SetMsgResult(OnSetActive(LPPSHNOTIFY(lParam))); break;
+ case PSN_RESET: OnReset(LPPSHNOTIFY(lParam)); break;
+ case PSN_HELP: OnNotifyHelp(LPPSHNOTIFY(lParam)); break;
+ default: return false;
+ }
+ return true;
+}
+
+INT_PTR MyPropertySheet(const CObjectVector<CPageInfo> &pagesInfo, HWND hwndParent, const UString &title)
+{
+ #ifndef _UNICODE
+ AStringVector titles;
+ #endif
+ #ifndef _UNICODE
+ CRecordVector<PROPSHEETPAGEA> pagesA;
+ #endif
+ CRecordVector<PROPSHEETPAGEW> pagesW;
+
+ unsigned i;
+ #ifndef _UNICODE
+ for (i = 0; i < pagesInfo.Size(); i++)
+ titles.Add(GetSystemString(pagesInfo[i].Title));
+ #endif
+
+ for (i = 0; i < pagesInfo.Size(); i++)
+ {
+ const CPageInfo &pageInfo = pagesInfo[i];
+ #ifndef _UNICODE
+ {
+ PROPSHEETPAGE page;
+ page.dwSize = sizeof(page);
+ page.dwFlags = PSP_HASHELP;
+ page.hInstance = g_hInstance;
+ page.pszTemplate = MAKEINTRESOURCE(pageInfo.ID);
+ page.pszIcon = NULL;
+ page.pfnDlgProc = NWindows::NControl::MyProperyPageProcedure;
+
+ if (titles[i].IsEmpty())
+ page.pszTitle = NULL;
+ else
+ {
+ page.dwFlags |= PSP_USETITLE;
+ page.pszTitle = titles[i];
+ }
+ page.lParam = (LPARAM)pageInfo.Page;
+ page.pfnCallback = NULL;
+ pagesA.Add(page);
+ }
+ #endif
+ {
+ PROPSHEETPAGEW page;
+ page.dwSize = sizeof(page);
+ page.dwFlags = PSP_HASHELP;
+ page.hInstance = g_hInstance;
+ page.pszTemplate = MAKEINTRESOURCEW(pageInfo.ID);
+ page.pszIcon = NULL;
+ page.pfnDlgProc = NWindows::NControl::MyProperyPageProcedure;
+
+ if (pageInfo.Title.IsEmpty())
+ page.pszTitle = NULL;
+ else
+ {
+ page.dwFlags |= PSP_USETITLE;
+ page.pszTitle = pageInfo.Title;
+ }
+ page.lParam = (LPARAM)pageInfo.Page;
+ page.pfnCallback = NULL;
+ pagesW.Add(page);
+ }
+ }
+
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ PROPSHEETHEADER sheet;
+ sheet.dwSize = sizeof(sheet);
+ sheet.dwFlags = PSH_PROPSHEETPAGE;
+ sheet.hwndParent = hwndParent;
+ sheet.hInstance = g_hInstance;
+ AString titleA = GetSystemString(title);
+ sheet.pszCaption = titleA;
+ sheet.nPages = pagesInfo.Size();
+ sheet.nStartPage = 0;
+ sheet.ppsp = &pagesA.Front();
+ sheet.pfnCallback = NULL;
+ return ::PropertySheetA(&sheet);
+ }
+ else
+ #endif
+ {
+ PROPSHEETHEADERW sheet;
+ sheet.dwSize = sizeof(sheet);
+ sheet.dwFlags = PSH_PROPSHEETPAGE;
+ sheet.hwndParent = hwndParent;
+ sheet.hInstance = g_hInstance;
+ sheet.pszCaption = title;
+ sheet.nPages = pagesInfo.Size();
+ sheet.nStartPage = 0;
+ sheet.ppsp = &pagesW.Front();
+ sheet.pfnCallback = NULL;
+ return ::PropertySheetW(&sheet);
+ }
+}
+
+}}
diff --git a/3rdparty/lzma/CPP/Windows/Control/PropertyPage.h b/3rdparty/lzma/CPP/Windows/Control/PropertyPage.h
new file mode 100644
index 00000000000..4c4ddad9113
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/PropertyPage.h
@@ -0,0 +1,50 @@
+// Windows/Control/PropertyPage.h
+
+#ifndef __WINDOWS_CONTROL_PROPERTYPAGE_H
+#define __WINDOWS_CONTROL_PROPERTYPAGE_H
+
+#include "../../Common/MyWindows.h"
+
+#include <prsht.h>
+
+#include "Dialog.h"
+
+namespace NWindows {
+namespace NControl {
+
+INT_PTR APIENTRY ProperyPageProcedure(HWND dialogHWND, UINT message, WPARAM wParam, LPARAM lParam);
+
+class CPropertyPage: public CDialog
+{
+public:
+ CPropertyPage(HWND window = NULL): CDialog(window){};
+
+ void Changed() { PropSheet_Changed(GetParent(), (HWND)*this); }
+ void UnChanged() { PropSheet_UnChanged(GetParent(), (HWND)*this); }
+
+ virtual bool OnNotify(UINT controlID, LPNMHDR lParam);
+
+ virtual bool OnKillActive() { return false; } // false = OK
+ virtual bool OnKillActive(const PSHNOTIFY *) { return OnKillActive(); }
+ virtual LONG OnSetActive() { return false; } // false = OK
+ virtual LONG OnSetActive(const PSHNOTIFY *) { return OnSetActive(); }
+ virtual LONG OnApply() { return PSNRET_NOERROR; }
+ virtual LONG OnApply(const PSHNOTIFY *) { return OnApply(); }
+ virtual void OnNotifyHelp() {}
+ virtual void OnNotifyHelp(const PSHNOTIFY *) { OnNotifyHelp(); }
+ virtual void OnReset() {}
+ virtual void OnReset(const PSHNOTIFY *) { OnReset(); }
+};
+
+struct CPageInfo
+{
+ CPropertyPage *Page;
+ UString Title;
+ UINT ID;
+};
+
+INT_PTR MyPropertySheet(const CObjectVector<CPageInfo> &pagesInfo, HWND hwndParent, const UString &title);
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/ReBar.h b/3rdparty/lzma/CPP/Windows/Control/ReBar.h
new file mode 100644
index 00000000000..c2d58dbe80d
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/ReBar.h
@@ -0,0 +1,34 @@
+// Windows/Control/ReBar.h
+
+#ifndef __WINDOWS_CONTROL_REBAR_H
+#define __WINDOWS_CONTROL_REBAR_H
+
+#include "../Window.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CReBar: public NWindows::CWindow
+{
+public:
+ bool SetBarInfo(LPREBARINFO barInfo)
+ { return LRESULTToBool(SendMsg(RB_SETBARINFO, 0, (LPARAM)barInfo)); }
+ bool InsertBand(int index, LPREBARBANDINFO bandInfo)
+ { return LRESULTToBool(SendMsg(RB_INSERTBAND, index, (LPARAM)bandInfo)); }
+ bool SetBandInfo(unsigned index, LPREBARBANDINFO bandInfo)
+ { return LRESULTToBool(SendMsg(RB_SETBANDINFO, index, (LPARAM)bandInfo)); }
+ void MaximizeBand(unsigned index, bool ideal)
+ { SendMsg(RB_MAXIMIZEBAND, index, BoolToBOOL(ideal)); }
+ bool SizeToRect(LPRECT rect)
+ { return LRESULTToBool(SendMsg(RB_SIZETORECT, 0, (LPARAM)rect)); }
+ UINT GetHeight()
+ { return (UINT)SendMsg(RB_GETBARHEIGHT); }
+ UINT GetBandCount()
+ { return (UINT)SendMsg(RB_GETBANDCOUNT); }
+ bool DeleteBand(UINT index)
+ { return LRESULTToBool(SendMsg(RB_DELETEBAND, index)); }
+};
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/Static.h b/3rdparty/lzma/CPP/Windows/Control/Static.h
new file mode 100644
index 00000000000..5523b2e633e
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/Static.h
@@ -0,0 +1,28 @@
+// Windows/Control/Static.h
+
+#ifndef __WINDOWS_CONTROL_STATIC_H
+#define __WINDOWS_CONTROL_STATIC_H
+
+#include "../Window.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CStatic: public CWindow
+{
+public:
+ HANDLE SetImage(WPARAM imageType, HANDLE handle) { return (HANDLE)SendMsg(STM_SETIMAGE, imageType, (LPARAM)handle); }
+ HANDLE GetImage(WPARAM imageType) { return (HANDLE)SendMsg(STM_GETIMAGE, imageType, 0); }
+
+ #ifdef UNDER_CE
+ HICON SetIcon(HICON icon) { return (HICON)SetImage(IMAGE_ICON, icon); }
+ HICON GetIcon() { return (HICON)GetImage(IMAGE_ICON); }
+ #else
+ HICON SetIcon(HICON icon) { return (HICON)SendMsg(STM_SETICON, (WPARAM)icon, 0); }
+ HICON GetIcon() { return (HICON)SendMsg(STM_GETICON, 0, 0); }
+ #endif
+};
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/StatusBar.h b/3rdparty/lzma/CPP/Windows/Control/StatusBar.h
new file mode 100644
index 00000000000..988b84700b4
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/StatusBar.h
@@ -0,0 +1,42 @@
+// Windows/Control/StatusBar.h
+
+#ifndef __WINDOWS_CONTROL_STATUSBAR_H
+#define __WINDOWS_CONTROL_STATUSBAR_H
+
+#include "../Window.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CStatusBar: public NWindows::CWindow
+{
+public:
+ bool Create(LONG style, LPCTSTR text, HWND hwndParent, UINT id)
+ { return (_window = ::CreateStatusWindow(style, text, hwndParent, id)) != 0; }
+ bool SetText(LPCTSTR text)
+ { return CWindow::SetText(text); }
+ bool SetText(unsigned index, LPCTSTR text, UINT type)
+ { return LRESULTToBool(SendMsg(SB_SETTEXT, index | type, (LPARAM)text)); }
+ bool SetText(unsigned index, LPCTSTR text)
+ { return SetText(index, text, 0); }
+
+ #ifndef _UNICODE
+ bool Create(LONG style, LPCWSTR text, HWND hwndParent, UINT id)
+ { return (_window = ::CreateStatusWindowW(style, text, hwndParent, id)) != 0; }
+ bool SetText(LPCWSTR text)
+ { return CWindow::SetText(text); }
+ bool SetText(unsigned index, LPCWSTR text, UINT type)
+ { return LRESULTToBool(SendMsg(SB_SETTEXTW, index | type, (LPARAM)text)); }
+ bool SetText(unsigned index, LPCWSTR text)
+ { return SetText(index, text, 0); }
+ #endif
+
+ bool SetParts(unsigned numParts, const int *edgePostions)
+ { return LRESULTToBool(SendMsg(SB_SETPARTS, numParts, (LPARAM)edgePostions)); }
+ void Simple(bool simple)
+ { SendMsg(SB_SIMPLE, BoolToBOOL(simple), 0); }
+};
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/StdAfx.h b/3rdparty/lzma/CPP/Windows/Control/StdAfx.h
new file mode 100644
index 00000000000..1cbd7feaeec
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../Common/Common.h"
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/ToolBar.h b/3rdparty/lzma/CPP/Windows/Control/ToolBar.h
new file mode 100644
index 00000000000..7bc93a24170
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/ToolBar.h
@@ -0,0 +1,43 @@
+// Windows/Control/ToolBar.h
+
+#ifndef __WINDOWS_CONTROL_TOOLBAR_H
+#define __WINDOWS_CONTROL_TOOLBAR_H
+
+#include "../Window.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CToolBar: public NWindows::CWindow
+{
+public:
+ void AutoSize() { SendMsg(TB_AUTOSIZE, 0, 0); }
+ DWORD GetButtonSize() { return (DWORD)SendMsg(TB_GETBUTTONSIZE, 0, 0); }
+
+ bool GetMaxSize(LPSIZE size)
+ #ifdef UNDER_CE
+ {
+ // maybe it must be fixed for more than 1 buttons
+ DWORD val = GetButtonSize();
+ size->cx = LOWORD(val);
+ size->cy = HIWORD(val);
+ return true;
+ }
+ #else
+ {
+ return LRESULTToBool(SendMsg(TB_GETMAXSIZE, 0, (LPARAM)size));
+ }
+ #endif
+
+ bool EnableButton(UINT buttonID, bool enable) { return LRESULTToBool(SendMsg(TB_ENABLEBUTTON, buttonID, MAKELONG(BoolToBOOL(enable), 0))); }
+ void ButtonStructSize() { SendMsg(TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON)); }
+ HIMAGELIST SetImageList(UINT listIndex, HIMAGELIST imageList) { return HIMAGELIST(SendMsg(TB_SETIMAGELIST, listIndex, (LPARAM)imageList)); }
+ bool AddButton(UINT numButtons, LPTBBUTTON buttons) { return LRESULTToBool(SendMsg(TB_ADDBUTTONS, numButtons, (LPARAM)buttons)); }
+ #ifndef _UNICODE
+ bool AddButtonW(UINT numButtons, LPTBBUTTON buttons) { return LRESULTToBool(SendMsg(TB_ADDBUTTONSW, numButtons, (LPARAM)buttons)); }
+ #endif
+};
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/Trackbar.h b/3rdparty/lzma/CPP/Windows/Control/Trackbar.h
new file mode 100644
index 00000000000..313e0c851b6
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/Trackbar.h
@@ -0,0 +1,27 @@
+// Windows/Control/Trackbar.h
+
+#ifndef __WINDOWS_CONTROL_TRACKBAR_H
+#define __WINDOWS_CONTROL_TRACKBAR_H
+
+#include "../Window.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CTrackbar: public CWindow
+{
+public:
+ void SetRange(int minimum, int maximum, bool redraw = true)
+ { SendMsg(TBM_SETRANGE, BoolToBOOL(redraw), MAKELONG(minimum, maximum)); }
+ void SetPos(int pos, bool redraw = true)
+ { SendMsg(TBM_SETPOS, BoolToBOOL(redraw), pos); }
+ void SetTicFreq(int freq)
+ { SendMsg(TBM_SETTICFREQ, freq); }
+
+ int GetPos()
+ { return (int)SendMsg(TBM_GETPOS); }
+};
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Control/Window2.cpp b/3rdparty/lzma/CPP/Windows/Control/Window2.cpp
new file mode 100644
index 00000000000..994d96e080a
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/Window2.cpp
@@ -0,0 +1,200 @@
+// Windows/Control/Window2.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "../../Common/StringConvert.h"
+#endif
+
+#include "Window2.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+
+#ifndef _UNICODE
+ATOM MyRegisterClass(CONST WNDCLASSW *wndClass);
+#endif
+
+namespace NControl {
+
+#ifdef UNDER_CE
+#define MY_START_WM_CREATE WM_CREATE
+#else
+#define MY_START_WM_CREATE WM_NCCREATE
+#endif
+
+static LRESULT CALLBACK WindowProcedure(HWND aHWND, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ CWindow tempWindow(aHWND);
+ if (message == MY_START_WM_CREATE)
+ tempWindow.SetUserDataLongPtr((LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams));
+ CWindow2 *window = (CWindow2 *)(tempWindow.GetUserDataLongPtr());
+ if (window != NULL && message == MY_START_WM_CREATE)
+ window->Attach(aHWND);
+ if (window == 0)
+ {
+ #ifndef _UNICODE
+ if (g_IsNT)
+ return DefWindowProcW(aHWND, message, wParam, lParam);
+ else
+ #endif
+ return DefWindowProc(aHWND, message, wParam, lParam);
+ }
+ return window->OnMessage(message, wParam, lParam);
+}
+
+bool CWindow2::CreateEx(DWORD exStyle, LPCTSTR className, LPCTSTR windowName,
+ DWORD style, int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu, HINSTANCE instance)
+{
+ WNDCLASS wc;
+ if (!::GetClassInfo(instance, className, &wc))
+ {
+ // wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.style = 0;
+ wc.lpfnWndProc = WindowProcedure;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = instance;
+ wc.hIcon = NULL;
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = className;
+ if (::RegisterClass(&wc) == 0)
+ return false;
+ }
+ return CWindow::CreateEx(exStyle, className, windowName, style,
+ x, y, width, height, parentWindow, idOrHMenu, instance, this);
+}
+
+#ifndef _UNICODE
+
+bool CWindow2::CreateEx(DWORD exStyle, LPCWSTR className, LPCWSTR windowName,
+ DWORD style, int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu, HINSTANCE instance)
+{
+ bool needRegister;
+ if (g_IsNT)
+ {
+ WNDCLASSW wc;
+ needRegister = ::GetClassInfoW(instance, className, &wc) == 0;
+ }
+ else
+ {
+ WNDCLASSA windowClassA;
+ AString classNameA;
+ LPCSTR classNameP;
+ if (IS_INTRESOURCE(className))
+ classNameP = (LPCSTR)className;
+ else
+ {
+ classNameA = GetSystemString(className);
+ classNameP = classNameA;
+ }
+ needRegister = ::GetClassInfoA(instance, classNameP, &windowClassA) == 0;
+ }
+ if (needRegister)
+ {
+ WNDCLASSW wc;
+ // wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.style = 0;
+ wc.lpfnWndProc = WindowProcedure;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = instance;
+ wc.hIcon = NULL;
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = className;
+ if (MyRegisterClass(&wc) == 0)
+ return false;
+ }
+ return CWindow::CreateEx(exStyle, className, windowName, style,
+ x, y, width, height, parentWindow, idOrHMenu, instance, this);
+}
+
+#endif
+
+LRESULT CWindow2::DefProc(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ #ifndef _UNICODE
+ if (g_IsNT)
+ return DefWindowProcW(_window, message, wParam, lParam);
+ else
+ #endif
+ return DefWindowProc(_window, message, wParam, lParam);
+}
+
+LRESULT CWindow2::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT result;
+ switch (message)
+ {
+ case WM_CREATE:
+ if (!OnCreate((CREATESTRUCT *)lParam))
+ return -1;
+ break;
+ case WM_COMMAND:
+ if (OnCommand(wParam, lParam, result))
+ return result;
+ break;
+ case WM_NOTIFY:
+ if (OnNotify((UINT)wParam, (LPNMHDR) lParam, result))
+ return result;
+ break;
+ case WM_DESTROY:
+ OnDestroy();
+ break;
+ case WM_CLOSE:
+ OnClose();
+ return 0;
+ case WM_SIZE:
+ if (OnSize(wParam, LOWORD(lParam), HIWORD(lParam)))
+ return 0;
+ }
+ return DefProc(message, wParam, lParam);
+}
+
+bool CWindow2::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT &result)
+{
+ return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam, result);
+}
+
+bool CWindow2::OnCommand(int /* code */, int /* itemID */, LPARAM /* lParam */, LRESULT & /* result */)
+{
+ return false;
+ // return DefProc(message, wParam, lParam);
+ /*
+ if (code == BN_CLICKED)
+ return OnButtonClicked(itemID, (HWND)lParam);
+ */
+}
+
+/*
+bool CDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch (buttonID)
+ {
+ case IDOK:
+ OnOK();
+ break;
+ case IDCANCEL:
+ OnCancel();
+ break;
+ case IDHELP:
+ OnHelp();
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+*/
+
+}}
diff --git a/3rdparty/lzma/CPP/Windows/Control/Window2.h b/3rdparty/lzma/CPP/Windows/Control/Window2.h
new file mode 100644
index 00000000000..7ac580cb071
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Control/Window2.h
@@ -0,0 +1,51 @@
+// Windows/Control/Window2.h
+
+#ifndef __WINDOWS_CONTROL_WINDOW2_H
+#define __WINDOWS_CONTROL_WINDOW2_H
+
+#include "../Window.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CWindow2: public CWindow
+{
+ LRESULT DefProc(UINT message, WPARAM wParam, LPARAM lParam);
+public:
+ CWindow2(HWND newWindow = NULL): CWindow(newWindow){};
+ virtual ~CWindow2() {};
+
+ bool CreateEx(DWORD exStyle, LPCTSTR className, LPCTSTR windowName,
+ DWORD style, int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu, HINSTANCE instance);
+
+ #ifndef _UNICODE
+ bool CreateEx(DWORD exStyle, LPCWSTR className, LPCWSTR windowName,
+ DWORD style, int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu, HINSTANCE instance);
+ #endif
+
+ virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+ virtual bool OnCreate(CREATESTRUCT * /* createStruct */) { return true; }
+ // virtual LRESULT OnCommand(WPARAM wParam, LPARAM lParam);
+ virtual bool OnCommand(WPARAM wParam, LPARAM lParam, LRESULT &result);
+ virtual bool OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result);
+ virtual bool OnSize(WPARAM /* wParam */, int /* xSize */, int /* ySize */) { return false; }
+ virtual bool OnNotify(UINT /* controlID */, LPNMHDR /* lParam */, LRESULT & /* result */) { return false; }
+ virtual void OnDestroy() { PostQuitMessage(0); }
+ virtual void OnClose() { Destroy(); }
+ /*
+ virtual LRESULT OnHelp(LPHELPINFO helpInfo) { OnHelp(); }
+ virtual LRESULT OnHelp() {};
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnOK() {};
+ virtual void OnCancel() {};
+ */
+
+ LONG_PTR SetMsgResult(LONG_PTR newLongPtr) { return SetLongPtr(DWLP_MSGRESULT, newLongPtr); }
+ LONG_PTR GetMsgResult() const { return GetLongPtr(DWLP_MSGRESULT); }
+};
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/DLL.cpp b/3rdparty/lzma/CPP/Windows/DLL.cpp
index 81eec692182..a71a8017b87 100644
--- a/3rdparty/lzma/CPP/Windows/DLL.cpp
+++ b/3rdparty/lzma/CPP/Windows/DLL.cpp
@@ -13,7 +13,7 @@ extern HINSTANCE g_hInstance;
namespace NWindows {
namespace NDLL {
-bool CLibrary::Free()
+bool CLibrary::Free() throw()
{
if (_module == 0)
return true;
@@ -23,7 +23,7 @@ bool CLibrary::Free()
return true;
}
-bool CLibrary::LoadEx(CFSTR path, DWORD flags)
+bool CLibrary::LoadEx(CFSTR path, DWORD flags) throw()
{
if (!Free())
return false;
@@ -40,7 +40,7 @@ bool CLibrary::LoadEx(CFSTR path, DWORD flags)
return (_module != NULL);
}
-bool CLibrary::Load(CFSTR path)
+bool CLibrary::Load(CFSTR path) throw()
{
if (!Free())
return false;
@@ -93,11 +93,14 @@ bool MyGetModuleFileName(FString &path)
FString GetModuleDirPrefix()
{
FString s;
- if (NDLL::MyGetModuleFileName(s))
+ if (MyGetModuleFileName(s))
{
- int pos = s.ReverseFind(FCHAR_PATH_SEPARATOR);
+ int pos = s.ReverseFind_PathSepar();
if (pos >= 0)
- return s.Left(pos + 1);
+ {
+ s.DeleteFrom(pos + 1);
+ return s;
+ }
}
return FTEXT(".") FSTRING_PATH_SEPARATOR;
}
diff --git a/3rdparty/lzma/CPP/Windows/DLL.h b/3rdparty/lzma/CPP/Windows/DLL.h
index 9f0f5cd72f6..984a1d33b58 100644
--- a/3rdparty/lzma/CPP/Windows/DLL.h
+++ b/3rdparty/lzma/CPP/Windows/DLL.h
@@ -13,17 +13,23 @@ namespace NDLL {
#else
#define My_GetProcAddress(module, procName) ::GetProcAddress(module, procName)
#endif
-
+
+/* Win32: Don't call CLibrary::Free() and FreeLibrary() from another
+ FreeLibrary() code: detaching code in DLL entry-point or in
+ destructors of global objects in DLL module. */
+
class CLibrary
{
HMODULE _module;
+
+ // CLASS_NO_COPY(CLibrary);
public:
CLibrary(): _module(NULL) {};
~CLibrary() { Free(); }
operator HMODULE() const { return _module; }
HMODULE* operator&() { return &_module; }
- bool IsLoaded() const { return (_module != NULL); };
+ bool IsLoaded() const { return (_module != NULL); }
void Attach(HMODULE m)
{
@@ -37,9 +43,9 @@ public:
return m;
}
- bool Free();
- bool LoadEx(CFSTR path, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
- bool Load(CFSTR path);
+ bool Free() throw();
+ bool LoadEx(CFSTR path, DWORD flags = LOAD_LIBRARY_AS_DATAFILE) throw();
+ bool Load(CFSTR path) throw();
FARPROC GetProc(LPCSTR procName) const { return My_GetProcAddress(_module, procName); }
};
diff --git a/3rdparty/lzma/CPP/Windows/Error.h b/3rdparty/lzma/CPP/Windows/Error.h
deleted file mode 100644
index b7da3ca5e95..00000000000
--- a/3rdparty/lzma/CPP/Windows/Error.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Windows/Error.h
-
-#ifndef __WINDOWS_ERROR_H
-#define __WINDOWS_ERROR_H
-
-#include "Common/MyString.h"
-
-namespace NWindows {
-namespace NError {
-
-UString MyFormatMessageW(DWORD errorCode);
-
-}}
-
-#endif
diff --git a/3rdparty/lzma/CPP/Windows/Error.cpp b/3rdparty/lzma/CPP/Windows/ErrorMsg.cpp
index c02e3b9e59a..c9de4a6c0a7 100644
--- a/3rdparty/lzma/CPP/Windows/Error.cpp
+++ b/3rdparty/lzma/CPP/Windows/ErrorMsg.cpp
@@ -1,12 +1,13 @@
-// Windows/Error.h
+// Windows/ErrorMsg.h
#include "StdAfx.h"
-#include "Windows/Error.h"
#ifndef _UNICODE
-#include "Common/StringConvert.h"
+#include "../Common/StringConvert.h"
#endif
+#include "ErrorMsg.h"
+
#ifndef _UNICODE
extern bool g_IsNT;
#endif
@@ -39,22 +40,27 @@ static bool MyFormatMessage(DWORD errorCode, UString &message)
return true;
}
-UString MyFormatMessageW(DWORD errorCode)
+UString MyFormatMessage(DWORD errorCode)
{
- UString message;
- if (!MyFormatMessage(errorCode, message))
+ UString m;
+ if (!MyFormatMessage(errorCode, m) || m.IsEmpty())
{
- wchar_t s[16];
+ char s[16];
for (int i = 0; i < 8; i++)
{
- int t = errorCode & 0xF;
+ unsigned t = errorCode & 0xF;
errorCode >>= 4;
- s[7 - i] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
- s[8] = '\0';
- message = (UString)L"Error #" + s;
+ s[8] = 0;
+ m.AddAscii("Error #");
+ m.AddAscii(s);
}
- return message;
+ else if (m.Len() >= 2
+ && m[m.Len() - 1] == 0x0A
+ && m[m.Len() - 2] == 0x0D)
+ m.DeleteFrom(m.Len() - 2);
+ return m;
}
}}
diff --git a/3rdparty/lzma/CPP/Windows/ErrorMsg.h b/3rdparty/lzma/CPP/Windows/ErrorMsg.h
new file mode 100644
index 00000000000..0957c696ad1
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/ErrorMsg.h
@@ -0,0 +1,15 @@
+// Windows/ErrorMsg.h
+
+#ifndef __WINDOWS_ERROR_MSG_H
+#define __WINDOWS_ERROR_MSG_H
+
+#include "../Common/MyString.h"
+
+namespace NWindows {
+namespace NError {
+
+UString MyFormatMessage(DWORD errorCode);
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/FileDir.cpp b/3rdparty/lzma/CPP/Windows/FileDir.cpp
index 88215faa2ad..da71b710bdc 100644
--- a/3rdparty/lzma/CPP/Windows/FileDir.cpp
+++ b/3rdparty/lzma/CPP/Windows/FileDir.cpp
@@ -14,21 +14,17 @@
extern bool g_IsNT;
#endif
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
namespace NWindows {
namespace NFile {
-
-// SetCurrentDirectory doesn't support \\?\ prefix
-
-#ifdef WIN_LONG_PATH
-bool GetLongPathBase(CFSTR fileName, UString &res);
-bool GetLongPath(CFSTR fileName, UString &res);
-#endif
-
-namespace NDirectory {
+namespace NDir {
#ifndef UNDER_CE
-bool MyGetWindowsDirectory(FString &path)
+bool GetWindowsDir(FString &path)
{
UINT needLength;
#ifndef _UNICODE
@@ -50,8 +46,7 @@ bool MyGetWindowsDirectory(FString &path)
return (needLength > 0 && needLength <= MAX_PATH);
}
-
-bool MyGetSystemDirectory(FString &path)
+bool GetSystemDir(FString &path)
{
UINT needLength;
#ifndef _UNICODE
@@ -74,7 +69,7 @@ bool MyGetSystemDirectory(FString &path)
}
#endif
-bool SetDirTime(CFSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
+bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
{
#ifndef _UNICODE
if (!g_IsNT)
@@ -83,14 +78,17 @@ bool SetDirTime(CFSTR fileName, const FILETIME *cTime, const FILETIME *aTime, co
return false;
}
#endif
- HANDLE hDir = ::CreateFileW(fs2us(fileName), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+ HANDLE hDir = INVALID_HANDLE_VALUE;
+ IF_USE_MAIN_PATH
+ hDir = ::CreateFileW(fs2us(path), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
#ifdef WIN_LONG_PATH
- if (hDir == INVALID_HANDLE_VALUE)
+ if (hDir == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
- UString longPath;
- if (GetLongPath(fileName, longPath))
- hDir = ::CreateFileW(longPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ hDir = ::CreateFileW(superPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
}
#endif
@@ -104,87 +102,154 @@ bool SetDirTime(CFSTR fileName, const FILETIME *cTime, const FILETIME *aTime, co
return res;
}
-#ifdef WIN_LONG_PATH
-bool GetLongPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2)
+bool SetFileAttrib(CFSTR path, DWORD attrib)
{
- if (!GetLongPathBase(s1, d1) ||
- !GetLongPathBase(s2, d2))
- return false;
- if (d1.IsEmpty() && d2.IsEmpty())
- return false;
- if (d1.IsEmpty()) d1 = fs2us(s1);
- if (d2.IsEmpty()) d2 = fs2us(s2);
- return true;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ if (::SetFileAttributes(fs2fas(path), attrib))
+ return true;
+ }
+ else
+ #endif
+ {
+ IF_USE_MAIN_PATH
+ if (::SetFileAttributesW(fs2us(path), attrib))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ return BOOLToBool(::SetFileAttributesW(superPath, attrib));
+ }
+ #endif
+ }
+ return false;
}
-#endif
-bool MySetFileAttributes(CFSTR fileName, DWORD fileAttributes)
+bool RemoveDir(CFSTR path)
{
#ifndef _UNICODE
if (!g_IsNT)
{
- if (::SetFileAttributes(fs2fas(fileName), fileAttributes))
+ if (::RemoveDirectory(fs2fas(path)))
return true;
}
else
#endif
{
- if (::SetFileAttributesW(fs2us(fileName), fileAttributes))
- return true;
+ IF_USE_MAIN_PATH
+ if (::RemoveDirectoryW(fs2us(path)))
+ return true;
#ifdef WIN_LONG_PATH
- UString longPath;
- if (GetLongPath(fileName, longPath))
- return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
+ if (USE_SUPER_PATH)
+ {
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ return BOOLToBool(::RemoveDirectoryW(superPath));
+ }
#endif
}
return false;
}
-bool MyRemoveDirectory(CFSTR path)
+bool MyMoveFile(CFSTR oldFile, CFSTR newFile)
{
#ifndef _UNICODE
if (!g_IsNT)
{
- if (::RemoveDirectory(fs2fas(path)))
+ if (::MoveFile(fs2fas(oldFile), fs2fas(newFile)))
return true;
}
else
#endif
{
- if (::RemoveDirectoryW(fs2us(path)))
- return true;
+ IF_USE_MAIN_PATH_2(oldFile, newFile)
+ if (::MoveFileW(fs2us(oldFile), fs2us(newFile)))
+ return true;
#ifdef WIN_LONG_PATH
- UString longPath;
- if (GetLongPath(path, longPath))
- return BOOLToBool(::RemoveDirectoryW(longPath));
+ if (USE_SUPER_PATH_2)
+ {
+ UString d1, d2;
+ if (GetSuperPaths(oldFile, newFile, d1, d2, USE_MAIN_PATH_2))
+ return BOOLToBool(::MoveFileW(d1, d2));
+ }
#endif
}
return false;
}
-bool MyMoveFile(CFSTR existFileName, CFSTR newFileName)
+#ifndef UNDER_CE
+
+EXTERN_C_BEGIN
+typedef BOOL (WINAPI *Func_CreateHardLinkW)(
+ LPCWSTR lpFileName,
+ LPCWSTR lpExistingFileName,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes
+ );
+EXTERN_C_END
+
+bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName)
{
#ifndef _UNICODE
if (!g_IsNT)
{
- if (::MoveFile(fs2fas(existFileName), fs2fas(newFileName)))
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ /*
+ if (::CreateHardLink(fs2fas(newFileName), fs2fas(existFileName), NULL))
return true;
+ */
}
else
#endif
{
- if (::MoveFileW(fs2us(existFileName), fs2us(newFileName)))
- return true;
+ Func_CreateHardLinkW my_CreateHardLinkW = (Func_CreateHardLinkW)
+ ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "CreateHardLinkW");
+ if (!my_CreateHardLinkW)
+ return false;
+ IF_USE_MAIN_PATH_2(newFileName, existFileName)
+ if (my_CreateHardLinkW(fs2us(newFileName), fs2us(existFileName), NULL))
+ return true;
#ifdef WIN_LONG_PATH
- UString d1, d2;
- if (GetLongPaths(existFileName, newFileName, d1, d2))
- return BOOLToBool(::MoveFileW(d1, d2));
+ if (USE_SUPER_PATH_2)
+ {
+ UString d1, d2;
+ if (GetSuperPaths(newFileName, existFileName, d1, d2, USE_MAIN_PATH_2))
+ return BOOLToBool(my_CreateHardLinkW(d1, d2, NULL));
+ }
#endif
}
return false;
}
-bool MyCreateDirectory(CFSTR path)
+#endif
+
+/*
+WinXP-64 CreateDir():
+ "" - ERROR_PATH_NOT_FOUND
+ \ - ERROR_ACCESS_DENIED
+ C:\ - ERROR_ACCESS_DENIED, if there is such drive,
+
+ D:\folder - ERROR_PATH_NOT_FOUND, if there is no such drive,
+ C:\nonExistent\folder - ERROR_PATH_NOT_FOUND
+
+ C:\existFolder - ERROR_ALREADY_EXISTS
+ C:\existFolder\ - ERROR_ALREADY_EXISTS
+
+ C:\folder - OK
+ C:\folder\ - OK
+
+ \\Server\nonExistent - ERROR_BAD_NETPATH
+ \\Server\Share_Readonly - ERROR_ACCESS_DENIED
+ \\Server\Share - ERROR_ALREADY_EXISTS
+
+ \\Server\Share_NTFS_drive - ERROR_ACCESS_DENIED
+ \\Server\Share_FAT_drive - ERROR_ALREADY_EXISTS
+*/
+
+bool CreateDir(CFSTR path)
{
#ifndef _UNICODE
if (!g_IsNT)
@@ -195,200 +260,241 @@ bool MyCreateDirectory(CFSTR path)
else
#endif
{
- if (::CreateDirectoryW(fs2us(path), NULL))
- return true;
+ IF_USE_MAIN_PATH
+ if (::CreateDirectoryW(fs2us(path), NULL))
+ return true;
#ifdef WIN_LONG_PATH
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH)
{
- UString longPath;
- if (GetLongPath(path, longPath))
- return BOOLToBool(::CreateDirectoryW(longPath, NULL));
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ return BOOLToBool(::CreateDirectoryW(superPath, NULL));
}
#endif
}
return false;
}
-bool CreateComplexDirectory(CFSTR _aPathName)
+/*
+ CreateDir2 returns true, if directory can contain files after the call (two cases):
+ 1) the directory already exists
+ 2) the directory was created
+ path must be WITHOUT trailing path separator.
+
+ We need CreateDir2, since fileInfo.Find() for reserved names like "com8"
+ returns FILE instead of DIRECTORY. And we need to use SuperPath */
+
+static bool CreateDir2(CFSTR path)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ if (::CreateDirectory(fs2fas(path), NULL))
+ return true;
+ }
+ else
+ #endif
+ {
+ IF_USE_MAIN_PATH
+ if (::CreateDirectoryW(fs2us(path), NULL))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH)
+ {
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ {
+ if (::CreateDirectoryW(superPath, NULL))
+ return true;
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ return false;
+ NFind::CFileInfo fi;
+ if (!fi.Find(us2fs(superPath)))
+ return false;
+ return fi.IsDir();
+ }
+ }
+ #endif
+ }
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ return false;
+ NFind::CFileInfo fi;
+ if (!fi.Find(path))
+ return false;
+ return fi.IsDir();
+}
+
+bool CreateComplexDir(CFSTR _path)
{
- FString pathName = _aPathName;
- int pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
- if (pos > 0 && pos == pathName.Length() - 1)
+ #ifdef _WIN32
+
{
- if (pathName.Length() == 3 && pathName[1] == L':')
- return true; // Disk folder;
- pathName.Delete(pos);
+ DWORD attrib = NFind::GetFileAttrib(_path);
+ if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ return true;
}
- FString pathName2 = pathName;
- pos = pathName.Length();
+
+ #ifndef UNDER_CE
+
+ if (IsDriveRootPath_SuperAllowed(_path))
+ return false;
+
+ unsigned prefixSize = GetRootPrefixSize(_path);
+
+ #endif
+
+ #endif
+
+ FString path = _path;
+
+ int pos = path.ReverseFind_PathSepar();
+ if (pos >= 0 && (unsigned)pos == path.Len() - 1)
+ {
+ if (path.Len() == 1)
+ return true;
+ path.DeleteBack();
+ }
+
+ const FString path2 = path;
+ pos = path.Len();
+
for (;;)
{
- if (MyCreateDirectory(pathName))
+ if (CreateDir2(path))
break;
if (::GetLastError() == ERROR_ALREADY_EXISTS)
- {
- NFind::CFileInfo fileInfo;
- if (!fileInfo.Find(pathName)) // For network folders
- return true;
- if (!fileInfo.IsDir())
- return false;
- break;
- }
- pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
+ return false;
+ pos = path.ReverseFind_PathSepar();
if (pos < 0 || pos == 0)
return false;
- if (pathName[pos - 1] == L':')
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (pos == 1 && IS_PATH_SEPAR(path[0]))
+ return false;
+ if (prefixSize >= (unsigned)pos + 1)
return false;
- pathName = pathName.Left(pos);
+ #endif
+
+ path.DeleteFrom(pos);
}
- pathName = pathName2;
- while (pos < pathName.Length())
+
+ while (pos < (int)path2.Len())
{
- pos = pathName.Find(FCHAR_PATH_SEPARATOR, pos + 1);
- if (pos < 0)
- pos = pathName.Length();
- if (!MyCreateDirectory(pathName.Left(pos)))
+ int pos2 = NName::FindSepar(path2.Ptr(pos + 1));
+ if (pos2 < 0)
+ pos = path2.Len();
+ else
+ pos += 1 + pos2;
+ path.SetFrom(path2, pos);
+ if (!CreateDir(path))
return false;
}
+
return true;
}
-bool DeleteFileAlways(CFSTR name)
+bool DeleteFileAlways(CFSTR path)
{
- if (!MySetFileAttributes(name, 0))
- return false;
+ /* If alt stream, we also need to clear READ-ONLY attribute of main file before delete.
+ SetFileAttrib("name:stream", ) changes attributes of main file. */
+ {
+ DWORD attrib = NFind::GetFileAttrib(path);
+ if (attrib != INVALID_FILE_ATTRIBUTES
+ && (attrib & FILE_ATTRIBUTE_DIRECTORY) == 0
+ && (attrib & FILE_ATTRIBUTE_READONLY) != 0)
+ {
+ if (!SetFileAttrib(path, attrib & ~FILE_ATTRIBUTE_READONLY))
+ return false;
+ }
+ }
+
#ifndef _UNICODE
if (!g_IsNT)
{
- if (::DeleteFile(fs2fas(name)))
+ if (::DeleteFile(fs2fas(path)))
return true;
}
else
#endif
{
- if (::DeleteFileW(fs2us(name)))
- return true;
+ /* DeleteFile("name::$DATA") deletes all alt streams (same as delete DeleteFile("name")).
+ Maybe it's better to open "name::$DATA" and clear data for unnamed stream? */
+ IF_USE_MAIN_PATH
+ if (::DeleteFileW(fs2us(path)))
+ return true;
#ifdef WIN_LONG_PATH
- UString longPath;
- if (GetLongPath(name, longPath))
- return BOOLToBool(::DeleteFileW(longPath));
+ if (USE_SUPER_PATH)
+ {
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ return BOOLToBool(::DeleteFileW(superPath));
+ }
#endif
}
return false;
}
-static bool RemoveDirectorySubItems2(const FString pathPrefix, const NFind::CFileInfo &fileInfo)
-{
- if (fileInfo.IsDir())
- return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
- return DeleteFileAlways(pathPrefix + fileInfo.Name);
-}
-bool RemoveDirectoryWithSubItems(const FString &path)
+bool RemoveDirWithSubItems(const FString &path)
{
- NFind::CFileInfo fileInfo;
- FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
+ bool needRemoveSubItems = true;
{
- NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK);
- while (enumerator.Next(fileInfo))
- if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+ NFind::CFileInfo fi;
+ if (!fi.Find(path))
+ return false;
+ if (!fi.IsDir())
+ {
+ ::SetLastError(ERROR_DIRECTORY);
+ return false;
+ }
+ if (fi.HasReparsePoint())
+ needRemoveSubItems = false;
+ }
+
+ if (needRemoveSubItems)
+ {
+ FString s = path;
+ s.Add_PathSepar();
+ unsigned prefixSize = s.Len();
+ s += FCHAR_ANY_MASK;
+ NFind::CEnumerator enumerator(s);
+ NFind::CFileInfo fi;
+ while (enumerator.Next(fi))
+ {
+ s.DeleteFrom(prefixSize);
+ s += fi.Name;
+ if (fi.IsDir())
+ {
+ if (!RemoveDirWithSubItems(s))
+ return false;
+ }
+ else if (!DeleteFileAlways(s))
return false;
+ }
}
- if (!MySetFileAttributes(path, 0))
+
+ if (!SetFileAttrib(path, 0))
return false;
- return MyRemoveDirectory(path);
+ return RemoveDir(path);
}
#ifdef UNDER_CE
-bool MyGetFullPathName(CFSTR fileName, FString &resFullPath)
+bool MyGetFullPathName(CFSTR path, FString &resFullPath)
{
- resFullPath = fileName;
+ resFullPath = path;
return true;
}
#else
-#ifdef WIN_LONG_PATH
-
-static FString GetLastPart(CFSTR path)
-{
- int i = MyStringLen(path);
- for (; i > 0; i--)
- {
- FChar c = path[i - 1];
- if (c == FCHAR_PATH_SEPARATOR || c == '/')
- break;
- }
- return path + i;
-}
-
-static void AddTrailingDots(CFSTR oldPath, FString &newPath)
+bool MyGetFullPathName(CFSTR path, FString &resFullPath)
{
- int len = MyStringLen(oldPath);
- int i;
- for (i = len; i > 0 && oldPath[i - 1] == '.'; i--);
- if (i == 0 || i == len)
- return;
- FString oldName = GetLastPart(oldPath);
- FString newName = GetLastPart(newPath);
- int nonDotsLen = oldName.Length() - (len - i);
- if (nonDotsLen == 0 || newName.CompareNoCase(oldName.Left(nonDotsLen)) != 0)
- return;
- for (; i != len; i++)
- newPath += '.';
-}
-
-#endif
-
-bool MyGetFullPathName(CFSTR fileName, FString &resFullPath)
-{
- resFullPath.Empty();
- #ifndef _UNICODE
- if (!g_IsNT)
- {
- TCHAR s[MAX_PATH + 2];
- s[0] = 0;
- LPTSTR fileNamePointer = 0;
- DWORD needLength = ::GetFullPathName(fs2fas(fileName), MAX_PATH + 1, s, &fileNamePointer);
- if (needLength == 0 || needLength > MAX_PATH)
- return false;
- resFullPath = fas2fs(s);
- return true;
- }
- else
- #endif
- {
- LPWSTR fileNamePointer = 0;
- WCHAR s[MAX_PATH + 2];
- s[0] = 0;
- DWORD needLength = ::GetFullPathNameW(fs2us(fileName), MAX_PATH + 1, s, &fileNamePointer);
- if (needLength == 0)
- return false;
- if (needLength <= MAX_PATH)
- {
- resFullPath = us2fs(s);
- return true;
- }
- #ifdef WIN_LONG_PATH
- needLength++;
- UString temp;
- LPWSTR buffer = temp.GetBuffer(needLength + 1);
- buffer[0] = 0;
- DWORD needLength2 = ::GetFullPathNameW(fs2us(fileName), needLength, buffer, &fileNamePointer);
- temp.ReleaseBuffer();
- if (needLength2 > 0 && needLength2 <= needLength)
- {
- resFullPath = us2fs(temp);
- AddTrailingDots(fileName, resFullPath);
- return true;
- }
- #endif
- return false;
- }
+ return GetFullPath(path, resFullPath);
}
-bool MySetCurrentDirectory(CFSTR path)
+bool SetCurrentDir(CFSTR path)
{
+ // SetCurrentDirectory doesn't support \\?\ prefix
#ifndef _UNICODE
if (!g_IsNT)
{
@@ -401,7 +507,7 @@ bool MySetCurrentDirectory(CFSTR path)
}
}
-bool MyGetCurrentDirectory(FString &path)
+bool GetCurrentDir(FString &path)
{
path.Empty();
DWORD needLength;
@@ -428,15 +534,12 @@ bool MyGetCurrentDirectory(FString &path)
bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName)
{
- bool res = MyGetFullPathName(path, resFileName);
+ bool res = MyGetFullPathName(path, resDirPrefix);
if (!res)
- resFileName = path;
- int pos = resFileName.ReverseFind(FCHAR_PATH_SEPARATOR);
- if (pos >= 0)
- {
- resDirPrefix = resFileName.Left(pos + 1);
- resFileName = resFileName.Mid(pos + 1);
- }
+ resDirPrefix = path;
+ int pos = resDirPrefix.ReverseFind_PathSepar();
+ resFileName = resDirPrefix.Ptr(pos + 1);
+ resDirPrefix.DeleteFrom(pos + 1);
return res;
}
@@ -484,7 +587,7 @@ static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COu
{
unsigned t = value & 0xF;
value >>= 4;
- s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ s[k] = (FChar)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
s[k] = '\0';
if (outFile)
@@ -510,7 +613,7 @@ static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COu
}
else
{
- if (MyCreateDirectory(path))
+ if (CreateDir(path))
return true;
}
DWORD error = GetLastError();
@@ -580,7 +683,7 @@ bool CTempDir::Remove()
{
if (!_mustBeDeleted)
return true;
- _mustBeDeleted = !RemoveDirectoryWithSubItems(_path);
+ _mustBeDeleted = !RemoveDirWithSubItems(_path);
return !_mustBeDeleted;
}
diff --git a/3rdparty/lzma/CPP/Windows/FileDir.h b/3rdparty/lzma/CPP/Windows/FileDir.h
index e43c19bd8a6..b13d1ccada2 100644
--- a/3rdparty/lzma/CPP/Windows/FileDir.h
+++ b/3rdparty/lzma/CPP/Windows/FileDir.h
@@ -4,27 +4,36 @@
#define __WINDOWS_FILE_DIR_H
#include "../Common/MyString.h"
+
#include "FileIO.h"
namespace NWindows {
namespace NFile {
-namespace NDirectory {
+namespace NDir {
+
+bool GetWindowsDir(FString &path);
+bool GetSystemDir(FString &path);
+
+bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
+bool SetFileAttrib(CFSTR path, DWORD attrib);
+bool MyMoveFile(CFSTR existFileName, CFSTR newFileName);
-#ifdef WIN_LONG_PATH
-bool GetLongPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2);
+#ifndef UNDER_CE
+bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName);
#endif
-bool MyGetWindowsDirectory(FString &path);
-bool MyGetSystemDirectory(FString &path);
+bool RemoveDir(CFSTR path);
+bool CreateDir(CFSTR path);
+
+/* CreateComplexDir returns true, if directory can contain files after the call (two cases):
+ 1) the directory already exists (network shares and drive paths are supported)
+ 2) the directory was created
+ path can be WITH or WITHOUT trailing path separator. */
+
+bool CreateComplexDir(CFSTR path);
-bool SetDirTime(CFSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
-bool MySetFileAttributes(CFSTR fileName, DWORD fileAttributes);
-bool MyMoveFile(CFSTR existFileName, CFSTR newFileName);
-bool MyRemoveDirectory(CFSTR path);
-bool MyCreateDirectory(CFSTR path);
-bool CreateComplexDirectory(CFSTR path);
bool DeleteFileAlways(CFSTR name);
-bool RemoveDirectoryWithSubItems(const FString &path);
+bool RemoveDirWithSubItems(const FString &path);
bool MyGetFullPathName(CFSTR path, FString &resFullPath);
bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName);
@@ -32,8 +41,8 @@ bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix);
#ifndef UNDER_CE
-bool MySetCurrentDirectory(CFSTR path);
-bool MyGetCurrentDirectory(FString &resultPath);
+bool SetCurrentDir(CFSTR path);
+bool GetCurrentDir(FString &resultPath);
#endif
@@ -67,6 +76,29 @@ public:
bool Remove();
};
+#if !defined(UNDER_CE)
+class CCurrentDirRestorer
+{
+ FString _path;
+public:
+ bool NeedRestore;
+
+ CCurrentDirRestorer(): NeedRestore(true)
+ {
+ GetCurrentDir(_path);
+ }
+ ~CCurrentDirRestorer()
+ {
+ if (!NeedRestore)
+ return;
+ FString s;
+ if (GetCurrentDir(s))
+ if (s != _path)
+ SetCurrentDir(_path);
+ }
+};
+#endif
+
}}}
#endif
diff --git a/3rdparty/lzma/CPP/Windows/FileFind.cpp b/3rdparty/lzma/CPP/Windows/FileFind.cpp
index 081bd9bc51d..94486977acd 100644
--- a/3rdparty/lzma/CPP/Windows/FileFind.cpp
+++ b/3rdparty/lzma/CPP/Windows/FileFind.cpp
@@ -2,36 +2,66 @@
#include "StdAfx.h"
-#include "FileFind.h"
-#include "FileIO.h"
#ifndef _UNICODE
#include "../Common/StringConvert.h"
#endif
+#include "FileFind.h"
+#include "FileIO.h"
+#include "FileName.h"
+
#ifndef _UNICODE
extern bool g_IsNT;
#endif
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+EXTERN_C_BEGIN
+
+typedef enum
+{
+ My_FindStreamInfoStandard,
+ My_FindStreamInfoMaxInfoLevel
+} MY_STREAM_INFO_LEVELS;
+
+typedef struct
+{
+ LARGE_INTEGER StreamSize;
+ WCHAR cStreamName[MAX_PATH + 36];
+} MY_WIN32_FIND_STREAM_DATA, *MY_PWIN32_FIND_STREAM_DATA;
+
+typedef WINBASEAPI HANDLE (WINAPI *FindFirstStreamW_Ptr)(LPCWSTR fileName, MY_STREAM_INFO_LEVELS infoLevel,
+ LPVOID findStreamData, DWORD flags);
+
+typedef WINBASEAPI BOOL (APIENTRY *FindNextStreamW_Ptr)(HANDLE findStream, LPVOID findStreamData);
+
+EXTERN_C_END
+
+#endif
+
namespace NWindows {
namespace NFile {
#ifdef SUPPORT_DEVICE_FILE
-bool IsDeviceName(CFSTR n);
-#endif
-
-#if defined(WIN_LONG_PATH)
-bool GetLongPath(CFSTR fileName, UString &res);
+namespace NSystem
+{
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
+}
#endif
namespace NFind {
-bool CFileInfo::IsDots() const
+bool CFileInfo::IsDots() const throw()
{
if (!IsDir() || Name.IsEmpty())
return false;
- if (Name[0] != FTEXT('.'))
+ if (Name[0] != '.')
return false;
- return Name.Length() == 1 || (Name.Length() == 2 && Name[1] == FTEXT('.'));
+ return Name.Len() == 1 || (Name.Len() == 2 && Name[1] == '.');
}
#define WIN_FD_TO_MY_FI(fi, fd) \
@@ -40,6 +70,7 @@ bool CFileInfo::IsDots() const
fi.ATime = fd.ftLastAccessTime; \
fi.MTime = fd.ftLastWriteTime; \
fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; \
+ fi.IsAltStream = false; \
fi.IsDevice = false;
/*
@@ -50,27 +81,31 @@ bool CFileInfo::IsDots() const
#endif
*/
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfo &fi)
+static void Convert_WIN32_FIND_DATA_to_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfo &fi)
{
WIN_FD_TO_MY_FI(fi, fd);
fi.Name = us2fs(fd.cFileName);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // fi.ShortName = us2fs(fd.cAlternateFileName);
+ #endif
}
#ifndef _UNICODE
-static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
+static void Convert_WIN32_FIND_DATA_to_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
{
WIN_FD_TO_MY_FI(fi, fd);
fi.Name = fas2fs(fd.cFileName);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // fi.ShortName = fas2fs(fd.cAlternateFileName);
+ #endif
}
#endif
////////////////////////////////
// CFindFile
-bool CFindFile::Close()
+bool CFindFileBase::Close() throw()
{
if (_handle == INVALID_HANDLE_VALUE)
return true;
@@ -80,7 +115,35 @@ bool CFindFile::Close()
return true;
}
-bool CFindFile::FindFirst(CFSTR wildcard, CFileInfo &fi)
+/*
+WinXP-64 FindFirstFile():
+ "" - ERROR_PATH_NOT_FOUND
+ folder\ - ERROR_FILE_NOT_FOUND
+ \ - ERROR_FILE_NOT_FOUND
+ c:\ - ERROR_FILE_NOT_FOUND
+ c: - ERROR_FILE_NOT_FOUND, if current dir is ROOT ( c:\ )
+ c: - OK, if current dir is NOT ROOT ( c:\folder )
+ folder - OK
+
+ \\ - ERROR_INVALID_NAME
+ \\Server - ERROR_INVALID_NAME
+ \\Server\ - ERROR_INVALID_NAME
+
+ \\Server\Share - ERROR_BAD_NETPATH
+ \\Server\Share - ERROR_BAD_NET_NAME (Win7)
+ \\Server\Share\ - ERROR_FILE_NOT_FOUND
+
+ \\?\UNC\Server\Share - ERROR_INVALID_NAME
+ \\?\UNC\Server\Share - ERROR_BAD_PATHNAME (Win7)
+ \\?\UNC\Server\Share\ - ERROR_FILE_NOT_FOUND
+
+ \\Server\Share_RootDrive - ERROR_INVALID_NAME
+ \\Server\Share_RootDrive\ - ERROR_INVALID_NAME
+
+ c:\* - ERROR_FILE_NOT_FOUND, if thare are no item in that folder
+*/
+
+bool CFindFile::FindFirst(CFSTR path, CFileInfo &fi)
{
if (!Close())
return false;
@@ -88,27 +151,29 @@ bool CFindFile::FindFirst(CFSTR wildcard, CFileInfo &fi)
if (!g_IsNT)
{
WIN32_FIND_DATAA fd;
- _handle = ::FindFirstFileA(fs2fas(wildcard), &fd);
+ _handle = ::FindFirstFileA(fs2fas(path), &fd);
if (_handle == INVALID_HANDLE_VALUE)
return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
else
#endif
{
WIN32_FIND_DATAW fd;
- _handle = ::FindFirstFileW(fs2us(wildcard), &fd);
+
+ IF_USE_MAIN_PATH
+ _handle = ::FindFirstFileW(fs2us(path), &fd);
#ifdef WIN_LONG_PATH
- if (_handle == INVALID_HANDLE_VALUE)
+ if (_handle == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
- UString longPath;
- if (GetLongPath(wildcard, longPath))
- _handle = ::FindFirstFileW(longPath, &fd);
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ _handle = ::FindFirstFileW(superPath, &fd);
}
#endif
if (_handle == INVALID_HANDLE_VALUE)
return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
return true;
}
@@ -121,7 +186,7 @@ bool CFindFile::FindNext(CFileInfo &fi)
WIN32_FIND_DATAA fd;
if (!::FindNextFileA(_handle, &fd))
return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
else
#endif
@@ -129,72 +194,395 @@ bool CFindFile::FindNext(CFileInfo &fi)
WIN32_FIND_DATAW fd;
if (!::FindNextFileW(_handle, &fd))
return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
return true;
}
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+////////////////////////////////
+// AltStreams
+
+static FindFirstStreamW_Ptr g_FindFirstStreamW;
+static FindNextStreamW_Ptr g_FindNextStreamW;
+
+struct CFindStreamLoader
+{
+ CFindStreamLoader()
+ {
+ g_FindFirstStreamW = (FindFirstStreamW_Ptr)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "FindFirstStreamW");
+ g_FindNextStreamW = (FindNextStreamW_Ptr)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "FindNextStreamW");
+ }
+} g_FindStreamLoader;
+
+bool CStreamInfo::IsMainStream() const throw()
+{
+ return StringsAreEqualNoCase_Ascii(Name, "::$DATA");
+};
+
+UString CStreamInfo::GetReducedName() const
+{
+ // remove ":$DATA" postfix, but keep postfix, if Name is "::$DATA"
+ UString s = Name;
+ if (s.Len() > 6 + 1 && StringsAreEqualNoCase_Ascii(s.RightPtr(6), ":$DATA"))
+ s.DeleteFrom(s.Len() - 6);
+ return s;
+}
+
+/*
+UString CStreamInfo::GetReducedName2() const
+{
+ UString s = GetReducedName();
+ if (!s.IsEmpty() && s[0] == ':')
+ s.Delete(0);
+ return s;
+}
+*/
+
+static void Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(const MY_WIN32_FIND_STREAM_DATA &sd, CStreamInfo &si)
+{
+ si.Size = sd.StreamSize.QuadPart;
+ si.Name = sd.cStreamName;
+}
+
+/*
+ WinXP-64 FindFirstStream():
+ "" - ERROR_PATH_NOT_FOUND
+ folder\ - OK
+ folder - OK
+ \ - OK
+ c:\ - OK
+ c: - OK, if current dir is ROOT ( c:\ )
+ c: - OK, if current dir is NOT ROOT ( c:\folder )
+ \\Server\Share - OK
+ \\Server\Share\ - OK
+
+ \\ - ERROR_INVALID_NAME
+ \\Server - ERROR_INVALID_NAME
+ \\Server\ - ERROR_INVALID_NAME
+*/
+
+bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si)
+{
+ if (!Close())
+ return false;
+ if (!g_FindFirstStreamW)
+ {
+ ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ }
+ {
+ MY_WIN32_FIND_STREAM_DATA sd;
+ SetLastError(0);
+ IF_USE_MAIN_PATH
+ _handle = g_FindFirstStreamW(fs2us(path), My_FindStreamInfoStandard, &sd, 0);
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ if (::GetLastError() == ERROR_HANDLE_EOF)
+ return false;
+ // long name can be tricky for path like ".\dirName".
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ _handle = g_FindFirstStreamW(superPath, My_FindStreamInfoStandard, &sd, 0);
+ }
+ #endif
+ }
+ if (_handle == INVALID_HANDLE_VALUE)
+ return false;
+ Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si);
+ }
+ return true;
+}
+
+bool CFindStream::FindNext(CStreamInfo &si)
+{
+ if (!g_FindNextStreamW)
+ {
+ ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ }
+ {
+ MY_WIN32_FIND_STREAM_DATA sd;
+ if (!g_FindNextStreamW(_handle, &sd))
+ return false;
+ Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si);
+ }
+ return true;
+}
+
+bool CStreamEnumerator::Next(CStreamInfo &si, bool &found)
+{
+ bool res;
+ if (_find.IsHandleAllocated())
+ res = _find.FindNext(si);
+ else
+ res = _find.FindFirst(_filePath, si);
+ if (res)
+ {
+ found = true;
+ return true;
+ }
+ found = false;
+ return (::GetLastError() == ERROR_HANDLE_EOF);
+}
+
+#endif
+
+
#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0;
-void CFileInfoBase::Clear()
+void CFileInfoBase::ClearBase() throw()
{
Size = 0;
MY_CLEAR_FILETIME(CTime);
MY_CLEAR_FILETIME(ATime);
MY_CLEAR_FILETIME(MTime);
Attrib = 0;
+ IsAltStream = false;
+ IsDevice = false;
}
-
-bool CFileInfo::Find(CFSTR wildcard)
+
+/*
+WinXP-64 GetFileAttributes():
+ If the function fails, it returns INVALID_FILE_ATTRIBUTES and use GetLastError() to get error code
+
+ \ - OK
+ C:\ - OK, if there is such drive,
+ D:\ - ERROR_PATH_NOT_FOUND, if there is no such drive,
+
+ C:\folder - OK
+ C:\folder\ - OK
+ C:\folderBad - ERROR_FILE_NOT_FOUND
+
+ \\Server\BadShare - ERROR_BAD_NETPATH
+ \\Server\Share - WORKS OK, but MSDN says:
+ GetFileAttributes for a network share, the function fails, and GetLastError
+ returns ERROR_BAD_NETPATH. You must specify a path to a subfolder on that share.
+*/
+
+DWORD GetFileAttrib(CFSTR path)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ return ::GetFileAttributes(fs2fas(path));
+ else
+ #endif
+ {
+ IF_USE_MAIN_PATH
+ {
+ DWORD dw = ::GetFileAttributesW(fs2us(path));
+ if (dw != INVALID_FILE_ATTRIBUTES)
+ return dw;
+ }
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ return ::GetFileAttributesW(superPath);
+ }
+ #endif
+ return INVALID_FILE_ATTRIBUTES;
+ }
+}
+
+/* if path is "c:" or "c::" then CFileInfo::Find() returns name of current folder for that disk
+ so instead of absolute path we have relative path in Name. That is not good in some calls */
+
+/* In CFileInfo::Find() we want to support same names for alt streams as in CreateFile(). */
+
+/* CFileInfo::Find()
+We alow the following paths (as FindFirstFile):
+ C:\folder
+ c: - if current dir is NOT ROOT ( c:\folder )
+
+also we support paths that are not supported by FindFirstFile:
+ \
+ \\.\c:
+ c:\ - Name will be without tail slash ( c: )
+ \\?\c:\ - Name will be without tail slash ( c: )
+ \\Server\Share
+ \\?\UNC\Server\Share
+
+ c:\folder:stream - Name = folder:stream
+ c:\:stream - Name = :stream
+ c::stream - Name = c::stream
+*/
+
+bool CFileInfo::Find(CFSTR path)
{
#ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceName(wildcard))
+ if (IsDevicePath(path))
{
- Clear();
+ ClearBase();
+ Name = path + 4;
IsDevice = true;
+
+ if (NName::IsDrivePath2(path + 4) && path[6] == 0)
+ {
+ FChar drive[4] = { path[4], ':', '\\', 0 };
+ UInt64 clusterSize, totalSize, freeSize;
+ if (NSystem::MyGetDiskFreeSpace(drive, clusterSize, totalSize, freeSize))
+ {
+ Size = totalSize;
+ return true;
+ }
+ }
+
NIO::CInFile inFile;
- if (!inFile.Open(wildcard))
+ // ::OutputDebugStringW(path);
+ if (!inFile.Open(path))
return false;
- Name = wildcard + 4;
- if (inFile.LengthDefined)
- Size = inFile.Length;
+ // ::OutputDebugStringW(L"---");
+ if (inFile.SizeDefined)
+ Size = inFile.Size;
return true;
}
#endif
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+
+ int colonPos = FindAltStreamColon(path);
+ if (colonPos >= 0 && path[(unsigned)colonPos + 1] != 0)
+ {
+ UString streamName = fs2us(path + (unsigned)colonPos);
+ FString filePath = path;
+ filePath.DeleteFrom(colonPos);
+ /* we allow both cases:
+ name:stream
+ name:stream:$DATA
+ */
+ const unsigned kPostfixSize = 6;
+ if (streamName.Len() <= kPostfixSize
+ || !StringsAreEqualNoCase_Ascii(streamName.RightPtr(kPostfixSize), ":$DATA"))
+ streamName += L":$DATA";
+
+ bool isOk = true;
+
+ if (IsDrivePath2(filePath) &&
+ (colonPos == 2 || colonPos == 3 && filePath[2] == '\\'))
+ {
+ // FindFirstFile doesn't work for "c:\" and for "c:" (if current dir is ROOT)
+ ClearBase();
+ Name.Empty();
+ if (colonPos == 2)
+ Name = filePath;
+ }
+ else
+ isOk = Find(filePath);
+
+ if (isOk)
+ {
+ Attrib &= ~(FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+ Size = 0;
+ CStreamEnumerator enumerator(filePath);
+ for (;;)
+ {
+ CStreamInfo si;
+ bool found;
+ if (!enumerator.Next(si, found))
+ return false;
+ if (!found)
+ {
+ ::SetLastError(ERROR_FILE_NOT_FOUND);
+ return false;
+ }
+ if (si.Name.IsEqualTo_NoCase(streamName))
+ {
+ // we delete postfix, if alt stream name is not "::$DATA"
+ if (si.Name.Len() > kPostfixSize + 1)
+ si.Name.DeleteFrom(si.Name.Len() - kPostfixSize);
+ Name += us2fs(si.Name);
+ Size = si.Size;
+ IsAltStream = true;
+ return true;
+ }
+ }
+ }
+ }
+
+ #endif
+
CFindFile finder;
- if (finder.FindFirst(wildcard, *this))
+ if (finder.FindFirst(path, *this))
return true;
- #ifdef _WIN32
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
{
DWORD lastError = GetLastError();
- if (lastError == ERROR_BAD_NETPATH || lastError == ERROR_FILE_NOT_FOUND)
+ if (lastError == ERROR_FILE_NOT_FOUND
+ || lastError == ERROR_BAD_NETPATH // XP64: "\\Server\Share"
+ || lastError == ERROR_BAD_NET_NAME // Win7: "\\Server\Share"
+ || lastError == ERROR_INVALID_NAME // XP64: "\\?\UNC\Server\Share"
+ || lastError == ERROR_BAD_PATHNAME // Win7: "\\?\UNC\Server\Share"
+ )
{
- int len = MyStringLen(wildcard);
- if (len > 2 && wildcard[0] == '\\' && wildcard[1] == '\\')
+ unsigned rootSize = 0;
+ if (IsSuperPath(path))
+ rootSize = kSuperPathPrefixSize;
+ if (IS_PATH_SEPAR(path[0]) && path[1] == 0)
{
- int pos = FindCharPosInString(wildcard + 2, FTEXT('\\'));
- if (pos >= 0)
+ DWORD attrib = GetFileAttrib(path);
+ if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)
{
- pos += 2 + 1;
- len -= pos;
- CFSTR remString = wildcard + pos;
- int pos2 = FindCharPosInString(remString, FTEXT('\\'));
- FString s = wildcard;
- if (pos2 < 0 || pos2 == len - 1)
+ ClearBase();
+ Name.Empty();
+ Attrib = attrib;
+ return true;
+ }
+ }
+ else if (NName::IsDrivePath(path + rootSize) && path[rootSize + 3] == 0)
+ {
+ DWORD attrib = GetFileAttrib(path);
+ if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ {
+ ClearBase();
+ Attrib = attrib;
+ Name = path + rootSize;
+ Name.DeleteFrom(2); // we don't need backslash (C:)
+ return true;
+ }
+ }
+ else
+ {
+ unsigned prefixSize = GetNetworkServerPrefixSize(path);
+ if (prefixSize > 0 && path[prefixSize] != 0)
+ {
+ if (NName::FindSepar(path + prefixSize) < 0)
{
- FString s = wildcard;
- if (pos2 < 0)
- {
- pos2 = len;
- s += FTEXT('\\');
- }
+ FString s = path;
+ s.Add_PathSepar();
s += FCHAR_ANY_MASK;
+
+ bool isOK = false;
if (finder.FindFirst(s, *this))
+ {
if (Name == FTEXT("."))
{
- Name = s.Mid(pos, pos2);
+ Name = path + prefixSize;;
+ return true;
+ }
+ isOK = true;
+ /* if "\\server\share" maps to root folder "d:\", there is no "." item.
+ But it's possible that there are another items */
+ }
+ {
+ DWORD attrib = GetFileAttrib(path);
+ if (isOK || attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ {
+ ClearBase();
+ if (attrib != INVALID_FILE_ATTRIBUTES)
+ Attrib = attrib;
+ else
+ SetAsDir();
+ Name = path + prefixSize;
return true;
}
+ }
::SetLastError(lastError);
}
}
@@ -202,6 +590,7 @@ bool CFileInfo::Find(CFSTR wildcard)
}
}
#endif
+
return false;
}
@@ -216,12 +605,14 @@ bool DoesDirExist(CFSTR name)
CFileInfo fi;
return fi.Find(name) && fi.IsDir();
}
+
bool DoesFileOrDirExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name);
}
+
bool CEnumerator::NextAny(CFileInfo &fi)
{
if (_findFile.IsHandleAllocated())
@@ -256,7 +647,7 @@ bool CEnumerator::Next(CFileInfo &fi, bool &found)
// CFindChangeNotification
// FindFirstChangeNotification can return 0. MSDN doesn't tell about it.
-bool CFindChangeNotification::Close()
+bool CFindChangeNotification::Close() throw()
{
if (!IsHandleAllocated())
return true;
@@ -266,21 +657,22 @@ bool CFindChangeNotification::Close()
return true;
}
-HANDLE CFindChangeNotification::FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter)
+HANDLE CFindChangeNotification::FindFirst(CFSTR path, bool watchSubtree, DWORD notifyFilter)
{
#ifndef _UNICODE
if (!g_IsNT)
- _handle = ::FindFirstChangeNotification(fs2fas(pathName), BoolToBOOL(watchSubtree), notifyFilter);
+ _handle = ::FindFirstChangeNotification(fs2fas(path), BoolToBOOL(watchSubtree), notifyFilter);
else
#endif
{
- _handle = ::FindFirstChangeNotificationW(fs2us(pathName), BoolToBOOL(watchSubtree), notifyFilter);
+ IF_USE_MAIN_PATH
+ _handle = ::FindFirstChangeNotificationW(fs2us(path), BoolToBOOL(watchSubtree), notifyFilter);
#ifdef WIN_LONG_PATH
if (!IsHandleAllocated())
{
- UString longPath;
- if (GetLongPath(pathName, longPath))
- _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ _handle = ::FindFirstChangeNotificationW(superPath, BoolToBOOL(watchSubtree), notifyFilter);
}
#endif
}
@@ -299,23 +691,22 @@ bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings)
UINT32 size = GetLogicalDriveStrings(0, NULL);
if (size == 0)
return false;
- AString buf;
- UINT32 newSize = GetLogicalDriveStrings(size, buf.GetBuffer(size));
+ CObjArray<char> buf(size);
+ UINT32 newSize = GetLogicalDriveStrings(size, buf);
if (newSize == 0 || newSize > size)
return false;
AString s;
+ UINT32 prev = 0;
for (UINT32 i = 0; i < newSize; i++)
{
- char c = buf[i];
- if (c == '\0')
+ if (buf[i] == 0)
{
+ s = buf + prev;
+ prev = i + 1;
driveStrings.Add(fas2fs(s));
- s.Empty();
}
- else
- s += c;
}
- return s.IsEmpty();
+ return prev == newSize;;
}
else
#endif
@@ -323,23 +714,22 @@ bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings)
UINT32 size = GetLogicalDriveStringsW(0, NULL);
if (size == 0)
return false;
- UString buf;
- UINT32 newSize = GetLogicalDriveStringsW(size, buf.GetBuffer(size));
+ CObjArray<wchar_t> buf(size);
+ UINT32 newSize = GetLogicalDriveStringsW(size, buf);
if (newSize == 0 || newSize > size)
return false;
UString s;
+ UINT32 prev = 0;
for (UINT32 i = 0; i < newSize; i++)
{
- WCHAR c = buf[i];
- if (c == L'\0')
+ if (buf[i] == 0)
{
+ s = buf + prev;
+ prev = i + 1;
driveStrings.Add(us2fs(s));
- s.Empty();
}
- else
- s += c;
}
- return s.IsEmpty();
+ return prev == newSize;
}
}
diff --git a/3rdparty/lzma/CPP/Windows/FileFind.h b/3rdparty/lzma/CPP/Windows/FileFind.h
index 97a3b7c2a62..615c2dfe24c 100644
--- a/3rdparty/lzma/CPP/Windows/FileFind.h
+++ b/3rdparty/lzma/CPP/Windows/FileFind.h
@@ -4,7 +4,6 @@
#define __WINDOWS_FILE_FIND_H
#include "../Common/MyString.h"
-#include "../Common/Types.h"
#include "Defs.h"
namespace NWindows {
@@ -25,14 +24,13 @@ namespace NAttributes
class CFileInfoBase
{
bool MatchesMask(UINT32 mask) const { return ((Attrib & mask) != 0); }
-protected:
- void Clear();
public:
UInt64 Size;
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
DWORD Attrib;
+ bool IsAltStream;
bool IsDevice;
/*
@@ -43,6 +41,11 @@ public:
#endif
*/
+ CFileInfoBase() { ClearBase(); }
+ void ClearBase() throw();
+
+ void SetAsDir() { Attrib = FILE_ATTRIBUTE_DIRECTORY; }
+
bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
bool IsDir() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); }
@@ -60,28 +63,70 @@ public:
struct CFileInfo: public CFileInfoBase
{
FString Name;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // FString ShortName;
+ #endif
- bool IsDots() const;
- bool Find(CFSTR wildcard);
+ bool IsDots() const throw();
+ bool Find(CFSTR path);
};
-class CFindFile
+class CFindFileBase
{
- friend class CEnumerator;
+protected:
HANDLE _handle;
public:
bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; }
- CFindFile(): _handle(INVALID_HANDLE_VALUE) {}
- ~CFindFile() { Close(); }
+ CFindFileBase(): _handle(INVALID_HANDLE_VALUE) {}
+ ~CFindFileBase() { Close(); }
+ bool Close() throw();
+};
+
+class CFindFile: public CFindFileBase
+{
+public:
bool FindFirst(CFSTR wildcard, CFileInfo &fileInfo);
bool FindNext(CFileInfo &fileInfo);
- bool Close();
};
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+struct CStreamInfo
+{
+ UString Name;
+ UInt64 Size;
+
+ UString GetReducedName() const; // returns ":Name"
+ // UString GetReducedName2() const; // returns "Name"
+ bool IsMainStream() const throw();
+};
+
+class CFindStream: public CFindFileBase
+{
+public:
+ bool FindFirst(CFSTR filePath, CStreamInfo &streamInfo);
+ bool FindNext(CStreamInfo &streamInfo);
+};
+
+class CStreamEnumerator
+{
+ CFindStream _find;
+ FString _filePath;
+
+ bool NextAny(CFileInfo &fileInfo);
+public:
+ CStreamEnumerator(const FString &filePath): _filePath(filePath) {}
+ bool Next(CStreamInfo &streamInfo, bool &found);
+};
+
+#endif
+
bool DoesFileExist(CFSTR name);
bool DoesDirExist(CFSTR name);
bool DoesFileOrDirExist(CFSTR name);
+DWORD GetFileAttrib(CFSTR path);
+
class CEnumerator
{
CFindFile _findFile;
@@ -102,7 +147,7 @@ public:
bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE && _handle != 0; }
CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {}
~CFindChangeNotification() { Close(); }
- bool Close();
+ bool Close() throw();
HANDLE FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter);
bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); }
};
diff --git a/3rdparty/lzma/CPP/Windows/FileIO.cpp b/3rdparty/lzma/CPP/Windows/FileIO.cpp
index e8f98747c8f..56e6ca45796 100644
--- a/3rdparty/lzma/CPP/Windows/FileIO.cpp
+++ b/3rdparty/lzma/CPP/Windows/FileIO.cpp
@@ -2,88 +2,51 @@
#include "StdAfx.h"
+#ifdef SUPPORT_DEVICE_FILE
+#include "../../C/Alloc.h"
+#endif
+
#include "FileIO.h"
+#include "FileName.h"
#ifndef _UNICODE
extern bool g_IsNT;
#endif
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
namespace NWindows {
namespace NFile {
#ifdef SUPPORT_DEVICE_FILE
-bool IsDeviceName(CFSTR n)
-{
- #ifdef UNDER_CE
- int len = (int)MyStringLen(n);
- if (len < 5 || len > 5 || memcmp(n, FTEXT("DSK"), 3 * sizeof(FCHAR)) != 0)
- return false;
- if (n[4] != ':')
- return false;
- // for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ));
- #else
- if (n[0] != '\\' || n[1] != '\\' || n[2] != '.' || n[3] != '\\')
- return false;
- int len = (int)MyStringLen(n);
- if (len == 6 && n[5] == ':')
- return true;
- if (len < 18 || len > 22 || memcmp(n + 4, FTEXT("PhysicalDrive"), 13 * sizeof(FCHAR)) != 0)
- return false;
- for (int i = 17; i < len; i++)
- if (n[i] < '0' || n[i] > '9')
- return false;
- #endif
- return true;
-}
-
-#endif
-
-#if defined(WIN_LONG_PATH) && defined(_UNICODE)
-#define WIN_LONG_PATH2
-#endif
-
-#ifdef WIN_LONG_PATH
-bool GetLongPathBase(CFSTR s, UString &res)
-{
- res.Empty();
- int len = MyStringLen(s);
- FChar c = s[0];
- if (len < 1 || c == '\\' || c == '.' && (len == 1 || len == 2 && s[1] == '.'))
- return true;
- UString curDir;
- bool isAbs = false;
- if (len > 3)
- isAbs = (s[1] == ':' && s[2] == '\\' && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'));
-
- if (!isAbs)
- {
- WCHAR temp[MAX_PATH + 2];
- temp[0] = 0;
- DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, temp);
- if (needLength == 0 || needLength > MAX_PATH)
- return false;
- curDir = temp;
- if (curDir.Back() != L'\\')
- curDir += L'\\';
- }
- res = UString(L"\\\\?\\") + curDir + fs2us(s);
- return true;
-}
-
-bool GetLongPath(CFSTR path, UString &longPath)
+namespace NSystem
{
- if (GetLongPathBase(path, longPath))
- return !longPath.IsEmpty();
- return false;
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
}
#endif
namespace NIO {
-CFileBase::~CFileBase() { Close(); }
+/*
+WinXP-64 CreateFile():
+ "" - ERROR_PATH_NOT_FOUND
+ :stream - OK
+ .:stream - ERROR_PATH_NOT_FOUND
+ .\:stream - OK
+
+ folder\:stream - ERROR_INVALID_NAME
+ folder:stream - OK
+
+ c:\:stream - OK
+
+ c::stream - ERROR_INVALID_NAME, if current dir is NOT ROOT ( c:\dir1 )
+ c::stream - OK, if current dir is ROOT ( c:\ )
+*/
-bool CFileBase::Create(CFSTR fileName, DWORD desiredAccess,
+bool CFileBase::Create(CFSTR path, DWORD desiredAccess,
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
{
if (!Close())
@@ -96,20 +59,21 @@ bool CFileBase::Create(CFSTR fileName, DWORD desiredAccess,
#ifndef _UNICODE
if (!g_IsNT)
{
- _handle = ::CreateFile(fs2fas(fileName), desiredAccess, shareMode,
+ _handle = ::CreateFile(fs2fas(path), desiredAccess, shareMode,
(LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
}
else
#endif
{
- _handle = ::CreateFileW(fs2us(fileName), desiredAccess, shareMode,
+ IF_USE_MAIN_PATH
+ _handle = ::CreateFileW(fs2us(path), desiredAccess, shareMode,
(LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
#ifdef WIN_LONG_PATH
- if (_handle == INVALID_HANDLE_VALUE)
+ if (_handle == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
- UString longPath;
- if (GetLongPath(fileName, longPath))
- _handle = ::CreateFileW(longPath, desiredAccess, shareMode,
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ _handle = ::CreateFileW(superPath, desiredAccess, shareMode,
(LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
}
#endif
@@ -117,7 +81,7 @@ bool CFileBase::Create(CFSTR fileName, DWORD desiredAccess,
return (_handle != INVALID_HANDLE_VALUE);
}
-bool CFileBase::Close()
+bool CFileBase::Close() throw()
{
if (_handle == INVALID_HANDLE_VALUE)
return true;
@@ -127,17 +91,17 @@ bool CFileBase::Close()
return true;
}
-bool CFileBase::GetPosition(UInt64 &position) const
+bool CFileBase::GetPosition(UInt64 &position) const throw()
{
return Seek(0, FILE_CURRENT, position);
}
-bool CFileBase::GetLength(UInt64 &length) const
+bool CFileBase::GetLength(UInt64 &length) const throw()
{
#ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceFile && LengthDefined)
+ if (IsDeviceFile && SizeDefined)
{
- length = Length;
+ length = Size;
return true;
}
#endif
@@ -151,98 +115,195 @@ bool CFileBase::GetLength(UInt64 &length) const
return true;
}
-bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const
+bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const throw()
{
#ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceFile && LengthDefined && moveMethod == FILE_END)
+ if (IsDeviceFile && SizeDefined && moveMethod == FILE_END)
{
- distanceToMove += Length;
+ distanceToMove += Size;
moveMethod = FILE_BEGIN;
}
#endif
- LARGE_INTEGER value;
- value.QuadPart = distanceToMove;
- value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod);
- if (value.LowPart == 0xFFFFFFFF)
+ LONG high = (LONG)(distanceToMove >> 32);
+ DWORD low = ::SetFilePointer(_handle, (LONG)(distanceToMove & 0xFFFFFFFF), &high, moveMethod);
+ if (low == 0xFFFFFFFF)
if (::GetLastError() != NO_ERROR)
return false;
- newPosition = value.QuadPart;
+ newPosition = (((UInt64)(UInt32)high) << 32) + low;
return true;
}
-bool CFileBase::Seek(UInt64 position, UInt64 &newPosition)
+bool CFileBase::Seek(UInt64 position, UInt64 &newPosition) const throw()
{
return Seek(position, FILE_BEGIN, newPosition);
}
-bool CFileBase::SeekToBegin()
+bool CFileBase::SeekToBegin() const throw()
{
UInt64 newPosition;
return Seek(0, newPosition);
}
-bool CFileBase::SeekToEnd(UInt64 &newPosition)
+bool CFileBase::SeekToEnd(UInt64 &newPosition) const throw()
{
return Seek(0, FILE_END, newPosition);
}
-/*
-bool CFileBase::GetFileInformation(CByHandleFileInfo &fi) const
-{
- BY_HANDLE_FILE_INFORMATION wfi;
- if (!::GetFileInformationByHandle(_handle, &wfi))
- return false;
- fi.Attrib = wfi.dwFileAttributes;
- fi.CTime = wfi.ftCreationTime;
- fi.ATime = wfi.ftLastAccessTime;
- fi.MTime = wfi.ftLastWriteTime;
- fi.Size = (((UInt64)wfi.nFileSizeHigh) << 32) + wfi.nFileSizeLow;
- fi.VolumeSerialNumber = wfi.dwVolumeSerialNumber;
- fi.NumLinks = wfi.nNumberOfLinks;
- fi.FileIndex = (((UInt64)wfi.nFileIndexHigh) << 32) + wfi.nFileIndexLow;
- return true;
-}
-*/
-
-/////////////////////////
-// CInFile
+// ---------- CInFile ---------
#ifdef SUPPORT_DEVICE_FILE
-void CInFile::GetDeviceLength()
+
+void CInFile::CorrectDeviceSize()
{
- if (_handle != INVALID_HANDLE_VALUE && IsDeviceFile)
+ // maybe we must decrease kClusterSize to 1 << 12, if we want correct size at tail
+ static const UInt32 kClusterSize = 1 << 14;
+ UInt64 pos = Size & ~(UInt64)(kClusterSize - 1);
+ UInt64 realNewPosition;
+ if (!Seek(pos, realNewPosition))
+ return;
+ Byte *buf = (Byte *)MidAlloc(kClusterSize);
+
+ bool needbackward = true;
+
+ for (;;)
+ {
+ UInt32 processed = 0;
+ // up test is slow for "PhysicalDrive".
+ // processed size for latest block for "PhysicalDrive0" is 0.
+ if (!Read1(buf, kClusterSize, processed))
+ break;
+ if (processed == 0)
+ break;
+ needbackward = false;
+ Size = pos + processed;
+ if (processed != kClusterSize)
+ break;
+ pos += kClusterSize;
+ }
+
+ if (needbackward && pos != 0)
{
- #ifdef UNDER_CE
- LengthDefined = true;
- Length = 128 << 20;
+ pos -= kClusterSize;
+ for (;;)
+ {
+ // break;
+ if (!Seek(pos, realNewPosition))
+ break;
+ if (!buf)
+ {
+ buf = (Byte *)MidAlloc(kClusterSize);
+ if (!buf)
+ break;
+ }
+ UInt32 processed = 0;
+ // that code doesn't work for "PhysicalDrive0"
+ if (!Read1(buf, kClusterSize, processed))
+ break;
+ if (processed != 0)
+ {
+ Size = pos + processed;
+ break;
+ }
+ if (pos == 0)
+ break;
+ pos -= kClusterSize;
+ }
+ }
+ MidFree(buf);
+}
+
- #else
- PARTITION_INFORMATION partInfo;
- LengthDefined = true;
- Length = 0;
+void CInFile::CalcDeviceSize(CFSTR s)
+{
+ SizeDefined = false;
+ Size = 0;
+ if (_handle == INVALID_HANDLE_VALUE || !IsDeviceFile)
+ return;
+ #ifdef UNDER_CE
- if (GetPartitionInfo(&partInfo))
- Length = partInfo.PartitionLength.QuadPart;
+ SizeDefined = true;
+ Size = 128 << 20;
+
+ #else
+
+ PARTITION_INFORMATION partInfo;
+ bool needCorrectSize = true;
+
+ /*
+ WinXP 64-bit:
+
+ HDD \\.\PhysicalDrive0 (MBR):
+ GetPartitionInfo == GeometryEx : corrrect size? (includes tail)
+ Geometry : smaller than GeometryEx (no tail, maybe correct too?)
+ MyGetDiskFreeSpace : FAIL
+ Size correction is slow and block size (kClusterSize) must be small?
+
+ HDD partition \\.\N: (NTFS):
+ MyGetDiskFreeSpace : Size of NTFS clusters. Same size can be calculated after correction
+ GetPartitionInfo : size of partition data: NTFS clusters + TAIL; TAIL contains extra empty sectors and copy of first sector of NTFS
+ Geometry / CdRomGeometry / GeometryEx : size of HDD (not that partition)
+
+ CD-ROM drive (ISO):
+ MyGetDiskFreeSpace : correct size. Same size can be calculated after correction
+ Geometry == CdRomGeometry : smaller than corrrect size
+ GetPartitionInfo == GeometryEx : larger than corrrect size
+
+ Floppy \\.\a: (FAT):
+ Geometry : correct size.
+ CdRomGeometry / GeometryEx / GetPartitionInfo / MyGetDiskFreeSpace - FAIL
+ correction works OK for FAT.
+ correction works OK for non-FAT, if kClusterSize = 512.
+ */
+
+ if (GetPartitionInfo(&partInfo))
+ {
+ Size = partInfo.PartitionLength.QuadPart;
+ SizeDefined = true;
+ needCorrectSize = false;
+ if ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '.' && (s)[3] == '\\' && (s)[5] == ':' && (s)[6] == 0)
+ {
+ FChar path[4] = { s[4], ':', '\\', 0 };
+ UInt64 clusterSize, totalSize, freeSize;
+ if (NSystem::MyGetDiskFreeSpace(path, clusterSize, totalSize, freeSize))
+ Size = totalSize;
+ else
+ needCorrectSize = true;
+ }
+ }
+
+ if (!SizeDefined)
+ {
+ my_DISK_GEOMETRY_EX geomEx;
+ SizeDefined = GetGeometryEx(&geomEx);
+ if (SizeDefined)
+ Size = geomEx.DiskSize.QuadPart;
else
{
DISK_GEOMETRY geom;
- if (!GetGeometry(&geom))
- if (!GetCdRomGeometry(&geom))
- LengthDefined = false;
- if (LengthDefined)
- Length = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector;
+ SizeDefined = GetGeometry(&geom);
+ if (!SizeDefined)
+ SizeDefined = GetCdRomGeometry(&geom);
+ if (SizeDefined)
+ Size = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector;
}
- // SeekToBegin();
- #endif
}
+
+ if (needCorrectSize && SizeDefined && Size != 0)
+ {
+ CorrectDeviceSize();
+ SeekToBegin();
+ }
+
+ // SeekToBegin();
+ #endif
}
// ((desiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA | GENERIC_WRITE)) == 0 &&
#define MY_DEVICE_EXTRA_CODE \
- IsDeviceFile = IsDeviceName(fileName); \
- GetDeviceLength();
+ IsDeviceFile = IsDevicePath(fileName); \
+ CalcDeviceSize(fileName);
#else
#define MY_DEVICE_EXTRA_CODE
#endif
@@ -271,7 +332,7 @@ bool CInFile::Open(CFSTR fileName)
static UInt32 kChunkSizeMax = (1 << 22);
-bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize)
+bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize) throw()
{
DWORD processedLoc = 0;
bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
@@ -279,14 +340,14 @@ bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize)
return res;
}
-bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize)
+bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw()
{
if (size > kChunkSizeMax)
size = kChunkSizeMax;
return Read1(data, size, processedSize);
}
-bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
+bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize) throw()
{
processedSize = 0;
do
@@ -305,8 +366,7 @@ bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
return true;
}
-/////////////////////////
-// COutFile
+// ---------- COutFile ---------
static inline DWORD GetCreationDisposition(bool createAlways)
{ return createAlways? CREATE_ALWAYS: CREATE_NEW; }
@@ -320,12 +380,15 @@ bool COutFile::Open(CFSTR fileName, DWORD creationDisposition)
bool COutFile::Create(CFSTR fileName, bool createAlways)
{ return Open(fileName, GetCreationDisposition(createAlways)); }
-bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
+bool COutFile::CreateAlways(CFSTR fileName, DWORD flagsAndAttributes)
+ { return Open(fileName, FILE_SHARE_READ, GetCreationDisposition(true), flagsAndAttributes); }
+
+bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw()
{ return BOOLToBool(::SetFileTime(_handle, cTime, aTime, mTime)); }
-bool COutFile::SetMTime(const FILETIME *mTime) { return SetTime(NULL, NULL, mTime); }
+bool COutFile::SetMTime(const FILETIME *mTime) throw() { return SetTime(NULL, NULL, mTime); }
-bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
+bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw()
{
if (size > kChunkSizeMax)
size = kChunkSizeMax;
@@ -335,7 +398,7 @@ bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
return res;
}
-bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
+bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize) throw()
{
processedSize = 0;
do
@@ -354,9 +417,9 @@ bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
return true;
}
-bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); }
+bool COutFile::SetEndOfFile() throw() { return BOOLToBool(::SetEndOfFile(_handle)); }
-bool COutFile::SetLength(UInt64 length)
+bool COutFile::SetLength(UInt64 length) throw()
{
UInt64 newPosition;
if (!Seek(length, newPosition))
diff --git a/3rdparty/lzma/CPP/Windows/FileIO.h b/3rdparty/lzma/CPP/Windows/FileIO.h
index ecd7af964be..32c285fb9cc 100644
--- a/3rdparty/lzma/CPP/Windows/FileIO.h
+++ b/3rdparty/lzma/CPP/Windows/FileIO.h
@@ -3,96 +3,163 @@
#ifndef __WINDOWS_FILE_IO_H
#define __WINDOWS_FILE_IO_H
-#include "../Common/Types.h"
+#include "../Common/MyWindows.h"
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+#include <winioctl.h>
+#endif
+
#include "../Common/MyString.h"
+#include "../Common/MyBuffer.h"
#include "Defs.h"
+#define _my_IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
+#define _my_IO_REPARSE_TAG_SYMLINK (0xA000000CL)
+
+#define _my_SYMLINK_FLAG_RELATIVE 1
+
+#define my_FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // REPARSE_DATA_BUFFER
+#define my_FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) // REPARSE_DATA_BUFFER
+
namespace NWindows {
namespace NFile {
-namespace NIO {
-/*
-struct CByHandleFileInfo
+#if defined(_WIN32) && !defined(UNDER_CE)
+bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink);
+#endif
+
+struct CReparseShortInfo
+{
+ unsigned Offset;
+ unsigned Size;
+
+ bool Parse(const Byte *p, size_t size);
+};
+
+struct CReparseAttr
{
- UInt64 Size;
- FILETIME CTime;
- FILETIME ATime;
- FILETIME MTime;
- DWORD Attrib;
- DWORD VolumeSerialNumber;
- DWORD NumLinks;
- UInt64 FileIndex;
+ UInt32 Tag;
+ UInt32 Flags;
+ UString SubsName;
+ UString PrintName;
+
+ CReparseAttr(): Tag(0), Flags(0) {}
+ bool Parse(const Byte *p, size_t size);
+
+ bool IsMountPoint() const { return Tag == _my_IO_REPARSE_TAG_MOUNT_POINT; } // it's Junction
+ bool IsSymLink() const { return Tag == _my_IO_REPARSE_TAG_SYMLINK; }
+ bool IsRelative() const { return Flags == _my_SYMLINK_FLAG_RELATIVE; }
+ // bool IsVolume() const;
+
+ bool IsOkNamePair() const;
+ UString GetPath() const;
};
-*/
+
+namespace NIO {
+
+bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo = NULL);
+bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size);
class CFileBase
{
protected:
HANDLE _handle;
- bool Create(CFSTR fileName, DWORD desiredAccess,
+ bool Create(CFSTR path, DWORD desiredAccess,
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
public:
+
+ bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inSize,
+ LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned, LPOVERLAPPED overlapped = NULL) const
+ {
+ return BOOLToBool(::DeviceIoControl(_handle, controlCode, inBuffer, inSize,
+ outBuffer, outSize, bytesReturned, overlapped));
+ }
+
+ bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned) const
+ {
+ return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize, bytesReturned);
+ }
+
+ bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize) const
+ {
+ DWORD bytesReturned;
+ return DeviceIoControlOut(controlCode, outBuffer, outSize, &bytesReturned);
+ }
+
+public:
#ifdef SUPPORT_DEVICE_FILE
bool IsDeviceFile;
- bool LengthDefined;
- UInt64 Length;
+ bool SizeDefined;
+ UInt64 Size; // it can be larger than real available size
#endif
CFileBase(): _handle(INVALID_HANDLE_VALUE) {};
- ~CFileBase();
+ ~CFileBase() { Close(); }
- bool Close();
+ bool Close() throw();
- bool GetPosition(UInt64 &position) const;
- bool GetLength(UInt64 &length) const;
+ bool GetPosition(UInt64 &position) const throw();
+ bool GetLength(UInt64 &length) const throw();
- bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const;
- bool Seek(UInt64 position, UInt64 &newPosition);
- bool SeekToBegin();
- bool SeekToEnd(UInt64 &newPosition);
+ bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const throw();
+ bool Seek(UInt64 position, UInt64 &newPosition) const throw();
+ bool SeekToBegin() const throw();
+ bool SeekToEnd(UInt64 &newPosition) const throw();
- // bool GetFileInformation(CByHandleFileInfo &fileInfo) const;
+ bool GetFileInformation(BY_HANDLE_FILE_INFORMATION *info) const
+ { return BOOLToBool(GetFileInformationByHandle(_handle, info)); }
+
+ static bool GetFileInformation(CFSTR path, BY_HANDLE_FILE_INFORMATION *info)
+ {
+ NIO::CFileBase file;
+ if (!file.Create(path, 0, FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS))
+ return false;
+ return file.GetFileInformation(info);
+ }
};
+#ifndef UNDER_CE
#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS)
-#define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
+// #define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
+
+// IOCTL_DISK_GET_DRIVE_GEOMETRY_EX works since WinXP
+#define my_IOCTL_DISK_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_DISK_BASE, 0x0028, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+struct my_DISK_GEOMETRY_EX
+{
+ DISK_GEOMETRY Geometry;
+ LARGE_INTEGER DiskSize;
+ BYTE Data[1];
+};
+#endif
class CInFile: public CFileBase
{
#ifdef SUPPORT_DEVICE_FILE
- bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inSize,
- LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned, LPOVERLAPPED overlapped) const
- {
- return BOOLToBool(::DeviceIoControl(_handle, controlCode, inBuffer, inSize,
- outBuffer, outSize, bytesReturned, overlapped));
- }
-
- bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer,
- DWORD inSize, LPVOID outBuffer, DWORD outSize) const
- {
- DWORD ret;
- return DeviceIoControl(controlCode, inBuffer, inSize, outBuffer, outSize, &ret, 0);
- }
-
- bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize) const
- { return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize); }
#ifndef UNDER_CE
+
bool GetGeometry(DISK_GEOMETRY *res) const
{ return DeviceIoControlOut(IOCTL_DISK_GET_DRIVE_GEOMETRY, res, sizeof(*res)); }
+ bool GetGeometryEx(my_DISK_GEOMETRY_EX *res) const
+ { return DeviceIoControlOut(my_IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, res, sizeof(*res)); }
+
bool GetCdRomGeometry(DISK_GEOMETRY *res) const
{ return DeviceIoControlOut(IOCTL_CDROM_GET_DRIVE_GEOMETRY, res, sizeof(*res)); }
bool GetPartitionInfo(PARTITION_INFORMATION *res)
{ return DeviceIoControlOut(IOCTL_DISK_GET_PARTITION_INFO, LPVOID(res), sizeof(*res)); }
+
#endif
- void GetDeviceLength();
+ void CorrectDeviceSize();
+ void CalcDeviceSize(CFSTR name);
+
#endif
public:
@@ -100,9 +167,19 @@ public:
bool OpenShared(CFSTR fileName, bool shareForWrite);
bool Open(CFSTR fileName);
- bool Read1(void *data, UInt32 size, UInt32 &processedSize);
- bool ReadPart(void *data, UInt32 size, UInt32 &processedSize);
- bool Read(void *data, UInt32 size, UInt32 &processedSize);
+ #ifndef UNDER_CE
+
+ bool OpenReparse(CFSTR fileName)
+ {
+ return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS);
+ }
+
+ #endif
+
+ bool Read1(void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool Read(void *data, UInt32 size, UInt32 &processedSize) throw();
};
class COutFile: public CFileBase
@@ -111,13 +188,14 @@ public:
bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
bool Open(CFSTR fileName, DWORD creationDisposition);
bool Create(CFSTR fileName, bool createAlways);
-
- bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
- bool SetMTime(const FILETIME *mTime);
- bool WritePart(const void *data, UInt32 size, UInt32 &processedSize);
- bool Write(const void *data, UInt32 size, UInt32 &processedSize);
- bool SetEndOfFile();
- bool SetLength(UInt64 length);
+ bool CreateAlways(CFSTR fileName, DWORD flagsAndAttributes);
+
+ bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw();
+ bool SetMTime(const FILETIME *mTime) throw();
+ bool WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool Write(const void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool SetEndOfFile() throw();
+ bool SetLength(UInt64 length) throw();
};
}}}
diff --git a/3rdparty/lzma/CPP/Windows/FileLink.cpp b/3rdparty/lzma/CPP/Windows/FileLink.cpp
new file mode 100644
index 00000000000..25d49ac3ed6
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/FileLink.cpp
@@ -0,0 +1,436 @@
+// Windows/FileLink.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/CpuArch.h"
+
+#ifdef SUPPORT_DEVICE_FILE
+#include "../../C/Alloc.h"
+#endif
+
+#include "FileDir.h"
+#include "FileFind.h"
+#include "FileIO.h"
+#include "FileName.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+using namespace NName;
+
+/*
+ Reparse Points (Junctions and Symbolic Links):
+ struct
+ {
+ UInt32 Tag;
+ UInt16 Size; // not including starting 8 bytes
+ UInt16 Reserved; // = 0
+
+ UInt16 SubstituteOffset; // offset in bytes from start of namesChars
+ UInt16 SubstituteLen; // size in bytes, it doesn't include tailed NUL
+ UInt16 PrintOffset; // offset in bytes from start of namesChars
+ UInt16 PrintLen; // size in bytes, it doesn't include tailed NUL
+
+ [UInt32] Flags; // for Symbolic Links only.
+
+ UInt16 namesChars[]
+ }
+
+ MOUNT_POINT (Junction point):
+ 1) there is NUL wchar after path
+ 2) Default Order in table:
+ Substitute Path
+ Print Path
+ 3) pathnames can not contain dot directory names
+
+ SYMLINK:
+ 1) there is no NUL wchar after path
+ 2) Default Order in table:
+ Print Path
+ Substitute Path
+*/
+
+/*
+static const UInt32 kReparseFlags_Alias = (1 << 29);
+static const UInt32 kReparseFlags_HighLatency = (1 << 30);
+static const UInt32 kReparseFlags_Microsoft = ((UInt32)1 << 31);
+
+#define _my_IO_REPARSE_TAG_HSM (0xC0000004L)
+#define _my_IO_REPARSE_TAG_HSM2 (0x80000006L)
+#define _my_IO_REPARSE_TAG_SIS (0x80000007L)
+#define _my_IO_REPARSE_TAG_WIM (0x80000008L)
+#define _my_IO_REPARSE_TAG_CSV (0x80000009L)
+#define _my_IO_REPARSE_TAG_DFS (0x8000000AL)
+#define _my_IO_REPARSE_TAG_DFSR (0x80000012L)
+*/
+
+#define Get16(p) GetUi16(p)
+#define Get32(p) GetUi32(p)
+
+#define Set16(p, v) SetUi16(p, v)
+#define Set32(p, v) SetUi32(p, v)
+
+static const wchar_t *k_LinkPrefix = L"\\??\\";
+static const unsigned k_LinkPrefix_Size = 4;
+
+static const bool IsLinkPrefix(const wchar_t *s)
+{
+ return IsString1PrefixedByString2(s, k_LinkPrefix);
+}
+
+/*
+static const wchar_t *k_VolumePrefix = L"Volume{";
+static const bool IsVolumeName(const wchar_t *s)
+{
+ return IsString1PrefixedByString2(s, k_VolumePrefix);
+}
+*/
+
+void WriteString(Byte *dest, const wchar_t *path)
+{
+ for (;;)
+ {
+ wchar_t c = *path++;
+ if (c == 0)
+ return;
+ Set16(dest, (UInt16)c);
+ dest += 2;
+ }
+}
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink)
+{
+ bool isAbs = IsAbsolutePath(path);
+ if (!isAbs && !isSymLink)
+ return false;
+
+ bool needPrintName = true;
+
+ if (IsSuperPath(path))
+ {
+ path += kSuperPathPrefixSize;
+ if (!IsDrivePath(path))
+ needPrintName = false;
+ }
+
+ const unsigned add_Prefix_Len = isAbs ? k_LinkPrefix_Size : 0;
+
+ unsigned len2 = MyStringLen(path) * 2;
+ const unsigned len1 = len2 + add_Prefix_Len * 2;
+ if (!needPrintName)
+ len2 = 0;
+
+ unsigned totalNamesSize = (len1 + len2);
+
+ /* some WIM imagex software uses old scheme for symbolic links.
+ so we can old scheme for byte to byte compatibility */
+
+ bool newOrderScheme = isSymLink;
+ // newOrderScheme = false;
+
+ if (!newOrderScheme)
+ totalNamesSize += 2 * 2;
+
+ const size_t size = 8 + 8 + (isSymLink ? 4 : 0) + totalNamesSize;
+ dest.Alloc(size);
+ memset(dest, 0, size);
+ const UInt32 tag = isSymLink ?
+ _my_IO_REPARSE_TAG_SYMLINK :
+ _my_IO_REPARSE_TAG_MOUNT_POINT;
+ Byte *p = dest;
+ Set32(p, tag);
+ Set16(p + 4, (UInt16)(size - 8));
+ Set16(p + 6, 0);
+ p += 8;
+
+ unsigned subOffs = 0;
+ unsigned printOffs = 0;
+ if (newOrderScheme)
+ subOffs = len2;
+ else
+ printOffs = len1 + 2;
+
+ Set16(p + 0, (UInt16)subOffs);
+ Set16(p + 2, (UInt16)len1);
+ Set16(p + 4, (UInt16)printOffs);
+ Set16(p + 6, (UInt16)len2);
+
+ p += 8;
+ if (isSymLink)
+ {
+ UInt32 flags = isAbs ? 0 : _my_SYMLINK_FLAG_RELATIVE;
+ Set32(p, flags);
+ p += 4;
+ }
+
+ if (add_Prefix_Len != 0)
+ WriteString(p + subOffs, k_LinkPrefix);
+ WriteString(p + subOffs + add_Prefix_Len * 2, path);
+ if (needPrintName)
+ WriteString(p + printOffs, path);
+ return true;
+}
+
+#endif
+
+static void GetString(const Byte *p, unsigned len, UString &res)
+{
+ wchar_t *s = res.GetBuf(len);
+ unsigned i;
+ for (i = 0; i < len; i++)
+ {
+ wchar_t c = Get16(p + i * 2);
+ if (c == 0)
+ break;
+ s[i] = c;
+ }
+ s[i] = 0;
+ res.ReleaseBuf_SetLen(i);
+}
+
+bool CReparseAttr::Parse(const Byte *p, size_t size)
+{
+ if (size < 8)
+ return false;
+ Tag = Get32(p);
+ UInt32 len = Get16(p + 4);
+ if (len + 8 > size)
+ return false;
+ /*
+ if ((type & kReparseFlags_Alias) == 0 ||
+ (type & kReparseFlags_Microsoft) == 0 ||
+ (type & 0xFFFF) != 3)
+ */
+ if (Tag != _my_IO_REPARSE_TAG_MOUNT_POINT &&
+ Tag != _my_IO_REPARSE_TAG_SYMLINK)
+ // return true;
+ return false;
+
+ if (Get16(p + 6) != 0) // padding
+ return false;
+
+ p += 8;
+ size -= 8;
+
+ if (len != size) // do we need that check?
+ return false;
+
+ if (len < 8)
+ return false;
+ unsigned subOffs = Get16(p);
+ unsigned subLen = Get16(p + 2);
+ unsigned printOffs = Get16(p + 4);
+ unsigned printLen = Get16(p + 6);
+ len -= 8;
+ p += 8;
+
+ Flags = 0;
+ if (Tag == _my_IO_REPARSE_TAG_SYMLINK)
+ {
+ if (len < 4)
+ return false;
+ Flags = Get32(p);
+ len -= 4;
+ p += 4;
+ }
+
+ if ((subOffs & 1) != 0 || subOffs > len || len - subOffs < subLen)
+ return false;
+ if ((printOffs & 1) != 0 || printOffs > len || len - printOffs < printLen)
+ return false;
+ GetString(p + subOffs, subLen >> 1, SubsName);
+ GetString(p + printOffs, printLen >> 1, PrintName);
+
+ return true;
+}
+
+bool CReparseShortInfo::Parse(const Byte *p, size_t size)
+{
+ const Byte *start = p;
+ Offset= 0;
+ Size = 0;
+ if (size < 8)
+ return false;
+ UInt32 Tag = Get32(p);
+ UInt32 len = Get16(p + 4);
+ if (len + 8 > size)
+ return false;
+ /*
+ if ((type & kReparseFlags_Alias) == 0 ||
+ (type & kReparseFlags_Microsoft) == 0 ||
+ (type & 0xFFFF) != 3)
+ */
+ if (Tag != _my_IO_REPARSE_TAG_MOUNT_POINT &&
+ Tag != _my_IO_REPARSE_TAG_SYMLINK)
+ // return true;
+ return false;
+
+ if (Get16(p + 6) != 0) // padding
+ return false;
+
+ p += 8;
+ size -= 8;
+
+ if (len != size) // do we need that check?
+ return false;
+
+ if (len < 8)
+ return false;
+ unsigned subOffs = Get16(p);
+ unsigned subLen = Get16(p + 2);
+ unsigned printOffs = Get16(p + 4);
+ unsigned printLen = Get16(p + 6);
+ len -= 8;
+ p += 8;
+
+ // UInt32 Flags = 0;
+ if (Tag == _my_IO_REPARSE_TAG_SYMLINK)
+ {
+ if (len < 4)
+ return false;
+ // Flags = Get32(p);
+ len -= 4;
+ p += 4;
+ }
+
+ if ((subOffs & 1) != 0 || subOffs > len || len - subOffs < subLen)
+ return false;
+ if ((printOffs & 1) != 0 || printOffs > len || len - printOffs < printLen)
+ return false;
+
+ Offset = (unsigned)(p - start) + subOffs;
+ Size = subLen;
+ return true;
+}
+
+bool CReparseAttr::IsOkNamePair() const
+{
+ if (IsLinkPrefix(SubsName))
+ {
+ if (!IsDrivePath(SubsName.Ptr(k_LinkPrefix_Size)))
+ return PrintName.IsEmpty();
+ if (wcscmp(SubsName.Ptr(k_LinkPrefix_Size), PrintName) == 0)
+ return true;
+ }
+ return wcscmp(SubsName, PrintName) == 0;
+}
+
+/*
+bool CReparseAttr::IsVolume() const
+{
+ if (!IsLinkPrefix(SubsName))
+ return false;
+ return IsVolumeName(SubsName.Ptr(k_LinkPrefix_Size));
+}
+*/
+
+UString CReparseAttr::GetPath() const
+{
+ UString s = SubsName;
+ if (IsLinkPrefix(s))
+ {
+ s.ReplaceOneCharAtPos(1, '\\');
+ if (IsDrivePath(s.Ptr(k_LinkPrefix_Size)))
+ s.DeleteFrontal(k_LinkPrefix_Size);
+ }
+ return s;
+}
+
+
+#ifdef SUPPORT_DEVICE_FILE
+
+namespace NSystem
+{
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
+}
+#endif
+
+#ifndef UNDER_CE
+
+namespace NIO {
+
+bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo)
+{
+ reparseData.Free();
+ CInFile file;
+ if (!file.OpenReparse(path))
+ return false;
+
+ if (fileInfo)
+ file.GetFileInformation(fileInfo);
+
+ const unsigned kBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
+ CByteArr buf(kBufSize);
+ DWORD returnedSize;
+ if (!file.DeviceIoControlOut(my_FSCTL_GET_REPARSE_POINT, buf, kBufSize, &returnedSize))
+ return false;
+ reparseData.CopyFrom(buf, returnedSize);
+ return true;
+}
+
+static bool CreatePrefixDirOfFile(CFSTR path)
+{
+ FString path2 = path;
+ int pos = path2.ReverseFind_PathSepar();
+ if (pos < 0)
+ return true;
+ #ifdef _WIN32
+ if (pos == 2 && path2[1] == L':')
+ return true; // we don't create Disk folder;
+ #endif
+ path2.DeleteFrom(pos);
+ return NDir::CreateComplexDir(path2);
+}
+
+// If there is Reprase data already, it still writes new Reparse data
+bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size)
+{
+ NFile::NFind::CFileInfo fi;
+ if (fi.Find(path))
+ {
+ if (fi.IsDir() != isDir)
+ {
+ ::SetLastError(ERROR_DIRECTORY);
+ return false;
+ }
+ }
+ else
+ {
+ if (isDir)
+ {
+ if (!NDir::CreateComplexDir(path))
+ return false;
+ }
+ else
+ {
+ CreatePrefixDirOfFile(path);
+ COutFile file;
+ if (!file.Create(path, CREATE_NEW))
+ return false;
+ }
+ }
+
+ COutFile file;
+ if (!file.Open(path,
+ FILE_SHARE_WRITE,
+ OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS))
+ return false;
+
+ DWORD returnedSize;
+ if (!file.DeviceIoControl(my_FSCTL_SET_REPARSE_POINT, (void *)data, size, NULL, 0, &returnedSize))
+ return false;
+ return true;
+}
+
+}
+
+#endif
+
+}}
diff --git a/3rdparty/lzma/CPP/Windows/FileMapping.cpp b/3rdparty/lzma/CPP/Windows/FileMapping.cpp
index 55048fdb239..1933f7c8b19 100644
--- a/3rdparty/lzma/CPP/Windows/FileMapping.cpp
+++ b/3rdparty/lzma/CPP/Windows/FileMapping.cpp
@@ -2,7 +2,7 @@
#include "StdAfx.h"
-#include "Windows/FileMapping.h"
+#include "FileMapping.h"
namespace NWindows {
namespace NFile {
diff --git a/3rdparty/lzma/CPP/Windows/FileMapping.h b/3rdparty/lzma/CPP/Windows/FileMapping.h
index 3f0ebd74cc6..f90c429f1d7 100644
--- a/3rdparty/lzma/CPP/Windows/FileMapping.h
+++ b/3rdparty/lzma/CPP/Windows/FileMapping.h
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_FILEMAPPING_H
#define __WINDOWS_FILEMAPPING_H
-#include "Common/Types.h"
+#include "../Common/MyTypes.h"
#include "Handle.h"
@@ -18,7 +18,11 @@ public:
return ::GetLastError();
}
- WRes Open(DWORD desiredAccess, LPCTSTR name)
+ WRes Open(DWORD
+ #ifndef UNDER_CE
+ desiredAccess
+ #endif
+ , LPCTSTR name)
{
#ifdef UNDER_CE
WRes res = Create(PAGE_READONLY, 0, name);
diff --git a/3rdparty/lzma/CPP/Windows/FileName.cpp b/3rdparty/lzma/CPP/Windows/FileName.cpp
index 8f464aa8681..382c2e56677 100644
--- a/3rdparty/lzma/CPP/Windows/FileName.cpp
+++ b/3rdparty/lzma/CPP/Windows/FileName.cpp
@@ -4,26 +4,826 @@
#include "FileName.h"
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
namespace NWindows {
namespace NFile {
namespace NName {
+#define IS_SEPAR(c) IS_PATH_SEPAR(c)
+
+int FindSepar(const wchar_t *s) throw()
+{
+ for (const wchar_t *p = s;; p++)
+ {
+ const wchar_t c = *p;
+ if (c == 0)
+ return -1;
+ if (IS_SEPAR(c))
+ return (int)(p - s);
+ }
+}
+
+#ifndef USE_UNICODE_FSTRING
+int FindSepar(const FChar *s) throw()
+{
+ for (const FChar *p = s;; p++)
+ {
+ const FChar c = *p;
+ if (c == 0)
+ return -1;
+ if (IS_SEPAR(c))
+ return (int)(p - s);
+ }
+}
+#endif
+
+#ifndef USE_UNICODE_FSTRING
void NormalizeDirPathPrefix(FString &dirPath)
{
if (dirPath.IsEmpty())
return;
- if (dirPath.ReverseFind(FCHAR_PATH_SEPARATOR) != dirPath.Length() - 1)
- dirPath += FCHAR_PATH_SEPARATOR;
+ if (!IsPathSepar(dirPath.Back()))
+ dirPath.Add_PathSepar();
}
+#endif
-#ifndef USE_UNICODE_FSTRING
void NormalizeDirPathPrefix(UString &dirPath)
{
if (dirPath.IsEmpty())
return;
- if (dirPath.ReverseFind(WCHAR_PATH_SEPARATOR) != dirPath.Length() - 1)
- dirPath += WCHAR_PATH_SEPARATOR;
+ if (!IsPathSepar(dirPath.Back()))
+ dirPath.Add_PathSepar();
+}
+
+#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
+
+bool IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]); }
+
+bool IsAltPathPrefix(CFSTR s) throw()
+{
+ unsigned len = MyStringLen(s);
+ if (len == 0)
+ return false;
+ if (s[len - 1] != ':')
+ return false;
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (IsDevicePath(s))
+ return false;
+ if (IsSuperPath(s))
+ {
+ s += kSuperPathPrefixSize;
+ len -= kSuperPathPrefixSize;
+ }
+ if (len == 2 && IsDrivePath2(s))
+ return false;
+ #endif
+
+ return true;
+}
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+const wchar_t *kSuperPathPrefix = L"\\\\?\\";
+static const wchar_t *kSuperUncPrefix = L"\\\\?\\UNC\\";
+
+#define IS_DEVICE_PATH(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && (s)[2] == '.' && IS_SEPAR((s)[3]))
+#define IS_SUPER_PREFIX(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && (s)[2] == '?' && IS_SEPAR((s)[3]))
+#define IS_SUPER_OR_DEVICE_PATH(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && ((s)[2] == '?' || (s)[2] == '.') && IS_SEPAR((s)[3]))
+
+#define IS_UNC_WITH_SLASH(s) ( \
+ ((s)[0] == 'U' || (s)[0] == 'u') \
+ && ((s)[1] == 'N' || (s)[1] == 'n') \
+ && ((s)[2] == 'C' || (s)[2] == 'c') \
+ && IS_SEPAR((s)[3]))
+
+bool IsDevicePath(CFSTR s) throw()
+{
+ #ifdef UNDER_CE
+
+ s = s;
+ return false;
+ /*
+ // actually we don't know the way to open device file in WinCE.
+ unsigned len = MyStringLen(s);
+ if (len < 5 || len > 5 || memcmp(s, FTEXT("DSK"), 3 * sizeof(FChar)) != 0)
+ return false;
+ if (s[4] != ':')
+ return false;
+ // for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ));
+ */
+
+ #else
+
+ if (!IS_DEVICE_PATH(s))
+ return false;
+ unsigned len = MyStringLen(s);
+ if (len == 6 && s[5] == ':')
+ return true;
+ if (len < 18 || len > 22 || memcmp(s + kDevicePathPrefixSize, FTEXT("PhysicalDrive"), 13 * sizeof(FChar)) != 0)
+ return false;
+ for (unsigned i = 17; i < len; i++)
+ if (s[i] < '0' || s[i] > '9')
+ return false;
+ return true;
+
+ #endif
+}
+
+bool IsSuperUncPath(CFSTR s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
+bool IsNetworkPath(CFSTR s) throw()
+{
+ if (!IS_SEPAR(s[0]) || !IS_SEPAR(s[1]))
+ return false;
+ if (IsSuperUncPath(s))
+ return true;
+ FChar c = s[2];
+ return (c != '.' && c != '?');
+}
+
+unsigned GetNetworkServerPrefixSize(CFSTR s) throw()
+{
+ if (!IS_SEPAR(s[0]) || !IS_SEPAR(s[1]))
+ return 0;
+ unsigned prefixSize = 2;
+ if (IsSuperUncPath(s))
+ prefixSize = kSuperUncPathPrefixSize;
+ else
+ {
+ FChar c = s[2];
+ if (c == '.' || c == '?')
+ return 0;
+ }
+ int pos = FindSepar(s + prefixSize);
+ if (pos < 0)
+ return 0;
+ return prefixSize + pos + 1;
+}
+
+bool IsNetworkShareRootPath(CFSTR s) throw()
+{
+ unsigned prefixSize = GetNetworkServerPrefixSize(s);
+ if (prefixSize == 0)
+ return false;
+ s += prefixSize;
+ int pos = FindSepar(s);
+ if (pos < 0)
+ return true;
+ return s[(unsigned)pos + 1] == 0;
+}
+
+static const unsigned kDrivePrefixSize = 3; /* c:\ */
+
+bool IsDrivePath2(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':'; }
+// bool IsDriveName2(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == 0; }
+bool IsSuperPath(const wchar_t *s) throw() { return IS_SUPER_PREFIX(s); }
+bool IsSuperOrDevicePath(const wchar_t *s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); }
+// bool IsSuperUncPath(const wchar_t *s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
+
+#ifndef USE_UNICODE_FSTRING
+bool IsDrivePath2(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':'; }
+// bool IsDriveName2(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == 0; }
+bool IsDrivePath(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]); }
+bool IsSuperPath(CFSTR s) throw() { return IS_SUPER_PREFIX(s); }
+bool IsSuperOrDevicePath(CFSTR s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); }
+#endif // USE_UNICODE_FSTRING
+
+/*
+bool IsDrivePath_SuperAllowed(CFSTR s)
+{
+ if (IsSuperPath(s))
+ s += kSuperPathPrefixSize;
+ return IsDrivePath(s);
+}
+*/
+
+bool IsDriveRootPath_SuperAllowed(CFSTR s) throw()
+{
+ if (IsSuperPath(s))
+ s += kSuperPathPrefixSize;
+ return IsDrivePath(s) && s[kDrivePrefixSize] == 0;
+}
+
+bool IsAbsolutePath(const wchar_t *s) throw()
+{
+ return IS_SEPAR(s[0]) || IsDrivePath2(s);
+}
+
+int FindAltStreamColon(CFSTR path)
+{
+ unsigned i = 0;
+ if (IsDrivePath2(path))
+ i = 2;
+ int colonPos = -1;
+ for (;; i++)
+ {
+ FChar c = path[i];
+ if (c == 0)
+ return colonPos;
+ if (c == ':')
+ {
+ if (colonPos < 0)
+ colonPos = i;
+ continue;
+ }
+ if (IS_SEPAR(c))
+ colonPos = -1;
+ }
+}
+
+#ifndef USE_UNICODE_FSTRING
+
+static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s)
+{
+ // Network path: we look "server\path\" as root prefix
+ int pos = FindSepar(s);
+ if (pos < 0)
+ return 0;
+ int pos2 = FindSepar(s + (unsigned)pos + 1);
+ if (pos2 < 0)
+ return 0;
+ return pos + pos2 + 2;
+}
+
+static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s)
+{
+ if (IsDrivePath(s))
+ return kDrivePrefixSize;
+ if (!IS_SEPAR(s[0]))
+ return 0;
+ if (s[1] == 0 || !IS_SEPAR(s[1]))
+ return 1;
+ unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
+ return (size == 0) ? 0 : 2 + size;
+}
+
+static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s)
+{
+ if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
+ {
+ unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize);
+ return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
+ }
+ // we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
+ int pos = FindSepar(s + kSuperPathPrefixSize);
+ if (pos < 0)
+ return 0;
+ return kSuperPathPrefixSize + pos + 1;
+}
+
+unsigned GetRootPrefixSize(CFSTR s)
+{
+ if (IS_DEVICE_PATH(s))
+ return kDevicePathPrefixSize;
+ if (IsSuperPath(s))
+ return GetRootPrefixSize_Of_SuperPath(s);
+ return GetRootPrefixSize_Of_SimplePath(s);
+}
+
+#endif // USE_UNICODE_FSTRING
+
+static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s)
+{
+ // Network path: we look "server\path\" as root prefix
+ int pos = FindSepar(s);
+ if (pos < 0)
+ return 0;
+ int pos2 = FindSepar(s + (unsigned)pos + 1);
+ if (pos2 < 0)
+ return 0;
+ return pos + pos2 + 2;
+}
+
+static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s)
+{
+ if (IsDrivePath(s))
+ return kDrivePrefixSize;
+ if (!IS_SEPAR(s[0]))
+ return 0;
+ if (s[1] == 0 || !IS_SEPAR(s[1]))
+ return 1;
+ unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
+ return (size == 0) ? 0 : 2 + size;
+}
+
+static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s)
+{
+ if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
+ {
+ unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize);
+ return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
+ }
+ // we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
+ int pos = FindSepar(s + kSuperPathPrefixSize);
+ if (pos < 0)
+ return 0;
+ return kSuperPathPrefixSize + pos + 1;
}
+
+unsigned GetRootPrefixSize(const wchar_t *s) throw()
+{
+ if (IS_DEVICE_PATH(s))
+ return kDevicePathPrefixSize;
+ if (IsSuperPath(s))
+ return GetRootPrefixSize_Of_SuperPath(s);
+ return GetRootPrefixSize_Of_SimplePath(s);
+}
+
+#else // _WIN32
+
+bool IsAbsolutePath(const wchar_t *s) { return IS_SEPAR(s[0]); }
+
+#ifndef USE_UNICODE_FSTRING
+unsigned GetRootPrefixSize(CFSTR s) { return IS_SEPAR(s[0]) ? 1 : 0; }
#endif
+unsigned GetRootPrefixSize(const wchar_t *s) { return IS_SEPAR(s[0]) ? 1 : 0; }
+
+#endif // _WIN32
+
+
+#ifndef UNDER_CE
+
+static bool GetCurDir(UString &path)
+{
+ path.Empty();
+ DWORD needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetCurrentDirectory(MAX_PATH + 1, s);
+ path = fs2us(fas2fs(s));
+ }
+ else
+ #endif
+ {
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, s);
+ path = s;
+ }
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+static bool ResolveDotsFolders(UString &s)
+{
+ #ifdef _WIN32
+ // s.Replace(L'/', WCHAR_PATH_SEPARATOR);
+ #endif
+ for (unsigned i = 0;;)
+ {
+ wchar_t c = s[i];
+ if (c == 0)
+ return true;
+ if (c == '.' && (i == 0 || IS_SEPAR(s[i - 1])))
+ {
+ wchar_t c1 = s[i + 1];
+ if (c1 == '.')
+ {
+ wchar_t c2 = s[i + 2];
+ if (IS_SEPAR(c2) || c2 == 0)
+ {
+ if (i == 0)
+ return false;
+ int k = i - 2;
+ for (; k >= 0; k--)
+ if (IS_SEPAR(s[(unsigned)k]))
+ break;
+ unsigned num;
+ if (k >= 0)
+ {
+ num = i + 2 - k;
+ i = k;
+ }
+ else
+ {
+ num = (c2 == 0 ? (i + 2) : (i + 3));
+ i = 0;
+ }
+ s.Delete(i, num);
+ continue;
+ }
+ }
+ else
+ {
+ if (IS_SEPAR(c1) || c1 == 0)
+ {
+ unsigned num = 2;
+ if (i != 0)
+ i--;
+ else if (c1 == 0)
+ num = 1;
+ s.Delete(i, num);
+ continue;
+ }
+ }
+ }
+ i++;
+ }
+}
+
+#endif // UNDER_CE
+
+#define LONG_PATH_DOTS_FOLDERS_PARSING
+
+
+/*
+Windows (at least 64-bit XP) can't resolve "." or ".." in paths that start with SuperPrefix \\?\
+To solve that problem we check such path:
+ - super path contains "." or ".." - we use kSuperPathType_UseOnlySuper
+ - super path doesn't contain "." or ".." - we use kSuperPathType_UseOnlyMain
+*/
+#ifdef LONG_PATH_DOTS_FOLDERS_PARSING
+#ifndef UNDER_CE
+static bool AreThereDotsFolders(CFSTR s)
+{
+ for (unsigned i = 0;; i++)
+ {
+ FChar c = s[i];
+ if (c == 0)
+ return false;
+ if (c == '.' && (i == 0 || IS_SEPAR(s[i - 1])))
+ {
+ FChar c1 = s[i + 1];
+ if (c1 == 0 || IS_SEPAR(c1) ||
+ (c1 == '.' && (s[i + 2] == 0 || IS_SEPAR(s[i + 2]))))
+ return true;
+ }
+ }
+}
+#endif
+#endif // LONG_PATH_DOTS_FOLDERS_PARSING
+
+#ifdef WIN_LONG_PATH
+
+/*
+Most of Windows versions have problems, if some file or dir name
+contains '.' or ' ' at the end of name (Bad Path).
+To solve that problem, we always use Super Path ("\\?\" prefix and full path)
+in such cases. Note that "." and ".." are not bad names.
+
+There are 3 cases:
+ 1) If the path is already Super Path, we use that path
+ 2) If the path is not Super Path :
+ 2.1) Bad Path; we use only Super Path.
+ 2.2) Good Path; we use Main Path. If it fails, we use Super Path.
+
+ NeedToUseOriginalPath returns:
+ kSuperPathType_UseOnlyMain : Super already
+ kSuperPathType_UseOnlySuper : not Super, Bad Path
+ kSuperPathType_UseMainAndSuper : not Super, Good Path
+*/
+
+int GetUseSuperPathType(CFSTR s) throw()
+{
+ if (IsSuperOrDevicePath(s))
+ {
+ #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
+ if ((s)[2] != '.')
+ if (AreThereDotsFolders(s + kSuperPathPrefixSize))
+ return kSuperPathType_UseOnlySuper;
+ #endif
+ return kSuperPathType_UseOnlyMain;
+ }
+
+ for (unsigned i = 0;; i++)
+ {
+ FChar c = s[i];
+ if (c == 0)
+ return kSuperPathType_UseMainAndSuper;
+ if (c == '.' || c == ' ')
+ {
+ FChar c2 = s[i + 1];
+ if (c2 == 0 || IS_SEPAR(c2))
+ {
+ // if it's "." or "..", it's not bad name.
+ if (c == '.')
+ {
+ if (i == 0 || IS_SEPAR(s[i - 1]))
+ continue;
+ if (s[i - 1] == '.')
+ {
+ if (i - 1 == 0 || IS_SEPAR(s[i - 2]))
+ continue;
+ }
+ }
+ return kSuperPathType_UseOnlySuper;
+ }
+ }
+ }
+}
+
+
+/*
+ returns false in two cases:
+ - if GetCurDir was used, and GetCurDir returned error.
+ - if we can't resolve ".." name.
+ if path is ".", "..", res is empty.
+ if it's Super Path already, res is empty.
+ for \**** , and if GetCurDir is not drive (c:\), res is empty
+ for absolute paths, returns true, res is Super path.
+*/
+
+
+static bool GetSuperPathBase(CFSTR s, UString &res)
+{
+ res.Empty();
+
+ FChar c = s[0];
+ if (c == 0)
+ return true;
+ if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
+ return true;
+
+ if (IsSuperOrDevicePath(s))
+ {
+ #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
+
+ if ((s)[2] == '.')
+ return true;
+
+ // we will return true here, so we will try to use these problem paths.
+
+ if (!AreThereDotsFolders(s + kSuperPathPrefixSize))
+ return true;
+
+ UString temp = fs2us(s);
+ unsigned fixedSize = GetRootPrefixSize_Of_SuperPath(temp);
+ if (fixedSize == 0)
+ return true;
+
+ UString rem = &temp[fixedSize];
+ if (!ResolveDotsFolders(rem))
+ return true;
+
+ temp.DeleteFrom(fixedSize);
+ res += temp;
+ res += rem;
+
+ #endif
+
+ return true;
+ }
+
+ if (IS_SEPAR(c))
+ {
+ if (IS_SEPAR(s[1]))
+ {
+ UString temp = fs2us(s + 2);
+ unsigned fixedSize = GetRootPrefixSize_Of_NetworkPath(temp);
+ // we ignore that error to allow short network paths server\share?
+ /*
+ if (fixedSize == 0)
+ return false;
+ */
+ UString rem = &temp[fixedSize];
+ if (!ResolveDotsFolders(rem))
+ return false;
+ res += kSuperUncPrefix;
+ temp.DeleteFrom(fixedSize);
+ res += temp;
+ res += rem;
+ return true;
+ }
+ }
+ else
+ {
+ if (IsDrivePath2(s))
+ {
+ UString temp = fs2us(s);
+ unsigned prefixSize = 2;
+ if (IsDrivePath(s))
+ prefixSize = kDrivePrefixSize;
+ UString rem = temp.Ptr(prefixSize);
+ if (!ResolveDotsFolders(rem))
+ return true;
+ res += kSuperPathPrefix;
+ temp.DeleteFrom(prefixSize);
+ res += temp;
+ res += rem;
+ return true;
+ }
+ }
+
+ UString curDir;
+ if (!GetCurDir(curDir))
+ return false;
+ NormalizeDirPathPrefix(curDir);
+
+ unsigned fixedSizeStart = 0;
+ unsigned fixedSize = 0;
+ const wchar_t *superMarker = NULL;
+ if (IsSuperPath(curDir))
+ {
+ fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
+ if (fixedSize == 0)
+ return false;
+ }
+ else
+ {
+ if (IsDrivePath(curDir))
+ {
+ superMarker = kSuperPathPrefix;
+ fixedSize = kDrivePrefixSize;
+ }
+ else
+ {
+ if (!IsPathSepar(curDir[0]) || !IsPathSepar(curDir[1]))
+ return false;
+ fixedSizeStart = 2;
+ fixedSize = GetRootPrefixSize_Of_NetworkPath(curDir.Ptr(2));
+ if (fixedSize == 0)
+ return false;
+ superMarker = kSuperUncPrefix;
+ }
+ }
+
+ UString temp;
+ if (IS_SEPAR(c))
+ {
+ temp = fs2us(s + 1);
+ }
+ else
+ {
+ temp += &curDir[fixedSizeStart + fixedSize];
+ temp += fs2us(s);
+ }
+ if (!ResolveDotsFolders(temp))
+ return false;
+ if (superMarker)
+ res += superMarker;
+ res += curDir.Mid(fixedSizeStart, fixedSize);
+ res += temp;
+ return true;
+}
+
+
+/*
+ In that case if GetSuperPathBase doesn't return new path, we don't need
+ to use same path that was used as main path
+
+ GetSuperPathBase superPath.IsEmpty() onlyIfNew
+ false * * GetCurDir Error
+ true false * use Super path
+ true true true don't use any path, we already used mainPath
+ true true false use main path as Super Path, we don't try mainMath
+ That case is possible now if GetCurDir returns unknow
+ type of path (not drive and not network)
+
+ We can change that code if we want to try mainPath, if GetSuperPathBase returns error,
+ and we didn't try mainPath still.
+ If we want to work that way, we don't need to use GetSuperPathBase return code.
+*/
+
+bool GetSuperPath(CFSTR path, UString &superPath, bool onlyIfNew)
+{
+ if (GetSuperPathBase(path, superPath))
+ {
+ if (superPath.IsEmpty())
+ {
+ // actually the only possible when onlyIfNew == true and superPath is empty
+ // is case when
+
+ if (onlyIfNew)
+ return false;
+ superPath = fs2us(path);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew)
+{
+ if (!GetSuperPathBase(s1, d1) ||
+ !GetSuperPathBase(s2, d2))
+ return false;
+ if (d1.IsEmpty() && d2.IsEmpty() && onlyIfNew)
+ return false;
+ if (d1.IsEmpty()) d1 = fs2us(s1);
+ if (d2.IsEmpty()) d2 = fs2us(s2);
+ return true;
+}
+
+
+/*
+// returns true, if we need additional use with New Super path.
+bool GetSuperPath(CFSTR path, UString &superPath)
+{
+ if (GetSuperPathBase(path, superPath))
+ return !superPath.IsEmpty();
+ return false;
+}
+*/
+#endif // WIN_LONG_PATH
+
+bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
+{
+ res = s;
+
+ #ifdef UNDER_CE
+
+ if (!IS_SEPAR(s[0]))
+ {
+ if (!dirPrefix)
+ return false;
+ res = dirPrefix;
+ res += s;
+ }
+
+ #else
+
+ unsigned prefixSize = GetRootPrefixSize(s);
+ if (prefixSize != 0)
+ {
+ if (!AreThereDotsFolders(s + prefixSize))
+ return true;
+
+ UString rem = fs2us(s + prefixSize);
+ if (!ResolveDotsFolders(rem))
+ return true; // maybe false;
+ res.DeleteFrom(prefixSize);
+ res += us2fs(rem);
+ return true;
+ }
+
+ /*
+ FChar c = s[0];
+ if (c == 0)
+ return true;
+ if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
+ return true;
+ if (IS_SEPAR(c) && IS_SEPAR(s[1]))
+ return true;
+ if (IsDrivePath(s))
+ return true;
+ */
+
+ UString curDir;
+ if (dirPrefix)
+ curDir = fs2us(dirPrefix);
+ else
+ {
+ if (!GetCurDir(curDir))
+ return false;
+ }
+ NormalizeDirPathPrefix(curDir);
+
+ unsigned fixedSize = 0;
+
+ #ifdef _WIN32
+
+ if (IsSuperPath(curDir))
+ {
+ fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
+ if (fixedSize == 0)
+ return false;
+ }
+ else
+ {
+ if (IsDrivePath(curDir))
+ fixedSize = kDrivePrefixSize;
+ else
+ {
+ if (!IsPathSepar(curDir[0]) || !IsPathSepar(curDir[1]))
+ return false;
+ fixedSize = GetRootPrefixSize_Of_NetworkPath(curDir.Ptr(2));
+ if (fixedSize == 0)
+ return false;
+ fixedSize += 2;
+ }
+ }
+
+ #endif // _WIN32
+
+ UString temp;
+ if (IS_SEPAR(s[0]))
+ {
+ temp = fs2us(s + 1);
+ }
+ else
+ {
+ temp += curDir.Ptr(fixedSize);
+ temp += fs2us(s);
+ }
+ if (!ResolveDotsFolders(temp))
+ return false;
+ curDir.DeleteFrom(fixedSize);
+ res = us2fs(curDir);
+ res += us2fs(temp);
+
+ #endif // UNDER_CE
+
+ return true;
+}
+
+bool GetFullPath(CFSTR path, FString &fullPath)
+{
+ return GetFullPath(NULL, path, fullPath);
+}
}}}
diff --git a/3rdparty/lzma/CPP/Windows/FileName.h b/3rdparty/lzma/CPP/Windows/FileName.h
index 9ee57f9da17..6f9b6e03932 100644
--- a/3rdparty/lzma/CPP/Windows/FileName.h
+++ b/3rdparty/lzma/CPP/Windows/FileName.h
@@ -9,9 +9,107 @@ namespace NWindows {
namespace NFile {
namespace NName {
+int FindSepar(const wchar_t *s) throw();
+#ifndef USE_UNICODE_FSTRING
+int FindSepar(const FChar *s) throw();
+#endif
+
void NormalizeDirPathPrefix(FString &dirPath); // ensures that it ended with '\\', if dirPath is not epmty
void NormalizeDirPathPrefix(UString &dirPath);
+bool IsDrivePath(const wchar_t *s) throw(); // first 3 chars are drive chars like "a:\\"
+
+bool IsAltPathPrefix(CFSTR s) throw(); /* name: */
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+extern const wchar_t *kSuperPathPrefix; /* \\?\ */
+const unsigned kDevicePathPrefixSize = 4;
+const unsigned kSuperPathPrefixSize = 4;
+const unsigned kSuperUncPathPrefixSize = kSuperPathPrefixSize + 4;
+
+bool IsDevicePath(CFSTR s) throw(); /* \\.\ */
+bool IsSuperUncPath(CFSTR s) throw(); /* \\?\UNC\ */
+bool IsNetworkPath(CFSTR s) throw(); /* \\?\UNC\ or \\SERVER */
+
+/* GetNetworkServerPrefixSize() returns size of server prefix:
+ \\?\UNC\SERVER\
+ \\SERVER\
+ in another cases it returns 0
+*/
+
+unsigned GetNetworkServerPrefixSize(CFSTR s) throw();
+
+bool IsNetworkShareRootPath(CFSTR s) throw(); /* \\?\UNC\SERVER\share or \\SERVER\share or with slash */
+
+// bool IsDrivePath_SuperAllowed(CFSTR s) throw(); // first chars are drive chars like "a:\" or "\\?\a:\"
+bool IsDriveRootPath_SuperAllowed(CFSTR s) throw(); // exact drive root path "a:\" or "\\?\a:\"
+
+bool IsDrivePath2(const wchar_t *s) throw(); // first 2 chars are drive chars like "a:"
+// bool IsDriveName2(const wchar_t *s) throw(); // is drive name like "a:"
+bool IsSuperPath(const wchar_t *s) throw();
+bool IsSuperOrDevicePath(const wchar_t *s) throw();
+
+#ifndef USE_UNICODE_FSTRING
+bool IsDrivePath2(CFSTR s) throw(); // first 2 chars are drive chars like "a:"
+// bool IsDriveName2(CFSTR s) throw(); // is drive name like "a:"
+bool IsDrivePath(CFSTR s) throw();
+bool IsSuperPath(CFSTR s) throw();
+bool IsSuperOrDevicePath(CFSTR s) throw();
+
+/* GetRootPrefixSize() returns size of ROOT PREFIX for cases:
+ \
+ \\.\
+ C:\
+ \\?\C:\
+ \\?\UNC\SERVER\Shared\
+ \\SERVER\Shared\
+ in another cases it returns 0
+*/
+
+unsigned GetRootPrefixSize(CFSTR s) throw();
+
+#endif
+
+int FindAltStreamColon(CFSTR path);
+
+#endif // _WIN32
+
+bool IsAbsolutePath(const wchar_t *s) throw();
+unsigned GetRootPrefixSize(const wchar_t *s) throw();
+
+#ifdef WIN_LONG_PATH
+
+const int kSuperPathType_UseOnlyMain = 0;
+const int kSuperPathType_UseOnlySuper = 1;
+const int kSuperPathType_UseMainAndSuper = 2;
+
+int GetUseSuperPathType(CFSTR s) throw();
+bool GetSuperPath(CFSTR path, UString &superPath, bool onlyIfNew);
+bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew);
+
+#define USE_MAIN_PATH (__useSuperPathType != kSuperPathType_UseOnlySuper)
+#define USE_MAIN_PATH_2 (__useSuperPathType1 != kSuperPathType_UseOnlySuper && __useSuperPathType2 != kSuperPathType_UseOnlySuper)
+
+#define USE_SUPER_PATH (__useSuperPathType != kSuperPathType_UseOnlyMain)
+#define USE_SUPER_PATH_2 (__useSuperPathType1 != kSuperPathType_UseOnlyMain || __useSuperPathType2 != kSuperPathType_UseOnlyMain)
+
+#define IF_USE_MAIN_PATH int __useSuperPathType = GetUseSuperPathType(path); if (USE_MAIN_PATH)
+#define IF_USE_MAIN_PATH_2(x1, x2) \
+ int __useSuperPathType1 = GetUseSuperPathType(x1); \
+ int __useSuperPathType2 = GetUseSuperPathType(x2); \
+ if (USE_MAIN_PATH_2)
+
+#else
+
+#define IF_USE_MAIN_PATH
+#define IF_USE_MAIN_PATH_2(x1, x2)
+
+#endif // WIN_LONG_PATH
+
+bool GetFullPath(CFSTR dirPrefix, CFSTR path, FString &fullPath);
+bool GetFullPath(CFSTR path, FString &fullPath);
+
}}}
#endif
diff --git a/3rdparty/lzma/CPP/Windows/FileSystem.cpp b/3rdparty/lzma/CPP/Windows/FileSystem.cpp
new file mode 100644
index 00000000000..6c1f48a206c
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/FileSystem.cpp
@@ -0,0 +1,131 @@
+// Windows/FileSystem.cpp
+
+#include "StdAfx.h"
+
+#ifndef UNDER_CE
+
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#include "FileSystem.h"
+#include "Defs.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+namespace NSystem {
+
+bool MyGetVolumeInformation(
+ CFSTR rootPath,
+ UString &volumeName,
+ LPDWORD volumeSerialNumber,
+ LPDWORD maximumComponentLength,
+ LPDWORD fileSystemFlags,
+ UString &fileSystemName)
+{
+ BOOL res;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ TCHAR v[MAX_PATH + 2]; v[0] = 0;
+ TCHAR f[MAX_PATH + 2]; f[0] = 0;
+ res = GetVolumeInformation(fs2fas(rootPath),
+ v, MAX_PATH,
+ volumeSerialNumber, maximumComponentLength, fileSystemFlags,
+ f, MAX_PATH);
+ volumeName = MultiByteToUnicodeString(v);
+ fileSystemName = MultiByteToUnicodeString(f);
+ }
+ else
+ #endif
+ {
+ WCHAR v[MAX_PATH + 2]; v[0] = 0;
+ WCHAR f[MAX_PATH + 2]; f[0] = 0;
+ res = GetVolumeInformationW(fs2us(rootPath),
+ v, MAX_PATH,
+ volumeSerialNumber, maximumComponentLength, fileSystemFlags,
+ f, MAX_PATH);
+ volumeName = v;
+ fileSystemName = f;
+ }
+ return BOOLToBool(res);
+}
+
+UINT MyGetDriveType(CFSTR pathName)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ return GetDriveType(fs2fas(pathName));
+ }
+ else
+ #endif
+ {
+ return GetDriveTypeW(fs2us(pathName));
+ }
+}
+
+typedef BOOL (WINAPI * GetDiskFreeSpaceExA_Pointer)(
+ LPCSTR lpDirectoryName, // directory name
+ PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller
+ PULARGE_INTEGER lpTotalNumberOfBytes, // bytes on disk
+ PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
+);
+
+typedef BOOL (WINAPI * GetDiskFreeSpaceExW_Pointer)(
+ LPCWSTR lpDirectoryName, // directory name
+ PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller
+ PULARGE_INTEGER lpTotalNumberOfBytes, // bytes on disk
+ PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
+);
+
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize)
+{
+ DWORD numSectorsPerCluster, bytesPerSector, numFreeClusters, numClusters;
+ bool sizeIsDetected = false;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ GetDiskFreeSpaceExA_Pointer pGetDiskFreeSpaceEx = (GetDiskFreeSpaceExA_Pointer)GetProcAddress(
+ GetModuleHandle(TEXT("kernel32.dll")), "GetDiskFreeSpaceExA");
+ if (pGetDiskFreeSpaceEx)
+ {
+ ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2;
+ sizeIsDetected = BOOLToBool(pGetDiskFreeSpaceEx(fs2fas(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2));
+ totalSize = totalSize2.QuadPart;
+ freeSize = freeSize2.QuadPart;
+ }
+ if (!::GetDiskFreeSpace(fs2fas(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters))
+ return false;
+ }
+ else
+ #endif
+ {
+ GetDiskFreeSpaceExW_Pointer pGetDiskFreeSpaceEx = (GetDiskFreeSpaceExW_Pointer)GetProcAddress(
+ GetModuleHandle(TEXT("kernel32.dll")), "GetDiskFreeSpaceExW");
+ if (pGetDiskFreeSpaceEx)
+ {
+ ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2;
+ sizeIsDetected = BOOLToBool(pGetDiskFreeSpaceEx(fs2us(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2));
+ totalSize = totalSize2.QuadPart;
+ freeSize = freeSize2.QuadPart;
+ }
+ if (!::GetDiskFreeSpaceW(fs2us(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters))
+ return false;
+ }
+ clusterSize = (UInt64)bytesPerSector * (UInt64)numSectorsPerCluster;
+ if (!sizeIsDetected)
+ {
+ totalSize = clusterSize * (UInt64)numClusters;
+ freeSize = clusterSize * (UInt64)numFreeClusters;
+ }
+ return true;
+}
+
+}}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/FileSystem.h b/3rdparty/lzma/CPP/Windows/FileSystem.h
new file mode 100644
index 00000000000..9076ea13f4f
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/FileSystem.h
@@ -0,0 +1,27 @@
+// Windows/FileSystem.h
+
+#ifndef __WINDOWS_FILE_SYSTEM_H
+#define __WINDOWS_FILE_SYSTEM_H
+
+#include "../Common/MyString.h"
+#include "../Common/MyTypes.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NSystem {
+
+bool MyGetVolumeInformation(
+ CFSTR rootPath ,
+ UString &volumeName,
+ LPDWORD volumeSerialNumber,
+ LPDWORD maximumComponentLength,
+ LPDWORD fileSystemFlags,
+ UString &fileSystemName);
+
+UINT MyGetDriveType(CFSTR pathName);
+
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
+
+}}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/MemoryLock.cpp b/3rdparty/lzma/CPP/Windows/MemoryLock.cpp
index e0f43099672..b628a03e8f9 100644
--- a/3rdparty/lzma/CPP/Windows/MemoryLock.cpp
+++ b/3rdparty/lzma/CPP/Windows/MemoryLock.cpp
@@ -1,81 +1,71 @@
-// Common/MemoryLock.cpp
+// Windows/MemoryLock.cpp
#include "StdAfx.h"
+#include "MemoryLock.h"
+
namespace NWindows {
namespace NSecurity {
#ifndef UNDER_CE
-#ifndef _UNICODE
-typedef BOOL (WINAPI * OpenProcessTokenP)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
-typedef BOOL (WINAPI * LookupPrivilegeValueP)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid);
-typedef BOOL (WINAPI * AdjustTokenPrivilegesP)(HANDLE TokenHandle, BOOL DisableAllPrivileges,
- PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState,PDWORD ReturnLength);
-#endif
-
#ifdef _UNICODE
-bool EnableLockMemoryPrivilege(
+#define MY_FUNC_SELECT(f) :: f
#else
-static bool EnableLockMemoryPrivilege2(HMODULE hModule,
+#define MY_FUNC_SELECT(f) my_ ## f
+extern "C" {
+typedef BOOL (WINAPI * Func_OpenProcessToken)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
+typedef BOOL (WINAPI * Func_LookupPrivilegeValue)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid);
+typedef BOOL (WINAPI * Func_AdjustTokenPrivileges)(HANDLE TokenHandle, BOOL DisableAllPrivileges,
+ PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength);
+}
+#define GET_PROC_ADDR(fff, name) Func_ ## fff my_ ## fff = (Func_ ## fff)GetProcAddress(hModule, name)
#endif
-bool enable)
+
+bool EnablePrivilege(LPCTSTR privilegeName, bool enable)
{
+ bool res = false;
+
#ifndef _UNICODE
+
+ HMODULE hModule = ::LoadLibrary(TEXT("Advapi32.dll"));
if (hModule == NULL)
return false;
- OpenProcessTokenP openProcessToken = (OpenProcessTokenP)GetProcAddress(hModule, "OpenProcessToken");
- LookupPrivilegeValueP lookupPrivilegeValue = (LookupPrivilegeValueP)GetProcAddress(hModule, "LookupPrivilegeValueA" );
- AdjustTokenPrivilegesP adjustTokenPrivileges = (AdjustTokenPrivilegesP)GetProcAddress(hModule, "AdjustTokenPrivileges");
- if (openProcessToken == NULL || adjustTokenPrivileges == NULL || lookupPrivilegeValue == NULL)
- return false;
+
+ GET_PROC_ADDR(OpenProcessToken, "OpenProcessToken");
+ GET_PROC_ADDR(LookupPrivilegeValue, "LookupPrivilegeValueA");
+ GET_PROC_ADDR(AdjustTokenPrivileges, "AdjustTokenPrivileges");
+
+ if (my_OpenProcessToken &&
+ my_AdjustTokenPrivileges &&
+ my_LookupPrivilegeValue)
+
#endif
- HANDLE token;
- if (!
- #ifdef _UNICODE
- ::OpenProcessToken
- #else
- openProcessToken
- #endif
- (::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
- return false;
- TOKEN_PRIVILEGES tp;
- bool res = false;
- if (
- #ifdef _UNICODE
- ::LookupPrivilegeValue
- #else
- lookupPrivilegeValue
- #endif
- (NULL, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)))
{
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED: 0;
- if (
- #ifdef _UNICODE
- ::AdjustTokenPrivileges
- #else
- adjustTokenPrivileges
- #endif
- (token, FALSE, &tp, 0, NULL, NULL))
- res = (GetLastError() == ERROR_SUCCESS);
+ HANDLE token;
+ if (MY_FUNC_SELECT(OpenProcessToken)(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
+ {
+ TOKEN_PRIVILEGES tp;
+ if (MY_FUNC_SELECT(LookupPrivilegeValue)(NULL, privilegeName, &(tp.Privileges[0].Luid)))
+ {
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Attributes = (enable ? SE_PRIVILEGE_ENABLED : 0);
+ if (MY_FUNC_SELECT(AdjustTokenPrivileges)(token, FALSE, &tp, 0, NULL, NULL))
+ res = (GetLastError() == ERROR_SUCCESS);
+ }
+ ::CloseHandle(token);
+ }
}
- ::CloseHandle(token);
- return res;
-}
+
+ #ifndef _UNICODE
-#ifndef _UNICODE
-bool EnableLockMemoryPrivilege(bool enable)
-{
- HMODULE hModule = LoadLibrary(TEXT("Advapi32.dll"));
- if (hModule == NULL)
- return false;
- bool res = EnableLockMemoryPrivilege2(hModule, enable);
::FreeLibrary(hModule);
+
+ #endif
+
return res;
}
-#endif
#endif
diff --git a/3rdparty/lzma/CPP/Windows/MemoryLock.h b/3rdparty/lzma/CPP/Windows/MemoryLock.h
index 5fe619de05f..4a5dafcf01d 100644
--- a/3rdparty/lzma/CPP/Windows/MemoryLock.h
+++ b/3rdparty/lzma/CPP/Windows/MemoryLock.h
@@ -1,13 +1,36 @@
// Windows/MemoryLock.h
-#ifndef __WINDOWS_MEMORYLOCK_H
-#define __WINDOWS_MEMORYLOCK_H
+#ifndef __WINDOWS_MEMORY_LOCK_H
+#define __WINDOWS_MEMORY_LOCK_H
+
+#include "../Common/MyWindows.h"
namespace NWindows {
namespace NSecurity {
#ifndef UNDER_CE
-bool EnableLockMemoryPrivilege(bool enable = true);
+
+bool EnablePrivilege(LPCTSTR privilegeName, bool enable = true);
+
+inline bool EnablePrivilege_LockMemory(bool enable = true)
+{
+ return EnablePrivilege(SE_LOCK_MEMORY_NAME, enable);
+}
+
+inline void EnablePrivilege_SymLink()
+{
+ /* Probably we do not to set any Privilege for junction points.
+ But we need them for Symbolic links */
+ NSecurity::EnablePrivilege(SE_RESTORE_NAME);
+
+ /* Probably we need only SE_RESTORE_NAME, but there is also
+ SE_CREATE_SYMBOLIC_LINK_NAME. So we set it also. Do we need it? */
+
+ NSecurity::EnablePrivilege(TEXT("SeCreateSymbolicLinkPrivilege")); // SE_CREATE_SYMBOLIC_LINK_NAME
+
+ // Do we need to set SE_BACKUP_NAME ?
+}
+
#endif
}}
diff --git a/3rdparty/lzma/CPP/Windows/NtCheck.h b/3rdparty/lzma/CPP/Windows/NtCheck.h
index e56318f0093..a1b89ef2d1f 100644
--- a/3rdparty/lzma/CPP/Windows/NtCheck.h
+++ b/3rdparty/lzma/CPP/Windows/NtCheck.h
@@ -5,6 +5,8 @@
#ifdef _WIN32
+#include "../Common/MyWindows.h"
+
#if !defined(_WIN64) && !defined(UNDER_CE)
static inline bool IsItWindowsNT()
{
diff --git a/3rdparty/lzma/CPP/Windows/PropVariant.cpp b/3rdparty/lzma/CPP/Windows/PropVariant.cpp
index 90212e08fc6..e95cbd2b8d5 100644
--- a/3rdparty/lzma/CPP/Windows/PropVariant.cpp
+++ b/3rdparty/lzma/CPP/Windows/PropVariant.cpp
@@ -2,13 +2,53 @@
#include "StdAfx.h"
-#include "PropVariant.h"
-
#include "../Common/Defs.h"
+#include "PropVariant.h"
+
namespace NWindows {
namespace NCOM {
+BSTR AllocBstrFromAscii(const char *s) throw()
+{
+ if (!s)
+ return NULL;
+ UINT len = (UINT)strlen(s);
+ BSTR p = ::SysAllocStringLen(NULL, len);
+ if (p)
+ {
+ for (UINT i = 0; i <= len; i++)
+ p[i] = (Byte)s[i];
+ }
+ return p;
+}
+
+HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw()
+{
+ p->bstrVal = ::SysAllocStringLen(NULL, numChars);
+ if (!p->bstrVal)
+ {
+ p->vt = VT_ERROR;
+ p->scode = E_OUTOFMEMORY;
+ return E_OUTOFMEMORY;
+ }
+ p->vt = VT_BSTR;
+ return S_OK;
+}
+
+HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw()
+{
+ p->bstrVal = AllocBstrFromAscii(s);
+ if (p->bstrVal)
+ {
+ p->vt = VT_BSTR;
+ return S_OK;
+ }
+ p->vt = VT_ERROR;
+ p->scode = E_OUTOFMEMORY;
+ return E_OUTOFMEMORY;
+}
+
CPropVariant::CPropVariant(const PROPVARIANT &varSrc)
{
vt = VT_EMPTY;
@@ -38,6 +78,7 @@ CPropVariant& CPropVariant::operator=(const CPropVariant &varSrc)
InternalCopy(&varSrc);
return *this;
}
+
CPropVariant& CPropVariant::operator=(const PROPVARIANT &varSrc)
{
InternalCopy(&varSrc);
@@ -58,7 +99,7 @@ CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
vt = VT_BSTR;
wReserved1 = 0;
bstrVal = ::SysAllocString(lpszSrc);
- if (bstrVal == NULL && lpszSrc != NULL)
+ if (!bstrVal && lpszSrc)
{
throw kMemException;
// vt = VT_ERROR;
@@ -67,29 +108,64 @@ CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
return *this;
}
+CPropVariant& CPropVariant::operator=(const UString &s)
+{
+ InternalClear();
+ vt = VT_BSTR;
+ wReserved1 = 0;
+ bstrVal = ::SysAllocStringLen(s, s.Len());
+ if (!bstrVal)
+ throw kMemException;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(const UString2 &s)
+{
+ /*
+ if (s.IsEmpty())
+ *this = L"";
+ else
+ */
+ {
+ InternalClear();
+ vt = VT_BSTR;
+ wReserved1 = 0;
+ bstrVal = ::SysAllocStringLen(s.GetRawPtr(), s.Len());
+ if (!bstrVal)
+ throw kMemException;
+ /* SysAllocStringLen probably appends a null-terminating character for NULL string.
+ But it doesn't specified in MSDN.
+ But we suppose that it works
+
+ if (!s.GetRawPtr())
+ {
+ *bstrVal = 0;
+ }
+ */
+
+ /* MSDN: Windows CE: SysAllocStringLen() : Passing invalid (and under some circumstances NULL)
+ pointers to this function causes an unexpected termination of the application.
+ Is it safe? Maybe we must chamnge the code for that case ? */
+ }
+ return *this;
+}
CPropVariant& CPropVariant::operator=(const char *s)
{
InternalClear();
vt = VT_BSTR;
wReserved1 = 0;
- UINT len = (UINT)strlen(s);
- bstrVal = ::SysAllocStringByteLen(0, (UINT)len * sizeof(OLECHAR));
- if (bstrVal == NULL)
+ bstrVal = AllocBstrFromAscii(s);
+ if (!bstrVal)
{
throw kMemException;
// vt = VT_ERROR;
// scode = E_OUTOFMEMORY;
}
- else
- {
- for (UINT i = 0; i <= len; i++)
- bstrVal[i] = s[i];
- }
return *this;
}
-CPropVariant& CPropVariant::operator=(bool bSrc)
+CPropVariant& CPropVariant::operator=(bool bSrc) throw()
{
if (vt != VT_BOOL)
{
@@ -100,22 +176,40 @@ CPropVariant& CPropVariant::operator=(bool bSrc)
return *this;
}
+BSTR CPropVariant::AllocBstr(unsigned numChars)
+{
+ if (vt != VT_EMPTY)
+ InternalClear();
+ vt = VT_BSTR;
+ wReserved1 = 0;
+ bstrVal = ::SysAllocStringLen(NULL, numChars);
+ if (!bstrVal)
+ {
+ throw kMemException;
+ // vt = VT_ERROR;
+ // scode = E_OUTOFMEMORY;
+ }
+ return bstrVal;
+}
+
#define SET_PROP_FUNC(type, id, dest) \
- CPropVariant& CPropVariant::operator=(type value) \
+ CPropVariant& CPropVariant::operator=(type value) throw() \
{ if (vt != id) { InternalClear(); vt = id; } \
dest = value; return *this; }
SET_PROP_FUNC(Byte, VT_UI1, bVal)
-SET_PROP_FUNC(Int16, VT_I2, iVal)
+// SET_PROP_FUNC(Int16, VT_I2, iVal)
SET_PROP_FUNC(Int32, VT_I4, lVal)
SET_PROP_FUNC(UInt32, VT_UI4, ulVal)
SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
+SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart)
SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
-static HRESULT MyPropVariantClear(PROPVARIANT *prop)
+HRESULT PropVariant_Clear(PROPVARIANT *prop) throw()
{
- switch(prop->vt)
+ switch (prop->vt)
{
+ case VT_EMPTY:
case VT_UI1:
case VT_I1:
case VT_I2:
@@ -134,20 +228,27 @@ static HRESULT MyPropVariantClear(PROPVARIANT *prop)
case VT_DATE:
prop->vt = VT_EMPTY;
prop->wReserved1 = 0;
+ prop->wReserved2 = 0;
+ prop->wReserved3 = 0;
+ prop->uhVal.QuadPart = 0;
return S_OK;
}
return ::VariantClear((VARIANTARG *)prop);
+ // return ::PropVariantClear(prop);
+ // PropVariantClear can clear VT_BLOB.
}
-HRESULT CPropVariant::Clear()
+HRESULT CPropVariant::Clear() throw()
{
- return MyPropVariantClear(this);
+ if (vt == VT_EMPTY)
+ return S_OK;
+ return PropVariant_Clear(this);
}
-HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
+HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
{
::VariantClear((tagVARIANT *)this);
- switch(pSrc->vt)
+ switch (pSrc->vt)
{
case VT_UI1:
case VT_I1:
@@ -172,7 +273,7 @@ HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
}
-HRESULT CPropVariant::Attach(PROPVARIANT *pSrc)
+HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw()
{
HRESULT hr = Clear();
if (FAILED(hr))
@@ -182,18 +283,23 @@ HRESULT CPropVariant::Attach(PROPVARIANT *pSrc)
return S_OK;
}
-HRESULT CPropVariant::Detach(PROPVARIANT *pDest)
+HRESULT CPropVariant::Detach(PROPVARIANT *pDest) throw()
{
- HRESULT hr = MyPropVariantClear(pDest);
- if (FAILED(hr))
- return hr;
+ if (pDest->vt != VT_EMPTY)
+ {
+ HRESULT hr = PropVariant_Clear(pDest);
+ if (FAILED(hr))
+ return hr;
+ }
memcpy(pDest, this, sizeof(PROPVARIANT));
vt = VT_EMPTY;
return S_OK;
}
-HRESULT CPropVariant::InternalClear()
+HRESULT CPropVariant::InternalClear() throw()
{
+ if (vt == VT_EMPTY)
+ return S_OK;
HRESULT hr = Clear();
if (FAILED(hr))
{
@@ -215,7 +321,7 @@ void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
}
}
-int CPropVariant::Compare(const CPropVariant &a)
+int CPropVariant::Compare(const CPropVariant &a) throw()
{
if (vt != a.vt)
return MyCompare(vt, a.vt);
@@ -233,9 +339,7 @@ int CPropVariant::Compare(const CPropVariant &a)
case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
case VT_BOOL: return -MyCompare(boolVal, a.boolVal);
case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime);
- case VT_BSTR:
- return 0; // Not implemented
- // return MyCompare(aPropVarint.cVal);
+ case VT_BSTR: return 0; // Not implemented
default: return 0;
}
}
diff --git a/3rdparty/lzma/CPP/Windows/PropVariant.h b/3rdparty/lzma/CPP/Windows/PropVariant.h
index d018034ebcf..3610d6a8085 100644
--- a/3rdparty/lzma/CPP/Windows/PropVariant.h
+++ b/3rdparty/lzma/CPP/Windows/PropVariant.h
@@ -1,54 +1,110 @@
// Windows/PropVariant.h
-#ifndef __WINDOWS_PROPVARIANT_H
-#define __WINDOWS_PROPVARIANT_H
+#ifndef __WINDOWS_PROP_VARIANT_H
+#define __WINDOWS_PROP_VARIANT_H
+#include "../Common/MyTypes.h"
#include "../Common/MyWindows.h"
-#include "../Common/Types.h"
+#include "../Common/MyString.h"
namespace NWindows {
namespace NCOM {
+BSTR AllocBstrFromAscii(const char *s) throw();
+
+HRESULT PropVariant_Clear(PROPVARIANT *p) throw();
+
+HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw();
+HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw();
+
+inline void PropVarEm_Set_UInt32(PROPVARIANT *p, UInt32 v) throw()
+{
+ p->vt = VT_UI4;
+ p->ulVal = v;
+}
+
+inline void PropVarEm_Set_UInt64(PROPVARIANT *p, UInt64 v) throw()
+{
+ p->vt = VT_UI8;
+ p->uhVal.QuadPart = v;
+}
+
+inline void PropVarEm_Set_FileTime64(PROPVARIANT *p, UInt64 v) throw()
+{
+ p->vt = VT_FILETIME;
+ p->filetime.dwLowDateTime = (DWORD)v;
+ p->filetime.dwHighDateTime = (DWORD)(v >> 32);
+}
+
+inline void PropVarEm_Set_Bool(PROPVARIANT *p, bool b) throw()
+{
+ p->vt = VT_BOOL;
+ p->boolVal = (b ? VARIANT_TRUE : VARIANT_FALSE);
+}
+
+
class CPropVariant : public tagPROPVARIANT
{
public:
- CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; }
- ~CPropVariant() { Clear(); }
+ CPropVariant()
+ {
+ vt = VT_EMPTY;
+ wReserved1 = 0;
+ // wReserved2 = 0;
+ // wReserved3 = 0;
+ // uhVal.QuadPart = 0;
+ bstrVal = 0;
+ }
+ ~CPropVariant() throw() { Clear(); }
CPropVariant(const PROPVARIANT &varSrc);
CPropVariant(const CPropVariant &varSrc);
CPropVariant(BSTR bstrSrc);
CPropVariant(LPCOLESTR lpszSrc);
- CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); };
+ CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); }
CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; }
- CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; iVal = value; }
- CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; }
+
+private:
+ CPropVariant(Int16 value); // { vt = VT_I2; wReserved1 = 0; iVal = value; }
+ CPropVariant(Int32 value); // { vt = VT_I4; wReserved1 = 0; lVal = value; }
+
+public:
CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; }
CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal.QuadPart = value; }
+ CPropVariant(Int64 value) { vt = VT_I8; wReserved1 = 0; hVal.QuadPart = value; }
CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; }
CPropVariant& operator=(const CPropVariant &varSrc);
CPropVariant& operator=(const PROPVARIANT &varSrc);
CPropVariant& operator=(BSTR bstrSrc);
CPropVariant& operator=(LPCOLESTR lpszSrc);
+ CPropVariant& operator=(const UString &s);
+ CPropVariant& operator=(const UString2 &s);
CPropVariant& operator=(const char *s);
- CPropVariant& operator=(bool bSrc);
- CPropVariant& operator=(Byte value);
- CPropVariant& operator=(Int16 value);
- CPropVariant& operator=(Int32 value);
- CPropVariant& operator=(UInt32 value);
- CPropVariant& operator=(Int64 value);
- CPropVariant& operator=(UInt64 value);
- CPropVariant& operator=(const FILETIME &value);
-
- HRESULT Clear();
- HRESULT Copy(const PROPVARIANT *pSrc);
- HRESULT Attach(PROPVARIANT *pSrc);
- HRESULT Detach(PROPVARIANT *pDest);
-
- HRESULT InternalClear();
+
+ CPropVariant& operator=(bool bSrc) throw();
+ CPropVariant& operator=(Byte value) throw();
+
+private:
+ CPropVariant& operator=(Int16 value) throw();
+
+public:
+ CPropVariant& operator=(Int32 value) throw();
+ CPropVariant& operator=(UInt32 value) throw();
+ CPropVariant& operator=(UInt64 value) throw();
+ CPropVariant& operator=(Int64 value) throw();
+ CPropVariant& operator=(const FILETIME &value) throw();
+
+ BSTR AllocBstr(unsigned numChars);
+
+ HRESULT Clear() throw();
+ HRESULT Copy(const PROPVARIANT *pSrc) throw();
+ HRESULT Attach(PROPVARIANT *pSrc) throw();
+ HRESULT Detach(PROPVARIANT *pDest) throw();
+
+ HRESULT InternalClear() throw();
void InternalCopy(const PROPVARIANT *pSrc);
- int Compare(const CPropVariant &a1);
+ int Compare(const CPropVariant &a) throw();
};
}}
diff --git a/3rdparty/lzma/CPP/Windows/PropVariantConv.cpp b/3rdparty/lzma/CPP/Windows/PropVariantConv.cpp
new file mode 100644
index 00000000000..fe86f9365f0
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/PropVariantConv.cpp
@@ -0,0 +1,109 @@
+// PropVariantConvert.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/IntToString.h"
+
+#include "Defs.h"
+#include "PropVariantConv.h"
+
+#define UINT_TO_STR_2(c, val) { s[0] = (c); s[1] = (char)('0' + (val) / 10); s[2] = (char)('0' + (val) % 10); s += 3; }
+
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds) throw()
+{
+ SYSTEMTIME st;
+ if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
+ {
+ *s = 0;
+ return false;
+ }
+ unsigned val = st.wYear;
+ if (val >= 10000)
+ {
+ *s++ = (char)('0' + val / 10000);
+ val %= 10000;
+ }
+ {
+ s[3] = (char)('0' + val % 10); val /= 10;
+ s[2] = (char)('0' + val % 10); val /= 10;
+ s[1] = (char)('0' + val % 10);
+ s[0] = (char)('0' + val / 10);
+ s += 4;
+ }
+ UINT_TO_STR_2('-', st.wMonth);
+ UINT_TO_STR_2('-', st.wDay);
+ if (includeTime)
+ {
+ UINT_TO_STR_2(' ', st.wHour);
+ UINT_TO_STR_2(':', st.wMinute);
+ if (includeSeconds)
+ {
+ UINT_TO_STR_2(':', st.wSecond);
+ /*
+ *s++ = '.';
+ unsigned val = st.wMilliseconds;
+ s[2] = (char)('0' + val % 10); val /= 10;
+ s[1] = (char)('0' + val % 10);
+ s[0] = (char)('0' + val / 10);
+ s += 3;
+ */
+ }
+ }
+ *s = 0;
+ return true;
+}
+
+void ConvertFileTimeToString(const FILETIME &ft, wchar_t *dest, bool includeTime, bool includeSeconds) throw()
+{
+ char s[32];
+ ConvertFileTimeToString(ft, s, includeTime, includeSeconds);
+ for (unsigned i = 0;; i++)
+ {
+ unsigned char c = s[i];
+ dest[i] = c;
+ if (c == 0)
+ return;
+ }
+}
+
+void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw()
+{
+ *dest = 0;
+ switch (prop.vt)
+ {
+ case VT_EMPTY: return;
+ case VT_BSTR: dest[0] = '?'; dest[1] = 0; return;
+ case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return;
+ case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
+ case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
+ case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
+ case VT_FILETIME: ConvertFileTimeToString(prop.filetime, dest, true, true); return;
+ // case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
+ case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
+ case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
+ case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return;
+ case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? '+' : '-'; dest[1] = 0; return;
+ default: dest[0] = '?'; dest[1] = ':'; ConvertUInt64ToString(prop.vt, dest + 2);
+ }
+}
+
+void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw()
+{
+ *dest = 0;
+ switch (prop.vt)
+ {
+ case VT_EMPTY: return;
+ case VT_BSTR: dest[0] = '?'; dest[1] = 0; return;
+ case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return;
+ case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
+ case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
+ case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
+ case VT_FILETIME: ConvertFileTimeToString(prop.filetime, dest, true, true); return;
+ // case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
+ case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
+ case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
+ case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return;
+ case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? (wchar_t)'+' : (wchar_t)'-'; dest[1] = 0; return;
+ default: dest[0] = '?'; dest[1] = ':'; ConvertUInt32ToString(prop.vt, dest + 2);
+ }
+}
diff --git a/3rdparty/lzma/CPP/Windows/PropVariantConv.h b/3rdparty/lzma/CPP/Windows/PropVariantConv.h
new file mode 100644
index 00000000000..5d26357f08d
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/PropVariantConv.h
@@ -0,0 +1,30 @@
+// Windows/PropVariantConv.h
+
+#ifndef __PROP_VARIANT_CONV_H
+#define __PROP_VARIANT_CONV_H
+
+#include "../Common/MyTypes.h"
+
+// provide at least 32 bytes for buffer including zero-end
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true) throw();
+void ConvertFileTimeToString(const FILETIME &ft, wchar_t *s, bool includeTime = true, bool includeSeconds = true) throw();
+
+// provide at least 32 bytes for buffer including zero-end
+// don't send VT_BSTR to these functions
+void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw();
+void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw();
+
+inline bool ConvertPropVariantToUInt64(const PROPVARIANT &prop, UInt64 &value)
+{
+ switch (prop.vt)
+ {
+ case VT_UI8: value = (UInt64)prop.uhVal.QuadPart; return true;
+ case VT_UI4: value = prop.ulVal; return true;
+ case VT_UI2: value = prop.uiVal; return true;
+ case VT_UI1: value = prop.bVal; return true;
+ case VT_EMPTY: return false;
+ default: throw 151199;
+ }
+}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/PropVariantConversions.cpp b/3rdparty/lzma/CPP/Windows/PropVariantConversions.cpp
deleted file mode 100644
index 2d8456cd691..00000000000
--- a/3rdparty/lzma/CPP/Windows/PropVariantConversions.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-// PropVariantConversions.cpp
-
-#include "StdAfx.h"
-
-#include "Common/IntToString.h"
-#include "Common/StringConvert.h"
-
-#include "Windows/Defs.h"
-
-#include "PropVariantConversions.h"
-
-static UString ConvertUInt64ToString(UInt64 value)
-{
- wchar_t buffer[32];
- ConvertUInt64ToString(value, buffer);
- return buffer;
-}
-
-static UString ConvertInt64ToString(Int64 value)
-{
- wchar_t buffer[32];
- ConvertInt64ToString(value, buffer);
- return buffer;
-}
-
-static char *UIntToStringSpec(char c, UInt32 value, char *s, int numPos)
-{
- if (c != 0)
- *s++ = c;
- char temp[16];
- int pos = 0;
- do
- {
- temp[pos++] = (char)('0' + value % 10);
- value /= 10;
- }
- while (value != 0);
- int i;
- for (i = 0; i < numPos - pos; i++)
- *s++ = '0';
- do
- *s++ = temp[--pos];
- while (pos > 0);
- *s = '\0';
- return s;
-}
-
-bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds)
-{
- s[0] = '\0';
- SYSTEMTIME st;
- if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
- return false;
- s = UIntToStringSpec(0, st.wYear, s, 4);
- s = UIntToStringSpec('-', st.wMonth, s, 2);
- s = UIntToStringSpec('-', st.wDay, s, 2);
- if (includeTime)
- {
- s = UIntToStringSpec(' ', st.wHour, s, 2);
- s = UIntToStringSpec(':', st.wMinute, s, 2);
- if (includeSeconds)
- UIntToStringSpec(':', st.wSecond, s, 2);
- }
- return true;
-}
-
-UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime, bool includeSeconds)
-{
- char s[32];
- ConvertFileTimeToString(ft, s, includeTime, includeSeconds);
- return GetUnicodeString(s);
-}
-
-
-UString ConvertPropVariantToString(const PROPVARIANT &prop)
-{
- switch (prop.vt)
- {
- case VT_EMPTY: return UString();
- case VT_BSTR: return prop.bstrVal;
- case VT_UI1: return ConvertUInt64ToString(prop.bVal);
- case VT_UI2: return ConvertUInt64ToString(prop.uiVal);
- case VT_UI4: return ConvertUInt64ToString(prop.ulVal);
- case VT_UI8: return ConvertUInt64ToString(prop.uhVal.QuadPart);
- case VT_FILETIME: return ConvertFileTimeToString(prop.filetime, true, true);
- // case VT_I1: return ConvertInt64ToString(prop.cVal);
- case VT_I2: return ConvertInt64ToString(prop.iVal);
- case VT_I4: return ConvertInt64ToString(prop.lVal);
- case VT_I8: return ConvertInt64ToString(prop.hVal.QuadPart);
- case VT_BOOL: return VARIANT_BOOLToBool(prop.boolVal) ? L"+" : L"-";
- default: throw 150245;
- }
-}
-
-UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop)
-{
- switch (prop.vt)
- {
- case VT_UI1: return prop.bVal;
- case VT_UI2: return prop.uiVal;
- case VT_UI4: return prop.ulVal;
- case VT_UI8: return (UInt64)prop.uhVal.QuadPart;
- default: throw 151199;
- }
-}
diff --git a/3rdparty/lzma/CPP/Windows/PropVariantConversions.h b/3rdparty/lzma/CPP/Windows/PropVariantConversions.h
deleted file mode 100644
index 3de4dedb3be..00000000000
--- a/3rdparty/lzma/CPP/Windows/PropVariantConversions.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Windows/PropVariantConversions.h
-
-#ifndef __PROP_VARIANT_CONVERSIONS_H
-#define __PROP_VARIANT_CONVERSIONS_H
-
-#include "Common/MyString.h"
-#include "Common/Types.h"
-
-bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true);
-UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime = true, bool includeSeconds = true);
-UString ConvertPropVariantToString(const PROPVARIANT &prop);
-UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop);
-
-#endif
diff --git a/3rdparty/lzma/CPP/Windows/Registry.cpp b/3rdparty/lzma/CPP/Windows/Registry.cpp
index 8b25375d946..c000e62897d 100644
--- a/3rdparty/lzma/CPP/Windows/Registry.cpp
+++ b/3rdparty/lzma/CPP/Windows/Registry.cpp
@@ -2,10 +2,12 @@
#include "StdAfx.h"
+#include <wchar.h>
+
#ifndef _UNICODE
-#include "Common/StringConvert.h"
+#include "../Common/StringConvert.h"
#endif
-#include "Windows/Registry.h"
+#include "Registry.h"
#ifndef _UNICODE
extern bool g_IsNT;
@@ -18,7 +20,7 @@ namespace NRegistry {
LONG CKey::Create(HKEY parentKey, LPCTSTR keyName,
LPTSTR keyClass, DWORD options, REGSAM accessMask,
- LPSECURITY_ATTRIBUTES securityAttributes, LPDWORD disposition)
+ LPSECURITY_ATTRIBUTES securityAttributes, LPDWORD disposition) throw()
{
MYASSERT(parentKey != NULL);
DWORD dispositionReal;
@@ -35,7 +37,7 @@ LONG CKey::Create(HKEY parentKey, LPCTSTR keyName,
return res;
}
-LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask)
+LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask) throw()
{
MYASSERT(parentKey != NULL);
HKEY key = NULL;
@@ -49,7 +51,7 @@ LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask)
return res;
}
-LONG CKey::Close()
+LONG CKey::Close() throw()
{
LONG res = ERROR_SUCCESS;
if (_object != NULL)
@@ -62,28 +64,28 @@ LONG CKey::Close()
// win95, win98: deletes sunkey and all its subkeys
// winNT to be deleted must not have subkeys
-LONG CKey::DeleteSubKey(LPCTSTR subKeyName)
+LONG CKey::DeleteSubKey(LPCTSTR subKeyName) throw()
{
MYASSERT(_object != NULL);
return RegDeleteKey(_object, subKeyName);
}
-LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName)
+LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName) throw()
{
CKey key;
LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE);
if (res != ERROR_SUCCESS)
return res;
FILETIME fileTime;
- const UInt32 kBufferSize = MAX_PATH + 1; // 256 in ATL
- DWORD size = kBufferSize;
- TCHAR buffer[kBufferSize];
+ const UInt32 kBufSize = MAX_PATH + 1; // 256 in ATL
+ DWORD size = kBufSize;
+ TCHAR buffer[kBufSize];
while (RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime) == ERROR_SUCCESS)
{
res = key.RecurseDeleteKey(buffer);
if (res != ERROR_SUCCESS)
return res;
- size = kBufferSize;
+ size = kBufSize;
}
key.Close();
return DeleteSubKey(subKeyName);
@@ -97,7 +99,7 @@ static inline UInt32 BoolToUINT32(bool value) { return (value ? 1: 0); }
static inline bool UINT32ToBool(UInt32 value) { return (value != 0); }
-LONG CKey::DeleteValue(LPCTSTR name)
+LONG CKey::DeleteValue(LPCTSTR name) throw()
{
MYASSERT(_object != NULL);
return ::RegDeleteValue(_object, name);
@@ -113,23 +115,23 @@ LONG CKey::DeleteValue(LPCWSTR name)
}
#endif
-LONG CKey::SetValue(LPCTSTR name, UInt32 value)
+LONG CKey::SetValue(LPCTSTR name, UInt32 value) throw()
{
MYASSERT(_object != NULL);
- return RegSetValueEx(_object, name, NULL, REG_DWORD,
+ return RegSetValueEx(_object, name, 0, REG_DWORD,
(BYTE * const)&value, sizeof(UInt32));
}
-LONG CKey::SetValue(LPCTSTR name, bool value)
+LONG CKey::SetValue(LPCTSTR name, bool value) throw()
{
return SetValue(name, BoolToUINT32(value));
}
-LONG CKey::SetValue(LPCTSTR name, LPCTSTR value)
+LONG CKey::SetValue(LPCTSTR name, LPCTSTR value) throw()
{
MYASSERT(value != NULL);
MYASSERT(_object != NULL);
- return RegSetValueEx(_object, name, NULL, REG_SZ,
+ return RegSetValueEx(_object, name, 0, REG_SZ,
(const BYTE * )value, (lstrlen(value) + 1) * sizeof(TCHAR));
}
@@ -139,7 +141,7 @@ LONG CKey::SetValue(LPCTSTR name, const CSysString &value)
MYASSERT(value != NULL);
MYASSERT(_object != NULL);
return RegSetValueEx(_object, name, NULL, REG_SZ,
- (const BYTE *)(const TCHAR *)value, (value.Length() + 1) * sizeof(TCHAR));
+ (const BYTE *)(const TCHAR *)value, (value.Len() + 1) * sizeof(TCHAR));
}
*/
@@ -159,11 +161,11 @@ LONG CKey::SetValue(LPCWSTR name, LPCWSTR value)
#endif
-LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size)
+LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size) throw()
{
MYASSERT(value != NULL);
MYASSERT(_object != NULL);
- return RegSetValueEx(_object, name, NULL, REG_BINARY,
+ return RegSetValueEx(_object, name, 0, REG_BINARY,
(const BYTE *)value, size);
}
@@ -177,7 +179,7 @@ LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value)
return res;
}
-LONG CKey::SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value)
+LONG CKey::SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw()
{
MYASSERT(value != NULL);
CKey key;
@@ -187,18 +189,18 @@ LONG CKey::SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value)
return res;
}
-LONG CKey::QueryValue(LPCTSTR name, UInt32 &value)
+LONG CKey::QueryValue(LPCTSTR name, UInt32 &value) throw()
{
- DWORD type = NULL;
+ DWORD type = 0;
DWORD count = sizeof(DWORD);
LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type,
(LPBYTE)&value, &count);
- MYASSERT((res!=ERROR_SUCCESS) || (type == REG_DWORD));
- MYASSERT((res!=ERROR_SUCCESS) || (count == sizeof(UInt32)));
+ MYASSERT((res != ERROR_SUCCESS) || (type == REG_DWORD));
+ MYASSERT((res != ERROR_SUCCESS) || (count == sizeof(UInt32)));
return res;
}
-LONG CKey::QueryValue(LPCTSTR name, bool &value)
+LONG CKey::QueryValue(LPCTSTR name, bool &value) throw()
{
UInt32 uintValue = BoolToUINT32(value);
LONG res = QueryValue(name, uintValue);
@@ -206,7 +208,7 @@ LONG CKey::QueryValue(LPCTSTR name, bool &value)
return res;
}
-LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value)
+LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value) throw()
{
UInt32 newVal;
LONG res = QueryValue(name, newVal);
@@ -215,7 +217,7 @@ LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value)
return res;
}
-LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value)
+LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value) throw()
{
bool newVal;
LONG res = QueryValue(name, newVal);
@@ -224,51 +226,59 @@ LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value)
return res;
}
-LONG CKey::QueryValue(LPCTSTR name, LPTSTR value, UInt32 &count)
+LONG CKey::QueryValue(LPCTSTR name, LPTSTR value, UInt32 &count) throw()
{
- MYASSERT(count != NULL);
- DWORD type = NULL;
+ DWORD type = 0;
LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
- MYASSERT((res!=ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
+ MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
return res;
}
LONG CKey::QueryValue(LPCTSTR name, CSysString &value)
{
value.Empty();
- DWORD type = NULL;
- UInt32 currentSize = 0;
- LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&currentSize);
+ DWORD type = 0;
+ UInt32 curSize = 0;
+ LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&curSize);
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
return res;
- res = QueryValue(name, value.GetBuffer(currentSize), currentSize);
- value.ReleaseBuffer();
+ UInt32 curSize2 = curSize;
+ res = QueryValue(name, value.GetBuf(curSize), curSize2);
+ if (curSize > curSize2)
+ curSize = curSize2;
+ value.ReleaseBuf_CalcLen(curSize / sizeof(TCHAR));
return res;
}
+
#ifndef _UNICODE
+
LONG CKey::QueryValue(LPCWSTR name, LPWSTR value, UInt32 &count)
{
- MYASSERT(count != NULL);
- DWORD type = NULL;
+ DWORD type = 0;
LONG res = RegQueryValueExW(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
- MYASSERT((res!=ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
+ MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
return res;
}
+
LONG CKey::QueryValue(LPCWSTR name, UString &value)
{
value.Empty();
- DWORD type = NULL;
- UInt32 currentSize = 0;
+ DWORD type = 0;
+ UInt32 curSize = 0;
LONG res;
+
if (g_IsNT)
{
- res = RegQueryValueExW(_object, name, NULL, &type, NULL, (DWORD *)&currentSize);
+ res = RegQueryValueExW(_object, name, NULL, &type, NULL, (DWORD *)&curSize);
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
return res;
- res = QueryValue(name, value.GetBuffer(currentSize), currentSize);
- value.ReleaseBuffer();
+ UInt32 curSize2 = curSize;
+ res = QueryValue(name, value.GetBuf(curSize), curSize2);
+ if (curSize > curSize2)
+ curSize = curSize2;
+ value.ReleaseBuf_CalcLen(curSize / sizeof(wchar_t));
}
else
{
@@ -276,27 +286,30 @@ LONG CKey::QueryValue(LPCWSTR name, UString &value)
res = QueryValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), vTemp);
value = GetUnicodeString(vTemp);
}
+
return res;
}
+
#endif
-LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &count)
+
+LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &count) throw()
{
- DWORD type = NULL;
+ DWORD type = 0;
LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
- MYASSERT((res!=ERROR_SUCCESS) || (type == REG_BINARY));
+ MYASSERT((res != ERROR_SUCCESS) || (type == REG_BINARY));
return res;
}
LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize)
{
- DWORD type = NULL;
+ DWORD type = 0;
dataSize = 0;
LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&dataSize);
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
return res;
- value.SetCapacity(dataSize);
+ value.Alloc(dataSize);
return QueryValue(name, (BYTE *)value, dataSize);
}
@@ -304,14 +317,14 @@ LONG CKey::EnumKeys(CSysStringVector &keyNames)
{
keyNames.Clear();
CSysString keyName;
- for (UInt32 index = 0; ; index++)
+ for (DWORD index = 0; ; index++)
{
- const UInt32 kBufferSize = MAX_PATH + 1; // 256 in ATL
+ const unsigned kBufSize = MAX_PATH + 1; // 256 in ATL
FILETIME lastWriteTime;
- UInt32 nameSize = kBufferSize;
- LONG result = ::RegEnumKeyEx(_object, index, keyName.GetBuffer(kBufferSize),
+ UInt32 nameSize = kBufSize;
+ LONG result = ::RegEnumKeyEx(_object, index, keyName.GetBuf(kBufSize),
(DWORD *)&nameSize, NULL, NULL, NULL, &lastWriteTime);
- keyName.ReleaseBuffer();
+ keyName.ReleaseBuf_CalcLen(kBufSize);
if (result == ERROR_NO_MORE_ITEMS)
break;
if (result != ERROR_SUCCESS)
@@ -323,46 +336,54 @@ LONG CKey::EnumKeys(CSysStringVector &keyNames)
LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings)
{
- UInt32 numChars = 0;
- int i;
+ size_t numChars = 0;
+
+ unsigned i;
+
for (i = 0; i < strings.Size(); i++)
- numChars += strings[i].Length() + 1;
- CBuffer<wchar_t> buffer;
- buffer.SetCapacity(numChars);
- int pos = 0;
+ numChars += strings[i].Len() + 1;
+
+ CObjArray<wchar_t> buffer(numChars);
+ size_t pos = 0;
+
for (i = 0; i < strings.Size(); i++)
{
const UString &s = strings[i];
- MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)s);
- pos += s.Length() + 1;
+ size_t size = s.Len() + 1;
+ wmemcpy(buffer + pos, s, size);
+ pos += size;
}
- return SetValue(valueName, buffer, numChars * sizeof(wchar_t));
+ return SetValue(valueName, buffer, (UInt32)numChars * sizeof(wchar_t));
}
LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)
{
strings.Clear();
CByteBuffer buffer;
- UInt32 dataSize;
+ UInt32 dataSize = 0;
LONG res = QueryValue(valueName, buffer, dataSize);
if (res != ERROR_SUCCESS)
return res;
+ if (dataSize > buffer.Size())
+ return E_FAIL;
if (dataSize % sizeof(wchar_t) != 0)
return E_FAIL;
+
const wchar_t *data = (const wchar_t *)(const Byte *)buffer;
- int numChars = dataSize / sizeof(wchar_t);
+ size_t numChars = dataSize / sizeof(wchar_t);
+ size_t prev = 0;
UString s;
- for (int i = 0; i < numChars; i++)
+
+ for (size_t i = 0; i < numChars; i++)
{
- wchar_t c = data[i];
- if (c == 0)
+ if (data[i] == 0)
{
+ s = data + prev;
strings.Add(s);
- s.Empty();
+ prev = i + 1;
}
- else
- s += c;
}
+
return res;
}
diff --git a/3rdparty/lzma/CPP/Windows/Registry.h b/3rdparty/lzma/CPP/Windows/Registry.h
index f0561e68856..ca79dfe3cda 100644
--- a/3rdparty/lzma/CPP/Windows/Registry.h
+++ b/3rdparty/lzma/CPP/Windows/Registry.h
@@ -3,9 +3,8 @@
#ifndef __WINDOWS_REGISTRY_H
#define __WINDOWS_REGISTRY_H
-#include "Common/Buffer.h"
-#include "Common/MyString.h"
-#include "Common/Types.h"
+#include "../Common/MyBuffer.h"
+#include "../Common/MyString.h"
namespace NWindows {
namespace NRegistry {
@@ -32,49 +31,49 @@ public:
LPTSTR keyClass = REG_NONE, DWORD options = REG_OPTION_NON_VOLATILE,
REGSAM accessMask = KEY_ALL_ACCESS,
LPSECURITY_ATTRIBUTES securityAttributes = NULL,
- LPDWORD disposition = NULL);
- LONG Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask = KEY_ALL_ACCESS);
+ LPDWORD disposition = NULL) throw();
+ LONG Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask = KEY_ALL_ACCESS) throw();
- LONG Close();
+ LONG Close() throw();
- LONG DeleteSubKey(LPCTSTR subKeyName);
- LONG RecurseDeleteKey(LPCTSTR subKeyName);
+ LONG DeleteSubKey(LPCTSTR subKeyName) throw();
+ LONG RecurseDeleteKey(LPCTSTR subKeyName) throw();
- LONG DeleteValue(LPCTSTR name);
+ LONG DeleteValue(LPCTSTR name) throw();
#ifndef _UNICODE
LONG DeleteValue(LPCWSTR name);
#endif
- LONG SetValue(LPCTSTR valueName, UInt32 value);
- LONG SetValue(LPCTSTR valueName, bool value);
- LONG SetValue(LPCTSTR valueName, LPCTSTR value);
+ LONG SetValue(LPCTSTR valueName, UInt32 value) throw();
+ LONG SetValue(LPCTSTR valueName, bool value) throw();
+ LONG SetValue(LPCTSTR valueName, LPCTSTR value) throw();
// LONG SetValue(LPCTSTR valueName, const CSysString &value);
#ifndef _UNICODE
LONG SetValue(LPCWSTR name, LPCWSTR value);
// LONG SetValue(LPCWSTR name, const UString &value);
#endif
- LONG SetValue(LPCTSTR name, const void *value, UInt32 size);
+ LONG SetValue(LPCTSTR name, const void *value, UInt32 size) throw();
LONG SetValue_Strings(LPCTSTR valueName, const UStringVector &strings);
LONG GetValue_Strings(LPCTSTR valueName, UStringVector &strings);
- LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value);
+ LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw();
- LONG QueryValue(LPCTSTR name, UInt32 &value);
- LONG QueryValue(LPCTSTR name, bool &value);
- LONG QueryValue(LPCTSTR name, LPTSTR value, UInt32 &dataSize);
+ LONG QueryValue(LPCTSTR name, UInt32 &value) throw();
+ LONG QueryValue(LPCTSTR name, bool &value) throw();
+ LONG QueryValue(LPCTSTR name, LPTSTR value, UInt32 &dataSize) throw();
LONG QueryValue(LPCTSTR name, CSysString &value);
- LONG GetValue_IfOk(LPCTSTR name, UInt32 &value);
- LONG GetValue_IfOk(LPCTSTR name, bool &value);
+ LONG GetValue_IfOk(LPCTSTR name, UInt32 &value) throw();
+ LONG GetValue_IfOk(LPCTSTR name, bool &value) throw();
#ifndef _UNICODE
LONG QueryValue(LPCWSTR name, LPWSTR value, UInt32 &dataSize);
LONG QueryValue(LPCWSTR name, UString &value);
#endif
- LONG QueryValue(LPCTSTR name, void *value, UInt32 &dataSize);
+ LONG QueryValue(LPCTSTR name, void *value, UInt32 &dataSize) throw();
LONG QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize);
LONG EnumKeys(CSysStringVector &keyNames);
diff --git a/3rdparty/lzma/CPP/Windows/ResourceString.cpp b/3rdparty/lzma/CPP/Windows/ResourceString.cpp
new file mode 100644
index 00000000000..cc8b964a213
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/ResourceString.cpp
@@ -0,0 +1,103 @@
+// Windows/ResourceString.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#include "ResourceString.h"
+
+extern HINSTANCE g_hInstance;
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+
+#ifndef _UNICODE
+
+static CSysString MyLoadStringA(HINSTANCE hInstance, UINT resourceID)
+{
+ CSysString s;
+ int size = 128;
+ int len;
+ do
+ {
+ size <<= 1;
+ len = ::LoadString(hInstance, resourceID, s.GetBuf(size - 1), size);
+ }
+ while (size - len <= 1);
+ s.ReleaseBuf_CalcLen(len);
+ return s;
+}
+
+#endif
+
+static const int kStartSize = 256;
+
+static void MyLoadString2(HINSTANCE hInstance, UINT resourceID, UString &s)
+{
+ int size = kStartSize;
+ int len;
+ do
+ {
+ size <<= 1;
+ len = ::LoadStringW(hInstance, resourceID, s.GetBuf(size - 1), size);
+ }
+ while (size - len <= 1);
+ s.ReleaseBuf_CalcLen(len);
+}
+
+// NT4 doesn't support LoadStringW(,,, 0) to get pointer to resource string. So we don't use it.
+
+UString MyLoadString(UINT resourceID)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ return GetUnicodeString(MyLoadStringA(g_hInstance, resourceID));
+ else
+ #endif
+ {
+ {
+ wchar_t s[kStartSize];
+ s[0] = 0;
+ int len = ::LoadStringW(g_hInstance, resourceID, s, kStartSize);
+ if (kStartSize - len > 1)
+ return s;
+ }
+ UString dest;
+ MyLoadString2(g_hInstance, resourceID, dest);
+ return dest;
+ }
+}
+
+void MyLoadString(HINSTANCE hInstance, UINT resourceID, UString &dest)
+{
+ dest.Empty();
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ MultiByteToUnicodeString2(dest, MyLoadStringA(hInstance, resourceID));
+ else
+ #endif
+ {
+ {
+ wchar_t s[kStartSize];
+ s[0] = 0;
+ int len = ::LoadStringW(hInstance, resourceID, s, kStartSize);
+ if (kStartSize - len > 1)
+ {
+ dest = s;
+ return;
+ }
+ }
+ MyLoadString2(hInstance, resourceID, dest);
+ }
+}
+
+void MyLoadString(UINT resourceID, UString &dest)
+{
+ MyLoadString(g_hInstance, resourceID, dest);
+}
+
+}
diff --git a/3rdparty/lzma/CPP/Windows/ResourceString.h b/3rdparty/lzma/CPP/Windows/ResourceString.h
new file mode 100644
index 00000000000..f0bdabf47fe
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/ResourceString.h
@@ -0,0 +1,16 @@
+// Windows/ResourceString.h
+
+#ifndef __WINDOWS_RESOURCE_STRING_H
+#define __WINDOWS_RESOURCE_STRING_H
+
+#include "../Common/MyString.h"
+
+namespace NWindows {
+
+UString MyLoadString(UINT resourceID);
+void MyLoadString(HINSTANCE hInstance, UINT resourceID, UString &dest);
+void MyLoadString(UINT resourceID, UString &dest);
+
+}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/SecurityUtils.cpp b/3rdparty/lzma/CPP/Windows/SecurityUtils.cpp
new file mode 100644
index 00000000000..67a9d7fdcb3
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/SecurityUtils.cpp
@@ -0,0 +1,181 @@
+// Windows/SecurityUtils.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/MyString.h"
+
+#include "SecurityUtils.h"
+
+namespace NWindows {
+namespace NSecurity {
+
+/*
+bool MyLookupAccountSid(LPCTSTR systemName, PSID sid,
+ CSysString &accountName, CSysString &domainName, PSID_NAME_USE sidNameUse)
+{
+ DWORD accountNameSize = 0, domainNameSize = 0;
+
+ if (!::LookupAccountSid(systemName, sid,
+ accountName.GetBuf(0), &accountNameSize,
+ domainName.GetBuf(0), &domainNameSize, sidNameUse))
+ {
+ if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ return false;
+ }
+ DWORD accountNameSize2 = accountNameSize, domainNameSize2 = domainNameSize;
+ bool result = BOOLToBool(::LookupAccountSid(systemName, sid,
+ accountName.GetBuf(accountNameSize), &accountNameSize2,
+ domainName.GetBuf(domainNameSize), &domainNameSize2, sidNameUse));
+ accountName.ReleaseBuf_CalcLen(accountNameSize);
+ domainName.ReleaseBuf_CalcLen(domainNameSize);
+ return result;
+}
+*/
+
+static void SetLsaString(LPWSTR src, PLSA_UNICODE_STRING dest)
+{
+ int len = (int)wcslen(src);
+ dest->Length = (USHORT)(len * sizeof(WCHAR));
+ dest->MaximumLength = (USHORT)((len + 1) * sizeof(WCHAR));
+ dest->Buffer = src;
+}
+
+/*
+static void MyLookupSids(CPolicy &policy, PSID ps)
+{
+ LSA_REFERENCED_DOMAIN_LIST *referencedDomains = NULL;
+ LSA_TRANSLATED_NAME *names = NULL;
+ NTSTATUS nts = policy.LookupSids(1, &ps, &referencedDomains, &names);
+ int res = LsaNtStatusToWinError(nts);
+ LsaFreeMemory(referencedDomains);
+ LsaFreeMemory(names);
+}
+*/
+
+#ifndef _UNICODE
+typedef BOOL (WINAPI * LookupAccountNameWP)(
+ LPCWSTR lpSystemName,
+ LPCWSTR lpAccountName,
+ PSID Sid,
+ LPDWORD cbSid,
+ LPWSTR ReferencedDomainName,
+ LPDWORD cchReferencedDomainName,
+ PSID_NAME_USE peUse
+ );
+#endif
+
+static PSID GetSid(LPWSTR accountName)
+{
+ #ifndef _UNICODE
+ HMODULE hModule = GetModuleHandle(TEXT("Advapi32.dll"));
+ if (hModule == NULL)
+ return NULL;
+ LookupAccountNameWP lookupAccountNameW = (LookupAccountNameWP)GetProcAddress(hModule, "LookupAccountNameW");
+ if (lookupAccountNameW == NULL)
+ return NULL;
+ #endif
+
+ DWORD sidLen = 0, domainLen = 0;
+ SID_NAME_USE sidNameUse;
+ if (!
+ #ifdef _UNICODE
+ ::LookupAccountNameW
+ #else
+ lookupAccountNameW
+ #endif
+ (NULL, accountName, NULL, &sidLen, NULL, &domainLen, &sidNameUse))
+ {
+ if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+ {
+ PSID pSid = ::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sidLen);
+ LPWSTR domainName = (LPWSTR)::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (domainLen + 1) * sizeof(WCHAR));
+ BOOL res =
+ #ifdef _UNICODE
+ ::LookupAccountNameW
+ #else
+ lookupAccountNameW
+ #endif
+ (NULL, accountName, pSid, &sidLen, domainName, &domainLen, &sidNameUse);
+ ::HeapFree(GetProcessHeap(), 0, domainName);
+ if (res)
+ return pSid;
+ }
+ }
+ return NULL;
+}
+
+#define MY__SE_LOCK_MEMORY_NAME L"SeLockMemoryPrivilege"
+
+bool AddLockMemoryPrivilege()
+{
+ CPolicy policy;
+ LSA_OBJECT_ATTRIBUTES attr;
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = NULL;
+ attr.ObjectName = NULL;
+ attr.Attributes = 0;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+ if (policy.Open(NULL, &attr,
+ // GENERIC_WRITE)
+ POLICY_ALL_ACCESS)
+ // STANDARD_RIGHTS_REQUIRED,
+ // GENERIC_READ | GENERIC_EXECUTE | POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES)
+ != 0)
+ return false;
+ LSA_UNICODE_STRING userRights;
+ wchar_t s[128] = MY__SE_LOCK_MEMORY_NAME;
+ SetLsaString(s, &userRights);
+ WCHAR userName[256 + 2];
+ DWORD size = 256;
+ if (!GetUserNameW(userName, &size))
+ return false;
+ PSID psid = GetSid(userName);
+ if (psid == NULL)
+ return false;
+ bool res = false;
+
+ /*
+ PLSA_UNICODE_STRING userRightsArray;
+ ULONG countOfRights;
+ NTSTATUS status = policy.EnumerateAccountRights(psid, &userRightsArray, &countOfRights);
+ if (status != 0)
+ return false;
+ bool finded = false;
+ for (ULONG i = 0; i < countOfRights; i++)
+ {
+ LSA_UNICODE_STRING &ur = userRightsArray[i];
+ if (ur.Length != s.Length() * sizeof(WCHAR))
+ continue;
+ if (wcsncmp(ur.Buffer, s, s.Length()) != 0)
+ continue;
+ finded = true;
+ res = true;
+ break;
+ }
+ if (!finded)
+ */
+ {
+ /*
+ LSA_ENUMERATION_INFORMATION *enums;
+ ULONG countReturned;
+ NTSTATUS status = policy.EnumerateAccountsWithUserRight(&userRights, &enums, &countReturned);
+ if (status == 0)
+ {
+ for (ULONG i = 0; i < countReturned; i++)
+ MyLookupSids(policy, enums[i].Sid);
+ if (enums)
+ ::LsaFreeMemory(enums);
+ res = true;
+ }
+ */
+ NTSTATUS status = policy.AddAccountRights(psid, &userRights);
+ if (status == 0)
+ res = true;
+ // ULONG res = LsaNtStatusToWinError(status);
+ }
+ HeapFree(GetProcessHeap(), 0, psid);
+ return res;
+}
+
+}}
diff --git a/3rdparty/lzma/CPP/Windows/SecurityUtils.h b/3rdparty/lzma/CPP/Windows/SecurityUtils.h
new file mode 100644
index 00000000000..8966dfd3b7d
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/SecurityUtils.h
@@ -0,0 +1,167 @@
+// Windows/SecurityUtils.h
+
+#ifndef __WINDOWS_SECURITY_UTILS_H
+#define __WINDOWS_SECURITY_UTILS_H
+
+#include <NTSecAPI.h>
+
+#include "Defs.h"
+
+namespace NWindows {
+namespace NSecurity {
+
+class CAccessToken
+{
+ HANDLE _handle;
+public:
+ CAccessToken(): _handle(NULL) {};
+ ~CAccessToken() { Close(); }
+ bool Close()
+ {
+ if (_handle == NULL)
+ return true;
+ bool res = BOOLToBool(::CloseHandle(_handle));
+ if (res)
+ _handle = NULL;
+ return res;
+ }
+
+ bool OpenProcessToken(HANDLE processHandle, DWORD desiredAccess)
+ {
+ Close();
+ return BOOLToBool(::OpenProcessToken(processHandle, desiredAccess, &_handle));
+ }
+
+ /*
+ bool OpenThreadToken(HANDLE threadHandle, DWORD desiredAccess, bool openAsSelf)
+ {
+ Close();
+ return BOOLToBool(::OpenTreadToken(threadHandle, desiredAccess, BoolToBOOL(anOpenAsSelf), &_handle));
+ }
+ */
+
+ bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState,
+ DWORD bufferLength, PTOKEN_PRIVILEGES previousState, PDWORD returnLength)
+ { return BOOLToBool(::AdjustTokenPrivileges(_handle, BoolToBOOL(disableAllPrivileges),
+ newState, bufferLength, previousState, returnLength)); }
+
+ bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState)
+ { return AdjustPrivileges(disableAllPrivileges, newState, 0, NULL, NULL); }
+
+ bool AdjustPrivileges(PTOKEN_PRIVILEGES newState)
+ { return AdjustPrivileges(false, newState); }
+
+};
+
+#ifndef _UNICODE
+typedef NTSTATUS (NTAPI *LsaOpenPolicyP)(PLSA_UNICODE_STRING SystemName,
+ PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK DesiredAccess, PLSA_HANDLE PolicyHandle);
+typedef NTSTATUS (NTAPI *LsaCloseP)(LSA_HANDLE ObjectHandle);
+typedef NTSTATUS (NTAPI *LsaAddAccountRightsP)(LSA_HANDLE PolicyHandle,
+ PSID AccountSid, PLSA_UNICODE_STRING UserRights, ULONG CountOfRights );
+#define MY_STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L)
+#endif
+
+struct CPolicy
+{
+protected:
+ LSA_HANDLE _handle;
+ #ifndef _UNICODE
+ HMODULE hModule;
+ #endif
+public:
+ operator LSA_HANDLE() const { return _handle; }
+ CPolicy(): _handle(NULL)
+ {
+ #ifndef _UNICODE
+ hModule = GetModuleHandle(TEXT("Advapi32.dll"));
+ #endif
+ };
+ ~CPolicy() { Close(); }
+
+ NTSTATUS Open(PLSA_UNICODE_STRING systemName, PLSA_OBJECT_ATTRIBUTES objectAttributes,
+ ACCESS_MASK desiredAccess)
+ {
+ #ifndef _UNICODE
+ if (hModule == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ LsaOpenPolicyP lsaOpenPolicy = (LsaOpenPolicyP)GetProcAddress(hModule, "LsaOpenPolicy");
+ if (lsaOpenPolicy == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ #endif
+
+ Close();
+ return
+ #ifdef _UNICODE
+ ::LsaOpenPolicy
+ #else
+ lsaOpenPolicy
+ #endif
+ (systemName, objectAttributes, desiredAccess, &_handle);
+ }
+
+ NTSTATUS Close()
+ {
+ if (_handle == NULL)
+ return 0;
+
+ #ifndef _UNICODE
+ if (hModule == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ LsaCloseP lsaClose = (LsaCloseP)GetProcAddress(hModule, "LsaClose");
+ if (lsaClose == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ #endif
+
+ NTSTATUS res =
+ #ifdef _UNICODE
+ ::LsaClose
+ #else
+ lsaClose
+ #endif
+ (_handle);
+ _handle = NULL;
+ return res;
+ }
+
+ NTSTATUS EnumerateAccountsWithUserRight(PLSA_UNICODE_STRING userRights,
+ PLSA_ENUMERATION_INFORMATION *enumerationBuffer, PULONG countReturned)
+ { return LsaEnumerateAccountsWithUserRight(_handle, userRights, (void **)enumerationBuffer, countReturned); }
+
+ NTSTATUS EnumerateAccountRights(PSID sid, PLSA_UNICODE_STRING* userRights, PULONG countOfRights)
+ { return ::LsaEnumerateAccountRights(_handle, sid, userRights, countOfRights); }
+
+ NTSTATUS LookupSids(ULONG count, PSID* sids,
+ PLSA_REFERENCED_DOMAIN_LIST* referencedDomains, PLSA_TRANSLATED_NAME* names)
+ { return LsaLookupSids(_handle, count, sids, referencedDomains, names); }
+
+ NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights, ULONG countOfRights)
+ {
+ #ifndef _UNICODE
+ if (hModule == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ LsaAddAccountRightsP lsaAddAccountRights = (LsaAddAccountRightsP)GetProcAddress(hModule, "LsaAddAccountRights");
+ if (lsaAddAccountRights == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ #endif
+
+ return
+ #ifdef _UNICODE
+ ::LsaAddAccountRights
+ #else
+ lsaAddAccountRights
+ #endif
+ (_handle, accountSid, userRights, countOfRights);
+ }
+ NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights)
+ { return AddAccountRights(accountSid, userRights, 1); }
+
+ NTSTATUS RemoveAccountRights(PSID accountSid, bool allRights, PLSA_UNICODE_STRING userRights, ULONG countOfRights)
+ { return LsaRemoveAccountRights(_handle, accountSid, (BOOLEAN)(allRights ? TRUE : FALSE), userRights, countOfRights); }
+};
+
+bool AddLockMemoryPrivilege();
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Shell.cpp b/3rdparty/lzma/CPP/Windows/Shell.cpp
new file mode 100644
index 00000000000..8e82c14a726
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Shell.cpp
@@ -0,0 +1,340 @@
+// Windows/Shell.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/MyCom.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#include "COM.h"
+#include "Shell.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NShell {
+
+#ifndef UNDER_CE
+
+// SHGetMalloc is unsupported in Windows Mobile?
+
+void CItemIDList::Free()
+{
+ if (m_Object == NULL)
+ return;
+ CMyComPtr<IMalloc> shellMalloc;
+ if (::SHGetMalloc(&shellMalloc) != NOERROR)
+ throw 41099;
+ shellMalloc->Free(m_Object);
+ m_Object = NULL;
+}
+
+/*
+CItemIDList::(LPCITEMIDLIST itemIDList): m_Object(NULL)
+ { *this = itemIDList; }
+CItemIDList::(const CItemIDList& itemIDList): m_Object(NULL)
+ { *this = itemIDList; }
+
+CItemIDList& CItemIDList::operator=(LPCITEMIDLIST object)
+{
+ Free();
+ if (object != 0)
+ {
+ UINT32 size = GetSize(object);
+ m_Object = (LPITEMIDLIST)CoTaskMemAlloc(size);
+ if (m_Object != NULL)
+ MoveMemory(m_Object, object, size);
+ }
+ return *this;
+}
+
+CItemIDList& CItemIDList::operator=(const CItemIDList &object)
+{
+ Free();
+ if (object.m_Object != NULL)
+ {
+ UINT32 size = GetSize(object.m_Object);
+ m_Object = (LPITEMIDLIST)CoTaskMemAlloc(size);
+ if (m_Object != NULL)
+ MoveMemory(m_Object, object.m_Object, size);
+ }
+ return *this;
+}
+*/
+
+/////////////////////////////
+// CDrop
+
+void CDrop::Attach(HDROP object)
+{
+ Free();
+ m_Object = object;
+ m_Assigned = true;
+}
+
+void CDrop::Free()
+{
+ if (m_MustBeFinished && m_Assigned)
+ Finish();
+ m_Assigned = false;
+}
+
+UINT CDrop::QueryCountOfFiles()
+{
+ return QueryFile(0xFFFFFFFF, (LPTSTR)NULL, 0);
+}
+
+UString CDrop::QueryFileName(UINT fileIndex)
+{
+ UString fileName;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ AString fileNameA;
+ UINT bufferSize = QueryFile(fileIndex, (LPTSTR)NULL, 0);
+ const unsigned len = bufferSize + 2;
+ QueryFile(fileIndex, fileNameA.GetBuf(len), bufferSize + 1);
+ fileNameA.ReleaseBuf_CalcLen(len);
+ fileName = GetUnicodeString(fileNameA);
+ }
+ else
+ #endif
+ {
+ UINT bufferSize = QueryFile(fileIndex, (LPWSTR)NULL, 0);
+ const unsigned len = bufferSize + 2;
+ QueryFile(fileIndex, fileName.GetBuf(len), bufferSize + 1);
+ fileName.ReleaseBuf_CalcLen(len);
+ }
+ return fileName;
+}
+
+void CDrop::QueryFileNames(UStringVector &fileNames)
+{
+ UINT numFiles = QueryCountOfFiles();
+ fileNames.ClearAndReserve(numFiles);
+ for (UINT i = 0; i < numFiles; i++)
+ fileNames.AddInReserved(QueryFileName(i));
+}
+
+
+bool GetPathFromIDList(LPCITEMIDLIST itemIDList, CSysString &path)
+{
+ const unsigned len = MAX_PATH * 2;
+ bool result = BOOLToBool(::SHGetPathFromIDList(itemIDList, path.GetBuf(len)));
+ path.ReleaseBuf_CalcLen(len);
+ return result;
+}
+
+#endif
+
+#ifdef UNDER_CE
+
+bool BrowseForFolder(LPBROWSEINFO, CSysString)
+{
+ return false;
+}
+
+bool BrowseForFolder(HWND, LPCTSTR, UINT, LPCTSTR, CSysString &)
+{
+ return false;
+}
+
+bool BrowseForFolder(HWND /* owner */, LPCTSTR /* title */,
+ LPCTSTR /* initialFolder */, CSysString & /* resultPath */)
+{
+ /*
+ // SHBrowseForFolder doesn't work before CE 6.0 ?
+ if (GetProcAddress(LoadLibrary(L"ceshell.dll", L"SHBrowseForFolder") == 0)
+ MessageBoxW(0, L"no", L"", 0);
+ else
+ MessageBoxW(0, L"yes", L"", 0);
+ */
+ /*
+ UString s = L"all files";
+ s += L" (*.*)";
+ return MyGetOpenFileName(owner, title, initialFolder, s, resultPath, true);
+ */
+ return false;
+}
+
+#else
+
+bool BrowseForFolder(LPBROWSEINFO browseInfo, CSysString &resultPath)
+{
+ NWindows::NCOM::CComInitializer comInitializer;
+ LPITEMIDLIST itemIDList = ::SHBrowseForFolder(browseInfo);
+ if (itemIDList == NULL)
+ return false;
+ CItemIDList itemIDListHolder;
+ itemIDListHolder.Attach(itemIDList);
+ return GetPathFromIDList(itemIDList, resultPath);
+}
+
+
+int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data)
+{
+ #ifndef UNDER_CE
+ switch (uMsg)
+ {
+ case BFFM_INITIALIZED:
+ {
+ SendMessage(hwnd, BFFM_SETSELECTION, TRUE, data);
+ break;
+ }
+ /*
+ case BFFM_SELCHANGED:
+ {
+ TCHAR dir[MAX_PATH];
+ if (::SHGetPathFromIDList((LPITEMIDLIST) lp , dir))
+ SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)dir);
+ else
+ SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)TEXT(""));
+ break;
+ }
+ */
+ default:
+ break;
+ }
+ #endif
+ return 0;
+}
+
+
+bool BrowseForFolder(HWND owner, LPCTSTR title, UINT ulFlags,
+ LPCTSTR initialFolder, CSysString &resultPath)
+{
+ CSysString displayName;
+ BROWSEINFO browseInfo;
+ browseInfo.hwndOwner = owner;
+ browseInfo.pidlRoot = NULL;
+
+ // there are Unicode/Astring problems in some WinCE SDK ?
+ /*
+ #ifdef UNDER_CE
+ browseInfo.pszDisplayName = (LPSTR)displayName.GetBuf(MAX_PATH);
+ browseInfo.lpszTitle = (LPCSTR)title;
+ #else
+ */
+ browseInfo.pszDisplayName = displayName.GetBuf(MAX_PATH);
+ browseInfo.lpszTitle = title;
+ // #endif
+ browseInfo.ulFlags = ulFlags;
+ browseInfo.lpfn = (initialFolder != NULL) ? BrowseCallbackProc : NULL;
+ browseInfo.lParam = (LPARAM)initialFolder;
+ return BrowseForFolder(&browseInfo, resultPath);
+}
+
+bool BrowseForFolder(HWND owner, LPCTSTR title,
+ LPCTSTR initialFolder, CSysString &resultPath)
+{
+ return BrowseForFolder(owner, title,
+ #ifndef UNDER_CE
+ BIF_NEWDIALOGSTYLE |
+ #endif
+ BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT, initialFolder, resultPath);
+ // BIF_STATUSTEXT; BIF_USENEWUI (Version 5.0)
+}
+
+#ifndef _UNICODE
+
+typedef BOOL (WINAPI * SHGetPathFromIDListWP)(LPCITEMIDLIST pidl, LPWSTR pszPath);
+
+bool GetPathFromIDList(LPCITEMIDLIST itemIDList, UString &path)
+{
+ path.Empty();
+ SHGetPathFromIDListWP shGetPathFromIDListW = (SHGetPathFromIDListWP)
+ ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetPathFromIDListW");
+ if (shGetPathFromIDListW == 0)
+ return false;
+ const unsigned len = MAX_PATH * 2;
+ bool result = BOOLToBool(shGetPathFromIDListW(itemIDList, path.GetBuf(len)));
+ path.ReleaseBuf_CalcLen(len);
+ return result;
+}
+
+typedef LPITEMIDLIST (WINAPI * SHBrowseForFolderWP)(LPBROWSEINFOW lpbi);
+
+bool BrowseForFolder(LPBROWSEINFOW browseInfo, UString &resultPath)
+{
+ NWindows::NCOM::CComInitializer comInitializer;
+ SHBrowseForFolderWP shBrowseForFolderW = (SHBrowseForFolderWP)
+ ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHBrowseForFolderW");
+ if (shBrowseForFolderW == 0)
+ return false;
+ LPITEMIDLIST itemIDList = shBrowseForFolderW(browseInfo);
+ if (itemIDList == NULL)
+ return false;
+ CItemIDList itemIDListHolder;
+ itemIDListHolder.Attach(itemIDList);
+ return GetPathFromIDList(itemIDList, resultPath);
+}
+
+
+int CALLBACK BrowseCallbackProc2(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data)
+{
+ switch (uMsg)
+ {
+ case BFFM_INITIALIZED:
+ {
+ SendMessageW(hwnd, BFFM_SETSELECTIONW, TRUE, data);
+ break;
+ }
+ /*
+ case BFFM_SELCHANGED:
+ {
+ wchar_t dir[MAX_PATH * 2];
+
+ if (shGetPathFromIDListW((LPITEMIDLIST)lp , dir))
+ SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM)dir);
+ else
+ SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM)L"");
+ break;
+ }
+ */
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+static bool BrowseForFolder(HWND owner, LPCWSTR title, UINT ulFlags,
+ LPCWSTR initialFolder, UString &resultPath)
+{
+ UString displayName;
+ BROWSEINFOW browseInfo;
+ browseInfo.hwndOwner = owner;
+ browseInfo.pidlRoot = NULL;
+ browseInfo.pszDisplayName = displayName.GetBuf(MAX_PATH);
+ browseInfo.lpszTitle = title;
+ browseInfo.ulFlags = ulFlags;
+ browseInfo.lpfn = (initialFolder != NULL) ? BrowseCallbackProc2 : NULL;
+ browseInfo.lParam = (LPARAM)initialFolder;
+ return BrowseForFolder(&browseInfo, resultPath);
+}
+
+bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath)
+{
+ if (g_IsNT)
+ return BrowseForFolder(owner, title,
+ BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS
+ // | BIF_STATUSTEXT // This flag is not supported when BIF_NEWDIALOGSTYLE is specified.
+ , initialFolder, resultPath);
+ // BIF_STATUSTEXT; BIF_USENEWUI (Version 5.0)
+ CSysString s;
+ bool res = BrowseForFolder(owner, GetSystemString(title),
+ BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS
+ // | BIF_STATUSTEXT // This flag is not supported when BIF_NEWDIALOGSTYLE is specified.
+ , GetSystemString(initialFolder), s);
+ resultPath = GetUnicodeString(s);
+ return res;
+}
+
+#endif
+
+#endif
+
+}}
diff --git a/3rdparty/lzma/CPP/Windows/Shell.h b/3rdparty/lzma/CPP/Windows/Shell.h
new file mode 100644
index 00000000000..4bff18cf99a
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Shell.h
@@ -0,0 +1,94 @@
+// Windows/Shell.h
+
+#ifndef __WINDOWS_SHELL_H
+#define __WINDOWS_SHELL_H
+
+#include <windows.h>
+#include <shlobj.h>
+
+#include "../Common/MyString.h"
+
+#include "Defs.h"
+
+namespace NWindows{
+namespace NShell{
+
+/////////////////////////
+// CItemIDList
+#ifndef UNDER_CE
+
+class CItemIDList
+{
+ LPITEMIDLIST m_Object;
+public:
+ CItemIDList(): m_Object(NULL) {}
+ // CItemIDList(LPCITEMIDLIST itemIDList);
+ // CItemIDList(const CItemIDList& itemIDList);
+ ~CItemIDList() { Free(); }
+ void Free();
+ void Attach(LPITEMIDLIST object)
+ {
+ Free();
+ m_Object = object;
+ }
+ LPITEMIDLIST Detach()
+ {
+ LPITEMIDLIST object = m_Object;
+ m_Object = NULL;
+ return object;
+ }
+ operator LPITEMIDLIST() { return m_Object;}
+ operator LPCITEMIDLIST() const { return m_Object;}
+ LPITEMIDLIST* operator&() { return &m_Object; }
+ LPITEMIDLIST operator->() { return m_Object; }
+
+ // CItemIDList& operator=(LPCITEMIDLIST object);
+ // CItemIDList& operator=(const CItemIDList &object);
+};
+
+/////////////////////////////
+// CDrop
+
+class CDrop
+{
+ HDROP m_Object;
+ bool m_MustBeFinished;
+ bool m_Assigned;
+ void Free();
+public:
+ CDrop(bool mustBeFinished) : m_MustBeFinished(mustBeFinished), m_Assigned(false) {}
+ ~CDrop() { Free(); }
+
+ void Attach(HDROP object);
+ operator HDROP() { return m_Object;}
+ bool QueryPoint(LPPOINT point)
+ { return BOOLToBool(::DragQueryPoint(m_Object, point)); }
+ void Finish() { ::DragFinish(m_Object); }
+ UINT QueryFile(UINT fileIndex, LPTSTR fileName, UINT fileNameSize)
+ { return ::DragQueryFile(m_Object, fileIndex, fileName, fileNameSize); }
+ #ifndef _UNICODE
+ UINT QueryFile(UINT fileIndex, LPWSTR fileName, UINT fileNameSize)
+ { return ::DragQueryFileW(m_Object, fileIndex, fileName, fileNameSize); }
+ #endif
+ UINT QueryCountOfFiles();
+ UString QueryFileName(UINT fileIndex);
+ void QueryFileNames(UStringVector &fileNames);
+};
+
+#endif
+
+/////////////////////////////
+// Functions
+
+bool GetPathFromIDList(LPCITEMIDLIST itemIDList, CSysString &path);
+bool BrowseForFolder(LPBROWSEINFO lpbi, CSysString &resultPath);
+bool BrowseForFolder(HWND owner, LPCTSTR title, LPCTSTR initialFolder, CSysString &resultPath);
+
+#ifndef _UNICODE
+bool GetPathFromIDList(LPCITEMIDLIST itemIDList, UString &path);
+bool BrowseForFolder(LPBROWSEINFO lpbi, UString &resultPath);
+bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath);
+#endif
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/StdAfx.h b/3rdparty/lzma/CPP/Windows/StdAfx.h
index 8b383c5ba9b..1766dfa860a 100644
--- a/3rdparty/lzma/CPP/Windows/StdAfx.h
+++ b/3rdparty/lzma/CPP/Windows/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../Common/MyWindows.h"
-#include "../Common/NewHandler.h"
+#include "../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/Windows/System.cpp b/3rdparty/lzma/CPP/Windows/System.cpp
index 4bc8d2a3fa6..59cb7c0b4e8 100644
--- a/3rdparty/lzma/CPP/Windows/System.cpp
+++ b/3rdparty/lzma/CPP/Windows/System.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../Common/MyWindows.h"
+
#include "../Common/Defs.h"
#include "System.h"
@@ -9,6 +11,8 @@
namespace NWindows {
namespace NSystem {
+#ifdef _WIN32
+
UInt32 GetNumberOfProcessors()
{
SYSTEM_INFO systemInfo;
@@ -16,6 +20,18 @@ UInt32 GetNumberOfProcessors()
return (UInt32)systemInfo.dwNumberOfProcessors;
}
+#else
+
+UInt32 GetNumberOfProcessors()
+{
+ return 1;
+}
+
+#endif
+
+
+#ifdef _WIN32
+
#ifndef UNDER_CE
#if !defined(_WIN64) && defined(__GNUC__)
@@ -43,29 +59,53 @@ typedef BOOL (WINAPI *GlobalMemoryStatusExP)(MY_LPMEMORYSTATUSEX lpBuffer);
#endif
-UInt64 GetRamSize()
+#endif
+
+
+bool GetRamSize(UInt64 &size)
{
+ size = (UInt64)(sizeof(size_t)) << 29;
+
+ #ifdef _WIN32
+
#ifndef UNDER_CE
- MY_MEMORYSTATUSEX stat;
- stat.dwLength = sizeof(stat);
+ MY_MEMORYSTATUSEX stat;
+ stat.dwLength = sizeof(stat);
#endif
+
#ifdef _WIN64
- if (!::GlobalMemoryStatusEx(&stat))
- return 0;
- return MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);
+
+ if (!::GlobalMemoryStatusEx(&stat))
+ return false;
+ size = MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);
+ return true;
+
#else
- #ifndef UNDER_CE
- GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP)
- ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GlobalMemoryStatusEx");
- if (globalMemoryStatusEx != 0 && globalMemoryStatusEx(&stat))
- return MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);
+
+ #ifndef UNDER_CE
+ GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP)
+ ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GlobalMemoryStatusEx");
+ if (globalMemoryStatusEx && globalMemoryStatusEx(&stat))
+ {
+ size = MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);
+ return true;
+ }
+ #endif
+
+ {
+ MEMORYSTATUS stat2;
+ stat2.dwLength = sizeof(stat2);
+ ::GlobalMemoryStatus(&stat2);
+ size = MyMin(stat2.dwTotalVirtual, stat2.dwTotalPhys);
+ return true;
+ }
+
#endif
- {
- MEMORYSTATUS stat;
- stat.dwLength = sizeof(stat);
- ::GlobalMemoryStatus(&stat);
- return MyMin(stat.dwTotalVirtual, stat.dwTotalPhys);
- }
+
+ #else
+
+ return false;
+
#endif
}
diff --git a/3rdparty/lzma/CPP/Windows/System.h b/3rdparty/lzma/CPP/Windows/System.h
index e0067158fd9..910bc7fd5f5 100644
--- a/3rdparty/lzma/CPP/Windows/System.h
+++ b/3rdparty/lzma/CPP/Windows/System.h
@@ -3,13 +3,14 @@
#ifndef __WINDOWS_SYSTEM_H
#define __WINDOWS_SYSTEM_H
-#include "../Common/Types.h"
+#include "../Common/MyTypes.h"
namespace NWindows {
namespace NSystem {
UInt32 GetNumberOfProcessors();
-UInt64 GetRamSize();
+
+bool GetRamSize(UInt64 &size); // returns false, if unknown ram size
}}
diff --git a/3rdparty/lzma/CPP/Windows/Time.h b/3rdparty/lzma/CPP/Windows/Time.h
deleted file mode 100644
index 537b80e6161..00000000000
--- a/3rdparty/lzma/CPP/Windows/Time.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Windows/Time.h
-
-#ifndef __WINDOWS_TIME_H
-#define __WINDOWS_TIME_H
-
-#include "Common/Types.h"
-
-namespace NWindows {
-namespace NTime {
-
-bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime);
-bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime);
-void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime);
-bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &fileTime);
-bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime);
-Int64 FileTimeToUnixTime64(const FILETIME &ft);
-bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
- unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds);
-void GetCurUtcFileTime(FILETIME &ft);
-
-}}
-
-#endif
diff --git a/3rdparty/lzma/CPP/Windows/Time.cpp b/3rdparty/lzma/CPP/Windows/TimeUtils.cpp
index 2cb028f9564..7ef44d9cc50 100644
--- a/3rdparty/lzma/CPP/Windows/Time.cpp
+++ b/3rdparty/lzma/CPP/Windows/TimeUtils.cpp
@@ -1,10 +1,9 @@
-// Windows/Time.cpp
+// Windows/TimeUtils.cpp
#include "StdAfx.h"
-#include "Windows/Defs.h"
-
-#include "Time.h"
+#include "Defs.h"
+#include "TimeUtils.h"
namespace NWindows {
namespace NTime {
@@ -17,7 +16,7 @@ static const UInt64 kUnixTimeOffset =
(UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));
static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond;
-bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft)
+bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) throw()
{
#if defined(_WIN32) && !defined(UNDER_CE)
return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft));
@@ -42,7 +41,7 @@ static const UInt32 kLowDosTime = 0x210000;
#define PERIOD_100 (PERIOD_4 * 25 - 1)
#define PERIOD_400 (PERIOD_100 * 4 + 1)
-bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime)
+bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw()
{
#if defined(_WIN32) && !defined(UNDER_CE)
@@ -116,31 +115,25 @@ bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime)
return true;
}
-void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft)
+void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft) throw()
{
UInt64 v = (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond;
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
}
-bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft)
+bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft) throw()
{
- Int64 v = (Int64)kUnixTimeOffset + unixTime;
- if (unixTime < 0)
+ if (unixTime > kNumSecondsInFileTime - kUnixTimeOffset)
{
- if (v < 0)
- {
- ft.dwLowDateTime = ft.dwHighDateTime = 0;
- return false;
- }
+ ft.dwLowDateTime = ft.dwHighDateTime = (UInt32)(Int32)-1;
+ return false;
}
- else
+ Int64 v = (Int64)kUnixTimeOffset + unixTime;
+ if (v < 0)
{
- if (v < unixTime || v > kNumSecondsInFileTime)
- {
- ft.dwLowDateTime = ft.dwHighDateTime = (UInt32)(Int32)-1;
- return false;
- }
+ ft.dwLowDateTime = ft.dwHighDateTime = 0;
+ return false;
}
UInt64 v2 = (UInt64)v * kNumTimeQuantumsInSecond;
ft.dwLowDateTime = (DWORD)v2;
@@ -148,13 +141,13 @@ bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft)
return true;
}
-Int64 FileTimeToUnixTime64(const FILETIME &ft)
+Int64 FileTimeToUnixTime64(const FILETIME &ft) throw()
{
UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
return (Int64)(winTime / kNumTimeQuantumsInSecond) - kUnixTimeOffset;
}
-bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime)
+bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw()
{
UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
winTime /= kNumTimeQuantumsInSecond;
@@ -174,7 +167,7 @@ bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime)
}
bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
- unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds)
+ unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw()
{
resSeconds = 0;
if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 ||
@@ -193,11 +186,18 @@ bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
return true;
}
-void GetCurUtcFileTime(FILETIME &ft)
+void GetCurUtcFileTime(FILETIME &ft) throw()
{
+ // Both variants provide same low resolution on WinXP: about 15 ms.
+ // But GetSystemTimeAsFileTime is much faster.
+
+ #ifdef UNDER_CE
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &ft);
+ #else
+ GetSystemTimeAsFileTime(&ft);
+ #endif
}
}}
diff --git a/3rdparty/lzma/CPP/Windows/TimeUtils.h b/3rdparty/lzma/CPP/Windows/TimeUtils.h
new file mode 100644
index 00000000000..d3033ede3ef
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/TimeUtils.h
@@ -0,0 +1,24 @@
+// Windows/TimeUtils.h
+
+#ifndef __WINDOWS_TIME_UTILS_H
+#define __WINDOWS_TIME_UTILS_H
+
+#include "../Common/MyTypes.h"
+#include "../Common/MyWindows.h"
+
+namespace NWindows {
+namespace NTime {
+
+bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime) throw();
+bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime) throw();
+void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime) throw();
+bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &fileTime) throw();
+bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime) throw();
+Int64 FileTimeToUnixTime64(const FILETIME &ft) throw();
+bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
+ unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw();
+void GetCurUtcFileTime(FILETIME &ft) throw();
+
+}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/Windows/Window.cpp b/3rdparty/lzma/CPP/Windows/Window.cpp
new file mode 100644
index 00000000000..365850223ce
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Window.cpp
@@ -0,0 +1,179 @@
+// Windows/Window.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+#include "Window.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+
+#ifndef _UNICODE
+ATOM MyRegisterClass(CONST WNDCLASSW *wndClass)
+{
+ if (g_IsNT)
+ return RegisterClassW(wndClass);
+ WNDCLASSA wndClassA;
+ wndClassA.style = wndClass->style;
+ wndClassA.lpfnWndProc = wndClass->lpfnWndProc;
+ wndClassA.cbClsExtra = wndClass->cbClsExtra;
+ wndClassA.cbWndExtra = wndClass->cbWndExtra;
+ wndClassA.hInstance = wndClass->hInstance;
+ wndClassA.hIcon = wndClass->hIcon;
+ wndClassA.hCursor = wndClass->hCursor;
+ wndClassA.hbrBackground = wndClass->hbrBackground;
+ AString menuName;
+ AString className;
+ if (IS_INTRESOURCE(wndClass->lpszMenuName))
+ wndClassA.lpszMenuName = (LPCSTR)wndClass->lpszMenuName;
+ else
+ {
+ menuName = GetSystemString(wndClass->lpszMenuName);
+ wndClassA.lpszMenuName = menuName;
+ }
+ if (IS_INTRESOURCE(wndClass->lpszClassName))
+ wndClassA.lpszClassName = (LPCSTR)wndClass->lpszClassName;
+ else
+ {
+ className = GetSystemString(wndClass->lpszClassName);
+ wndClassA.lpszClassName = className;
+ }
+ return RegisterClassA(&wndClassA);
+}
+
+bool CWindow::Create(LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+{
+ if (g_IsNT)
+ {
+ _window = ::CreateWindowW(className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+ return Create(GetSystemString(className), GetSystemString(windowName),
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+}
+
+bool CWindow::CreateEx(DWORD exStyle, LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+{
+ if (g_IsNT)
+ {
+ _window = ::CreateWindowExW(exStyle, className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+ AString classNameA;
+ LPCSTR classNameP;
+ if (IS_INTRESOURCE(className))
+ classNameP = (LPCSTR)className;
+ else
+ {
+ classNameA = GetSystemString(className);
+ classNameP = classNameA;
+ }
+ AString windowNameA;
+ LPCSTR windowNameP;
+ if (IS_INTRESOURCE(windowName))
+ windowNameP = (LPCSTR)windowName;
+ else
+ {
+ windowNameA = GetSystemString(windowName);
+ windowNameP = windowNameA;
+ }
+ return CreateEx(exStyle, classNameP, windowNameP,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+}
+
+#endif
+
+#ifndef _UNICODE
+bool MySetWindowText(HWND wnd, LPCWSTR s)
+{
+ if (g_IsNT)
+ return BOOLToBool(::SetWindowTextW(wnd, s));
+ return BOOLToBool(::SetWindowTextA(wnd, UnicodeStringToMultiByte(s)));
+}
+#endif
+
+bool CWindow::GetText(CSysString &s)
+{
+ s.Empty();
+ int len = GetTextLength();
+ if (len == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ TCHAR *p = s.GetBuf(len);
+ {
+ int len2 = GetText(p, len + 1);
+ if (len > len2)
+ len = len2;
+ }
+ s.ReleaseBuf_CalcLen(len);
+ if (len == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ return true;
+}
+
+#ifndef _UNICODE
+bool CWindow::GetText(UString &s)
+{
+ if (g_IsNT)
+ {
+ s.Empty();
+ int len = GetWindowTextLengthW(_window);
+ if (len == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ wchar_t *p = s.GetBuf(len);
+ {
+ int len2 = GetWindowTextW(_window, p, len + 1);
+ if (len > len2)
+ len = len2;
+ }
+ s.ReleaseBuf_CalcLen(len);
+ if (len == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ return true;
+ }
+ CSysString sysString;
+ bool result = GetText(sysString);
+ MultiByteToUnicodeString2(s, sysString);
+ return result;
+}
+#endif
+
+
+/*
+bool CWindow::ModifyStyleBase(int styleOffset,
+ DWORD remove, DWORD add, UINT flags)
+{
+ DWORD style = GetWindowLong(styleOffset);
+ DWORD newStyle = (style & ~remove) | add;
+ if (style == newStyle)
+ return false; // it is not good
+
+ SetWindowLong(styleOffset, newStyle);
+ if (flags != 0)
+ {
+ ::SetWindowPos(_window, NULL, 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | flags);
+ }
+ return TRUE;
+}
+*/
+
+}
diff --git a/3rdparty/lzma/CPP/Windows/Window.h b/3rdparty/lzma/CPP/Windows/Window.h
new file mode 100644
index 00000000000..3bda6795d0c
--- /dev/null
+++ b/3rdparty/lzma/CPP/Windows/Window.h
@@ -0,0 +1,284 @@
+// Windows/Window.h
+
+#ifndef __WINDOWS_WINDOW_H
+#define __WINDOWS_WINDOW_H
+
+#include "../Common/MyWindows.h"
+#include "../Common/MyString.h"
+
+#include "Defs.h"
+
+#ifndef UNDER_CE
+
+#define MY__WM_CHANGEUISTATE 0x0127
+#define MY__WM_UPDATEUISTATE 0x0128
+#define MY__WM_QUERYUISTATE 0x0129
+
+// LOWORD(wParam) values in WM_*UISTATE
+#define MY__UIS_SET 1
+#define MY__UIS_CLEAR 2
+#define MY__UIS_INITIALIZE 3
+
+// HIWORD(wParam) values in WM_*UISTATE
+#define MY__UISF_HIDEFOCUS 0x1
+#define MY__UISF_HIDEACCEL 0x2
+#define MY__UISF_ACTIVE 0x4
+
+#endif
+
+namespace NWindows {
+
+inline ATOM MyRegisterClass(CONST WNDCLASS *wndClass)
+ { return ::RegisterClass(wndClass); }
+
+#ifndef _UNICODE
+ATOM MyRegisterClass(CONST WNDCLASSW *wndClass);
+#endif
+
+#ifdef _UNICODE
+inline bool MySetWindowText(HWND wnd, LPCWSTR s) { return BOOLToBool(::SetWindowText(wnd, s)); }
+#else
+bool MySetWindowText(HWND wnd, LPCWSTR s);
+#endif
+
+
+#ifdef UNDER_CE
+#define GWLP_USERDATA GWL_USERDATA
+#define GWLP_WNDPROC GWL_WNDPROC
+#define BTNS_BUTTON TBSTYLE_BUTTON
+#define WC_COMBOBOXW L"ComboBox"
+#define DWLP_MSGRESULT DWL_MSGRESULT
+#endif
+
+class CWindow
+{
+private:
+ // bool ModifyStyleBase(int styleOffset, DWORD remove, DWORD add, UINT flags);
+protected:
+ HWND _window;
+public:
+ CWindow(HWND newWindow = NULL): _window(newWindow){};
+ CWindow& operator=(HWND newWindow)
+ {
+ _window = newWindow;
+ return *this;
+ }
+ operator HWND() const { return _window; }
+ void Attach(HWND newWindow) { _window = newWindow; }
+ HWND Detach()
+ {
+ HWND window = _window;
+ _window = NULL;
+ return window;
+ }
+
+ bool Foreground() { return BOOLToBool(::SetForegroundWindow(_window)); }
+
+ HWND GetParent() const { return ::GetParent(_window); }
+ bool GetWindowRect(LPRECT rect) const { return BOOLToBool(::GetWindowRect(_window,rect)); }
+ #ifndef UNDER_CE
+ bool IsZoomed() const { return BOOLToBool(::IsZoomed(_window)); }
+ #endif
+ bool ClientToScreen(LPPOINT point) const { return BOOLToBool(::ClientToScreen(_window, point)); }
+ bool ScreenToClient(LPPOINT point) const { return BOOLToBool(::ScreenToClient(_window, point)); }
+
+ bool CreateEx(DWORD exStyle, LPCTSTR className,
+ LPCTSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+ {
+ _window = ::CreateWindowEx(exStyle, className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+
+ bool Create(LPCTSTR className,
+ LPCTSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+ {
+ _window = ::CreateWindow(className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+
+ #ifndef _UNICODE
+ bool Create(LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam);
+ bool CreateEx(DWORD exStyle, LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam);
+ #endif
+
+
+ bool Destroy()
+ {
+ if (_window == NULL)
+ return true;
+ bool result = BOOLToBool(::DestroyWindow(_window));
+ if (result)
+ _window = NULL;
+ return result;
+ }
+ bool IsWindow() { return BOOLToBool(::IsWindow(_window)); }
+ bool Move(int x, int y, int width, int height, bool repaint = true)
+ { return BOOLToBool(::MoveWindow(_window, x, y, width, height, BoolToBOOL(repaint))); }
+
+ bool ChangeSubWindowSizeX(HWND hwnd, int xSize)
+ {
+ RECT rect;
+ ::GetWindowRect(hwnd, &rect);
+ POINT p1;
+ p1.x = rect.left;
+ p1.y = rect.top;
+ ScreenToClient(&p1);
+ return BOOLToBool(::MoveWindow(hwnd, p1.x, p1.y, xSize, rect.bottom - rect.top, TRUE));
+ }
+
+ void ScreenToClient(RECT *rect)
+ {
+ POINT p1, p2;
+ p1.x = rect->left;
+ p1.y = rect->top;
+ p2.x = rect->right;
+ p2.y = rect->bottom;
+ ScreenToClient(&p1);
+ ScreenToClient(&p2);
+
+ rect->left = p1.x;
+ rect->top = p1.y;
+ rect->right = p2.x;
+ rect->bottom = p2.y;
+ }
+
+ bool GetClientRect(LPRECT rect) { return BOOLToBool(::GetClientRect(_window, rect)); }
+ bool Show(int cmdShow) { return BOOLToBool(::ShowWindow(_window, cmdShow)); }
+ bool Show_Bool(bool show) { return Show(show ? SW_SHOW: SW_HIDE); }
+
+ #ifndef UNDER_CE
+ bool SetPlacement(CONST WINDOWPLACEMENT *placement) { return BOOLToBool(::SetWindowPlacement(_window, placement)); }
+ bool GetPlacement(WINDOWPLACEMENT *placement) { return BOOLToBool(::GetWindowPlacement(_window, placement)); }
+ #endif
+ bool Update() { return BOOLToBool(::UpdateWindow(_window)); }
+ bool InvalidateRect(LPCRECT rect, bool backgroundErase = true)
+ { return BOOLToBool(::InvalidateRect(_window, rect, BoolToBOOL(backgroundErase))); }
+ void SetRedraw(bool redraw = true) { SendMsg(WM_SETREDRAW, BoolToBOOL(redraw), 0); }
+
+ LONG_PTR SetStyle(LONG_PTR style) { return SetLongPtr(GWL_STYLE, style); }
+ LONG_PTR GetStyle() const { return GetLongPtr(GWL_STYLE); }
+ // bool MyIsMaximized() const { return ((GetStyle() & WS_MAXIMIZE) != 0); }
+
+ LONG_PTR SetLong(int index, LONG newLongPtr) { return ::SetWindowLong(_window, index, newLongPtr); }
+ LONG_PTR GetLong(int index) const { return ::GetWindowLong(_window, index); }
+ LONG_PTR SetUserDataLong(LONG newLongPtr) { return SetLong(GWLP_USERDATA, newLongPtr); }
+ LONG_PTR GetUserDataLong() const { return GetLong(GWLP_USERDATA); }
+
+
+ #ifdef UNDER_CE
+
+ LONG_PTR SetLongPtr(int index, LONG_PTR newLongPtr) { return SetLong(index, newLongPtr); }
+ LONG_PTR GetLongPtr(int index) const { return GetLong(index); }
+
+ LONG_PTR SetUserDataLongPtr(LONG_PTR newLongPtr) { return SetUserDataLong(newLongPtr); }
+ LONG_PTR GetUserDataLongPtr() const { return GetUserDataLong(); }
+
+ #else
+
+ LONG_PTR SetLongPtr(int index, LONG_PTR newLongPtr)
+ { return ::SetWindowLongPtr(_window, index,
+ #ifndef _WIN64
+ (LONG)
+ #endif
+ newLongPtr); }
+ #ifndef _UNICODE
+ LONG_PTR SetLongPtrW(int index, LONG_PTR newLongPtr)
+ { return ::SetWindowLongPtrW(_window, index,
+ #ifndef _WIN64
+ (LONG)
+ #endif
+ newLongPtr); }
+ #endif
+
+ LONG_PTR GetLongPtr(int index) const { return ::GetWindowLongPtr(_window, index); }
+ LONG_PTR SetUserDataLongPtr(LONG_PTR newLongPtr) { return SetLongPtr(GWLP_USERDATA, newLongPtr); }
+ LONG_PTR GetUserDataLongPtr() const { return GetLongPtr(GWLP_USERDATA); }
+
+ #endif
+
+ /*
+ bool ModifyStyle(HWND hWnd, DWORD remove, DWORD add, UINT flags = 0)
+ { return ModifyStyleBase(GWL_STYLE, remove, add, flags); }
+ bool ModifyStyleEx(HWND hWnd, DWORD remove, DWORD add, UINT flags = 0)
+ { return ModifyStyleBase(GWL_EXSTYLE, remove, add, flags); }
+ */
+
+ HWND SetFocus() { return ::SetFocus(_window); }
+
+ LRESULT SendMsg(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return ::SendMessage(_window, message, wParam, lParam); }
+ #ifndef _UNICODE
+ LRESULT SendMsgW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return ::SendMessageW(_window, message, wParam, lParam); }
+ #endif
+
+ bool PostMsg(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return BOOLToBool(::PostMessage(_window, message, wParam, lParam)); }
+ #ifndef _UNICODE
+ bool PostMsgW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return BOOLToBool(::PostMessageW(_window, message, wParam, lParam)); }
+ #endif
+
+ bool SetText(LPCTSTR s) { return BOOLToBool(::SetWindowText(_window, s)); }
+ #ifndef _UNICODE
+ bool SetText(LPCWSTR s) { return MySetWindowText(_window, s); }
+ #endif
+
+ int GetTextLength() const
+ { return GetWindowTextLength(_window); }
+ UINT GetText(LPTSTR string, int maxCount) const
+ { return GetWindowText(_window, string, maxCount); }
+ bool GetText(CSysString &s);
+ #ifndef _UNICODE
+ /*
+ UINT GetText(LPWSTR string, int maxCount) const
+ { return GetWindowTextW(_window, string, maxCount); }
+ */
+ bool GetText(UString &s);
+ #endif
+
+ bool Enable(bool enable)
+ { return BOOLToBool(::EnableWindow(_window, BoolToBOOL(enable))); }
+
+ bool IsEnabled()
+ { return BOOLToBool(::IsWindowEnabled(_window)); }
+
+ #ifndef UNDER_CE
+ HMENU GetSystemMenu(bool revert)
+ { return ::GetSystemMenu(_window, BoolToBOOL(revert)); }
+ #endif
+
+ UINT_PTR SetTimer(UINT_PTR idEvent, UINT elapse, TIMERPROC timerFunc = 0)
+ { return ::SetTimer(_window, idEvent, elapse, timerFunc); }
+ bool KillTimer(UINT_PTR idEvent)
+ {return BOOLToBool(::KillTimer(_window, idEvent)); }
+
+ HICON SetIcon(WPARAM sizeType, HICON icon) { return (HICON)SendMsg(WM_SETICON, sizeType, (LPARAM)icon); }
+};
+
+#define RECT_SIZE_X(r) ((r).right - (r).left)
+#define RECT_SIZE_Y(r) ((r).bottom - (r).top)
+
+inline bool IsKeyDown(int virtKey) { return (::GetKeyState(virtKey) & 0x8000) != 0; }
+
+}
+
+#endif
diff --git a/3rdparty/lzma/7zC.txt b/3rdparty/lzma/DOC/7zC.txt
index 5d5d06d7b44..939b720f986 100644
--- a/3rdparty/lzma/7zC.txt
+++ b/3rdparty/lzma/DOC/7zC.txt
@@ -1,4 +1,4 @@
-7z ANSI-C Decoder 4.62
+7z ANSI-C Decoder 9.35
----------------------
7z ANSI-C provides 7z/LZMA decoding.
@@ -29,11 +29,9 @@ Files
How To Use
----------
-You must download 7-Zip program from www.7-zip.org.
+You can create .7z archive with 7z.exe, 7za.exe or 7zr.exe:
-You can create .7z archive with 7z.exe or 7za.exe:
-
- 7za.exe a archive.7z *.htm -r -mx -m0fb=255
+ 7z.exe a archive.7z *.htm -r -mx -m0fb=255
If you have big number of files in archive, and you need fast extracting,
you can use partly-solid archives:
@@ -112,14 +110,9 @@ SzArEx_Open function allocates and frees temporary structures by "allocTemp" fun
Listing code:
~~~~~~~~~~~~~
- {
- UInt32 i;
- for (i = 0; i < db.db.NumFiles; i++)
- {
- CFileItem *f = db.db.Files + i;
- printf("%10d %s\n", (int)f->Size, f->Name);
- }
- }
+
+ Use SzArEx_GetFileNameUtf16 function. Look example code in C\Util\7z\7zMain.c file.
+
Extracting code:
~~~~~~~~~~~~~~~~
diff --git a/3rdparty/lzma/7zFormat.txt b/3rdparty/lzma/DOC/7zFormat.txt
index e1cf7380d24..55b52b1b9ca 100644
--- a/3rdparty/lzma/7zFormat.txt
+++ b/3rdparty/lzma/DOC/7zFormat.txt
@@ -1,5 +1,5 @@
-7z Format description (2.30 Beta 25)
------------------------------------
+7z Format description (4.59)
+----------------------------
This file contains description of 7z archive format.
7z archive can contain files compressed with any method.
@@ -126,40 +126,43 @@ UINT64 means real UINT64 encoded with the following scheme:
Property IDs
------------
-0x00 = kEnd,
+0x00 = kEnd
-0x01 = kHeader,
+0x01 = kHeader
-0x02 = kArchiveProperties,
+0x02 = kArchiveProperties
-0x03 = kAdditionalStreamsInfo,
-0x04 = kMainStreamsInfo,
-0x05 = kFilesInfo,
+0x03 = kAdditionalStreamsInfo
+0x04 = kMainStreamsInfo
+0x05 = kFilesInfo
-0x06 = kPackInfo,
-0x07 = kUnPackInfo,
-0x08 = kSubStreamsInfo,
+0x06 = kPackInfo
+0x07 = kUnPackInfo
+0x08 = kSubStreamsInfo
-0x09 = kSize,
-0x0A = kCRC,
+0x09 = kSize
+0x0A = kCRC
-0x0B = kFolder,
+0x0B = kFolder
-0x0C = kCodersUnPackSize,
-0x0D = kNumUnPackStream,
+0x0C = kCodersUnPackSize
+0x0D = kNumUnPackStream
-0x0E = kEmptyStream,
-0x0F = kEmptyFile,
-0x10 = kAnti,
+0x0E = kEmptyStream
+0x0F = kEmptyFile
+0x10 = kAnti
-0x11 = kName,
-0x12 = kCreationTime,
-0x13 = kLastAccessTime,
-0x14 = kLastWriteTime,
-0x15 = kWinAttributes,
-0x16 = kComment,
+0x11 = kName
+0x12 = kCTime
+0x13 = kATime
+0x14 = kMTime
+0x15 = kWinAttributes
+0x16 = kComment
-0x17 = kEncodedHeader,
+0x17 = kEncodedHeader
+
+0x18 = kStartPos
+0x19 = kDummy
7z format headers
@@ -238,24 +241,19 @@ Folder
{
BYTE
{
- 0:3 DecompressionMethod.IDSize
- 4:
- 0 - IsSimple
- 1 - Is not simple
- 5:
- 0 - No Attributes
- 1 - There Are Attributes
- 7:
- 0 - Last Method in Alternative_Method_List
- 1 - There are more alternative methods
+ 0:3 CodecIdSize
+ 4: Is Complex Coder
+ 5: There Are Attributes
+ 6: Reserved
+ 7: There are more alternative methods. (Not used anymore, must be 0).
}
- BYTE DecompressionMethod.ID[DecompressionMethod.IDSize]
- if (!IsSimple)
+ BYTE CodecId[CodecIdSize]
+ if (Is Complex Coder)
{
UINT64 NumInStreams;
UINT64 NumOutStreams;
}
- if (DecompressionMethod[0] != 0)
+ if (There Are Attributes)
{
UINT64 PropertiesSize
BYTE Properties[PropertiesSize]
@@ -387,9 +385,9 @@ FilesInfo
for(EmptyStreams)
BIT IsAntiFile
- case kCreationTime: (0x12)
- case kLastAccessTime: (0x13)
- case kLastWriteTime: (0x14)
+ case kCTime: (0x12)
+ case kATime: (0x13)
+ case kMTime: (0x14)
BYTE AllAreDefined
if (AllAreDefined == 0)
{
@@ -401,7 +399,7 @@ FilesInfo
UINT64 DataIndex
[]
for(Definded Items)
- UINT32 Time
+ UINT64 Time
[]
kNames: (0x11)
diff --git a/3rdparty/lzma/DOC/Methods.txt b/3rdparty/lzma/DOC/Methods.txt
new file mode 100644
index 00000000000..1a1c54c503f
--- /dev/null
+++ b/3rdparty/lzma/DOC/Methods.txt
@@ -0,0 +1,158 @@
+7-Zip method IDs for 7z and xz archives
+---------------------------------------
+
+Version: 15.06
+Date: 2015-06-23
+
+Each compression or crypto method in 7z is associated with unique binary value (ID).
+The length of ID in bytes is arbitrary but it can not exceed 63 bits (8 bytes).
+
+xz and 7z formats use same ID map.
+
+If you want to add some new ID, you have two ways:
+ 1) Write request for allocating IDs to 7-Zip developers.
+ 2) Generate 8-bytes ID:
+
+ 3F ZZ ZZ ZZ ZZ ZZ MM MM
+
+ 3F - Prefix for random IDs (1 byte)
+ ZZ ZZ ZZ ZZ ZZ - Developer ID (5 bytes). Use real random bytes.
+
+ MM MM - Method ID (2 bytes)
+
+ You can notify 7-Zip developers about your Developer ID / Method ID.
+
+ Note: Use new ID, if old codec can not decode data encoded with new version.
+
+
+List of defined IDs
+-------------------
+
+00 - Copy
+
+03 - Delta
+04 - BCJ (x86)
+05 - PPC (big-endian)
+06 - IA64
+07 - ARM (little-endian)
+08 - ARMT (little-endian)
+09 - SPARC
+
+21 - LZMA2
+
+02.. - Common
+ 03 [Swap]
+ - 2 Swap2
+ - 4 Swap4
+
+03.. - 7z
+ 01 -
+ 01 - LZMA
+
+ 03 - [Branch Codecs]
+ 01 - [x86 Codecs]
+ 03 - BCJ
+ 1B - BCJ2 (4 packed streams)
+ 02 -
+ 05 - PPC (big-endian)
+ 03 -
+ 01 - Alpha
+ 04 -
+ 01 - IA64
+ 05 -
+ 01 - ARM (little-endian)
+ 06 -
+ 05 - M68 (big-endian)
+ 07 -
+ 01 - ARMT (little-endian)
+ 08 -
+ 05 - SPARC
+
+ 04 -
+ 01 - PPMD
+
+ 7F -
+ 01 - experimental method.
+
+
+04.. - Misc codecs
+
+ 00 - Reserved
+
+ 01 - [Zip]
+ 00 - Copy (not used. Use {00} instead)
+ 01 - Shrink
+ 06 - Implode
+ 08 - Deflate
+ 09 - Deflate64
+ 0A - Imploding
+ 0C - BZip2 (not used. Use {040202} instead)
+ 0E - LZMA (LZMA-zip)
+ 5F - xz
+ 60 - Jpeg
+ 61 - WavPack
+ 62 - PPMd (PPMd-zip)
+ 63 - wzAES
+
+ 02 -
+ 02 - BZip2
+
+ 03 - [Rar]
+ 01 - Rar1
+ 02 - Rar2
+ 03 - Rar3
+ 05 - Rar5
+
+ 04 - [Arj]
+ 01 - Arj(1,2,3)
+ 02 - Arj4
+
+ 05 - [Z]
+
+ 06 - [Lzh]
+
+ 07 - Reserved for 7z
+
+ 08 - [Cab]
+
+ 09 - [NSIS]
+ 01 - DeflateNSIS
+ 02 - BZip2NSIS
+
+ F7 - External codecs (that are not included to 7-Zip)
+
+ 0x xx - reserved
+ 10 xx - reserved
+
+
+06.. - Crypto
+
+ F0 - Ciphers without hashing algo
+
+ 01 - [AES]
+ 0x - AES-128
+ 4x - AES-192
+ 8x - AES-256
+ Cx - AES
+
+ x0 - ECB
+ x1 - CBC
+ x2 - CFB
+ x3 - OFB
+ x4 - CTR
+
+ F1 - Combine Ciphers
+
+ 01 - [Zip]
+ 01 - ZipCrypto (Main Zip crypto algo)
+
+ 03 - [RAR]
+ 02 -
+ 03 - Rar29AES (AES-128 + modified SHA-1)
+
+ 07 - [7z]
+ 01 - 7zAES (AES-256 + SHA-256)
+
+
+---
+End of document
diff --git a/3rdparty/lzma/DOC/installer.txt b/3rdparty/lzma/DOC/installer.txt
new file mode 100644
index 00000000000..b99d21d24ff
--- /dev/null
+++ b/3rdparty/lzma/DOC/installer.txt
@@ -0,0 +1,166 @@
+7-Zip for installers 9.38
+-------------------------
+
+7-Zip is a file archiver for Windows NT/2000/2003/2008/XP/Vista/7/8/10.
+
+7-Zip for installers is part of LZMA SDK.
+LZMA SDK is written and placed in the public domain by Igor Pavlov.
+
+It's allowed to join 7-Zip SFX module with another software.
+It's allowed to change resources of 7-Zip's SFX modules.
+
+
+HOW to use
+-----------
+
+7zr.exe is reduced version of 7za.exe of 7-Zip.
+7zr.exe supports only format with these codecs: LZMA, LZMA2, BCJ, BCJ2, ARM, Copy.
+
+Example of compressing command for installation packages:
+
+7zr a archive.7z files
+
+7zSD.sfx is SFX module for installers. 7zSD.sfx uses msvcrt.dll.
+
+SFX modules for installers allow to create installation program.
+Such module extracts archive to temp folder and then runs specified program and removes
+temp files after program finishing. Self-extract archive for installers must be created
+as joining 3 files: SFX_Module, Installer_Config, 7z_Archive.
+Installer_Config is optional file. You can use the following command to create installer
+self-extract archive:
+
+copy /b 7zSD.sfx + config.txt + archive.7z archive.exe
+
+The smallest installation package size can be achieved, if installation files was
+uncompressed before including to 7z archive.
+
+-y switch for installer module (at runtime) specifies quiet mode for extracting.
+
+Installer Config file format
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Config file contains commands for Installer. File begins from string
+;!@Install@!UTF-8! and ends with ;!@InstallEnd@!. File must be written
+in UTF-8 encoding. File contains string pairs:
+
+ID_String="Value"
+
+ID_String Description
+
+Title Title for messages
+BeginPrompt Begin Prompt message
+Progress Value can be "yes" or "no". Default value is "yes".
+RunProgram Command for executing. Default value is "setup.exe".
+ Substring %%T will be replaced with path to temporary
+ folder, where files were extracted
+Directory Directory prefix for "RunProgram". Default value is ".\\"
+ExecuteFile Name of file for executing
+ExecuteParameters Parameters for "ExecuteFile"
+
+
+You can omit any string pair.
+
+There are two ways to run program: RunProgram and ExecuteFile.
+Use RunProgram, if you want to run some program from .7z archive.
+Use ExecuteFile, if you want to open some document from .7z archive or
+if you want to execute some command from Windows.
+
+If you use RunProgram and if you specify empty directory prefix: Directory="",
+the system searches for the executable file in the following sequence:
+
+1. The directory from which the application (installer) loaded.
+2. The temporary folder, where files were extracted.
+3. The Windows system directory.
+
+
+Config file Examples
+~~~~~~~~~~~~~~~~~~~~
+
+;!@Install@!UTF-8!
+Title="7-Zip 4.00"
+BeginPrompt="Do you want to install the 7-Zip 4.00?"
+RunProgram="setup.exe"
+;!@InstallEnd@!
+
+
+
+;!@Install@!UTF-8!
+Title="7-Zip 4.00"
+BeginPrompt="Do you want to install the 7-Zip 4.00?"
+ExecuteFile="7zip.msi"
+;!@InstallEnd@!
+
+
+
+;!@Install@!UTF-8!
+Title="7-Zip 4.01 Update"
+BeginPrompt="Do you want to install the 7-Zip 4.01 Update?"
+ExecuteFile="msiexec.exe"
+ExecuteParameters="/i 7zip.msi REINSTALL=ALL REINSTALLMODE=vomus"
+;!@InstallEnd@!
+
+
+
+Small SFX modules for installers
+--------------------------------
+
+7zS2.sfx - small SFX module (GUI version)
+7zS2con.sfx - small SFX module (Console version)
+
+Small SFX modules support this codecs: LZMA, LZMA2, BCJ, BCJ2, ARM, COPY
+
+Small SFX module is similar to common SFX module for installers.
+The difference (what's new in small version):
+ - Smaller size (30 KB vs 100 KB)
+ - C source code instead of Ñ++
+ - No installer Configuration file
+ - No extracting progress window
+ - It decompresses solid 7z blocks (it can be whole 7z archive) to RAM.
+ So user that calls SFX installer must have free RAM of size of largest
+ solid 7z block (size of 7z archive at simplest case).
+
+How to use
+----------
+
+copy /b 7zS2.sfx + archive.7z sfx.exe
+
+When you run installer sfx module (sfx.exe)
+1) It creates "7zNNNNNNNN" temp folder in system temp folder.
+2) It extracts .7z archive to that folder
+3) It executes one file from "7zNNNNNNNN" temp folder.
+4) It removes "7zNNNNNNNN" temp folder
+
+You can send parameters to installer, and installer will transfer them to extracted .exe file.
+
+Small SFX uses 3 levels of priorities to select file to execute:
+
+ 1) Files in root folder have higher priority than files in subfolders.
+ 2) File extension priorities (from high to low priority order):
+ bat, cmd, exe, inf, msi, cab (under Windows CE), html, htm
+ 3) File name priorities (from high to low priority order):
+ setup, install, run, start
+
+Windows CE (ARM) version of 7zS2.sfx is included to 7-Zip for Windows Mobile package.
+
+
+Examples
+--------
+
+1) To create compressed console 7-Zip:
+
+7zr a c.7z 7z.exe 7z.dll -mx
+copy /b 7zS2con.sfx + c.7z 7zCompr.exe
+7zCompr.exe b -md22
+
+
+2) To create compressed GUI 7-Zip:
+
+7zr a g.7z 7zg.exe 7z.dll -mx
+copy /b 7zS2.sfx + g.7z 7zgCompr.exe
+7zgCompr.exe b -md22
+
+
+3) To open some file:
+
+7zr a h.7z readme.txt -mx
+copy /b 7zS2.sfx + h.7z 7zTxt.exe
+7zTxt.exe
diff --git a/3rdparty/lzma/history.txt b/3rdparty/lzma/DOC/lzma-history.txt
index c6b77641500..9ce878cc743 100644
--- a/3rdparty/lzma/history.txt
+++ b/3rdparty/lzma/DOC/lzma-history.txt
@@ -1,6 +1,62 @@
HISTORY of the LZMA SDK
-----------------------
+15.12 2015-11-19
+-------------------------
+- The BUG in C version of 7z decoder was fixed:
+ 7zDec.c : SzDecodeLzma2()
+ 7z decoder could mistakenly report about decoding error for some 7z archives
+ that use LZMA2 compression method.
+ The probability to get that mistaken decoding error report was about
+ one error per 16384 solid blocks for solid blocks larger than 16 KB (compressed size).
+- The BUG (in 9.26-15.11) in C version of 7z decoder was fixed:
+ 7zArcIn.c : SzReadHeader2()
+ 7z decoder worked incorrectly for 7z archives that contain
+ empty solid blocks, that can be placed to 7z archive, if some file is
+ unavailable for reading during archive creation.
+
+
+15.09 beta 2015-10-16
+-------------------------
+- The BUG in LZMA / LZMA2 encoding code was fixed.
+ The BUG in LzFind.c::MatchFinder_ReadBlock() function.
+ If input data size is larger than (4 GiB - dictionary_size),
+ the following code worked incorrectly:
+ - LZMA : LzmaEnc_MemEncode(), LzmaEncode() : LZMA encoding functions
+ for compressing from memory to memory.
+ That BUG is not related to LZMA encoder version that works via streams.
+ - LZMA2 : multi-threaded version of LZMA2 encoder worked incorrectly, if
+ default value of chunk size (CLzma2EncProps::blockSize) is changed
+ to value larger than (4 GiB - dictionary_size).
+
+
+9.38 beta 2015-01-03
+-------------------------
+- The BUG in 9.31-9.37 was fixed:
+ IArchiveGetRawProps interface was disabled for 7z archives.
+- The BUG in 9.26-9.36 was fixed:
+ Some code in CPP\7zip\Archive\7z\ worked correctly only under Windows.
+
+
+9.36 beta 2014-12-26
+-------------------------
+- The BUG in command line version was fixed:
+ 7-Zip created temporary archive in current folder during update archive
+ operation, if -w{Path} switch was not specified.
+ The fixed 7-Zip creates temporary archive in folder that contains updated archive.
+- The BUG in 9.33-9.35 was fixed:
+ 7-Zip silently ignored file reading errors during 7z or gz archive creation,
+ and the created archive contained only part of file that was read before error.
+ The fixed 7-Zip stops archive creation and it reports about error.
+
+
+9.35 beta 2014-12-07
+-------------------------
+- 7zr.exe now support AES encryption.
+- SFX mudules were added to LZMA SDK
+- Some bugs were fixed.
+
+
9.21 beta 2011-04-11
-------------------------
- New class FString for file names at file systems.
diff --git a/3rdparty/lzma/DOC/lzma-sdk.txt b/3rdparty/lzma/DOC/lzma-sdk.txt
new file mode 100644
index 00000000000..0367867c725
--- /dev/null
+++ b/3rdparty/lzma/DOC/lzma-sdk.txt
@@ -0,0 +1,357 @@
+LZMA SDK 15.14
+--------------
+
+LZMA SDK provides the documentation, samples, header files,
+libraries, and tools you need to develop applications that
+use 7z / LZMA / LZMA2 / XZ compression.
+
+LZMA is an improved version of famous LZ77 compression algorithm.
+It was improved in way of maximum increasing of compression ratio,
+keeping high decompression speed and low memory requirements for
+decompressing.
+
+LZMA2 is a LZMA based compression method. LZMA2 provides better
+multithreading support for compression than LZMA and some other improvements.
+
+7z is a file format for data compression and file archiving.
+7z is a main file format for 7-Zip compression program (www.7-zip.org).
+7z format supports different compression methods: LZMA, LZMA2 and others.
+7z also supports AES-256 based encryption.
+
+XZ is a file format for data compression that uses LZMA2 compression.
+XZ format provides additional features: SHA/CRC check, filters for
+improved compression ratio, splitting to blocks and streams,
+
+
+
+LICENSE
+-------
+
+LZMA SDK is written and placed in the public domain by Igor Pavlov.
+
+Some code in LZMA SDK is based on public domain code from another developers:
+ 1) PPMd var.H (2001): Dmitry Shkarin
+ 2) SHA-256: Wei Dai (Crypto++ library)
+
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute the
+original LZMA SDK code, either in source code form or as a compiled binary, for
+any purpose, commercial or non-commercial, and by any means.
+
+LZMA SDK code is compatible with open source licenses, for example, you can
+include it to GNU GPL or GNU LGPL code.
+
+
+LZMA SDK Contents
+-----------------
+
+ Source code:
+
+ - C / C++ / C# / Java - LZMA compression and decompression
+ - C / C++ - LZMA2 compression and decompression
+ - C / C++ - XZ compression and decompression
+ - C - 7z decompression
+ - C++ - 7z compression and decompression
+ - C - small SFXs for installers (7z decompression)
+ - C++ - SFXs and SFXs for installers (7z decompression)
+
+ Precomiled binaries:
+
+ - console programs for lzma / 7z / xz compression and decompression
+ - SFX modules for installers.
+
+
+UNIX/Linux version
+------------------
+To compile C++ version of file->file LZMA encoding, go to directory
+CPP/7zip/Bundles/LzmaCon
+and call make to recompile it:
+ make -f makefile.gcc clean all
+
+In some UNIX/Linux versions you must compile LZMA with static libraries.
+To compile with static libraries, you can use
+LIB = -lm -static
+
+Also you can use p7zip (port of 7-Zip for POSIX systems like Unix or Linux):
+
+ http://p7zip.sourceforge.net/
+
+
+Files
+-----
+
+DOC/7zC.txt - 7z ANSI-C Decoder description
+DOC/7zFormat.txt - 7z Format description
+DOC/installer.txt - information about 7-Zip for installers
+DOC/lzma.txt - LZMA compression description
+DOC/lzma-sdk.txt - LZMA SDK description (this file)
+DOC/lzma-history.txt - history of LZMA SDK
+DOC/lzma-specification.txt - Specification of LZMA
+DOC/Methods.txt - Compression method IDs for .7z
+
+bin/installer/ - example script to create installer that uses SFX module,
+
+bin/7zdec.exe - simplified 7z archive decoder
+bin/7zr.exe - 7-Zip console program (reduced version)
+bin/x64/7zr.exe - 7-Zip console program (reduced version) (x64 version)
+bin/lzma.exe - file->file LZMA encoder/decoder for Windows
+bin/7zS2.sfx - small SFX module for installers (GUI version)
+bin/7zS2con.sfx - small SFX module for installers (Console version)
+bin/7zSD.sfx - SFX module for installers.
+
+
+7zDec.exe
+---------
+7zDec.exe is simplified 7z archive decoder.
+It supports only LZMA, LZMA2, and PPMd methods.
+7zDec decodes whole solid block from 7z archive to RAM.
+The RAM consumption can be high.
+
+
+
+
+Source code structure
+---------------------
+
+
+Asm/ - asm files (optimized code for CRC calculation and Intel-AES encryption)
+
+C/ - C files (compression / decompression and other)
+ Util/
+ 7z - 7z decoder program (decoding 7z files)
+ Lzma - LZMA program (file->file LZMA encoder/decoder).
+ LzmaLib - LZMA library (.DLL for Windows)
+ SfxSetup - small SFX module for installers
+
+CPP/ -- CPP files
+
+ Common - common files for C++ projects
+ Windows - common files for Windows related code
+
+ 7zip - files related to 7-Zip
+
+ Archive - files related to archiving
+
+ Common - common files for archive handling
+ 7z - 7z C++ Encoder/Decoder
+
+ Bundles - Modules that are bundles of other modules (files)
+
+ Alone7z - 7zr.exe: Standalone 7-Zip console program (reduced version)
+ Format7zExtractR - 7zxr.dll: Reduced version of 7z DLL: extracting from 7z/LZMA/BCJ/BCJ2.
+ Format7zR - 7zr.dll: Reduced version of 7z DLL: extracting/compressing to 7z/LZMA/BCJ/BCJ2
+ LzmaCon - lzma.exe: LZMA compression/decompression
+ LzmaSpec - example code for LZMA Specification
+ SFXCon - 7zCon.sfx: Console 7z SFX module
+ SFXSetup - 7zS.sfx: 7z SFX module for installers
+ SFXWin - 7z.sfx: GUI 7z SFX module
+
+ Common - common files for 7-Zip
+
+ Compress - files for compression/decompression
+
+ Crypto - files for encryption / decompression
+
+ UI - User Interface files
+
+ Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll
+ Common - Common UI files
+ Console - Code for console program (7z.exe)
+ Explorer - Some code from 7-Zip Shell extension
+ FileManager - Some GUI code from 7-Zip File Manager
+ GUI - Some GUI code from 7-Zip
+
+
+CS/ - C# files
+ 7zip
+ Common - some common files for 7-Zip
+ Compress - files related to compression/decompression
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm
+ LZMA - LZMA compression/decompression
+ LzmaAlone - file->file LZMA compression/decompression
+ RangeCoder - Range Coder (special code of compression/decompression)
+
+Java/ - Java files
+ SevenZip
+ Compression - files related to compression/decompression
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm
+ LZMA - LZMA compression/decompression
+ RangeCoder - Range Coder (special code of compression/decompression)
+
+
+Note:
+ Asm / C / C++ source code of LZMA SDK is part of 7-Zip's source code.
+ 7-Zip's source code can be downloaded from 7-Zip's SourceForge page:
+
+ http://sourceforge.net/projects/sevenzip/
+
+
+
+LZMA features
+-------------
+ - Variable dictionary size (up to 1 GB)
+ - Estimated compressing speed: about 2 MB/s on 2 GHz CPU
+ - Estimated decompressing speed:
+ - 20-30 MB/s on modern 2 GHz cpu
+ - 1-2 MB/s on 200 MHz simple RISC cpu: (ARM, MIPS, PowerPC)
+ - Small memory requirements for decompressing (16 KB + DictionarySize)
+ - Small code size for decompressing: 5-8 KB
+
+LZMA decoder uses only integer operations and can be
+implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
+
+Some critical operations that affect the speed of LZMA decompression:
+ 1) 32*16 bit integer multiply
+ 2) Mispredicted branches (penalty mostly depends from pipeline length)
+ 3) 32-bit shift and arithmetic operations
+
+The speed of LZMA decompressing mostly depends from CPU speed.
+Memory speed has no big meaning. But if your CPU has small data cache,
+overall weight of memory speed will slightly increase.
+
+
+How To Use
+----------
+
+Using LZMA encoder/decoder executable
+--------------------------------------
+
+Usage: LZMA <e|d> inputFile outputFile [<switches>...]
+
+ e: encode file
+
+ d: decode file
+
+ b: Benchmark. There are two tests: compressing and decompressing
+ with LZMA method. Benchmark shows rating in MIPS (million
+ instructions per second). Rating value is calculated from
+ measured speed and it is normalized with Intel's Core 2 results.
+ Also Benchmark checks possible hardware errors (RAM
+ errors in most cases). Benchmark uses these settings:
+ (-a1, -d21, -fb32, -mfbt4). You can change only -d parameter.
+ Also you can change the number of iterations. Example for 30 iterations:
+ LZMA b 30
+ Default number of iterations is 10.
+
+<Switches>
+
+
+ -a{N}: set compression mode 0 = fast, 1 = normal
+ default: 1 (normal)
+
+ d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
+ The maximum value for dictionary size is 1 GB = 2^30 bytes.
+ Dictionary size is calculated as DictionarySize = 2^N bytes.
+ For decompressing file compressed by LZMA method with dictionary
+ size D = 2^N you need about D bytes of memory (RAM).
+
+ -fb{N}: set number of fast bytes - [5, 273], default: 128
+ Usually big number gives a little bit better compression ratio
+ and slower compression process.
+
+ -lc{N}: set number of literal context bits - [0, 8], default: 3
+ Sometimes lc=4 gives gain for big files.
+
+ -lp{N}: set number of literal pos bits - [0, 4], default: 0
+ lp switch is intended for periodical data when period is
+ equal 2^N. For example, for 32-bit (4 bytes)
+ periodical data you can use lp=2. Often it's better to set lc0,
+ if you change lp switch.
+
+ -pb{N}: set number of pos bits - [0, 4], default: 2
+ pb switch is intended for periodical data
+ when period is equal 2^N.
+
+ -mf{MF_ID}: set Match Finder. Default: bt4.
+ Algorithms from hc* group doesn't provide good compression
+ ratio, but they often works pretty fast in combination with
+ fast mode (-a0).
+
+ Memory requirements depend from dictionary size
+ (parameter "d" in table below).
+
+ MF_ID Memory Description
+
+ bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
+ bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
+ bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
+ hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
+
+ -eos: write End Of Stream marker. By default LZMA doesn't write
+ eos marker, since LZMA decoder knows uncompressed size
+ stored in .lzma file header.
+
+ -si: Read data from stdin (it will write End Of Stream marker).
+ -so: Write data to stdout
+
+
+Examples:
+
+1) LZMA e file.bin file.lzma -d16 -lc0
+
+compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)
+and 0 literal context bits. -lc0 allows to reduce memory requirements
+for decompression.
+
+
+2) LZMA e file.bin file.lzma -lc0 -lp2
+
+compresses file.bin to file.lzma with settings suitable
+for 32-bit periodical data (for example, ARM or MIPS code).
+
+3) LZMA d file.lzma file.bin
+
+decompresses file.lzma to file.bin.
+
+
+Compression ratio hints
+-----------------------
+
+Recommendations
+---------------
+
+To increase the compression ratio for LZMA compressing it's desirable
+to have aligned data (if it's possible) and also it's desirable to locate
+data in such order, where code is grouped in one place and data is
+grouped in other place (it's better than such mixing: code, data, code,
+data, ...).
+
+
+Filters
+-------
+You can increase the compression ratio for some data types, using
+special filters before compressing. For example, it's possible to
+increase the compression ratio on 5-10% for code for those CPU ISAs:
+x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
+
+You can find C source code of such filters in C/Bra*.* files
+
+You can check the compression ratio gain of these filters with such
+7-Zip commands (example for ARM code):
+No filter:
+ 7z a a1.7z a.bin -m0=lzma
+
+With filter for little-endian ARM code:
+ 7z a a2.7z a.bin -m0=arm -m1=lzma
+
+It works in such manner:
+Compressing = Filter_encoding + LZMA_encoding
+Decompressing = LZMA_decoding + Filter_decoding
+
+Compressing and decompressing speed of such filters is very high,
+so it will not increase decompressing time too much.
+Moreover, it reduces decompression time for LZMA_decoding,
+since compression ratio with filtering is higher.
+
+These filters convert CALL (calling procedure) instructions
+from relative offsets to absolute addresses, so such data becomes more
+compressible.
+
+For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
+
+
+
+---
+
+http://www.7-zip.org
+http://www.7-zip.org/sdk.html
+http://www.7-zip.org/support.html
diff --git a/3rdparty/lzma/DOC/lzma-specification.txt b/3rdparty/lzma/DOC/lzma-specification.txt
new file mode 100644
index 00000000000..ac0cce76a54
--- /dev/null
+++ b/3rdparty/lzma/DOC/lzma-specification.txt
@@ -0,0 +1,1176 @@
+LZMA specification (DRAFT version)
+----------------------------------
+
+Author: Igor Pavlov
+Date: 2015-06-14
+
+This specification defines the format of LZMA compressed data and lzma file format.
+
+Notation
+--------
+
+We use the syntax of C++ programming language.
+We use the following types in C++ code:
+ unsigned - unsigned integer, at least 16 bits in size
+ int - signed integer, at least 16 bits in size
+ UInt64 - 64-bit unsigned integer
+ UInt32 - 32-bit unsigned integer
+ UInt16 - 16-bit unsigned integer
+ Byte - 8-bit unsigned integer
+ bool - boolean type with two possible values: false, true
+
+
+lzma file format
+================
+
+The lzma file contains the raw LZMA stream and the header with related properties.
+
+The files in that format use ".lzma" extension.
+
+The lzma file format layout:
+
+Offset Size Description
+
+ 0 1 LZMA model properties (lc, lp, pb) in encoded form
+ 1 4 Dictionary size (32-bit unsigned integer, little-endian)
+ 5 8 Uncompressed size (64-bit unsigned integer, little-endian)
+ 13 Compressed data (LZMA stream)
+
+LZMA properties:
+
+ name Range Description
+
+ lc [0, 8] the number of "literal context" bits
+ lp [0, 4] the number of "literal pos" bits
+ pb [0, 4] the number of "pos" bits
+dictSize [0, 2^32 - 1] the dictionary size
+
+The following code encodes LZMA properties:
+
+void EncodeProperties(Byte *properties)
+{
+ properties[0] = (Byte)((pb * 5 + lp) * 9 + lc);
+ Set_UInt32_LittleEndian(properties + 1, dictSize);
+}
+
+If the value of dictionary size in properties is smaller than (1 << 12),
+the LZMA decoder must set the dictionary size variable to (1 << 12).
+
+#define LZMA_DIC_MIN (1 << 12)
+
+ unsigned lc, pb, lp;
+ UInt32 dictSize;
+ UInt32 dictSizeInProperties;
+
+ void DecodeProperties(const Byte *properties)
+ {
+ unsigned d = properties[0];
+ if (d >= (9 * 5 * 5))
+ throw "Incorrect LZMA properties";
+ lc = d % 9;
+ d /= 9;
+ pb = d / 5;
+ lp = d % 5;
+ dictSizeInProperties = 0;
+ for (int i = 0; i < 4; i++)
+ dictSizeInProperties |= (UInt32)properties[i + 1] << (8 * i);
+ dictSize = dictSizeInProperties;
+ if (dictSize < LZMA_DIC_MIN)
+ dictSize = LZMA_DIC_MIN;
+ }
+
+If "Uncompressed size" field contains ones in all 64 bits, it means that
+uncompressed size is unknown and there is the "end marker" in stream,
+that indicates the end of decoding point.
+In opposite case, if the value from "Uncompressed size" field is not
+equal to ((2^64) - 1), the LZMA stream decoding must be finished after
+specified number of bytes (Uncompressed size) is decoded. And if there
+is the "end marker", the LZMA decoder must read that marker also.
+
+
+The new scheme to encode LZMA properties
+----------------------------------------
+
+If LZMA compression is used for some another format, it's recommended to
+use a new improved scheme to encode LZMA properties. That new scheme was
+used in xz format that uses the LZMA2 compression algorithm.
+The LZMA2 is a new compression algorithm that is based on the LZMA algorithm.
+
+The dictionary size in LZMA2 is encoded with just one byte and LZMA2 supports
+only reduced set of dictionary sizes:
+ (2 << 11), (3 << 11),
+ (2 << 12), (3 << 12),
+ ...
+ (2 << 30), (3 << 30),
+ (2 << 31) - 1
+
+The dictionary size can be extracted from encoded value with the following code:
+
+ dictSize = (p == 40) ? 0xFFFFFFFF : (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11));
+
+Also there is additional limitation (lc + lp <= 4) in LZMA2 for values of
+"lc" and "lp" properties:
+
+ if (lc + lp > 4)
+ throw "Unsupported properties: (lc + lp) > 4";
+
+There are some advantages for LZMA decoder with such (lc + lp) value
+limitation. It reduces the maximum size of tables allocated by decoder.
+And it reduces the complexity of initialization procedure, that can be
+important to keep high speed of decoding of big number of small LZMA streams.
+
+It's recommended to use that limitation (lc + lp <= 4) for any new format
+that uses LZMA compression. Note that the combinations of "lc" and "lp"
+parameters, where (lc + lp > 4), can provide significant improvement in
+compression ratio only in some rare cases.
+
+The LZMA properties can be encoded into two bytes in new scheme:
+
+Offset Size Description
+
+ 0 1 The dictionary size encoded with LZMA2 scheme
+ 1 1 LZMA model properties (lc, lp, pb) in encoded form
+
+
+The RAM usage
+=============
+
+The RAM usage for LZMA decoder is determined by the following parts:
+
+1) The Sliding Window (from 4 KiB to 4 GiB).
+2) The probability model counter arrays (arrays of 16-bit variables).
+3) Some additional state variables (about 10 variables of 32-bit integers).
+
+
+The RAM usage for Sliding Window
+--------------------------------
+
+There are two main scenarios of decoding:
+
+1) The decoding of full stream to one RAM buffer.
+
+ If we decode full LZMA stream to one output buffer in RAM, the decoder
+ can use that output buffer as sliding window. So the decoder doesn't
+ need additional buffer allocated for sliding window.
+
+2) The decoding to some external storage.
+
+ If we decode LZMA stream to external storage, the decoder must allocate
+ the buffer for sliding window. The size of that buffer must be equal
+ or larger than the value of dictionary size from properties of LZMA stream.
+
+In this specification we describe the code for decoding to some external
+storage. The optimized version of code for decoding of full stream to one
+output RAM buffer can require some minor changes in code.
+
+
+The RAM usage for the probability model counters
+------------------------------------------------
+
+The size of the probability model counter arrays is calculated with the
+following formula:
+
+size_of_prob_arrays = 1846 + 768 * (1 << (lp + lc))
+
+Each probability model counter is 11-bit unsigned integer.
+If we use 16-bit integer variables (2-byte integers) for these probability
+model counters, the RAM usage required by probability model counter arrays
+can be estimated with the following formula:
+
+ RAM = 4 KiB + 1.5 KiB * (1 << (lp + lc))
+
+For example, for default LZMA parameters (lp = 0 and lc = 3), the RAM usage is
+
+ RAM_lc3_lp0 = 4 KiB + 1.5 KiB * 8 = 16 KiB
+
+The maximum RAM state usage is required for decoding the stream with lp = 4
+and lc = 8:
+
+ RAM_lc8_lp4 = 4 KiB + 1.5 KiB * 4096 = 6148 KiB
+
+If the decoder uses LZMA2's limited property condition
+(lc + lp <= 4), the RAM usage will be not larger than
+
+ RAM_lc_lp_4 = 4 KiB + 1.5 KiB * 16 = 28 KiB
+
+
+The RAM usage for encoder
+-------------------------
+
+There are many variants for LZMA encoding code.
+These variants have different values for memory consumption.
+Note that memory consumption for LZMA Encoder can not be
+smaller than memory consumption of LZMA Decoder for same stream.
+
+The RAM usage required by modern effective implementation of
+LZMA Encoder can be estimated with the following formula:
+
+ Encoder_RAM_Usage = 4 MiB + 11 * dictionarySize.
+
+But there are some modes of the encoder that require less memory.
+
+
+LZMA Decoding
+=============
+
+The LZMA compression algorithm uses LZ-based compression with Sliding Window
+and Range Encoding as entropy coding method.
+
+
+Sliding Window
+--------------
+
+LZMA uses Sliding Window compression similar to LZ77 algorithm.
+
+LZMA stream must be decoded to the sequence that consists
+of MATCHES and LITERALS:
+
+ - a LITERAL is a 8-bit character (one byte).
+ The decoder just puts that LITERAL to the uncompressed stream.
+
+ - a MATCH is a pair of two numbers (DISTANCE-LENGTH pair).
+ The decoder takes one byte exactly "DISTANCE" characters behind
+ current position in the uncompressed stream and puts it to
+ uncompressed stream. The decoder must repeat it "LENGTH" times.
+
+The "DISTANCE" can not be larger than dictionary size.
+And the "DISTANCE" can not be larger than the number of bytes in
+the uncompressed stream that were decoded before that match.
+
+In this specification we use cyclic buffer to implement Sliding Window
+for LZMA decoder:
+
+class COutWindow
+{
+ Byte *Buf;
+ UInt32 Pos;
+ UInt32 Size;
+ bool IsFull;
+
+public:
+ unsigned TotalPos;
+ COutStream OutStream;
+
+ COutWindow(): Buf(NULL) {}
+ ~COutWindow() { delete []Buf; }
+
+ void Create(UInt32 dictSize)
+ {
+ Buf = new Byte[dictSize];
+ Pos = 0;
+ Size = dictSize;
+ IsFull = false;
+ TotalPos = 0;
+ }
+
+ void PutByte(Byte b)
+ {
+ TotalPos++;
+ Buf[Pos++] = b;
+ if (Pos == Size)
+ {
+ Pos = 0;
+ IsFull = true;
+ }
+ OutStream.WriteByte(b);
+ }
+
+ Byte GetByte(UInt32 dist) const
+ {
+ return Buf[dist <= Pos ? Pos - dist : Size - dist + Pos];
+ }
+
+ void CopyMatch(UInt32 dist, unsigned len)
+ {
+ for (; len > 0; len--)
+ PutByte(GetByte(dist));
+ }
+
+ bool CheckDistance(UInt32 dist) const
+ {
+ return dist <= Pos || IsFull;
+ }
+
+ bool IsEmpty() const
+ {
+ return Pos == 0 && !IsFull;
+ }
+};
+
+
+In another implementation it's possible to use one buffer that contains
+Sliding Window and the whole data stream after uncompressing.
+
+
+Range Decoder
+-------------
+
+LZMA algorithm uses Range Encoding (1) as entropy coding method.
+
+LZMA stream contains just one very big number in big-endian encoding.
+LZMA decoder uses the Range Decoder to extract a sequence of binary
+symbols from that big number.
+
+The state of the Range Decoder:
+
+struct CRangeDecoder
+{
+ UInt32 Range;
+ UInt32 Code;
+ InputStream *InStream;
+
+ bool Corrupted;
+}
+
+The notes about UInt32 type for the "Range" and "Code" variables:
+
+ It's possible to use 64-bit (unsigned or signed) integer type
+ for the "Range" and the "Code" variables instead of 32-bit unsigned,
+ but some additional code must be used to truncate the values to
+ low 32-bits after some operations.
+
+ If the programming language does not support 32-bit unsigned integer type
+ (like in case of JAVA language), it's possible to use 32-bit signed integer,
+ but some code must be changed. For example, it's required to change the code
+ that uses comparison operations for UInt32 variables in this specification.
+
+The Range Decoder can be in some states that can be treated as
+"Corruption" in LZMA stream. The Range Decoder uses the variable "Corrupted":
+
+ (Corrupted == false), if the Range Decoder has not detected any corruption.
+ (Corrupted == true), if the Range Decoder has detected some corruption.
+
+The reference LZMA Decoder ignores the value of the "Corrupted" variable.
+So it continues to decode the stream, even if the corruption can be detected
+in the Range Decoder. To provide the full compatibility with output of the
+reference LZMA Decoder, another LZMA Decoder implementations must also
+ignore the value of the "Corrupted" variable.
+
+The LZMA Encoder is required to create only such LZMA streams, that will not
+lead the Range Decoder to states, where the "Corrupted" variable is set to true.
+
+The Range Decoder reads first 5 bytes from input stream to initialize
+the state:
+
+bool CRangeDecoder::Init()
+{
+ Corrupted = false;
+ Range = 0xFFFFFFFF;
+ Code = 0;
+
+ Byte b = InStream->ReadByte();
+
+ for (int i = 0; i < 4; i++)
+ Code = (Code << 8) | InStream->ReadByte();
+
+ if (b != 0 || Code == Range)
+ Corrupted = true;
+ return b == 0;
+}
+
+The LZMA Encoder always writes ZERO in initial byte of compressed stream.
+That scheme allows to simplify the code of the Range Encoder in the
+LZMA Encoder. If initial byte is not equal to ZERO, the LZMA Decoder must
+stop decoding and report error.
+
+After the last bit of data was decoded by Range Decoder, the value of the
+"Code" variable must be equal to 0. The LZMA Decoder must check it by
+calling the IsFinishedOK() function:
+
+ bool IsFinishedOK() const { return Code == 0; }
+
+If there is corruption in data stream, there is big probability that
+the "Code" value will be not equal to 0 in the Finish() function. So that
+check in the IsFinishedOK() function provides very good feature for
+corruption detection.
+
+The value of the "Range" variable before each bit decoding can not be smaller
+than ((UInt32)1 << 24). The Normalize() function keeps the "Range" value in
+described range.
+
+#define kTopValue ((UInt32)1 << 24)
+
+void CRangeDecoder::Normalize()
+{
+ if (Range < kTopValue)
+ {
+ Range <<= 8;
+ Code = (Code << 8) | InStream->ReadByte();
+ }
+}
+
+Notes: if the size of the "Code" variable is larger than 32 bits, it's
+required to keep only low 32 bits of the "Code" variable after the change
+in Normalize() function.
+
+If the LZMA Stream is not corrupted, the value of the "Code" variable is
+always smaller than value of the "Range" variable.
+But the Range Decoder ignores some types of corruptions, so the value of
+the "Code" variable can be equal or larger than value of the "Range" variable
+for some "Corrupted" archives.
+
+
+LZMA uses Range Encoding only with binary symbols of two types:
+ 1) binary symbols with fixed and equal probabilities (direct bits)
+ 2) binary symbols with predicted probabilities
+
+The DecodeDirectBits() function decodes the sequence of direct bits:
+
+UInt32 CRangeDecoder::DecodeDirectBits(unsigned numBits)
+{
+ UInt32 res = 0;
+ do
+ {
+ Range >>= 1;
+ Code -= Range;
+ UInt32 t = 0 - ((UInt32)Code >> 31);
+ Code += Range & t;
+
+ if (Code == Range)
+ Corrupted = true;
+
+ Normalize();
+ res <<= 1;
+ res += t + 1;
+ }
+ while (--numBits);
+ return res;
+}
+
+
+The Bit Decoding with Probability Model
+---------------------------------------
+
+The task of Bit Probability Model is to estimate probabilities of binary
+symbols. And then it provides the Range Decoder with that information.
+The better prediction provides better compression ratio.
+The Bit Probability Model uses statistical data of previous decoded
+symbols.
+
+That estimated probability is presented as 11-bit unsigned integer value
+that represents the probability of symbol "0".
+
+#define kNumBitModelTotalBits 11
+
+Mathematical probabilities can be presented with the following formulas:
+ probability(symbol_0) = prob / 2048.
+ probability(symbol_1) = 1 - Probability(symbol_0) =
+ = 1 - prob / 2048 =
+ = (2048 - prob) / 2048
+where the "prob" variable contains 11-bit integer probability counter.
+
+It's recommended to use 16-bit unsigned integer type, to store these 11-bit
+probability values:
+
+typedef UInt16 CProb;
+
+Each probability value must be initialized with value ((1 << 11) / 2),
+that represents the state, where probabilities of symbols 0 and 1
+are equal to 0.5:
+
+#define PROB_INIT_VAL ((1 << kNumBitModelTotalBits) / 2)
+
+The INIT_PROBS macro is used to initialize the array of CProb variables:
+
+#define INIT_PROBS(p) \
+ { for (unsigned i = 0; i < sizeof(p) / sizeof(p[0]); i++) p[i] = PROB_INIT_VAL; }
+
+
+The DecodeBit() function decodes one bit.
+The LZMA decoder provides the pointer to CProb variable that contains
+information about estimated probability for symbol 0 and the Range Decoder
+updates that CProb variable after decoding. The Range Decoder increases
+estimated probability of the symbol that was decoded:
+
+#define kNumMoveBits 5
+
+unsigned CRangeDecoder::DecodeBit(CProb *prob)
+{
+ unsigned v = *prob;
+ UInt32 bound = (Range >> kNumBitModelTotalBits) * v;
+ unsigned symbol;
+ if (Code < bound)
+ {
+ v += ((1 << kNumBitModelTotalBits) - v) >> kNumMoveBits;
+ Range = bound;
+ symbol = 0;
+ }
+ else
+ {
+ v -= v >> kNumMoveBits;
+ Code -= bound;
+ Range -= bound;
+ symbol = 1;
+ }
+ *prob = (CProb)v;
+ Normalize();
+ return symbol;
+}
+
+
+The Binary Tree of bit model counters
+-------------------------------------
+
+LZMA uses a tree of Bit model variables to decode symbol that needs
+several bits for storing. There are two versions of such trees in LZMA:
+ 1) the tree that decodes bits from high bit to low bit (the normal scheme).
+ 2) the tree that decodes bits from low bit to high bit (the reverse scheme).
+
+Each binary tree structure supports different size of decoded symbol
+(the size of binary sequence that contains value of symbol).
+If that size of decoded symbol is "NumBits" bits, the tree structure
+uses the array of (2 << NumBits) counters of CProb type.
+But only ((2 << NumBits) - 1) items are used by encoder and decoder.
+The first item (the item with index equal to 0) in array is unused.
+That scheme with unused array's item allows to simplify the code.
+
+unsigned BitTreeReverseDecode(CProb *probs, unsigned numBits, CRangeDecoder *rc)
+{
+ unsigned m = 1;
+ unsigned symbol = 0;
+ for (unsigned i = 0; i < numBits; i++)
+ {
+ unsigned bit = rc->DecodeBit(&probs[m]);
+ m <<= 1;
+ m += bit;
+ symbol |= (bit << i);
+ }
+ return symbol;
+}
+
+template <unsigned NumBits>
+class CBitTreeDecoder
+{
+ CProb Probs[(unsigned)1 << NumBits];
+
+public:
+
+ void Init()
+ {
+ INIT_PROBS(Probs);
+ }
+
+ unsigned Decode(CRangeDecoder *rc)
+ {
+ unsigned m = 1;
+ for (unsigned i = 0; i < NumBits; i++)
+ m = (m << 1) + rc->DecodeBit(&Probs[m]);
+ return m - ((unsigned)1 << NumBits);
+ }
+
+ unsigned ReverseDecode(CRangeDecoder *rc)
+ {
+ return BitTreeReverseDecode(Probs, NumBits, rc);
+ }
+};
+
+
+LZ part of LZMA
+---------------
+
+LZ part of LZMA describes details about the decoding of MATCHES and LITERALS.
+
+
+The Literal Decoding
+--------------------
+
+The LZMA Decoder uses (1 << (lc + lp)) tables with CProb values, where
+each table contains 0x300 CProb values:
+
+ CProb *LitProbs;
+
+ void CreateLiterals()
+ {
+ LitProbs = new CProb[(UInt32)0x300 << (lc + lp)];
+ }
+
+ void InitLiterals()
+ {
+ UInt32 num = (UInt32)0x300 << (lc + lp);
+ for (UInt32 i = 0; i < num; i++)
+ LitProbs[i] = PROB_INIT_VAL;
+ }
+
+To select the table for decoding it uses the context that consists of
+(lc) high bits from previous literal and (lp) low bits from value that
+represents current position in outputStream.
+
+If (State > 7), the Literal Decoder also uses "matchByte" that represents
+the byte in OutputStream at position the is the DISTANCE bytes before
+current position, where the DISTANCE is the distance in DISTANCE-LENGTH pair
+of latest decoded match.
+
+The following code decodes one literal and puts it to Sliding Window buffer:
+
+ void DecodeLiteral(unsigned state, UInt32 rep0)
+ {
+ unsigned prevByte = 0;
+ if (!OutWindow.IsEmpty())
+ prevByte = OutWindow.GetByte(1);
+
+ unsigned symbol = 1;
+ unsigned litState = ((OutWindow.TotalPos & ((1 << lp) - 1)) << lc) + (prevByte >> (8 - lc));
+ CProb *probs = &LitProbs[(UInt32)0x300 * litState];
+
+ if (state >= 7)
+ {
+ unsigned matchByte = OutWindow.GetByte(rep0 + 1);
+ do
+ {
+ unsigned matchBit = (matchByte >> 7) & 1;
+ matchByte <<= 1;
+ unsigned bit = RangeDec.DecodeBit(&probs[((1 + matchBit) << 8) + symbol]);
+ symbol = (symbol << 1) | bit;
+ if (matchBit != bit)
+ break;
+ }
+ while (symbol < 0x100);
+ }
+ while (symbol < 0x100)
+ symbol = (symbol << 1) | RangeDec.DecodeBit(&probs[symbol]);
+ OutWindow.PutByte((Byte)(symbol - 0x100));
+ }
+
+
+The match length decoding
+-------------------------
+
+The match length decoder returns normalized (zero-based value)
+length of match. That value can be converted to real length of the match
+with the following code:
+
+#define kMatchMinLen 2
+
+ matchLen = len + kMatchMinLen;
+
+The match length decoder can return the values from 0 to 271.
+And the corresponded real match length values can be in the range
+from 2 to 273.
+
+The following scheme is used for the match length encoding:
+
+ Binary encoding Binary Tree structure Zero-based match length
+ sequence (binary + decimal):
+
+ 0 xxx LowCoder[posState] xxx
+ 1 0 yyy MidCoder[posState] yyy + 8
+ 1 1 zzzzzzzz HighCoder zzzzzzzz + 16
+
+LZMA uses bit model variable "Choice" to decode the first selection bit.
+
+If the first selection bit is equal to 0, the decoder uses binary tree
+ LowCoder[posState] to decode 3-bit zero-based match length (xxx).
+
+If the first selection bit is equal to 1, the decoder uses bit model
+ variable "Choice2" to decode the second selection bit.
+
+ If the second selection bit is equal to 0, the decoder uses binary tree
+ MidCoder[posState] to decode 3-bit "yyy" value, and zero-based match
+ length is equal to (yyy + 8).
+
+ If the second selection bit is equal to 1, the decoder uses binary tree
+ HighCoder to decode 8-bit "zzzzzzzz" value, and zero-based
+ match length is equal to (zzzzzzzz + 16).
+
+LZMA uses "posState" value as context to select the binary tree
+from LowCoder and MidCoder binary tree arrays:
+
+ unsigned posState = OutWindow.TotalPos & ((1 << pb) - 1);
+
+The full code of the length decoder:
+
+class CLenDecoder
+{
+ CProb Choice;
+ CProb Choice2;
+ CBitTreeDecoder<3> LowCoder[1 << kNumPosBitsMax];
+ CBitTreeDecoder<3> MidCoder[1 << kNumPosBitsMax];
+ CBitTreeDecoder<8> HighCoder;
+
+public:
+
+ void Init()
+ {
+ Choice = PROB_INIT_VAL;
+ Choice2 = PROB_INIT_VAL;
+ HighCoder.Init();
+ for (unsigned i = 0; i < (1 << kNumPosBitsMax); i++)
+ {
+ LowCoder[i].Init();
+ MidCoder[i].Init();
+ }
+ }
+
+ unsigned Decode(CRangeDecoder *rc, unsigned posState)
+ {
+ if (rc->DecodeBit(&Choice) == 0)
+ return LowCoder[posState].Decode(rc);
+ if (rc->DecodeBit(&Choice2) == 0)
+ return 8 + MidCoder[posState].Decode(rc);
+ return 16 + HighCoder.Decode(rc);
+ }
+};
+
+The LZMA decoder uses two instances of CLenDecoder class.
+The first instance is for the matches of "Simple Match" type,
+and the second instance is for the matches of "Rep Match" type:
+
+ CLenDecoder LenDecoder;
+ CLenDecoder RepLenDecoder;
+
+
+The match distance decoding
+---------------------------
+
+LZMA supports dictionary sizes up to 4 GiB minus 1.
+The value of match distance (decoded by distance decoder) can be
+from 1 to 2^32. But the distance value that is equal to 2^32 is used to
+indicate the "End of stream" marker. So real largest match distance
+that is used for LZ-window match is (2^32 - 1).
+
+LZMA uses normalized match length (zero-based length)
+to calculate the context state "lenState" do decode the distance value:
+
+#define kNumLenToPosStates 4
+
+ unsigned lenState = len;
+ if (lenState > kNumLenToPosStates - 1)
+ lenState = kNumLenToPosStates - 1;
+
+The distance decoder returns the "dist" value that is zero-based value
+of match distance. The real match distance can be calculated with the
+following code:
+
+ matchDistance = dist + 1;
+
+The state of the distance decoder and the initialization code:
+
+ #define kEndPosModelIndex 14
+ #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+ #define kNumAlignBits 4
+
+ CBitTreeDecoder<6> PosSlotDecoder[kNumLenToPosStates];
+ CProb PosDecoders[1 + kNumFullDistances - kEndPosModelIndex];
+ CBitTreeDecoder<kNumAlignBits> AlignDecoder;
+
+ void InitDist()
+ {
+ for (unsigned i = 0; i < kNumLenToPosStates; i++)
+ PosSlotDecoder[i].Init();
+ AlignDecoder.Init();
+ INIT_PROBS(PosDecoders);
+ }
+
+At first stage the distance decoder decodes 6-bit "posSlot" value with bit
+tree decoder from PosSlotDecoder array. It's possible to get 2^6=64 different
+"posSlot" values.
+
+ unsigned posSlot = PosSlotDecoder[lenState].Decode(&RangeDec);
+
+The encoding scheme for distance value is shown in the following table:
+
+posSlot (decimal) /
+ zero-based distance (binary)
+ 0 0
+ 1 1
+ 2 10
+ 3 11
+
+ 4 10 x
+ 5 11 x
+ 6 10 xx
+ 7 11 xx
+ 8 10 xxx
+ 9 11 xxx
+10 10 xxxx
+11 11 xxxx
+12 10 xxxxx
+13 11 xxxxx
+
+14 10 yy zzzz
+15 11 yy zzzz
+16 10 yyy zzzz
+17 11 yyy zzzz
+...
+62 10 yyyyyyyyyyyyyyyyyyyyyyyyyy zzzz
+63 11 yyyyyyyyyyyyyyyyyyyyyyyyyy zzzz
+
+where
+ "x ... x" means the sequence of binary symbols encoded with binary tree and
+ "Reverse" scheme. It uses separated binary tree for each posSlot from 4 to 13.
+ "y" means direct bit encoded with range coder.
+ "zzzz" means the sequence of four binary symbols encoded with binary
+ tree with "Reverse" scheme, where one common binary tree "AlignDecoder"
+ is used for all posSlot values.
+
+If (posSlot < 4), the "dist" value is equal to posSlot value.
+
+If (posSlot >= 4), the decoder uses "posSlot" value to calculate the value of
+ the high bits of "dist" value and the number of the low bits.
+
+ If (4 <= posSlot < kEndPosModelIndex), the decoder uses bit tree decoders.
+ (one separated bit tree decoder per one posSlot value) and "Reverse" scheme.
+ In this implementation we use one CProb array "PosDecoders" that contains
+ all CProb variables for all these bit decoders.
+
+ if (posSlot >= kEndPosModelIndex), the middle bits are decoded as direct
+ bits from RangeDecoder and the low 4 bits are decoded with a bit tree
+ decoder "AlignDecoder" with "Reverse" scheme.
+
+The code to decode zero-based match distance:
+
+ unsigned DecodeDistance(unsigned len)
+ {
+ unsigned lenState = len;
+ if (lenState > kNumLenToPosStates - 1)
+ lenState = kNumLenToPosStates - 1;
+
+ unsigned posSlot = PosSlotDecoder[lenState].Decode(&RangeDec);
+ if (posSlot < 4)
+ return posSlot;
+
+ unsigned numDirectBits = (unsigned)((posSlot >> 1) - 1);
+ UInt32 dist = ((2 | (posSlot & 1)) << numDirectBits);
+ if (posSlot < kEndPosModelIndex)
+ dist += BitTreeReverseDecode(PosDecoders + dist - posSlot, numDirectBits, &RangeDec);
+ else
+ {
+ dist += RangeDec.DecodeDirectBits(numDirectBits - kNumAlignBits) << kNumAlignBits;
+ dist += AlignDecoder.ReverseDecode(&RangeDec);
+ }
+ return dist;
+ }
+
+
+
+LZMA Decoding modes
+-------------------
+
+There are 2 types of LZMA streams:
+
+1) The stream with "End of stream" marker.
+2) The stream without "End of stream" marker.
+
+And the LZMA Decoder supports 3 modes of decoding:
+
+1) The unpack size is undefined. The LZMA decoder stops decoding after
+ getting "End of stream" marker.
+ The input variables for that case:
+
+ markerIsMandatory = true
+ unpackSizeDefined = false
+ unpackSize contains any value
+
+2) The unpack size is defined and LZMA decoder supports both variants,
+ where the stream can contain "End of stream" marker or the stream is
+ finished without "End of stream" marker. The LZMA decoder must detect
+ any of these situations.
+ The input variables for that case:
+
+ markerIsMandatory = false
+ unpackSizeDefined = true
+ unpackSize contains unpack size
+
+3) The unpack size is defined and the LZMA stream must contain
+ "End of stream" marker
+ The input variables for that case:
+
+ markerIsMandatory = true
+ unpackSizeDefined = true
+ unpackSize contains unpack size
+
+
+The main loop of decoder
+------------------------
+
+The main loop of LZMA decoder:
+
+Initialize the LZMA state.
+loop
+{
+ // begin of loop
+ Check "end of stream" conditions.
+ Decode Type of MATCH / LITERAL.
+ If it's LITERAL, decode LITERAL value and put the LITERAL to Window.
+ If it's MATCH, decode the length of match and the match distance.
+ Check error conditions, check end of stream conditions and copy
+ the sequence of match bytes from sliding window to current position
+ in window.
+ Go to begin of loop
+}
+
+The reference implementation of LZMA decoder uses "unpackSize" variable
+to keep the number of remaining bytes in output stream. So it reduces
+"unpackSize" value after each decoded LITERAL or MATCH.
+
+The following code contains the "end of stream" condition check at the start
+of the loop:
+
+ if (unpackSizeDefined && unpackSize == 0 && !markerIsMandatory)
+ if (RangeDec.IsFinishedOK())
+ return LZMA_RES_FINISHED_WITHOUT_MARKER;
+
+LZMA uses three types of matches:
+
+1) "Simple Match" - the match with distance value encoded with bit models.
+
+2) "Rep Match" - the match that uses the distance from distance
+ history table.
+
+3) "Short Rep Match" - the match of single byte length, that uses the latest
+ distance from distance history table.
+
+The LZMA decoder keeps the history of latest 4 match distances that were used
+by decoder. That set of 4 variables contains zero-based match distances and
+these variables are initialized with zero values:
+
+ UInt32 rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
+
+The LZMA decoder uses binary model variables to select type of MATCH or LITERAL:
+
+#define kNumStates 12
+#define kNumPosBitsMax 4
+
+ CProb IsMatch[kNumStates << kNumPosBitsMax];
+ CProb IsRep[kNumStates];
+ CProb IsRepG0[kNumStates];
+ CProb IsRepG1[kNumStates];
+ CProb IsRepG2[kNumStates];
+ CProb IsRep0Long[kNumStates << kNumPosBitsMax];
+
+The decoder uses "state" variable value to select exact variable
+from "IsRep", "IsRepG0", "IsRepG1" and "IsRepG2" arrays.
+The "state" variable can get the value from 0 to 11.
+Initial value for "state" variable is zero:
+
+ unsigned state = 0;
+
+The "state" variable is updated after each LITERAL or MATCH with one of the
+following functions:
+
+unsigned UpdateState_Literal(unsigned state)
+{
+ if (state < 4) return 0;
+ else if (state < 10) return state - 3;
+ else return state - 6;
+}
+unsigned UpdateState_Match (unsigned state) { return state < 7 ? 7 : 10; }
+unsigned UpdateState_Rep (unsigned state) { return state < 7 ? 8 : 11; }
+unsigned UpdateState_ShortRep(unsigned state) { return state < 7 ? 9 : 11; }
+
+The decoder calculates "state2" variable value to select exact variable from
+"IsMatch" and "IsRep0Long" arrays:
+
+unsigned posState = OutWindow.TotalPos & ((1 << pb) - 1);
+unsigned state2 = (state << kNumPosBitsMax) + posState;
+
+The decoder uses the following code flow scheme to select exact
+type of LITERAL or MATCH:
+
+IsMatch[state2] decode
+ 0 - the Literal
+ 1 - the Match
+ IsRep[state] decode
+ 0 - Simple Match
+ 1 - Rep Match
+ IsRepG0[state] decode
+ 0 - the distance is rep0
+ IsRep0Long[state2] decode
+ 0 - Short Rep Match
+ 1 - Rep Match 0
+ 1 -
+ IsRepG1[state] decode
+ 0 - Rep Match 1
+ 1 -
+ IsRepG2[state] decode
+ 0 - Rep Match 2
+ 1 - Rep Match 3
+
+
+LITERAL symbol
+--------------
+If the value "0" was decoded with IsMatch[state2] decoding, we have "LITERAL" type.
+
+At first the LZMA decoder must check that it doesn't exceed
+specified uncompressed size:
+
+ if (unpackSizeDefined && unpackSize == 0)
+ return LZMA_RES_ERROR;
+
+Then it decodes literal value and puts it to sliding window:
+
+ DecodeLiteral(state, rep0);
+
+Then the decoder must update the "state" value and "unpackSize" value;
+
+ state = UpdateState_Literal(state);
+ unpackSize--;
+
+Then the decoder must go to the begin of main loop to decode next Match or Literal.
+
+
+Simple Match
+------------
+
+If the value "1" was decoded with IsMatch[state2] decoding,
+we have the "Simple Match" type.
+
+The distance history table is updated with the following scheme:
+
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+
+The zero-based length is decoded with "LenDecoder":
+
+ len = LenDecoder.Decode(&RangeDec, posState);
+
+The state is update with UpdateState_Match function:
+
+ state = UpdateState_Match(state);
+
+and the new "rep0" value is decoded with DecodeDistance:
+
+ rep0 = DecodeDistance(len);
+
+That "rep0" will be used as zero-based distance for current match.
+
+If the value of "rep0" is equal to 0xFFFFFFFF, it means that we have
+"End of stream" marker, so we can stop decoding and check finishing
+condition in Range Decoder:
+
+ if (rep0 == 0xFFFFFFFF)
+ return RangeDec.IsFinishedOK() ?
+ LZMA_RES_FINISHED_WITH_MARKER :
+ LZMA_RES_ERROR;
+
+If uncompressed size is defined, LZMA decoder must check that it doesn't
+exceed that specified uncompressed size:
+
+ if (unpackSizeDefined && unpackSize == 0)
+ return LZMA_RES_ERROR;
+
+Also the decoder must check that "rep0" value is not larger than dictionary size
+and is not larger than the number of already decoded bytes:
+
+ if (rep0 >= dictSize || !OutWindow.CheckDistance(rep0))
+ return LZMA_RES_ERROR;
+
+Then the decoder must copy match bytes as described in
+"The match symbols copying" section.
+
+
+Rep Match
+---------
+
+If the LZMA decoder has decoded the value "1" with IsRep[state] variable,
+we have "Rep Match" type.
+
+At first the LZMA decoder must check that it doesn't exceed
+specified uncompressed size:
+
+ if (unpackSizeDefined && unpackSize == 0)
+ return LZMA_RES_ERROR;
+
+Also the decoder must return error, if the LZ window is empty:
+
+ if (OutWindow.IsEmpty())
+ return LZMA_RES_ERROR;
+
+If the match type is "Rep Match", the decoder uses one of the 4 variables of
+distance history table to get the value of distance for current match.
+And there are 4 corresponding ways of decoding flow.
+
+The decoder updates the distance history with the following scheme
+depending from type of match:
+
+- "Rep Match 0" or "Short Rep Match":
+ ; LZMA doesn't update the distance history
+
+- "Rep Match 1":
+ UInt32 dist = rep1;
+ rep1 = rep0;
+ rep0 = dist;
+
+- "Rep Match 2":
+ UInt32 dist = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ rep0 = dist;
+
+- "Rep Match 3":
+ UInt32 dist = rep3;
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ rep0 = dist;
+
+Then the decoder decodes exact subtype of "Rep Match" using "IsRepG0", "IsRep0Long",
+"IsRepG1", "IsRepG2".
+
+If the subtype is "Short Rep Match", the decoder updates the state, puts
+the one byte from window to current position in window and goes to next
+MATCH/LITERAL symbol (the begin of main loop):
+
+ state = UpdateState_ShortRep(state);
+ OutWindow.PutByte(OutWindow.GetByte(rep0 + 1));
+ unpackSize--;
+ continue;
+
+In other cases (Rep Match 0/1/2/3), it decodes the zero-based
+length of match with "RepLenDecoder" decoder:
+
+ len = RepLenDecoder.Decode(&RangeDec, posState);
+
+Then it updates the state:
+
+ state = UpdateState_Rep(state);
+
+Then the decoder must copy match bytes as described in
+"The Match symbols copying" section.
+
+
+The match symbols copying
+-------------------------
+
+If we have the match (Simple Match or Rep Match 0/1/2/3), the decoder must
+copy the sequence of bytes with calculated match distance and match length.
+If uncompressed size is defined, LZMA decoder must check that it doesn't
+exceed that specified uncompressed size:
+
+ len += kMatchMinLen;
+ bool isError = false;
+ if (unpackSizeDefined && unpackSize < len)
+ {
+ len = (unsigned)unpackSize;
+ isError = true;
+ }
+ OutWindow.CopyMatch(rep0 + 1, len);
+ unpackSize -= len;
+ if (isError)
+ return LZMA_RES_ERROR;
+
+Then the decoder must go to the begin of main loop to decode next MATCH or LITERAL.
+
+
+
+NOTES
+-----
+
+This specification doesn't describe the variant of decoder implementation
+that supports partial decoding. Such partial decoding case can require some
+changes in "end of stream" condition checks code. Also such code
+can use additional status codes, returned by decoder.
+
+This specification uses C++ code with templates to simplify describing.
+The optimized version of LZMA decoder doesn't need templates.
+Such optimized version can use just two arrays of CProb variables:
+ 1) The dynamic array of CProb variables allocated for the Literal Decoder.
+ 2) The one common array that contains all other CProb variables.
+
+
+References:
+
+1. G. N. N. Martin, Range encoding: an algorithm for removing redundancy
+ from a digitized message, Video & Data Recording Conference,
+ Southampton, UK, July 24-27, 1979.
diff --git a/3rdparty/lzma/DOC/lzma.txt b/3rdparty/lzma/DOC/lzma.txt
new file mode 100644
index 00000000000..87d727b55b5
--- /dev/null
+++ b/3rdparty/lzma/DOC/lzma.txt
@@ -0,0 +1,328 @@
+LZMA compression
+----------------
+Version: 9.35
+
+This file describes LZMA encoding and decoding functions written in C language.
+
+LZMA is an improved version of famous LZ77 compression algorithm.
+It was improved in way of maximum increasing of compression ratio,
+keeping high decompression speed and low memory requirements for
+decompressing.
+
+Note: you can read also LZMA Specification (lzma-specification.txt from LZMA SDK)
+
+Also you can look source code for LZMA encoding and decoding:
+ C/Util/Lzma/LzmaUtil.c
+
+
+LZMA compressed file format
+---------------------------
+Offset Size Description
+ 0 1 Special LZMA properties (lc,lp, pb in encoded form)
+ 1 4 Dictionary size (little endian)
+ 5 8 Uncompressed size (little endian). -1 means unknown size
+ 13 Compressed data
+
+
+
+ANSI-C LZMA Decoder
+~~~~~~~~~~~~~~~~~~~
+
+Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58.
+If you want to use old interfaces you can download previous version of LZMA SDK
+from sourceforge.net site.
+
+To use ANSI-C LZMA Decoder you need the following files:
+1) LzmaDec.h + LzmaDec.c + Types.h
+
+Look example code:
+ C/Util/Lzma/LzmaUtil.c
+
+
+Memory requirements for LZMA decoding
+-------------------------------------
+
+Stack usage of LZMA decoding function for local variables is not
+larger than 200-400 bytes.
+
+LZMA Decoder uses dictionary buffer and internal state structure.
+Internal state structure consumes
+ state_size = (4 + (1.5 << (lc + lp))) KB
+by default (lc=3, lp=0), state_size = 16 KB.
+
+
+How To decompress data
+----------------------
+
+LZMA Decoder (ANSI-C version) now supports 2 interfaces:
+1) Single-call Decompressing
+2) Multi-call State Decompressing (zlib-like interface)
+
+You must use external allocator:
+Example:
+void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }
+void SzFree(void *p, void *address) { p = p; free(address); }
+ISzAlloc alloc = { SzAlloc, SzFree };
+
+You can use p = p; operator to disable compiler warnings.
+
+
+Single-call Decompressing
+-------------------------
+When to use: RAM->RAM decompressing
+Compile files: LzmaDec.h + LzmaDec.c + Types.h
+Compile defines: no defines
+Memory Requirements:
+ - Input buffer: compressed size
+ - Output buffer: uncompressed size
+ - LZMA Internal Structures: state_size (16 KB for default settings)
+
+Interface:
+ int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+ ELzmaStatus *status, ISzAlloc *alloc);
+ In:
+ dest - output data
+ destLen - output data size
+ src - input data
+ srcLen - input data size
+ propData - LZMA properties (5 bytes)
+ propSize - size of propData buffer (5 bytes)
+ finishMode - It has meaning only if the decoding reaches output limit (*destLen).
+ LZMA_FINISH_ANY - Decode just destLen bytes.
+ LZMA_FINISH_END - Stream must be finished after (*destLen).
+ You can use LZMA_FINISH_END, when you know that
+ current output buffer covers last bytes of stream.
+ alloc - Memory allocator.
+
+ Out:
+ destLen - processed output size
+ srcLen - processed input size
+
+ Output:
+ SZ_OK
+ status:
+ LZMA_STATUS_FINISHED_WITH_MARK
+ LZMA_STATUS_NOT_FINISHED
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+ SZ_ERROR_DATA - Data error
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+
+ If LZMA decoder sees end_marker before reaching output limit, it returns OK result,
+ and output value of destLen will be less than output buffer size limit.
+
+ You can use multiple checks to test data integrity after full decompression:
+ 1) Check Result and "status" variable.
+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
+ You must use correct finish mode in that case. */
+
+
+Multi-call State Decompressing (zlib-like interface)
+----------------------------------------------------
+
+When to use: file->file decompressing
+Compile files: LzmaDec.h + LzmaDec.c + Types.h
+
+Memory Requirements:
+ - Buffer for input stream: any size (for example, 16 KB)
+ - Buffer for output stream: any size (for example, 16 KB)
+ - LZMA Internal Structures: state_size (16 KB for default settings)
+ - LZMA dictionary (dictionary size is encoded in LZMA properties header)
+
+1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header:
+ unsigned char header[LZMA_PROPS_SIZE + 8];
+ ReadFile(inFile, header, sizeof(header)
+
+2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties
+
+ CLzmaDec state;
+ LzmaDec_Constr(&state);
+ res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);
+ if (res != SZ_OK)
+ return res;
+
+3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop
+
+ LzmaDec_Init(&state);
+ for (;;)
+ {
+ ...
+ int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);
+ ...
+ }
+
+
+4) Free all allocated structures
+ LzmaDec_Free(&state, &g_Alloc);
+
+Look example code:
+ C/Util/Lzma/LzmaUtil.c
+
+
+How To compress data
+--------------------
+
+Compile files:
+ Types.h
+ Threads.h
+ LzmaEnc.h
+ LzmaEnc.c
+ LzFind.h
+ LzFind.c
+ LzFindMt.h
+ LzFindMt.c
+ LzHash.h
+
+Memory Requirements:
+ - (dictSize * 11.5 + 6 MB) + state_size
+
+Lzma Encoder can use two memory allocators:
+1) alloc - for small arrays.
+2) allocBig - for big arrays.
+
+For example, you can use Large RAM Pages (2 MB) in allocBig allocator for
+better compression speed. Note that Windows has bad implementation for
+Large RAM Pages.
+It's OK to use same allocator for alloc and allocBig.
+
+
+Single-call Compression with callbacks
+--------------------------------------
+
+Look example code:
+ C/Util/Lzma/LzmaUtil.c
+
+When to use: file->file compressing
+
+1) you must implement callback structures for interfaces:
+ISeqInStream
+ISeqOutStream
+ICompressProgress
+ISzAlloc
+
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+ CFileSeqInStream inStream;
+ CFileSeqOutStream outStream;
+
+ inStream.funcTable.Read = MyRead;
+ inStream.file = inFile;
+ outStream.funcTable.Write = MyWrite;
+ outStream.file = outFile;
+
+
+2) Create CLzmaEncHandle object;
+
+ CLzmaEncHandle enc;
+
+ enc = LzmaEnc_Create(&g_Alloc);
+ if (enc == 0)
+ return SZ_ERROR_MEM;
+
+
+3) initialize CLzmaEncProps properties;
+
+ LzmaEncProps_Init(&props);
+
+ Then you can change some properties in that structure.
+
+4) Send LZMA properties to LZMA Encoder
+
+ res = LzmaEnc_SetProps(enc, &props);
+
+5) Write encoded properties to header
+
+ Byte header[LZMA_PROPS_SIZE + 8];
+ size_t headerSize = LZMA_PROPS_SIZE;
+ UInt64 fileSize;
+ int i;
+
+ res = LzmaEnc_WriteProperties(enc, header, &headerSize);
+ fileSize = MyGetFileLength(inFile);
+ for (i = 0; i < 8; i++)
+ header[headerSize++] = (Byte)(fileSize >> (8 * i));
+ MyWriteFileAndCheck(outFile, header, headerSize)
+
+6) Call encoding function:
+ res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable,
+ NULL, &g_Alloc, &g_Alloc);
+
+7) Destroy LZMA Encoder Object
+ LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
+
+
+If callback function return some error code, LzmaEnc_Encode also returns that code
+or it can return the code like SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS.
+
+
+Single-call RAM->RAM Compression
+--------------------------------
+
+Single-call RAM->RAM Compression is similar to Compression with callbacks,
+but you provide pointers to buffers instead of pointers to stream callbacks:
+
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+
+Return code:
+ SZ_OK - OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_PARAM - Incorrect paramater
+ SZ_ERROR_OUTPUT_EOF - output buffer overflow
+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
+
+
+
+Defines
+-------
+
+_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code.
+
+_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for
+ some structures will be doubled in that case.
+
+_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is 32-bit.
+
+_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type.
+
+
+_7ZIP_PPMD_SUPPPORT - Define it if you don't want to support PPMD method in AMSI-C .7z decoder.
+
+
+C++ LZMA Encoder/Decoder
+~~~~~~~~~~~~~~~~~~~~~~~~
+C++ LZMA code use COM-like interfaces. So if you want to use it,
+you can study basics of COM/OLE.
+C++ LZMA code is just wrapper over ANSI-C code.
+
+
+C++ Notes
+~~~~~~~~~~~~~~~~~~~~~~~~
+If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling),
+you must check that you correctly work with "new" operator.
+7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator.
+So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator:
+operator new(size_t size)
+{
+ void *p = ::malloc(size);
+ if (p == 0)
+ throw CNewException();
+ return p;
+}
+If you use MSCV that throws exception for "new" operator, you can compile without
+"NewHandler.cpp". So standard exception will be used. Actually some code of
+7-Zip catches any exception in internal code and converts it to HRESULT code.
+So you don't need to catch CNewException, if you call COM interfaces of 7-Zip.
+
+---
+
+http://www.7-zip.org
+http://www.7-zip.org/sdk.html
+http://www.7-zip.org/support.html
diff --git a/3rdparty/lzma/Methods.txt b/3rdparty/lzma/Methods.txt
deleted file mode 100644
index f52e7c3158e..00000000000
--- a/3rdparty/lzma/Methods.txt
+++ /dev/null
@@ -1,152 +0,0 @@
-7-Zip method IDs (9.18)
------------------------
-
-Each compression or crypto method in 7z has unique binary value (ID).
-The length of ID in bytes is arbitrary but it can not exceed 63 bits (8 bytes).
-
-If you want to add some new ID, you have two ways:
-1) Write request for allocating IDs to 7-zip developers.
-2) Generate 8-bytes ID:
-
- 3F ZZ ZZ ZZ ZZ ZZ MM MM
-
- 3F - Prefix for random IDs (1 byte)
- ZZ ZZ ZZ ZZ ZZ - Developer ID (5 bytes). Use real random bytes.
-
- MM MM - Method ID (2 bytes)
-
- You can notify 7-Zip developers about your Developer ID / Method ID.
-
- Note: Use new ID only if old codec can not decode data encoded with new version.
-
-
-List of defined IDs
--------------------
-
-00 - Copy
-
-03 - Delta
-04 - x86 (BCJ)
-05 - PPC (Big Endian)
-06 - IA64
-07 - ARM (little endian)
-08 - ARM Thumb (little endian)
-09 - SPARC
-21 - LZMA2
-
-02.. - Common
- 03 Swap
- - 2 Swap2
- - 4 Swap4
-
-03.. - 7z
- 01 - LZMA
- 01 - Version
-
- 03 - Branch
- 01 - x86
- 03 - BCJ
- 1B - BCJ2
- 02 - PPC
- 05 - PPC (Big Endian)
- 03 - Alpha
- 01 - Alpha
- 04 - IA64
- 01 - IA64
- 05 - ARM
- 01 - ARM
- 06 - M68
- 05 - M68 (Big Endian)
- 07 - ARM Thumb
- 01 - ARMT
- 08 - SPARC
- 05 - SPARC
-
- 04 - PPMD
- 01 - Version
-
- 7F -
- 01 - experimental methods.
-
-
-04.. - Misc
- 00 - Reserved
- 01 - Zip
- 00 - Copy (not used). Use {00} instead
- 01 - Shrink
- 06 - Implode
- 08 - Deflate
- 09 - Deflate64
- 10 - Imploding
- 12 - BZip2 (not used). Use {04 02 02} instead
- 14 - LZMA
- 60 - Jpeg
- 61 - WavPack
- 62 - PPMd
- 63 - wzAES
- 02 - BZip
- 02 - BZip2
- 03 - Rar
- 01 - Rar15
- 02 - Rar20
- 03 - Rar29
- 04 - Arj
- 01 - Arj (1,2,3)
- 02 - Arj 4
- 05 - Z
- 06 - Lzh
- 07 - Reserved for 7z
- 08 - Cab
- 09 - NSIS
- 01 - DeflateNSIS
- 02 - BZip2NSIS
-
-
-06.. - Crypto
- 00 -
- 01 - AES
- 0x - AES-128
- 4x - AES-192
- 8x - AES-256
- Cx - AES
-
- x0 - ECB
- x1 - CBC
- x2 - CFB
- x3 - OFB
-
- 07 - Reserved
- 0F - Reserved
-
- F0 - Misc Ciphers (Real Ciphers without hashing algo)
-
- F1 - Misc Ciphers (Combine)
- 01 - Zip
- 01 - Main Zip crypto algo
- 03 - RAR
- 02 -
- 03 - Rar29 AES-128 + (modified SHA-1)
- 07 - 7z
- 01 - AES-256 + SHA-256
-
-07.. - Hash (subject to change)
- 00 -
- 01 - CRC
- 02 - SHA-1
- 03 - SHA-256
- 04 - SHA-384
- 05 - SHA-512
-
- F0 - Misc Hash
-
- F1 - Misc
- 03 - RAR
- 03 - Rar29 Password Hashing (modified SHA1)
- 07 - 7z
- 01 - SHA-256 Password Hashing
-
-
-
-
----
-End of document
diff --git a/3rdparty/lzma/lzma.exe b/3rdparty/lzma/lzma.exe
deleted file mode 100644
index a1e8fa7a1e9..00000000000
--- a/3rdparty/lzma/lzma.exe
+++ /dev/null
Binary files differ
diff --git a/3rdparty/lzma/lzma.txt b/3rdparty/lzma/lzma.txt
deleted file mode 100644
index 77e5b61612a..00000000000
--- a/3rdparty/lzma/lzma.txt
+++ /dev/null
@@ -1,604 +0,0 @@
-LZMA SDK 9.22
--------------
-
-LZMA SDK provides the documentation, samples, header files, libraries,
-and tools you need to develop applications that use LZMA compression.
-
-LZMA is default and general compression method of 7z format
-in 7-Zip compression program (www.7-zip.org). LZMA provides high
-compression ratio and very fast decompression.
-
-LZMA is an improved version of famous LZ77 compression algorithm.
-It was improved in way of maximum increasing of compression ratio,
-keeping high decompression speed and low memory requirements for
-decompressing.
-
-
-
-LICENSE
--------
-
-LZMA SDK is written and placed in the public domain by Igor Pavlov.
-
-Some code in LZMA SDK is based on public domain code from another developers:
- 1) PPMd var.H (2001): Dmitry Shkarin
- 2) SHA-256: Wei Dai (Crypto++ library)
-
-You can copy, modify, distribute and perform LZMA SDK code, even for commercial purposes,
-all without asking permission.
-
-LZMA SDK code is compatible with open source licenses, for example, you can
-include it to GNU GPL or GNU LGPL code.
-
-
-LZMA SDK Contents
------------------
-
-LZMA SDK includes:
-
- - ANSI-C/C++/C#/Java source code for LZMA compressing and decompressing
- - Compiled file->file LZMA compressing/decompressing program for Windows system
-
-
-UNIX/Linux version
-------------------
-To compile C++ version of file->file LZMA encoding, go to directory
-CPP/7zip/Bundles/LzmaCon
-and call make to recompile it:
- make -f makefile.gcc clean all
-
-In some UNIX/Linux versions you must compile LZMA with static libraries.
-To compile with static libraries, you can use
-LIB = -lm -static
-
-
-Files
----------------------
-lzma.txt - LZMA SDK description (this file)
-7zFormat.txt - 7z Format description
-7zC.txt - 7z ANSI-C Decoder description
-methods.txt - Compression method IDs for .7z
-lzma.exe - Compiled file->file LZMA encoder/decoder for Windows
-7zr.exe - 7-Zip with 7z/lzma/xz support.
-history.txt - history of the LZMA SDK
-
-
-Source code structure
----------------------
-
-C/ - C files
- 7zCrc*.* - CRC code
- Alloc.* - Memory allocation functions
- Bra*.* - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
- LzFind.* - Match finder for LZ (LZMA) encoders
- LzFindMt.* - Match finder for LZ (LZMA) encoders for multithreading encoding
- LzHash.h - Additional file for LZ match finder
- LzmaDec.* - LZMA decoding
- LzmaEnc.* - LZMA encoding
- LzmaLib.* - LZMA Library for DLL calling
- Types.h - Basic types for another .c files
- Threads.* - The code for multithreading.
-
- LzmaLib - LZMA Library (.DLL for Windows)
-
- LzmaUtil - LZMA Utility (file->file LZMA encoder/decoder).
-
- Archive - files related to archiving
- 7z - 7z ANSI-C Decoder
-
-CPP/ -- CPP files
-
- Common - common files for C++ projects
- Windows - common files for Windows related code
-
- 7zip - files related to 7-Zip Project
-
- Common - common files for 7-Zip
-
- Compress - files related to compression/decompression
-
- Archive - files related to archiving
-
- Common - common files for archive handling
- 7z - 7z C++ Encoder/Decoder
-
- Bundles - Modules that are bundles of other modules
-
- Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2
- LzmaCon - lzma.exe: LZMA compression/decompression
- Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2
- Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.
-
- UI - User Interface files
-
- Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll
- Common - Common UI files
- Console - Code for console archiver
-
-
-
-CS/ - C# files
- 7zip
- Common - some common files for 7-Zip
- Compress - files related to compression/decompression
- LZ - files related to LZ (Lempel-Ziv) compression algorithm
- LZMA - LZMA compression/decompression
- LzmaAlone - file->file LZMA compression/decompression
- RangeCoder - Range Coder (special code of compression/decompression)
-
-Java/ - Java files
- SevenZip
- Compression - files related to compression/decompression
- LZ - files related to LZ (Lempel-Ziv) compression algorithm
- LZMA - LZMA compression/decompression
- RangeCoder - Range Coder (special code of compression/decompression)
-
-
-C/C++ source code of LZMA SDK is part of 7-Zip project.
-7-Zip source code can be downloaded from 7-Zip's SourceForge page:
-
- http://sourceforge.net/projects/sevenzip/
-
-
-
-LZMA features
--------------
- - Variable dictionary size (up to 1 GB)
- - Estimated compressing speed: about 2 MB/s on 2 GHz CPU
- - Estimated decompressing speed:
- - 20-30 MB/s on 2 GHz Core 2 or AMD Athlon 64
- - 1-2 MB/s on 200 MHz ARM, MIPS, PowerPC or other simple RISC
- - Small memory requirements for decompressing (16 KB + DictionarySize)
- - Small code size for decompressing: 5-8 KB
-
-LZMA decoder uses only integer operations and can be
-implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
-
-Some critical operations that affect the speed of LZMA decompression:
- 1) 32*16 bit integer multiply
- 2) Misspredicted branches (penalty mostly depends from pipeline length)
- 3) 32-bit shift and arithmetic operations
-
-The speed of LZMA decompressing mostly depends from CPU speed.
-Memory speed has no big meaning. But if your CPU has small data cache,
-overall weight of memory speed will slightly increase.
-
-
-How To Use
-----------
-
-Using LZMA encoder/decoder executable
---------------------------------------
-
-Usage: LZMA <e|d> inputFile outputFile [<switches>...]
-
- e: encode file
-
- d: decode file
-
- b: Benchmark. There are two tests: compressing and decompressing
- with LZMA method. Benchmark shows rating in MIPS (million
- instructions per second). Rating value is calculated from
- measured speed and it is normalized with Intel's Core 2 results.
- Also Benchmark checks possible hardware errors (RAM
- errors in most cases). Benchmark uses these settings:
- (-a1, -d21, -fb32, -mfbt4). You can change only -d parameter.
- Also you can change the number of iterations. Example for 30 iterations:
- LZMA b 30
- Default number of iterations is 10.
-
-<Switches>
-
-
- -a{N}: set compression mode 0 = fast, 1 = normal
- default: 1 (normal)
-
- d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
- The maximum value for dictionary size is 1 GB = 2^30 bytes.
- Dictionary size is calculated as DictionarySize = 2^N bytes.
- For decompressing file compressed by LZMA method with dictionary
- size D = 2^N you need about D bytes of memory (RAM).
-
- -fb{N}: set number of fast bytes - [5, 273], default: 128
- Usually big number gives a little bit better compression ratio
- and slower compression process.
-
- -lc{N}: set number of literal context bits - [0, 8], default: 3
- Sometimes lc=4 gives gain for big files.
-
- -lp{N}: set number of literal pos bits - [0, 4], default: 0
- lp switch is intended for periodical data when period is
- equal 2^N. For example, for 32-bit (4 bytes)
- periodical data you can use lp=2. Often it's better to set lc0,
- if you change lp switch.
-
- -pb{N}: set number of pos bits - [0, 4], default: 2
- pb switch is intended for periodical data
- when period is equal 2^N.
-
- -mf{MF_ID}: set Match Finder. Default: bt4.
- Algorithms from hc* group doesn't provide good compression
- ratio, but they often works pretty fast in combination with
- fast mode (-a0).
-
- Memory requirements depend from dictionary size
- (parameter "d" in table below).
-
- MF_ID Memory Description
-
- bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
- bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
- bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
- hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
-
- -eos: write End Of Stream marker. By default LZMA doesn't write
- eos marker, since LZMA decoder knows uncompressed size
- stored in .lzma file header.
-
- -si: Read data from stdin (it will write End Of Stream marker).
- -so: Write data to stdout
-
-
-Examples:
-
-1) LZMA e file.bin file.lzma -d16 -lc0
-
-compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)
-and 0 literal context bits. -lc0 allows to reduce memory requirements
-for decompression.
-
-
-2) LZMA e file.bin file.lzma -lc0 -lp2
-
-compresses file.bin to file.lzma with settings suitable
-for 32-bit periodical data (for example, ARM or MIPS code).
-
-3) LZMA d file.lzma file.bin
-
-decompresses file.lzma to file.bin.
-
-
-Compression ratio hints
------------------------
-
-Recommendations
----------------
-
-To increase the compression ratio for LZMA compressing it's desirable
-to have aligned data (if it's possible) and also it's desirable to locate
-data in such order, where code is grouped in one place and data is
-grouped in other place (it's better than such mixing: code, data, code,
-data, ...).
-
-
-Filters
--------
-You can increase the compression ratio for some data types, using
-special filters before compressing. For example, it's possible to
-increase the compression ratio on 5-10% for code for those CPU ISAs:
-x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
-
-You can find C source code of such filters in C/Bra*.* files
-
-You can check the compression ratio gain of these filters with such
-7-Zip commands (example for ARM code):
-No filter:
- 7z a a1.7z a.bin -m0=lzma
-
-With filter for little-endian ARM code:
- 7z a a2.7z a.bin -m0=arm -m1=lzma
-
-It works in such manner:
-Compressing = Filter_encoding + LZMA_encoding
-Decompressing = LZMA_decoding + Filter_decoding
-
-Compressing and decompressing speed of such filters is very high,
-so it will not increase decompressing time too much.
-Moreover, it reduces decompression time for LZMA_decoding,
-since compression ratio with filtering is higher.
-
-These filters convert CALL (calling procedure) instructions
-from relative offsets to absolute addresses, so such data becomes more
-compressible.
-
-For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
-
-
-LZMA compressed file format
----------------------------
-Offset Size Description
- 0 1 Special LZMA properties (lc,lp, pb in encoded form)
- 1 4 Dictionary size (little endian)
- 5 8 Uncompressed size (little endian). -1 means unknown size
- 13 Compressed data
-
-
-ANSI-C LZMA Decoder
-~~~~~~~~~~~~~~~~~~~
-
-Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58.
-If you want to use old interfaces you can download previous version of LZMA SDK
-from sourceforge.net site.
-
-To use ANSI-C LZMA Decoder you need the following files:
-1) LzmaDec.h + LzmaDec.c + Types.h
-LzmaUtil/LzmaUtil.c is example application that uses these files.
-
-
-Memory requirements for LZMA decoding
--------------------------------------
-
-Stack usage of LZMA decoding function for local variables is not
-larger than 200-400 bytes.
-
-LZMA Decoder uses dictionary buffer and internal state structure.
-Internal state structure consumes
- state_size = (4 + (1.5 << (lc + lp))) KB
-by default (lc=3, lp=0), state_size = 16 KB.
-
-
-How To decompress data
-----------------------
-
-LZMA Decoder (ANSI-C version) now supports 2 interfaces:
-1) Single-call Decompressing
-2) Multi-call State Decompressing (zlib-like interface)
-
-You must use external allocator:
-Example:
-void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }
-void SzFree(void *p, void *address) { p = p; free(address); }
-ISzAlloc alloc = { SzAlloc, SzFree };
-
-You can use p = p; operator to disable compiler warnings.
-
-
-Single-call Decompressing
--------------------------
-When to use: RAM->RAM decompressing
-Compile files: LzmaDec.h + LzmaDec.c + Types.h
-Compile defines: no defines
-Memory Requirements:
- - Input buffer: compressed size
- - Output buffer: uncompressed size
- - LZMA Internal Structures: state_size (16 KB for default settings)
-
-Interface:
- int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
- const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
- ELzmaStatus *status, ISzAlloc *alloc);
- In:
- dest - output data
- destLen - output data size
- src - input data
- srcLen - input data size
- propData - LZMA properties (5 bytes)
- propSize - size of propData buffer (5 bytes)
- finishMode - It has meaning only if the decoding reaches output limit (*destLen).
- LZMA_FINISH_ANY - Decode just destLen bytes.
- LZMA_FINISH_END - Stream must be finished after (*destLen).
- You can use LZMA_FINISH_END, when you know that
- current output buffer covers last bytes of stream.
- alloc - Memory allocator.
-
- Out:
- destLen - processed output size
- srcLen - processed input size
-
- Output:
- SZ_OK
- status:
- LZMA_STATUS_FINISHED_WITH_MARK
- LZMA_STATUS_NOT_FINISHED
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
- SZ_ERROR_DATA - Data error
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_UNSUPPORTED - Unsupported properties
- SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
-
- If LZMA decoder sees end_marker before reaching output limit, it returns OK result,
- and output value of destLen will be less than output buffer size limit.
-
- You can use multiple checks to test data integrity after full decompression:
- 1) Check Result and "status" variable.
- 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
- 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
- You must use correct finish mode in that case. */
-
-
-Multi-call State Decompressing (zlib-like interface)
-----------------------------------------------------
-
-When to use: file->file decompressing
-Compile files: LzmaDec.h + LzmaDec.c + Types.h
-
-Memory Requirements:
- - Buffer for input stream: any size (for example, 16 KB)
- - Buffer for output stream: any size (for example, 16 KB)
- - LZMA Internal Structures: state_size (16 KB for default settings)
- - LZMA dictionary (dictionary size is encoded in LZMA properties header)
-
-1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header:
- unsigned char header[LZMA_PROPS_SIZE + 8];
- ReadFile(inFile, header, sizeof(header)
-
-2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties
-
- CLzmaDec state;
- LzmaDec_Constr(&state);
- res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);
- if (res != SZ_OK)
- return res;
-
-3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop
-
- LzmaDec_Init(&state);
- for (;;)
- {
- ...
- int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);
- ...
- }
-
-
-4) Free all allocated structures
- LzmaDec_Free(&state, &g_Alloc);
-
-For full code example, look at C/LzmaUtil/LzmaUtil.c code.
-
-
-How To compress data
---------------------
-
-Compile files: LzmaEnc.h + LzmaEnc.c + Types.h +
-LzFind.c + LzFind.h + LzFindMt.c + LzFindMt.h + LzHash.h
-
-Memory Requirements:
- - (dictSize * 11.5 + 6 MB) + state_size
-
-Lzma Encoder can use two memory allocators:
-1) alloc - for small arrays.
-2) allocBig - for big arrays.
-
-For example, you can use Large RAM Pages (2 MB) in allocBig allocator for
-better compression speed. Note that Windows has bad implementation for
-Large RAM Pages.
-It's OK to use same allocator for alloc and allocBig.
-
-
-Single-call Compression with callbacks
---------------------------------------
-
-Check C/LzmaUtil/LzmaUtil.c as example,
-
-When to use: file->file decompressing
-
-1) you must implement callback structures for interfaces:
-ISeqInStream
-ISeqOutStream
-ICompressProgress
-ISzAlloc
-
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
- CFileSeqInStream inStream;
- CFileSeqOutStream outStream;
-
- inStream.funcTable.Read = MyRead;
- inStream.file = inFile;
- outStream.funcTable.Write = MyWrite;
- outStream.file = outFile;
-
-
-2) Create CLzmaEncHandle object;
-
- CLzmaEncHandle enc;
-
- enc = LzmaEnc_Create(&g_Alloc);
- if (enc == 0)
- return SZ_ERROR_MEM;
-
-
-3) initialize CLzmaEncProps properties;
-
- LzmaEncProps_Init(&props);
-
- Then you can change some properties in that structure.
-
-4) Send LZMA properties to LZMA Encoder
-
- res = LzmaEnc_SetProps(enc, &props);
-
-5) Write encoded properties to header
-
- Byte header[LZMA_PROPS_SIZE + 8];
- size_t headerSize = LZMA_PROPS_SIZE;
- UInt64 fileSize;
- int i;
-
- res = LzmaEnc_WriteProperties(enc, header, &headerSize);
- fileSize = MyGetFileLength(inFile);
- for (i = 0; i < 8; i++)
- header[headerSize++] = (Byte)(fileSize >> (8 * i));
- MyWriteFileAndCheck(outFile, header, headerSize)
-
-6) Call encoding function:
- res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable,
- NULL, &g_Alloc, &g_Alloc);
-
-7) Destroy LZMA Encoder Object
- LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
-
-
-If callback function return some error code, LzmaEnc_Encode also returns that code
-or it can return the code like SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS.
-
-
-Single-call RAM->RAM Compression
---------------------------------
-
-Single-call RAM->RAM Compression is similar to Compression with callbacks,
-but you provide pointers to buffers instead of pointers to stream callbacks:
-
-HRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
- CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-
-Return code:
- SZ_OK - OK
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_PARAM - Incorrect paramater
- SZ_ERROR_OUTPUT_EOF - output buffer overflow
- SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
-
-
-
-Defines
--------
-
-_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code.
-
-_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for
- some structures will be doubled in that case.
-
-_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is 32-bit.
-
-_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type.
-
-
-_7ZIP_PPMD_SUPPPORT - Define it if you don't want to support PPMD method in AMSI-C .7z decoder.
-
-
-C++ LZMA Encoder/Decoder
-~~~~~~~~~~~~~~~~~~~~~~~~
-C++ LZMA code use COM-like interfaces. So if you want to use it,
-you can study basics of COM/OLE.
-C++ LZMA code is just wrapper over ANSI-C code.
-
-
-C++ Notes
-~~~~~~~~~~~~~~~~~~~~~~~~
-If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling),
-you must check that you correctly work with "new" operator.
-7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator.
-So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator:
-operator new(size_t size)
-{
- void *p = ::malloc(size);
- if (p == 0)
- throw CNewException();
- return p;
-}
-If you use MSCV that throws exception for "new" operator, you can compile without
-"NewHandler.cpp". So standard exception will be used. Actually some code of
-7-Zip catches any exception in internal code and converts it to HRESULT code.
-So you don't need to catch CNewException, if you call COM interfaces of 7-Zip.
-
----
-
-http://www.7-zip.org
-http://www.7-zip.org/sdk.html
-http://www.7-zip.org/support.html