Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2017-04-30 03:00:00 +0300
committerKornel <kornel@geekhood.net>2017-05-05 20:56:20 +0300
commit2efa10565ac395d2ce9a679ead46e70fb2f963eb (patch)
tree84c8df4deb69ec44ea15af9378f24347db55c357
parent603abd5528c97346e9448c0ff47949f818fe558c (diff)
17.0017.00
-rw-r--r--C/7z.h12
-rw-r--r--C/7zAlloc.c12
-rw-r--r--C/7zAlloc.h20
-rw-r--r--C/7zArcIn.c98
-rw-r--r--C/7zBuf.c12
-rw-r--r--C/7zBuf.h10
-rw-r--r--C/7zBuf2.c17
-rw-r--r--C/7zCrc.c10
-rw-r--r--C/7zCrcOpt.c50
-rw-r--r--C/7zDec.c54
-rw-r--r--C/7zFile.c26
-rw-r--r--C/7zFile.h8
-rw-r--r--C/7zStream.c111
-rw-r--r--C/7zTypes.h210
-rw-r--r--C/7zVersion.h22
-rw-r--r--C/Aes.c67
-rw-r--r--C/Alloc.c14
-rw-r--r--C/Alloc.h6
-rw-r--r--C/Bcj2.c5
-rw-r--r--C/Bcj2Enc.c4
-rw-r--r--C/Bra.c279
-rw-r--r--C/Bra86.c4
-rw-r--r--C/BraIA64.c82
-rw-r--r--C/BwtSort.c20
-rw-r--r--C/Compiler.h3
-rw-r--r--C/CpuArch.h150
-rw-r--r--C/HuffEnc.c6
-rw-r--r--C/LzFind.c118
-rw-r--r--C/LzFind.h6
-rw-r--r--C/LzFindMt.c30
-rw-r--r--C/LzFindMt.h6
-rw-r--r--C/Lzma2Dec.c160
-rw-r--r--C/Lzma2Dec.h8
-rw-r--r--C/Lzma2Enc.c32
-rw-r--r--C/Lzma2Enc.h6
-rw-r--r--C/LzmaDec.c24
-rw-r--r--C/LzmaDec.h12
-rw-r--r--C/LzmaEnc.c116
-rw-r--r--C/LzmaEnc.h13
-rw-r--r--C/MtCoder.c18
-rw-r--r--C/MtCoder.h14
-rw-r--r--C/Ppmd.h4
-rw-r--r--C/Ppmd7.c28
-rw-r--r--C/Ppmd7.h26
-rw-r--r--C/Ppmd7Dec.c34
-rw-r--r--C/Ppmd7Enc.c4
-rw-r--r--C/Ppmd8.c20
-rw-r--r--C/Ppmd8.h8
-rw-r--r--C/Ppmd8Dec.c6
-rw-r--r--C/Ppmd8Enc.c6
-rw-r--r--C/Sha1.c12
-rw-r--r--C/Sha256.c6
-rw-r--r--C/Util/7z/7zMain.c126
-rw-r--r--C/Util/7zipInstall/7zipInstall.c126
-rw-r--r--C/Util/7zipInstall/7zipInstall.dsp7
-rw-r--r--C/Util/7zipInstall/makefile2
-rw-r--r--C/Util/7zipUninstall/7zipUninstall.c26
-rw-r--r--C/Util/7zipUninstall/7zipUninstall.dsp2
-rw-r--r--C/Util/Lzma/LzmaUtil.c40
-rw-r--r--C/Util/SfxSetup/SfxSetup.c30
-rw-r--r--C/Xz.c8
-rw-r--r--C/Xz.h18
-rw-r--r--C/XzCrc64.c10
-rw-r--r--C/XzCrc64Opt.c18
-rw-r--r--C/XzDec.c57
-rw-r--r--C/XzEnc.c78
-rw-r--r--C/XzIn.c30
-rw-r--r--CPP/7zip/Aes.mak2
-rw-r--r--CPP/7zip/Archive/7z/7zDecode.cpp20
-rw-r--r--CPP/7zip/Archive/7z/7zDecode.h2
-rw-r--r--CPP/7zip/Archive/7z/7zEncode.cpp6
-rw-r--r--CPP/7zip/Archive/7z/7zExtract.cpp19
-rw-r--r--CPP/7zip/Archive/7z/7zHandler.cpp4
-rw-r--r--CPP/7zip/Archive/7z/7zHandler.h1
-rw-r--r--CPP/7zip/Archive/7z/7zHandlerOut.cpp34
-rw-r--r--CPP/7zip/Archive/7z/7zIn.cpp136
-rw-r--r--CPP/7zip/Archive/7z/7zIn.h4
-rw-r--r--CPP/7zip/Archive/7z/7zItem.h47
-rw-r--r--CPP/7zip/Archive/7z/7zOut.cpp93
-rw-r--r--CPP/7zip/Archive/7z/7zOut.h32
-rw-r--r--CPP/7zip/Archive/7z/7zUpdate.cpp76
-rw-r--r--CPP/7zip/Archive/ApmHandler.cpp13
-rw-r--r--CPP/7zip/Archive/ArHandler.cpp4
-rw-r--r--CPP/7zip/Archive/ArjHandler.cpp15
-rw-r--r--CPP/7zip/Archive/Bz2Handler.cpp111
-rw-r--r--CPP/7zip/Archive/Cab/CabHandler.cpp11
-rw-r--r--CPP/7zip/Archive/Chm/ChmHandler.cpp2
-rw-r--r--CPP/7zip/Archive/Chm/ChmIn.cpp107
-rw-r--r--CPP/7zip/Archive/Chm/ChmIn.h6
-rw-r--r--CPP/7zip/Archive/ComHandler.cpp19
-rw-r--r--CPP/7zip/Archive/Common/CoderMixer2.cpp88
-rw-r--r--CPP/7zip/Archive/Common/CoderMixer2.h30
-rw-r--r--CPP/7zip/Archive/Common/HandlerOut.cpp17
-rw-r--r--CPP/7zip/Archive/Common/HandlerOut.h12
-rw-r--r--CPP/7zip/Archive/Common/ItemNameUtils.cpp78
-rw-r--r--CPP/7zip/Archive/Common/ItemNameUtils.h27
-rw-r--r--CPP/7zip/Archive/CpioHandler.cpp4
-rw-r--r--CPP/7zip/Archive/DmgHandler.cpp335
-rw-r--r--CPP/7zip/Archive/ElfHandler.cpp465
-rw-r--r--CPP/7zip/Archive/ExtHandler.cpp254
-rw-r--r--CPP/7zip/Archive/GptHandler.cpp50
-rw-r--r--CPP/7zip/Archive/GzHandler.cpp9
-rw-r--r--CPP/7zip/Archive/HfsHandler.cpp34
-rw-r--r--CPP/7zip/Archive/Iso/IsoHandler.cpp9
-rw-r--r--CPP/7zip/Archive/Iso/IsoHeader.cpp2
-rw-r--r--CPP/7zip/Archive/Iso/IsoHeader.h2
-rw-r--r--CPP/7zip/Archive/Iso/IsoIn.cpp8
-rw-r--r--CPP/7zip/Archive/Iso/IsoIn.h1
-rw-r--r--CPP/7zip/Archive/Iso/IsoItem.h1
-rw-r--r--CPP/7zip/Archive/LzhHandler.cpp162
-rw-r--r--CPP/7zip/Archive/LzmaHandler.cpp78
-rw-r--r--CPP/7zip/Archive/MachoHandler.cpp56
-rw-r--r--CPP/7zip/Archive/MbrHandler.cpp26
-rw-r--r--CPP/7zip/Archive/MslzHandler.cpp2
-rw-r--r--CPP/7zip/Archive/MubHandler.cpp10
-rw-r--r--CPP/7zip/Archive/Nsis/NsisDecode.cpp49
-rw-r--r--CPP/7zip/Archive/Nsis/NsisDecode.h16
-rw-r--r--CPP/7zip/Archive/Nsis/NsisHandler.cpp18
-rw-r--r--CPP/7zip/Archive/Nsis/NsisIn.cpp51
-rw-r--r--CPP/7zip/Archive/Nsis/NsisIn.h19
-rw-r--r--CPP/7zip/Archive/NtfsHandler.cpp27
-rw-r--r--CPP/7zip/Archive/PeHandler.cpp94
-rw-r--r--CPP/7zip/Archive/PpmdHandler.cpp78
-rw-r--r--CPP/7zip/Archive/QcowHandler.cpp6
-rw-r--r--CPP/7zip/Archive/Rar/Rar5Handler.cpp366
-rw-r--r--CPP/7zip/Archive/Rar/Rar5Handler.h38
-rw-r--r--CPP/7zip/Archive/Rar/RarHandler.cpp134
-rw-r--r--CPP/7zip/Archive/Rar/RarVol.h6
-rw-r--r--CPP/7zip/Archive/RpmHandler.cpp111
-rw-r--r--CPP/7zip/Archive/SplitHandler.cpp2
-rw-r--r--CPP/7zip/Archive/SquashfsHandler.cpp86
-rw-r--r--CPP/7zip/Archive/SwfHandler.cpp15
-rw-r--r--CPP/7zip/Archive/Tar/TarHandler.cpp17
-rw-r--r--CPP/7zip/Archive/Tar/TarHandlerOut.cpp4
-rw-r--r--CPP/7zip/Archive/Tar/TarHeader.cpp10
-rw-r--r--CPP/7zip/Archive/Tar/TarHeader.h12
-rw-r--r--CPP/7zip/Archive/Tar/TarIn.cpp14
-rw-r--r--CPP/7zip/Archive/Tar/TarItem.h28
-rw-r--r--CPP/7zip/Archive/Udf/UdfIn.cpp44
-rw-r--r--CPP/7zip/Archive/UefiHandler.cpp550
-rw-r--r--CPP/7zip/Archive/VdiHandler.cpp167
-rw-r--r--CPP/7zip/Archive/VhdHandler.cpp48
-rw-r--r--CPP/7zip/Archive/VmdkHandler.cpp38
-rw-r--r--CPP/7zip/Archive/Wim/WimHandler.cpp73
-rw-r--r--CPP/7zip/Archive/Wim/WimHandlerOut.cpp2
-rw-r--r--CPP/7zip/Archive/Wim/WimIn.cpp2
-rw-r--r--CPP/7zip/Archive/Wim/WimRegister.cpp2
-rw-r--r--CPP/7zip/Archive/XarHandler.cpp18
-rw-r--r--CPP/7zip/Archive/XzHandler.cpp330
-rw-r--r--CPP/7zip/Archive/XzHandler.h54
-rw-r--r--CPP/7zip/Archive/Zip/ZipAddCommon.cpp197
-rw-r--r--CPP/7zip/Archive/Zip/ZipAddCommon.h9
-rw-r--r--CPP/7zip/Archive/Zip/ZipCompressionMode.h20
-rw-r--r--CPP/7zip/Archive/Zip/ZipHandler.cpp555
-rw-r--r--CPP/7zip/Archive/Zip/ZipHandler.h10
-rw-r--r--CPP/7zip/Archive/Zip/ZipHandlerOut.cpp281
-rw-r--r--CPP/7zip/Archive/Zip/ZipHeader.h48
-rw-r--r--CPP/7zip/Archive/Zip/ZipIn.cpp2112
-rw-r--r--CPP/7zip/Archive/Zip/ZipIn.h162
-rw-r--r--CPP/7zip/Archive/Zip/ZipItem.cpp98
-rw-r--r--CPP/7zip/Archive/Zip/ZipItem.h27
-rw-r--r--CPP/7zip/Archive/Zip/ZipOut.cpp211
-rw-r--r--CPP/7zip/Archive/Zip/ZipOut.h39
-rw-r--r--CPP/7zip/Archive/Zip/ZipRegister.cpp11
-rw-r--r--CPP/7zip/Archive/Zip/ZipUpdate.cpp303
-rw-r--r--CPP/7zip/Archive/Zip/ZipUpdate.h13
-rw-r--r--CPP/7zip/Asm.mak2
-rw-r--r--CPP/7zip/Bundles/Alone/Alone.dsp36
-rw-r--r--CPP/7zip/Bundles/Alone/makefile5
-rw-r--r--CPP/7zip/Bundles/Alone7z/Alone.dsp20
-rw-r--r--CPP/7zip/Bundles/Alone7z/makefile3
-rw-r--r--CPP/7zip/Bundles/Fm/FM.dsp47
-rw-r--r--CPP/7zip/Bundles/Format7zF/Arc.mak7
-rw-r--r--CPP/7zip/Bundles/Format7zF/Format7z.dsp204
-rw-r--r--CPP/7zip/Bundles/Format7zF/resource.rc2
-rw-r--r--CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp47
-rw-r--r--CPP/7zip/Bundles/SFXCon/SfxCon.cpp32
-rw-r--r--CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp6
-rw-r--r--CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp6
-rw-r--r--CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp24
-rw-r--r--CPP/7zip/Bundles/SFXWin/SfxWin.cpp2
-rw-r--r--CPP/7zip/Common/CWrappers.cpp113
-rw-r--r--CPP/7zip/Common/CWrappers.h28
-rw-r--r--CPP/7zip/Common/FilePathAutoRename.cpp9
-rw-r--r--CPP/7zip/Common/FilterCoder.h9
-rw-r--r--CPP/7zip/Common/InBuffer.h4
-rw-r--r--CPP/7zip/Common/InOutTempBuffer.cpp2
-rw-r--r--CPP/7zip/Common/MethodProps.cpp28
-rw-r--r--CPP/7zip/Common/MethodProps.h69
-rw-r--r--CPP/7zip/Common/OutBuffer.h7
-rw-r--r--CPP/7zip/Compress/BZip2Crc.cpp4
-rw-r--r--CPP/7zip/Compress/BZip2Decoder.cpp2061
-rw-r--r--CPP/7zip/Compress/BZip2Decoder.h402
-rw-r--r--CPP/7zip/Compress/BZip2Encoder.cpp19
-rw-r--r--CPP/7zip/Compress/Bcj2Coder.cpp12
-rw-r--r--CPP/7zip/Compress/Bcj2Coder.h5
-rw-r--r--CPP/7zip/Compress/BitlDecoder.h18
-rw-r--r--CPP/7zip/Compress/BitmDecoder.h11
-rw-r--r--CPP/7zip/Compress/CopyCoder.cpp5
-rw-r--r--CPP/7zip/Compress/CopyCoder.h5
-rw-r--r--CPP/7zip/Compress/DeflateDecoder.cpp146
-rw-r--r--CPP/7zip/Compress/DeflateDecoder.h55
-rw-r--r--CPP/7zip/Compress/DeflateEncoder.cpp64
-rw-r--r--CPP/7zip/Compress/DeflateEncoder.h7
-rw-r--r--CPP/7zip/Compress/HuffmanDecoder.h120
-rw-r--r--CPP/7zip/Compress/ImplodeDecoder.cpp326
-rw-r--r--CPP/7zip/Compress/ImplodeDecoder.h61
-rw-r--r--CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp86
-rw-r--r--CPP/7zip/Compress/ImplodeHuffmanDecoder.h28
-rw-r--r--CPP/7zip/Compress/Lzma2Decoder.cpp254
-rw-r--r--CPP/7zip/Compress/Lzma2Decoder.h30
-rw-r--r--CPP/7zip/Compress/Lzma2Encoder.cpp12
-rw-r--r--CPP/7zip/Compress/LzmaDecoder.cpp292
-rw-r--r--CPP/7zip/Compress/LzmaDecoder.h44
-rw-r--r--CPP/7zip/Compress/LzmaEncoder.cpp13
-rw-r--r--CPP/7zip/Compress/LzmaEncoder.h2
-rw-r--r--CPP/7zip/Compress/LzmsDecoder.cpp6
-rw-r--r--CPP/7zip/Compress/LzxDecoder.cpp6
-rw-r--r--CPP/7zip/Compress/Mtf8.h43
-rw-r--r--CPP/7zip/Compress/PpmdDecoder.cpp9
-rw-r--r--CPP/7zip/Compress/PpmdDecoder.h26
-rw-r--r--CPP/7zip/Compress/PpmdEncoder.cpp2
-rw-r--r--CPP/7zip/Compress/PpmdZip.cpp48
-rw-r--r--CPP/7zip/Compress/PpmdZip.h12
-rw-r--r--CPP/7zip/Compress/QuantumDecoder.cpp10
-rw-r--r--CPP/7zip/Compress/Rar1Decoder.cpp4
-rw-r--r--CPP/7zip/Compress/Rar2Decoder.cpp60
-rw-r--r--CPP/7zip/Compress/Rar3Decoder.cpp57
-rw-r--r--CPP/7zip/Compress/Rar3Decoder.h5
-rw-r--r--CPP/7zip/Compress/Rar3Vm.cpp66
-rw-r--r--CPP/7zip/Compress/Rar5Decoder.cpp4
-rw-r--r--CPP/7zip/Compress/Rar5Decoder.h32
-rw-r--r--CPP/7zip/Compress/ShrinkDecoder.cpp127
-rw-r--r--CPP/7zip/Compress/ShrinkDecoder.h17
-rw-r--r--CPP/7zip/Compress/XpressDecoder.cpp4
-rw-r--r--CPP/7zip/Compress/XzDecoder.cpp260
-rw-r--r--CPP/7zip/Compress/XzDecoder.h95
-rw-r--r--CPP/7zip/Compress/XzEncoder.cpp190
-rw-r--r--CPP/7zip/Compress/XzEncoder.h44
-rw-r--r--CPP/7zip/Compress/ZDecoder.cpp4
-rw-r--r--CPP/7zip/Crc.mak2
-rw-r--r--CPP/7zip/Crc64.mak2
-rw-r--r--CPP/7zip/Crypto/MyAes.h2
-rw-r--r--CPP/7zip/Crypto/Rar20Crypto.cpp2
-rw-r--r--CPP/7zip/Crypto/Rar20Crypto.h6
-rw-r--r--CPP/7zip/Crypto/WzAes.h2
-rw-r--r--CPP/7zip/Crypto/ZipCrypto.h2
-rw-r--r--CPP/7zip/Crypto/ZipStrong.cpp29
-rw-r--r--CPP/7zip/Crypto/ZipStrong.h8
-rw-r--r--CPP/7zip/Guid.txt1
-rw-r--r--CPP/7zip/ICoder.h5
-rw-r--r--CPP/7zip/UI/Agent/Agent.cpp55
-rw-r--r--CPP/7zip/UI/Agent/Agent.h22
-rw-r--r--CPP/7zip/UI/Agent/AgentOut.cpp49
-rw-r--r--CPP/7zip/UI/Agent/AgentProxy.cpp4
-rw-r--r--CPP/7zip/UI/Agent/ArchiveFolderOut.cpp39
-rw-r--r--CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp12
-rw-r--r--CPP/7zip/UI/Client7z/Client7z.cpp161
-rw-r--r--CPP/7zip/UI/Client7z/Client7z.dsp2
-rw-r--r--CPP/7zip/UI/Client7z/resource.rc2
-rw-r--r--CPP/7zip/UI/Common/ArchiveCommandLine.cpp82
-rw-r--r--CPP/7zip/UI/Common/ArchiveCommandLine.h1
-rw-r--r--CPP/7zip/UI/Common/ArchiveExtractCallback.cpp105
-rw-r--r--CPP/7zip/UI/Common/ArchiveExtractCallback.h10
-rw-r--r--CPP/7zip/UI/Common/ArchiveName.cpp2
-rw-r--r--CPP/7zip/UI/Common/Bench.cpp396
-rw-r--r--CPP/7zip/UI/Common/Bench.h17
-rw-r--r--CPP/7zip/UI/Common/CompressCall.cpp79
-rw-r--r--CPP/7zip/UI/Common/CompressCall2.cpp13
-rw-r--r--CPP/7zip/UI/Common/DirItem.h11
-rw-r--r--CPP/7zip/UI/Common/EnumDirItems.cpp11
-rw-r--r--CPP/7zip/UI/Common/Extract.cpp6
-rw-r--r--CPP/7zip/UI/Common/ExtractingFilePath.cpp64
-rw-r--r--CPP/7zip/UI/Common/HashCalc.cpp8
-rw-r--r--CPP/7zip/UI/Common/LoadCodecs.cpp26
-rw-r--r--CPP/7zip/UI/Common/OpenArchive.cpp40
-rw-r--r--CPP/7zip/UI/Common/PropIDUtils.cpp36
-rw-r--r--CPP/7zip/UI/Common/PropIDUtils.h4
-rw-r--r--CPP/7zip/UI/Common/Update.cpp158
-rw-r--r--CPP/7zip/UI/Common/UpdateCallback.cpp15
-rw-r--r--CPP/7zip/UI/Common/UpdateCallback.h16
-rw-r--r--CPP/7zip/UI/Common/UpdatePair.cpp9
-rw-r--r--CPP/7zip/UI/Common/UpdateProduce.cpp2
-rw-r--r--CPP/7zip/UI/Common/ZipRegistry.cpp82
-rw-r--r--CPP/7zip/UI/Console/Console.dsp2
-rw-r--r--CPP/7zip/UI/Console/ExtractCallbackConsole.cpp70
-rw-r--r--CPP/7zip/UI/Console/HashCon.cpp6
-rw-r--r--CPP/7zip/UI/Console/List.cpp28
-rw-r--r--CPP/7zip/UI/Console/Main.cpp92
-rw-r--r--CPP/7zip/UI/Console/MainAr.cpp12
-rw-r--r--CPP/7zip/UI/Console/OpenCallbackConsole.cpp12
-rw-r--r--CPP/7zip/UI/Console/OpenCallbackConsole.h7
-rw-r--r--CPP/7zip/UI/Console/UpdateCallbackConsole.cpp47
-rw-r--r--CPP/7zip/UI/Console/UserInputUtils.cpp44
-rw-r--r--CPP/7zip/UI/Console/UserInputUtils.h7
-rw-r--r--CPP/7zip/UI/Console/resource.rc2
-rw-r--r--CPP/7zip/UI/Explorer/ContextMenu.cpp105
-rw-r--r--CPP/7zip/UI/Explorer/ContextMenu.h2
-rw-r--r--CPP/7zip/UI/Explorer/DllExportsExplorer.cpp24
-rw-r--r--CPP/7zip/UI/Explorer/RegistryContextMenu.cpp54
-rw-r--r--CPP/7zip/UI/Far/ExtractEngine.cpp15
-rw-r--r--CPP/7zip/UI/Far/Far.cpp21
-rw-r--r--CPP/7zip/UI/Far/FarUtils.cpp63
-rw-r--r--CPP/7zip/UI/Far/FarUtils.h24
-rw-r--r--CPP/7zip/UI/Far/OverwriteDialogFar.cpp59
-rw-r--r--CPP/7zip/UI/Far/Plugin.cpp42
-rw-r--r--CPP/7zip/UI/Far/PluginDelete.cpp2
-rw-r--r--CPP/7zip/UI/Far/PluginRead.cpp12
-rw-r--r--CPP/7zip/UI/Far/PluginWrite.cpp35
-rw-r--r--CPP/7zip/UI/Far/ProgressBox.cpp13
-rw-r--r--CPP/7zip/UI/Far/ProgressBox.h2
-rw-r--r--CPP/7zip/UI/Far/UpdateCallbackFar.cpp33
-rw-r--r--CPP/7zip/UI/Far/UpdateCallbackFar.h20
-rw-r--r--CPP/7zip/UI/FileManager/AboutDialog.cpp15
-rw-r--r--CPP/7zip/UI/FileManager/AltStreamsFolder.cpp10
-rw-r--r--CPP/7zip/UI/FileManager/App.cpp40
-rw-r--r--CPP/7zip/UI/FileManager/App.h18
-rw-r--r--CPP/7zip/UI/FileManager/BrowseDialog.cpp37
-rw-r--r--CPP/7zip/UI/FileManager/EditPage.cpp33
-rw-r--r--CPP/7zip/UI/FileManager/ExtractCallback.cpp26
-rw-r--r--CPP/7zip/UI/FileManager/FM.cpp37
-rw-r--r--CPP/7zip/UI/FileManager/FM.dsp2
-rw-r--r--CPP/7zip/UI/FileManager/FSDrives.cpp21
-rw-r--r--CPP/7zip/UI/FileManager/FSFolder.cpp102
-rw-r--r--CPP/7zip/UI/FileManager/FSFolder.h4
-rw-r--r--CPP/7zip/UI/FileManager/FSFolderCopy.cpp7
-rw-r--r--CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp4
-rw-r--r--CPP/7zip/UI/FileManager/FoldersPage.cpp6
-rw-r--r--CPP/7zip/UI/FileManager/HelpUtils.cpp11
-rw-r--r--CPP/7zip/UI/FileManager/HelpUtils.h2
-rw-r--r--CPP/7zip/UI/FileManager/LangPage.cpp18
-rw-r--r--CPP/7zip/UI/FileManager/LangUtils.cpp27
-rw-r--r--CPP/7zip/UI/FileManager/LinkDialog.cpp6
-rw-r--r--CPP/7zip/UI/FileManager/MenuPage.cpp27
-rw-r--r--CPP/7zip/UI/FileManager/MyLoadMenu.cpp136
-rw-r--r--CPP/7zip/UI/FileManager/NetFolder.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/OpenCallback.cpp6
-rw-r--r--CPP/7zip/UI/FileManager/OverwriteDialog.cpp15
-rw-r--r--CPP/7zip/UI/FileManager/Panel.cpp19
-rw-r--r--CPP/7zip/UI/FileManager/Panel.h17
-rw-r--r--CPP/7zip/UI/FileManager/PanelCopy.cpp15
-rw-r--r--CPP/7zip/UI/FileManager/PanelCrc.cpp11
-rw-r--r--CPP/7zip/UI/FileManager/PanelDrag.cpp10
-rw-r--r--CPP/7zip/UI/FileManager/PanelFolderChange.cpp62
-rw-r--r--CPP/7zip/UI/FileManager/PanelItemOpen.cpp170
-rw-r--r--CPP/7zip/UI/FileManager/PanelItems.cpp50
-rw-r--r--CPP/7zip/UI/FileManager/PanelKey.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/PanelListNotify.cpp50
-rw-r--r--CPP/7zip/UI/FileManager/PanelMenu.cpp80
-rw-r--r--CPP/7zip/UI/FileManager/PanelOperations.cpp6
-rw-r--r--CPP/7zip/UI/FileManager/PanelSelect.cpp4
-rw-r--r--CPP/7zip/UI/FileManager/PanelSort.cpp8
-rw-r--r--CPP/7zip/UI/FileManager/PanelSplitFile.cpp18
-rw-r--r--CPP/7zip/UI/FileManager/ProgressDialog.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/ProgressDialog2.cpp26
-rw-r--r--CPP/7zip/UI/FileManager/RegistryAssociations.cpp31
-rw-r--r--CPP/7zip/UI/FileManager/RegistryPlugins.cpp18
-rw-r--r--CPP/7zip/UI/FileManager/RegistryUtils.cpp50
-rw-r--r--CPP/7zip/UI/FileManager/RootFolder.cpp10
-rw-r--r--CPP/7zip/UI/FileManager/SettingsPage.cpp4
-rw-r--r--CPP/7zip/UI/FileManager/SplitDialog.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/SplitUtils.cpp25
-rw-r--r--CPP/7zip/UI/FileManager/StringUtils.cpp6
-rw-r--r--CPP/7zip/UI/FileManager/SystemPage.cpp14
-rw-r--r--CPP/7zip/UI/FileManager/TextPairs.cpp8
-rw-r--r--CPP/7zip/UI/FileManager/ViewSettings.cpp27
-rw-r--r--CPP/7zip/UI/FileManager/resource.h2
-rw-r--r--CPP/7zip/UI/FileManager/resource.rc9
-rw-r--r--CPP/7zip/UI/GUI/BenchmarkDialog.cpp245
-rw-r--r--CPP/7zip/UI/GUI/BenchmarkDialog.h18
-rw-r--r--CPP/7zip/UI/GUI/BenchmarkDialog.rc29
-rw-r--r--CPP/7zip/UI/GUI/BenchmarkDialogRes.h6
-rw-r--r--CPP/7zip/UI/GUI/CompressDialog.cpp109
-rw-r--r--CPP/7zip/UI/GUI/ExtractDialog.cpp6
-rw-r--r--CPP/7zip/UI/GUI/ExtractGUI.cpp23
-rw-r--r--CPP/7zip/UI/GUI/GUI.cpp35
-rw-r--r--CPP/7zip/UI/GUI/GUI.dsp10
-rw-r--r--CPP/7zip/UI/GUI/HashGUI.cpp38
-rw-r--r--CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp4
-rw-r--r--CPP/7zip/UI/GUI/UpdateGUI.cpp62
-rw-r--r--CPP/Build.mak27
-rw-r--r--CPP/Common/ComTry.h6
-rw-r--r--CPP/Common/CommandLineParser.cpp54
-rw-r--r--CPP/Common/CommandLineParser.h10
-rw-r--r--CPP/Common/Common.h32
-rw-r--r--CPP/Common/DynLimBuf.h1
-rw-r--r--CPP/Common/IntToString.cpp57
-rw-r--r--CPP/Common/IntToString.h4
-rw-r--r--CPP/Common/Lang.cpp14
-rw-r--r--CPP/Common/Lang.h2
-rw-r--r--CPP/Common/ListFileUtils.cpp6
-rw-r--r--CPP/Common/MyBuffer.h25
-rw-r--r--CPP/Common/MyBuffer2.h45
-rw-r--r--CPP/Common/MyCom.h21
-rw-r--r--CPP/Common/MyString.cpp259
-rw-r--r--CPP/Common/MyString.h179
-rw-r--r--CPP/Common/MyVector.h30
-rw-r--r--CPP/Common/MyWindows.h10
-rw-r--r--CPP/Common/MyXml.cpp10
-rw-r--r--CPP/Common/MyXml.h10
-rw-r--r--CPP/Common/NewHandler.cpp2
-rw-r--r--CPP/Common/NewHandler.h51
-rw-r--r--CPP/Common/StdInStream.cpp65
-rw-r--r--CPP/Common/StdInStream.h13
-rw-r--r--CPP/Common/StdOutStream.cpp6
-rw-r--r--CPP/Common/StringConvert.cpp6
-rw-r--r--CPP/Common/StringConvert.h123
-rw-r--r--CPP/Common/TextConfig.cpp8
-rw-r--r--CPP/Common/TextConfig.h4
-rw-r--r--CPP/Common/Wildcard.cpp28
-rw-r--r--CPP/Common/Wildcard.h2
-rw-r--r--CPP/Common/XzCrc64Init.cpp7
-rw-r--r--CPP/Windows/Clipboard.cpp2
-rw-r--r--CPP/Windows/Control/PropertyPage.cpp2
-rw-r--r--CPP/Windows/DLL.cpp7
-rw-r--r--CPP/Windows/ErrorMsg.cpp4
-rw-r--r--CPP/Windows/FileDir.cpp26
-rw-r--r--CPP/Windows/FileFind.cpp16
-rw-r--r--CPP/Windows/FileFind.h2
-rw-r--r--CPP/Windows/FileLink.cpp8
-rw-r--r--CPP/Windows/FileName.cpp24
-rw-r--r--CPP/Windows/FileName.h6
-rw-r--r--CPP/Windows/Net.cpp4
-rw-r--r--CPP/Windows/ProcessUtils.cpp4
-rw-r--r--CPP/Windows/PropVariant.cpp2
-rw-r--r--CPP/Windows/PropVariant.h2
-rw-r--r--CPP/Windows/PropVariantConv.cpp79
-rw-r--r--CPP/Windows/PropVariantConv.h11
-rw-r--r--CPP/Windows/PropVariantUtils.cpp84
-rw-r--r--CPP/Windows/PropVariantUtils.h1
-rw-r--r--CPP/Windows/Shell.cpp4
-rw-r--r--CPP/Windows/System.cpp30
-rw-r--r--CPP/Windows/System.h23
-rw-r--r--CPP/Windows/TimeUtils.cpp16
-rw-r--r--CPP/Windows/TimeUtils.h8
-rw-r--r--DOC/7zip.inf4
-rw-r--r--DOC/7zip.nsi6
-rw-r--r--DOC/7zip.wxs4
-rw-r--r--DOC/License.txt2
-rw-r--r--DOC/Methods.txt12
-rw-r--r--DOC/readme.txt6
-rw-r--r--DOC/src-history.txt9
442 files changed, 15284 insertions, 8330 deletions
diff --git a/C/7z.h b/C/7z.h
index 47681519..6c7886e3 100644
--- a/C/7z.h
+++ b/C/7z.h
@@ -1,5 +1,5 @@
/* 7z.h -- 7z interface
-2015-11-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_H
#define __7Z_H
@@ -98,7 +98,7 @@ UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize,
- ISzAlloc *allocMain);
+ ISzAllocPtr allocMain);
typedef struct
{
@@ -131,7 +131,7 @@ typedef struct
#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
void SzArEx_Init(CSzArEx *p);
-void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
+void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc);
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
@@ -179,8 +179,8 @@ SRes SzArEx_Extract(
size_t *outBufferSize, /* buffer size for output buffer */
size_t *offset, /* offset of stream for required file in *outBuffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp);
+ ISzAllocPtr allocMain,
+ ISzAllocPtr allocTemp);
/*
@@ -195,7 +195,7 @@ SZ_ERROR_FAIL
*/
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
- ISzAlloc *allocMain, ISzAlloc *allocTemp);
+ ISzAllocPtr allocMain, ISzAllocPtr allocTemp);
EXTERN_C_END
diff --git a/C/7zAlloc.c b/C/7zAlloc.c
index 3e848c98..c924a529 100644
--- a/C/7zAlloc.c
+++ b/C/7zAlloc.c
@@ -1,8 +1,10 @@
/* 7zAlloc.c -- Allocation functions
-2015-11-09 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
+#include <stdlib.h>
+
#include "7zAlloc.h"
/* #define _SZ_ALLOC_DEBUG */
@@ -20,7 +22,7 @@ int g_allocCountTemp = 0;
#endif
-void *SzAlloc(void *p, size_t size)
+void *SzAlloc(ISzAllocPtr p, size_t size)
{
UNUSED_VAR(p);
if (size == 0)
@@ -32,7 +34,7 @@ void *SzAlloc(void *p, size_t size)
return malloc(size);
}
-void SzFree(void *p, void *address)
+void SzFree(ISzAllocPtr p, void *address)
{
UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG
@@ -45,7 +47,7 @@ void SzFree(void *p, void *address)
free(address);
}
-void *SzAllocTemp(void *p, size_t size)
+void *SzAllocTemp(ISzAllocPtr p, size_t size)
{
UNUSED_VAR(p);
if (size == 0)
@@ -60,7 +62,7 @@ void *SzAllocTemp(void *p, size_t size)
return malloc(size);
}
-void SzFreeTemp(void *p, void *address)
+void SzFreeTemp(ISzAllocPtr p, void *address)
{
UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG
diff --git a/C/7zAlloc.h b/C/7zAlloc.h
index 2fd5bdbc..44778f9b 100644
--- a/C/7zAlloc.h
+++ b/C/7zAlloc.h
@@ -1,23 +1,19 @@
/* 7zAlloc.h -- Allocation functions
-2013-03-25 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H
-#include <stdlib.h>
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
-void *SzAlloc(void *p, size_t size);
-void SzFree(void *p, void *address);
+void *SzAlloc(ISzAllocPtr p, size_t size);
+void SzFree(ISzAllocPtr p, void *address);
-void *SzAllocTemp(void *p, size_t size);
-void SzFreeTemp(void *p, void *address);
+void *SzAllocTemp(ISzAllocPtr p, size_t size);
+void SzFreeTemp(ISzAllocPtr p, void *address);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/C/7zArcIn.c b/C/7zArcIn.c
index 2beed3d5..e1b03d87 100644
--- a/C/7zArcIn.c
+++ b/C/7zArcIn.c
@@ -1,5 +1,5 @@
/* 7zArcIn.c -- 7z Input functions
-2016-05-16 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -11,7 +11,7 @@
#include "CpuArch.h"
#define MY_ALLOC(T, p, size, alloc) { \
- if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }
+ if ((p = (T *)ISzAlloc_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) }
@@ -60,7 +60,7 @@ 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)
+static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc)
{
if (num == 0)
{
@@ -75,18 +75,18 @@ static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
return SZ_OK;
}
-void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc)
+void SzBitUi32s_Free(CSzBitUi32s *p, ISzAllocPtr alloc)
{
- IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
- IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
+ ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL;
+ ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL;
}
#define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
-void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc)
+void SzBitUi64s_Free(CSzBitUi64s *p, ISzAllocPtr alloc)
{
- IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
- IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
+ ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL;
+ ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL;
}
@@ -107,18 +107,18 @@ static void SzAr_Init(CSzAr *p)
p->CodersData = NULL;
}
-static void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
+static void SzAr_Free(CSzAr *p, ISzAllocPtr alloc)
{
- IAlloc_Free(alloc, p->PackPositions);
+ ISzAlloc_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);
+ ISzAlloc_Free(alloc, p->FoCodersOffsets);
+ ISzAlloc_Free(alloc, p->FoStartPackStreamIndex);
+ ISzAlloc_Free(alloc, p->FoToCoderUnpackSizes);
+ ISzAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);
+ ISzAlloc_Free(alloc, p->CoderUnpackSizes);
- IAlloc_Free(alloc, p->CodersData);
+ ISzAlloc_Free(alloc, p->CodersData);
SzAr_Init(p);
}
@@ -147,16 +147,16 @@ void SzArEx_Init(CSzArEx *p)
SzBitUi64s_Init(&p->CTime);
}
-void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
+void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc)
{
- IAlloc_Free(alloc, p->UnpackPositions);
- IAlloc_Free(alloc, p->IsDirs);
+ ISzAlloc_Free(alloc, p->UnpackPositions);
+ ISzAlloc_Free(alloc, p->IsDirs);
- IAlloc_Free(alloc, p->FolderToFile);
- IAlloc_Free(alloc, p->FileToFolder);
+ ISzAlloc_Free(alloc, p->FolderToFile);
+ ISzAlloc_Free(alloc, p->FileToFolder);
- IAlloc_Free(alloc, p->FileNameOffsets);
- IAlloc_Free(alloc, p->FileNames);
+ ISzAlloc_Free(alloc, p->FileNameOffsets);
+ ISzAlloc_Free(alloc, p->FileNames);
SzBitUi32s_Free(&p->CRCs, alloc);
SzBitUi32s_Free(&p->Attribs, alloc);
@@ -305,7 +305,7 @@ static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems)
return sum;
}
-static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc)
+static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAllocPtr alloc)
{
Byte allAreDefined;
Byte *v2;
@@ -328,12 +328,12 @@ static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, I
{
unsigned numBits = (unsigned)numItems & 7;
if (numBits != 0)
- v2[numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits));
+ v2[(size_t)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)
+static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
{
UInt32 i;
CSzData sd;
@@ -354,7 +354,7 @@ static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *c
return SZ_OK;
}
-static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)
+static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
{
SzBitUi32s_Free(crcs, alloc);
RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc));
@@ -380,7 +380,7 @@ static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)
return SZ_OK;
}
-static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAlloc *alloc)
+static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc)
{
RINOK(SzReadNumber32(sd, &p->NumPackStreams));
@@ -635,7 +635,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
CSzData *sd2,
UInt32 numFoldersMax,
const CBuf *tempBufs, UInt32 numTempBufs,
- ISzAlloc *alloc)
+ ISzAllocPtr alloc)
{
CSzData sd;
@@ -934,7 +934,7 @@ static SRes SzReadStreamsInfo(CSzAr *p,
UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,
UInt64 *dataOffset,
CSubStreamInfo *ssi,
- ISzAlloc *alloc)
+ ISzAllocPtr alloc)
{
UInt64 type;
@@ -976,7 +976,7 @@ static SRes SzReadAndDecodePackedStreams(
UInt32 numFoldersMax,
UInt64 baseOffset,
CSzAr *p,
- ISzAlloc *allocTemp)
+ ISzAllocPtr allocTemp)
{
UInt64 dataStartPos;
UInt32 fo;
@@ -1043,7 +1043,7 @@ static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size
static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
CSzData *sd2,
const CBuf *tempBufs, UInt32 numTempBufs,
- ISzAlloc *alloc)
+ ISzAllocPtr alloc)
{
CSzData sd;
UInt32 i;
@@ -1096,8 +1096,8 @@ static SRes SzReadHeader2(
CSzData *sd,
ILookInStream *inStream,
CBuf *tempBufs, UInt32 *numTempBufs,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp
+ ISzAllocPtr allocMain,
+ ISzAllocPtr allocTemp
)
{
CSubStreamInfo ssi;
@@ -1472,8 +1472,8 @@ static SRes SzReadHeader(
CSzArEx *p,
CSzData *sd,
ILookInStream *inStream,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
+ ISzAllocPtr allocMain,
+ ISzAllocPtr allocTemp)
{
UInt32 i;
UInt32 numTempBufs = 0;
@@ -1501,8 +1501,8 @@ static SRes SzReadHeader(
static SRes SzArEx_Open2(
CSzArEx *p,
ILookInStream *inStream,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
+ ISzAllocPtr allocMain,
+ ISzAllocPtr allocTemp)
{
Byte header[k7zStartHeaderSize];
Int64 startArcPos;
@@ -1513,7 +1513,7 @@ static SRes SzArEx_Open2(
SRes res;
startArcPos = 0;
- RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
+ RINOK(ILookInStream_Seek(inStream, &startArcPos, SZ_SEEK_CUR));
RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
@@ -1542,7 +1542,7 @@ static SRes SzArEx_Open2(
{
Int64 pos = 0;
- RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
+ RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END));
if ((UInt64)pos < startArcPos + nextHeaderOffset ||
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
@@ -1623,7 +1623,7 @@ static SRes SzArEx_Open2(
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
- ISzAlloc *allocMain, ISzAlloc *allocTemp)
+ ISzAllocPtr allocMain, ISzAllocPtr allocTemp)
{
SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
if (res != SZ_OK)
@@ -1641,8 +1641,8 @@ SRes SzArEx_Extract(
size_t *outBufferSize,
size_t *offset,
size_t *outSizeProcessed,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
+ ISzAllocPtr allocMain,
+ ISzAllocPtr allocTemp)
{
UInt32 folderIndex = p->FileToFolder[fileIndex];
SRes res = SZ_OK;
@@ -1652,7 +1652,7 @@ SRes SzArEx_Extract(
if (folderIndex == (UInt32)-1)
{
- IAlloc_Free(allocMain, *tempBuf);
+ ISzAlloc_Free(allocMain, *tempBuf);
*blockIndex = folderIndex;
*tempBuf = NULL;
*outBufferSize = 0;
@@ -1664,7 +1664,7 @@ SRes SzArEx_Extract(
UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
/*
UInt64 unpackSizeSpec =
- p->UnpackPositions[p->FolderToFile[folderIndex + 1]] -
+ p->UnpackPositions[p->FolderToFile[(size_t)folderIndex + 1]] -
p->UnpackPositions[p->FolderToFile[folderIndex]];
*/
size_t unpackSize = (size_t)unpackSizeSpec;
@@ -1672,7 +1672,7 @@ SRes SzArEx_Extract(
if (unpackSize != unpackSizeSpec)
return SZ_ERROR_MEM;
*blockIndex = folderIndex;
- IAlloc_Free(allocMain, *tempBuf);
+ ISzAlloc_Free(allocMain, *tempBuf);
*tempBuf = NULL;
if (res == SZ_OK)
@@ -1680,7 +1680,7 @@ SRes SzArEx_Extract(
*outBufferSize = unpackSize;
if (unpackSize != 0)
{
- *tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
+ *tempBuf = (Byte *)ISzAlloc_Alloc(allocMain, unpackSize);
if (*tempBuf == NULL)
res = SZ_ERROR_MEM;
}
@@ -1697,7 +1697,7 @@ SRes SzArEx_Extract(
{
UInt64 unpackPos = p->UnpackPositions[fileIndex];
*offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]);
- *outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos);
+ *outSizeProcessed = (size_t)(p->UnpackPositions[(size_t)fileIndex + 1] - unpackPos);
if (*offset + *outSizeProcessed > *outBufferSize)
return SZ_ERROR_FAIL;
if (SzBitWithVals_Check(&p->CRCs, fileIndex))
diff --git a/C/7zBuf.c b/C/7zBuf.c
index 089a5c4f..8865c32a 100644
--- a/C/7zBuf.c
+++ b/C/7zBuf.c
@@ -1,5 +1,5 @@
/* 7zBuf.c -- Byte Buffer
-2013-01-21 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -11,7 +11,7 @@ void Buf_Init(CBuf *p)
p->size = 0;
}
-int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
+int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc)
{
p->size = 0;
if (size == 0)
@@ -19,8 +19,8 @@ int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
p->data = 0;
return 1;
}
- p->data = (Byte *)alloc->Alloc(alloc, size);
- if (p->data != 0)
+ p->data = (Byte *)ISzAlloc_Alloc(alloc, size);
+ if (p->data)
{
p->size = size;
return 1;
@@ -28,9 +28,9 @@ int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
return 0;
}
-void Buf_Free(CBuf *p, ISzAlloc *alloc)
+void Buf_Free(CBuf *p, ISzAllocPtr alloc)
{
- alloc->Free(alloc, p->data);
+ ISzAlloc_Free(alloc, p->data);
p->data = 0;
p->size = 0;
}
diff --git a/C/7zBuf.h b/C/7zBuf.h
index 65f1d7a7..81d1b5b6 100644
--- a/C/7zBuf.h
+++ b/C/7zBuf.h
@@ -1,5 +1,5 @@
/* 7zBuf.h -- Byte Buffer
-2013-01-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_BUF_H
#define __7Z_BUF_H
@@ -15,8 +15,8 @@ typedef struct
} CBuf;
void Buf_Init(CBuf *p);
-int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
-void Buf_Free(CBuf *p, ISzAlloc *alloc);
+int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc);
+void Buf_Free(CBuf *p, ISzAllocPtr alloc);
typedef struct
{
@@ -27,8 +27,8 @@ typedef struct
void DynBuf_Construct(CDynBuf *p);
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);
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc);
+void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc);
EXTERN_C_END
diff --git a/C/7zBuf2.c b/C/7zBuf2.c
index 430f76bf..20834741 100644
--- a/C/7zBuf2.c
+++ b/C/7zBuf2.c
@@ -1,5 +1,5 @@
/* 7zBuf2.c -- Byte Buffer
-2014-08-22 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -19,19 +19,20 @@ void DynBuf_SeekToBeg(CDynBuf *p)
p->pos = 0;
}
-int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc)
{
if (size > p->size - p->pos)
{
size_t newSize = p->pos + size;
Byte *data;
newSize += newSize / 4;
- data = (Byte *)alloc->Alloc(alloc, newSize);
- if (data == 0)
+ data = (Byte *)ISzAlloc_Alloc(alloc, newSize);
+ if (!data)
return 0;
p->size = newSize;
- memcpy(data, p->data, p->pos);
- alloc->Free(alloc, p->data);
+ if (p->pos != 0)
+ memcpy(data, p->data, p->pos);
+ ISzAlloc_Free(alloc, p->data);
p->data = data;
}
if (size != 0)
@@ -42,9 +43,9 @@ int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)
return 1;
}
-void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc)
+void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc)
{
- alloc->Free(alloc, p->data);
+ ISzAlloc_Free(alloc, p->data);
p->data = 0;
p->size = 0;
p->pos = 0;
diff --git a/C/7zCrc.c b/C/7zCrc.c
index dc6d6abd..0ae5074b 100644
--- a/C/7zCrc.c
+++ b/C/7zCrc.c
@@ -1,5 +1,5 @@
/* 7zCrc.c -- CRC32 init
-2015-03-10 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -61,12 +61,12 @@ void MY_FAST_CALL CrcGenerateTable()
UInt32 r = i;
unsigned j;
for (j = 0; j < 8; j++)
- r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+ r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
g_CrcTable[i] = r;
}
- for (; i < 256 * CRC_NUM_TABLES; i++)
+ for (i = 256; i < 256 * CRC_NUM_TABLES; i++)
{
- UInt32 r = g_CrcTable[i - 256];
+ UInt32 r = g_CrcTable[(size_t)i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
@@ -111,7 +111,7 @@ void MY_FAST_CALL CrcGenerateTable()
{
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
{
- UInt32 x = g_CrcTable[i - 256];
+ UInt32 x = g_CrcTable[(size_t)i - 256];
g_CrcTable[i] = CRC_UINT32_SWAP(x);
}
g_CrcUpdateT4 = CrcUpdateT1_BeT4;
diff --git a/C/7zCrcOpt.c b/C/7zCrcOpt.c
index d1e1cd7b..73beba29 100644
--- a/C/7zCrcOpt.c
+++ b/C/7zCrcOpt.c
@@ -1,5 +1,5 @@
/* 7zCrcOpt.c -- CRC32 calculation
-2015-03-01 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -18,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);
@@ -38,16 +38,16 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U
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))];
+ (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))];
+ (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);
@@ -74,10 +74,10 @@ UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, co
{
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))];
}
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p);
@@ -96,16 +96,16 @@ UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, co
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))];
+ (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))];
+ (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);
diff --git a/C/7zDec.c b/C/7zDec.c
index c45d6bf8..1ae87dfa 100644
--- a/C/7zDec.c
+++ b/C/7zDec.c
@@ -1,5 +1,5 @@
/* 7zDec.c -- Decoding from 7z folder
-2015-11-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -39,28 +39,28 @@
typedef struct
{
- IByteIn p;
+ IByteIn vt;
const Byte *cur;
const Byte *end;
const Byte *begin;
UInt64 processed;
Bool extra;
SRes res;
- ILookInStream *inStream;
+ const ILookInStream *inStream;
} CByteInToLook;
-static Byte ReadByte(void *pp)
+static Byte ReadByte(const IByteIn *pp)
{
- CByteInToLook *p = (CByteInToLook *)pp;
+ CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt);
if (p->cur != p->end)
return *p->cur++;
if (p->res == SZ_OK)
{
size_t size = p->cur - p->begin;
p->processed += size;
- p->res = p->inStream->Skip(p->inStream, size);
+ p->res = ILookInStream_Skip(p->inStream, size);
size = (1 << 25);
- p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
+ p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size);
p->cur = p->begin;
p->end = p->begin + size;
if (size != 0)
@@ -70,14 +70,14 @@ static Byte ReadByte(void *pp)
return 0;
}
-static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
- Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
+static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream,
+ Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{
CPpmd7 ppmd;
CByteInToLook s;
SRes res = SZ_OK;
- s.p.Read = ReadByte;
+ s.vt.Read = ReadByte;
s.inStream = inStream;
s.begin = s.end = s.cur = NULL;
s.extra = False;
@@ -103,7 +103,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
{
CPpmd7z_RangeDec rc;
Ppmd7z_RangeDec_CreateVTable(&rc);
- rc.Stream = &s.p;
+ rc.Stream = &s.vt;
if (!Ppmd7z_RangeDec_Init(&rc))
res = SZ_ERROR_DATA;
else if (s.extra)
@@ -113,7 +113,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
SizeT i;
for (i = 0; i < outSize; i++)
{
- int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
+ int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.vt);
if (s.extra || sym < 0)
break;
outBuffer[i] = (Byte)sym;
@@ -132,7 +132,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
- Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
+ Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{
CLzmaDec state;
SRes res = SZ_OK;
@@ -149,7 +149,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
- res = inStream->Look(inStream, &inBuf, &lookahead);
+ res = ILookInStream_Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK)
break;
@@ -178,7 +178,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
break;
}
- res = inStream->Skip((void *)inStream, inProcessed);
+ res = ILookInStream_Skip(inStream, inProcessed);
if (res != SZ_OK)
break;
}
@@ -192,7 +192,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
#ifndef _7Z_NO_METHOD_LZMA2
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
- Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
+ Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{
CLzma2Dec state;
SRes res = SZ_OK;
@@ -211,7 +211,7 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
- res = inStream->Look(inStream, &inBuf, &lookahead);
+ res = ILookInStream_Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK)
break;
@@ -237,7 +237,7 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
break;
}
- res = inStream->Skip((void *)inStream, inProcessed);
+ res = ILookInStream_Skip(inStream, inProcessed);
if (res != SZ_OK)
break;
}
@@ -258,13 +258,13 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
size_t curSize = (1 << 18);
if (curSize > inSize)
curSize = (size_t)inSize;
- RINOK(inStream->Look(inStream, &inBuf, &curSize));
+ RINOK(ILookInStream_Look(inStream, &inBuf, &curSize));
if (curSize == 0)
return SZ_ERROR_INPUT_EOF;
memcpy(outBuffer, inBuf, curSize);
outBuffer += curSize;
inSize -= curSize;
- RINOK(inStream->Skip((void *)inStream, curSize));
+ RINOK(ILookInStream_Skip(inStream, curSize));
}
return SZ_OK;
}
@@ -372,7 +372,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
const UInt64 *unpackSizes,
const UInt64 *packPositions,
ILookInStream *inStream, UInt64 startPos,
- Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
+ Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain,
Byte *tempBuf[])
{
UInt32 ci;
@@ -404,7 +404,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
outSizeCur = (SizeT)unpackSize;
if (outSizeCur != unpackSize)
return SZ_ERROR_MEM;
- temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
+ temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur);
if (!temp && outSizeCur != 0)
return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp;
@@ -421,7 +421,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
return SZ_ERROR_UNSUPPORTED;
}
offset = packPositions[si];
- inSize = packPositions[si + 1] - offset;
+ inSize = packPositions[(size_t)si + 1] - offset;
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
if (coder->MethodID == k_Copy)
@@ -460,7 +460,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
tempSizes[2] = (SizeT)s3Size;
if (tempSizes[2] != s3Size)
return SZ_ERROR_MEM;
- tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
+ tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]);
if (!tempBuf[2] && tempSizes[2] != 0)
return SZ_ERROR_MEM;
@@ -549,7 +549,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, size_t outSize,
- ISzAlloc *allocMain)
+ ISzAllocPtr allocMain)
{
SRes res;
CSzFolder folder;
@@ -557,7 +557,7 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
sd.Data = data;
- sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];
+ sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex];
res = SzGetNextFolderItem(&folder, &sd);
@@ -579,7 +579,7 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
outBuffer, (SizeT)outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++)
- IAlloc_Free(allocMain, tempBuf[i]);
+ ISzAlloc_Free(allocMain, tempBuf[i]);
if (res == SZ_OK)
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
diff --git a/C/7zFile.c b/C/7zFile.c
index 041e5b15..8992fb1c 100644
--- a/C/7zFile.c
+++ b/C/7zFile.c
@@ -1,5 +1,5 @@
/* 7zFile.c -- File IO
-2009-11-24 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -238,49 +238,49 @@ WRes File_GetLength(CSzFile *p, UInt64 *length)
/* ---------- FileSeqInStream ---------- */
-static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
+static SRes FileSeqInStream_Read(const ISeqInStream *pp, void *buf, size_t *size)
{
- CFileSeqInStream *p = (CFileSeqInStream *)pp;
+ CFileSeqInStream *p = CONTAINER_FROM_VTBL(pp, CFileSeqInStream, vt);
return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
}
void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
{
- p->s.Read = FileSeqInStream_Read;
+ p->vt.Read = FileSeqInStream_Read;
}
/* ---------- FileInStream ---------- */
-static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
+static SRes FileInStream_Read(const ISeekInStream *pp, void *buf, size_t *size)
{
- CFileInStream *p = (CFileInStream *)pp;
+ CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
}
-static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
+static SRes FileInStream_Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin)
{
- CFileInStream *p = (CFileInStream *)pp;
+ CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
return File_Seek(&p->file, pos, origin);
}
void FileInStream_CreateVTable(CFileInStream *p)
{
- p->s.Read = FileInStream_Read;
- p->s.Seek = FileInStream_Seek;
+ p->vt.Read = FileInStream_Read;
+ p->vt.Seek = FileInStream_Seek;
}
/* ---------- FileOutStream ---------- */
-static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
+static size_t FileOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size)
{
- CFileOutStream *p = (CFileOutStream *)pp;
+ CFileOutStream *p = CONTAINER_FROM_VTBL(pp, CFileOutStream, vt);
File_Write(&p->file, data, &size);
return size;
}
void FileOutStream_CreateVTable(CFileOutStream *p)
{
- p->s.Write = FileOutStream_Write;
+ p->vt.Write = FileOutStream_Write;
}
diff --git a/C/7zFile.h b/C/7zFile.h
index 658987ed..0e792538 100644
--- a/C/7zFile.h
+++ b/C/7zFile.h
@@ -1,5 +1,5 @@
/* 7zFile.h -- File IO
-2013-01-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_FILE_H
#define __7Z_FILE_H
@@ -54,7 +54,7 @@ WRes File_GetLength(CSzFile *p, UInt64 *length);
typedef struct
{
- ISeqInStream s;
+ ISeqInStream vt;
CSzFile file;
} CFileSeqInStream;
@@ -63,7 +63,7 @@ void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
typedef struct
{
- ISeekInStream s;
+ ISeekInStream vt;
CSzFile file;
} CFileInStream;
@@ -72,7 +72,7 @@ void FileInStream_CreateVTable(CFileInStream *p);
typedef struct
{
- ISeqOutStream s;
+ ISeqOutStream vt;
CSzFile file;
} CFileOutStream;
diff --git a/C/7zStream.c b/C/7zStream.c
index 88f9c42b..6b5aa162 100644
--- a/C/7zStream.c
+++ b/C/7zStream.c
@@ -1,5 +1,5 @@
/* 7zStream.c -- 7z Stream functions
-2013-11-12 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -7,12 +7,12 @@
#include "7zTypes.h"
-SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
+SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType)
{
while (size != 0)
{
size_t processed = size;
- RINOK(stream->Read(stream, buf, &processed));
+ RINOK(ISeqInStream_Read(stream, buf, &processed));
if (processed == 0)
return errorType;
buf = (void *)((Byte *)buf + processed);
@@ -21,40 +21,42 @@ SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorT
return SZ_OK;
}
-SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
+SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size)
{
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
}
-SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
+SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf)
{
size_t processed = 1;
- RINOK(stream->Read(stream, buf, &processed));
+ RINOK(ISeqInStream_Read(stream, buf, &processed));
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
}
-SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
+
+
+SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset)
{
Int64 t = offset;
- return stream->Seek(stream, &t, SZ_SEEK_SET);
+ return ILookInStream_Seek(stream, &t, SZ_SEEK_SET);
}
-SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
+SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size)
{
const void *lookBuf;
if (*size == 0)
return SZ_OK;
- RINOK(stream->Look(stream, &lookBuf, size));
+ RINOK(ILookInStream_Look(stream, &lookBuf, size));
memcpy(buf, lookBuf, *size);
- return stream->Skip(stream, *size);
+ return ILookInStream_Skip(stream, *size);
}
-SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
+SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType)
{
while (size != 0)
{
size_t processed = size;
- RINOK(stream->Read(stream, buf, &processed));
+ RINOK(ILookInStream_Read(stream, buf, &processed));
if (processed == 0)
return errorType;
buf = (void *)((Byte *)buf + processed);
@@ -63,61 +65,67 @@ SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes erro
return SZ_OK;
}
-SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
+SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size)
{
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
}
-static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
+
+
+#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt);
+
+static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size)
{
SRes res = SZ_OK;
- CLookToRead *p = (CLookToRead *)pp;
+ GET_LookToRead2
size_t size2 = p->size - p->pos;
- if (size2 == 0 && *size > 0)
+ if (size2 == 0 && *size != 0)
{
p->pos = 0;
- size2 = LookToRead_BUF_SIZE;
- res = p->realStream->Read(p->realStream, p->buf, &size2);
+ p->size = 0;
+ size2 = p->bufSize;
+ res = ISeekInStream_Read(p->realStream, p->buf, &size2);
p->size = size2;
}
- if (size2 < *size)
+ if (*size > size2)
*size = size2;
*buf = p->buf + p->pos;
return res;
}
-static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
+static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size)
{
SRes res = SZ_OK;
- CLookToRead *p = (CLookToRead *)pp;
+ GET_LookToRead2
size_t size2 = p->size - p->pos;
- if (size2 == 0 && *size > 0)
+ if (size2 == 0 && *size != 0)
{
p->pos = 0;
- if (*size > LookToRead_BUF_SIZE)
- *size = LookToRead_BUF_SIZE;
- res = p->realStream->Read(p->realStream, p->buf, size);
+ p->size = 0;
+ if (*size > p->bufSize)
+ *size = p->bufSize;
+ res = ISeekInStream_Read(p->realStream, p->buf, size);
size2 = p->size = *size;
}
- if (size2 < *size)
+ if (*size > size2)
*size = size2;
*buf = p->buf + p->pos;
return res;
}
-static SRes LookToRead_Skip(void *pp, size_t offset)
+static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset)
{
- CLookToRead *p = (CLookToRead *)pp;
+ GET_LookToRead2
p->pos += offset;
return SZ_OK;
}
-static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
+static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size)
{
- CLookToRead *p = (CLookToRead *)pp;
+ GET_LookToRead2
size_t rem = p->size - p->pos;
if (rem == 0)
- return p->realStream->Read(p->realStream, buf, size);
+ return ISeekInStream_Read(p->realStream, buf, size);
if (rem > *size)
rem = *size;
memcpy(buf, p->buf + p->pos, rem);
@@ -126,46 +134,43 @@ static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
return SZ_OK;
}
-static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
+static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin)
{
- CLookToRead *p = (CLookToRead *)pp;
+ GET_LookToRead2
p->pos = p->size = 0;
- return p->realStream->Seek(p->realStream, pos, origin);
+ return ISeekInStream_Seek(p->realStream, pos, origin);
}
-void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
+void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead)
{
- p->s.Look = lookahead ?
- LookToRead_Look_Lookahead :
- LookToRead_Look_Exact;
- p->s.Skip = LookToRead_Skip;
- p->s.Read = LookToRead_Read;
- p->s.Seek = LookToRead_Seek;
+ p->vt.Look = lookahead ?
+ LookToRead2_Look_Lookahead :
+ LookToRead2_Look_Exact;
+ p->vt.Skip = LookToRead2_Skip;
+ p->vt.Read = LookToRead2_Read;
+ p->vt.Seek = LookToRead2_Seek;
}
-void LookToRead_Init(CLookToRead *p)
-{
- p->pos = p->size = 0;
-}
-static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
+
+static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size)
{
- CSecToLook *p = (CSecToLook *)pp;
+ CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt);
return LookInStream_LookRead(p->realStream, buf, size);
}
void SecToLook_CreateVTable(CSecToLook *p)
{
- p->s.Read = SecToLook_Read;
+ p->vt.Read = SecToLook_Read;
}
-static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
+static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size)
{
- CSecToRead *p = (CSecToRead *)pp;
- return p->realStream->Read(p->realStream, buf, size);
+ CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt);
+ return ILookInStream_Read(p->realStream, buf, size);
}
void SecToRead_CreateVTable(CSecToRead *p)
{
- p->s.Read = SecToRead_Read;
+ p->vt.Read = SecToRead_Read;
}
diff --git a/C/7zTypes.h b/C/7zTypes.h
index 778413ef..588ec5ee 100644
--- a/C/7zTypes.h
+++ b/C/7zTypes.h
@@ -1,5 +1,5 @@
/* 7zTypes.h -- Basic types
-2013-11-12 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
@@ -112,48 +112,72 @@ typedef int Bool;
#define MY_NO_INLINE
#endif
+#define MY_FORCE_INLINE __forceinline
+
#define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall
#else
#define MY_NO_INLINE
+#define MY_FORCE_INLINE
#define MY_CDECL
#define MY_FAST_CALL
+/* inline keyword : for C++ / C99 */
+
+/* GCC, clang: */
+/*
+#if defined (__GNUC__) && (__GNUC__ >= 4)
+#define MY_FORCE_INLINE __attribute__((always_inline))
+#define MY_NO_INLINE __attribute__((noinline))
+#endif
+*/
+
#endif
/* The following interfaces use first parameter as pointer to structure */
-typedef struct
+typedef struct IByteIn IByteIn;
+struct IByteIn
{
- Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
-} IByteIn;
+ Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
+};
+#define IByteIn_Read(p) (p)->Read(p)
-typedef struct
+
+typedef struct IByteOut IByteOut;
+struct IByteOut
{
- void (*Write)(void *p, Byte b);
-} IByteOut;
+ void (*Write)(const IByteOut *p, Byte b);
+};
+#define IByteOut_Write(p, b) (p)->Write(p, b)
-typedef struct
+
+typedef struct ISeqInStream ISeqInStream;
+struct ISeqInStream
{
- SRes (*Read)(void *p, void *buf, size_t *size);
+ SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
-} ISeqInStream;
+};
+#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
/* it can return SZ_ERROR_INPUT_EOF */
-SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
-SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
-SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
+SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
+SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
+SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
-typedef struct
+
+typedef struct ISeqOutStream ISeqOutStream;
+struct ISeqOutStream
{
- size_t (*Write)(void *p, const void *buf, size_t size);
+ size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
-} ISeqOutStream;
+};
+#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
typedef enum
{
@@ -162,78 +186,162 @@ typedef enum
SZ_SEEK_END = 2
} ESzSeek;
-typedef struct
+
+typedef struct ISeekInStream ISeekInStream;
+struct ISeekInStream
{
- SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
- SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-} ISeekInStream;
+ SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
+ SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
+};
+#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
+#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
-typedef struct
+
+typedef struct ILookInStream ILookInStream;
+struct ILookInStream
{
- SRes (*Look)(void *p, const void **buf, size_t *size);
+ SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */
- SRes (*Skip)(void *p, size_t offset);
+ SRes (*Skip)(const ILookInStream *p, size_t offset);
/* offset must be <= output(*size) of Look */
- SRes (*Read)(void *p, void *buf, size_t *size);
+ SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */
- SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-} ILookInStream;
+ SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
+};
+
+#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
+#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
+#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
+#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
-SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
-SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
+
+SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
+SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */
-SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
-SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
+SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
+SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
+
-#define LookToRead_BUF_SIZE (1 << 14)
typedef struct
{
- ILookInStream s;
- ISeekInStream *realStream;
+ ILookInStream vt;
+ const ISeekInStream *realStream;
+
size_t pos;
- size_t size;
- Byte buf[LookToRead_BUF_SIZE];
-} CLookToRead;
+ size_t size; /* it's data size */
+
+ /* the following variables must be set outside */
+ Byte *buf;
+ size_t bufSize;
+} CLookToRead2;
+
+void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
+
+#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
-void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
-void LookToRead_Init(CLookToRead *p);
typedef struct
{
- ISeqInStream s;
- ILookInStream *realStream;
+ ISeqInStream vt;
+ const ILookInStream *realStream;
} CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p);
+
+
typedef struct
{
- ISeqInStream s;
- ILookInStream *realStream;
+ ISeqInStream vt;
+ const ILookInStream *realStream;
} CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p);
-typedef struct
+
+typedef struct ICompressProgress ICompressProgress;
+
+struct ICompressProgress
{
- SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
+ SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
-} ICompressProgress;
+};
+#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
-typedef struct
+
+
+typedef struct ISzAlloc ISzAlloc;
+typedef const ISzAlloc * ISzAllocPtr;
+
+struct ISzAlloc
{
- void *(*Alloc)(void *p, size_t size);
- void (*Free)(void *p, void *address); /* address can be 0 */
-} ISzAlloc;
+ void *(*Alloc)(ISzAllocPtr p, size_t size);
+ void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
+};
+
+#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
+#define ISzAlloc_Free(p, a) (p)->Free(p, a)
+
+/* deprecated */
+#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
+#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
+
+
+
+
+
+#ifndef MY_offsetof
+ #ifdef offsetof
+ #define MY_offsetof(type, m) offsetof(type, m)
+ /*
+ #define MY_offsetof(type, m) FIELD_OFFSET(type, m)
+ */
+ #else
+ #define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
+ #endif
+#endif
+
+
+
+#ifndef MY_container_of
+
+/*
+#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
+#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
+#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
+#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
+*/
+
+/*
+ GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
+ GCC 3.4.4 : classes with constructor
+ GCC 4.8.1 : classes with non-public variable members"
+*/
+
+#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
+
+
+#endif
+
+#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
+
+/*
+#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
+*/
+#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
+
+#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
+/*
+#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
+*/
+
-#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
-#define IAlloc_Free(p, a) (p)->Free((p), a)
#ifdef _WIN32
diff --git a/C/7zVersion.h b/C/7zVersion.h
index 4f15081d..e8f24442 100644
--- a/C/7zVersion.h
+++ b/C/7zVersion.h
@@ -1,14 +1,21 @@
-#define MY_VER_MAJOR 16
-#define MY_VER_MINOR 04
+#define MY_VER_MAJOR 17
+#define MY_VER_MINOR 00
#define MY_VER_BUILD 0
-#define MY_VERSION_NUMBERS "16.04"
-#define MY_VERSION "16.04"
-#define MY_DATE "2016-10-04"
+#define MY_VERSION_NUMBERS "17.00 beta"
+#define MY_VERSION MY_VERSION_NUMBERS
+
+#ifdef MY_CPU_NAME
+ #define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
+#else
+ #define MY_VERSION_CPU MY_VERSION
+#endif
+
+#define MY_DATE "2017-04-29"
#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-2016 Igor Pavlov"
+#define MY_COPYRIGHT_CR "Copyright (c) 1999-2017 Igor Pavlov"
#ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR
@@ -16,4 +23,5 @@
#define MY_COPYRIGHT MY_COPYRIGHT_PD
#endif
-#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE
+#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE
diff --git a/C/Aes.c b/C/Aes.c
index b10b9e58..1cdd0e78 100644
--- a/C/Aes.c
+++ b/C/Aes.c
@@ -1,5 +1,5 @@
/* Aes.c -- AES encryption / decryption
-2016-05-21 : Igor Pavlov : Public domain */
+2017-01-24 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -49,7 +49,13 @@ static const Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0
#define gb0(x) ( (x) & 0xFF)
#define gb1(x) (((x) >> ( 8)) & 0xFF)
#define gb2(x) (((x) >> (16)) & 0xFF)
-#define gb3(x) (((x) >> (24)) & 0xFF)
+#define gb3(x) (((x) >> (24)))
+
+#define gb(n, x) gb ## n(x)
+
+#define TT(x) (T + (x << 8))
+#define DD(x) (D + (x << 8))
+
void AesGenTables(void)
{
@@ -63,10 +69,10 @@ void AesGenTables(void)
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);
+ TT(0)[i] = Ui32(a2, a1, a1, a3);
+ TT(1)[i] = Ui32(a3, a2, a1, a1);
+ TT(2)[i] = Ui32(a1, a3, a2, a1);
+ TT(3)[i] = Ui32(a1, a1, a3, a2);
}
{
UInt32 a1 = InvS[i];
@@ -77,10 +83,10 @@ void AesGenTables(void)
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);
+ DD(0)[i] = Ui32(aE, a9, aD, aB);
+ DD(1)[i] = Ui32(aB, aE, a9, aD);
+ DD(2)[i] = Ui32(aD, aB, aE, a9);
+ DD(3)[i] = Ui32(a9, aD, aB, aE);
}
}
@@ -99,7 +105,7 @@ void AesGenTables(void)
}
-#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])]
+#define HT(i, x, s) TT(x)[gb(x, s[(i + x) & 3])]
#define HT4(m, i, s, p) m[i] = \
HT(i, 0, s) ^ \
@@ -113,11 +119,11 @@ void AesGenTables(void)
HT4(m, 2, s, p); \
HT4(m, 3, s, p); \
-#define FT(i, x) Sbox[gb ## x(m[(i + x) & 3])]
+#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 HD(i, x, s) DD(x)[gb(x, s[(i - x) & 3])]
#define HD4(m, i, s, p) m[i] = \
HD(i, 0, s) ^ \
@@ -131,7 +137,7 @@ void AesGenTables(void)
HD4(m, 2, s, p); \
HD4(m, 3, s, p); \
-#define FD(i, x) InvS[gb ## x(m[(i - x) & 3])]
+#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)
@@ -147,7 +153,7 @@ void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize)
for (; i < wSize; i++)
{
- UInt32 t = w[i - 1];
+ UInt32 t = w[(size_t)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)]);
@@ -167,10 +173,10 @@ void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize)
{
UInt32 r = w[i];
w[i] =
- D[ (unsigned)Sbox[gb0(r)]] ^
- D[0x100 + (unsigned)Sbox[gb1(r)]] ^
- D[0x200 + (unsigned)Sbox[gb2(r)]] ^
- D[0x300 + (unsigned)Sbox[gb3(r)]];
+ DD(0)[Sbox[gb0(r)]] ^
+ DD(1)[Sbox[gb1(r)]] ^
+ DD(2)[Sbox[gb2(r)]] ^
+ DD(3)[Sbox[gb3(r)]];
}
}
@@ -276,20 +282,25 @@ 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;
+ unsigned 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];
+ for (i = 0; i < 4; i++, data += 4)
+ {
+ UInt32 t = temp[i];
+
+ #ifdef MY_CPU_LE_UNALIGN
+ *((UInt32 *)data) ^= t;
+ #else
+ data[0] ^= (t & 0xFF);
+ data[1] ^= ((t >> 8) & 0xFF);
+ data[2] ^= ((t >> 16) & 0xFF);
+ data[3] ^= ((t >> 24));
+ #endif
+ }
}
}
diff --git a/C/Alloc.c b/C/Alloc.c
index 3f6ac419..9665ad49 100644
--- a/C/Alloc.c
+++ b/C/Alloc.c
@@ -1,5 +1,5 @@
/* Alloc.c -- Memory allocation functions
-2015-02-21 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -127,10 +127,10 @@ 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 *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
+static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); }
+ISzAlloc const 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 };
+static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
+static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); }
+ISzAlloc const g_BigAlloc = { SzBigAlloc, SzBigFree };
diff --git a/C/Alloc.h b/C/Alloc.h
index bac0d87e..3b88ef75 100644
--- a/C/Alloc.h
+++ b/C/Alloc.h
@@ -1,5 +1,5 @@
/* Alloc.h -- Memory allocation functions
-2015-02-21 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H
@@ -29,8 +29,8 @@ void BigFree(void *address);
#endif
-extern ISzAlloc g_Alloc;
-extern ISzAlloc g_BigAlloc;
+extern const ISzAlloc g_Alloc;
+extern const ISzAlloc g_BigAlloc;
EXTERN_C_END
diff --git a/C/Bcj2.c b/C/Bcj2.c
index 3c88e44f..0efff4e5 100644
--- a/C/Bcj2.c
+++ b/C/Bcj2.c
@@ -1,5 +1,5 @@
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
-2015-08-01 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -61,7 +61,8 @@ SRes Bcj2Dec_Decode(CBcj2Dec *p)
Byte *dest = p->dest;
if (dest == p->destLim)
return SZ_OK;
- *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0];
+ *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0];
+ p->state++;
p->dest = dest + 1;
}
}
diff --git a/C/Bcj2Enc.c b/C/Bcj2Enc.c
index 0ea36462..98b775b7 100644
--- a/C/Bcj2Enc.c
+++ b/C/Bcj2Enc.c
@@ -1,5 +1,5 @@
/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code)
-2014-11-10 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -271,7 +271,7 @@ void Bcj2Enc_Encode(CBcj2Enc *p)
unsigned i;
p->tempPos = tempPos;
for (i = 0; i < tempPos; i++)
- p->temp[i] = p->temp[i + num];
+ p->temp[i] = p->temp[(size_t)i + num];
p->src = src;
p->srcLim = srcLim;
diff --git a/C/Bra.c b/C/Bra.c
index cdb94569..aed17e33 100644
--- a/C/Bra.c
+++ b/C/Bra.c
@@ -1,135 +1,230 @@
/* Bra.c -- Converters for RISC code
-2010-04-16 : Igor Pavlov : Public domain */
+2017-04-04 : Igor Pavlov : Public domain */
#include "Precomp.h"
+#include "CpuArch.h"
#include "Bra.h"
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{
- SizeT i;
- if (size < 4)
- return 0;
- size -= 4;
- ip += 8;
- for (i = 0; i <= size; i += 4)
+ Byte *p;
+ const Byte *lim;
+ size &= ~(size_t)3;
+ ip += 4;
+ p = data;
+ lim = data + size;
+
+ if (encoding)
+
+ for (;;)
{
- if (data[i + 3] == 0xEB)
+ for (;;)
{
- UInt32 dest;
- UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
- src <<= 2;
- if (encoding)
- dest = ip + (UInt32)i + src;
- else
- dest = src - (ip + (UInt32)i);
- dest >>= 2;
- data[i + 2] = (Byte)(dest >> 16);
- data[i + 1] = (Byte)(dest >> 8);
- data[i + 0] = (Byte)dest;
+ if (p >= lim)
+ return p - data;
+ p += 4;
+ if (p[-1] == 0xEB)
+ break;
+ }
+ {
+ UInt32 v = GetUi32(p - 4);
+ v <<= 2;
+ v += ip + (UInt32)(p - data);
+ v >>= 2;
+ v &= 0x00FFFFFF;
+ v |= 0xEB000000;
+ SetUi32(p - 4, v);
+ }
+ }
+
+ for (;;)
+ {
+ for (;;)
+ {
+ if (p >= lim)
+ return p - data;
+ p += 4;
+ if (p[-1] == 0xEB)
+ break;
+ }
+ {
+ UInt32 v = GetUi32(p - 4);
+ v <<= 2;
+ v -= ip + (UInt32)(p - data);
+ v >>= 2;
+ v &= 0x00FFFFFF;
+ v |= 0xEB000000;
+ SetUi32(p - 4, v);
}
}
- return i;
}
+
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{
- SizeT i;
- if (size < 4)
- return 0;
- size -= 4;
- ip += 4;
- for (i = 0; i <= size; i += 2)
+ Byte *p;
+ const Byte *lim;
+ size &= ~(size_t)1;
+ p = data;
+ lim = data + size - 4;
+
+ if (encoding)
+
+ for (;;)
{
- if ((data[i + 1] & 0xF8) == 0xF0 &&
- (data[i + 3] & 0xF8) == 0xF8)
+ UInt32 b1;
+ for (;;)
{
- UInt32 dest;
- UInt32 src =
- (((UInt32)data[i + 1] & 0x7) << 19) |
- ((UInt32)data[i + 0] << 11) |
- (((UInt32)data[i + 3] & 0x7) << 8) |
- (data[i + 2]);
-
- src <<= 1;
- if (encoding)
- dest = ip + (UInt32)i + src;
- else
- dest = src - (ip + (UInt32)i);
- dest >>= 1;
+ UInt32 b3;
+ if (p > lim)
+ return p - data;
+ b1 = p[1];
+ b3 = p[3];
+ p += 2;
+ b1 ^= 8;
+ if ((b3 & b1) >= 0xF8)
+ break;
+ }
+ {
+ UInt32 v =
+ ((UInt32)b1 << 19)
+ + (((UInt32)p[1] & 0x7) << 8)
+ + (((UInt32)p[-2] << 11))
+ + (p[0]);
+
+ p += 2;
+ {
+ UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
+ v += cur;
+ }
+
+ p[-4] = (Byte)(v >> 11);
+ p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
+ p[-2] = (Byte)v;
+ p[-1] = (Byte)(0xF8 | (v >> 8));
+ }
+ }
+
+ for (;;)
+ {
+ UInt32 b1;
+ for (;;)
+ {
+ UInt32 b3;
+ if (p > lim)
+ return p - data;
+ b1 = p[1];
+ b3 = p[3];
+ p += 2;
+ b1 ^= 8;
+ if ((b3 & b1) >= 0xF8)
+ break;
+ }
+ {
+ UInt32 v =
+ ((UInt32)b1 << 19)
+ + (((UInt32)p[1] & 0x7) << 8)
+ + (((UInt32)p[-2] << 11))
+ + (p[0]);
+
+ p += 2;
+ {
+ UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
+ v -= cur;
+ }
+
+ /*
+ SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000));
+ SetUi16(p - 2, (UInt16)(v | 0xF800));
+ */
- data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
- data[i + 0] = (Byte)(dest >> 11);
- data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
- data[i + 2] = (Byte)dest;
- i += 2;
+ p[-4] = (Byte)(v >> 11);
+ p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
+ p[-2] = (Byte)v;
+ p[-1] = (Byte)(0xF8 | (v >> 8));
}
}
- return i;
}
+
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{
- SizeT i;
- if (size < 4)
- return 0;
- size -= 4;
- for (i = 0; i <= size; i += 4)
+ Byte *p;
+ const Byte *lim;
+ size &= ~(size_t)3;
+ ip -= 4;
+ p = data;
+ lim = data + size;
+
+ for (;;)
{
- if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
+ for (;;)
{
- UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
- ((UInt32)data[i + 1] << 16) |
- ((UInt32)data[i + 2] << 8) |
- ((UInt32)data[i + 3] & (~3));
-
- UInt32 dest;
+ if (p >= lim)
+ return p - data;
+ p += 4;
+ /* if ((v & 0xFC000003) == 0x48000001) */
+ if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1)
+ break;
+ }
+ {
+ UInt32 v = GetBe32(p - 4);
if (encoding)
- dest = ip + (UInt32)i + src;
+ v += ip + (UInt32)(p - data);
else
- dest = src - (ip + (UInt32)i);
- data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
- data[i + 1] = (Byte)(dest >> 16);
- data[i + 2] = (Byte)(dest >> 8);
- data[i + 3] &= 0x3;
- data[i + 3] |= dest;
+ v -= ip + (UInt32)(p - data);
+ v &= 0x03FFFFFF;
+ v |= 0x48000000;
+ SetBe32(p - 4, v);
}
}
- return i;
}
+
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{
- UInt32 i;
- if (size < 4)
- return 0;
- size -= 4;
- for (i = 0; i <= size; i += 4)
+ Byte *p;
+ const Byte *lim;
+ size &= ~(size_t)3;
+ ip -= 4;
+ p = data;
+ lim = data + size;
+
+ for (;;)
{
- if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
- (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
+ for (;;)
{
- UInt32 src =
- ((UInt32)data[i + 0] << 24) |
- ((UInt32)data[i + 1] << 16) |
- ((UInt32)data[i + 2] << 8) |
- ((UInt32)data[i + 3]);
- UInt32 dest;
-
- src <<= 2;
+ if (p >= lim)
+ return p - data;
+ /*
+ v = GetBe32(p);
+ p += 4;
+ m = v + ((UInt32)5 << 29);
+ m ^= (UInt32)7 << 29;
+ m += (UInt32)1 << 22;
+ if ((m & ((UInt32)0x1FF << 23)) == 0)
+ break;
+ */
+ p += 4;
+ if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) ||
+ (p[-4] == 0x7F && (p[-3] >= 0xC0)))
+ break;
+ }
+ {
+ UInt32 v = GetBe32(p - 4);
+ v <<= 2;
if (encoding)
- dest = ip + i + src;
+ v += ip + (UInt32)(p - data);
else
- dest = src - (ip + i);
- dest >>= 2;
+ v -= ip + (UInt32)(p - data);
- dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
-
- data[i + 0] = (Byte)(dest >> 24);
- data[i + 1] = (Byte)(dest >> 16);
- data[i + 2] = (Byte)(dest >> 8);
- data[i + 3] = (Byte)dest;
+ v &= 0x01FFFFFF;
+ v -= (UInt32)1 << 24;
+ v ^= 0xFF000000;
+ v >>= 2;
+ v |= 0x40000000;
+ SetBe32(p - 4, v);
}
}
- return i;
}
diff --git a/C/Bra86.c b/C/Bra86.c
index 6db15e7e..93ed4d76 100644
--- a/C/Bra86.c
+++ b/C/Bra86.c
@@ -1,5 +1,5 @@
/* Bra86.c -- Converter for x86 code (BCJ)
-2013-11-12 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -37,7 +37,7 @@ SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding
else
{
mask >>= (unsigned)d;
- if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1])))
+ if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
{
mask = (mask >> 1) | 4;
pos++;
diff --git a/C/BraIA64.c b/C/BraIA64.c
index fa60356b..d1dbc62c 100644
--- a/C/BraIA64.c
+++ b/C/BraIA64.c
@@ -1,69 +1,53 @@
/* BraIA64.c -- Converter for IA-64 code
-2013-11-12 : Igor Pavlov : Public domain */
+2017-01-26 : Igor Pavlov : Public domain */
#include "Precomp.h"
+#include "CpuArch.h"
#include "Bra.h"
-static const Byte kBranchTable[32] =
-{
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 4, 4, 6, 6, 0, 0, 7, 7,
- 4, 4, 0, 0, 4, 4, 0, 0
-};
-
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{
SizeT i;
if (size < 16)
return 0;
size -= 16;
- for (i = 0; i <= size; i += 16)
+ i = 0;
+ do
{
- UInt32 instrTemplate = data[i] & 0x1F;
- UInt32 mask = kBranchTable[instrTemplate];
- UInt32 bitPos = 5;
- int slot;
- for (slot = 0; slot < 3; slot++, bitPos += 41)
+ unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3;
+ if (m)
{
- UInt32 bytePos, bitRes;
- UInt64 instruction, instNorm;
- int j;
- if (((mask >> slot) & 1) == 0)
- continue;
- bytePos = (bitPos >> 3);
- bitRes = bitPos & 0x7;
- instruction = 0;
- for (j = 0; j < 6; j++)
- instruction += (UInt64)data[i + j + bytePos] << (8 * j);
-
- instNorm = instruction >> bitRes;
- if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)
+ m++;
+ do
{
- UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
- UInt32 dest;
- src |= ((UInt32)(instNorm >> 36) & 1) << 20;
-
- src <<= 4;
-
- if (encoding)
- dest = ip + (UInt32)i + src;
- else
- dest = src - (ip + (UInt32)i);
-
- dest >>= 4;
-
- instNorm &= ~((UInt64)(0x8FFFFF) << 13);
- instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
- instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
-
- instruction &= (1 << bitRes) - 1;
- instruction |= (instNorm << bitRes);
- for (j = 0; j < 6; j++)
- data[i + j + bytePos] = (Byte)(instruction >> (8 * j));
+ Byte *p = data + (i + (size_t)m * 5 - 8);
+ if (((p[3] >> m) & 15) == 5
+ && (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0)
+ {
+ unsigned raw = GetUi32(p);
+ unsigned v = raw >> m;
+ v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3);
+
+ v <<= 4;
+ if (encoding)
+ v += ip + (UInt32)i;
+ else
+ v -= ip + (UInt32)i;
+ v >>= 4;
+
+ v &= 0x1FFFFF;
+ v += 0x700000;
+ v &= 0x8FFFFF;
+ raw &= ~((UInt32)0x8FFFFF << m);
+ raw |= (v << m);
+ SetUi32(p, raw);
+ }
}
+ while (++m <= 4);
}
+ i += 16;
}
+ while (i <= size);
return i;
}
diff --git a/C/BwtSort.c b/C/BwtSort.c
index 36501cc9..aa319201 100644
--- a/C/BwtSort.c
+++ b/C/BwtSort.c
@@ -1,5 +1,5 @@
/* BwtSort.c -- BWT block sorting
-2013-11-12 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -314,7 +314,7 @@ UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 group
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax);
if ((ind2[j] & 0x40000000) != 0)
- subGroupSize += ((ind2[j + 1] >> kNumBitsMax) << kNumExtra0Bits);
+ subGroupSize += ((ind2[(size_t)j + 1] >> kNumBitsMax) << kNumExtra0Bits);
subGroupSize++;
for (;;)
{
@@ -362,7 +362,7 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
for (i = 0; i < kNumHashValues; i++)
counters[i] = 0;
for (i = 0; i < blockSize - 1; i++)
- counters[((UInt32)data[i] << 8) | data[i + 1]]++;
+ counters[((UInt32)data[i] << 8) | data[(size_t)i + 1]]++;
counters[((UInt32)data[i] << 8) | data[0]]++;
Groups = counters + BS_TEMP_SIZE;
@@ -392,11 +392,11 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
}
for (i = 0; i < blockSize - 1; i++)
- Groups[i] = counters[((UInt32)data[i] << 8) | data[i + 1]];
+ Groups[i] = counters[((UInt32)data[i] << 8) | data[(size_t)i + 1]];
Groups[i] = counters[((UInt32)data[i] << 8) | data[0]];
for (i = 0; i < blockSize - 1; i++)
- Indices[counters[((UInt32)data[i] << 8) | data[i + 1]]++] = i;
+ Indices[counters[((UInt32)data[i] << 8) | data[(size_t)i + 1]]++] = i;
Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i;
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
@@ -451,8 +451,8 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
Bool finishedGroup = ((Indices[i] & 0x80000000) == 0);
if ((Indices[i] & 0x40000000) != 0)
{
- groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits);
- Indices[i + 1] &= kIndexMask;
+ groupSize += ((Indices[(size_t)i + 1] >> kNumBitsMax) << kNumExtra0Bits);
+ Indices[(size_t)i + 1] &= kIndexMask;
}
Indices[i] &= kIndexMask;
groupSize++;
@@ -460,7 +460,7 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
{
Indices[i - finishedGroupSize] &= kIndexMask;
if (finishedGroupSize > 1)
- Indices[i - finishedGroupSize + 1] &= kIndexMask;
+ Indices[(size_t)(i - finishedGroupSize) + 1] &= kIndexMask;
{
UInt32 newGroupSize = groupSize + finishedGroupSize;
SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize);
@@ -503,8 +503,8 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax);
if ((Indices[i] & 0x40000000) != 0)
{
- groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits);
- Indices[i + 1] &= kIndexMask;
+ groupSize += ((Indices[(size_t)i + 1] >> kNumBitsMax) << kNumExtra0Bits);
+ Indices[(size_t)i + 1] &= kIndexMask;
}
Indices[i] &= kIndexMask;
groupSize++;
diff --git a/C/Compiler.h b/C/Compiler.h
index 5bba7ee5..0cc409d8 100644
--- a/C/Compiler.h
+++ b/C/Compiler.h
@@ -1,5 +1,5 @@
/* Compiler.h
-2015-08-02 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_COMPILER_H
#define __7Z_COMPILER_H
@@ -21,6 +21,7 @@
#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 : 4714) // function marked as __forceinline not inlined
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
#endif
diff --git a/C/CpuArch.h b/C/CpuArch.h
index e42ce281..95c65168 100644
--- a/C/CpuArch.h
+++ b/C/CpuArch.h
@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code
-2016-06-09: Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
@@ -16,48 +16,122 @@ If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of pl
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
*/
-#if defined(_M_X64) \
- || defined(_M_AMD64) \
- || defined(__x86_64__) \
- || defined(__AMD64__) \
- || defined(__amd64__)
+#if defined(_M_X64) \
+ || defined(_M_AMD64) \
+ || defined(__x86_64__) \
+ || defined(__AMD64__) \
+ || defined(__amd64__)
#define MY_CPU_AMD64
+ #ifdef __ILP32__
+ #define MY_CPU_NAME "x32"
+ #else
+ #define MY_CPU_NAME "x64"
+ #endif
+ #define MY_CPU_64BIT
#endif
-#if defined(MY_CPU_AMD64) \
- || defined(_M_IA64) \
- || defined(__AARCH64EL__) \
- || defined(__AARCH64EB__)
+
+#if defined(_M_IX86) \
+ || defined(__i386__)
+ #define MY_CPU_X86
+ #define MY_CPU_NAME "x86"
+ #define MY_CPU_32BIT
+#endif
+
+
+#if defined(_M_ARM64) \
+ || defined(__AARCH64EL__) \
+ || defined(__AARCH64EB__) \
+ || defined(__aarch64__)
+ #define MY_CPU_ARM64
+ #define MY_CPU_NAME "arm64"
#define MY_CPU_64BIT
#endif
-#if defined(_M_IX86) || defined(__i386__)
-#define MY_CPU_X86
+
+#if defined(_M_ARM) \
+ || defined(_M_ARM_NT) \
+ || defined(_M_ARMT) \
+ || defined(__arm__) \
+ || defined(__thumb__) \
+ || defined(__ARMEL__) \
+ || defined(__ARMEB__) \
+ || defined(__THUMBEL__) \
+ || defined(__THUMBEB__)
+ #define MY_CPU_ARM
+ #define MY_CPU_NAME "arm"
+ #define MY_CPU_32BIT
#endif
-#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
-#define MY_CPU_X86_OR_AMD64
+
+#if defined(_M_IA64) \
+ || defined(__ia64__)
+ #define MY_CPU_IA64
+ #define MY_CPU_NAME "ia64"
+ #define MY_CPU_64BIT
#endif
-#if defined(MY_CPU_X86) \
- || defined(_M_ARM) \
- || defined(__ARMEL__) \
- || defined(__THUMBEL__) \
- || defined(__ARMEB__) \
- || defined(__THUMBEB__)
+
+#if defined(__mips64) \
+ || defined(__mips64__) \
+ || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
+ #define MY_CPU_NAME "mips64"
+ #define MY_CPU_64BIT
+#elif defined(__mips__)
+ #define MY_CPU_NAME "mips"
+ /* #define MY_CPU_32BIT */
+#endif
+
+
+#if defined(__ppc64__) \
+ || defined(__powerpc64__)
+ #ifdef __ILP32__
+ #define MY_CPU_NAME "ppc64-32"
+ #else
+ #define MY_CPU_NAME "ppc64"
+ #endif
+ #define MY_CPU_64BIT
+#elif defined(__ppc__) \
+ || defined(__powerpc__)
+ #define MY_CPU_NAME "ppc"
#define MY_CPU_32BIT
#endif
-#if defined(_WIN32) && defined(_M_ARM)
-#define MY_CPU_ARM_LE
+
+#if defined(__sparc64__)
+ #define MY_CPU_NAME "sparc64"
+ #define MY_CPU_64BIT
+#elif defined(__sparc__)
+ #define MY_CPU_NAME "sparc"
+ /* #define MY_CPU_32BIT */
#endif
-#if defined(_WIN32) && defined(_M_IA64)
-#define MY_CPU_IA64_LE
+
+#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
+#define MY_CPU_X86_OR_AMD64
+#endif
+
+
+#ifdef _WIN32
+
+ #ifdef MY_CPU_ARM
+ #define MY_CPU_ARM_LE
+ #endif
+
+ #ifdef MY_CPU_ARM64
+ #define MY_CPU_ARM64_LE
+ #endif
+
+ #ifdef _M_IA64
+ #define MY_CPU_IA64_LE
+ #endif
+
#endif
+
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_LE) \
+ || defined(MY_CPU_ARM64_LE) \
|| defined(MY_CPU_IA64_LE) \
|| defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \
@@ -86,14 +160,38 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
#define MY_CPU_BE
#endif
+
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
-Stop_Compiling_Bad_Endian
+ #error Stop_Compiling_Bad_Endian
+#endif
+
+
+#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
+ #error Stop_Compiling_Bad_32_64_BIT
+#endif
+
+
+#ifndef MY_CPU_NAME
+ #ifdef MY_CPU_LE
+ #define MY_CPU_NAME "LE"
+ #elif MY_CPU_BE
+ #define MY_CPU_NAME "BE"
+ #else
+ /*
+ #define MY_CPU_NAME ""
+ */
+ #endif
#endif
+
+
+
#ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \
- /* || defined(__AARCH64EL__) */
+ || defined(MY_CPU_ARM64) \
+ || defined(__ARM_FEATURE_UNALIGNED) \
+ || defined(__AARCH64EL__)
#define MY_CPU_LE_UNALIGN
#endif
#endif
diff --git a/C/HuffEnc.c b/C/HuffEnc.c
index 55b497e5..a54b3d87 100644
--- a/C/HuffEnc.c
+++ b/C/HuffEnc.c
@@ -1,5 +1,5 @@
/* HuffEnc.c -- functions for Huffman encoding
-2016-05-16 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -113,7 +113,7 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
if (len >= maxLen)
for (len = maxLen - 1; lenCounters[len] == 0; len--);
lenCounters[len]--;
- lenCounters[len + 1] += 2;
+ lenCounters[(size_t)len + 1] += 2;
}
{
@@ -133,7 +133,7 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
UInt32 code = 0;
UInt32 len;
for (len = 1; len <= kMaxLen; len++)
- nextCodes[len] = code = (code + lenCounters[len - 1]) << 1;
+ nextCodes[len] = code = (code + lenCounters[(size_t)len - 1]) << 1;
}
/* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
diff --git a/C/LzFind.c b/C/LzFind.c
index 2d05fa39..1533eb92 100644
--- a/C/LzFind.c
+++ b/C/LzFind.c
@@ -1,5 +1,5 @@
/* LzFind.c -- Match finder for LZ algorithms
-2015-10-15 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -16,18 +16,18 @@
#define kStartMaxLen 3
-static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
+static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc)
{
if (!p->directInput)
{
- alloc->Free(alloc, p->bufferBase);
+ ISzAlloc_Free(alloc, p->bufferBase);
p->bufferBase = NULL;
}
}
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
-static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAllocPtr alloc)
{
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
if (p->directInput)
@@ -39,7 +39,7 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a
{
LzInWindow_Free(p, alloc);
p->blockSize = blockSize;
- p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
+ p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, (size_t)blockSize);
}
return (p->bufferBase != NULL);
}
@@ -81,7 +81,7 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
if (size == 0)
return;
- p->result = p->stream->Read(p->stream, dest, &size);
+ p->result = ISeqInStream_Read(p->stream, dest, &size);
if (p->result != SZ_OK)
return;
if (size == 0)
@@ -149,34 +149,34 @@ void MatchFinder_Construct(CMatchFinder *p)
UInt32 r = i;
unsigned j;
for (j = 0; j < 8; j++)
- r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+ r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
p->crc[i] = r;
}
}
-static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc)
{
- alloc->Free(alloc, p->hash);
+ ISzAlloc_Free(alloc, p->hash);
p->hash = NULL;
}
-void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
+void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc)
{
MatchFinder_FreeThisClassMemory(p, alloc);
LzInWindow_Free(p, alloc);
}
-static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc)
+static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc)
{
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
if (sizeInBytes / sizeof(CLzRef) != num)
return NULL;
- return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
+ return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes);
}
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
- ISzAlloc *alloc)
+ ISzAllocPtr alloc)
{
UInt32 sizeReserv;
@@ -558,10 +558,10 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
d2 = pos - hash[h2];
- curMatch = hash[kFix3HashSize + hv];
+ curMatch = (hash + kFix3HashSize)[hv];
hash[h2] = pos;
- hash[kFix3HashSize + hv] = pos;
+ (hash + kFix3HashSize)[hv] = pos;
maxLen = 2;
offset = 0;
@@ -594,13 +594,13 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
pos = p->pos;
d2 = pos - hash[ h2];
- d3 = pos - hash[kFix3HashSize + h3];
+ d3 = pos - (hash + kFix3HashSize)[h3];
- curMatch = hash[kFix4HashSize + hv];
+ curMatch = (hash + kFix4HashSize)[hv];
hash[ h2] = pos;
- hash[kFix3HashSize + h3] = pos;
- hash[kFix4HashSize + hv] = pos;
+ (hash + kFix3HashSize)[h3] = pos;
+ (hash + kFix4HashSize)[hv] = pos;
maxLen = 0;
offset = 0;
@@ -615,7 +615,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
maxLen = 3;
- distances[offset + 1] = d3 - 1;
+ distances[(size_t)offset + 1] = d3 - 1;
offset += 2;
d2 = d3;
}
@@ -623,7 +623,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (offset != 0)
{
UPDATE_maxLen
- distances[offset - 2] = maxLen;
+ distances[(size_t)offset - 2] = maxLen;
if (maxLen == lenLimit)
{
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
@@ -650,15 +650,15 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
pos = p->pos;
d2 = pos - hash[ h2];
- d3 = pos - hash[kFix3HashSize + h3];
- d4 = pos - hash[kFix4HashSize + h4];
+ d3 = pos - (hash + kFix3HashSize)[h3];
+ d4 = pos - (hash + kFix4HashSize)[h4];
- curMatch = hash[kFix5HashSize + hv];
+ curMatch = (hash + kFix5HashSize)[hv];
hash[ h2] = pos;
- hash[kFix3HashSize + h3] = pos;
- hash[kFix4HashSize + h4] = pos;
- hash[kFix5HashSize + hv] = pos;
+ (hash + kFix3HashSize)[h3] = pos;
+ (hash + kFix4HashSize)[h4] = pos;
+ (hash + kFix5HashSize)[hv] = pos;
maxLen = 0;
offset = 0;
@@ -691,7 +691,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
&& *(cur - d4 + 3) == *(cur + 3))
{
maxLen = 4;
- distances[offset + 1] = d4 - 1;
+ distances[(size_t)offset + 1] = d4 - 1;
offset += 2;
d2 = d4;
}
@@ -699,7 +699,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (offset != 0)
{
UPDATE_maxLen
- distances[offset - 2] = maxLen;
+ distances[(size_t)offset - 2] = maxLen;
if (maxLen == lenLimit)
{
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
@@ -726,13 +726,13 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
pos = p->pos;
d2 = pos - hash[ h2];
- d3 = pos - hash[kFix3HashSize + h3];
+ d3 = pos - (hash + kFix3HashSize)[h3];
- curMatch = hash[kFix4HashSize + hv];
+ curMatch = (hash + kFix4HashSize)[hv];
hash[ h2] = pos;
- hash[kFix3HashSize + h3] = pos;
- hash[kFix4HashSize + hv] = pos;
+ (hash + kFix3HashSize)[h3] = pos;
+ (hash + kFix4HashSize)[hv] = pos;
maxLen = 0;
offset = 0;
@@ -747,7 +747,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
maxLen = 3;
- distances[offset + 1] = d3 - 1;
+ distances[(size_t)offset + 1] = d3 - 1;
offset += 2;
d2 = d3;
}
@@ -755,7 +755,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (offset != 0)
{
UPDATE_maxLen
- distances[offset - 2] = maxLen;
+ distances[(size_t)offset - 2] = maxLen;
if (maxLen == lenLimit)
{
p->son[p->cyclicBufferPos] = curMatch;
@@ -784,15 +784,15 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
pos = p->pos;
d2 = pos - hash[ h2];
- d3 = pos - hash[kFix3HashSize + h3];
- d4 = pos - hash[kFix4HashSize + h4];
+ d3 = pos - (hash + kFix3HashSize)[h3];
+ d4 = pos - (hash + kFix4HashSize)[h4];
- curMatch = hash[kFix5HashSize + hv];
+ curMatch = (hash + kFix5HashSize)[hv];
hash[ h2] = pos;
- hash[kFix3HashSize + h3] = pos;
- hash[kFix4HashSize + h4] = pos;
- hash[kFix5HashSize + hv] = pos;
+ (hash + kFix3HashSize)[h3] = pos;
+ (hash + kFix4HashSize)[h4] = pos;
+ (hash + kFix5HashSize)[hv] = pos;
maxLen = 0;
offset = 0;
@@ -825,7 +825,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
&& *(cur - d4 + 3) == *(cur + 3))
{
maxLen = 4;
- distances[offset + 1] = d4 - 1;
+ distances[(size_t)offset + 1] = d4 - 1;
offset += 2;
d2 = d4;
}
@@ -833,7 +833,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (offset != 0)
{
UPDATE_maxLen
- distances[offset - 2] = maxLen;
+ distances[(size_t)offset - 2] = maxLen;
if (maxLen == lenLimit)
{
p->son[p->cyclicBufferPos] = curMatch;
@@ -897,9 +897,9 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(3)
HASH3_CALC;
hash = p->hash;
- curMatch = hash[kFix3HashSize + hv];
+ curMatch = (hash + kFix3HashSize)[hv];
hash[h2] =
- hash[kFix3HashSize + hv] = p->pos;
+ (hash + kFix3HashSize)[hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
@@ -914,10 +914,10 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(4)
HASH4_CALC;
hash = p->hash;
- curMatch = hash[kFix4HashSize + hv];
+ curMatch = (hash + kFix4HashSize)[hv];
hash[ h2] =
- hash[kFix3HashSize + h3] =
- hash[kFix4HashSize + hv] = p->pos;
+ (hash + kFix3HashSize)[h3] =
+ (hash + kFix4HashSize)[hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
@@ -933,11 +933,11 @@ static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(5)
HASH5_CALC;
hash = p->hash;
- curMatch = hash[kFix5HashSize + hv];
+ curMatch = (hash + kFix5HashSize)[hv];
hash[ h2] =
- hash[kFix3HashSize + h3] =
- hash[kFix4HashSize + h4] =
- hash[kFix5HashSize + hv] = p->pos;
+ (hash + kFix3HashSize)[h3] =
+ (hash + kFix4HashSize)[h4] =
+ (hash + kFix5HashSize)[hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
@@ -953,10 +953,10 @@ static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(4)
HASH4_CALC;
hash = p->hash;
- curMatch = hash[kFix4HashSize + hv];
+ curMatch = (hash + kFix4HashSize)[hv];
hash[ h2] =
- hash[kFix3HashSize + h3] =
- hash[kFix4HashSize + hv] = p->pos;
+ (hash + kFix3HashSize)[h3] =
+ (hash + kFix4HashSize)[hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
@@ -973,11 +973,11 @@ static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(5)
HASH5_CALC;
hash = p->hash;
- curMatch = p->hash[kFix5HashSize + hv];
+ curMatch = hash + kFix5HashSize)[hv];
hash[ h2] =
- hash[kFix3HashSize + h3] =
- hash[kFix4HashSize + h4] =
- hash[kFix5HashSize + hv] = p->pos;
+ (hash + kFix3HashSize)[h3] =
+ (hash + kFix4HashSize)[h4] =
+ (hash + kFix5HashSize)[hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
diff --git a/C/LzFind.h b/C/LzFind.h
index d119944f..961c8095 100644
--- a/C/LzFind.h
+++ b/C/LzFind.h
@@ -1,5 +1,5 @@
/* LzFind.h -- Match finder for LZ algorithms
-2015-10-15 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H
#define __LZ_FIND_H
@@ -71,8 +71,8 @@ void MatchFinder_Construct(CMatchFinder *p);
*/
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
- ISzAlloc *alloc);
-void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
+ ISzAllocPtr alloc);
+void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
diff --git a/C/LzFindMt.c b/C/LzFindMt.c
index a4ffa5ef..ed2bd616 100644
--- a/C/LzFindMt.c
+++ b/C/LzFindMt.c
@@ -1,5 +1,5 @@
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
-2015-10-15 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -443,13 +443,13 @@ void MatchFinderMt_Construct(CMatchFinderMt *p)
MtSync_Construct(&p->btSync);
}
-static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
+static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAllocPtr alloc)
{
- alloc->Free(alloc, p->hashBuf);
+ ISzAlloc_Free(alloc, p->hashBuf);
p->hashBuf = NULL;
}
-void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc)
{
MtSync_Destruct(&p->hashSync);
MtSync_Destruct(&p->btSync);
@@ -472,7 +472,7 @@ static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
}
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
- UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc)
{
CMatchFinder *mf = p->MatchFinder;
p->historySize = historySize;
@@ -480,7 +480,7 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
return SZ_ERROR_PARAM;
if (!p->hashBuf)
{
- p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
+ p->hashBuf = (UInt32 *)ISzAlloc_Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
if (!p->hashBuf)
return SZ_ERROR_MEM;
p->btBuf = p->hashBuf + kHashBufferSize;
@@ -591,10 +591,10 @@ static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *dista
MT_HASH3_CALC
curMatch2 = hash[ h2];
- curMatch3 = hash[kFix3HashSize + h3];
+ curMatch3 = (hash + kFix3HashSize)[h3];
hash[ h2] = lzPos;
- hash[kFix3HashSize + h3] = lzPos;
+ (hash + kFix3HashSize)[h3] = lzPos;
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
{
@@ -627,12 +627,12 @@ static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distan
MT_HASH4_CALC
curMatch2 = hash[ h2];
- curMatch3 = hash[kFix3HashSize + h3];
- curMatch4 = hash[kFix4HashSize + h4];
+ curMatch3 = (hash + kFix3HashSize)[h3];
+ curMatch4 = (hash + kFix4HashSize)[h4];
hash[ h2] = lzPos;
- hash[kFix3HashSize + h3] = lzPos;
- hash[kFix4HashSize + h4] = lzPos;
+ (hash + kFix3HashSize)[h3] = lzPos;
+ (hash + kFix4HashSize)[h4] = lzPos;
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
{
@@ -746,7 +746,7 @@ static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
SKIP_HEADER_MT(3)
UInt32 h2, h3;
MT_HASH3_CALC
- hash[kFix3HashSize + h3] =
+ (hash + kFix3HashSize)[h3] =
hash[ h2] =
p->lzPos;
SKIP_FOOTER_MT
@@ -758,8 +758,8 @@ static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
SKIP_HEADER_MT(4)
UInt32 h2, h3, h4;
MT_HASH4_CALC
- hash[kFix4HashSize + h4] =
- hash[kFix3HashSize + h3] =
+ (hash + kFix4HashSize)[h4] =
+ (hash + kFix3HashSize)[h3] =
hash[ h2] =
p->lzPos;
SKIP_FOOTER_MT
diff --git a/C/LzFindMt.h b/C/LzFindMt.h
index 89b91fef..a6645f53 100644
--- a/C/LzFindMt.h
+++ b/C/LzFindMt.h
@@ -1,5 +1,5 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
-2015-05-03 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_MT_H
#define __LZ_FIND_MT_H
@@ -90,9 +90,9 @@ typedef struct _CMatchFinderMt
} CMatchFinderMt;
void MatchFinderMt_Construct(CMatchFinderMt *p);
-void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc);
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
- UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc);
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
diff --git a/C/Lzma2Dec.c b/C/Lzma2Dec.c
index b84f88a4..63853c6d 100644
--- a/C/Lzma2Dec.c
+++ b/C/Lzma2Dec.c
@@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder
-2015-11-09 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
@@ -74,14 +74,14 @@ static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
return SZ_OK;
}
-SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
+SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
{
Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
}
-SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
+SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
{
Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props));
@@ -105,16 +105,16 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
p->control = b;
PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
PRF(printf(" %2X", (unsigned)b));
- if (p->control == 0)
+ if (b == 0)
return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
- if ((p->control & 0x7F) > 2)
+ if (b > 2)
return LZMA2_STATE_ERROR;
p->unpackSize = 0;
}
else
- p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
+ p->unpackSize = (UInt32)(b & 0x1F) << 16;
return LZMA2_STATE_UNPACK0;
case LZMA2_STATE_UNPACK0:
@@ -169,6 +169,7 @@ static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT s
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
+
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
@@ -176,12 +177,17 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
*srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
- while (p->state != LZMA2_STATE_FINISHED)
+ while (p->state != LZMA2_STATE_ERROR)
{
- SizeT dicPos = p->decoder.dicPos;
+ SizeT dicPos;
+
+ if (p->state == LZMA2_STATE_FINISHED)
+ {
+ *status = LZMA_STATUS_FINISHED_WITH_MARK;
+ return SZ_OK;
+ }
- if (p->state == LZMA2_STATE_ERROR)
- return SZ_ERROR_DATA;
+ dicPos = p->decoder.dicPos;
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{
@@ -198,29 +204,25 @@ 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;
- }
+ break;
continue;
}
{
- SizeT destSizeCur = dicLimit - dicPos;
- SizeT srcSizeCur = inSize - *srcLen;
+ SizeT inCur = inSize - *srcLen;
+ SizeT outCur = dicLimit - dicPos;
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
- if (p->unpackSize <= destSizeCur)
+ if (outCur >= p->unpackSize)
{
- destSizeCur = (SizeT)p->unpackSize;
+ outCur = (SizeT)p->unpackSize;
curFinishMode = LZMA_FINISH_END;
}
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
- if (*srcLen == inSize)
+ if (inCur == 0)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
@@ -232,33 +234,25 @@ 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;
- }
+ break;
p->needInitDic = False;
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
}
- if (srcSizeCur > destSizeCur)
- srcSizeCur = destSizeCur;
-
- if (srcSizeCur == 0)
- {
- p->state = LZMA2_STATE_ERROR;
- return SZ_ERROR_DATA;
- }
+ if (inCur > outCur)
+ inCur = outCur;
+ if (inCur == 0)
+ break;
- LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
+ LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
- src += srcSizeCur;
- *srcLen += srcSizeCur;
- p->unpackSize -= (UInt32)srcSizeCur;
+ src += inCur;
+ *srcLen += inCur;
+ p->unpackSize -= (UInt32)inCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
}
else
{
- SizeT outSizeProcessed;
SRes res;
if (p->state == LZMA2_STATE_DATA)
@@ -267,96 +261,98 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
Bool initDic = (mode == 3);
Bool initState = (mode != 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
- {
- p->state = LZMA2_STATE_ERROR;
- return SZ_ERROR_DATA;
- }
-
+ break;
+
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;
+ if (inCur > p->packSize)
+ inCur = (SizeT)p->packSize;
- res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
+ res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
+
+ src += inCur;
+ *srcLen += inCur;
+ p->packSize -= (UInt32)inCur;
+ outCur = p->decoder.dicPos - dicPos;
+ p->unpackSize -= (UInt32)outCur;
+
+ if (res != 0)
+ break;
- src += srcSizeCur;
- *srcLen += srcSizeCur;
- p->packSize -= (UInt32)srcSizeCur;
-
- outSizeProcessed = p->decoder.dicPos - dicPos;
- p->unpackSize -= (UInt32)outSizeProcessed;
-
- RINOK(res);
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
- return res;
+ {
+ if (p->packSize == 0)
+ break;
+ return SZ_OK;
+ }
- if (srcSizeCur == 0 && outSizeProcessed == 0)
+ if (inCur == 0 && outCur == 0)
{
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|| p->unpackSize != 0
|| p->packSize != 0)
- {
- p->state = LZMA2_STATE_ERROR;
- return SZ_ERROR_DATA;
- }
+ break;
p->state = LZMA2_STATE_CONTROL;
}
- if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
- *status = LZMA_STATUS_NOT_FINISHED;
+ *status = LZMA_STATUS_NOT_SPECIFIED;
}
}
}
- *status = LZMA_STATUS_FINISHED_WITH_MARK;
- return SZ_OK;
+ *status = LZMA_STATUS_NOT_SPECIFIED;
+ p->state = LZMA2_STATE_ERROR;
+ return SZ_ERROR_DATA;
}
+
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT outSize = *destLen, inSize = *srcLen;
*srcLen = *destLen = 0;
+
for (;;)
{
- SizeT srcSizeCur = inSize, outSizeCur, dicPos;
+ SizeT inCur = inSize, outCur, dicPos;
ELzmaFinishMode curFinishMode;
SRes res;
+
if (p->decoder.dicPos == p->decoder.dicBufSize)
p->decoder.dicPos = 0;
dicPos = p->decoder.dicPos;
- if (outSize > p->decoder.dicBufSize - dicPos)
- {
- outSizeCur = p->decoder.dicBufSize;
- curFinishMode = LZMA_FINISH_ANY;
- }
- else
+ curFinishMode = LZMA_FINISH_ANY;
+ outCur = p->decoder.dicBufSize - dicPos;
+
+ if (outCur >= outSize)
{
- outSizeCur = dicPos + outSize;
+ outCur = outSize;
curFinishMode = finishMode;
}
- res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
- src += srcSizeCur;
- inSize -= srcSizeCur;
- *srcLen += srcSizeCur;
- outSizeCur = p->decoder.dicPos - dicPos;
- memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
- dest += outSizeCur;
- outSize -= outSizeCur;
- *destLen += outSizeCur;
+ res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
+
+ src += inCur;
+ inSize -= inCur;
+ *srcLen += inCur;
+ outCur = p->decoder.dicPos - dicPos;
+ memcpy(dest, p->decoder.dic + dicPos, outCur);
+ dest += outCur;
+ outSize -= outCur;
+ *destLen += outCur;
if (res != 0)
return res;
- if (outSizeCur == 0 || outSize == 0)
+ if (outCur == 0 || outSize == 0)
return SZ_OK;
}
}
+
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
- Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
+ Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
{
CLzma2Dec p;
SRes res;
diff --git a/C/Lzma2Dec.h b/C/Lzma2Dec.h
index e6a0f6ed..917af990 100644
--- a/C/Lzma2Dec.h
+++ b/C/Lzma2Dec.h
@@ -1,5 +1,5 @@
/* Lzma2Dec.h -- LZMA2 Decoder
-2015-05-13 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H
@@ -26,8 +26,8 @@ typedef struct
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
-SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
-SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
+SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
+SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
void Lzma2Dec_Init(CLzma2Dec *p);
@@ -73,7 +73,7 @@ Returns:
*/
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
- Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
+ Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc);
EXTERN_C_END
diff --git a/C/Lzma2Enc.c b/C/Lzma2Enc.c
index 1b77a2bb..a3f72c68 100644
--- a/C/Lzma2Enc.c
+++ b/C/Lzma2Enc.c
@@ -1,5 +1,5 @@
/* Lzma2Enc.c -- LZMA2 Encoder
-2015-10-04 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -60,9 +60,9 @@ static SRes Lzma2EncInt_Init(CLzma2EncInt *p, const CLzma2EncProps *props)
}
SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize,
- ISzAlloc *alloc, ISzAlloc *allocBig);
+ ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
- UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig);
+ UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize);
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp);
@@ -126,7 +126,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
if (outStream)
{
*packSizeRes += destPos;
- if (outStream->Write(outStream, outBuf, destPos) != destPos)
+ if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos)
return SZ_ERROR_WRITE;
destPos = 0;
}
@@ -162,7 +162,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
p->srcPos += unpackSize;
if (outStream)
- if (outStream->Write(outStream, outBuf, destPos) != destPos)
+ if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos)
return SZ_ERROR_WRITE;
*packSizeRes = destPos;
@@ -264,7 +264,7 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
{
- return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
+ return (p && ICompressProgress_Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
}
@@ -277,8 +277,8 @@ typedef struct
Byte *outBuf;
- ISzAlloc *alloc;
- ISzAlloc *allocBig;
+ ISzAllocPtr alloc;
+ ISzAllocPtr allocBig;
CLzma2EncInt coders[NUM_MT_CODER_THREADS_MAX];
@@ -299,7 +299,7 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
if (!mainEncoder->outBuf)
{
- mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
+ mainEncoder->outBuf = (Byte *)ISzAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
if (!mainEncoder->outBuf)
return SZ_ERROR_MEM;
}
@@ -327,7 +327,7 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
if (res == SZ_OK)
{
Byte b = 0;
- if (outStream->Write(outStream, &b, 1) != 1)
+ if (ISeqOutStream_Write(outStream, &b, 1) != 1)
return SZ_ERROR_WRITE;
}
@@ -343,10 +343,10 @@ typedef struct
CLzma2Enc *lzma2Enc;
} CMtCallbackImp;
-static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *destSize,
+static SRes MtCallbackImp_Code(const IMtCoderCallback *pp, unsigned index, Byte *dest, size_t *destSize,
const Byte *src, size_t srcSize, int finished)
{
- CMtCallbackImp *imp = (CMtCallbackImp *)pp;
+ CMtCallbackImp *imp = CONTAINER_FROM_VTBL(pp, CMtCallbackImp, funcTable);
CLzma2Enc *mainEncoder = imp->lzma2Enc;
CLzma2EncInt *p = &mainEncoder->coders[index];
@@ -403,9 +403,9 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des
/* ---------- Lzma2Enc ---------- */
-CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
+CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
- CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc));
+ CLzma2Enc *p = (CLzma2Enc *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Enc));
if (!p)
return NULL;
Lzma2EncProps_Init(&p->props);
@@ -444,8 +444,8 @@ void Lzma2Enc_Destroy(CLzma2EncHandle pp)
MtCoder_Destruct(&p->mtCoder);
#endif
- IAlloc_Free(p->alloc, p->outBuf);
- IAlloc_Free(p->alloc, pp);
+ ISzAlloc_Free(p->alloc, p->outBuf);
+ ISzAlloc_Free(p->alloc, pp);
}
SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props)
diff --git a/C/Lzma2Enc.h b/C/Lzma2Enc.h
index f409f184..760f0633 100644
--- a/C/Lzma2Enc.h
+++ b/C/Lzma2Enc.h
@@ -1,5 +1,5 @@
/* Lzma2Enc.h -- LZMA2 Encoder
-2013-01-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __LZMA2_ENC_H
#define __LZMA2_ENC_H
@@ -33,7 +33,7 @@ Returns:
typedef void * CLzma2EncHandle;
-CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig);
+CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig);
void Lzma2Enc_Destroy(CLzma2EncHandle p);
SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props);
Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p);
@@ -54,7 +54,7 @@ Return code:
/*
SRes Lzma2Encode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, int writeEndMark,
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+ ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
*/
EXTERN_C_END
diff --git a/C/LzmaDec.c b/C/LzmaDec.c
index 12dce11f..e96fa975 100644
--- a/C/LzmaDec.c
+++ b/C/LzmaDec.c
@@ -1,5 +1,5 @@
/* LzmaDec.c -- LZMA Decoder
-2016-05-16 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -975,19 +975,19 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
}
}
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc)
{
- alloc->Free(alloc, p->probs);
+ ISzAlloc_Free(alloc, p->probs);
p->probs = NULL;
}
-static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc)
{
- alloc->Free(alloc, p->dic);
+ ISzAlloc_Free(alloc, p->dic);
p->dic = NULL;
}
-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
+void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc)
{
LzmaDec_FreeProbs(p, alloc);
LzmaDec_FreeDict(p, alloc);
@@ -1019,13 +1019,13 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
return SZ_OK;
}
-static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc)
{
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
if (!p->probs || numProbs != p->numProbs)
{
LzmaDec_FreeProbs(p, alloc);
- p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
+ p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs;
if (!p->probs)
return SZ_ERROR_MEM;
@@ -1033,7 +1033,7 @@ static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAl
return SZ_OK;
}
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
{
CLzmaProps propNew;
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
@@ -1042,7 +1042,7 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, I
return SZ_OK;
}
-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
{
CLzmaProps propNew;
SizeT dicBufSize;
@@ -1062,7 +1062,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
if (!p->dic || dicBufSize != p->dicBufSize)
{
LzmaDec_FreeDict(p, alloc);
- p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
+ p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize);
if (!p->dic)
{
LzmaDec_FreeProbs(p, alloc);
@@ -1076,7 +1076,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
- ELzmaStatus *status, ISzAlloc *alloc)
+ ELzmaStatus *status, ISzAllocPtr alloc)
{
CLzmaDec p;
SRes res;
diff --git a/C/LzmaDec.h b/C/LzmaDec.h
index cc44daef..d6af9220 100644
--- a/C/LzmaDec.h
+++ b/C/LzmaDec.h
@@ -1,5 +1,5 @@
/* LzmaDec.h -- LZMA Decoder
-2013-01-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H
#define __LZMA_DEC_H
@@ -129,11 +129,11 @@ LzmaDec_Allocate* can return:
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
-SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
-void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAllocPtr alloc);
+void LzmaDec_Free(CLzmaDec *state, ISzAllocPtr alloc);
/* ---------- Dictionary Interface ---------- */
@@ -220,7 +220,7 @@ Returns:
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
- ELzmaStatus *status, ISzAlloc *alloc);
+ ELzmaStatus *status, ISzAllocPtr alloc);
EXTERN_C_END
diff --git a/C/LzmaEnc.c b/C/LzmaEnc.c
index 70df4569..3e829468 100644
--- a/C/LzmaEnc.c
+++ b/C/LzmaEnc.c
@@ -1,5 +1,5 @@
/* LzmaEnc.c -- LZMA Encoder
-2016-05-16 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -512,11 +512,11 @@ static void RangeEnc_Construct(CRangeEnc *p)
#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
#define RC_BUF_SIZE (1 << 16)
-static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
+static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc)
{
if (!p->bufBase)
{
- p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
+ p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE);
if (!p->bufBase)
return 0;
p->bufLim = p->bufBase + RC_BUF_SIZE;
@@ -524,9 +524,9 @@ static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
return 1;
}
-static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
+static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc)
{
- alloc->Free(alloc, p->bufBase);
+ ISzAlloc_Free(alloc, p->bufBase);
p->bufBase = 0;
}
@@ -550,7 +550,7 @@ static void RangeEnc_FlushStream(CRangeEnc *p)
if (p->res != SZ_OK)
return;
num = p->buf - p->bufBase;
- if (num != p->outStream->Write(p->outStream, p->bufBase, num))
+ if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num))
p->res = SZ_ERROR_WRITE;
p->processed += num;
p->buf = p->bufBase;
@@ -882,7 +882,7 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
if (numPairs > 0)
{
- lenRes = p->matches[numPairs - 2];
+ lenRes = p->matches[(size_t)numPairs - 2];
if (lenRes == p->numFastBytes)
{
UInt32 numAvail = p->numAvail;
@@ -891,7 +891,7 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
{
const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
const Byte *pby = pbyCur + lenRes;
- ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1];
+ ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[(size_t)numPairs - 1];
const Byte *pbyLim = pbyCur + numAvail;
for (; pby != pbyLim && *pby == pby[dif]; pby++);
lenRes = (UInt32)(pby - pbyCur);
@@ -939,7 +939,7 @@ static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32
static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
{
- return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
+ return p->repLenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN] +
GetPureRepPrice(p, repIndex, state, posState);
}
@@ -956,9 +956,9 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
p->opt[posMem].posPrev = posMem - 1;
if (p->opt[cur].prev2)
{
- p->opt[posMem - 1].prev1IsChar = False;
- p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
- p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
+ p->opt[(size_t)posMem - 1].prev1IsChar = False;
+ p->opt[(size_t)posMem - 1].posPrev = p->opt[cur].posPrev2;
+ p->opt[(size_t)posMem - 1].backPrev = p->opt[cur].backPrev2;
}
}
{
@@ -1051,7 +1051,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
matches = p->matches;
if (mainLen >= p->numFastBytes)
{
- *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
+ *backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
MovePos(p, mainLen - 1);
return mainLen;
}
@@ -1116,7 +1116,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
do
{
- UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][(size_t)repLen - 2];
COptimal *opt = &p->opt[repLen];
if (curAndLenPrice < opt->price)
{
@@ -1140,9 +1140,9 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
for (; ; len++)
{
COptimal *opt;
- UInt32 distance = matches[offs + 1];
+ UInt32 distance = matches[(size_t)offs + 1];
- UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN];
UInt32 lenToPosState = GetLenToPosState(len);
if (distance < kNumFullDistances)
curAndLenPrice += p->distancesPrices[lenToPosState][distance];
@@ -1256,7 +1256,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 i;
reps[0] = prevOpt->backs[pos];
for (i = 1; i <= pos; i++)
- reps[i] = prevOpt->backs[i - 1];
+ reps[i] = prevOpt->backs[(size_t)i - 1];
for (; i < LZMA_NUM_REPS; i++)
reps[i] = prevOpt->backs[i];
}
@@ -1265,7 +1265,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 i;
reps[0] = (pos - LZMA_NUM_REPS);
for (i = 1; i < LZMA_NUM_REPS; i++)
- reps[i] = prevOpt->backs[i - 1];
+ reps[i] = prevOpt->backs[(size_t)i - 1];
}
}
curOpt->state = (CState)state;
@@ -1292,7 +1292,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
LitEnc_GetPrice(probs, curByte, p->ProbPrices));
}
- nextOpt = &p->opt[cur + 1];
+ nextOpt = &p->opt[(size_t)cur + 1];
if (curAnd1Price < nextOpt->price)
{
@@ -1385,7 +1385,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
do
{
- UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][(size_t)lenTest - 2];
COptimal *opt = &p->opt[cur + lenTest];
if (curAndLenPrice < opt->price)
{
@@ -1415,9 +1415,9 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 state2 = kRepNextStates[state];
UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice =
- price + p->repLenEnc.prices[posState][lenTest - 2] +
+ price + p->repLenEnc.prices[posState][(size_t)lenTest - 2] +
GET_PRICE_0(p->isMatch[state2][posStateNext]) +
- LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[(size_t)lenTest - 1]),
data[lenTest], data2[lenTest], p->ProbPrices);
state2 = kLiteralNextStates[state2];
posStateNext = (position + lenTest + 1) & p->pbMask;
@@ -1468,11 +1468,11 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
offs = 0;
while (startLen > matches[offs])
offs += 2;
- curBack = matches[offs + 1];
+ curBack = matches[(size_t)offs + 1];
GetPosSlot2(curBack, posSlot);
for (lenTest = /*2*/ startLen; ; lenTest++)
{
- UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][(size_t)lenTest - LZMA_MATCH_LEN_MIN];
{
UInt32 lenToPosState = GetLenToPosState(lenTest);
COptimal *opt;
@@ -1508,7 +1508,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice = curAndLenPrice +
GET_PRICE_0(p->isMatch[state2][posStateNext]) +
- LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[(size_t)lenTest - 1]),
data[lenTest], data2[lenTest], p->ProbPrices);
state2 = kLiteralNextStates[state2];
posStateNext = (posStateNext + 1) & p->pbMask;
@@ -1540,7 +1540,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
offs += 2;
if (offs == numPairs)
break;
- curBack = matches[offs + 1];
+ curBack = matches[(size_t)offs + 1];
if (curBack >= kNumFullDistances)
GetPosSlot2(curBack, posSlot);
}
@@ -1597,7 +1597,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
matches = p->matches;
if (mainLen >= p->numFastBytes)
{
- *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
+ *backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
MovePos(p, mainLen - 1);
return mainLen;
}
@@ -1605,14 +1605,14 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
mainDist = 0; /* for GCC */
if (mainLen >= 2)
{
- mainDist = matches[numPairs - 1];
- while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
+ mainDist = matches[(size_t)numPairs - 1];
+ while (numPairs > 2 && mainLen == matches[(size_t)numPairs - 4] + 1)
{
- if (!ChangePair(matches[numPairs - 3], mainDist))
+ if (!ChangePair(matches[(size_t)numPairs - 3], mainDist))
break;
numPairs -= 2;
- mainLen = matches[numPairs - 2];
- mainDist = matches[numPairs - 1];
+ mainLen = matches[(size_t)numPairs - 2];
+ mainDist = matches[(size_t)numPairs - 1];
}
if (mainLen == 2 && mainDist >= 0x80)
mainLen = 1;
@@ -1634,7 +1634,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
if (p->longestMatchLength >= 2)
{
- UInt32 newDistance = matches[p->numPairs - 1];
+ UInt32 newDistance = matches[(size_t)p->numPairs - 1];
if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
(p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
(p->longestMatchLength > mainLen + 1) ||
@@ -1762,24 +1762,24 @@ void LzmaEnc_Construct(CLzmaEnc *p)
p->saveState.litProbs = NULL;
}
-CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
+CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)
{
void *p;
- p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
+ p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc));
if (p)
LzmaEnc_Construct((CLzmaEnc *)p);
return p;
}
-void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc)
{
- alloc->Free(alloc, p->litProbs);
- alloc->Free(alloc, p->saveState.litProbs);
+ ISzAlloc_Free(alloc, p->litProbs);
+ ISzAlloc_Free(alloc, p->saveState.litProbs);
p->litProbs = NULL;
p->saveState.litProbs = NULL;
}
-void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
#ifndef _7ZIP_ST
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
@@ -1790,10 +1790,10 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
RangeEnc_Free(&p->rc, alloc);
}
-void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
- alloc->Free(alloc, p);
+ ISzAlloc_Free(alloc, p);
}
static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
@@ -1960,7 +1960,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
#define kBigHashDicLimit ((UInt32)1 << 24)
-static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
UInt32 beforeSize = kNumOpts;
if (!RangeEnc_Alloc(&p->rc, alloc))
@@ -1975,8 +1975,8 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
{
LzmaEnc_FreeLits(p, alloc);
- p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
- p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
+ p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
+ p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
if (!p->litProbs || !p->saveState.litProbs)
{
LzmaEnc_FreeLits(p, alloc);
@@ -2084,7 +2084,7 @@ void LzmaEnc_InitPrices(CLzmaEnc *p)
LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
}
-static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
UInt32 i;
for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
@@ -2102,7 +2102,7 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *a
}
static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
- ISzAlloc *alloc, ISzAlloc *allocBig)
+ ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
p->matchFinderBase.stream = inStream;
@@ -2113,7 +2113,7 @@ static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInS
SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
ISeqInStream *inStream, UInt32 keepWindowSize,
- ISzAlloc *alloc, ISzAlloc *allocBig)
+ ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
p->matchFinderBase.stream = inStream;
@@ -2129,7 +2129,7 @@ static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
}
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
- UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+ UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
LzmaEnc_SetInputBuf(p, src, srcLen);
@@ -2158,9 +2158,9 @@ typedef struct
Bool overflow;
} CSeqOutStreamBuf;
-static size_t MyWrite(void *pp, const void *data, size_t size)
+static size_t MyWrite(const ISeqOutStream *pp, const void *data, size_t size)
{
- CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
+ CSeqOutStreamBuf *p = CONTAINER_FROM_VTBL(pp, CSeqOutStreamBuf, funcTable);
if (p->rem < size)
{
size = p->rem;
@@ -2239,7 +2239,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
break;
if (progress)
{
- res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
+ res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
if (res != SZ_OK)
{
res = SZ_ERROR_PROGRESS;
@@ -2251,7 +2251,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
LzmaEnc_Finish(p);
/*
- if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
+ if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
res = SZ_ERROR_FAIL;
}
*/
@@ -2261,7 +2261,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
- ISzAlloc *alloc, ISzAlloc *allocBig)
+ ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
@@ -2296,8 +2296,14 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
}
+unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle pp)
+{
+ return ((CLzmaEnc *)pp)->writeEndMark;
+}
+
+
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
- int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
+ int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
SRes res;
CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -2330,7 +2336,7 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
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)
+ ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
SRes res;
diff --git a/C/LzmaEnc.h b/C/LzmaEnc.h
index cffe220b..967f802c 100644
--- a/C/LzmaEnc.h
+++ b/C/LzmaEnc.h
@@ -1,5 +1,5 @@
/* LzmaEnc.h -- LZMA Encoder
-2013-01-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __LZMA_ENC_H
#define __LZMA_ENC_H
@@ -49,14 +49,15 @@ Returns:
typedef void * CLzmaEncHandle;
-CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
-void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
+CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc);
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
+unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p);
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+ ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
- int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+ int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
/* ---------- One Call Interface ---------- */
@@ -71,7 +72,7 @@ Return code:
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);
+ ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
EXTERN_C_END
diff --git a/C/MtCoder.c b/C/MtCoder.c
index 8d9731d0..85c99e0a 100644
--- a/C/MtCoder.c
+++ b/C/MtCoder.c
@@ -1,5 +1,5 @@
/* MtCoder.c -- Multi-thread Coder
-2015-10-13 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -55,7 +55,7 @@ WRes LoopThread_WaitSubThread(CLoopThread *p) { return Event_Wait(&p->finishedEv
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
{
- return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
+ return (p && ICompressProgress_Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
}
static void MtProgress_Init(CMtProgress *p, ICompressProgress *progress)
@@ -137,18 +137,18 @@ static void CMtThread_Destruct(CMtThread *p)
}
if (p->mtCoder->alloc)
- IAlloc_Free(p->mtCoder->alloc, p->outBuf);
+ ISzAlloc_Free(p->mtCoder->alloc, p->outBuf);
p->outBuf = 0;
if (p->mtCoder->alloc)
- IAlloc_Free(p->mtCoder->alloc, p->inBuf);
+ ISzAlloc_Free(p->mtCoder->alloc, p->inBuf);
p->inBuf = 0;
}
#define MY_BUF_ALLOC(buf, size, newSize) \
if (buf == 0 || size != newSize) \
- { IAlloc_Free(p->mtCoder->alloc, buf); \
- size = newSize; buf = (Byte *)IAlloc_Alloc(p->mtCoder->alloc, size); \
+ { ISzAlloc_Free(p->mtCoder->alloc, buf); \
+ size = newSize; buf = (Byte *)ISzAlloc_Alloc(p->mtCoder->alloc, size); \
if (buf == 0) return SZ_ERROR_MEM; }
static SRes CMtThread_Prepare(CMtThread *p)
@@ -171,7 +171,7 @@ static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize)
while (size != 0)
{
size_t curSize = size;
- SRes res = stream->Read(stream, data, &curSize);
+ SRes res = ISeqInStream_Read(stream, data, &curSize);
*processedSize += curSize;
data += curSize;
size -= curSize;
@@ -208,7 +208,7 @@ static SRes MtThread_Process(CMtThread *p, Bool *stop)
if (Event_Set(&next->canRead) != 0)
return SZ_ERROR_THREAD;
- RINOK(p->mtCoder->mtCallback->Code(p->mtCoder->mtCallback, p->index,
+ RINOK(IMtCoderCallback_Code(p->mtCoder->mtCallback, p->index,
p->outBuf, &destSize, p->inBuf, size, *stop));
MtProgress_Reinit(&p->mtCoder->mtProgress, p->index);
@@ -217,7 +217,7 @@ static SRes MtThread_Process(CMtThread *p, Bool *stop)
return SZ_ERROR_THREAD;
if (p->stopWriting)
return SZ_ERROR_FAIL;
- if (p->mtCoder->outStream->Write(p->mtCoder->outStream, p->outBuf, destSize) != destSize)
+ if (ISeqOutStream_Write(p->mtCoder->outStream, p->outBuf, destSize) != destSize)
return SZ_ERROR_WRITE;
return Event_Set(&next->canWrite) == 0 ? SZ_OK : SZ_ERROR_THREAD;
}
diff --git a/C/MtCoder.h b/C/MtCoder.h
index f0f06da2..7d7e207f 100644
--- a/C/MtCoder.h
+++ b/C/MtCoder.h
@@ -1,5 +1,5 @@
/* MtCoder.h -- Multi-thread Coder
-2009-11-19 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __MT_CODER_H
#define __MT_CODER_H
@@ -64,11 +64,15 @@ typedef struct
CAutoResetEvent canWrite;
} CMtThread;
-typedef struct
+
+typedef struct IMtCoderCallback IMtCoderCallback;
+struct IMtCoderCallback
{
- SRes (*Code)(void *p, unsigned index, Byte *dest, size_t *destSize,
+ SRes (*Code)(const IMtCoderCallback *p, unsigned index, Byte *dest, size_t *destSize,
const Byte *src, size_t srcSize, int finished);
-} IMtCoderCallback;
+};
+#define IMtCoderCallback_Code(p, index, dest, destSize, src, srcSize, finished) (p)->Code(p, index, dest, destSize, src, srcSize, finished)
+
typedef struct _CMtCoder
{
@@ -79,7 +83,7 @@ typedef struct _CMtCoder
ISeqInStream *inStream;
ISeqOutStream *outStream;
ICompressProgress *progress;
- ISzAlloc *alloc;
+ ISzAllocPtr alloc;
IMtCoderCallback *mtCallback;
CCriticalSection cs;
diff --git a/C/Ppmd.h b/C/Ppmd.h
index 5655b26d..a5c1e3ef 100644
--- a/C/Ppmd.h
+++ b/C/Ppmd.h
@@ -1,5 +1,5 @@
/* Ppmd.h -- PPMD codec common code
-2016-05-16 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H
@@ -77,7 +77,7 @@ typedef
CPpmd_Byte_Ref;
#define PPMD_SetAllBitsIn256Bytes(p) \
- { unsigned z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
+ { size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
EXTERN_C_END
diff --git a/C/Ppmd7.c b/C/Ppmd7.c
index eda8eb70..0951a7c7 100644
--- a/C/Ppmd7.c
+++ b/C/Ppmd7.c
@@ -1,5 +1,5 @@
/* Ppmd7.c -- PPMdH codec
-2016-05-21 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h"
@@ -15,7 +15,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x
#define UNIT_SIZE 12
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
-#define U2I(nu) (p->Units2Indx[(nu) - 1])
+#define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1])
#define I2U(indx) (p->Indx2Units[indx])
#ifdef PPMD_32BIT
@@ -88,29 +88,31 @@ void Ppmd7_Construct(CPpmd7 *p)
memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
}
-void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
+void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc)
{
- alloc->Free(alloc, p->Base);
+ ISzAlloc_Free(alloc, p->Base);
p->Size = 0;
p->Base = 0;
}
-Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
+Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc)
{
- if (p->Base == 0 || p->Size != size)
+ if (!p->Base || p->Size != size)
{
+ size_t size2;
Ppmd7_Free(p, alloc);
+ size2 = 0
+ #ifndef PPMD_32BIT
+ + UNIT_SIZE
+ #endif
+ ;
p->AlignOffset =
#ifdef PPMD_32BIT
(4 - size) & 3;
#else
4 - (size & 3);
#endif
- if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
- #ifndef PPMD_32BIT
- + UNIT_SIZE
- #endif
- )) == 0)
+ if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size + size2)) == 0)
return False;
p->Size = size;
}
@@ -513,7 +515,7 @@ static void UpdateModel(CPpmd7 *p)
/* Expand for one UNIT */
unsigned oldNU = ns1 >> 1;
unsigned i = U2I(oldNU);
- if (i != U2I(oldNU + 1))
+ if (i != U2I((size_t)oldNU + 1))
{
void *ptr = AllocUnits(p, i + 1);
void *oldPtr;
@@ -639,7 +641,7 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
unsigned nonMasked = p->MinContext->NumStats - numMasked;
if (p->MinContext->NumStats != 256)
{
- see = p->See[(unsigned)p->NS2Indx[nonMasked - 1]] +
+ see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]] +
(nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
4 * (unsigned)(numMasked > nonMasked) +
diff --git a/C/Ppmd7.h b/C/Ppmd7.h
index 87eefde8..45002d95 100644
--- a/C/Ppmd7.h
+++ b/C/Ppmd7.h
@@ -1,5 +1,5 @@
/* Ppmd7.h -- PPMdH compression codec
-2016-05-21 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
/* This code supports virtual RangeDecoder and includes the implementation
@@ -60,8 +60,8 @@ typedef struct
} CPpmd7;
void Ppmd7_Construct(CPpmd7 *p);
-Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
-void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc);
+Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc);
+void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc);
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
@@ -86,8 +86,8 @@ void Ppmd7_Update2(CPpmd7 *p);
void Ppmd7_UpdateBin(CPpmd7 *p);
#define Ppmd7_GetBinSumm(p) \
- &p->BinSumm[(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
- p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
+ &p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
+ p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \
((p->RunLength >> 26) & 0x20)]
@@ -97,16 +97,18 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
/* ---------- Decode ---------- */
-typedef struct
+typedef struct IPpmd7_RangeDec IPpmd7_RangeDec;
+
+struct IPpmd7_RangeDec
{
- UInt32 (*GetThreshold)(void *p, UInt32 total);
- void (*Decode)(void *p, UInt32 start, UInt32 size);
- UInt32 (*DecodeBit)(void *p, UInt32 size0);
-} IPpmd7_RangeDec;
+ UInt32 (*GetThreshold)(const IPpmd7_RangeDec *p, UInt32 total);
+ void (*Decode)(const IPpmd7_RangeDec *p, UInt32 start, UInt32 size);
+ UInt32 (*DecodeBit)(const IPpmd7_RangeDec *p, UInt32 size0);
+};
typedef struct
{
- IPpmd7_RangeDec p;
+ IPpmd7_RangeDec vt;
UInt32 Range;
UInt32 Code;
IByteIn *Stream;
@@ -116,7 +118,7 @@ void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
-int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);
+int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc);
/* ---------- Encode ---------- */
diff --git a/C/Ppmd7Dec.c b/C/Ppmd7Dec.c
index 04b4b09e..7953bb07 100644
--- a/C/Ppmd7Dec.c
+++ b/C/Ppmd7Dec.c
@@ -1,5 +1,5 @@
/* Ppmd7Dec.c -- PPMdH Decoder
-2010-03-12 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h"
@@ -13,44 +13,46 @@ Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
unsigned i;
p->Code = 0;
p->Range = 0xFFFFFFFF;
- if (p->Stream->Read((void *)p->Stream) != 0)
+ if (IByteIn_Read(p->Stream) != 0)
return False;
for (i = 0; i < 4; i++)
- p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+ p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
return (p->Code < 0xFFFFFFFF);
}
-static UInt32 Range_GetThreshold(void *pp, UInt32 total)
+#define GET_Ppmd7z_RangeDec CPpmd7z_RangeDec *p = CONTAINER_FROM_VTBL(pp, CPpmd7z_RangeDec, vt);
+
+static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total)
{
- CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
- return (p->Code) / (p->Range /= total);
+ GET_Ppmd7z_RangeDec
+ return p->Code / (p->Range /= total);
}
static void Range_Normalize(CPpmd7z_RangeDec *p)
{
if (p->Range < kTopValue)
{
- p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+ p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
p->Range <<= 8;
if (p->Range < kTopValue)
{
- p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+ p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
p->Range <<= 8;
}
}
}
-static void Range_Decode(void *pp, UInt32 start, UInt32 size)
+static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size)
{
- CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+ GET_Ppmd7z_RangeDec
p->Code -= start * p->Range;
p->Range *= size;
Range_Normalize(p);
}
-static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
+static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0)
{
- CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+ GET_Ppmd7z_RangeDec
UInt32 newBound = (p->Range >> 14) * size0;
UInt32 symbol;
if (p->Code < newBound)
@@ -70,15 +72,15 @@ static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
{
- p->p.GetThreshold = Range_GetThreshold;
- p->p.Decode = Range_Decode;
- p->p.DecodeBit = Range_DecodeBit;
+ p->vt.GetThreshold = Range_GetThreshold;
+ p->vt.Decode = Range_Decode;
+ p->vt.DecodeBit = Range_DecodeBit;
}
#define MASK(sym) ((signed char *)charMask)[sym]
-int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
+int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc)
{
size_t charMask[256 / sizeof(size_t)];
if (p->MinContext->NumStats != 1)
diff --git a/C/Ppmd7Enc.c b/C/Ppmd7Enc.c
index e6dd3d2f..286b8712 100644
--- a/C/Ppmd7Enc.c
+++ b/C/Ppmd7Enc.c
@@ -1,5 +1,5 @@
/* Ppmd7Enc.c -- PPMdH Encoder
-2015-09-28 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h"
@@ -23,7 +23,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
Byte temp = p->Cache;
do
{
- p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
+ IByteOut_Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
temp = 0xFF;
}
while (--p->CacheSize != 0);
diff --git a/C/Ppmd8.c b/C/Ppmd8.c
index b60d10fe..15c76bb5 100644
--- a/C/Ppmd8.c
+++ b/C/Ppmd8.c
@@ -1,5 +1,5 @@
/* Ppmd8.c -- PPMdI codec
-2016-05-21 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */
#include "Precomp.h"
@@ -15,7 +15,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x
#define UNIT_SIZE 12
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
-#define U2I(nu) (p->Units2Indx[(nu) - 1])
+#define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1])
#define I2U(indx) (p->Indx2Units[indx])
#ifdef PPMD_32BIT
@@ -86,16 +86,16 @@ void Ppmd8_Construct(CPpmd8 *p)
}
}
-void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc)
+void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc)
{
- alloc->Free(alloc, p->Base);
+ ISzAlloc_Free(alloc, p->Base);
p->Size = 0;
p->Base = 0;
}
-Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc)
+Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc)
{
- if (p->Base == 0 || p->Size != size)
+ if (!p->Base || p->Size != size)
{
Ppmd8_Free(p, alloc);
p->AlignOffset =
@@ -104,7 +104,7 @@ Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc)
#else
4 - (size & 3);
#endif
- if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size)) == 0)
+ if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size)) == 0)
return False;
p->Size = size;
}
@@ -386,7 +386,7 @@ static void RestartModel(CPpmd8 *p)
for (i = m = 0; m < 24; m++)
{
- while (p->NS2Indx[i + 3] == m + 3)
+ while (p->NS2Indx[(size_t)i + 3] == m + 3)
i++;
for (k = 0; k < 32; k++)
{
@@ -905,7 +905,7 @@ static void UpdateModel(CPpmd8 *p)
/* Expand for one UNIT */
unsigned oldNU = (ns1 + 1) >> 1;
unsigned i = U2I(oldNU);
- if (i != U2I(oldNU + 1))
+ if (i != U2I((size_t)oldNU + 1))
{
void *ptr = AllocUnits(p, i + 1);
void *oldPtr;
@@ -1038,7 +1038,7 @@ CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked1, UInt32 *escFreq)
CPpmd_See *see;
if (p->MinContext->NumStats != 0xFF)
{
- see = p->See[(unsigned)p->NS2Indx[(unsigned)p->MinContext->NumStats + 2] - 3] +
+ see = p->See[(size_t)(unsigned)p->NS2Indx[(size_t)(unsigned)p->MinContext->NumStats + 2] - 3] +
(p->MinContext->SummFreq > 11 * ((unsigned)p->MinContext->NumStats + 1)) +
2 * (unsigned)(2 * (unsigned)p->MinContext->NumStats <
((unsigned)SUFFIX(p->MinContext)->NumStats + numMasked1)) +
diff --git a/C/Ppmd8.h b/C/Ppmd8.h
index 7dcfc916..3b15920e 100644
--- a/C/Ppmd8.h
+++ b/C/Ppmd8.h
@@ -1,5 +1,5 @@
/* Ppmd8.h -- PPMdI codec
-2011-01-27 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -86,8 +86,8 @@ typedef struct
} CPpmd8;
void Ppmd8_Construct(CPpmd8 *p);
-Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc);
-void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc);
+Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc);
+void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc);
void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
#define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
@@ -112,7 +112,7 @@ void Ppmd8_Update2(CPpmd8 *p);
void Ppmd8_UpdateBin(CPpmd8 *p);
#define Ppmd8_GetBinSumm(p) \
- &p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
+ &p->BinSumm[p->NS2Indx[(size_t)Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
diff --git a/C/Ppmd8Dec.c b/C/Ppmd8Dec.c
index 317bd651..dc79f0fd 100644
--- a/C/Ppmd8Dec.c
+++ b/C/Ppmd8Dec.c
@@ -1,5 +1,5 @@
/* Ppmd8Dec.c -- PPMdI Decoder
-2010-04-16 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -18,7 +18,7 @@ Bool Ppmd8_RangeDec_Init(CPpmd8 *p)
p->Range = 0xFFFFFFFF;
p->Code = 0;
for (i = 0; i < 4; i++)
- p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
+ p->Code = (p->Code << 8) | IByteIn_Read(p->Stream.In);
return (p->Code < 0xFFFFFFFF);
}
@@ -37,7 +37,7 @@ static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
{
- p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
+ p->Code = (p->Code << 8) | IByteIn_Read(p->Stream.In);
p->Range <<= 8;
p->Low <<= 8;
}
diff --git a/C/Ppmd8Enc.c b/C/Ppmd8Enc.c
index 5e389be4..1cbc17f1 100644
--- a/C/Ppmd8Enc.c
+++ b/C/Ppmd8Enc.c
@@ -1,5 +1,5 @@
/* Ppmd8Enc.c -- PPMdI Encoder
-2010-04-16 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -15,7 +15,7 @@ void Ppmd8_RangeEnc_FlushData(CPpmd8 *p)
{
unsigned i;
for (i = 0; i < 4; i++, p->Low <<= 8 )
- p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24));
+ IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24));
}
static void RangeEnc_Normalize(CPpmd8 *p)
@@ -23,7 +23,7 @@ static void RangeEnc_Normalize(CPpmd8 *p)
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
{
- p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24));
+ IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24));
p->Range <<= 8;
p->Low <<= 8;
}
diff --git a/C/Sha1.c b/C/Sha1.c
index 55c1c63c..96b5e787 100644
--- a/C/Sha1.c
+++ b/C/Sha1.c
@@ -1,5 +1,5 @@
/* Sha1.c -- SHA-1 Hash
-2016-05-20 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
#include "Precomp.h"
@@ -62,8 +62,8 @@ This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ l
#else
-#define RX_15 { unsigned i; for (i = 0; i < 15; i += 5) { RX_5(R0, i); } }
-#define RX_20(rx, ii) { unsigned i; i = ii; for (; i < ii + 20; i += 5) { RX_5(rx, i); } }
+#define RX_15 { size_t i; for (i = 0; i < 15; i += 5) { RX_5(R0, i); } }
+#define RX_20(rx, ii) { size_t i; i = ii; for (; i < ii + 20; i += 5) { RX_5(rx, i); } }
#endif
@@ -131,7 +131,7 @@ void Sha1_UpdateBlock_Rar(CSha1 *p, UInt32 *data, int returnRes)
if (returnRes)
{
- unsigned i;
+ size_t i;
for (i = 0 ; i < SHA1_NUM_BLOCK_WORDS; i++)
data[i] = W[kNumW - SHA1_NUM_BLOCK_WORDS + i];
}
@@ -176,7 +176,7 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
{
for (;;)
{
- unsigned i;
+ size_t i;
Sha1_UpdateBlock(p);
if (size < SHA1_BLOCK_SIZE)
break;
@@ -238,7 +238,7 @@ void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size /* , int rar350Mode */)
Sha1_UpdateBlock_Rar(p, p->buffer, returnRes);
if (returnRes)
{
- unsigned i;
+ size_t i;
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
{
UInt32 d = p->buffer[i];
diff --git a/C/Sha256.c b/C/Sha256.c
index b5bc19b9..04b688c6 100644
--- a/C/Sha256.c
+++ b/C/Sha256.c
@@ -1,5 +1,5 @@
/* Crypto/Sha256.c -- SHA-256 Hash
-2015-11-14 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
This code is based on public domain code from Wei Dai's Crypto++ library. */
#include "Precomp.h"
@@ -45,7 +45,7 @@ void Sha256_Init(CSha256 *p)
#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)); \
+ h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \
d += h; \
h += S0(a) + Maj(a, b, c)
@@ -73,7 +73,7 @@ void Sha256_Init(CSha256 *p)
#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)); \
+ h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \
d(i) += h(i); \
h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \
diff --git a/C/Util/7z/7zMain.c b/C/Util/7z/7zMain.c
index 1837e9d6..2e1481bc 100644
--- a/C/Util/7z/7zMain.c
+++ b/C/Util/7z/7zMain.c
@@ -1,11 +1,13 @@
/* 7zMain.c - Test application for 7z Decoder
-2016-05-16 : Igor Pavlov : Public domain */
+2017-04-05 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <stdio.h>
#include <string.h>
+#include "../../CpuArch.h"
+
#include "../../7z.h"
#include "../../7zAlloc.h"
#include "../../7zBuf.h"
@@ -23,7 +25,17 @@
#endif
#endif
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+#define kInputBufSize ((size_t)1 << 18)
+
+static const ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+
+static void Print(const char *s)
+{
+ fputs(s, stdout);
+}
+
static int Buf_EnsureSize(CBuf *dest, size_t size)
{
@@ -227,6 +239,7 @@ static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
#endif
}
+
static SRes PrintString(const UInt16 *s)
{
CBuf buf;
@@ -238,12 +251,12 @@ static SRes PrintString(const UInt16 *s)
#endif
);
if (res == SZ_OK)
- fputs((const char *)buf.data, stdout);
+ Print((const char *)buf.data);
Buf_Free(&buf, &g_Alloc);
return res;
}
-static void UInt64ToStr(UInt64 value, char *s)
+static void UInt64ToStr(UInt64 value, char *s, int numDigits)
{
char temp[32];
int pos = 0;
@@ -253,6 +266,10 @@ static void UInt64ToStr(UInt64 value, char *s)
value /= 10;
}
while (value != 0);
+
+ for (numDigits -= pos; numDigits > 0; numDigits--)
+ *s++ = ' ';
+
do
*s++ = temp[--pos];
while (pos);
@@ -266,8 +283,10 @@ static char *UIntToStr(char *s, unsigned value, int numDigits)
do
temp[pos++] = (char)('0' + (value % 10));
while (value /= 10);
+
for (numDigits -= pos; numDigits > 0; numDigits--)
*s++ = '0';
+
do
*s++ = temp[--pos];
while (pos);
@@ -323,9 +342,16 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
UIntToStr_2(s, sec); s[2] = 0;
}
-void PrintError(char *sz)
+static void PrintLF()
+{
+ Print("\n");
+}
+
+static void PrintError(char *s)
{
- printf("\nERROR: %s\n", sz);
+ Print("\nERROR: ");
+ Print(s);
+ PrintLF();
}
static void GetAttribString(UInt32 wa, Bool isDir, char *s)
@@ -343,25 +369,27 @@ static void GetAttribString(UInt32 wa, Bool isDir, char *s)
#endif
}
+
// #define NUM_PARENTS_MAX 128
int MY_CDECL main(int numargs, char *args[])
{
+ ISzAlloc allocImp;
+ ISzAlloc allocTempImp;
+
CFileInStream archiveStream;
- CLookToRead lookStream;
+ CLookToRead2 lookStream;
CSzArEx db;
SRes res;
- ISzAlloc allocImp;
- 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");
+ Print("\n7z Decoder " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n");
if (numargs == 1)
{
- printf(
+ Print(
"Usage: 7zDec <command> <archive_name>\n\n"
"<Commands>\n"
" e: Extract files from archive (without using directory names)\n"
@@ -370,7 +398,7 @@ int MY_CDECL main(int numargs, char *args[])
" x: eXtract files with full paths\n");
return 0;
}
-
+
if (numargs < 3)
{
PrintError("incorrect command");
@@ -381,11 +409,9 @@ int MY_CDECL main(int numargs, char *args[])
g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
#endif
- allocImp.Alloc = SzAlloc;
- allocImp.Free = SzFree;
- allocTempImp.Alloc = SzAllocTemp;
- allocTempImp.Free = SzFreeTemp;
+ allocImp = g_Alloc;
+ allocTempImp = g_Alloc;
#ifdef UNDER_CE
if (InFile_OpenW(&archiveStream.file, L"\test.7z"))
@@ -398,16 +424,31 @@ int MY_CDECL main(int numargs, char *args[])
}
FileInStream_CreateVTable(&archiveStream);
- LookToRead_CreateVTable(&lookStream, False);
-
- lookStream.realStream = &archiveStream.s;
- LookToRead_Init(&lookStream);
+ LookToRead2_CreateVTable(&lookStream, False);
+ lookStream.buf = NULL;
- CrcGenerateTable();
+ res = SZ_OK;
+ {
+ lookStream.buf = ISzAlloc_Alloc(&allocImp, kInputBufSize);
+ if (!lookStream.buf)
+ res = SZ_ERROR_MEM;
+ else
+ {
+ lookStream.bufSize = kInputBufSize;
+ lookStream.realStream = &archiveStream.vt;
+ LookToRead2_Init(&lookStream);
+ }
+ }
+
+ CrcGenerateTable();
+
SzArEx_Init(&db);
-
- res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
+
+ if (res == SZ_OK)
+ {
+ res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp);
+ }
if (res == SZ_OK)
{
@@ -477,7 +518,7 @@ int MY_CDECL main(int numargs, char *args[])
GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr);
fileSize = SzArEx_GetFileSize(&db, i);
- UInt64ToStr(fileSize, s);
+ UInt64ToStr(fileSize, s, 10);
if (SzBitWithVals_Check(&db.MTime, i))
ConvertFileTimeToString(&db.MTime.Vals[i], t);
@@ -489,29 +530,33 @@ int MY_CDECL main(int numargs, char *args[])
t[j] = '\0';
}
- printf("%s %s %10s ", t, attr, s);
+ Print(t);
+ Print(" ");
+ Print(attr);
+ Print(" ");
+ Print(s);
+ Print(" ");
res = PrintString(temp);
if (res != SZ_OK)
break;
if (isDir)
- printf("/");
- printf("\n");
+ Print("/");
+ PrintLF();
continue;
}
- fputs(testCommand ?
+ Print(testCommand ?
"Testing ":
- "Extracting ",
- stdout);
+ "Extracting ");
res = PrintString(temp);
if (res != SZ_OK)
break;
if (isDir)
- printf("/");
+ Print("/");
else
{
- res = SzArEx_Extract(&db, &lookStream.s, i,
+ res = SzArEx_Extract(&db, &lookStream.vt, i,
&blockIndex, &outBuffer, &outBufferSize,
&offset, &outSizeProcessed,
&allocImp, &allocTempImp);
@@ -543,7 +588,7 @@ int MY_CDECL main(int numargs, char *args[])
if (isDir)
{
MyCreateDir(destPath);
- printf("\n");
+ PrintLF();
continue;
}
else if (OutFile_OpenUtf16(&outFile, destPath))
@@ -574,20 +619,21 @@ int MY_CDECL main(int numargs, char *args[])
SetFileAttributesW(destPath, db.Attribs.Vals[i]);
#endif
}
- printf("\n");
+ PrintLF();
}
- IAlloc_Free(&allocImp, outBuffer);
+ ISzAlloc_Free(&allocImp, outBuffer);
}
}
- SzArEx_Free(&db, &allocImp);
SzFree(NULL, temp);
+ SzArEx_Free(&db, &allocImp);
+ ISzAlloc_Free(&allocImp, lookStream.buf);
File_Close(&archiveStream.file);
if (res == SZ_OK)
{
- printf("\nEverything is Ok\n");
+ Print("\nEverything is Ok\n");
return 0;
}
@@ -598,7 +644,11 @@ int MY_CDECL main(int numargs, char *args[])
else if (res == SZ_ERROR_CRC)
PrintError("CRC error");
else
- printf("\nERROR #%d\n", res);
+ {
+ char s[32];
+ UInt64ToStr(res, s, 0);
+ PrintError(s);
+ }
return 1;
}
diff --git a/C/Util/7zipInstall/7zipInstall.c b/C/Util/7zipInstall/7zipInstall.c
index 31e52da8..67df159f 100644
--- a/C/Util/7zipInstall/7zipInstall.c
+++ b/C/Util/7zipInstall/7zipInstall.c
@@ -1,5 +1,5 @@
/* 7zipInstall.c - 7-Zip Installer
-2016-06-08 : Igor Pavlov : Public domain */
+2017-04-04 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -25,9 +25,22 @@
#include "resource.h"
-static const WCHAR *k_7zip = L"7-Zip";
-static const WCHAR *k_Reg_Software_7zip = L"Software\\7-Zip";
+#define wcscat lstrcatW
+#define wcslen lstrlenW
+#define wcscpy lstrcpyW
+#define wcsncpy lstrcpynW
+
+
+#define kInputBufSize ((size_t)1 << 18)
+
+
+#define _7ZIP_CUR_VER ((MY_VER_MAJOR << 16) | MY_VER_MINOR)
+#define _7ZIP_DLL_VER_COMPAT ((16 << 16) | 3)
+
+static LPCWSTR const k_7zip = L"7-Zip";
+
+static LPCWSTR const k_Reg_Software_7zip = L"Software\\7-Zip";
// #define _64BIT_INSTALLER 1
@@ -43,13 +56,13 @@ static const WCHAR *k_Reg_Software_7zip = L"Software\\7-Zip";
#define k_7zip_with_Ver k_7zip_with_Ver_base
#endif
-static const WCHAR *k_7zip_with_Ver_str = k_7zip_with_Ver;
+static LPCWSTR const k_7zip_with_Ver_str = k_7zip_with_Ver;
-static const WCHAR *k_7zip_Setup = k_7zip_with_Ver L" Setup";
+static LPCWSTR const k_7zip_Setup = k_7zip_with_Ver L" Setup";
-static const WCHAR *k_Reg_Path = L"Path";
+static LPCWSTR const k_Reg_Path = L"Path";
-static const WCHAR *k_Reg_Path32 = L"Path"
+static LPCWSTR const k_Reg_Path32 = L"Path"
#ifdef _64BIT_INSTALLER
L"64"
#else
@@ -71,8 +84,8 @@ static const WCHAR *k_Reg_Path32 = L"Path"
#define k_7zip_CLSID L"{23170F69-40C1-278A-1000-000100020000}"
-static const WCHAR *k_Reg_CLSID_7zip = L"CLSID\\" k_7zip_CLSID;
-static const WCHAR *k_Reg_CLSID_7zip_Inproc = L"CLSID\\" k_7zip_CLSID L"\\InprocServer32";
+static LPCWSTR const k_Reg_CLSID_7zip = L"CLSID\\" k_7zip_CLSID;
+static LPCWSTR const k_Reg_CLSID_7zip_Inproc = L"CLSID\\" k_7zip_CLSID L"\\InprocServer32";
#define g_AllUsers True
@@ -107,7 +120,35 @@ static void PrintErrorMessage(const char *s)
MessageBoxW(g_HWND, s2, k_7zip_with_Ver_str, MB_ICONERROR);
}
-static WRes MyCreateDir(const WCHAR *name)
+
+static DWORD GetFileVersion(LPCWSTR s)
+{
+ DWORD size = 0;
+ BYTE *vi = NULL;
+ DWORD version = 0;
+
+ size = GetFileVersionInfoSizeW(s, NULL);
+ if (size == 0)
+ return 0;
+
+ vi = malloc(size);
+ if (!vi)
+ return 0;
+
+ if (GetFileVersionInfoW(s, 0, size, vi))
+ {
+ VS_FIXEDFILEINFO *fi = NULL;
+ UINT fiLen = 0;
+ if (VerQueryValueW(vi, L"\\", (LPVOID *)&fi, &fiLen))
+ version = fi->dwFileVersionMS;
+ }
+
+ free(vi);
+ return version;
+}
+
+
+static WRes MyCreateDir(LPCWSTR name)
{
return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
}
@@ -455,7 +496,7 @@ static wchar_t MyWCharLower_Ascii(wchar_t c)
return c;
}
-static const WCHAR *FindSubString(const WCHAR *s1, const char *s2)
+static LPCWSTR FindSubString(LPCWSTR s1, const char *s2)
{
for (;;)
{
@@ -702,8 +743,8 @@ static void SetShellProgramsGroup(HWND hwndOwner)
#endif
}
-static const WCHAR *k_Shell_Approved = L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";
-static const WCHAR *k_7zip_ShellExtension = L"7-Zip Shell Extension";
+static LPCWSTR const k_Shell_Approved = L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";
+static LPCWSTR const k_7zip_ShellExtension = L"7-Zip Shell Extension";
static void WriteCLSID()
{
@@ -747,7 +788,7 @@ static void WriteCLSID()
}
}
-static const WCHAR * const k_ShellEx_Items[] =
+static LPCWSTR const k_ShellEx_Items[] =
{
L"*\\shellex\\ContextMenuHandlers"
, L"Directory\\shellex\\ContextMenuHandlers"
@@ -916,7 +957,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
num = s2 - s;
if (num > MAX_PATH)
num = MAX_PATH;
- wcsncpy(path, s, num);
+ wcsncpy(path, s, (unsigned)num);
RemoveQuotes(path);
}
}
@@ -1059,6 +1100,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
}
}
+
static Bool GetErrorMessage(DWORD errorCode, WCHAR *message)
{
LPVOID msgBuf;
@@ -1073,10 +1115,12 @@ static Bool GetErrorMessage(DWORD errorCode, WCHAR *message)
return True;
}
+
+
static int Install()
{
CFileInStream archiveStream;
- CLookToRead lookStream;
+ CLookToRead2 lookStream;
CSzArEx db;
SRes res = SZ_OK;
@@ -1087,7 +1131,7 @@ static int Install()
ISzAlloc allocTempImp;
WCHAR sfxPath[MAX_PATH + 2];
- Bool needReboot = False;
+ int needRebootLevel = 0;
allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree;
@@ -1127,7 +1171,8 @@ if (res == SZ_OK)
}
FileInStream_CreateVTable(&archiveStream);
- LookToRead_CreateVTable(&lookStream, False);
+ LookToRead2_CreateVTable(&lookStream, False);
+ lookStream.buf = NULL;
{
// Remove post spaces
@@ -1150,17 +1195,28 @@ if (res == SZ_OK)
winRes = CreateComplexDir();
if (winRes != 0)
- res = E_FAIL;
+ res = SZ_ERROR_FAIL;
pathLen = wcslen(path);
+
+ if (res == SZ_OK)
+ {
+ lookStream.buf = ISzAlloc_Alloc(&allocImp, kInputBufSize);
+ if (!lookStream.buf)
+ res = SZ_ERROR_MEM;
+ else
+ {
+ lookStream.bufSize = kInputBufSize;
+ lookStream.realStream = &archiveStream.vt;
+ LookToRead2_Init(&lookStream);
+ }
+ }
+
SzArEx_Init(&db);
if (res == SZ_OK)
{
- lookStream.realStream = &archiveStream.s;
- LookToRead_Init(&lookStream);
-
- res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
+ res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp);
}
if (res == SZ_OK)
@@ -1222,7 +1278,7 @@ if (res == SZ_OK)
SetWindowTextW(g_InfoLine_HWND, temp);
{
- res = SzArEx_Extract(&db, &lookStream.s, i,
+ res = SzArEx_Extract(&db, &lookStream.vt, i,
&blockIndex, &outBuf, &outBufSize,
&offset, &outSizeProcessed,
&allocImp, &allocTempImp);
@@ -1236,6 +1292,7 @@ if (res == SZ_OK)
size_t j;
// size_t nameStartPos = 0;
UInt32 tempIndex = 0;
+ int fileLevel = 1 << 2;
WCHAR origPath[MAX_PATH * 2 + 10];
for (j = 0; temp[j] != 0; j++)
@@ -1289,13 +1346,20 @@ if (res == SZ_OK)
break;
}
- if (tempIndex != 0
- || FindSubString(temp, "7-zip.dll")
+ if (tempIndex != 0)
+ {
+ tempIndex++;
+ continue;
+ }
+
+ if (FindSubString(temp, "7-zip.dll")
#ifdef _64BIT_INSTALLER
|| FindSubString(temp, "7-zip32.dll")
#endif
)
{
+ DWORD ver = GetFileVersion(path);
+ fileLevel = ((ver < _7ZIP_DLL_VER_COMPAT || ver > _7ZIP_CUR_VER) ? 2 : 1);
tempIndex++;
continue;
}
@@ -1339,7 +1403,7 @@ if (res == SZ_OK)
*/
}
- // if (res = S_OK)
+ // if (res == SZ_OK)
{
processedSize = outSizeProcessed;
winRes = File_Write(&outFile, outBuf + offset, &processedSize);
@@ -1388,14 +1452,14 @@ if (res == SZ_OK)
winRes = GetLastError();
break;
}
- needReboot = True;
+ needRebootLevel |= fileLevel;
#endif
}
}
}
- IAlloc_Free(&allocImp, outBuf);
+ ISzAlloc_Free(&allocImp, outBuf);
if (!g_SilentMode)
SendMessage(g_Progress_HWND, PBM_SETPOS, i, 0);
@@ -1416,6 +1480,8 @@ if (res == SZ_OK)
SzArEx_Free(&db, &allocImp);
+ ISzAlloc_Free(&allocImp, lookStream.buf);
+
File_Close(&archiveStream.file);
}
@@ -1425,7 +1491,7 @@ if (res == SZ_OK)
if (res == SZ_OK)
{
- if (!g_SilentMode && needReboot)
+ if (!g_SilentMode && needRebootLevel > 1)
{
if (MessageBoxW(g_HWND, L"You must restart your system to complete the installation.\nRestart now?",
k_7zip_Setup, MB_YESNO | MB_DEFBUTTON2) == IDYES)
diff --git a/C/Util/7zipInstall/7zipInstall.dsp b/C/Util/7zipInstall/7zipInstall.dsp
index 83ea6765..d3b5c4c9 100644
--- a/C/Util/7zipInstall/7zipInstall.dsp
+++ b/C/Util/7zipInstall/7zipInstall.dsp
@@ -40,9 +40,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 "_WINDOWS" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /c
+# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /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"
@@ -52,7 +53,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 /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
+# 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 version.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "7zipInstall - Win32 Debug"
@@ -78,7 +79,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 /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 /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 version.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
diff --git a/C/Util/7zipInstall/makefile b/C/Util/7zipInstall/makefile
index aabc7d44..e84d552d 100644
--- a/C/Util/7zipInstall/makefile
+++ b/C/Util/7zipInstall/makefile
@@ -1,5 +1,7 @@
PROG = 7zipInstall.exe
+LIBS = $(LIBS) version.lib
+
!IFDEF _64BIT_INSTALLER
CFLAGS = $(CFLAGS) -D_64BIT_INSTALLER
!ENDIF
diff --git a/C/Util/7zipUninstall/7zipUninstall.c b/C/Util/7zipUninstall/7zipUninstall.c
index cdbc2d5e..0bf27cc2 100644
--- a/C/Util/7zipUninstall/7zipUninstall.c
+++ b/C/Util/7zipUninstall/7zipUninstall.c
@@ -1,5 +1,5 @@
/* 7zipUninstall.c - 7-Zip Uninstaller
-2016-05-16 : Igor Pavlov : Public domain */
+2017-04-04 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -20,7 +20,7 @@
#define LLL_(quote) L##quote
#define LLL(quote) LLL_(quote)
-// static const WCHAR *k_7zip = L"7-Zip";
+// static const WCHAR * const k_7zip = L"7-Zip";
// #define _64BIT_INSTALLER 1
@@ -36,13 +36,13 @@
#define k_7zip_with_Ver k_7zip_with_Ver_base
#endif
-// static const WCHAR *k_7zip_with_Ver_str = k_7zip_with_Ver;
+// static const WCHAR * const k_7zip_with_Ver_str = k_7zip_with_Ver;
-static const WCHAR *k_Reg_Software_7zip = L"Software\\7-Zip";
+static const WCHAR * const k_Reg_Software_7zip = L"Software\\7-Zip";
-static const WCHAR *k_Reg_Path = L"Path";
+static const WCHAR * const k_Reg_Path = L"Path";
-static const WCHAR *k_Reg_Path32 = L"Path"
+static const WCHAR * const k_Reg_Path32 = L"Path"
#ifdef _64BIT_INSTALLER
L"64"
#else
@@ -64,8 +64,8 @@ static const WCHAR *k_Reg_Path32 = L"Path"
#define k_7zip_CLSID L"{23170F69-40C1-278A-1000-000100020000}"
-static const WCHAR *k_Reg_CLSID_7zip = L"CLSID\\" k_7zip_CLSID;
-static const WCHAR *k_Reg_CLSID_7zip_Inproc = L"CLSID\\" k_7zip_CLSID L"\\InprocServer32";
+static const WCHAR * const k_Reg_CLSID_7zip = L"CLSID\\" k_7zip_CLSID;
+static const WCHAR * const k_Reg_CLSID_7zip_Inproc = L"CLSID\\" k_7zip_CLSID L"\\InprocServer32";
#define g_AllUsers True
@@ -90,7 +90,7 @@ static WCHAR tempPath[MAX_PATH * 2 + 40];
static WCHAR cmdLine[MAX_PATH * 3 + 40];
static WCHAR copyPath[MAX_PATH * 2 + 40];
-static const WCHAR *kUninstallExe = L"Uninstall.exe";
+static const WCHAR * const kUninstallExe = L"Uninstall.exe";
#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c)))
@@ -340,11 +340,11 @@ static const WCHAR * const k_ShellEx_Items[] =
, L"Drive\\shellex\\DragDropHandlers"
};
-static const WCHAR *k_Shell_Approved = L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";
+static const WCHAR * const k_Shell_Approved = L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";
-static const WCHAR *k_AppPaths_7zFm = L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\7zFM.exe";
+static const WCHAR * const k_AppPaths_7zFm = L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\7zFM.exe";
#define k_REG_Uninstall L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
-static const WCHAR *k_Uninstall_7zip = k_REG_Uninstall L"7-Zip";
+static const WCHAR * const k_Uninstall_7zip = k_REG_Uninstall L"7-Zip";
static Bool AreEqual_Path_PrefixName(const wchar_t *s, const wchar_t *prefix, const wchar_t *name)
@@ -556,7 +556,7 @@ static BOOL RemoveDir()
#define NUM_FILES (NUM_LANG_TXT_FILES + 1 + 13 + NUM_EXTRA_FILES_64BIT)
-static const char *k_Names =
+static const char * const k_Names =
"af an ar ast az ba be bg bn br ca co cs cy da de el eo es et eu ext"
" fa fi fr fur fy ga gl gu he hi hr hu hy id io is it ja ka kaa kk ko ku ku-ckb ky"
" lij lt lv mk mn mng mng2 mr ms nb ne nl nn pa-in pl ps pt pt-br ro ru"
diff --git a/C/Util/7zipUninstall/7zipUninstall.dsp b/C/Util/7zipUninstall/7zipUninstall.dsp
index 06afc672..cc7b6b6b 100644
--- a/C/Util/7zipUninstall/7zipUninstall.dsp
+++ b/C/Util/7zipUninstall/7zipUninstall.dsp
@@ -43,7 +43,7 @@ RSC=rc.exe
# 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 /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /c
+# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /FAcs /Yu"Precomp.h" /FD /GF /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
diff --git a/C/Util/Lzma/LzmaUtil.c b/C/Util/Lzma/LzmaUtil.c
index e5857cef..33db3e16 100644
--- a/C/Util/Lzma/LzmaUtil.c
+++ b/C/Util/Lzma/LzmaUtil.c
@@ -1,5 +1,5 @@
/* LzmaUtil.c -- Test application for LZMA compression
-2015-11-08 : Igor Pavlov : Public domain */
+2017-04-27 : Igor Pavlov : Public domain */
#include "../../Precomp.h"
@@ -7,26 +7,29 @@
#include <stdlib.h>
#include <string.h>
+#include "../../CpuArch.h"
+
#include "../../Alloc.h"
#include "../../7zFile.h"
#include "../../7zVersion.h"
#include "../../LzmaDec.h"
#include "../../LzmaEnc.h"
-const char *kCantReadMessage = "Can not read input file";
-const char *kCantWriteMessage = "Can not write output file";
-const char *kCantAllocateMessage = "Can not allocate memory";
-const char *kDataErrorMessage = "Data error";
+static const char * const kCantReadMessage = "Can not read input file";
+static const char * const kCantWriteMessage = "Can not write output file";
+static const char * const kCantAllocateMessage = "Can not allocate memory";
+static const char * const kDataErrorMessage = "Data error";
-void PrintHelp(char *buffer)
+static void PrintHelp(char *buffer)
{
- strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"
- "\nUsage: lzma <e|d> inputFile outputFile\n"
- " e: encode file\n"
- " d: decode file\n");
+ strcat(buffer,
+ "\nLZMA-C " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n"
+ "Usage: lzma <e|d> inputFile outputFile\n"
+ " e: encode file\n"
+ " d: decode file\n");
}
-int PrintError(char *buffer, const char *message)
+static int PrintError(char *buffer, const char *message)
{
strcat(buffer, "\nError: ");
strcat(buffer, message);
@@ -34,20 +37,22 @@ int PrintError(char *buffer, const char *message)
return 1;
}
-int PrintErrorNumber(char *buffer, SRes val)
+static int PrintErrorNumber(char *buffer, SRes val)
{
sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val);
return 1;
}
-int PrintUserError(char *buffer)
+static int PrintUserError(char *buffer)
{
return PrintError(buffer, "Incorrect command");
}
+
#define IN_BUF_SIZE (1 << 16)
#define OUT_BUF_SIZE (1 << 16)
+
static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
UInt64 unpackSize)
{
@@ -101,6 +106,7 @@ static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inS
}
}
+
static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream)
{
UInt64 unpackSize;
@@ -163,7 +169,8 @@ static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 file
return res;
}
-int main2(int numArgs, const char *args[], char *rs)
+
+static int main2(int numArgs, const char *args[], char *rs)
{
CFileSeqInStream inStream;
CFileOutStream outStream;
@@ -215,11 +222,11 @@ int main2(int numArgs, const char *args[], char *rs)
{
UInt64 fileSize;
File_GetLength(&inStream.file, &fileSize);
- res = Encode(&outStream.s, &inStream.s, fileSize, rs);
+ res = Encode(&outStream.vt, &inStream.vt, fileSize, rs);
}
else
{
- res = Decode(&outStream.s, useOutFile ? &inStream.s : NULL);
+ res = Decode(&outStream.vt, useOutFile ? &inStream.vt : NULL);
}
if (useOutFile)
@@ -241,6 +248,7 @@ int main2(int numArgs, const char *args[], char *rs)
return 0;
}
+
int MY_CDECL main(int numArgs, const char *args[])
{
char rs[800] = { 0 };
diff --git a/C/Util/SfxSetup/SfxSetup.c b/C/Util/SfxSetup/SfxSetup.c
index 57e73d86..8275dfea 100644
--- a/C/Util/SfxSetup/SfxSetup.c
+++ b/C/Util/SfxSetup/SfxSetup.c
@@ -1,5 +1,5 @@
/* SfxSetup.c - 7z SFX Setup
-2016-05-16 : Igor Pavlov : Public domain */
+2017-04-04 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -24,6 +24,8 @@
#define k_EXE_ExtIndex 2
+#define kInputBufSize ((size_t)1 << 18)
+
static const char * const kExts[] =
{
"bat"
@@ -238,7 +240,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
#endif
{
CFileInStream archiveStream;
- CLookToRead lookStream;
+ CLookToRead2 lookStream;
CSzArEx db;
SRes res = SZ_OK;
ISzAlloc allocImp;
@@ -275,7 +277,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
allocTempImp.Free = SzFreeTemp;
FileInStream_CreateVTable(&archiveStream);
- LookToRead_CreateVTable(&lookStream, False);
+ LookToRead2_CreateVTable(&lookStream, False);
+ lookStream.buf = NULL;
winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH);
if (winRes == 0 || winRes > MAX_PATH)
@@ -376,14 +379,22 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
if (res == SZ_OK)
{
- lookStream.realStream = &archiveStream.s;
- LookToRead_Init(&lookStream);
+ lookStream.buf = ISzAlloc_Alloc(&allocImp, kInputBufSize);
+ if (!lookStream.buf)
+ res = SZ_ERROR_MEM;
+ else
+ {
+ lookStream.bufSize = kInputBufSize;
+ lookStream.realStream = &archiveStream.vt;
+ LookToRead2_Init(&lookStream);
+ }
}
SzArEx_Init(&db);
+
if (res == SZ_OK)
{
- res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
+ res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp);
}
if (res == SZ_OK)
@@ -411,7 +422,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
SzArEx_GetFileNameUtf16(&db, i, temp);
{
- res = SzArEx_Extract(&db, &lookStream.s, i,
+ res = SzArEx_Extract(&db, &lookStream.vt, i,
&blockIndex, &outBuffer, &outBufferSize,
&offset, &outSizeProcessed,
&allocImp, &allocTempImp);
@@ -522,10 +533,13 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
temp[j] = CHAR_PATH_SEPARATOR;
}
}
- IAlloc_Free(&allocImp, outBuffer);
+ ISzAlloc_Free(&allocImp, outBuffer);
}
+
SzArEx_Free(&db, &allocImp);
+ ISzAlloc_Free(&allocImp, lookStream.buf);
+
File_Close(&archiveStream.file);
if (res == SZ_OK)
diff --git a/C/Xz.c b/C/Xz.c
index 1ef68782..6e2c86cb 100644
--- a/C/Xz.c
+++ b/C/Xz.c
@@ -1,5 +1,5 @@
/* Xz.c - Xz
-2015-05-01 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -20,7 +20,7 @@ unsigned Xz_WriteVarInt(Byte *buf, UInt64 v)
v >>= 7;
}
while (v != 0);
- buf[i - 1] &= 0x7F;
+ buf[(size_t)i - 1] &= 0x7F;
return i;
}
@@ -31,9 +31,9 @@ void Xz_Construct(CXzStream *p)
p->flags = 0;
}
-void Xz_Free(CXzStream *p, ISzAlloc *alloc)
+void Xz_Free(CXzStream *p, ISzAllocPtr alloc)
{
- alloc->Free(alloc, p->blocks);
+ ISzAlloc_Free(alloc, p->blocks);
p->numBlocks = p->numBlocksAllocated = 0;
p->blocks = 0;
}
diff --git a/C/Xz.h b/C/Xz.h
index be3a1c36..7e30e386 100644
--- a/C/Xz.h
+++ b/C/Xz.h
@@ -1,5 +1,5 @@
/* Xz.h - Xz interface
-2015-05-01 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#ifndef __XZ_H
#define __XZ_H
@@ -112,7 +112,7 @@ typedef struct
} CXzStream;
void Xz_Construct(CXzStream *p);
-void Xz_Free(CXzStream *p, ISzAlloc *alloc);
+void Xz_Free(CXzStream *p, ISzAllocPtr alloc);
#define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1)
@@ -127,8 +127,8 @@ typedef struct
} CXzs;
void Xzs_Construct(CXzs *p);
-void Xzs_Free(CXzs *p, ISzAlloc *alloc);
-SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc);
+void Xzs_Free(CXzs *p, ISzAllocPtr alloc);
+SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICompressProgress *progress, ISzAllocPtr alloc);
UInt64 Xzs_GetNumBlocks(const CXzs *p);
UInt64 Xzs_GetUnpackSize(const CXzs *p);
@@ -150,8 +150,8 @@ typedef enum
typedef struct _IStateCoder
{
void *p;
- void (*Free)(void *p, ISzAlloc *alloc);
- SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc);
+ void (*Free)(void *p, ISzAllocPtr alloc);
+ SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAllocPtr alloc);
void (*Init)(void *p);
SRes (*Code)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished);
@@ -161,7 +161,7 @@ typedef struct _IStateCoder
typedef struct
{
- ISzAlloc *alloc;
+ ISzAllocPtr alloc;
Byte *buf;
unsigned numCoders;
int finished[MIXCODER_NUM_FILTERS_MAX - 1];
@@ -171,7 +171,7 @@ typedef struct
IStateCoder coders[MIXCODER_NUM_FILTERS_MAX];
} CMixCoder;
-void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc);
+void MixCoder_Construct(CMixCoder *p, ISzAllocPtr alloc);
void MixCoder_Free(CMixCoder *p);
void MixCoder_Init(CMixCoder *p);
SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId);
@@ -222,7 +222,7 @@ typedef struct
Byte buf[XZ_BLOCK_HEADER_SIZE_MAX];
} CXzUnpacker;
-void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc);
+void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc);
void XzUnpacker_Init(CXzUnpacker *p);
void XzUnpacker_Free(CXzUnpacker *p);
diff --git a/C/XzCrc64.c b/C/XzCrc64.c
index e2da63b6..c45cf9c1 100644
--- a/C/XzCrc64.c
+++ b/C/XzCrc64.c
@@ -1,5 +1,5 @@
/* XzCrc64.c -- CRC64 calculation
-2015-03-01 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -52,12 +52,12 @@ void MY_FAST_CALL Crc64GenerateTable()
UInt64 r = i;
unsigned j;
for (j = 0; j < 8; j++)
- r = (r >> 1) ^ (kCrc64Poly & ~((r & 1) - 1));
+ r = (r >> 1) ^ (kCrc64Poly & ((UInt64)0 - (r & 1)));
g_Crc64Table[i] = r;
}
- for (; i < 256 * CRC_NUM_TABLES; i++)
+ for (i = 256; i < 256 * CRC_NUM_TABLES; i++)
{
- UInt64 r = g_Crc64Table[i - 256];
+ UInt64 r = g_Crc64Table[(size_t)i - 256];
g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8);
}
@@ -76,7 +76,7 @@ void MY_FAST_CALL Crc64GenerateTable()
{
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
{
- UInt64 x = g_Crc64Table[i - 256];
+ UInt64 x = g_Crc64Table[(size_t)i - 256];
g_Crc64Table[i] = CRC_UINT64_SWAP(x);
}
g_Crc64Update = XzCrc64UpdateT1_BeT4;
diff --git a/C/XzCrc64Opt.c b/C/XzCrc64Opt.c
index c4fde65a..30995a60 100644
--- a/C/XzCrc64Opt.c
+++ b/C/XzCrc64Opt.c
@@ -1,5 +1,5 @@
/* XzCrc64Opt.c -- CRC64 calculation
-2015-03-01 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -18,10 +18,10 @@ UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, con
{
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))];
+ ^ (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);
@@ -56,10 +56,10 @@ UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size
{
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))];
+ ^ (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);
diff --git a/C/XzDec.c b/C/XzDec.c
index 1edc0245..2b804270 100644
--- a/C/XzDec.c
+++ b/C/XzDec.c
@@ -1,5 +1,5 @@
/* XzDec.c -- Xz Decode
-2015-11-09 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -28,7 +28,7 @@
#define XZ_CHECK_SIZE_MAX 64
-#define CODER_BUF_SIZE (1 << 17)
+#define CODER_BUF_SIZE ((size_t)1 << 17)
unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
{
@@ -66,12 +66,12 @@ typedef struct
Byte buf[BRA_BUF_SIZE];
} CBraState;
-static void BraState_Free(void *pp, ISzAlloc *alloc)
+static void BraState_Free(void *pp, ISzAllocPtr alloc)
{
- alloc->Free(alloc, pp);
+ ISzAlloc_Free(alloc, pp);
}
-static 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, ISzAllocPtr alloc)
{
CBraState *p = ((CBraState *)pp);
UNUSED_VAR(alloc);
@@ -197,7 +197,7 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
return SZ_OK;
}
-SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc)
+SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAllocPtr alloc)
{
CBraState *decoder;
if (id != XZ_ID_Delta &&
@@ -209,8 +209,8 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc
id != XZ_ID_SPARC)
return SZ_ERROR_UNSUPPORTED;
p->p = 0;
- decoder = (CBraState *)alloc->Alloc(alloc, sizeof(CBraState));
- if (decoder == 0)
+ decoder = (CBraState *)ISzAlloc_Alloc(alloc, sizeof(CBraState));
+ if (!decoder)
return SZ_ERROR_MEM;
decoder->methodId = (UInt32)id;
decoder->encodeMode = encodeMode;
@@ -226,14 +226,14 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc
#ifdef USE_SUBBLOCK
-static void SbState_Free(void *pp, ISzAlloc *alloc)
+static void SbState_Free(void *pp, ISzAllocPtr alloc)
{
CSbDec *p = (CSbDec *)pp;
SbDec_Free(p);
- alloc->Free(alloc, pp);
+ ISzAlloc_Free(alloc, pp);
}
-static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
+static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc)
{
UNUSED_VAR(pp);
UNUSED_VAR(props);
@@ -264,12 +264,12 @@ static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
return res;
}
-SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
+SRes SbState_SetFromMethod(IStateCoder *p, ISzAllocPtr alloc)
{
CSbDec *decoder;
p->p = 0;
- decoder = alloc->Alloc(alloc, sizeof(CSbDec));
- if (decoder == 0)
+ decoder = ISzAlloc_Alloc(alloc, sizeof(CSbDec));
+ if (!decoder)
return SZ_ERROR_MEM;
p->p = decoder;
p->Free = SbState_Free;
@@ -284,13 +284,13 @@ SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
/* ---------- Lzma2State ---------- */
-static void Lzma2State_Free(void *pp, ISzAlloc *alloc)
+static void Lzma2State_Free(void *pp, ISzAllocPtr alloc)
{
Lzma2Dec_Free((CLzma2Dec *)pp, alloc);
- alloc->Free(alloc, pp);
+ ISzAlloc_Free(alloc, pp);
}
-static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
+static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc)
{
if (propSize != 1)
return SZ_ERROR_UNSUPPORTED;
@@ -313,11 +313,11 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr
return res;
}
-static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
+static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAllocPtr alloc)
{
- CLzma2Dec *decoder = (CLzma2Dec *)alloc->Alloc(alloc, sizeof(CLzma2Dec));
+ CLzma2Dec *decoder = (CLzma2Dec *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Dec));
p->p = decoder;
- if (decoder == 0)
+ if (!decoder)
return SZ_ERROR_MEM;
p->Free = Lzma2State_Free;
p->SetProps = Lzma2State_SetProps;
@@ -328,7 +328,7 @@ static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
}
-void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
+void MixCoder_Construct(CMixCoder *p, ISzAllocPtr alloc)
{
unsigned i;
p->alloc = alloc;
@@ -350,7 +350,7 @@ void MixCoder_Free(CMixCoder *p)
p->numCoders = 0;
if (p->buf)
{
- p->alloc->Free(p->alloc, p->buf);
+ ISzAlloc_Free(p->alloc, p->buf);
p->buf = NULL; /* 9.31: the BUG was fixed */
}
}
@@ -400,7 +400,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
if (!p->buf)
{
- p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
+ p->buf = (Byte *)ISzAlloc_Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
if (!p->buf)
return SZ_ERROR_MEM;
}
@@ -435,9 +435,10 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
}
else
{
- srcCur = p->buf + (CODER_BUF_SIZE * (i - 1)) + p->pos[i - 1];
- srcLenCur = p->size[i - 1] - p->pos[i - 1];
- srcFinishedCur = p->finished[i - 1];
+ size_t k = i - 1;
+ srcCur = p->buf + (CODER_BUF_SIZE * k) + p->pos[k];
+ srcLenCur = p->size[k] - p->pos[k];
+ srcFinishedCur = p->finished[k];
}
if (i == p->numCoders - 1)
@@ -465,7 +466,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
}
else
{
- p->pos[i - 1] += srcLenCur;
+ p->pos[(size_t)i - 1] += srcLenCur;
}
if (i == p->numCoders - 1)
@@ -616,7 +617,7 @@ void XzUnpacker_Init(CXzUnpacker *p)
p->padSize = 0;
}
-void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc)
+void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc)
{
MixCoder_Construct(&p->decoder, alloc);
XzUnpacker_Init(p);
diff --git a/C/XzEnc.c b/C/XzEnc.c
index ccac7a8e..90ac3819 100644
--- a/C/XzEnc.c
+++ b/C/XzEnc.c
@@ -1,7 +1,5 @@
/* XzEnc.c -- Xz Encode
-2015-09-16 : Igor Pavlov : Public domain */
-
-#include "Precomp.h"
+2017-04-03 : Igor Pavlov : Public domain */
#include <stdlib.h>
#include <string.h>
@@ -26,7 +24,7 @@
static SRes WriteBytes(ISeqOutStream *s, const void *buf, UInt32 size)
{
- return (s->Write(s, buf, size) == size) ? SZ_OK : SZ_ERROR_WRITE;
+ return (ISeqOutStream_Write(s, buf, size) == size) ? SZ_OK : SZ_ERROR_WRITE;
}
static SRes WriteBytesAndCrc(ISeqOutStream *s, const void *buf, UInt32 size, UInt32 *crc)
@@ -127,7 +125,7 @@ static SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
}
-static SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc)
+static SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAllocPtr alloc)
{
if (!p->blocks || p->numBlocksAllocated == p->numBlocks)
{
@@ -136,13 +134,13 @@ static SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize,
CXzBlockSizes *blocks;
if (newSize / sizeof(CXzBlockSizes) != num)
return SZ_ERROR_MEM;
- blocks = (CXzBlockSizes *)alloc->Alloc(alloc, newSize);
+ blocks = (CXzBlockSizes *)ISzAlloc_Alloc(alloc, newSize);
if (!blocks)
return SZ_ERROR_MEM;
if (p->numBlocks != 0)
{
memcpy(blocks, p->blocks, p->numBlocks * sizeof(CXzBlockSizes));
- alloc->Free(alloc, p->blocks);
+ ISzAlloc_Free(alloc, p->blocks);
}
p->blocks = blocks;
p->numBlocksAllocated = num;
@@ -160,7 +158,7 @@ static SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize,
typedef struct
{
- ISeqInStream p;
+ ISeqInStream vt;
ISeqInStream *realStream;
UInt64 processed;
CXzCheck check;
@@ -177,10 +175,10 @@ static void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest)
XzCheck_Final(&p->check, digest);
}
-static SRes SeqCheckInStream_Read(void *pp, void *data, size_t *size)
+static SRes SeqCheckInStream_Read(const ISeqInStream *pp, void *data, size_t *size)
{
- CSeqCheckInStream *p = (CSeqCheckInStream *)pp;
- SRes res = p->realStream->Read(p->realStream, data, size);
+ CSeqCheckInStream *p = CONTAINER_FROM_VTBL(pp, CSeqCheckInStream, vt);
+ SRes res = ISeqInStream_Read(p->realStream, data, size);
XzCheck_Update(&p->check, data, *size);
p->processed += *size;
return res;
@@ -191,15 +189,15 @@ static SRes SeqCheckInStream_Read(void *pp, void *data, size_t *size)
typedef struct
{
- ISeqOutStream p;
+ ISeqOutStream vt;
ISeqOutStream *realStream;
UInt64 processed;
} CSeqSizeOutStream;
-static size_t MyWrite(void *pp, const void *data, size_t size)
+static size_t MyWrite(const ISeqOutStream *pp, const void *data, size_t size)
{
- CSeqSizeOutStream *p = (CSeqSizeOutStream *)pp;
- size = p->realStream->Write(p->realStream, data, size);
+ CSeqSizeOutStream *p = CONTAINER_FROM_VTBL(pp, CSeqSizeOutStream, vt);
+ size = ISeqOutStream_Write(p->realStream, data, size);
p->processed += size;
return size;
}
@@ -220,9 +218,9 @@ typedef struct
int srcWasFinished;
} CSeqInFilter;
-static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)
+static SRes SeqInFilter_Read(const ISeqInStream *pp, void *data, size_t *size)
{
- CSeqInFilter *p = (CSeqInFilter *)pp;
+ CSeqInFilter *p = CONTAINER_FROM_VTBL(pp, CSeqInFilter, p);
size_t sizeOriginal = *size;
if (sizeOriginal == 0)
return SZ_OK;
@@ -234,7 +232,7 @@ static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)
{
p->curPos = 0;
p->endPos = FILTER_BUF_SIZE;
- RINOK(p->realStream->Read(p->realStream, p->buf, &p->endPos));
+ RINOK(ISeqInStream_Read(p->realStream, p->buf, &p->endPos));
if (p->endPos == 0)
p->srcWasFinished = 1;
}
@@ -262,18 +260,18 @@ static void SeqInFilter_Free(CSeqInFilter *p)
{
if (p->buf)
{
- g_Alloc.Free(&g_Alloc, p->buf);
+ ISzAlloc_Free(&g_Alloc, p->buf);
p->buf = NULL;
}
}
-SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc);
+SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAllocPtr alloc);
static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props)
{
if (!p->buf)
{
- p->buf = g_Alloc.Alloc(&g_Alloc, FILTER_BUF_SIZE);
+ p->buf = ISzAlloc_Alloc(&g_Alloc, FILTER_BUF_SIZE);
if (!p->buf)
return SZ_ERROR_MEM;
}
@@ -292,17 +290,17 @@ static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props)
typedef struct
{
- ISeqInStream p;
+ ISeqInStream vt;
ISeqInStream *inStream;
CSbEnc enc;
} CSbEncInStream;
-static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
+static SRes SbEncInStream_Read(const ISeqInStream *pp, void *data, size_t *size)
{
- CSbEncInStream *p = (CSbEncInStream *)pp;
+ CSbEncInStream *p = CONTAINER_FROM_VTBL(pp, CSbEncInStream, vt);
size_t sizeOriginal = *size;
if (sizeOriginal == 0)
- return S_OK;
+ return SZ_OK;
for (;;)
{
@@ -322,14 +320,14 @@ static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
*size = sizeOriginal;
RINOK(SbEnc_Read(&p->enc, data, size));
if (*size != 0 || !p->enc.needRead)
- return S_OK;
+ return SZ_OK;
}
}
-void SbEncInStream_Construct(CSbEncInStream *p, ISzAlloc *alloc)
+void SbEncInStream_Construct(CSbEncInStream *p, ISzAllocPtr alloc)
{
SbEnc_Construct(&p->enc, alloc);
- p->p.Read = SbEncInStream_Read;
+ p->vt.Read = SbEncInStream_Read;
}
SRes SbEncInStream_Init(CSbEncInStream *p)
@@ -352,12 +350,12 @@ typedef struct
CSbEncInStream sb;
#endif
CSeqInFilter filter;
- ISzAlloc *alloc;
- ISzAlloc *bigAlloc;
+ ISzAllocPtr alloc;
+ ISzAllocPtr bigAlloc;
} CLzma2WithFilters;
-static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, ISzAlloc *bigAlloc)
+static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAllocPtr alloc, ISzAllocPtr bigAlloc)
{
p->alloc = alloc;
p->bigAlloc = bigAlloc;
@@ -451,13 +449,13 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2);
}
- seqSizeOutStream.p.Write = MyWrite;
+ seqSizeOutStream.vt.Write = MyWrite;
seqSizeOutStream.realStream = outStream;
seqSizeOutStream.processed = 0;
- RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p));
+ RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.vt));
- checkInStream.p.Read = SeqCheckInStream_Read;
+ checkInStream.vt.Read = SeqCheckInStream_Read;
checkInStream.realStream = inStream;
SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags));
@@ -466,13 +464,13 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
#ifdef USE_SUBBLOCK
if (fp->id == XZ_ID_Subblock)
{
- lzmaf->sb.inStream = &checkInStream.p;
+ lzmaf->sb.inStream = &checkInStream.vt;
RINOK(SbEncInStream_Init(&lzmaf->sb));
}
else
#endif
{
- lzmaf->filter.realStream = &checkInStream.p;
+ lzmaf->filter.realStream = &checkInStream.vt;
RINOK(SeqInFilter_Init(&lzmaf->filter, filter));
}
}
@@ -480,13 +478,13 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
{
UInt64 packPos = seqSizeOutStream.processed;
- SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
+ SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.vt,
fp ?
#ifdef USE_SUBBLOCK
- (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
+ (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.vt:
#endif
&lzmaf->filter.p:
- &checkInStream.p,
+ &checkInStream.vt,
progress);
RINOK(res);
@@ -500,7 +498,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
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)));
+ RINOK(WriteBytes(&seqSizeOutStream.vt, buf, padSize + XzFlags_GetCheckSize(xz->flags)));
RINOK(Xz_AddIndexRecord(xz, block.unpackSize, seqSizeOutStream.processed - padSize, &g_Alloc));
}
}
diff --git a/C/XzIn.c b/C/XzIn.c
index 07b1cc39..38597674 100644
--- a/C/XzIn.c
+++ b/C/XzIn.c
@@ -1,5 +1,5 @@
/* XzIn.c - Xz input
-2015-11-08 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -70,7 +70,7 @@ SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream)
}
*/
-static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc)
+static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAllocPtr alloc)
{
size_t numBlocks, pos = 1;
UInt32 crc;
@@ -97,7 +97,7 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *
size_t i;
p->numBlocks = numBlocks;
p->numBlocksAllocated = numBlocks;
- p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);
+ p->blocks = ISzAlloc_Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);
if (p->blocks == 0)
return SZ_ERROR_MEM;
for (i = 0; i < numBlocks; i++)
@@ -115,7 +115,7 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *
return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
}
-static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize, ISzAlloc *alloc)
+static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize, ISzAllocPtr alloc)
{
SRes res;
size_t size;
@@ -125,13 +125,13 @@ static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize,
size = (size_t)indexSize;
if (size != indexSize)
return SZ_ERROR_UNSUPPORTED;
- buf = alloc->Alloc(alloc, size);
+ buf = ISzAlloc_Alloc(alloc, size);
if (buf == 0)
return SZ_ERROR_MEM;
res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED);
if (res == SZ_OK)
res = Xz_ReadIndex2(p, buf, size, alloc);
- alloc->Free(alloc, buf);
+ ISzAlloc_Free(alloc, buf);
return res;
}
@@ -142,7 +142,7 @@ static SRes LookInStream_SeekRead_ForArc(ILookInStream *stream, UInt64 offset, v
/* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */
}
-static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc)
+static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAllocPtr alloc)
{
UInt64 indexSize;
Byte buf[XZ_STREAM_FOOTER_SIZE];
@@ -224,7 +224,7 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
SecToRead_CreateVTable(&secToRead);
secToRead.realStream = stream;
- RINOK(Xz_ReadHeader(&headerFlags, &secToRead.s));
+ RINOK(Xz_ReadHeader(&headerFlags, &secToRead.vt));
return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE;
}
}
@@ -238,12 +238,12 @@ void Xzs_Construct(CXzs *p)
p->streams = 0;
}
-void Xzs_Free(CXzs *p, ISzAlloc *alloc)
+void Xzs_Free(CXzs *p, ISzAllocPtr alloc)
{
size_t i;
for (i = 0; i < p->num; i++)
Xz_Free(&p->streams[i], alloc);
- alloc->Free(alloc, p->streams);
+ ISzAlloc_Free(alloc, p->streams);
p->num = p->numAllocated = 0;
p->streams = 0;
}
@@ -277,10 +277,10 @@ UInt64 Xzs_GetPackSize(const CXzs *p)
}
*/
-SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc)
+SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompressProgress *progress, ISzAllocPtr alloc)
{
Int64 endOffset = 0;
- RINOK(stream->Seek(stream, &endOffset, SZ_SEEK_END));
+ RINOK(ILookInStream_Seek(stream, &endOffset, SZ_SEEK_END));
*startOffset = endOffset;
for (;;)
{
@@ -293,20 +293,20 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompr
if (p->num == p->numAllocated)
{
size_t newNum = p->num + p->num / 4 + 1;
- Byte *data = (Byte *)alloc->Alloc(alloc, newNum * sizeof(CXzStream));
+ Byte *data = (Byte *)ISzAlloc_Alloc(alloc, newNum * sizeof(CXzStream));
if (data == 0)
return SZ_ERROR_MEM;
p->numAllocated = newNum;
if (p->num != 0)
memcpy(data, p->streams, p->num * sizeof(CXzStream));
- alloc->Free(alloc, p->streams);
+ ISzAlloc_Free(alloc, p->streams);
p->streams = (CXzStream *)data;
}
p->streams[p->num++] = st;
if (*startOffset == 0)
break;
RINOK(LookInStream_SeekTo(stream, *startOffset));
- if (progress && progress->Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK)
+ if (progress && ICompressProgress_Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK)
return SZ_ERROR_PROGRESS;
}
return SZ_OK;
diff --git a/CPP/7zip/Aes.mak b/CPP/7zip/Aes.mak
index c5a58f28..fbd70aae 100644
--- a/CPP/7zip/Aes.mak
+++ b/CPP/7zip/Aes.mak
@@ -1,7 +1,7 @@
C_OBJS = $(C_OBJS) \
$O\Aes.obj
-!IF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM"
+!IF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM" && "$(CPU)" != "ARM64"
ASM_OBJS = $(ASM_OBJS) \
$O\AesOpt.obj
!ENDIF
diff --git a/CPP/7zip/Archive/7z/7zDecode.cpp b/CPP/7zip/Archive/7z/7zDecode.cpp
index b0d6dd83..d2687479 100644
--- a/CPP/7zip/Archive/7z/7zDecode.cpp
+++ b/CPP/7zip/Archive/7z/7zDecode.cpp
@@ -226,11 +226,13 @@ HRESULT CDecoder::Decode(
, ISequentialOutStream *outStream
, ICompressProgressInfo *compressProgress
+
, ISequentialInStream **
+ #ifdef USE_MIXER_ST
+ inStreamMainRes
+ #endif
- #ifdef USE_MIXER_ST
- inStreamMainRes
- #endif
+ , bool &dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS_DECL
@@ -239,6 +241,8 @@ HRESULT CDecoder::Decode(
#endif
)
{
+ dataAfterEnd_Error = false;
+
const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]];
CFolderEx folderInfo;
folders.ParseFolderEx(folderIndex, folderInfo);
@@ -415,12 +419,14 @@ HRESULT CDecoder::Decode(
}
#endif
+ bool finishMode = false;
{
CMyComPtr<ICompressSetFinishMode> setFinishMode;
decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
if (setFinishMode)
{
- RINOK(setFinishMode->SetFinishMode(BoolToInt(fullUnpack)));
+ finishMode = fullUnpack;
+ RINOK(setFinishMode->SetFinishMode(BoolToInt(finishMode)));
}
}
@@ -450,7 +456,7 @@ HRESULT CDecoder::Decode(
unpackSize :
&folders.CoderUnpackSizes[unpackStreamIndexStart + i];
- _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers);
+ _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers, finishMode);
}
if (outStream)
@@ -530,7 +536,9 @@ HRESULT CDecoder::Decode(
progress2 = new CDecProgress(compressProgress);
ISequentialOutStream *outStreamPointer = outStream;
- return _mixer->Code(inStreamPointers, &outStreamPointer, progress2 ? (ICompressProgressInfo *)progress2 : compressProgress);
+ return _mixer->Code(inStreamPointers, &outStreamPointer,
+ progress2 ? (ICompressProgressInfo *)progress2 : compressProgress,
+ dataAfterEnd_Error);
}
#ifdef USE_MIXER_ST
diff --git a/CPP/7zip/Archive/7z/7zDecode.h b/CPP/7zip/Archive/7z/7zDecode.h
index 5b729f6c..62a38038 100644
--- a/CPP/7zip/Archive/7z/7zDecode.h
+++ b/CPP/7zip/Archive/7z/7zDecode.h
@@ -53,7 +53,9 @@ public:
, ISequentialOutStream *outStream
, ICompressProgressInfo *compressProgress
+
, ISequentialInStream **inStreamMainRes
+ , bool &dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS_DECL
diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp
index 97e9ad7a..b206faa5 100644
--- a/CPP/7zip/Archive/7z/7zEncode.cpp
+++ b/CPP/7zip/Archive/7z/7zEncode.cpp
@@ -333,7 +333,7 @@ HRESULT CEncoder::Encode(
}
for (i = 0; i < numMethods; i++)
- _mixer->SetCoderInfo(i, NULL, NULL);
+ _mixer->SetCoderInfo(i, NULL, NULL, false);
/* inStreamSize can be used by BCJ2 to set optimal range of conversion.
@@ -429,10 +429,12 @@ HRESULT CEncoder::Encode(
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
outStreamPointers.Add(tempBuffers[i - 1]);
+ bool dataAfterEnd_Error;
+
RINOK(_mixer->Code(
&inStreamPointer,
&outStreamPointers.Front(),
- mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress));
+ mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress, dataAfterEnd_Error));
if (_bindInfo.PackStreams.Size() != 0)
packSizes.Add(outStreamSizeCountSpec->GetSize());
diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp
index 05fd80de..8fea5aa5 100644
--- a/CPP/7zip/Archive/7z/7zExtract.cpp
+++ b/CPP/7zip/Archive/7z/7zExtract.cpp
@@ -348,6 +348,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
#endif
+ bool dataAfterEnd_Error = false;
+
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_VARS
_inStream,
@@ -358,6 +360,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
outStream,
progress,
NULL // *inStreamMainRes
+ , dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) && !defined(_SFX)
@@ -365,13 +368,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
#endif
);
- if (result == S_FALSE || result == E_NOTIMPL)
+ if (result == S_FALSE || result == E_NOTIMPL || dataAfterEnd_Error)
{
bool wasFinished = folderOutStream->WasWritingFinished();
-
- int resOp = (result == S_FALSE ?
- NExtract::NOperationResult::kDataError :
- NExtract::NOperationResult::kUnsupportedMethod);
+
+ int resOp = NExtract::NOperationResult::kDataError;
+
+ if (result != S_FALSE)
+ {
+ if (result == E_NOTIMPL)
+ resOp = NExtract::NOperationResult::kUnsupportedMethod;
+ else if (wasFinished && dataAfterEnd_Error)
+ resOp = NExtract::NOperationResult::kDataAfterEnd;
+ }
RINOK(folderOutStream->FlushCorrupted(resOp));
diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp
index ccd2c624..2642e691 100644
--- a/CPP/7zip/Archive/7z/7zHandler.cpp
+++ b/CPP/7zip/Archive/7z/7zHandler.cpp
@@ -540,7 +540,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
*/
const CFileItem &item = _db.Files[index];
- UInt32 index2 = index;
+ const UInt32 index2 = index;
switch (propID)
{
@@ -575,7 +575,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidCTime: SetFileTimeProp_From_UInt64Def(value, _db.CTime, index2); break;
case kpidATime: SetFileTimeProp_From_UInt64Def(value, _db.ATime, index2); break;
case kpidMTime: SetFileTimeProp_From_UInt64Def(value, _db.MTime, index2); break;
- case kpidAttrib: if (item.AttribDefined) PropVarEm_Set_UInt32(value, item.Attrib); break;
+ case kpidAttrib: if (_db.Attrib.ValidAndDefined(index2)) PropVarEm_Set_UInt32(value, _db.Attrib.Vals[index2]); break;
case kpidCRC: if (item.CrcDefined) PropVarEm_Set_UInt32(value, item.Crc); break;
case kpidEncrypted: PropVarEm_Set_Bool(value, IsFolderEncrypted(_db.FileIndexToFolderIndexMap[index2])); break;
case kpidIsAnti: PropVarEm_Set_Bool(value, _db.IsItemAnti(index2)); break;
diff --git a/CPP/7zip/Archive/7z/7zHandler.h b/CPP/7zip/Archive/7z/7zHandler.h
index d46401af..89e3275f 100644
--- a/CPP/7zip/Archive/7z/7zHandler.h
+++ b/CPP/7zip/Archive/7z/7zHandler.h
@@ -54,6 +54,7 @@ public:
CBoolPair Write_CTime;
CBoolPair Write_ATime;
CBoolPair Write_MTime;
+ CBoolPair Write_Attrib;
bool _useMultiThreadMixer;
diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
index 2b86ed26..c4fabed7 100644
--- a/CPP/7zip/Archive/7z/7zHandlerOut.cpp
+++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
@@ -18,11 +18,12 @@ using namespace NWindows;
namespace NArchive {
namespace N7z {
-static const char *k_LZMA_Name = "LZMA";
-static const char *kDefaultMethodName = "LZMA2";
-static const char *k_Copy_Name = "Copy";
+#define k_LZMA_Name "LZMA"
+#define kDefaultMethodName "LZMA2"
+#define k_Copy_Name "Copy"
+
+#define k_MatchFinder_ForHeaders "BT2"
-static const char *k_MatchFinder_ForHeaders = "BT2";
static const UInt32 k_NumFastBytes_ForHeaders = 273;
static const UInt32 k_Level_ForHeaders = 5;
static const UInt32 k_Dictionary_ForHeaders =
@@ -113,11 +114,11 @@ HRESULT CHandler::SetMainMethod(
FOR_VECTOR (i, methods)
{
COneMethodInfo &oneMethodInfo = methods[i];
- SetGlobalLevelAndThreads(oneMethodInfo
- #ifndef _7ZIP_ST
- , numThreads
- #endif
- );
+
+ SetGlobalLevelTo(oneMethodInfo);
+ #ifndef _7ZIP_ST
+ CMultiMethodProps::SetMethodThreadsTo(oneMethodInfo, numThreads);
+ #endif
CMethodFull &methodFull = methodMode.Methods.AddNew();
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
@@ -282,15 +283,18 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
+ bool need_Attrib = (Write_Attrib.Def && Write_Attrib.Val || !Write_Attrib.Def);
if (db && !db->Files.IsEmpty())
{
if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
if (!Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty();
+ if (!Write_Attrib.Def) need_Attrib = !db->Attrib.Defs.IsEmpty();
}
- UString s;
+ // UString s;
+ UString name;
for (UInt32 i = 0; i < numItems; i++)
{
@@ -307,7 +311,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
ui.IsAnti = false;
ui.Size = 0;
- UString name;
+ name.Empty();
// bool isAltStream = false;
if (ui.IndexInArchive != -1)
{
@@ -334,6 +338,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (ui.NewProps)
{
bool folderStatusIsDefined;
+ if (need_Attrib)
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
@@ -377,7 +382,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
else
{
- name = NItemName::MakeLegalName(prop.bstrVal);
+ name = prop.bstrVal;
+ NItemName::ReplaceSlashes_OsToUnix(name);
}
}
{
@@ -614,6 +620,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options.HeaderOptions.WriteCTime = Write_CTime;
options.HeaderOptions.WriteATime = Write_ATime;
options.HeaderOptions.WriteMTime = Write_MTime;
+ options.HeaderOptions.WriteAttrib = Write_Attrib;
*/
options.NumSolidFiles = _numSolidFiles;
@@ -705,6 +712,7 @@ void COutHandler::InitProps()
Write_CTime.Init();
Write_ATime.Init();
Write_MTime.Init();
+ Write_Attrib.Init();
_useMultiThreadMixer = true;
@@ -830,6 +838,8 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
+ if (name.IsEqualTo("tr")) return PROPVARIANT_to_BoolPair(value, Write_Attrib);
+
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
if (name.IsEqualTo("qs")) return PROPVARIANT_to_bool(value, _useTypeSorting);
diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp
index d8c27175..3db5f515 100644
--- a/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/CPP/7zip/Archive/7z/7zIn.cpp
@@ -32,6 +32,21 @@ using namespace NCOM;
namespace NArchive {
namespace N7z {
+unsigned BoolVector_CountSum(const CBoolVector &v)
+{
+ unsigned sum = 0;
+ const unsigned size = v.Size();
+ for (unsigned i = 0; i < size; i++)
+ if (v[i])
+ sum++;
+ return sum;
+}
+
+static inline bool BoolVector_Item_IsValidAndTrue(const CBoolVector &v, unsigned i)
+{
+ return (i < v.Size() ? v[i] : false);
+}
+
static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
{
v.ClearAndSetSize(size);
@@ -40,6 +55,7 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
p[i] = false;
}
+
class CInArchiveException {};
class CUnsupportedFeatureException: public CInArchiveException {};
@@ -566,21 +582,30 @@ void CInArchive::WaitId(UInt64 id)
}
}
-void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
+
+void CInArchive::Read_UInt32_Vector(CUInt32DefVector &v)
{
- ReadBoolVector2(numItems, crcs.Defs);
- crcs.Vals.ClearAndSetSize(numItems);
- UInt32 *p = &crcs.Vals[0];
- const bool *defs = &crcs.Defs[0];
+ unsigned numItems = v.Defs.Size();
+ v.Vals.ClearAndSetSize(numItems);
+ UInt32 *p = &v.Vals[0];
+ const bool *defs = &v.Defs[0];
for (unsigned i = 0; i < numItems; i++)
{
- UInt32 crc = 0;
+ UInt32 a = 0;
if (defs[i])
- crc = ReadUInt32();
- p[i] = crc;
+ a = ReadUInt32();
+ p[i] = a;
}
}
+
+void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
+{
+ ReadBoolVector2(numItems, crcs.Defs);
+ Read_UInt32_Vector(crcs);
+}
+
+
#define k_Scan_NumCoders_MAX 64
#define k_Scan_NumCodersStreams_in_Folder_MAX 64
@@ -1075,6 +1100,8 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->Init(data, unpackSize);
+ bool dataAfterEnd_Error = false;
+
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_LOC_VARS
_stream, baseOffset + dataOffset,
@@ -1083,16 +1110,23 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
outStream,
NULL, // *compressProgress
+
NULL // **inStreamMainRes
+ , dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) && !defined(_SFX)
, false // mtMode
, 1 // numThreads
#endif
+
);
+
RINOK(result);
+ if (dataAfterEnd_Error)
+ ThereIsHeaderError = true;
+
if (folders.FolderCRCs.ValidAndDefined(i))
if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
ThrowIncorrect();
@@ -1148,19 +1182,10 @@ HRESULT CInArchive::ReadHeader(
type = ReadID();
}
- db.Files.Clear();
-
if (type == NID::kFilesInfo)
{
const CNum numFiles = ReadNum();
- db.Files.ClearAndSetSize(numFiles);
- /*
- db.Files.Reserve(numFiles);
- CNum i;
- for (i = 0; i < numFiles; i++)
- db.Files.Add(CFileItem());
- */
db.ArcInfo.FileInfoPopIDs.Add(NID::kSize);
// if (!db.PackSizes.IsEmpty())
@@ -1169,7 +1194,6 @@ HRESULT CInArchive::ReadHeader(
db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC);
CBoolVector emptyStreamVector;
- BoolVector_Fill_False(emptyStreamVector, (unsigned)numFiles);
CBoolVector emptyFileVector;
CBoolVector antiFileVector;
CNum numEmptyStreams = 0;
@@ -1197,10 +1221,10 @@ HRESULT CInArchive::ReadHeader(
size_t rem = _inByteBack->GetRem();
db.NamesBuf.Alloc(rem);
ReadBytes(db.NamesBuf, rem);
- db.NameOffsets.Alloc(db.Files.Size() + 1);
+ db.NameOffsets.Alloc(numFiles + 1);
size_t pos = 0;
unsigned i;
- for (i = 0; i < db.Files.Size(); i++)
+ for (i = 0; i < numFiles; i++)
{
size_t curRem = (rem - pos) / 2;
const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos);
@@ -1216,36 +1240,31 @@ HRESULT CInArchive::ReadHeader(
ThereIsHeaderError = true;
break;
}
+
case NID::kWinAttrib:
{
- CBoolVector boolVector;
- ReadBoolVector2(db.Files.Size(), boolVector);
+ ReadBoolVector2(numFiles, db.Attrib.Defs);
CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector);
- for (CNum i = 0; i < numFiles; i++)
- {
- CFileItem &file = db.Files[i];
- file.AttribDefined = boolVector[i];
- if (file.AttribDefined)
- file.Attrib = ReadUInt32();
- }
+ Read_UInt32_Vector(db.Attrib);
break;
}
+
/*
case NID::kIsAux:
{
- ReadBoolVector(db.Files.Size(), db.IsAux);
+ ReadBoolVector(numFiles, db.IsAux);
break;
}
case NID::kParent:
{
db.IsTree = true;
// CBoolVector boolVector;
- // ReadBoolVector2(db.Files.Size(), boolVector);
+ // ReadBoolVector2(numFiles, boolVector);
// CStreamSwitch streamSwitch;
// streamSwitch.Set(this, &dataVector);
CBoolVector boolVector;
- ReadBoolVector2(db.Files.Size(), boolVector);
+ ReadBoolVector2(numFiles, boolVector);
db.ThereAreAltStreams = false;
for (i = 0; i < numFiles; i++)
@@ -1264,14 +1283,9 @@ HRESULT CInArchive::ReadHeader(
case NID::kEmptyStream:
{
ReadBoolVector(numFiles, emptyStreamVector);
- numEmptyStreams = 0;
- for (CNum i = 0; i < (CNum)emptyStreamVector.Size(); i++)
- if (emptyStreamVector[i])
- numEmptyStreams++;
-
- BoolVector_Fill_False(emptyFileVector, numEmptyStreams);
- BoolVector_Fill_False(antiFileVector, numEmptyStreams);
-
+ numEmptyStreams = BoolVector_CountSum(emptyStreamVector);
+ emptyFileVector.Clear();
+ antiFileVector.Clear();
break;
}
case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break;
@@ -1314,7 +1328,7 @@ HRESULT CInArchive::ReadHeader(
ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset);
}
db.SecureIDs.Clear();
- for (unsigned i = 0; i < db.Files.Size(); i++)
+ for (unsigned i = 0; i < numFiles; i++)
{
db.SecureIDs.Add(ReadNum());
// db.SecureIDs.Add(ReadUInt32());
@@ -1359,22 +1373,21 @@ HRESULT CInArchive::ReadHeader(
CNum emptyFileIndex = 0;
CNum sizeIndex = 0;
- CNum numAntiItems = 0;
+ const CNum numAntiItems = BoolVector_CountSum(antiFileVector);
- CNum i;
+ if (numAntiItems != 0)
+ db.IsAnti.ClearAndSetSize(numFiles);
- for (i = 0; i < numEmptyStreams; i++)
- if (antiFileVector[i])
- numAntiItems++;
+ db.Files.ClearAndSetSize(numFiles);
- for (i = 0; i < numFiles; i++)
+ for (CNum i = 0; i < numFiles; i++)
{
CFileItem &file = db.Files[i];
bool isAnti;
- file.HasStream = !emptyStreamVector[i];
file.Crc = 0;
- if (file.HasStream)
+ if (!BoolVector_Item_IsValidAndTrue(emptyStreamVector, i))
{
+ file.HasStream = true;
file.IsDir = false;
isAnti = false;
file.Size = unpackSizes[sizeIndex];
@@ -1385,26 +1398,31 @@ HRESULT CInArchive::ReadHeader(
}
else
{
- file.IsDir = !emptyFileVector[emptyFileIndex];
- isAnti = antiFileVector[emptyFileIndex];
+ file.HasStream = false;
+ file.IsDir = !BoolVector_Item_IsValidAndTrue(emptyFileVector, emptyFileIndex);
+ isAnti = BoolVector_Item_IsValidAndTrue(antiFileVector, emptyFileIndex);
emptyFileIndex++;
file.Size = 0;
file.CrcDefined = false;
}
if (numAntiItems != 0)
- db.IsAnti.Add(isAnti);
+ db.IsAnti[i] = isAnti;
}
+
}
+
db.FillLinks();
- /*
- if (type != NID::kEnd)
- ThrowIncorrect();
- if (_inByteBack->GetRem() != 0)
- ThrowIncorrect();
- */
+
+ if (type != NID::kEnd || _inByteBack->GetRem() != 0)
+ {
+ db.UnsupportedFeatureWarning = true;
+ // ThrowIncorrect();
+ }
+
return S_OK;
}
+
void CDbEx::FillLinks()
{
FolderStartFileIndex.Alloc(NumFolders);
@@ -1466,6 +1484,7 @@ void CDbEx::FillLinks()
}
}
+
HRESULT CInArchive::ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
@@ -1610,6 +1629,7 @@ HRESULT CInArchive::ReadDatabase2(
);
}
+
HRESULT CInArchive::ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h
index 3592e99b..2d5fbb79 100644
--- a/CPP/7zip/Archive/7z/7zIn.h
+++ b/CPP/7zip/Archive/7z/7zIn.h
@@ -115,6 +115,7 @@ struct CDatabase: public CFolders
CUInt64DefVector ATime;
CUInt64DefVector MTime;
CUInt64DefVector StartPos;
+ CUInt32DefVector Attrib;
CBoolVector IsAnti;
/*
CBoolVector IsAux;
@@ -146,6 +147,7 @@ struct CDatabase: public CFolders
ATime.Clear();
MTime.Clear();
StartPos.Clear();
+ Attrib.Clear();
IsAnti.Clear();
// IsAux.Clear();
}
@@ -369,6 +371,8 @@ class CInArchive
void SkipData() { _inByteBack->SkipData(); }
void WaitId(UInt64 id);
+ void Read_UInt32_Vector(CUInt32DefVector &v);
+
void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs);
diff --git a/CPP/7zip/Archive/7z/7zItem.h b/CPP/7zip/Archive/7z/7zItem.h
index 5e2b58f2..ee4aed3f 100644
--- a/CPP/7zip/Archive/7z/7zItem.h
+++ b/CPP/7zip/Archive/7z/7zItem.h
@@ -26,12 +26,14 @@ struct CCoderInfo
bool IsSimpleCoder() const { return NumStreams == 1; }
};
+
struct CBond
{
UInt32 PackIndex;
UInt32 UnpackIndex;
};
+
struct CFolder
{
CLASS_NO_COPY(CFolder)
@@ -87,6 +89,7 @@ public:
}
};
+
struct CUInt32DefVector
{
CBoolVector Defs;
@@ -110,9 +113,25 @@ struct CUInt32DefVector
Vals.ReserveDown();
}
+ bool GetItem(unsigned index, UInt32 &value) const
+ {
+ if (index < Defs.Size() && Defs[index])
+ {
+ value = Vals[index];
+ return true;
+ }
+ value = 0;
+ return false;
+ }
+
bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; }
+
+ bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
+
+ void SetItem(unsigned index, bool defined, UInt32 value);
};
+
struct CUInt64DefVector
{
CBoolVector Defs;
@@ -141,15 +160,15 @@ struct CUInt64DefVector
return false;
}
- void SetItem(unsigned index, bool defined, UInt64 value);
-
bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
+
+ void SetItem(unsigned index, bool defined, UInt64 value);
};
+
struct CFileItem
{
UInt64 Size;
- UInt32 Attrib;
UInt32 Crc;
/*
int Parent;
@@ -159,23 +178,23 @@ struct CFileItem
// stream in some folder. It can be empty stream
bool IsDir;
bool CrcDefined;
- bool AttribDefined;
+
+ /*
+ void Clear()
+ {
+ HasStream = true;
+ IsDir = false;
+ CrcDefined = false;
+ }
CFileItem():
- /*
- Parent(-1),
- IsAltStream(false),
- */
+ // Parent(-1),
+ // IsAltStream(false),
HasStream(true),
IsDir(false),
CrcDefined(false),
- AttribDefined(false)
{}
- void SetAttrib(UInt32 attrib)
- {
- AttribDefined = true;
- Attrib = attrib;
- }
+ */
};
}}
diff --git a/CPP/7zip/Archive/7z/7zOut.cpp b/CPP/7zip/Archive/7z/7zOut.cpp
index 3e70f466..904e32c5 100644
--- a/CPP/7zip/Archive/7z/7zOut.cpp
+++ b/CPP/7zip/Archive/7z/7zOut.cpp
@@ -330,13 +330,11 @@ void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector)
WriteBoolVector(boolVector);
}
+unsigned BoolVector_CountSum(const CBoolVector &v);
+
void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
{
- unsigned numDefined = 0;
- unsigned i;
- for (i = 0; i < digests.Defs.Size(); i++)
- if (digests.Defs[i])
- numDefined++;
+ const unsigned numDefined = BoolVector_CountSum(digests.Defs);
if (numDefined == 0)
return;
@@ -348,7 +346,8 @@ void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
WriteByte(0);
WriteBoolVector(digests.Defs);
}
- for (i = 0; i < digests.Defs.Size(); i++)
+
+ for (unsigned i = 0; i < digests.Defs.Size(); i++)
if (digests.Defs[i])
WriteUInt32(digests.Vals[i]);
}
@@ -453,10 +452,12 @@ void COutArchive::WriteSubStreamsInfo(const CObjectVector<CFolder> &folders,
// 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field.
-void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
+void COutArchive::SkipToAligned(unsigned pos, unsigned alignShifts)
{
if (!_useAlign)
return;
+
+ const unsigned alignSize = (unsigned)1 << alignShifts;
pos += (unsigned)GetPos();
pos &= (alignSize - 1);
if (pos == 0)
@@ -471,11 +472,11 @@ void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
WriteByte(0);
}
-void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize)
+void COutArchive::WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts)
{
const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);
- const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2;
- SkipAlign(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSize);
+ const UInt64 dataSize = ((UInt64)numDefined << itemSizeShifts) + bvSize + 2;
+ SkipToAligned(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSizeShifts);
WriteByte(type);
WriteNumber(dataSize);
@@ -486,24 +487,18 @@ void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefin
WriteByte(0);
WriteBoolVector(v);
}
- WriteByte(0);
+ WriteByte(0); // 0 means no switching to external stream
}
void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type)
{
- unsigned numDefined = 0;
-
- unsigned i;
- for (i = 0; i < v.Defs.Size(); i++)
- if (v.Defs[i])
- numDefined++;
-
+ const unsigned numDefined = BoolVector_CountSum(v.Defs);
if (numDefined == 0)
return;
- WriteAlignedBoolHeader(v.Defs, numDefined, type, 8);
+ WriteAlignedBools(v.Defs, numDefined, type, 3);
- for (i = 0; i < v.Defs.Size(); i++)
+ for (unsigned i = 0; i < v.Defs.Size(); i++)
if (v.Defs[i])
WriteUInt64(v.Vals[i]);
}
@@ -648,7 +643,7 @@ void COutArchive::WriteHeader(
if (numDefined > 0)
{
namesDataSize++;
- SkipAlign(2 + GetBigNumberSize(namesDataSize), 16);
+ SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4);
WriteByte(NID::kName);
WriteNumber(namesDataSize);
@@ -673,28 +668,15 @@ void COutArchive::WriteHeader(
{
/* ---------- Write Attrib ---------- */
- CBoolVector boolVector;
- boolVector.ClearAndSetSize(db.Files.Size());
- unsigned numDefined = 0;
-
- {
- FOR_VECTOR (i, db.Files)
- {
- bool defined = db.Files[i].AttribDefined;
- boolVector[i] = defined;
- if (defined)
- numDefined++;
- }
- }
+ const unsigned numDefined = BoolVector_CountSum(db.Attrib.Defs);
if (numDefined != 0)
{
- WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttrib, 4);
- FOR_VECTOR (i, db.Files)
+ WriteAlignedBools(db.Attrib.Defs, numDefined, NID::kWinAttrib, 2);
+ FOR_VECTOR (i, db.Attrib.Defs)
{
- const CFileItem &file = db.Files[i];
- if (file.AttribDefined)
- WriteUInt32(file.Attrib);
+ if (db.Attrib.Defs[i])
+ WriteUInt32(db.Attrib.Vals[i]);
}
}
}
@@ -702,18 +684,8 @@ void COutArchive::WriteHeader(
/*
{
// ---------- Write IsAux ----------
- unsigned numAux = 0;
- const CBoolVector &isAux = db.IsAux;
- for (i = 0; i < isAux.Size(); i++)
- if (isAux[i])
- numAux++;
- if (numAux > 0)
- {
- const unsigned bvSize = Bv_GetSizeInBytes(isAux);
- WriteByte(NID::kIsAux);
- WriteNumber(bvSize);
- WriteBoolVector(isAux);
- }
+ if (BoolVector_CountSum(db.IsAux) != 0)
+ WritePropBoolVector(NID::kIsAux, db.IsAux);
}
{
@@ -734,10 +706,10 @@ void COutArchive::WriteHeader(
}
if (numParentLinks > 0)
{
- // WriteAlignedBoolHeader(boolVector, numDefined, NID::kParent, 4);
+ // WriteAlignedBools(boolVector, numDefined, NID::kParent, 2);
const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector);
const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1;
- SkipAlign(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 4);
+ SkipToAligned(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 2);
WriteByte(NID::kParent);
WriteNumber(dataSize);
@@ -765,7 +737,7 @@ void COutArchive::WriteHeader(
// secureDataSize += db.SecureIDs.Size() * 4;
for (i = 0; i < db.SecureIDs.Size(); i++)
secureDataSize += GetBigNumberSize(db.SecureIDs[i]);
- SkipAlign(2 + GetBigNumberSize(secureDataSize), 4);
+ SkipToAligned(2 + GetBigNumberSize(secureDataSize), 2);
WriteByte(NID::kNtSecure);
WriteNumber(secureDataSize);
WriteByte(0);
@@ -888,6 +860,18 @@ HRESULT COutArchive::WriteDatabase(
}
}
+void CUInt32DefVector::SetItem(unsigned index, bool defined, UInt32 value)
+{
+ while (index >= Defs.Size())
+ Defs.Add(false);
+ Defs[index] = defined;
+ if (!defined)
+ return;
+ while (index >= Vals.Size())
+ Vals.Add(0);
+ Vals[index] = value;
+}
+
void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value)
{
while (index >= Defs.Size())
@@ -907,6 +891,7 @@ void CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2
ATime.SetItem(index, file2.ATimeDefined, file2.ATime);
MTime.SetItem(index, file2.MTimeDefined, file2.MTime);
StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos);
+ Attrib.SetItem(index, file2.AttribDefined, file2.Attrib);
SetItem_Anti(index, file2.IsAnti);
// SetItem_Aux(index, file2.IsAux);
Names.Add(name);
diff --git a/CPP/7zip/Archive/7z/7zOut.h b/CPP/7zip/Archive/7z/7zOut.h
index 6c902668..1ebad56d 100644
--- a/CPP/7zip/Archive/7z/7zOut.h
+++ b/CPP/7zip/Archive/7z/7zOut.h
@@ -45,6 +45,7 @@ public:
size_t GetPos() const { return _pos; }
};
+
struct CHeaderOptions
{
bool CompressMainHeader;
@@ -71,24 +72,31 @@ struct CFileItem2
UInt64 ATime;
UInt64 MTime;
UInt64 StartPos;
+ UInt32 Attrib;
+
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
bool StartPosDefined;
+ bool AttribDefined;
bool IsAnti;
// bool IsAux;
+ /*
void Init()
{
CTimeDefined = false;
ATimeDefined = false;
MTimeDefined = false;
StartPosDefined = false;
+ AttribDefined = false;
IsAnti = false;
// IsAux = false;
}
+ */
};
+
struct COutFolders
{
CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
@@ -111,6 +119,7 @@ struct COutFolders
}
};
+
struct CArchiveDatabaseOut: public COutFolders
{
CRecordVector<UInt64> PackSizes;
@@ -123,10 +132,11 @@ struct CArchiveDatabaseOut: public COutFolders
CUInt64DefVector ATime;
CUInt64DefVector MTime;
CUInt64DefVector StartPos;
- CRecordVector<bool> IsAnti;
+ CUInt32DefVector Attrib;
+ CBoolVector IsAnti;
/*
- CRecordVector<bool> IsAux;
+ CBoolVector IsAux;
CByteBuffer SecureBuf;
CRecordVector<UInt32> SecureSizes;
@@ -154,6 +164,7 @@ struct CArchiveDatabaseOut: public COutFolders
ATime.Clear();
MTime.Clear();
StartPos.Clear();
+ Attrib.Clear();
IsAnti.Clear();
/*
@@ -176,6 +187,7 @@ struct CArchiveDatabaseOut: public COutFolders
ATime.ReserveDown();
MTime.ReserveDown();
StartPos.ReserveDown();
+ Attrib.ReserveDown();
IsAnti.ReserveDown();
/*
@@ -196,11 +208,12 @@ struct CArchiveDatabaseOut: public COutFolders
{
unsigned size = Files.Size();
return (
- CTime.CheckSize(size) &&
- ATime.CheckSize(size) &&
- MTime.CheckSize(size) &&
- StartPos.CheckSize(size) &&
- (size == IsAnti.Size() || IsAnti.Size() == 0));
+ CTime.CheckSize(size)
+ && ATime.CheckSize(size)
+ && MTime.CheckSize(size)
+ && StartPos.CheckSize(size)
+ && Attrib.CheckSize(size)
+ && (size == IsAnti.Size() || IsAnti.Size() == 0));
}
bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
@@ -224,6 +237,7 @@ struct CArchiveDatabaseOut: public COutFolders
void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name);
};
+
class COutArchive
{
UInt64 _prefixHeaderPos;
@@ -261,8 +275,8 @@ class COutArchive
const CRecordVector<UInt64> &unpackSizes,
const CUInt32DefVector &digests);
- void SkipAlign(unsigned pos, unsigned alignSize);
- void WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize);
+ void SkipToAligned(unsigned pos, unsigned alignShifts);
+ void WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts);
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
HRESULT EncodeStream(
diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp
index 68e57f09..e0740e46 100644
--- a/CPP/7zip/Archive/7z/7zUpdate.cpp
+++ b/CPP/7zip/Archive/7z/7zUpdate.cpp
@@ -1088,18 +1088,23 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode,
}
-static void FromUpdateItemToFileItem(const CUpdateItem &ui,
- CFileItem &file, CFileItem2 &file2)
+static void UpdateItem_To_FileItem2(const CUpdateItem &ui, CFileItem2 &file2)
{
- if (ui.AttribDefined)
- file.SetAttrib(ui.Attrib);
-
+ file2.Attrib = ui.Attrib; file2.AttribDefined = ui.AttribDefined;
file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined;
file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined;
file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined;
file2.IsAnti = ui.IsAnti;
// file2.IsAux = false;
file2.StartPosDefined = false;
+ // file2.StartPos = 0;
+}
+
+
+static void UpdateItem_To_FileItem(const CUpdateItem &ui,
+ CFileItem &file, CFileItem2 &file2)
+{
+ UpdateItem_To_FileItem2(ui, file2);
file.Size = ui.Size;
file.IsDir = ui.IsDir;
@@ -1107,6 +1112,8 @@ static void FromUpdateItemToFileItem(const CUpdateItem &ui,
// file.IsAltStream = ui.IsAltStream;
}
+
+
class CRepackInStreamWithSizes:
public ISequentialInStream,
public ICompressGetSubStreamSize,
@@ -1437,6 +1444,7 @@ public:
#ifndef _7ZIP_ST
+ bool dataAfterEnd_Error;
HRESULT Result;
CMyComPtr<IInStream> InStream;
@@ -1479,7 +1487,9 @@ void CThreadDecoder::Execute()
bool passwordIsDefined = false;
UString password;
#endif
-
+
+ dataAfterEnd_Error = false;
+
Result = Decoder.Decode(
EXTERNAL_CODECS_LOC_VARS
InStream,
@@ -1491,12 +1501,15 @@ void CThreadDecoder::Execute()
Fos,
NULL, // compressProgress
+
NULL // *inStreamMainRes
+ , dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
#ifndef _7ZIP_ST
, MtMode, NumThreads
#endif
+
);
}
catch(...)
@@ -1541,6 +1554,7 @@ static void GetFile(const CDatabase &inDb, unsigned index, CFileItem &file, CFil
file2.ATimeDefined = inDb.ATime.GetItem(index, file2.ATime);
file2.MTimeDefined = inDb.MTime.GetItem(index, file2.MTime);
file2.StartPosDefined = inDb.StartPos.GetItem(index, file2.StartPos);
+ file2.AttribDefined = inDb.Attrib.GetItem(index, file2.Attrib);
file2.IsAnti = inDb.IsItemAnti(index);
// file2.IsAux = inDb.IsItemAux(index);
}
@@ -1837,7 +1851,7 @@ HRESULT Update(
continue;
secureID = ui.SecureIndex;
if (ui.NewProps)
- FromUpdateItemToFileItem(ui, file, file2);
+ UpdateItem_To_FileItem(ui, file, file2);
else
GetFile(*db, ui.IndexInArchive, file, file2);
}
@@ -1887,7 +1901,8 @@ HRESULT Update(
UString name;
if (ui.NewProps)
{
- FromUpdateItemToFileItem(ui, file, file2);
+ UpdateItem_To_FileItem(ui, file, file2);
+ file.CrcDefined = false;
name = ui.Name;
}
else
@@ -2107,6 +2122,8 @@ HRESULT Update(
#endif
CMyComPtr<ISequentialInStream> decodedStream;
+ bool dataAfterEnd_Error = false;
+
HRESULT res = threadDecoder.Decoder.Decode(
EXTERNAL_CODECS_LOC_VARS
inStream,
@@ -2117,13 +2134,16 @@ HRESULT Update(
NULL, // *outStream
NULL, // *compressProgress
+
&decodedStream
+ , dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
#ifndef _7ZIP_ST
, false // mtMode
, 1 // numThreads
#endif
+
);
RINOK(res);
@@ -2175,16 +2195,19 @@ HRESULT Update(
HRESULT decodeRes = threadDecoder.Result;
// if (res == k_My_HRESULT_CRC_ERROR)
- if (decodeRes == S_FALSE)
+ if (decodeRes == S_FALSE || threadDecoder.dataAfterEnd_Error)
{
if (extractCallback)
{
RINOK(extractCallback->ReportExtractResult(
NEventIndexType::kInArcIndex, db->FolderStartFileIndex[folderIndex],
// NEventIndexType::kBlockIndex, (UInt32)folderIndex,
- NExtract::NOperationResult::kDataError));
+ (decodeRes != S_OK ?
+ NExtract::NOperationResult::kDataError :
+ NExtract::NOperationResult::kDataAfterEnd)));
}
- return E_FAIL;
+ if (decodeRes != S_OK)
+ return E_FAIL;
}
RINOK(decodeRes);
if (encodeRes == S_OK)
@@ -2224,12 +2247,7 @@ HRESULT Update(
CNum indexInFolder = 0;
for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
{
- CFileItem file;
- CFileItem2 file2;
- GetFile(*db, fi, file, file2);
- UString name;
- db->GetPath(fi, name);
- if (file.HasStream)
+ if (db->Files[fi].HasStream)
{
indexInFolder++;
int updateIndex = fileIndexToUpdateIndexMap[fi];
@@ -2238,17 +2256,21 @@ HRESULT Update(
const CUpdateItem &ui = updateItems[updateIndex];
if (ui.NewData)
continue;
+
+ UString name;
+ CFileItem file;
+ CFileItem2 file2;
+ GetFile(*db, fi, file, file2);
+
if (ui.NewProps)
{
- CFileItem uf;
- FromUpdateItemToFileItem(ui, uf, file2);
- uf.Size = file.Size;
- uf.Crc = file.Crc;
- uf.CrcDefined = file.CrcDefined;
- uf.HasStream = file.HasStream;
- file = uf;
+ UpdateItem_To_FileItem2(ui, file2);
+ file.IsDir = ui.IsDir;
name = ui.Name;
}
+ else
+ db->GetPath(fi, name);
+
/*
file.Parent = ui.ParentFolderIndex;
if (ui.TreeFolderIndex >= 0)
@@ -2292,7 +2314,7 @@ HRESULT Update(
const CUpdateItem &ui = updateItems[index];
CFileItem file;
if (ui.NewProps)
- FromUpdateItemToFileItem(ui, file);
+ UpdateItem_To_FileItem(ui, file);
else
file = db.Files[ui.IndexInArchive];
if (file.IsAnti || file.IsDir)
@@ -2367,7 +2389,7 @@ HRESULT Update(
UString name;
if (ui.NewProps)
{
- FromUpdateItemToFileItem(ui, file, file2);
+ UpdateItem_To_FileItem(ui, file, file2);
name = ui.Name;
}
else
@@ -2386,7 +2408,7 @@ HRESULT Update(
{
skippedSize += ui.Size;
continue;
- // file.Name.AddAscii(".locked");
+ // file.Name += ".locked";
}
file.Crc = inStreamSpec->CRCs[subIndex];
diff --git a/CPP/7zip/Archive/ApmHandler.cpp b/CPP/7zip/Archive/ApmHandler.cpp
index 51719d53..4d3f2728 100644
--- a/CPP/7zip/Archive/ApmHandler.cpp
+++ b/CPP/7zip/Archive/ApmHandler.cpp
@@ -6,7 +6,6 @@
#include "../../Common/ComTry.h"
#include "../../Common/Defs.h"
-#include "../../Common/IntToString.h"
#include "../../Windows/PropVariant.h"
@@ -232,7 +231,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
int mainIndex = -1;
FOR_VECTOR (i, _items)
{
- AString s = GetString(_items[i].Type);
+ AString s (GetString(_items[i].Type));
if (s != "Apple_Free" &&
s != "Apple_partition_map")
{
@@ -279,14 +278,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath:
{
- AString s = GetString(item.Name);
+ AString s (GetString(item.Name));
if (s.IsEmpty())
- {
- char s2[32];
- ConvertUInt32ToString(index, s2);
- s = s2;
- }
- AString type = GetString(item.Type);
+ s.Add_UInt32(index);
+ AString type (GetString(item.Type));
if (type == "Apple_HFS")
type = "hfs";
if (!type.IsEmpty())
diff --git a/CPP/7zip/Archive/ArHandler.cpp b/CPP/7zip/Archive/ArHandler.cpp
index 83ed5a02..816a84e4 100644
--- a/CPP/7zip/Archive/ArHandler.cpp
+++ b/CPP/7zip/Archive/ArHandler.cpp
@@ -688,7 +688,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidShortComment:
case kpidSubType:
{
- AString s = k_TypeExtionsions[(unsigned)_type];
+ AString s (k_TypeExtionsions[(unsigned)_type]);
if (_subType == kSubType_BSD)
s += ":BSD";
prop = s;
@@ -720,7 +720,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (item.TextFileIndex >= 0)
prop = (item.TextFileIndex == 0) ? "1.txt" : "2.txt";
else
- prop = (const wchar_t *)NItemName::GetOSName2(MultiByteToUnicodeString(item.Name, CP_OEMCP));
+ prop = (const wchar_t *)NItemName::GetOsPath_Remove_TailSlash(MultiByteToUnicodeString(item.Name, CP_OEMCP));
break;
case kpidSize:
case kpidPackSize:
diff --git a/CPP/7zip/Archive/ArjHandler.cpp b/CPP/7zip/Archive/ArjHandler.cpp
index 90819753..fb9e3e7a 100644
--- a/CPP/7zip/Archive/ArjHandler.cpp
+++ b/CPP/7zip/Archive/ArjHandler.cpp
@@ -5,10 +5,10 @@
#include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h"
-#include "../../Common/IntToString.h"
#include "../../Common/StringConvert.h"
#include "../../Windows/PropVariant.h"
+#include "../../Windows/PropVariantUtils.h"
#include "../../Windows/TimeUtils.h"
#include "../Common/LimitedStreams.h"
@@ -642,16 +642,7 @@ static void SetTime(UInt32 dosTime, NCOM::CPropVariant &prop)
static void SetHostOS(Byte hostOS, NCOM::CPropVariant &prop)
{
- char temp[16];
- const char *s = NULL;
- if (hostOS < ARRAY_SIZE(kHostOS))
- s = kHostOS[hostOS];
- else
- {
- ConvertUInt32ToString(hostOS, temp);
- s = temp;
- }
- prop = s;
+ TYPE_TO_PROP(kHostOS, hostOS, prop);
}
static void SetUnicodeString(const AString &s, NCOM::CPropVariant &prop)
@@ -703,7 +694,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
const CItem &item = _items[index];
switch (propID)
{
- case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;
+ case kpidPath: prop = NItemName::GetOsPath(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;
case kpidIsDir: prop = item.IsDir(); break;
case kpidSize: prop = item.Size; break;
case kpidPackSize: prop = item.PackSize; break;
diff --git a/CPP/7zip/Archive/Bz2Handler.cpp b/CPP/7zip/Archive/Bz2Handler.cpp
index d1d5f727..98428430 100644
--- a/CPP/7zip/Archive/Bz2Handler.cpp
+++ b/CPP/7zip/Archive/Bz2Handler.cpp
@@ -179,6 +179,7 @@ STDMETHODIMP CHandler::Close()
return S_OK;
}
+
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
@@ -191,8 +192,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (_packSize_Defined)
extractCallback->SetTotal(_packSize);
- // RINOK(extractCallback->SetCompleted(&packSize));
-
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
@@ -203,7 +202,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
extractCallback->PrepareOperation(askMode);
-
if (_needSeekToStart)
{
if (!_stream)
@@ -213,14 +211,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
else
_needSeekToStart = true;
- Int32 opRes;
-
- try
- {
+ // try {
NCompress::NBZip2::CDecoder *decoderSpec = new NCompress::NBZip2::CDecoder;
CMyComPtr<ICompressCoder> decoder = decoderSpec;
- decoderSpec->SetInStream(_seqStream);
#ifndef _7ZIP_ST
RINOK(decoderSpec->SetNumberOfThreads(_props._numThreads));
@@ -237,74 +231,43 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, true);
- UInt64 packSize = 0;
- UInt64 unpackedSize = 0;
- UInt64 numStreams = 0;
-
- decoderSpec->InitNumBlocks();
+ decoderSpec->FinishMode = true;
+ decoderSpec->Base.DecodeAllStreams = true;
- HRESULT result = S_OK;
+ _dataAfterEnd = false;
+ _needMoreInput = false;
- for (;;)
+ lps->InSize = 0;
+ lps->OutSize = 0;
+
+ HRESULT result = decoderSpec->Code(_seqStream, outStream, NULL, NULL, progress);
+
+ if (result != S_FALSE && result != S_OK)
+ return result;
+
+ if (decoderSpec->Base.NumStreams == 0)
{
- lps->InSize = packSize;
- lps->OutSize = unpackedSize;
-
- RINOK(lps->SetCur());
-
- result = decoderSpec->CodeResume(outStream, progress);
-
- if (result != S_FALSE && result != S_OK)
- return result;
-
- if (decoderSpec->IsBz)
- numStreams++;
- else if (numStreams == 0)
- {
- _isArc = false;
- result = S_FALSE;
- break;
- }
-
- unpackedSize = outStreamSpec->GetSize();
- UInt64 streamSize = decoderSpec->GetStreamSize();
+ _isArc = false;
+ result = S_FALSE;
+ }
+ else
+ {
+ const UInt64 inProcessedSize = decoderSpec->GetInputProcessedSize();
+ UInt64 packSize = inProcessedSize;
- if (streamSize == packSize)
- {
- // no new bytes in input stream, So it's good end of archive.
- result = S_OK;
- break;
- }
+ if (decoderSpec->Base.NeedMoreInput)
+ _needMoreInput = true;
- if (!decoderSpec->IsBz)
+ if (!decoderSpec->Base.IsBz)
{
- _dataAfterEnd = true;
- result = S_FALSE;
- break;
+ packSize = decoderSpec->Base.FinishedPackSize;
+ if (packSize != inProcessedSize)
+ _dataAfterEnd = true;
}
- if (decoderSpec->Base.BitDecoder.ExtraBitsWereRead())
- {
- _needMoreInput = true;
- packSize = streamSize;
- result = S_FALSE;
- break;
- }
-
- packSize = decoderSpec->GetInputProcessedSize();
-
- if (packSize > streamSize)
- return E_FAIL;
-
- if (result != S_OK)
- break;
- }
-
- if (numStreams != 0)
- {
_packSize = packSize;
- _unpackSize = unpackedSize;
- _numStreams = numStreams;
+ _unpackSize = decoderSpec->GetOutProcessedSize();
+ _numStreams = decoderSpec->Base.NumStreams;
_numBlocks = decoderSpec->GetNumBlocks();
_packSize_Defined = true;
@@ -313,32 +276,36 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
_numBlocks_Defined = true;
}
- decoderSpec->ReleaseInStream();
outStream.Release();
+ Int32 opRes;
+
if (!_isArc)
opRes = NExtract::NOperationResult::kIsNotArc;
else if (_needMoreInput)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
- else if (decoderSpec->CrcError)
+ else if (decoderSpec->GetCrcError())
opRes = NExtract::NOperationResult::kCRCError;
else if (_dataAfterEnd)
opRes = NExtract::NOperationResult::kDataAfterEnd;
else if (result == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
+ else if (decoderSpec->Base.MinorError)
+ opRes = NExtract::NOperationResult::kDataError;
else if (result == S_OK)
opRes = NExtract::NOperationResult::kOK;
else
return result;
- }
- catch(const CInBufferException &e) { return e.ErrorCode; }
-
return extractCallback->SetOperationResult(opRes);
+ // } catch(...) { return E_FAIL; }
+
COM_TRY_END
}
+
+
static HRESULT UpdateArchive(
UInt64 unpackSize,
ISequentialOutStream *outStream,
diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp
index 18f58b3d..c62efbd8 100644
--- a/CPP/7zip/Archive/Cab/CabHandler.cpp
+++ b/CPP/7zip/Archive/Cab/CabHandler.cpp
@@ -226,12 +226,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (ai.SetID != 0)
{
AString s;
- char temp[32];
- ConvertUInt32ToString(ai.SetID, temp);
- s += temp;
- ConvertUInt32ToString(ai.CabinetNumber + 1, temp);
+ s.Add_UInt32(ai.SetID);
s += '_';
- s += temp;
+ s.Add_UInt32(ai.CabinetNumber + 1);
s += ".cab";
prop = s;
}
@@ -288,7 +285,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
ConvertUTF8ToUnicode(item.Name, unicodeName);
else
unicodeName = MultiByteToUnicodeString(item.Name, CP_ACP);
- prop = (const wchar_t *)NItemName::WinNameToOSName(unicodeName);
+ prop = (const wchar_t *)NItemName::WinPathToOsPath(unicodeName);
break;
}
@@ -491,7 +488,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
if (!_errorMessage.IsEmpty())
_errorMessage.Add_LF();
- _errorMessage.AddAscii("Can't open volume: ");
+ _errorMessage += "Can't open volume: ";
_errorMessage += fullName;
if (prevChecked)
diff --git a/CPP/7zip/Archive/Chm/ChmHandler.cpp b/CPP/7zip/Archive/Chm/ChmHandler.cpp
index b890d8ff..7ffdafe0 100644
--- a/CPP/7zip/Archive/Chm/ChmHandler.cpp
+++ b/CPP/7zip/Archive/Chm/ChmHandler.cpp
@@ -135,7 +135,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (us.Len() > 1 && us[0] == L'/')
us.Delete(0);
}
- NItemName::ConvertToOSName2(us);
+ NItemName::ReplaceToOsSlashes_Remove_TailSlash(us);
prop = us;
}
break;
diff --git a/CPP/7zip/Archive/Chm/ChmIn.cpp b/CPP/7zip/Archive/Chm/ChmIn.cpp
index 02ecfadd..7e3f155b 100644
--- a/CPP/7zip/Archive/Chm/ChmIn.cpp
+++ b/CPP/7zip/Archive/Chm/ChmIn.cpp
@@ -38,20 +38,13 @@ struct CHeaderErrorException {};
// define CHM_LOW, if you want to see low level items
// #define CHM_LOW
-static const GUID kChmLzxGuid = { 0x7FC28940, 0x9D31, 0x11D0, { 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C } };
-static const GUID kHelp2LzxGuid = { 0x0A9007C6, 0x4076, 0x11D3, { 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 } };
-static const GUID kDesGuid = { 0x67F6E4A2, 0x60BF, 0x11D3, { 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF } };
+static const Byte kChmLzxGuid[16] = { 0x40, 0x89, 0xC2, 0x7F, 0x31, 0x9D, 0xD0, 0x11, 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C };
+static const Byte kHelp2LzxGuid[16] = { 0xC6, 0x07, 0x90, 0x0A, 0x76, 0x40, 0xD3, 0x11, 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 };
+static const Byte kDesGuid[16] = { 0xA2, 0xE4, 0xF6, 0x67, 0xBF, 0x60, 0xD3, 0x11, 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF };
-static bool AreGuidsEqual(REFGUID g1, REFGUID g2)
+static bool inline AreGuidsEqual(const Byte *g1, const Byte *g2)
{
- if (g1.Data1 != g2.Data1 ||
- g1.Data2 != g2.Data2 ||
- g1.Data3 != g2.Data3)
- return false;
- for (int i = 0; i < 8; i++)
- if (g1.Data4[i] != g2.Data4[i])
- return false;
- return true;
+ return memcmp(g1, g2, 16) == 0;
}
static char GetHex(unsigned v)
@@ -65,35 +58,12 @@ static void PrintByte(Byte b, AString &s)
s += GetHex(b & 0xF);
}
-static void PrintUInt16(UInt16 v, AString &s)
-{
- PrintByte((Byte)(v >> 8), s);
- PrintByte((Byte)v, s);
-}
-
-static void PrintUInt32(UInt32 v, AString &s)
-{
- PrintUInt16((UInt16)(v >> 16), s);
- PrintUInt16((UInt16)v, s);
-}
-
AString CMethodInfo::GetGuidString() const
{
- AString s;
- s += '{';
- PrintUInt32(Guid.Data1, s);
- s += '-';
- PrintUInt16(Guid.Data2, s);
- s += '-';
- PrintUInt16(Guid.Data3, s);
- s += '-';
- PrintByte(Guid.Data4[0], s);
- PrintByte(Guid.Data4[1], s);
- s += '-';
- for (int i = 2; i < 8; i++)
- PrintByte(Guid.Data4[i], s);
- s += '}';
- return s;
+ char s[48];
+ RawLeGuidToString_Braced(Guid, s);
+ // MyStringUpper_Ascii(s);
+ return (AString)s;
}
bool CMethodInfo::IsLzx() const
@@ -108,32 +78,28 @@ bool CMethodInfo::IsDes() const
return AreGuidsEqual(Guid, kDesGuid);
}
-UString CMethodInfo::GetName() const
+AString CMethodInfo::GetName() const
{
- UString s;
+ AString s;
if (IsLzx())
{
- s.SetFromAscii("LZX:");
- char temp[16];
- ConvertUInt32ToString(LzxInfo.GetNumDictBits(), temp);
- s.AddAscii(temp);
+ s = "LZX:";
+ s.Add_UInt32(LzxInfo.GetNumDictBits());
}
else
{
- AString s2;
if (IsDes())
- s2 = "DES";
+ s = "DES";
else
{
- s2 = GetGuidString();
+ s = GetGuidString();
if (ControlData.Size() > 0)
{
- s2 += ':';
+ s += ':';
for (size_t i = 0; i < ControlData.Size(); i++)
- PrintByte(ControlData[i], s2);
+ PrintByte(ControlData[i], s);
}
}
- ConvertUTF8ToUnicode(s2, s);
}
return s;
}
@@ -153,7 +119,7 @@ UString CSectionInfo::GetMethodName() const
UString temp;
if (ConvertUTF8ToUnicode(Name, temp))
s += temp;
- s.AddAscii(": ");
+ s += ": ";
}
FOR_VECTOR (i, Methods)
{
@@ -220,12 +186,9 @@ UInt64 CInArchive::ReadEncInt()
throw CHeaderErrorException();
}
-void CInArchive::ReadGUID(GUID &g)
+void CInArchive::ReadGUID(Byte *g)
{
- g.Data1 = ReadUInt32();
- g.Data2 = ReadUInt16();
- g.Data3 = ReadUInt16();
- ReadBytes(g.Data4, 8);
+ ReadBytes(g, 16);
}
void CInArchive::ReadString(unsigned size, AString &s)
@@ -299,7 +262,7 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
// The third and fourth bytes may contain even more fractional bits.
// The 4 least significant bits in the last byte are constant.
/* UInt32 lang = */ ReadUInt32();
- GUID g;
+ Byte g[16];
ReadGUID(g); // {7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC}
ReadGUID(g); // {7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC}
const unsigned kNumSections = 2;
@@ -422,7 +385,7 @@ HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database)
IsArc = true;
ReadUInt32(); // Len of post-header table
- GUID g;
+ Byte g[16];
ReadGUID(g); // {0A9007C1-4076-11D3-8789-0000F8105754}
// header section table
@@ -637,18 +600,18 @@ HRESULT CInArchive::DecompressStream(IInStream *inStream, const CDatabase &datab
#define DATA_SPACE "::DataSpace/"
-static const char *kNameList = DATA_SPACE "NameList";
-static const char *kStorage = DATA_SPACE "Storage/";
-static const char *kContent = "Content";
-static const char *kControlData = "ControlData";
-static const char *kSpanInfo = "SpanInfo";
-static const char *kTransform = "Transform/";
-static const char *kResetTable = "/InstanceData/ResetTable";
-static const char *kTransformList = "List";
+#define kNameList DATA_SPACE "NameList"
+#define kStorage DATA_SPACE "Storage/"
+#define kContent "Content"
+#define kControlData "ControlData"
+#define kSpanInfo "SpanInfo"
+#define kTransform "Transform/"
+#define kResetTable "/InstanceData/ResetTable"
+#define kTransformList "List"
static AString GetSectionPrefix(const AString &name)
{
- AString s = kStorage;
+ AString s (kStorage);
s += name;
s += '/';
return s;
@@ -743,7 +706,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
{
{
// The NameList file
- RINOK(DecompressStream(inStream, database, kNameList));
+ RINOK(DecompressStream(inStream, database, (AString)kNameList));
/* UInt16 length = */ ReadUInt16();
UInt16 numSections = ReadUInt16();
for (unsigned i = 0; i < numSections; i++)
@@ -764,7 +727,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
for (si = 1; si < database.Sections.Size(); si++)
{
CSectionInfo &section = database.Sections[si];
- AString sectionPrefix = GetSectionPrefix(section.Name);
+ AString sectionPrefix (GetSectionPrefix(section.Name));
{
// Content
int index = database.FindItem(sectionPrefix + kContent);
@@ -774,7 +737,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
section.Offset = item.Offset;
section.CompressedSize = item.Size;
}
- AString transformPrefix = sectionPrefix + kTransform;
+ AString transformPrefix (sectionPrefix + kTransform);
if (database.Help2Format)
{
// Transform List
@@ -794,7 +757,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
else
{
CMethodInfo method;
- method.Guid = kChmLzxGuid;
+ memcpy(method.Guid, kChmLzxGuid, 16);
section.Methods.Add(method);
}
diff --git a/CPP/7zip/Archive/Chm/ChmIn.h b/CPP/7zip/Archive/Chm/ChmIn.h
index bf51616f..f7b75d81 100644
--- a/CPP/7zip/Archive/Chm/ChmIn.h
+++ b/CPP/7zip/Archive/Chm/ChmIn.h
@@ -149,14 +149,14 @@ struct CLzxInfo
struct CMethodInfo
{
- GUID Guid;
+ Byte Guid[16];
CByteBuffer ControlData;
CLzxInfo LzxInfo;
bool IsLzx() const;
bool IsDes() const;
AString GetGuidString() const;
- UString GetName() const;
+ AString GetName() const;
};
@@ -243,7 +243,7 @@ class CInArchive
UInt64 ReadEncInt();
void ReadString(unsigned size, AString &s);
void ReadUString(unsigned size, UString &s);
- void ReadGUID(GUID &g);
+ void ReadGUID(Byte *g);
HRESULT ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size);
diff --git a/CPP/7zip/Archive/ComHandler.cpp b/CPP/7zip/Archive/ComHandler.cpp
index c6d2bd25..d2dc6c5f 100644
--- a/CPP/7zip/Archive/ComHandler.cpp
+++ b/CPP/7zip/Archive/ComHandler.cpp
@@ -239,9 +239,6 @@ HRESULT CDatabase::AddNode(int parent, UInt32 did)
return S_OK;
}
-static const wchar_t kCharOpenBracket = L'[';
-static const wchar_t kCharCloseBracket = L']';
-
static UString CompoundNameToFileName(const UString &s)
{
UString res;
@@ -250,11 +247,9 @@ static UString CompoundNameToFileName(const UString &s)
wchar_t c = s[i];
if (c < 0x20)
{
- res += kCharOpenBracket;
- wchar_t buf[32];
- ConvertUInt32ToString(c, buf);
- res += buf;
- res += kCharCloseBracket;
+ res += '[';
+ res.Add_UInt32(c);
+ res += ']';
}
else
res += c;
@@ -265,8 +260,8 @@ static UString CompoundNameToFileName(const UString &s)
static const char k_Msi_Chars[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz._";
-// static const char *k_Msi_ID = ""; // "{msi}";
-static const wchar_t k_Msi_SpecChar = L'!';
+// static const char * const k_Msi_ID = ""; // "{msi}";
+static const char k_Msi_SpecChar = '!';
static const unsigned k_Msi_NumBits = 6;
static const unsigned k_Msi_NumChars = 1 << k_Msi_NumBits;
@@ -316,10 +311,10 @@ static bool CompoundMsiNameToFileName(const UString &name, UString &res)
if (c1 <= k_Msi_NumChars)
{
- res += (wchar_t)(Byte)k_Msi_Chars[c0];
+ res += k_Msi_Chars[c0];
if (c1 == k_Msi_NumChars)
break;
- res += (wchar_t)(Byte)k_Msi_Chars[c1];
+ res += k_Msi_Chars[c1];
}
else
res += k_Msi_SpecChar;
diff --git a/CPP/7zip/Archive/Common/CoderMixer2.cpp b/CPP/7zip/Archive/Common/CoderMixer2.cpp
index 41b5805c..7834c605 100644
--- a/CPP/7zip/Archive/Common/CoderMixer2.cpp
+++ b/CPP/7zip/Archive/Common/CoderMixer2.cpp
@@ -60,6 +60,62 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
p[i] = false;
}
+
+HRESULT CCoder::CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const
+{
+ if (Coder)
+ {
+ if (PackSizePointers.IsEmpty() || !PackSizePointers[0])
+ return S_OK;
+ CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
+ Coder.QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize);
+ // if (!getInStreamProcessedSize) return E_FAIL;
+ if (getInStreamProcessedSize)
+ {
+ UInt64 processed;
+ RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed));
+ if (processed != (UInt64)(Int64)-1)
+ {
+ const UInt64 size = PackSizes[0];
+ if (processed < size && Finish)
+ dataAfterEnd_Error = true;
+ if (processed > size)
+ {
+ // InternalPackSizeError = true;
+ // return S_FALSE;
+ }
+ }
+ }
+ }
+ else if (Coder2)
+ {
+ CMyComPtr<ICompressGetInStreamProcessedSize2> getInStreamProcessedSize2;
+ Coder2.QueryInterface(IID_ICompressGetInStreamProcessedSize2, (void **)&getInStreamProcessedSize2);
+ FOR_VECTOR (i, PackSizePointers)
+ {
+ if (!PackSizePointers[i])
+ continue;
+ UInt64 processed;
+ RINOK(getInStreamProcessedSize2->GetInStreamProcessedSize2(i, &processed));
+ if (processed != (UInt64)(Int64)-1)
+ {
+ const UInt64 size = PackSizes[i];
+ if (processed < size && Finish)
+ dataAfterEnd_Error = true;
+ else if (processed > size)
+ {
+ // InternalPackSizeError = true;
+ // return S_FALSE;
+ }
+ }
+ }
+ }
+
+ return S_OK;
+}
+
+
+
class CBondsChecks
{
CBoolVector _coderUsed;
@@ -151,8 +207,10 @@ bool CBindInfo::CalcMapsAndCheck()
}
-void CCoder::SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes)
+void CCoder::SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
{
+ Finish = finish;
+
if (unpackSize)
{
UnpackSize = *unpackSize;
@@ -640,8 +698,12 @@ void CMixerST::SelectMainCoder(bool useFirst)
HRESULT CMixerST::Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
- ICompressProgressInfo *progress)
+ ICompressProgressInfo *progress,
+ bool &dataAfterEnd_Error)
{
+ // InternalPackSizeError = false;
+ dataAfterEnd_Error = false;
+
_binderStreams.Clear();
unsigned ci = MainCoderIndex;
@@ -742,7 +804,16 @@ HRESULT CMixerST::Code(
if (res == k_My_HRESULT_WritingWasCut)
res = S_OK;
- return res;
+
+ if (res != S_OK)
+ return res;
+
+ for (i = 0; i < _coders.Size(); i++)
+ {
+ RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /*, InternalPackSizeError */));
+ }
+
+ return S_OK;
}
@@ -988,8 +1059,12 @@ HRESULT CMixerMT::ReturnIfError(HRESULT code)
HRESULT CMixerMT::Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
- ICompressProgressInfo *progress)
+ ICompressProgressInfo *progress,
+ bool &dataAfterEnd_Error)
{
+ // InternalPackSizeError = false;
+ dataAfterEnd_Error = false;
+
Init(inStreams, outStreams);
unsigned i;
@@ -1031,6 +1106,11 @@ HRESULT CMixerMT::Code(
return result;
}
+ for (i = 0; i < _coders.Size(); i++)
+ {
+ RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /* , InternalPackSizeError */));
+ }
+
return S_OK;
}
diff --git a/CPP/7zip/Archive/Common/CoderMixer2.h b/CPP/7zip/Archive/Common/CoderMixer2.h
index e63f2ff0..798411ab 100644
--- a/CPP/7zip/Archive/Common/CoderMixer2.h
+++ b/CPP/7zip/Archive/Common/CoderMixer2.h
@@ -201,9 +201,13 @@ public:
CRecordVector<UInt64> PackSizes;
CRecordVector<const UInt64 *> PackSizePointers;
- CCoder() {}
+ bool Finish;
- void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes);
+ CCoder(): Finish(false) {}
+
+ void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish);
+
+ HRESULT CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const;
IUnknown *GetUnknown() const
{
@@ -239,9 +243,12 @@ protected:
public:
unsigned MainCoderIndex;
+ // bool InternalPackSizeError;
+
CMixer(bool encodeMode):
EncodeMode(encodeMode),
MainCoderIndex(0)
+ // , InternalPackSizeError(false)
{}
/*
@@ -273,11 +280,12 @@ public:
virtual CCoder &GetCoder(unsigned index) = 0;
virtual void SelectMainCoder(bool useFirst) = 0;
virtual void ReInit() = 0;
- virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes) = 0;
+ virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) = 0;
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
- ICompressProgressInfo *progress) = 0;
+ ICompressProgressInfo *progress,
+ bool &dataAfterEnd_Error) = 0;
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const = 0;
bool Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex);
@@ -338,12 +346,13 @@ public:
virtual CCoder &GetCoder(unsigned index);
virtual void SelectMainCoder(bool useFirst);
virtual void ReInit();
- virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes)
- { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); }
+ virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
+ { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
- ICompressProgressInfo *progress);
+ ICompressProgressInfo *progress,
+ bool &dataAfterEnd_Error);
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
HRESULT GetMainUnpackStream(
@@ -419,12 +428,13 @@ public:
virtual CCoder &GetCoder(unsigned index);
virtual void SelectMainCoder(bool useFirst);
virtual void ReInit();
- virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes)
- { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); }
+ virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
+ { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
- ICompressProgressInfo *progress);
+ ICompressProgressInfo *progress,
+ bool &dataAfterEnd_Error);
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
CMixerMT(bool encodeMode): CMixer(encodeMode) {}
diff --git a/CPP/7zip/Archive/Common/HandlerOut.cpp b/CPP/7zip/Archive/Common/HandlerOut.cpp
index 30ca73bd..ea320e66 100644
--- a/CPP/7zip/Archive/Common/HandlerOut.cpp
+++ b/CPP/7zip/Archive/Common/HandlerOut.cpp
@@ -20,20 +20,19 @@ static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
m.AddProp32(propID, value);
}
-void CMultiMethodProps::SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
- #ifndef _7ZIP_ST
- , UInt32 numThreads
- #endif
- )
+void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
{
UInt32 level = _level;
if (level != (UInt32)(Int32)-1)
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
-
- #ifndef _7ZIP_ST
+}
+
+#ifndef _7ZIP_ST
+void CMultiMethodProps::SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads)
+{
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
- #endif
}
+#endif
void CMultiMethodProps::Init()
{
@@ -73,7 +72,7 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
return S_OK;
}
- if (name.IsEqualTo("crc"))
+ if (name.IsPrefixedBy_Ascii_NoCase("crc"))
{
name.Delete(0, 3);
_crcSize = 4;
diff --git a/CPP/7zip/Archive/Common/HandlerOut.h b/CPP/7zip/Archive/Common/HandlerOut.h
index 5a18d980..e24686da 100644
--- a/CPP/7zip/Archive/Common/HandlerOut.h
+++ b/CPP/7zip/Archive/Common/HandlerOut.h
@@ -22,11 +22,13 @@ public:
COneMethodInfo _filterMethod;
bool _autoFilter;
- void SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
- #ifndef _7ZIP_ST
- , UInt32 numThreads
- #endif
- );
+
+ void SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const;
+
+ #ifndef _7ZIP_ST
+ static void SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads);
+ #endif
+
unsigned GetNumEmptyMethods() const
{
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
index 7cd3037b..d5093a24 100644
--- a/CPP/7zip/Archive/Common/ItemNameUtils.cpp
+++ b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
@@ -7,58 +7,57 @@
namespace NArchive {
namespace NItemName {
-static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR;
-static const wchar_t kDirDelimiter = L'/';
+static const wchar_t kOsPathSepar = WCHAR_PATH_SEPARATOR;
+static const wchar_t kUnixPathSepar = L'/';
-void ReplaceToOsPathSeparator(wchar_t *s)
-{
- #ifdef _WIN32
- for (;;)
+void ReplaceSlashes_OsToUnix
+#if WCHAR_PATH_SEPARATOR != L'/'
+ (UString &name)
{
- wchar_t c = *s;
- if (c == 0)
- break;
- if (c == kDirDelimiter)
- *s = kOSDirDelimiter;
- s++;
+ name.Replace(kOsPathSepar, kUnixPathSepar);
}
- #endif
-}
+#else
+ (UString &) {}
+#endif
-UString MakeLegalName(const UString &name)
-{
- UString zipName = name;
- zipName.Replace(kOSDirDelimiter, kDirDelimiter);
- return zipName;
-}
-UString GetOSName(const UString &name)
+UString GetOsPath(const UString &name)
{
- UString newName = name;
- newName.Replace(kDirDelimiter, kOSDirDelimiter);
- return newName;
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ UString newName = name;
+ newName.Replace(kUnixPathSepar, kOsPathSepar);
+ return newName;
+ #else
+ return name;
+ #endif
}
-UString GetOSName2(const UString &name)
+
+UString GetOsPath_Remove_TailSlash(const UString &name)
{
if (name.IsEmpty())
return UString();
- UString newName = GetOSName(name);
- if (newName.Back() == kOSDirDelimiter)
+ UString newName = GetOsPath(name);
+ if (newName.Back() == kOsPathSepar)
newName.DeleteBack();
return newName;
}
-void ConvertToOSName2(UString &name)
+
+void ReplaceToOsSlashes_Remove_TailSlash(UString &name)
{
if (!name.IsEmpty())
{
- name.Replace(kDirDelimiter, kOSDirDelimiter);
- if (name.Back() == kOSDirDelimiter)
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ name.Replace(kUnixPathSepar, kOsPathSepar);
+ #endif
+
+ if (name.Back() == kOsPathSepar)
name.DeleteBack();
}
}
+
bool HasTailSlash(const AString &name, UINT
#if defined(_WIN32) && !defined(UNDER_CE)
codePage
@@ -67,20 +66,21 @@ bool HasTailSlash(const AString &name, UINT
{
if (name.IsEmpty())
return false;
- LPCSTR prev =
- #if defined(_WIN32) && !defined(UNDER_CE)
- CharPrevExA((WORD)codePage, name, &name[name.Len()], 0);
- #else
- (LPCSTR)(name) + (name.Len() - 1);
- #endif
- return (*prev == '/');
+ char c =
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ *CharPrevExA((WORD)codePage, name, name.Ptr(name.Len()), 0);
+ #else
+ name.Back();
+ #endif
+ return (c == '/');
}
+
#ifndef _WIN32
-UString WinNameToOSName(const UString &name)
+UString WinPathToOsPath(const UString &name)
{
UString newName = name;
- newName.Replace(L'\\', kOSDirDelimiter);
+ newName.Replace(L'\\', WCHAR_PATH_SEPARATOR);
return newName;
}
#endif
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.h b/CPP/7zip/Archive/Common/ItemNameUtils.h
index d0dc76a4..31150864 100644
--- a/CPP/7zip/Archive/Common/ItemNameUtils.h
+++ b/CPP/7zip/Archive/Common/ItemNameUtils.h
@@ -8,19 +8,20 @@
namespace NArchive {
namespace NItemName {
- void ReplaceToOsPathSeparator(wchar_t *s);
-
- UString MakeLegalName(const UString &name);
- UString GetOSName(const UString &name);
- UString GetOSName2(const UString &name);
- void ConvertToOSName2(UString &name);
- bool HasTailSlash(const AString &name, UINT codePage);
-
- #ifdef _WIN32
- inline UString WinNameToOSName(const UString &name) { return name; }
- #else
- UString WinNameToOSName(const UString &name);
- #endif
+void ReplaceSlashes_OsToUnix(UString &name);
+
+UString GetOsPath(const UString &name);
+UString GetOsPath_Remove_TailSlash(const UString &name);
+
+void ReplaceToOsSlashes_Remove_TailSlash(UString &name);
+
+bool HasTailSlash(const AString &name, UINT codePage);
+
+#ifdef _WIN32
+ inline UString WinPathToOsPath(const UString &name) { return name; }
+#else
+ UString WinPathToOsPath(const UString &name);
+#endif
}}
diff --git a/CPP/7zip/Archive/CpioHandler.cpp b/CPP/7zip/Archive/CpioHandler.cpp
index e8898cac..b8fb530f 100644
--- a/CPP/7zip/Archive/CpioHandler.cpp
+++ b/CPP/7zip/Archive/CpioHandler.cpp
@@ -36,7 +36,7 @@ static const Byte kMagicHex = '1'; // New ASCII Format
static const Byte kMagicHexCrc = '2'; // New CRC Format
static const Byte kMagicOct = '7'; // Portable ASCII Format
-static const char *kName_TRAILER = "TRAILER!!!";
+static const char * const kName_TRAILER = "TRAILER!!!";
static const unsigned k_BinRecord_Size = 2 + 8 * 2 + 2 * 4;
static const unsigned k_OctRecord_Size = 6 + 8 * 6 + 2 * 11;
@@ -627,7 +627,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
#endif
if (needConvert)
res = MultiByteToUnicodeString(item.Name, CP_OEMCP);
- prop = NItemName::GetOSName(res);
+ prop = NItemName::GetOsPath(res);
break;
}
case kpidIsDir: prop = item.IsDir(); break;
diff --git a/CPP/7zip/Archive/DmgHandler.cpp b/CPP/7zip/Archive/DmgHandler.cpp
index 09952ac8..8acbcea6 100644
--- a/CPP/7zip/Archive/DmgHandler.cpp
+++ b/CPP/7zip/Archive/DmgHandler.cpp
@@ -183,6 +183,30 @@ struct CExtraFile
};
#endif
+
+struct CForkPair
+{
+ UInt64 Offset;
+ UInt64 Len;
+
+ void Parse(const Byte *p)
+ {
+ Offset = Get64(p);
+ Len = Get64(p + 8);
+ }
+
+ bool UpdateTop(UInt64 limit, UInt64 &top)
+ {
+ if (Offset > limit || Len > limit - Offset)
+ return false;
+ UInt64 top2 = Offset + Len;
+ if (top <= top2)
+ top = top2;
+ return true;
+ }
+};
+
+
class CHandler:
public IInArchive,
public IInArchiveGetStream,
@@ -191,14 +215,19 @@ class CHandler:
CMyComPtr<IInStream> _inStream;
CObjectVector<CFile> _files;
bool _masterCrcError;
+ bool _headersError;
UInt64 _startPos;
UInt64 _phySize;
+
+ AString _name;
#ifdef DMG_SHOW_RAW
CObjectVector<CExtraFile> _extras;
#endif
+ HRESULT ReadData(IInStream *stream, const CForkPair &pair, CByteBuffer &buf);
+ bool ParseBlob(const CByteBuffer &data);
HRESULT Open2(IInStream *stream);
HRESULT Extract(IInStream *stream);
public:
@@ -249,24 +278,20 @@ void CMethods::GetString(AString &res) const
case METHOD_BZIP2: s = "BZip2"; break;
default: ConvertUInt32ToString(type, buf); s = buf;
}
- res.Add_Space_if_NotEmpty();
- res += s;
+ res.Add_OptSpaced(s);
}
for (i = 0; i < ChecksumTypes.Size(); i++)
{
+ res.Add_Space_if_NotEmpty();
UInt32 type = ChecksumTypes[i];
- char buf[32];
- const char *s;
switch (type)
{
- case kCheckSumType_CRC: s = "CRC"; break;
+ case kCheckSumType_CRC: res += "CRC"; break;
default:
- ConvertUInt32ToString(type, MyStpCpy(buf, "Check"));
- s = buf;
+ res += "Check";
+ res.Add_UInt32(type);
}
- res.Add_Space_if_NotEmpty();
- res += s;
}
}
@@ -308,7 +333,8 @@ IMP_IInArchive_Props
static const Byte kArcProps[] =
{
kpidMethod,
- kpidNumBlocks
+ kpidNumBlocks,
+ kpidComment
};
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
@@ -372,9 +398,30 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidWarning:
if (_masterCrcError)
prop = "Master CRC error";
+
+ case kpidWarningFlags:
+ {
+ UInt32 v = 0;
+ if (_headersError) v |= kpv_ErrorFlags_HeadersError;
+ if (v != 0)
+ prop = v;
break;
+ }
+
case kpidOffset: prop = _startPos; break;
case kpidPhySize: prop = _phySize; break;
+
+ case kpidComment:
+ if (!_name.IsEmpty() && _name.Len() < 256)
+ prop = _name;
+ break;
+
+ case kpidName:
+ if (!_name.IsEmpty() && _name.Len() < 256)
+ {
+ prop = _name + ".dmg";
+ }
+ break;
}
prop.Detach(value);
return S_OK;
@@ -461,7 +508,7 @@ HRESULT CFile::Parse(const Byte *p, UInt32 size)
return S_OK;
}
-static int FindKeyPair(const CXmlItem &item, const AString &key, const AString &nextTag)
+static int FindKeyPair(const CXmlItem &item, const char *key, const char *nextTag)
{
for (unsigned i = 0; i + 1 < item.SubItems.Size(); i++)
{
@@ -472,7 +519,7 @@ static int FindKeyPair(const CXmlItem &item, const AString &key, const AString &
return -1;
}
-static const AString *GetStringFromKeyPair(const CXmlItem &item, const AString &key, const AString &nextTag)
+static const AString *GetStringFromKeyPair(const CXmlItem &item, const char *key, const char *nextTag)
{
int index = FindKeyPair(item, key, nextTag);
if (index >= 0)
@@ -498,6 +545,83 @@ static inline bool IsKoly(const Byte *p)
*/
}
+
+HRESULT CHandler::ReadData(IInStream *stream, const CForkPair &pair, CByteBuffer &buf)
+{
+ size_t size = (size_t)pair.Len;
+ if (size != pair.Len)
+ return E_OUTOFMEMORY;
+ buf.Alloc(size);
+ RINOK(stream->Seek(_startPos + pair.Offset, STREAM_SEEK_SET, NULL));
+ return ReadStream_FALSE(stream, buf, size);
+}
+
+
+bool CHandler::ParseBlob(const CByteBuffer &data)
+{
+ if (data.Size() < 12)
+ return false;
+ const Byte *p = (const Byte *)data;
+ if (Get32(p) != 0xFADE0CC0)
+ return true;
+ const UInt32 size = Get32(p + 4);
+ if (size != data.Size())
+ return false;
+ const UInt32 num = Get32(p + 8);
+ if (num > (size - 12) / 8)
+ return false;
+
+ for (UInt32 i = 0; i < num; i++)
+ {
+ // UInt32 type = Get32(p + i * 8 + 12);
+ UInt32 offset = Get32(p + i * 8 + 12 + 4);
+ if (size - offset < 8)
+ return false;
+ const Byte *p2 = (const Byte *)data + offset;
+ const UInt32 magic = Get32(p2);
+ const UInt32 len = Get32(p2 + 4);
+ if (size - offset < len || len < 8)
+ return false;
+
+ #ifdef DMG_SHOW_RAW
+ CExtraFile &extra = _extras.AddNew();
+ extra.Name = "_blob_";
+ extra.Data.CopyFrom(p2, len);
+ #endif
+
+ if (magic == 0xFADE0C02)
+ {
+ #ifdef DMG_SHOW_RAW
+ extra.Name += "codedir";
+ #endif
+
+ if (len < 11 * 4)
+ return false;
+ UInt32 idOffset = Get32(p2 + 0x14);
+ if (idOffset >= len)
+ return false;
+ UInt32 len2 = len - idOffset;
+ if (len2 < (1 << 10))
+ _name.SetFrom_CalcLen((const char *)(p2 + idOffset), len2);
+ }
+ #ifdef DMG_SHOW_RAW
+ else if (magic == 0xFADE0C01)
+ extra.Name += "requirements";
+ else if (magic == 0xFADE0B01)
+ extra.Name += "signed";
+ else
+ {
+ char temp[16];
+ ConvertUInt32ToHex8Digits(magic, temp);
+ extra.Name += temp;
+ }
+ #endif
+ }
+
+ return true;
+}
+
+
HRESULT CHandler::Open2(IInStream *stream)
{
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_startPos));
@@ -522,35 +646,69 @@ HRESULT CHandler::Open2(IInStream *stream)
// UInt32 flags = Get32(buf + 12);
// UInt64 runningDataForkOffset = Get64(buf + 0x10);
- UInt64 dataForkOffset = Get64(buf + 0x18);
- UInt64 dataForkLen = Get64(buf + 0x20);
- UInt64 rsrcOffset = Get64(buf + 0x28);
- UInt64 rsrcLen = Get64(buf + 0x30);
+
+ CForkPair dataForkPair, rsrcPair, xmlPair, blobPair;
+
+ dataForkPair.Parse(buf + 0x18);
+ rsrcPair.Parse(buf + 0x28);
+ xmlPair.Parse(buf + 0xD8);
+ blobPair.Parse(buf + 0x128);
+
// UInt32 segmentNumber = Get32(buf + 0x38);
// UInt32 segmentCount = Get32(buf + 0x3C);
// Byte segmentGUID[16];
// CChecksum dataForkChecksum;
// dataForkChecksum.Parse(buf + 0x50);
- UInt64 xmlOffset = Get64(buf + 0xD8);
- UInt64 xmlLen = Get64(buf + 0xE0);
-
- if ( headerPos < dataForkOffset
- || headerPos - dataForkOffset < dataForkLen
- || headerPos < rsrcOffset
- || headerPos - rsrcOffset < rsrcLen
- || headerPos < xmlOffset
- || headerPos - xmlOffset < xmlLen)
- return S_FALSE;
- UInt64 totalLen = dataForkLen + rsrcLen + xmlLen;
- if (totalLen > headerPos)
- return S_FALSE;
- _startPos = headerPos - totalLen;
- _phySize = totalLen + HEADER_SIZE;
- headerPos = totalLen;
+ _startPos = 0;
+
+ UInt64 top = 0;
+ if (!dataForkPair.UpdateTop(headerPos, top)) return S_FALSE;
+ if (!xmlPair.UpdateTop(headerPos, top)) return S_FALSE;
+ if (!rsrcPair.UpdateTop(headerPos, top)) return S_FALSE;
+
+ /* Some old dmg files contain garbage data in blobPair field.
+ So we need to ignore such garbage case;
+ And we still need to detect offset of start of archive for "parser" mode. */
+
+ bool useBlob = blobPair.UpdateTop(headerPos, top);
+
+ _startPos = 0;
+ _phySize = headerPos + HEADER_SIZE;
+
+ if (top != headerPos)
+ {
+ CForkPair xmlPair2 = xmlPair;
+ const char *sz = "<?xml version";
+ const unsigned len = (unsigned)strlen(sz);
+ if (xmlPair2.Len > len)
+ xmlPair2.Len = len;
+ CByteBuffer buf2;
+ if (ReadData(stream, xmlPair2, buf2) != S_OK
+ || memcmp(buf2, sz, len) != 0)
+ {
+ _startPos = headerPos - top;
+ _phySize = top + HEADER_SIZE;
+ }
+ }
// Byte reserved[0x78]
+ if (useBlob && blobPair.Len != 0)
+ {
+ #ifdef DMG_SHOW_RAW
+ CExtraFile &extra = _extras.AddNew();
+ extra.Name = "_blob.bin";
+ CByteBuffer &blobBuf = extra.Data;
+ #else
+ CByteBuffer blobBuf;
+ #endif
+ RINOK(ReadData(stream, blobPair, blobBuf));
+ if (!ParseBlob(blobBuf))
+ _headersError = true;
+ }
+
+
CChecksum masterChecksum;
masterChecksum.Parse(buf + 0x160);
@@ -562,7 +720,7 @@ HRESULT CHandler::Open2(IInStream *stream)
// We don't know the size of the field "offset" in rsrc.
// We suppose that it uses 24 bits. So we use Rsrc, only if the rsrcLen < (1 << 24).
- bool useRsrc = (rsrcLen > RSRC_HEAD_SIZE && rsrcLen < ((UInt32)1 << 24));
+ bool useRsrc = (rsrcPair.Len > RSRC_HEAD_SIZE && rsrcPair.Len < ((UInt32)1 << 24));
// useRsrc = false;
if (useRsrc)
@@ -575,21 +733,18 @@ HRESULT CHandler::Open2(IInStream *stream)
CByteBuffer rsrcBuf;
#endif
- size_t rsrcLenT = (size_t)rsrcLen;
- rsrcBuf.Alloc(rsrcLenT);
- RINOK(stream->Seek(_startPos + rsrcOffset, STREAM_SEEK_SET, NULL));
- RINOK(ReadStream_FALSE(stream, rsrcBuf, rsrcLenT));
+ RINOK(ReadData(stream, rsrcPair, rsrcBuf));
const Byte *p = rsrcBuf;
UInt32 headSize = Get32(p + 0);
UInt32 footerOffset = Get32(p + 4);
UInt32 mainDataSize = Get32(p + 8);
UInt32 footerSize = Get32(p + 12);
- if (headSize != RSRC_HEAD_SIZE ||
- footerOffset >= rsrcLenT ||
- mainDataSize >= rsrcLenT ||
- footerOffset + footerSize != rsrcLenT ||
- footerOffset != headSize + mainDataSize)
+ if (headSize != RSRC_HEAD_SIZE
+ || footerOffset >= rsrcPair.Len
+ || mainDataSize >= rsrcPair.Len
+ || footerOffset + footerSize != rsrcPair.Len
+ || footerOffset != headSize + mainDataSize)
return S_FALSE;
if (footerSize < 16)
return S_FALSE;
@@ -600,7 +755,7 @@ HRESULT CHandler::Open2(IInStream *stream)
if ((UInt32)Get16(p + 0x18) != 0x1C)
return S_FALSE;
- UInt32 namesOffset = Get16(p + 0x1A);
+ const UInt32 namesOffset = Get16(p + 0x1A);
if (namesOffset > footerSize)
return S_FALSE;
@@ -612,12 +767,15 @@ HRESULT CHandler::Open2(IInStream *stream)
{
const Byte *p2 = p + 0x1E + i * 8;
- UInt32 typeId = Get32(p2);
+ const UInt32 typeId = Get32(p2);
+
+ #ifndef DMG_SHOW_RAW
if (typeId != 0x626C6B78) // blkx
continue;
+ #endif
- UInt32 numFiles = (UInt32)Get16(p2 + 4) + 1;
- UInt32 offs = Get16(p2 + 6);
+ const UInt32 numFiles = (UInt32)Get16(p2 + 4) + 1;
+ const UInt32 offs = Get16(p2 + 6);
if (0x1C + offs + 12 * numFiles > namesOffset)
return S_FALSE;
@@ -625,7 +783,7 @@ HRESULT CHandler::Open2(IInStream *stream)
{
const Byte *p3 = p + 0x1C + offs + k * 12;
// UInt32 id = Get16(p3);
- UInt32 namePos = Get16(p3 + 2);
+ const UInt32 namePos = Get16(p3 + 2);
// Byte attributes = p3[4]; // = 0x50 for blkx
// we don't know how many bits we can use. So we use 24 bits only
UInt32 blockOffset = Get32(p3 + 4);
@@ -634,21 +792,12 @@ HRESULT CHandler::Open2(IInStream *stream)
if (blockOffset + 4 >= mainDataSize)
return S_FALSE;
const Byte *pBlock = rsrcBuf + headSize + blockOffset;
- UInt32 blockSize = Get32(pBlock);
-
- #ifdef DMG_SHOW_RAW
- {
- CExtraFile &extra = _extras.AddNew();
- {
- char extraName[16];
- ConvertUInt32ToString(_files.Size(), extraName);
- extra.Name = extraName;
- }
- extra.Data.CopyFrom(pBlock + 4, blockSize);
- }
- #endif
+ const UInt32 blockSize = Get32(pBlock);
+ if (mainDataSize - (blockOffset + 4) < blockSize)
+ return S_FALSE;
+
+ AString name;
- CFile &file = _files.AddNew();
if (namePos != 0xFFFF)
{
UInt32 namesBlockSize = footerSize - namesOffset;
@@ -663,22 +812,56 @@ HRESULT CHandler::Open2(IInStream *stream)
Byte c = namePtr[r];
if (c < 0x20 || c >= 0x80)
break;
- file.Name += (char)c;
+ name += (char)c;
+ }
+ }
+
+ if (typeId == 0x626C6B78) // blkx
+ {
+ CFile &file = _files.AddNew();
+ file.Name = name;
+ RINOK(file.Parse(pBlock + 4, blockSize));
+ }
+
+ #ifdef DMG_SHOW_RAW
+ {
+ AString name2;
+
+ name2.Add_UInt32(i);
+ name2 += '_';
+
+ {
+ char temp[4 + 1] = { 0 };
+ memcpy(temp, p2, 4);
+ name2 += temp;
+ }
+ name2.Trim();
+ name2 += '_';
+ name2.Add_UInt32(k);
+
+ if (!name.IsEmpty())
+ {
+ name2 += '_';
+ name2 += name;
}
+
+ CExtraFile &extra = _extras.AddNew();
+ extra.Name = name2;
+ extra.Data.CopyFrom(pBlock + 4, blockSize);
}
- RINOK(file.Parse(pBlock + 4, blockSize));
+ #endif
}
}
}
else
{
- if (xmlLen >= kXmlSizeMax || xmlLen == 0)
+ if (xmlPair.Len >= kXmlSizeMax || xmlPair.Len == 0)
return S_FALSE;
- size_t size = (size_t)xmlLen;
- if (size != xmlLen)
+ size_t size = (size_t)xmlPair.Len;
+ if (size != xmlPair.Len)
return S_FALSE;
- RINOK(stream->Seek(_startPos + dataForkLen, STREAM_SEEK_SET, NULL));
+ RINOK(stream->Seek(_startPos + xmlPair.Offset, STREAM_SEEK_SET, NULL));
CXml xml;
{
@@ -733,16 +916,12 @@ HRESULT CHandler::Open2(IInStream *stream)
const Byte *endPtr = Base64ToBin(rawBuf, *dataString);
if (!endPtr)
return S_FALSE;
- destLen = (unsigned)(endPtr - rawBuf);
+ destLen = (unsigned)(endPtr - (const Byte *)rawBuf);
}
#ifdef DMG_SHOW_RAW
CExtraFile &extra = _extras.AddNew();
- {
- char extraName[16];
- ConvertUInt32ToString(_files.Size(), extraName);
- extra.Name = extraName;
- }
+ extra.Name.Add_UInt32(_files.Size());
extra.Data.CopyFrom(rawBuf, destLen);
#endif
}
@@ -800,6 +979,8 @@ STDMETHODIMP CHandler::Close()
_inStream.Release();
_files.Clear();
_masterCrcError = false;
+ _headersError = false;
+ _name.Empty();
#ifdef DMG_SHOW_RAW
_extras.Clear();
#endif
@@ -867,9 +1048,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPath:
{
UString name;
- wchar_t s[16];
- ConvertUInt32ToString(index, s);
- name = s;
+ name.Add_UInt32(index);
unsigned num = 10;
unsigned numDigits;
for (numDigits = 1; num < _files.Size(); numDigits++)
@@ -908,7 +1087,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
UString name2;
ConvertUTF8ToUnicode(subName, name2);
- name += L'.';
+ name += '.';
name += name2;
}
else
@@ -916,7 +1095,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
UString name2;
ConvertUTF8ToUnicode(item.Name, name2);
if (!name2.IsEmpty())
- name.AddAscii(" - ");
+ name += "_";
name += name2;
}
prop = name;
diff --git a/CPP/7zip/Archive/ElfHandler.cpp b/CPP/7zip/Archive/ElfHandler.cpp
index 4543b067..62674774 100644
--- a/CPP/7zip/Archive/ElfHandler.cpp
+++ b/CPP/7zip/Archive/ElfHandler.cpp
@@ -158,21 +158,21 @@ bool CHeader::Parse(const Byte *p)
static const char * const g_SegnmentTypes[] =
{
- "Unused",
- "Loadable segment",
- "Dynamic linking tables",
- "Program interpreter path name",
- "Note section",
- "SHLIB",
- "Program header table",
- "TLS"
+ "Unused"
+ , "Loadable segment"
+ , "Dynamic linking tables"
+ , "Program interpreter path name"
+ , "Note section"
+ , "SHLIB"
+ , "Program header table"
+ , "TLS"
};
-static const CUInt32PCharPair g_SegmentFlags[] =
+static const char * const g_SegmentFlags[] =
{
- { 0, "Execute" },
- { 1, "Write" },
- { 2, "Read" }
+ "Execute"
+ , "Write"
+ , "Read"
};
struct CSegment
@@ -359,173 +359,215 @@ bool CSection::Parse(const Byte *p, bool mode64, bool be)
return true;
}
-static const CUInt32PCharPair g_Machines[] =
+
+static const char * const g_Machines[] =
{
- { 0, "None" },
- { 1, "AT&T WE 32100" },
- { 2, "SPARC" },
- { 3, "Intel 386" },
- { 4, "Motorola 68000" },
- { 5, "Motorola 88000" },
- { 6, "Intel 486" },
- { 7, "Intel i860" },
- { 8, "MIPS" },
- { 9, "IBM S/370" },
- { 10, "MIPS RS3000 LE" },
- { 11, "RS6000" },
-
- { 15, "PA-RISC" },
- { 16, "nCUBE" },
- { 17, "Fujitsu VPP500" },
- { 18, "SPARC 32+" },
- { 19, "Intel i960" },
- { 20, "PowerPC" },
- { 21, "PowerPC 64-bit" },
- { 22, "IBM S/390" },
- { 23, "SPU" },
-
- { 36, "NEX v800" },
- { 37, "Fujitsu FR20" },
- { 38, "TRW RH-32" },
- { 39, "Motorola RCE" },
- { 40, "ARM" },
- { 41, "Alpha" },
- { 42, "Hitachi SH" },
- { 43, "SPARC-V9" },
- { 44, "Siemens Tricore" },
- { 45, "ARC" },
- { 46, "H8/300" },
- { 47, "H8/300H" },
- { 48, "H8S" },
- { 49, "H8/500" },
- { 50, "IA-64" },
- { 51, "Stanford MIPS-X" },
- { 52, "Motorola ColdFire" },
- { 53, "M68HC12" },
- { 54, "Fujitsu MMA" },
- { 55, "Siemens PCP" },
- { 56, "Sony nCPU" },
- { 57, "Denso NDR1" },
- { 58, "Motorola StarCore" },
- { 59, "Toyota ME16" },
- { 60, "ST100" },
- { 61, "Advanced Logic TinyJ" },
- { 62, "AMD64" },
- { 63, "Sony DSP" },
-
-
- { 66, "Siemens FX66" },
- { 67, "ST9+" },
- { 68, "ST7" },
- { 69, "MC68HC16" },
- { 70, "MC68HC11" },
- { 71, "MC68HC08" },
- { 72, "MC68HC05" },
- { 73, "Silicon Graphics SVx" },
- { 74, "ST19" },
- { 75, "Digital VAX" },
- { 76, "Axis CRIS" },
- { 77, "Infineon JAVELIN" },
- { 78, "Element 14 FirePath" },
- { 79, "LSI ZSP" },
- { 80, "MMIX" },
- { 81, "HUANY" },
- { 82, "SiTera Prism" },
- { 83, "Atmel AVR" },
- { 84, "Fujitsu FR30" },
- { 85, "Mitsubishi D10V" },
- { 86, "Mitsubishi D30V" },
- { 87, "NEC v850" },
- { 88, "Mitsubishi M32R" },
- { 89, "Matsushita MN10300" },
- { 90, "Matsushita MN10200" },
- { 91, "picoJava" },
- { 92, "OpenRISC" },
- { 93, "ARC Tangent-A5" },
- { 94, "Tensilica Xtensa" },
- { 95, "Alphamosaic VideoCore" },
- { 96, "Thompson MM GPP" },
- { 97, "National Semiconductor 32K" },
- { 98, "Tenor Network TPC" },
- { 99, "Trebia SNP 1000" },
- { 100, "ST200" },
- { 101, "Ubicom IP2xxx" },
- { 102, "MAX" },
- { 103, "NS CompactRISC" },
- { 104, "Fujitsu F2MC16" },
- { 105, "TI msp430" },
- { 106, "Blackfin (DSP)" },
- { 107, "SE S1C33" },
- { 108, "Sharp embedded" },
- { 109, "Arca RISC" },
- { 110, "Unicore" },
- { 111, "eXcess" },
- { 112, "DXP" },
- { 113, "Altera Nios II" },
- { 114, "NS CRX" },
- { 115, "Motorola XGATE" },
- { 116, "Infineon C16x/XC16x" },
- { 117, "Renesas M16C" },
- { 118, "Microchip Technology dsPIC30F" },
- { 119, "Freescale CE" },
- { 120, "Renesas M32C" },
-
- { 131, "Altium TSK3000" },
- { 132, "Freescale RS08" },
- { 133, "Analog Devices SHARC" },
- { 134, "Cyan Technology eCOG2" },
- { 135, "Sunplus S+core7 RISC" },
- { 136, "NJR 24-bit DSP" },
- { 137, "Broadcom VideoCore III" },
- { 138, "Lattice FPGA" },
- { 139, "SE C17" },
- { 140, "TI TMS320C6000" },
- { 141, "TI TMS320C2000" },
- { 142, "TI TMS320C55x" },
-
- { 160, "STM 64bit VLIW Data Signal" },
- { 161, "Cypress M8C" },
- { 162, "Renesas R32C" },
- { 163, "NXP TriMedia" },
- { 164, "Qualcomm Hexagon" },
- { 165, "Intel 8051" },
- { 166, "STMicroelectronics STxP7x" },
- { 167, "Andes" },
- { 168, "Cyan Technology eCOG1X" },
- { 169, "Dallas Semiconductor MAXQ30" },
- { 170, "NJR 16-bit DSP" },
- { 171, "M2000" },
- { 172, "Cray NV2" },
- { 173, "Renesas RX" },
- { 174, "Imagination Technologies META" },
- { 175, "MCST Elbrus" },
- { 176, "Cyan Technology eCOG16" },
- { 177, "National Semiconductor CR16" },
- { 178, "Freescale ETPUnit" },
- { 179, "Infineon SLE9X" },
- { 180, "Intel L10M" },
- { 181, "Intel K10M" },
-
- { 183, "ARM64" },
-
- { 185, "Atmel AVR32" },
- { 186, "STM8" },
- { 187, "Tilera TILE64" },
- { 188, "Tilera TILEPro" },
- { 189, "Xilinx MicroBlaze" },
- { 190, "NVIDIA CUDA" },
- { 191, "Tilera TILE-Gx" },
- { 192, "CloudShield" },
- { 193, "KIPO-KAIST Core-A 1st" },
- { 194, "KIPO-KAIST Core-A 2nd" },
- { 195, "Synopsys ARCompact V2" },
- { 196, "Open8" },
- { 197, "Renesas RL78" },
- { 198, "Broadcom VideoCore V" },
- { 199, "Renesas 78KOR" },
- { 200, "Freescale 56800EX" },
-
- { 47787, "Xilinx MicroBlaze" },
+ "None"
+ , "AT&T WE 32100"
+ , "SPARC"
+ , "Intel 386"
+ , "Motorola 68000"
+ , "Motorola 88000"
+ , "Intel 486"
+ , "Intel i860"
+ , "MIPS"
+ , "IBM S/370"
+ , "MIPS RS3000 LE"
+ , "RS6000"
+ , NULL
+ , NULL
+ , NULL
+ , "PA-RISC"
+ , "nCUBE"
+ , "Fujitsu VPP500"
+ , "SPARC 32+"
+ , "Intel i960"
+ , "PowerPC"
+ , "PowerPC 64-bit"
+ , "IBM S/390"
+ , "SPU"
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , "NEX v800"
+ , "Fujitsu FR20"
+ , "TRW RH-32"
+ , "Motorola RCE"
+ , "ARM"
+ , "Alpha"
+ , "Hitachi SH"
+ , "SPARC-V9"
+ , "Siemens Tricore"
+ , "ARC"
+ , "H8/300"
+ , "H8/300H"
+ , "H8S"
+ , "H8/500"
+ , "IA-64"
+ , "Stanford MIPS-X"
+ , "Motorola ColdFire"
+ , "M68HC12"
+ , "Fujitsu MMA"
+ , "Siemens PCP"
+ , "Sony nCPU"
+ , "Denso NDR1"
+ , "Motorola StarCore"
+ , "Toyota ME16"
+ , "ST100"
+ , "Advanced Logic TinyJ"
+ , "AMD64"
+ , "Sony DSP"
+ , NULL
+ , NULL
+ , "Siemens FX66"
+ , "ST9+"
+ , "ST7"
+ , "MC68HC16"
+ , "MC68HC11"
+ , "MC68HC08"
+ , "MC68HC05"
+ , "Silicon Graphics SVx"
+ , "ST19"
+ , "Digital VAX"
+ , "Axis CRIS"
+ , "Infineon JAVELIN"
+ , "Element 14 FirePath"
+ , "LSI ZSP"
+ , "MMIX"
+ , "HUANY"
+ , "SiTera Prism"
+ , "Atmel AVR"
+ , "Fujitsu FR30"
+ , "Mitsubishi D10V"
+ , "Mitsubishi D30V"
+ , "NEC v850"
+ , "Mitsubishi M32R"
+ , "Matsushita MN10300"
+ , "Matsushita MN10200"
+ , "picoJava"
+ , "OpenRISC"
+ , "ARC Tangent-A5"
+ , "Tensilica Xtensa"
+ , "Alphamosaic VideoCore"
+ , "Thompson MM GPP"
+ , "National Semiconductor 32K"
+ , "Tenor Network TPC"
+ , "Trebia SNP 1000"
+ , "ST200"
+ , "Ubicom IP2xxx"
+ , "MAX"
+ , "NS CompactRISC"
+ , "Fujitsu F2MC16"
+ , "TI msp430"
+ , "Blackfin (DSP)"
+ , "SE S1C33"
+ , "Sharp embedded"
+ , "Arca RISC"
+ , "Unicore"
+ , "eXcess"
+ , "DXP"
+ , "Altera Nios II"
+ , "NS CRX"
+ , "Motorola XGATE"
+ , "Infineon C16x/XC16x"
+ , "Renesas M16C"
+ , "Microchip Technology dsPIC30F"
+ , "Freescale CE"
+ , "Renesas M32C"
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , "Altium TSK3000"
+ , "Freescale RS08"
+ , "Analog Devices SHARC"
+ , "Cyan Technology eCOG2"
+ , "Sunplus S+core7 RISC"
+ , "NJR 24-bit DSP"
+ , "Broadcom VideoCore III"
+ , "Lattice FPGA"
+ , "SE C17"
+ , "TI TMS320C6000"
+ , "TI TMS320C2000"
+ , "TI TMS320C55x"
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , "STM 64bit VLIW Data Signal"
+ , "Cypress M8C"
+ , "Renesas R32C"
+ , "NXP TriMedia"
+ , "Qualcomm Hexagon"
+ , "Intel 8051"
+ , "STMicroelectronics STxP7x"
+ , "Andes"
+ , "Cyan Technology eCOG1X"
+ , "Dallas Semiconductor MAXQ30"
+ , "NJR 16-bit DSP"
+ , "M2000"
+ , "Cray NV2"
+ , "Renesas RX"
+ , "Imagination Technologies META"
+ , "MCST Elbrus"
+ , "Cyan Technology eCOG16"
+ , "National Semiconductor CR16"
+ , "Freescale ETPUnit"
+ , "Infineon SLE9X"
+ , "Intel L10M"
+ , "Intel K10M"
+ , NULL
+ , "ARM64"
+ , NULL
+ , "Atmel AVR32"
+ , "STM8"
+ , "Tilera TILE64"
+ , "Tilera TILEPro"
+ , "Xilinx MicroBlaze"
+ , "NVIDIA CUDA"
+ , "Tilera TILE-Gx"
+ , "CloudShield"
+ , "KIPO-KAIST Core-A 1st"
+ , "KIPO-KAIST Core-A 2nd"
+ , "Synopsys ARCompact V2"
+ , "Open8"
+ , "Renesas RL78"
+ , "Broadcom VideoCore V"
+ , "Renesas 78KOR"
+ , "Freescale 56800EX" // 200
+};
+
+static const CUInt32PCharPair g_MachinePairs[] =
+{
+ { 47787, "Xilinx MicroBlaze" }
// { 0x9026, "Alpha" }
};
@@ -554,6 +596,7 @@ static const CUInt32PCharPair g_OS[] =
{ 255, "Standalone" }
};
+#define k_Machine_MIPS 8
#define k_Machine_ARM 40
/*
@@ -566,12 +609,29 @@ static const CUInt32PCharPair g_OS[] =
static const CUInt32PCharPair g_ARM_Flags[] =
{
+ { 1, "HasEntry" },
{ 9, "SF" },
{ 10, "HF" },
{ 23, "BE8" }
};
+static const CUInt32PCharPair g_MIPS_Flags[] =
+{
+ { 0, "NOREORDER" },
+ { 1, "PIC" },
+ { 2, "CPIC" },
+ { 3, "XGOT" },
+ { 4, "64BIT_WHIRL" },
+ { 5, "ABI2" },
+ { 6, "ABI_ON32" },
+ { 10, "NAN2008" },
+ { 25, "MicroMIPS" },
+ { 26, "M16" },
+ { 27, "MDMX" }
+};
+
+
#define ET_NONE 0
#define ET_REL 1
#define ET_EXEC 2
@@ -580,11 +640,11 @@ static const CUInt32PCharPair g_ARM_Flags[] =
static const char * const g_Types[] =
{
- "None",
- "Relocatable file",
- "Executable file",
- "Shared object file",
- "Core file"
+ "None"
+ , "Relocatable file"
+ , "Executable file"
+ , "Shared object file"
+ , "Core file"
};
@@ -643,8 +703,7 @@ static const Byte kArcProps[] =
kpidBigEndian,
kpidHostOS,
kpidCharacts,
- kpidHeadersSize,
- kpidName
+ kpidHeadersSize
};
enum
@@ -683,21 +742,49 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidCpu:
{
- AString s = TypePairToString(g_Machines, ARRAY_SIZE(g_Machines), _header.Machine);
+ AString s;
+ if (_header.Machine < ARRAY_SIZE(g_Machines))
+ {
+ const char *name = g_Machines[_header.Machine];
+ if (name)
+ s = name;
+ }
+ if (s.IsEmpty())
+ s = TypePairToString(g_MachinePairs, ARRAY_SIZE(g_MachinePairs), _header.Machine);
UInt32 flags = _header.Flags;
if (flags != 0)
{
- char sz[16];
s.Add_Space();
if (_header.Machine == k_Machine_ARM)
{
s += FlagsToString(g_ARM_Flags, ARRAY_SIZE(g_ARM_Flags), flags & (((UInt32)1 << 24) - 1));
s += " ABI:";
- ConvertUInt32ToString(flags >> 24, sz);
+ s.Add_UInt32(flags >> 24);
+ }
+ else if (_header.Machine == k_Machine_MIPS)
+ {
+ UInt32 ver = flags >> 28;
+ s += "v";
+ s.Add_UInt32(ver);
+ flags &= (((UInt32)1 << 28) - 1);
+
+ UInt32 abi = (flags >> 12) & 7;
+ if (abi != 0)
+ {
+ s += " ABI:";
+ s.Add_UInt32(abi);
+ }
+ flags &= ~((UInt32)7 << 12);
+
+ s.Add_Space();
+ s += FlagsToString(g_MIPS_Flags, ARRAY_SIZE(g_MIPS_Flags), flags);
}
else
+ {
+ char sz[16];
ConvertUInt32ToHex(flags, sz);
- s += sz;
+ s += sz;
+ }
}
prop = s;
break;
diff --git a/CPP/7zip/Archive/ExtHandler.cpp b/CPP/7zip/Archive/ExtHandler.cpp
index 6c2cd726..3b690d07 100644
--- a/CPP/7zip/Archive/ExtHandler.cpp
+++ b/CPP/7zip/Archive/ExtHandler.cpp
@@ -20,7 +20,6 @@
#include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h"
-#include "../../Common/IntToString.h"
#include "../../Common/MyLinux.h"
#include "../../Common/StringConvert.h"
#include "../../Common/UTFConvert.h"
@@ -37,6 +36,8 @@
using namespace NWindows;
+UInt32 LzhCrc16Update(UInt32 crc, const void *data, size_t size);
+
namespace NArchive {
namespace NExt {
@@ -87,33 +88,9 @@ static UInt32 Crc32C_Calc(Byte const *data, size_t size)
*/
-// CRC-16-ANSI. The poly is 0x8005 (x^16 + x^15 + x^2 + 1)
-static UInt16 g_Crc16Table[256];
-
-static struct CInitCrc16
-{
- CInitCrc16()
- {
- for (unsigned i = 0; i < 256; i++)
- {
- UInt32 r = i;
- unsigned j;
- for (j = 0; j < 8; j++)
- r = (r >> 1) ^ (0xA001 & ~((r & 1) - 1));
- g_Crc16Table[i] = (UInt16)r;
- }
- }
-} g_InitCrc16;
-
-#define CRC16_UPDATE_BYTE(crc, b) (g_Crc16Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
#define CRC16_INIT_VAL 0xFFFF
-static UInt32 Crc16Update(UInt32 crc, Byte const *data, size_t size)
-{
- for (size_t i = 0; i < size; i++)
- crc = CRC16_UPDATE_BYTE(crc, data[i]);
- return crc;
-}
+#define Crc16Update(crc, data, size) LzhCrc16Update(crc, data, size)
static UInt32 Crc16Calc(Byte const *data, size_t size)
{
@@ -161,64 +138,64 @@ static const char * const kHostOS[] =
, "Lites"
};
-static const CUInt32PCharPair g_FeatureCompat_Flags[] =
-{
- { 0, "DIR_PREALLOC" },
- { 1, "IMAGIC_INODES" },
- { 2, "HAS_JOURNAL" },
- { 3, "EXT_ATTR" },
- { 4, "RESIZE_INODE" },
- { 5, "DIR_INDEX" },
- { 6, "LAZY_BG" }, // not in Linux
- // { 7, "EXCLUDE_INODE" }, // not used
- // { 8, "EXCLUDE_BITMAP" }, // not in kernel
- { 9, "SPARSE_SUPER2" }
+static const char * const g_FeatureCompat_Flags[] =
+{
+ "DIR_PREALLOC"
+ , "IMAGIC_INODES"
+ , "HAS_JOURNAL"
+ , "EXT_ATTR"
+ , "RESIZE_INODE"
+ , "DIR_INDEX"
+ , "LAZY_BG" // not in Linux
+ , NULL // { 7, "EXCLUDE_INODE" // not used
+ , NULL // { 8, "EXCLUDE_BITMAP" // not in kernel
+ , "SPARSE_SUPER2"
};
#define EXT4_FEATURE_INCOMPAT_FILETYPE (1 << 1)
#define EXT4_FEATURE_INCOMPAT_64BIT (1 << 7)
-static const CUInt32PCharPair g_FeatureIncompat_Flags[] =
-{
- { 0, "COMPRESSION" },
- { 1, "FILETYPE" },
- { 2, "RECOVER" }, /* Needs recovery */
- { 3, "JOURNAL_DEV" }, /* Journal device */
- { 4, "META_BG" },
-
- { 6, "EXTENTS" }, /* extents support */
- { 7, "64BIT" },
- { 8, "MMP" },
- { 9, "FLEX_BG" },
- { 10, "EA_INODE" }, /* EA in inode */
-
- { 12, "DIRDATA" }, /* data in dirent */
- { 13, "BG_USE_META_CSUM" }, /* use crc32c for bg */
- { 14, "LARGEDIR" }, /* >2GB or 3-lvl htree */
- { 15, "INLINE_DATA" }, /* data in inode */
- { 16, "ENCRYPT" }
+static const char * const g_FeatureIncompat_Flags[] =
+{
+ "COMPRESSION"
+ , "FILETYPE"
+ , "RECOVER" /* Needs recovery */
+ , "JOURNAL_DEV" /* Journal device */
+ , "META_BG"
+ , NULL
+ , "EXTENTS" /* extents support */
+ , "64BIT"
+ , "MMP"
+ , "FLEX_BG"
+ , "EA_INODE" /* EA in inode */
+ , NULL
+ , "DIRDATA" /* data in dirent */
+ , "BG_USE_META_CSUM" /* use crc32c for bg */
+ , "LARGEDIR" /* >2GB or 3-lvl htree */
+ , "INLINE_DATA" /* data in inode */
+ , "ENCRYPT" // 16
};
static const UInt32 RO_COMPAT_GDT_CSUM = 1 << 4;
static const UInt32 RO_COMPAT_METADATA_CSUM = 1 << 10;
-static const CUInt32PCharPair g_FeatureRoCompat_Flags[] =
-{
- { 0, "SPARSE_SUPER" },
- { 1, "LARGE_FILE" },
- { 2, "BTREE_DIR" },
- { 3, "HUGE_FILE" },
- { 4, "GDT_CSUM" },
- { 5, "DIR_NLINK" },
- { 6, "EXTRA_ISIZE" },
- { 7, "HAS_SNAPSHOT" },
- { 8, "QUOTA" },
- { 9, "BIGALLOC" },
- { 10, "METADATA_CSUM" },
- { 11, "REPLICA" },
- { 12, "READONLY" }
+static const char * const g_FeatureRoCompat_Flags[] =
+{
+ "SPARSE_SUPER"
+ , "LARGE_FILE"
+ , "BTREE_DIR"
+ , "HUGE_FILE"
+ , "GDT_CSUM"
+ , "DIR_NLINK"
+ , "EXTRA_ISIZE"
+ , "HAS_SNAPSHOT"
+ , "QUOTA"
+ , "BIGALLOC"
+ , "METADATA_CSUM"
+ , "REPLICA"
+ , "READONLY" // 12
};
@@ -227,33 +204,37 @@ static const UInt32 k_NodeFlags_HUGE = (UInt32)1 << 18;
static const UInt32 k_NodeFlags_EXTENTS = (UInt32)1 << 19;
-static const CUInt32PCharPair g_NodeFlags[] =
-{
- { 0, "SECRM" },
- { 1, "UNRM" },
- { 2, "COMPR" },
- { 3, "SYNC" },
- { 4, "IMMUTABLE" },
- { 5, "APPEND" },
- { 6, "NODUMP" },
- { 7, "NOATIME" },
- { 8, "DIRTY" },
- { 9, "COMPRBLK" },
- { 10, "NOCOMPR" },
- { 11, "ENCRYPT" },
- { 12, "INDEX" },
- { 13, "IMAGIC" },
- { 14, "JOURNAL_DATA" },
- { 15, "NOTAIL" },
- { 16, "DIRSYNC" },
- { 17, "TOPDIR" },
- { 18, "HUGE_FILE" },
- { 19, "EXTENTS" },
-
- { 21, "EA_INODE" },
- { 22, "EOFBLOCKS" },
-
- { 28, "INLINE_DATA" }
+static const char * const g_NodeFlags[] =
+{
+ "SECRM"
+ , "UNRM"
+ , "COMPR"
+ , "SYNC"
+ , "IMMUTABLE"
+ , "APPEND"
+ , "NODUMP"
+ , "NOATIME"
+ , "DIRTY"
+ , "COMPRBLK"
+ , "NOCOMPR"
+ , "ENCRYPT"
+ , "INDEX"
+ , "IMAGIC"
+ , "JOURNAL_DATA"
+ , "NOTAIL"
+ , "DIRSYNC"
+ , "TOPDIR"
+ , "HUGE_FILE"
+ , "EXTENTS"
+ , NULL
+ , "EA_INODE"
+ , "EOFBLOCKS"
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , "INLINE_DATA" // 28
};
@@ -1540,20 +1521,16 @@ HRESULT CHandler::Open2(IInStream *inStream)
useUnknown = true;
if (item.Name.IsEmpty())
- {
- char temp[16];
- ConvertUInt32ToString(item.Node, temp);
- item.Name = temp;
- }
+ item.Name.Add_UInt32(item.Node);
_items.Add(item);
}
}
if (useSys)
- _auxSysIndex = _auxItems.Add("[SYS]");
+ _auxSysIndex = _auxItems.Add((AString)"[SYS]");
if (useUnknown)
- _auxUnknownIndex = _auxItems.Add("[UNKNOWN]");
+ _auxUnknownIndex = _auxItems.Add((AString)"[UNKNOWN]");
}
return S_OK;
@@ -1834,16 +1811,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidHostOS:
{
- char temp[16];
- const char *s = NULL;
- if (_h.CreatorOs < ARRAY_SIZE(kHostOS))
- s = kHostOS[_h.CreatorOs];
- else
- {
- ConvertUInt32ToString(_h.CreatorOs, temp);
- s = temp;
- }
- prop = s;
+ TYPE_TO_PROP(kHostOS, _h.CreatorOs, prop);
break;
}
@@ -1995,39 +1963,34 @@ STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data
static void ExtTimeToProp(const CExtTime &t, NCOM::CPropVariant &prop)
{
- /*
- UInt32 nano = 0;
- if (t.Extra != 0)
- {
- UInt32 mask = t.Extra & 3;
- if (mask != 0)
- return;
- nano = t.Extra >> 2;
- }
- UInt64 v;
- if (t.Val == 0 && nano == 0)
+ if (t.Val == 0 && t.Extra == 0)
return;
- if (!NTime::UnixTime_to_FileTime64(t.Val, v))
- return;
- if (nano != 0)
- v += nano / 100;
FILETIME ft;
- ft.dwLowDateTime = (DWORD)v;
- ft.dwHighDateTime = (DWORD)(v >> 32);
- prop = ft;
- */
- if (t.Val == 0)
- return;
- if (t.Extra != 0)
+ // if (t.Extra != 0)
{
- UInt32 mask = t.Extra & 3;
- if (mask != 0)
- return;
+ // 1901-2446 :
+ Int64 v = (Int64)(Int32)t.Val;
+ v += (UInt64)(t.Extra & 3) << 32; // 2 low bits are offset for main timestamp
+ UInt64 ft64 = NTime::UnixTime64ToFileTime64(v);
+ const UInt32 ns = (t.Extra >> 2);
+ if (ns < 1000000000)
+ ft64 += ns / 100;
+ ft.dwLowDateTime = (DWORD)ft64;
+ ft.dwHighDateTime = (DWORD)(ft64 >> 32);
}
- FILETIME ft;
- if (NTime::UnixTime64ToFileTime(t.Val, ft))
- prop = ft;
+ /*
+ else
+ {
+ // 1901-2038 : that code is good for ext4 and compatibility with Extra
+ NTime::UnixTime64ToFileTime((Int32)t.Val, ft); // for
+
+ // 1970-2106 : that code is good if timestamp is used as unsigned 32-bit
+ // are there such systems?
+ // NTime::UnixTimeToFileTime(t.Val, ft); // for
+ }
+ */
+ prop = ft;
}
@@ -2043,8 +2006,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPath:
case kpidName:
{
- AString s = _auxItems[index - _items.Size()];
- prop = s;
+ prop = _auxItems[index - _items.Size()];
break;
}
case kpidIsDir: prop = true; break;
diff --git a/CPP/7zip/Archive/GptHandler.cpp b/CPP/7zip/Archive/GptHandler.cpp
index 52c7aab9..a86ad37c 100644
--- a/CPP/7zip/Archive/GptHandler.cpp
+++ b/CPP/7zip/Archive/GptHandler.cpp
@@ -123,33 +123,11 @@ static int FindPartType(const Byte *guid)
return -1;
}
-static inline char GetHex(unsigned t) { return (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); }
-static void PrintHex(unsigned v, char *s)
+static void RawLeGuidToString_Upper(const Byte *g, char *s)
{
- s[0] = GetHex((v >> 4) & 0xF);
- s[1] = GetHex(v & 0xF);
-}
-
-static void ConvertUInt16ToHex4Digits(UInt32 val, char *s) throw()
-{
- PrintHex(val >> 8, s);
- PrintHex(val & 0xFF, s + 2);
-}
-
-static void GuidToString(const Byte *g, char *s)
-{
- ConvertUInt32ToHex8Digits(Get32(g ), s); s += 8; *s++ = '-';
- ConvertUInt16ToHex4Digits(Get16(g + 4), s); s += 4; *s++ = '-';
- ConvertUInt16ToHex4Digits(Get16(g + 6), s); s += 4; *s++ = '-';
- for (unsigned i = 0; i < 8; i++)
- {
- if (i == 2)
- *s++ = '-';
- PrintHex(g[8 + i], s);
- s += 2;
- }
- *s = 0;
+ RawLeGuidToString(g, s);
+ // MyStringUpper_Ascii(s);
}
@@ -328,7 +306,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidId:
{
char s[48];
- GuidToString(Guid, s);
+ RawLeGuidToString_Upper(Guid, s);
prop = s;
break;
}
@@ -364,18 +342,16 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
s += c;
}
if (s.IsEmpty())
+ s.Add_UInt32(index);
{
- char temp[16];
- ConvertUInt32ToString(index, temp);
- s.AddAscii(temp);
- }
- {
+ s += '.';
+ const char *ext = NULL;
int typeIndex = FindPartType(item.Type);
- s += L'.';
- const char *ext = "img";
- if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Ext)
+ if (typeIndex >= 0)
ext = kPartTypes[(unsigned)typeIndex].Ext;
- s.AddAscii(ext);
+ if (!ext)
+ ext = "img";
+ s += ext;
}
prop = s;
break;
@@ -394,7 +370,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
res = kPartTypes[(unsigned)typeIndex].Type;
else
{
- GuidToString(item.Type, s);
+ RawLeGuidToString_Upper(item.Type, s);
res = s;
}
prop = res;
@@ -404,7 +380,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidId:
{
char s[48];
- GuidToString(item.Id, s);
+ RawLeGuidToString_Upper(item.Id, s);
prop = s;
break;
}
diff --git a/CPP/7zip/Archive/GzHandler.cpp b/CPP/7zip/Archive/GzHandler.cpp
index d8979ada..130f8b35 100644
--- a/CPP/7zip/Archive/GzHandler.cpp
+++ b/CPP/7zip/Archive/GzHandler.cpp
@@ -11,6 +11,7 @@
#include "../../Common/StringConvert.h"
#include "../../Windows/PropVariant.h"
+#include "../../Windows/PropVariantUtils.h"
#include "../../Windows/TimeUtils.h"
#include "../Common/ProgressUtils.h"
@@ -109,7 +110,6 @@ static const char * const kHostOSes[] =
, "OS/X"
};
-static const char *kUnknownOS = "Unknown";
class CItem
{
@@ -537,7 +537,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (_item.NameIsPresent())
{
UString s = MultiByteToUnicodeString(_item.Name, CP_ACP);
- s.AddAscii(".gz");
+ s += ".gz";
prop = s;
}
break;
@@ -587,8 +587,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
prop = _packSize;
break;
}
- case kpidHostOS: prop = (_item.HostOS < ARRAY_SIZE(kHostOSes)) ?
- kHostOSes[_item.HostOS] : kUnknownOS; break;
+ case kpidHostOS: TYPE_TO_PROP(kHostOSes, _item.HostOS, prop); break;
case kpidCRC: if (_stream) prop = _item.Crc; break;
}
prop.Detach(value);
@@ -1035,7 +1034,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
static const Byte k_Signature[] = { kSignature_0, kSignature_1, kSignature_2 };
REGISTER_ARC_IO(
- "gzip", "gz gzip tgz tpz", "* * .tar .tar", 0xEF,
+ "gzip", "gz gzip tgz tpz apk", "* * .tar .tar .tar", 0xEF,
k_Signature,
0,
NArcInfoFlags::kKeepName,
diff --git a/CPP/7zip/Archive/HfsHandler.cpp b/CPP/7zip/Archive/HfsHandler.cpp
index 185df7f0..d02f0725 100644
--- a/CPP/7zip/Archive/HfsHandler.cpp
+++ b/CPP/7zip/Archive/HfsHandler.cpp
@@ -28,7 +28,7 @@
namespace NArchive {
namespace NHfs {
-static const char *kResFileName = "rsrc"; // "com.apple.ResourceFork";
+static const char * const kResFileName = "rsrc"; // "com.apple.ResourceFork";
struct CExtent
{
@@ -497,11 +497,14 @@ struct CHeaderRec
// UInt32 Attributes;
// UInt32 Reserved3[16];
- HRESULT Parse(const Byte *p);
+ HRESULT Parse2(const CByteBuffer &buf);
};
-HRESULT CHeaderRec::Parse(const Byte *p)
+HRESULT CHeaderRec::Parse2(const CByteBuffer &buf)
{
+ if (buf.Size() < kNodeDescriptor_Size + 0x2A + 16 * 4)
+ return S_FALSE;
+ const Byte * p = (const Byte *)buf + kNodeDescriptor_Size;
// TreeDepth = Get16(p);
// RootNode = Get32(p + 2);
// LeafRecords = Get32(p + 6);
@@ -527,6 +530,10 @@ HRESULT CHeaderRec::Parse(const Byte *p)
for (int i = 0; i < 16; i++)
Reserved3[i] = Get32(p + 0x2A + i * 4);
*/
+
+ if ((buf.Size() >> NodeSizeLog) < TotalNodes)
+ return S_FALSE;
+
return S_OK;
}
@@ -553,10 +560,7 @@ HRESULT CDatabase::LoadExtentFile(const CFork &fork, IInStream *inStream, CObjec
// CNodeDescriptor nodeDesc;
// nodeDesc.Parse(p);
CHeaderRec hr;
- RINOK(hr.Parse(p + kNodeDescriptor_Size));
-
- if ((buf.Size() >> hr.NodeSizeLog) < hr.TotalNodes)
- return S_FALSE;
+ RINOK(hr.Parse2(buf));
UInt32 node = hr.FirstLeafNode;
if (node == 0)
@@ -695,13 +699,10 @@ HRESULT CDatabase::LoadAttrs(const CFork &fork, IInStream *inStream, IArchiveOpe
// CNodeDescriptor nodeDesc;
// nodeDesc.Parse(p);
CHeaderRec hr;
- RINOK(hr.Parse(p + kNodeDescriptor_Size));
+ RINOK(hr.Parse2(AttrBuf));
// CaseSensetive = (Header.IsHfsX() && hr.KeyCompareType == 0xBC);
- if ((AttrBuf.Size() >> hr.NodeSizeLog) < hr.TotalNodes)
- return S_FALSE;
-
UInt32 node = hr.FirstLeafNode;
if (node == 0)
return S_OK;
@@ -876,13 +877,10 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
// CNodeDescriptor nodeDesc;
// nodeDesc.Parse(p);
CHeaderRec hr;
- RINOK(hr.Parse(p + kNodeDescriptor_Size));
+ RINOK(hr.Parse2(buf));
// CaseSensetive = (Header.IsHfsX() && hr.KeyCompareType == 0xBC);
- if ((buf.Size() >> hr.NodeSizeLog) < hr.TotalNodes)
- return S_FALSE;
-
CByteBuffer usedBuf(hr.TotalNodes);
memset(usedBuf, 0, hr.TotalNodes);
@@ -966,13 +964,13 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
IsNameEqualTo(name + 8, "HFS+ Private Data"))
{
// it's folder for "Hard Links" files
- item.Name.SetFromAscii("[HFS+ Private Data]");
+ item.Name = "[HFS+ Private Data]";
}
}
// Some dmg files have ' ' folder item.
if (item.Name.IsEmpty() || item.Name[0] == L' ')
- item.Name.SetFromAscii("[]");
+ item.Name = "[]";
}
}
@@ -1228,7 +1226,7 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
return S_FALSE;
*/
- ResFileName.SetFromAscii(kResFileName);
+ ResFileName = kResFileName;
CFork extentsFork, catalogFork, attrFork;
// allocationFork.Parse(p + 0x70 + 0x50 * 0);
diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp
index 5a19516c..2230cd23 100644
--- a/CPP/7zip/Archive/Iso/IsoHandler.cpp
+++ b/CPP/7zip/Archive/Iso/IsoHandler.cpp
@@ -3,7 +3,6 @@
#include "StdAfx.h"
#include "../../../Common/ComTry.h"
-#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/PropVariant.h"
@@ -176,12 +175,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath:
{
- AString s = "[BOOT]" STRING_PATH_SEPARATOR;
+ AString s ("[BOOT]" STRING_PATH_SEPARATOR);
if (_archive.BootEntries.Size() != 1)
{
- char temp[16];
- ConvertUInt32ToString(index + 1, temp);
- s += temp;
+ s.Add_UInt32(index + 1);
s += '-';
}
s += be.GetName();
@@ -216,7 +213,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (!s.IsEmpty() && s.Back() == L'.')
s.DeleteBack();
- NItemName::ConvertToOSName2(s);
+ NItemName::ReplaceToOsSlashes_Remove_TailSlash(s);
prop = s;
}
break;
diff --git a/CPP/7zip/Archive/Iso/IsoHeader.cpp b/CPP/7zip/Archive/Iso/IsoHeader.cpp
index 59c283c1..3b59060a 100644
--- a/CPP/7zip/Archive/Iso/IsoHeader.cpp
+++ b/CPP/7zip/Archive/Iso/IsoHeader.cpp
@@ -7,6 +7,6 @@
namespace NArchive {
namespace NIso {
-const char *kElToritoSpec = "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0";
+const char * const kElToritoSpec = "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0";
}}
diff --git a/CPP/7zip/Archive/Iso/IsoHeader.h b/CPP/7zip/Archive/Iso/IsoHeader.h
index db0b1df9..e6a4d327 100644
--- a/CPP/7zip/Archive/Iso/IsoHeader.h
+++ b/CPP/7zip/Archive/Iso/IsoHeader.h
@@ -25,7 +25,7 @@ namespace NFileFlags
const Byte kNonFinalExtent = 1 << 7;
}
-extern const char *kElToritoSpec;
+extern const char * const kElToritoSpec;
const UInt32 kStartPos = 0x8000;
diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp
index 8530a25e..65be1146 100644
--- a/CPP/7zip/Archive/Iso/IsoIn.cpp
+++ b/CPP/7zip/Archive/Iso/IsoIn.cpp
@@ -47,17 +47,13 @@ bool CBootInitialEntry::Parse(const Byte *p)
AString CBootInitialEntry::GetName() const
{
- AString s = (Bootable ? "Boot" : "NotBoot");
+ AString s (Bootable ? "Boot" : "NotBoot");
s += '-';
if (BootMediaType < ARRAY_SIZE(kMediaTypes))
s += kMediaTypes[BootMediaType];
else
- {
- char name[16];
- ConvertUInt32ToString(BootMediaType, name);
- s += name;
- }
+ s.Add_UInt32(BootMediaType);
if (VendorSpec[0] == 1)
{
diff --git a/CPP/7zip/Archive/Iso/IsoIn.h b/CPP/7zip/Archive/Iso/IsoIn.h
index 4000fc92..347f9e9b 100644
--- a/CPP/7zip/Archive/Iso/IsoIn.h
+++ b/CPP/7zip/Archive/Iso/IsoIn.h
@@ -3,7 +3,6 @@
#ifndef __ARCHIVE_ISO_IN_H
#define __ARCHIVE_ISO_IN_H
-#include "../../../Common/IntToString.h"
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
diff --git a/CPP/7zip/Archive/Iso/IsoItem.h b/CPP/7zip/Archive/Iso/IsoItem.h
index c4950e60..5ae13a60 100644
--- a/CPP/7zip/Archive/Iso/IsoItem.h
+++ b/CPP/7zip/Archive/Iso/IsoItem.h
@@ -223,6 +223,7 @@ struct CDirRecord
const bool GetPx(int skipSize, unsigned pxType, UInt32 &val) const
{
+ val = 0;
const Byte *p = NULL;
unsigned len = 0;
p = FindSuspRecord(skipSize, 'P', 'X', len);
diff --git a/CPP/7zip/Archive/LzhHandler.cpp b/CPP/7zip/Archive/LzhHandler.cpp
index c8d3ff6d..53d69db7 100644
--- a/CPP/7zip/Archive/LzhHandler.cpp
+++ b/CPP/7zip/Archive/LzhHandler.cpp
@@ -9,6 +9,7 @@
#include "../../Common/StringConvert.h"
#include "../../Windows/PropVariant.h"
+#include "../../Windows/PropVariantUtils.h"
#include "../../Windows/TimeUtils.h"
#include "../ICoder.h"
@@ -31,10 +32,44 @@ using namespace NTime;
#define Get16(p) GetUi16(p)
#define Get32(p) GetUi32(p)
+
+// CRC-16 (-IBM, -ANSI). The poly is 0x8005 (x^16 + x^15 + x^2 + 1)
+
+static const UInt16 kCrc16Poly = 0xA001;
+
+static UInt16 g_LzhCrc16Table[256];
+
+#define CRC16_UPDATE_BYTE(crc, b) (g_LzhCrc16Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+
+UInt32 LzhCrc16Update(UInt32 crc, const void *data, size_t size)
+{
+ const Byte *p = (const Byte *)data;
+ const Byte *pEnd = p + size;
+ for (; p != pEnd; p++)
+ crc = CRC16_UPDATE_BYTE(crc, *p);
+ return crc;
+}
+
+static class CLzhCrc16TableInit
+{
+public:
+ CLzhCrc16TableInit()
+ {
+ for (UInt32 i = 0; i < 256; i++)
+ {
+ UInt32 r = i;
+ for (unsigned j = 0; j < 8; j++)
+ r = (r >> 1) ^ (kCrc16Poly & ((UInt32)0 - (r & 1)));
+ g_LzhCrc16Table[i] = (UInt16)r;
+ }
+ }
+} g_LzhCrc16TableInit;
+
+
namespace NArchive {
namespace NLzh{
-const int kMethodIdSize = 5;
+const unsigned kMethodIdSize = 5;
const Byte kExtIdFileName = 0x01;
const Byte kExtIdDirName = 0x02;
@@ -125,7 +160,7 @@ struct CItem
return false;
}
- int GetNumDictBits() const
+ unsigned GetNumDictBits() const
{
if (!IsLhMethod())
return 0;
@@ -185,7 +220,7 @@ struct CItem
AString GetName() const
{
- AString dirName = GetDirName();
+ AString dirName (GetDirName());
const char kDirSeparator = '\\';
// check kDirSeparator in Linux
dirName.Replace((char)(unsigned char)0xFF, kDirSeparator);
@@ -310,13 +345,8 @@ static HRESULT GetNextItem(ISequentialInStream *stream, bool &filled, CItem &ite
return S_OK;
}
-struct COsPair
-{
- Byte Id;
- const char *Name;
-};
-static const COsPair g_OsPairs[] =
+static const CUInt32PCharPair g_OsPairs[] =
{
{ 0, "MS-DOS" },
{ 'M', "MS-DOS" },
@@ -337,15 +367,6 @@ static const COsPair g_OsPairs[] =
{ 'J', "Java VM" }
};
-static const char *kUnknownOS = "Unknown";
-
-static const char *GetOS(Byte osId)
-{
- for (unsigned i = 0; i < ARRAY_SIZE(g_OsPairs); i++)
- if (g_OsPairs[i].Id == osId)
- return g_OsPairs[i].Name;
- return kUnknownOS;
-}
static const Byte kProps[] =
{
@@ -360,52 +381,6 @@ static const Byte kProps[] =
kpidHostOS
};
-class CCRC
-{
- UInt16 _value;
-public:
- static UInt16 Table[256];
- static void InitTable();
-
- CCRC(): _value(0) {}
- void Init() { _value = 0; }
- void Update(const void *data, size_t size);
- UInt16 GetDigest() const { return _value; }
-};
-
-static const UInt16 kCRCPoly = 0xA001;
-
-UInt16 CCRC::Table[256];
-
-void CCRC::InitTable()
-{
- for (UInt32 i = 0; i < 256; i++)
- {
- UInt32 r = i;
- for (int j = 0; j < 8; j++)
- if (r & 1)
- r = (r >> 1) ^ kCRCPoly;
- else
- r >>= 1;
- CCRC::Table[i] = (UInt16)r;
- }
-}
-
-class CCRCTableInit
-{
-public:
- CCRCTableInit() { CCRC::InitTable(); }
-} g_CRCTableInit;
-
-void CCRC::Update(const void *data, size_t size)
-{
- UInt16 v = _value;
- const Byte *p = (const Byte *)data;
- for (; size > 0; size--, p++)
- v = (UInt16)(Table[((Byte)(v)) ^ *p] ^ (v >> 8));
- _value = v;
-}
-
class COutStreamWithCRC:
public ISequentialOutStream,
@@ -416,41 +391,36 @@ public:
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
private:
- CCRC _crc;
+ UInt32 _crc;
CMyComPtr<ISequentialOutStream> _stream;
public:
void Init(ISequentialOutStream *stream)
{
_stream = stream;
- _crc.Init();
+ _crc = 0;
}
void ReleaseStream() { _stream.Release(); }
- UInt32 GetCRC() const { return _crc.GetDigest(); }
- void InitCRC() { _crc.Init(); }
+ UInt32 GetCRC() const { return _crc; }
};
STDMETHODIMP COutStreamWithCRC::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);
- _crc.Update(data, realProcessedSize);
- if (processedSize != NULL)
- *processedSize = realProcessedSize;
- return result;
+ HRESULT res = S_OK;
+ if (_stream)
+ res = _stream->Write(data, size, &size);
+ _crc = LzhCrc16Update(_crc, data, size);
+ if (processedSize)
+ *processedSize = size;
+ return res;
}
+
struct CItemEx: public CItem
{
UInt64 DataPosition;
};
+
class CHandler:
public IInArchive,
public CMyUnknownImp
@@ -503,7 +473,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath:
{
- UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetName(), CP_OEMCP));
+ UString s = NItemName::WinPathToOsPath(MultiByteToUnicodeString(item.GetName(), CP_OEMCP));
if (!s.IsEmpty())
{
if (s.Back() == WCHAR_PATH_SEPARATOR)
@@ -516,7 +486,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidSize: prop = item.Size; break;
case kpidPackSize: prop = item.PackSize; break;
case kpidCRC: prop = (UInt32)item.CRC; break;
- case kpidHostOS: prop = GetOS(item.OsId); break;
+ case kpidHostOS: PAIR_TO_PROP(g_OsPairs, item.OsId, prop); break;
case kpidMTime:
{
FILETIME utc;
@@ -571,15 +541,15 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
{
CItemEx item;
bool filled;
- HRESULT result = GetNextItem(stream, filled, item);
+ HRESULT res = GetNextItem(stream, filled, item);
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &item.DataPosition));
- if (result == S_FALSE)
+ if (res == S_FALSE)
{
_errorFlags = kpv_ErrorFlags_HeadersError;
break;
}
- if (result != S_OK)
+ if (res != S_OK)
return S_FALSE;
_phySize = item.DataPosition;
if (!filled)
@@ -720,14 +690,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
streamSpec->Init(item.PackSize);
- HRESULT result = S_OK;
+ HRESULT res = S_OK;
Int32 opRes = NExtract::NOperationResult::kOK;
if (item.IsCopyMethod())
{
- result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
- if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize)
- result = S_FALSE;
+ res = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
+ if (res == S_OK && copyCoderSpec->TotalSize != item.PackSize)
+ res = S_FALSE;
}
else if (item.IsLh4GroupMethod())
{
@@ -738,9 +708,9 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
lzhDecoderSpec->FinishMode = true;
lzhDecoderSpec->SetDictSize(1 << item.GetNumDictBits());
- result = lzhDecoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
- if (result == S_OK && lzhDecoderSpec->GetInputProcessedSize() != item.PackSize)
- result = S_FALSE;
+ res = lzhDecoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
+ if (res == S_OK && lzhDecoderSpec->GetInputProcessedSize() != item.PackSize)
+ res = S_FALSE;
}
/*
else if (item.IsLh1GroupMethod())
@@ -751,7 +721,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
lzh1Decoder = lzh1DecoderSpec;
}
lzh1DecoderSpec->SetDictionary(item.GetNumDictBits());
- result = lzh1Decoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
+ res = lzh1Decoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
}
*/
else
@@ -759,11 +729,11 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (opRes == NExtract::NOperationResult::kOK)
{
- if (result == S_FALSE)
+ if (res == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
else
{
- RINOK(result);
+ RINOK(res);
if (outStreamSpec->GetCRC() != item.CRC)
opRes = NExtract::NOperationResult::kCRCError;
}
diff --git a/CPP/7zip/Archive/LzmaHandler.cpp b/CPP/7zip/Archive/LzmaHandler.cpp
index 121cd67c..afdc2bfa 100644
--- a/CPP/7zip/Archive/LzmaHandler.cpp
+++ b/CPP/7zip/Archive/LzmaHandler.cpp
@@ -44,7 +44,8 @@ static const Byte kProps[] =
static const Byte kArcProps[] =
{
- kpidNumStreams
+ kpidNumStreams,
+ kpidMethod
};
struct CHeader
@@ -53,6 +54,7 @@ struct CHeader
Byte FilterID;
Byte LzmaProps[5];
+ Byte GetProp() const { return LzmaProps[0]; }
UInt32 GetDicSize() const { return GetUi32(LzmaProps + 1); }
bool HasSize() const { return (Size != (UInt64)(Int64)-1); }
bool Parse(const Byte *buf, bool isThereFilter);
@@ -197,6 +199,8 @@ class CHandler:
UInt64 _unpackSize;
UInt64 _numStreams;
+ void GetMethod(NCOM::CPropVariant &prop);
+
public:
MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq)
@@ -220,6 +224,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidPhySize: if (_packSize_Defined) prop = _packSize; break;
case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break;
case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break;
+ case kpidMethod: GetMethod(prop); break;
case kpidErrorFlags:
{
UInt32 v = 0;
@@ -229,6 +234,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
if (_dataError) v |= kpv_ErrorFlags_DataError;
prop = v;
+ break;
}
}
prop.Detach(value);
@@ -241,23 +247,60 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
-static void DictSizeToString(UInt32 value, char *s)
+
+static void DictSizeToString(UInt32 val, char *s)
{
- for (int i = 0; i <= 31; i++)
- if (((UInt32)1 << i) == value)
+ for (unsigned i = 0; i <= 31; i++)
+ if (((UInt32)1 << i) == val)
{
::ConvertUInt32ToString(i, s);
return;
}
char c = 'b';
- if ((value & ((1 << 20) - 1)) == 0) { value >>= 20; c = 'm'; }
- else if ((value & ((1 << 10) - 1)) == 0) { value >>= 10; c = 'k'; }
- ::ConvertUInt32ToString(value, s);
+ if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
+ else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
+ ::ConvertUInt32ToString(val, s);
s += MyStringLen(s);
*s++ = c;
*s = 0;
}
+static char *AddProp32(char *s, const char *name, UInt32 v)
+{
+ *s++ = ':';
+ s = MyStpCpy(s, name);
+ ::ConvertUInt32ToString(v, s);
+ return s + MyStringLen(s);
+}
+
+void CHandler::GetMethod(NCOM::CPropVariant &prop)
+{
+ if (!_stream)
+ return;
+
+ char sz[64];
+ char *s = sz;
+ if (_header.FilterID != 0)
+ s = MyStpCpy(s, "BCJ ");
+ s = MyStpCpy(s, "LZMA:");
+ DictSizeToString(_header.GetDicSize(), s);
+ s += strlen(s);
+
+ UInt32 d = _header.GetProp();
+ // if (d != 0x5D)
+ {
+ UInt32 lc = d % 9;
+ d /= 9;
+ UInt32 pb = d / 5;
+ UInt32 lp = d % 5;
+ if (lc != 3) s = AddProp32(s, "lc", lc);
+ if (lp != 0) s = AddProp32(s, "lp", lp);
+ if (pb != 2) s = AddProp32(s, "pb", pb);
+ }
+ prop = sz;
+}
+
+
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
@@ -265,18 +308,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
{
case kpidSize: if (_stream && _header.HasSize()) prop = _header.Size; break;
case kpidPackSize: if (_packSize_Defined) prop = _packSize; break;
- case kpidMethod:
- if (_stream)
- {
- char sz[64];
- char *s = sz;
- if (_header.FilterID != 0)
- s = MyStpCpy(s, "BCJ ");
- s = MyStpCpy(s, "LZMA:");
- DictSizeToString(_header.GetDicSize(), s);
- prop = sz;
- }
- break;
+ case kpidMethod: GetMethod(prop); break;
}
prop.Detach(value);
return S_OK;
@@ -396,9 +428,9 @@ STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const
{
if (Callback)
{
- UInt64 files = 0;
- UInt64 value = Offset + *inSize;
- return Callback->SetCompleted(&files, &value);
+ const UInt64 files = 0;
+ const UInt64 val = Offset + *inSize;
+ return Callback->SetCompleted(&files, &val);
}
return S_OK;
}
@@ -510,7 +542,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
if (dataAfterEnd)
_dataAfterEnd = true;
- else if (decoder._lzmaDecoderSpec->NeedMoreInput)
+ else if (decoder._lzmaDecoderSpec->NeedsMoreInput())
_needMoreInput = true;
_packSize = packSize;
diff --git a/CPP/7zip/Archive/MachoHandler.cpp b/CPP/7zip/Archive/MachoHandler.cpp
index 26260686..1f65574d 100644
--- a/CPP/7zip/Archive/MachoHandler.cpp
+++ b/CPP/7zip/Archive/MachoHandler.cpp
@@ -37,6 +37,7 @@ namespace NMacho {
#define CPU_TYPE_PPC64 (CPU_ARCH_ABI64 | CPU_TYPE_PPC)
#define CPU_TYPE_AMD64 (CPU_ARCH_ABI64 | CPU_TYPE_386)
+#define CPU_TYPE_ARM64 (CPU_ARCH_ABI64 | CPU_TYPE_ARM)
#define CPU_SUBTYPE_LIB64 (1 << 31)
@@ -60,6 +61,8 @@ static const char * const k_PowerPc_SubTypes[] =
static const CUInt32PCharPair g_CpuPairs[] =
{
+ { CPU_TYPE_AMD64, "x64" },
+ { CPU_TYPE_ARM64, "ARM64" },
{ CPU_TYPE_386, "x86" },
{ CPU_TYPE_ARM, "ARM" },
{ CPU_TYPE_SPARC, "SPARC" },
@@ -168,7 +171,7 @@ static const CUInt32PCharPair g_Flags[] =
{ 8, "LOC_RELOC" }
};
-static const int kNameSize = 16;
+static const unsigned kNameSize = 16;
struct CSegment
{
@@ -255,16 +258,16 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
AString s;
char temp[16];
UInt32 cpu = _cpuType & ~(UInt32)CPU_ARCH_ABI64;
- if (_cpuType == CPU_TYPE_AMD64)
- s = "x64";
- else
+ UInt32 flag64 = _cpuType & (UInt32)CPU_ARCH_ABI64;
{
const char *n = NULL;
for (unsigned i = 0; i < ARRAY_SIZE(g_CpuPairs); i++)
{
const CUInt32PCharPair &pair = g_CpuPairs[i];
- if (pair.Value == cpu)
+ if (pair.Value == cpu || pair.Value == _cpuType)
{
+ if (pair.Value == _cpuType)
+ flag64 = 0;
n = pair.Name;
break;
}
@@ -276,10 +279,10 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
}
s = n;
- if (_cpuType & CPU_ARCH_ABI64)
+ if (flag64 != 0)
s += " 64-bit";
- else if (_cpuSubType & CPU_SUBTYPE_LIB64)
- s += " 64-bit lib";
+ else if ((_cpuSubType & CPU_SUBTYPE_LIB64) && _cpuType != CPU_TYPE_AMD64)
+ s += " 64-bit-lib";
}
UInt32 t = _cpuSubType & ~(UInt32)CPU_SUBTYPE_LIB64;
if (t != 0 && (t != CPU_SUBTYPE_I386_ALL || cpu != CPU_TYPE_386))
@@ -306,8 +309,8 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidCharacts:
{
// TYPE_TO_PROP(g_FileTypes, _type, prop); break;
- AString res = TypeToString(g_FileTypes, ARRAY_SIZE(g_FileTypes), _type);
- AString s = FlagsToString(g_ArcFlags, ARRAY_SIZE(g_ArcFlags), _flags);
+ AString res (TypeToString(g_FileTypes, ARRAY_SIZE(g_FileTypes), _type));
+ AString s (FlagsToString(g_ArcFlags, ARRAY_SIZE(g_ArcFlags), _flags));
if (!s.IsEmpty())
{
res.Add_Space();
@@ -345,20 +348,9 @@ static AString GetName(const char *name)
char res[kNameSize + 1];
memcpy(res, name, kNameSize);
res[kNameSize] = 0;
- return res;
+ return (AString)res;
}
-static AString SectFlagsToString(UInt32 flags)
-{
- AString res = TypeToString(g_SectTypes, ARRAY_SIZE(g_SectTypes), flags & SECT_TYPE_MASK);
- AString s = FlagsToString(g_Flags, ARRAY_SIZE(g_Flags), flags & SECT_ATTR_MASK);
- if (!s.IsEmpty())
- {
- res.Add_Space();
- res += s;
- }
- return res;
-}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
@@ -369,7 +361,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath:
{
- AString s = GetName(_segments[item.SegmentIndex].Name);
+ AString s (GetName(_segments[item.SegmentIndex].Name));
if (!item.IsDummy)
s += GetName(item.Name);
prop = MultiByteToUnicodeString(s);
@@ -377,7 +369,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
case kpidSize: /* prop = (UInt64)item.VSize; break; */
case kpidPackSize: prop = (UInt64)item.GetPackSize(); break;
- case kpidCharacts: if (!item.IsDummy) prop = SectFlagsToString(item.Flags); break;
+ case kpidCharacts:
+ if (!item.IsDummy)
+ {
+ AString res (TypeToString(g_SectTypes, ARRAY_SIZE(g_SectTypes), item.Flags & SECT_TYPE_MASK));
+ AString s (FlagsToString(g_Flags, ARRAY_SIZE(g_Flags), item.Flags & SECT_ATTR_MASK));
+ if (!s.IsEmpty())
+ {
+ res.Add_Space();
+ res += s;
+ }
+ prop = res;
+ }
+ break;
case kpidOffset: prop = item.Pa; break;
case kpidVa: prop = item.Va; break;
}
@@ -386,6 +390,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
COM_TRY_END
}
+
HRESULT CHandler::Open2(ISequentialInStream *stream)
{
const UInt32 kStartHeaderSize = 7 * 4;
@@ -402,6 +407,9 @@ HRESULT CHandler::Open2(ISequentialInStream *stream)
default: return S_FALSE;
}
+ _mode64 = mode64;
+ _be = be;
+
UInt32 numCommands = Get32(header + 0x10, be);
UInt32 commandsSize = Get32(header + 0x14, be);
diff --git a/CPP/7zip/Archive/MbrHandler.cpp b/CPP/7zip/Archive/MbrHandler.cpp
index b92755ae..14a1224c 100644
--- a/CPP/7zip/Archive/MbrHandler.cpp
+++ b/CPP/7zip/Archive/MbrHandler.cpp
@@ -63,21 +63,14 @@ static int CompareChs(const CChs &c1, const CChs &c2)
}
*/
-static void AddUIntToString(UInt32 val, AString &res)
-{
- char s[16];
- ConvertUInt32ToString(val, s);
- res += s;
-}
-
void CChs::ToString(NCOM::CPropVariant &prop) const
{
AString s;
- AddUIntToString(GetCyl(), s);
+ s.Add_UInt32(GetCyl());
s += '-';
- AddUIntToString(Head, s);
+ s.Add_UInt32(Head);
s += '-';
- AddUIntToString(GetSector(), s);
+ s.Add_UInt32(GetSector());
prop = s;
}
@@ -137,7 +130,7 @@ struct CPartType
const char *Name;
};
-static const char *kFat = "fat";
+#define kFat "fat"
static const CPartType kPartTypes[] =
{
@@ -156,6 +149,7 @@ static const CPartType kPartTypes[] =
{ 0x1B, kFat, "FAT32-Hidden" },
{ 0x1C, kFat, "FAT32-LBA-Hidden" },
{ 0x1E, kFat, "FAT16-LBA-WIN95-Hidden" },
+ { 0x27, "ntfs", "NTFS-WinRE" },
{ 0x82, 0, "Solaris x86 / Linux swap" },
{ 0x83, 0, "Linux" },
{ 0x8E, "lvm", "Linux LVM" },
@@ -399,14 +393,16 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPath:
{
AString s;
- AddUIntToString(index, s);
+ s.Add_UInt32(index);
if (item.IsReal)
{
- int typeIndex = FindPartType(part.Type);
s += '.';
- const char *ext = "img";
- if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Ext)
+ const char *ext = NULL;
+ int typeIndex = FindPartType(part.Type);
+ if (typeIndex >= 0)
ext = kPartTypes[(unsigned)typeIndex].Ext;
+ if (!ext)
+ ext = "img";
s += ext;
}
prop = s;
diff --git a/CPP/7zip/Archive/MslzHandler.cpp b/CPP/7zip/Archive/MslzHandler.cpp
index ec375733..6f9057a6 100644
--- a/CPP/7zip/Archive/MslzHandler.cpp
+++ b/CPP/7zip/Archive/MslzHandler.cpp
@@ -159,7 +159,7 @@ void CHandler::ParseName(Byte replaceByte, IArchiveOpenCallback *callback)
}
if (replaceByte >= 0x20 && replaceByte < 0x80)
- _name += (wchar_t)replaceByte;
+ _name += (char)replaceByte;
}
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */,
diff --git a/CPP/7zip/Archive/MubHandler.cpp b/CPP/7zip/Archive/MubHandler.cpp
index 56b8aa32..6d054356 100644
--- a/CPP/7zip/Archive/MubHandler.cpp
+++ b/CPP/7zip/Archive/MubHandler.cpp
@@ -31,6 +31,7 @@ namespace NMub {
#define MACH_CPU_TYPE_PPC64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_PPC)
#define MACH_CPU_TYPE_AMD64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_386)
+#define MACH_CPU_TYPE_ARM64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_ARM)
#define MACH_CPU_SUBTYPE_LIB64 (1 << 31)
@@ -105,17 +106,20 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
const char *ext = 0;
switch (item.Type)
{
- case MACH_CPU_TYPE_386: ext = "x86"; break;
+ case MACH_CPU_TYPE_386: ext = "x86"; break;
case MACH_CPU_TYPE_ARM: ext = "arm"; break;
case MACH_CPU_TYPE_SPARC: ext = "sparc"; break;
case MACH_CPU_TYPE_PPC: ext = "ppc"; break;
- case MACH_CPU_TYPE_PPC64: ext = "ppc64"; break;
case MACH_CPU_TYPE_AMD64: ext = "x64"; break;
+ case MACH_CPU_TYPE_ARM64: ext = "arm64"; break;
+ case MACH_CPU_TYPE_PPC64: ext = "ppc64"; break;
default:
temp[0] = 'c';
temp[1] = 'p';
temp[2] = 'u';
- ConvertUInt32ToString(item.Type, temp + 3);
+ ConvertUInt32ToString(item.Type & ~MACH_CPU_ARCH_ABI64, temp + 3);
+ if (item.Type & MACH_CPU_ARCH_ABI64)
+ MyStringCopy(temp + MyStringLen(temp), "_64");
break;
}
if (ext)
diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.cpp b/CPP/7zip/Archive/Nsis/NsisDecode.cpp
index daf3df6e..e2822184 100644
--- a/CPP/7zip/Archive/Nsis/NsisDecode.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisDecode.cpp
@@ -11,13 +11,24 @@
#include "../../Common/MethodId.h"
#include "../../Compress/BcjCoder.h"
-#include "../../Compress/BZip2Decoder.h"
#define Get32(p) GetUi32(p)
namespace NArchive {
namespace NNsis {
+UInt64 CDecoder::GetInputProcessedSize() const
+{
+ if (_lzmaDecoder)
+ return _lzmaDecoder->GetInputProcessedSize();
+ if (_deflateDecoder)
+ return _deflateDecoder->GetInputProcessedSize();
+ if (_bzDecoder)
+ return _bzDecoder->GetInputProcessedSize();
+ return 0;
+}
+
+
HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter)
{
useFilter = false;
@@ -36,7 +47,10 @@ HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter)
_deflateDecoder = new NCompress::NDeflate::NDecoder::CCOMCoder();
_codecInStream = _deflateDecoder;
break;
- case NMethodType::kBZip2: _codecInStream = new NCompress::NBZip2::CNsisDecoder(); break;
+ case NMethodType::kBZip2:
+ _bzDecoder = new NCompress::NBZip2::CNsisDecoder();
+ _codecInStream = _bzDecoder;
+ break;
case NMethodType::kLZMA:
_lzmaDecoder = new NCompress::NLzma::CDecoder();
_codecInStream = _lzmaDecoder;
@@ -103,15 +117,15 @@ HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter)
return S_OK;
}
+
static const UInt32 kMask_IsCompressed = (UInt32)1 << 31;
+
HRESULT CDecoder::SetToPos(UInt64 pos, ICompressProgressInfo *progress)
{
if (StreamPos > pos)
return E_FAIL;
- UInt64 inSizeStart = 0;
- if (_lzmaDecoder)
- inSizeStart = _lzmaDecoder->GetInputProcessedSize();
+ const UInt64 inSizeStart = GetInputProcessedSize();
UInt64 offset = 0;
while (StreamPos < pos)
{
@@ -122,14 +136,13 @@ HRESULT CDecoder::SetToPos(UInt64 pos, ICompressProgressInfo *progress)
StreamPos += size;
offset += size;
- UInt64 inSize = 0;
- if (_lzmaDecoder)
- inSize = _lzmaDecoder->GetInputProcessedSize() - inSizeStart;
+ const UInt64 inSize = GetInputProcessedSize() - inSizeStart;
RINOK(progress->SetRatioInfo(&inSize, &offset));
}
return S_OK;
}
+
HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unpackSize,
ISequentialOutStream *realOutStream, ICompressProgressInfo *progress,
UInt32 &packSizeRes, UInt32 &unpackSizeRes)
@@ -144,9 +157,9 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp
Byte temp[4];
size_t processedSize = 4;
RINOK(Read(temp, &processedSize));
+ StreamPos += processedSize;
if (processedSize != 4)
return S_FALSE;
- StreamPos += processedSize;
UInt32 size = Get32(temp);
if (unpackSizeDefined && size != unpackSize)
return S_FALSE;
@@ -156,8 +169,13 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp
else
{
Byte temp[4];
- RINOK(ReadStream_FALSE(InputStream, temp, 4));
- StreamPos += 4;
+ {
+ size_t processedSize = 4;
+ RINOK(ReadStream(InputStream, temp, &processedSize));
+ StreamPos += processedSize;
+ if (processedSize != 4)
+ return S_FALSE;
+ }
UInt32 size = Get32(temp);
if ((size & kMask_IsCompressed) == 0)
@@ -209,9 +227,7 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp
outBuf->Alloc(unpackSize);
}
- UInt64 inSizeStart = 0;
- if (_lzmaDecoder)
- inSizeStart = _lzmaDecoder->GetInputProcessedSize();
+ const UInt64 inSizeStart = GetInputProcessedSize();
// we don't allow files larger than 4 GB;
if (!unpackSizeDefined)
@@ -254,9 +270,8 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp
StreamPos += size;
offset += (UInt32)size;
- UInt64 inSize = 0; // it can be improved: we need inSize for Deflate and BZip2 too.
- if (_lzmaDecoder)
- inSize = _lzmaDecoder->GetInputProcessedSize() - inSizeStart;
+ const UInt64 inSize = GetInputProcessedSize() - inSizeStart;
+
if (Solid)
packSizeRes = (UInt32)inSize;
unpackSizeRes += (UInt32)size;
diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.h b/CPP/7zip/Archive/Nsis/NsisDecode.h
index ec713d05..2153d785 100644
--- a/CPP/7zip/Archive/Nsis/NsisDecode.h
+++ b/CPP/7zip/Archive/Nsis/NsisDecode.h
@@ -8,6 +8,7 @@
#include "../../Common/FilterCoder.h"
#include "../../Common/StreamUtils.h"
+#include "../../Compress/BZip2Decoder.h"
#include "../../Compress/DeflateDecoder.h"
#include "../../Compress/LzmaDecoder.h"
@@ -38,6 +39,7 @@ class CDecoder
CMyComPtr<ISequentialInStream> _codecInStream;
CMyComPtr<ISequentialInStream> _decoderInStream;
+ NCompress::NBZip2::CNsisDecoder *_bzDecoder;
NCompress::NDeflate::NDecoder::CCOMCoder *_deflateDecoder;
NCompress::NLzma::CDecoder *_lzmaDecoder;
@@ -50,13 +52,17 @@ public:
bool Solid;
bool IsNsisDeflate;
- CByteBuffer Buffer; // temp buf.
+ CByteBuffer Buffer; // temp buf
CDecoder():
FilterFlag(false),
Solid(true),
IsNsisDeflate(true)
- {}
+ {
+ _bzDecoder = NULL;
+ _deflateDecoder = NULL;
+ _lzmaDecoder = NULL;
+ }
void Release()
{
@@ -64,10 +70,16 @@ public:
_codecInStream.Release();
_decoderInStream.Release();
InputStream.Release();
+
+ _bzDecoder = NULL;
+ _deflateDecoder = NULL;
_lzmaDecoder = NULL;
}
+
+ UInt64 GetInputProcessedSize() const;
HRESULT Init(ISequentialInStream *inStream, bool &useFilter);
+
HRESULT Read(void *data, size_t *processedSize)
{
return ReadStream(_decoderInStream, data, processedSize);;
diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp
index 971c8464..095105fe 100644
--- a/CPP/7zip/Archive/Nsis/NsisHandler.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisHandler.cpp
@@ -23,8 +23,8 @@ using namespace NWindows;
namespace NArchive {
namespace NNsis {
-static const char *kBcjMethod = "BCJ";
-static const char *kUnknownMethod = "Unknown";
+#define kBcjMethod "BCJ"
+#define kUnknownMethod "Unknown"
static const char * const kMethods[] =
{
@@ -64,7 +64,7 @@ static AString UInt32ToString(UInt32 val)
{
char s[16];
ConvertUInt32ToString(val, s);
- return s;
+ return (AString)s;
}
static AString GetStringForSizeValue(UInt32 val)
@@ -123,7 +123,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
// case kpidCodePage: if (_archive.IsUnicode) prop = "UTF-16"; break;
case kpidSubType:
{
- AString s = _archive.GetFormatDescription();
+ AString s (_archive.GetFormatDescription());
if (!_archive.IsInstaller)
{
s.Add_Space_if_NotEmpty();
@@ -308,7 +308,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidOffset: prop = item.Pos; break;
case kpidPath:
{
- UString s = NItemName::WinNameToOSName(_archive.GetReducedName(index));
+ UString s = NItemName::WinPathToOsPath(_archive.GetReducedName(index));
if (!s.IsEmpty())
prop = (const wchar_t *)s;
break;
@@ -481,7 +481,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
- UInt32 index = allFilesMode ? i : indices[i];
+ const UInt32 index = allFilesMode ? i : indices[i];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
@@ -647,6 +647,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
UInt32 curPacked2 = 0;
UInt32 curUnpacked2 = 0;
+
+ if (!_archive.IsSolid)
+ {
+ RINOK(_archive.SeekTo(_archive.GetPosOfNonSolidItem(index) + 4 + curPacked ));
+ }
+
HRESULT res = _archive.Decoder.Decode(
writeToTemp ? &tempBuf2 : NULL,
false, 0,
diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp
index a3bfcaec..f739b0ff 100644
--- a/CPP/7zip/Archive/Nsis/NsisIn.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp
@@ -398,11 +398,9 @@ static const char * const kShellStrings[] =
};
-static void UIntToString(AString &s, UInt32 v)
+static inline void UIntToString(AString &s, UInt32 v)
{
- char sz[16];
- ConvertUInt32ToString(v, sz);
- s += sz;
+ s.Add_UInt32(v);
}
#ifdef NSIS_SCRIPT
@@ -461,7 +459,7 @@ void CInArchive::AddLicense(UInt32 param, Int32 langID)
}
}
}
- AString fileName = "[LICENSE]";
+ AString fileName ("[LICENSE]");
if (langID >= 0)
{
fileName += "\\license-";
@@ -940,7 +938,7 @@ void CInArchive::GetNsisString_Unicode_Raw(const Byte *p)
break;
if (c < 0x80)
{
- Raw_UString += (wchar_t)c;
+ Raw_UString += (char)c;
continue;
}
@@ -963,7 +961,7 @@ void CInArchive::GetNsisString_Unicode_Raw(const Byte *p)
else // if (c == PARK_CODE_LANG)
Add_LangStr(Raw_AString, n);
}
- Raw_UString.AddAscii(Raw_AString);
+ Raw_UString += Raw_AString.Ptr(); // check it !
continue;
}
c = n;
@@ -1009,7 +1007,7 @@ void CInArchive::GetNsisString_Unicode_Raw(const Byte *p)
else // if (c == NS_3_CODE_LANG)
Add_LangStr(Raw_AString, n);
}
- Raw_UString.AddAscii(Raw_AString);
+ Raw_UString += Raw_AString.Ptr();
}
}
@@ -1145,7 +1143,7 @@ void CInArchive::ReadString2_Raw(UInt32 pos)
GetNsisString_Raw(_data + _stringsPos + pos);
return;
}
- Raw_UString.SetFromAscii(Raw_AString);
+ Raw_UString = Raw_AString.Ptr();
}
bool CInArchive::IsGoodString(UInt32 param) const
@@ -2309,7 +2307,7 @@ static void AddString(AString &dest, const char *src)
AString CInArchive::GetFormatDescription() const
{
- AString s = "NSIS-";
+ AString s ("NSIS-");
char c;
if (IsPark())
{
@@ -3185,8 +3183,8 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
UString spec_outdir_U;
AString spec_outdir_A;
- UPrefixes.Add(L"$INSTDIR");
- APrefixes.Add("$INSTDIR");
+ UPrefixes.Add(UString("$INSTDIR"));
+ APrefixes.Add(AString("$INSTDIR"));
p = _data + bh.Offset;
@@ -4021,7 +4019,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
case EW_INTOP:
{
AddParam_Var(params[0]);
- const char *kOps = "+-*/|&^!|&%<>"; // NSIS 2.01+
+ const char * const kOps = "+-*/|&^!|&%<>"; // NSIS 2.01+
// "+-*/|&^!|&%"; // NSIS 2.0b4+
// "+-*/|&^~!|&%"; // NSIS old
UInt32 opIndex = params[3];
@@ -4857,11 +4855,11 @@ static int CompareItems(void *const *p1, void *const *p2, void *param)
{
if (i1.Prefix < 0) return -1;
if (i2.Prefix < 0) return 1;
- RINOZ(wcscmp(
- inArchive->UPrefixes[i1.Prefix],
+ RINOZ(
+ inArchive->UPrefixes[i1.Prefix].Compare(
inArchive->UPrefixes[i2.Prefix]));
}
- RINOZ(wcscmp(i1.NameU, i2.NameU));
+ RINOZ(i1.NameU.Compare(i2.NameU));
}
else
{
@@ -4934,7 +4932,7 @@ HRESULT CInArchive::SortItems()
for (i = 0; i < Items.Size(); i++)
{
CItem &item = Items[i];
- RINOK(_stream->Seek(GetPosOfNonSolidItem(i), STREAM_SEEK_SET, NULL));
+ RINOK(SeekToNonSolidItem(i));
const UInt32 kSigSize = 4 + 1 + 1 + 4; // size,[flag],prop,dict
BYTE sig[kSigSize];
size_t processedSize = kSigSize;
@@ -4997,6 +4995,9 @@ HRESULT CInArchive::Parse()
// ???? offset == FirstHeader.HeaderSize
const Byte *p = _data;
+ if (_size < 4 + 8 * 8)
+ return S_FALSE;
+
CBlockHeader bhEntries, bhStrings, bhLangTables;
bhEntries.Parse(p + 4 + 8 * 2);
bhStrings.Parse(p + 4 + 8 * 3);
@@ -5014,12 +5015,14 @@ HRESULT CInArchive::Parse()
#endif
_stringsPos = bhStrings.Offset;
- if (_stringsPos > _size)
+ if (_stringsPos > _size
+ || bhLangTables.Offset > _size
+ || bhEntries.Offset > _size)
return S_FALSE;
{
if (bhLangTables.Offset < bhStrings.Offset)
return S_FALSE;
- UInt32 stringTableSize = bhLangTables.Offset - bhStrings.Offset;
+ const UInt32 stringTableSize = bhLangTables.Offset - bhStrings.Offset;
if (stringTableSize < 2)
return S_FALSE;
const Byte *strData = _data + _stringsPos;
@@ -5035,13 +5038,10 @@ HRESULT CInArchive::Parse()
if (strData[stringTableSize - 2] != 0)
return S_FALSE;
}
-
}
if (bhEntries.Num > (1 << 25))
return S_FALSE;
- if (bhEntries.Offset > _size)
- return S_FALSE;
if (bhEntries.Num * kCmdSize > _size - bhEntries.Offset)
return S_FALSE;
@@ -5595,16 +5595,19 @@ HRESULT CInArchive::Open2(const Byte *sig, size_t size)
if (IsSolid)
{
- RINOK(_stream->Seek(DataStreamOffset, STREAM_SEEK_SET, NULL));
+ RINOK(SeekTo_DataStreamOffset());
}
else
{
_headerIsCompressed = ((compressedHeaderSize & kMask_IsCompressed) != 0);
compressedHeaderSize &= ~kMask_IsCompressed;
_nonSolidStartOffset = compressedHeaderSize;
- RINOK(_stream->Seek(DataStreamOffset + 4, STREAM_SEEK_SET, NULL));
+ RINOK(SeekTo(DataStreamOffset + 4));
}
+ if (FirstHeader.HeaderSize == 0)
+ return S_FALSE;
+
_data.Alloc(FirstHeader.HeaderSize);
_size = (size_t)FirstHeader.HeaderSize;
diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h
index d8e6808b..028e4a5d 100644
--- a/CPP/7zip/Archive/Nsis/NsisIn.h
+++ b/CPP/7zip/Archive/Nsis/NsisIn.h
@@ -350,14 +350,19 @@ public:
return Decoder.Init(_stream, useFilter);
}
+ HRESULT SeekTo(UInt64 pos)
+ {
+ return _stream->Seek(pos, STREAM_SEEK_SET, NULL);
+ }
+
HRESULT SeekTo_DataStreamOffset()
{
- return _stream->Seek(DataStreamOffset, STREAM_SEEK_SET, NULL);
+ return SeekTo(DataStreamOffset);
}
HRESULT SeekToNonSolidItem(unsigned index)
{
- return _stream->Seek(GetPosOfNonSolidItem(index), STREAM_SEEK_SET, NULL);
+ return SeekTo(GetPosOfNonSolidItem(index));
}
void Clear();
@@ -403,23 +408,23 @@ public:
s = MultiByteToUnicodeString(APrefixes[item.Prefix]);
if (s.Len() > 0)
if (s.Back() != L'\\')
- s += L'\\';
+ s += '\\';
}
if (IsUnicode)
{
s += item.NameU;
if (item.NameU.IsEmpty())
- s += L"file";
+ s += "file";
}
else
{
s += MultiByteToUnicodeString(item.NameA);
if (item.NameA.IsEmpty())
- s += L"file";
+ s += "file";
}
- const char *kRemoveStr = "$INSTDIR\\";
+ const char * const kRemoveStr = "$INSTDIR\\";
if (s.IsPrefixedBy_Ascii_NoCase(kRemoveStr))
{
s.Delete(0, MyStringLen(kRemoveStr));
@@ -427,7 +432,7 @@ public:
s.DeleteFrontal(1);
}
if (item.IsUninstaller && ExeStub.Size() == 0)
- s += L".nsis";
+ s += ".nsis";
return s;
}
diff --git a/CPP/7zip/Archive/NtfsHandler.cpp b/CPP/7zip/Archive/NtfsHandler.cpp
index a6350944..dff7701d 100644
--- a/CPP/7zip/Archive/NtfsHandler.cpp
+++ b/CPP/7zip/Archive/NtfsHandler.cpp
@@ -56,9 +56,9 @@ using namespace NWindows;
namespace NArchive {
namespace Ntfs {
-static const wchar_t *kVirtualFolder_System = L"[SYSTEM]";
-static const wchar_t *kVirtualFolder_Lost_Normal = L"[LOST]";
-static const wchar_t *kVirtualFolder_Lost_Deleted = L"[UNKNOWN]";
+static const wchar_t * const kVirtualFolder_System = L"[SYSTEM]";
+static const wchar_t * const kVirtualFolder_Lost_Normal = L"[LOST]";
+static const wchar_t * const kVirtualFolder_Lost_Deleted = L"[UNKNOWN]";
static const unsigned kNumSysRecs = 16;
@@ -394,7 +394,7 @@ static int CompareAttr(void *const *elem1, void *const *elem2, void *)
return 1;
else
{
- RINOZ(wcscmp(a1.Name.GetRawPtr(), a2.Name.GetRawPtr()));
+ RINOZ(a1.Name.Compare(a2.Name.GetRawPtr()));
}
return MyCompare(a1.LowVcn, a2.LowVcn);
}
@@ -2340,7 +2340,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
}
case kpidFileSystem:
{
- AString s = "NTFS";
+ AString s ("NTFS");
FOR_VECTOR (i, VolAttrs)
{
const CAttr &attr = VolAttrs[i];
@@ -2350,12 +2350,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (attr.ParseVolInfo(vi))
{
s.Add_Space();
- char temp[16];
- ConvertUInt32ToString(vi.MajorVer, temp);
- s += temp;
+ s.Add_UInt32(vi.MajorVer);
s += '.';
- ConvertUInt32ToString(vi.MinorVer, temp);
- s += temp;
+ s.Add_UInt32(vi.MinorVer);
}
break;
}
@@ -2722,18 +2719,14 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
for (UInt32 i = 0; i < numProps; i++)
{
- UString name = names[i];
- name.MakeLower_Ascii();
- if (name.IsEmpty())
- return E_INVALIDARG;
-
+ const wchar_t *name = names[i];
const PROPVARIANT &prop = values[i];
- if (name.IsEqualTo("ld"))
+ if (StringsAreEqualNoCase_Ascii(name, "ld"))
{
RINOK(PROPVARIANT_to_bool(prop, _showDeletedFiles));
}
- else if (name.IsEqualTo("ls"))
+ else if (StringsAreEqualNoCase_Ascii(name, "ls"))
{
RINOK(PROPVARIANT_to_bool(prop, _showSystemFiles));
}
diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp
index 7175cef3..30a60843 100644
--- a/CPP/7zip/Archive/PeHandler.cpp
+++ b/CPP/7zip/Archive/PeHandler.cpp
@@ -85,12 +85,6 @@ static HRESULT CalcCheckSum(ISequentialInStream *stream, UInt32 size, UInt32 exc
return S_OK;
}
-static AString GetDecString(UInt32 v)
-{
- char sz[16];
- ConvertUInt32ToString(v, sz);
- return sz;
-}
struct CVersion
{
@@ -407,13 +401,16 @@ static const CUInt32PCharPair g_HeaderCharacts[] =
static const CUInt32PCharPair g_DllCharacts[] =
{
+ { 5, "HighEntropyVA" },
{ 6, "Relocated" },
{ 7, "Integrity" },
{ 8, "NX-Compatible" },
{ 9, "NoIsolation" },
{ 10, "NoSEH" },
{ 11, "NoBind" },
+ { 12, "AppContainer" },
{ 13, "WDM" },
+ { 14, "GuardCF" },
{ 15, "TerminalServerAware" }
};
@@ -467,22 +464,30 @@ static const CUInt32PCharPair g_MachinePairs[] =
{ 0x0EBC, "EFI" },
{ 0x8664, "x64" },
{ 0x9041, "M32R" },
+ { 0xAA64, "ARM64" },
{ 0xC0EE, "CEE" }
};
-static const CUInt32PCharPair g_SubSystems[] =
-{
- { 0, "Unknown" },
- { 1, "Native" },
- { 2, "Windows GUI" },
- { 3, "Windows CUI" },
- { 7, "Posix" },
- { 9, "Windows CE" },
- { 10, "EFI" },
- { 11, "EFI Boot" },
- { 12, "EFI Runtime" },
- { 13, "EFI ROM" },
- { 14, "XBOX" }
+static const char * const g_SubSystems[] =
+{
+ "Unknown"
+ , "Native"
+ , "Windows GUI"
+ , "Windows CUI"
+ , NULL // "Old Windows CE"
+ , "OS2"
+ , NULL
+ , "Posix"
+ , "Win9x"
+ , "Windows CE"
+ , "EFI"
+ , "EFI Boot"
+ , "EFI Runtime"
+ , "EFI ROM"
+ , "XBOX"
+ , NULL
+ , "Windows Boot"
+ , "XBOX Catalog" // 17
};
static const char * const g_ResTypes[] =
@@ -878,7 +883,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidCpu: PAIR_TO_PROP(g_MachinePairs, _header.Machine, prop); break;
case kpidBit64: if (_optHeader.Is64Bit()) prop = true; break;
- case kpidSubSystem: PAIR_TO_PROP(g_SubSystems, _optHeader.SubSystem, prop); break;
+ case kpidSubSystem: TYPE_TO_PROP(g_SubSystems, _optHeader.SubSystem, prop); break;
case kpidMTime:
case kpidCTime: TimeToProp(_header.Time, prop); break;
@@ -950,9 +955,7 @@ void CHandler::AddResNameToString(UString &s, UInt32 id) const
return;
}
}
- wchar_t sz[16];
- ConvertUInt32ToString(id, sz);
- s += sz;
+ s.Add_UInt32(id);
}
void CHandler::AddLangPrefix(UString &s, UInt32 lang) const
@@ -978,7 +981,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
UString s = _resourcesPrefix;
AddLangPrefix(s, item.Lang);
- s.AddAscii("string.txt");
+ s += "string.txt";
prop = s;
break;
}
@@ -996,7 +999,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
UString s = _resourcesPrefix;
AddLangPrefix(s, item.Lang);
- s.AddAscii("version.txt");
+ s += "version.txt";
prop = s;
break;
}
@@ -1019,7 +1022,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (item.Type < ARRAY_SIZE(g_ResTypes))
p = g_ResTypes[item.Type];
if (p)
- s.AddAscii(p);
+ s += p;
else
AddResNameToString(s, item.Type);
}
@@ -1028,9 +1031,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (item.HeaderSize != 0)
{
if (item.IsBmp())
- s.AddAscii(".bmp");
+ s += ".bmp";
else if (item.IsIcon())
- s.AddAscii(".ico");
+ s += ".ico";
}
prop = s;
break;
@@ -1112,7 +1115,8 @@ HRESULT CHandler::LoadDebugSections(IInStream *stream, bool &thereIsSection)
thereIsSection = true;
CSection &sect = _sections.AddNew();
- sect.Name = ".debug" + GetDecString(i);
+ sect.Name = ".debug";
+ sect.Name.Add_UInt32(i);
sect.IsDebug = true;
sect.Time = de.Time;
sect.Va = de.Va;
@@ -1384,11 +1388,9 @@ static void PrintUInt32(CTextFile &f, UInt32 v)
f.AddString(s);
}
-static void PrintUInt32(UString &dest, UInt32 v)
+static inline void PrintUInt32(UString &dest, UInt32 v)
{
- wchar_t s[16];
- ConvertUInt32ToString(v, s);
- dest += s;
+ dest.Add_UInt32(v);
}
static void PrintHex(CTextFile &f, UInt32 val)
@@ -1410,9 +1412,9 @@ static void PrintVersion(CTextFile &f, UInt32 ms, UInt32 ls)
static void PrintVersion(UString &s, UInt32 ms, UInt32 ls)
{
- PrintUInt32(s, HIWORD(ms)); s += L'.';
- PrintUInt32(s, LOWORD(ms)); s += L'.';
- PrintUInt32(s, HIWORD(ls)); s += L'.';
+ PrintUInt32(s, HIWORD(ms)); s += '.';
+ PrintUInt32(s, LOWORD(ms)); s += '.';
+ PrintUInt32(s, HIWORD(ls)); s += '.';
PrintUInt32(s, LOWORD(ls));
}
@@ -1694,7 +1696,7 @@ bool CVersionBlock::Parse(const Byte *p, UInt32 size)
return false;
TotalLen = Get16(p);
ValueLen = Get16(p + 2);
- if (TotalLen == 0 || TotalLen > size)
+ if (TotalLen < k_ResoureBlockHeader_Size || TotalLen > size)
return false;
switch (Get16(p + 4))
{
@@ -2114,7 +2116,8 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
static inline bool CheckPeOffset(UInt32 pe)
{
- return (pe >= 0x40 && pe <= 0x1000 && (pe & 7) == 0);
+ // ((pe & 7) == 0) is for most PE files. But there is unusual EFI-PE file that uses unaligned pe value.
+ return pe >= 0x40 && pe <= 0x1000 /* && (pe & 7) == 0 */ ;
}
static const unsigned kStartSize = 0x40;
@@ -2290,7 +2293,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
s2.PSize = s2.VSize = s.Pa - limit;
s2.IsAdditionalSection = true;
s2.Name = '[';
- s2.Name += GetDecString(num++);
+ s2.Name.Add_UInt32(num++);
s2.Name += ']';
limit = s.Pa;
}
@@ -2332,10 +2335,11 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
mixItem.SectionIndex = i;
if (_parseResources && sect.Name == ".rsrc" && _items.IsEmpty())
{
+ const unsigned numMixItems = _mixItems.Size();
HRESULT res = OpenResources(i, stream, callback);
if (res == S_OK)
{
- _resourcesPrefix.SetFromAscii(sect.Name);
+ _resourcesPrefix = sect.Name.Ptr();
_resourcesPrefix.Add_PathSepar();
FOR_VECTOR (j, _items)
{
@@ -2387,6 +2391,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
}
if (res != S_FALSE)
return res;
+ _mixItems.DeleteFrom(numMixItems);
CloseResources();
}
if (sect.IsAdditionalSection)
@@ -2422,7 +2427,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
_versionFullString.Add_LF();
const CStringKeyValue &k = _versionKeys[i];
_versionFullString += k.Key;
- _versionFullString += L": ";
+ _versionFullString += ": ";
_versionFullString += k.Value;
}
@@ -2702,7 +2707,8 @@ static bool FindValue(const CUInt32PCharPair *pairs, unsigned num, UInt32 value)
return false;
}
-#define MY_FIND_VALUE(pairs, value) FindValue(pairs, ARRAY_SIZE(pairs), value)
+#define MY_FIND_VALUE(pairs, val) FindValue(pairs, ARRAY_SIZE(pairs), val)
+#define MY_FIND_VALUE_2(strings, val) (val < ARRAY_SIZE(strings) && strings[val])
static const UInt32 kNumSection_MAX = 32;
@@ -2751,7 +2757,7 @@ bool CHeader::Parse(const Byte *p)
}
return
MY_FIND_VALUE(NPe::g_MachinePairs, Machine) &&
- MY_FIND_VALUE(NPe::g_SubSystems, SubSystem);
+ MY_FIND_VALUE_2(NPe::g_SubSystems, SubSystem);
}
API_FUNC_static_IsArc IsArc_Te(const Byte *p, size_t size)
@@ -2864,7 +2870,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
case kpidPhySize: prop = _totalSize; break;
case kpidCpu: PAIR_TO_PROP(NPe::g_MachinePairs, _h.Machine, prop); break;
- case kpidSubSystem: PAIR_TO_PROP(NPe::g_SubSystems, _h.SubSystem, prop); break;
+ case kpidSubSystem: TYPE_TO_PROP(NPe::g_SubSystems, _h.SubSystem, prop); break;
/*
case kpidImageBase: prop = _h.ImageBase; break;
case kpidAddressOfEntryPoint: prop = _h.AddressOfEntryPoint; break;
diff --git a/CPP/7zip/Archive/PpmdHandler.cpp b/CPP/7zip/Archive/PpmdHandler.cpp
index 528c5ceb..c80400bc 100644
--- a/CPP/7zip/Archive/PpmdHandler.cpp
+++ b/CPP/7zip/Archive/PpmdHandler.cpp
@@ -12,7 +12,6 @@ This code is based on:
#include "../../../C/Ppmd8.h"
#include "../../Common/ComTry.h"
-#include "../../Common/IntToString.h"
#include "../../Common/StringConvert.h"
#include "../../Windows/PropVariant.h"
@@ -104,6 +103,8 @@ class CHandler:
UInt64 _packSize;
CMyComPtr<ISequentialInStream> _stream;
+ void GetVersion(NCOM::CPropVariant &prop);
+
public:
MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq)
INTERFACE_IInArchive(;)
@@ -118,8 +119,30 @@ static const Byte kProps[] =
kpidMethod
};
+static const Byte kArcProps[] =
+{
+ kpidMethod
+};
+
IMP_IInArchive_Props
-IMP_IInArchive_ArcProps_NO_Table
+IMP_IInArchive_ArcProps
+
+void CHandler::GetVersion(NCOM::CPropVariant &prop)
+{
+ AString s ("PPMd");
+ s += (char)('A' + _item.Ver);
+ s += ":o";
+ s.Add_UInt32(_item.Order);
+ s += ":mem";
+ s.Add_UInt32(_item.MemInMB);
+ s += 'm';
+ if (_item.Ver >= kNewHeaderVer && _item.Restor != 0)
+ {
+ s += ":r";
+ s.Add_UInt32(_item.Restor);
+ }
+ prop = s;
+}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
@@ -127,6 +150,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
switch (propID)
{
case kpidPhySize: if (_packSize_Defined) prop = _packSize; break;
+ case kpidMethod: GetVersion(prop); break;
}
prop.Detach(value);
return S_OK;
@@ -139,14 +163,6 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
-static void UIntToString(AString &s, const char *prefix, unsigned value)
-{
- s += prefix;
- char temp[16];
- ::ConvertUInt32ToString((UInt32)value, temp);
- s += temp;
-}
-
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -164,17 +180,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
}
case kpidAttrib: prop = _item.Attrib; break;
case kpidPackSize: if (_packSize_Defined) prop = _packSize; break;
- case kpidMethod:
- {
- AString s = "PPMd";
- s += (char)('A' + _item.Ver);
- UIntToString(s, ":o", _item.Order);
- UIntToString(s, ":mem", _item.MemInMB);
- s += 'm';
- if (_item.Ver >= kNewHeaderVer && _item.Restor != 0)
- UIntToString(s, ":r", _item.Restor);
- prop = s;
- }
+ case kpidMethod: GetVersion(prop); break;
}
prop.Detach(value);
return S_OK;
@@ -217,7 +223,7 @@ static const UInt32 kBot = (1 << 15);
struct CRangeDecoder
{
- IPpmd7_RangeDec s;
+ IPpmd7_RangeDec vt;
UInt32 Range;
UInt32 Code;
UInt32 Low;
@@ -251,15 +257,17 @@ public:
extern "C" {
-static UInt32 Range_GetThreshold(void *pp, UInt32 total)
+#define GET_RangeDecoder CRangeDecoder *p = CONTAINER_FROM_VTBL(pp, CRangeDecoder, vt);
+
+static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total)
{
- CRangeDecoder *p = (CRangeDecoder *)pp;
+ GET_RangeDecoder
return p->Code / (p->Range /= total);
}
-static void Range_Decode(void *pp, UInt32 start, UInt32 size)
+static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size)
{
- CRangeDecoder *p = (CRangeDecoder *)pp;
+ GET_RangeDecoder
start *= p->Range;
p->Low += start;
p->Code -= start;
@@ -267,17 +275,17 @@ static void Range_Decode(void *pp, UInt32 start, UInt32 size)
p->Normalize();
}
-static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
+static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0)
{
- CRangeDecoder *p = (CRangeDecoder *)pp;
+ GET_RangeDecoder
if (p->Code / (p->Range >>= 14) < size0)
{
- Range_Decode(p, 0, size0);
+ Range_Decode(&p->vt, 0, size0);
return 0;
}
else
{
- Range_Decode(p, size0, (1 << 14) - size0);
+ Range_Decode(&p->vt, size0, (1 << 14) - size0);
return 1;
}
}
@@ -286,9 +294,9 @@ static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
CRangeDecoder::CRangeDecoder()
{
- s.GetThreshold = Range_GetThreshold;
- s.Decode = Range_Decode;
- s.DecodeBit = Range_DecodeBit;
+ vt.GetThreshold = Range_GetThreshold;
+ vt.Decode = Range_Decode;
+ vt.DecodeBit = Range_DecodeBit;
}
struct CPpmdCpp
@@ -336,7 +344,7 @@ struct CPpmdCpp
}
else
{
- _ppmd8.Stream.In = &inStream->p;
+ _ppmd8.Stream.In = &inStream->vt;
return Ppmd8_RangeDec_Init(&_ppmd8) != 0;
}
}
@@ -412,7 +420,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
for (i = 0; i < kBufSize; i++)
{
- sym = Ppmd7_DecodeSymbol(&ppmd._ppmd7, &ppmd._rc.s);
+ sym = Ppmd7_DecodeSymbol(&ppmd._ppmd7, &ppmd._rc.vt);
if (inBuf.Extra || sym < 0)
break;
outBuf.Buf[i] = (Byte)sym;
diff --git a/CPP/7zip/Archive/QcowHandler.cpp b/CPP/7zip/Archive/QcowHandler.cpp
index a84fdc9b..065f59b3 100644
--- a/CPP/7zip/Archive/QcowHandler.cpp
+++ b/CPP/7zip/Archive/QcowHandler.cpp
@@ -284,11 +284,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (_cryptMethod == 1)
s += "AES";
else
- {
- char temp[16];
- ConvertUInt32ToString(_cryptMethod, temp);
- s += temp;
- }
+ s.Add_UInt32(_cryptMethod);
}
if (!s.IsEmpty())
diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.cpp b/CPP/7zip/Archive/Rar/Rar5Handler.cpp
index d70a5686..f166730e 100644
--- a/CPP/7zip/Archive/Rar/Rar5Handler.cpp
+++ b/CPP/7zip/Archive/Rar/Rar5Handler.cpp
@@ -50,22 +50,59 @@ static const Byte kMarker[kMarkerSize] = SIGNATURE;
static const size_t kCommentSize_Max = (size_t)1 << 16;
+
static const char * const kHostOS[] =
{
"Windows"
, "Unix"
};
-static const CUInt32PCharPair k_ArcFlags[] =
+
+static const char * const k_ArcFlags[] =
+{
+ "Volume"
+ , "VolumeField"
+ , "Solid"
+ , "Recovery"
+ , "Lock" // 4
+};
+
+
+static const char * const k_FileFlags[] =
+{
+ "Dir"
+ , "UnixTime"
+ , "CRC"
+ , "UnknownSize"
+};
+
+
+static const char * const g_ExtraTypes[] =
+{
+ "0"
+ , "Crypto"
+ , "Hash"
+ , "Time"
+ , "Version"
+ , "Link"
+ , "UnixOwner"
+ , "Subdata"
+};
+
+
+static const char * const g_LinkTypes[] =
{
- { 0, "Volume" },
- { 1, "VolumeField" },
- { 2, "Solid" },
- { 3, "Recovery" },
- { 4, "Lock" }
+ "0"
+ , "UnixSymLink"
+ , "WinSymLink"
+ , "WinJunction"
+ , "HardLink"
+ , "FileCopy"
};
+static const char g_ExtraTimeFlags[] = { 'u', 'M', 'C', 'A', 'n' };
+
template <unsigned alignMask>
struct CAlignedBuffer
@@ -106,7 +143,8 @@ static unsigned ReadVarInt(const Byte *p, size_t maxSize, UInt64 *val)
{
Byte b = p[i];
if (i < 10)
- *val |= (UInt64)(b & 0x7F) << (7 * i++);
+ *val |= (UInt64)(b & 0x7F) << (7 * i);
+ i++;
if ((b & 0x80) == 0)
return i;
}
@@ -114,7 +152,54 @@ static unsigned ReadVarInt(const Byte *p, size_t maxSize, UInt64 *val)
}
-int CItem::FindExtra(unsigned type, unsigned &recordDataSize) const
+bool CLinkInfo::Parse(const Byte *p, unsigned size)
+{
+ const Byte *pStart = p;
+ unsigned num = ReadVarInt(p, size, &Type);
+ if (num == 0) return false; p += num; size -= num;
+
+ num = ReadVarInt(p, size, &Flags);
+ if (num == 0) return false; p += num; size -= num;
+
+ UInt64 len;
+ num = ReadVarInt(p, size, &len);
+ if (num == 0) return false; p += num; size -= num;
+
+ if (size != len)
+ return false;
+
+ NameLen = (unsigned)len;
+ NameOffset = (unsigned)(p - pStart);
+ return true;
+}
+
+
+static void AddHex64(AString &s, UInt64 v)
+{
+ char sz[32];
+ sz[0] = '0';
+ sz[1] = 'x';
+ ConvertUInt64ToHex(v, sz + 2);
+ s += sz;
+}
+
+
+static void PrintType(AString &s, const char * const table[], unsigned num, UInt64 val)
+{
+ char sz[32];
+ const char *p = NULL;
+ if (val < num)
+ p = table[(unsigned)val];
+ if (!p)
+ {
+ ConvertUInt64ToString(val, sz);
+ p = sz;
+ }
+ s += p;
+}
+
+
+int CItem::FindExtra(unsigned extraID, unsigned &recordDataSize) const
{
recordDataSize = 0;
size_t offset = 0;
@@ -137,8 +222,8 @@ int CItem::FindExtra(unsigned type, unsigned &recordDataSize) const
rem = (size_t)size;
}
{
- UInt64 type2;
- unsigned num = ReadVarInt(Extra + offset, rem, &type2);
+ UInt64 id;
+ unsigned num = ReadVarInt(Extra + offset, rem, &id);
if (num == 0)
return -1;
offset += num;
@@ -147,12 +232,12 @@ int CItem::FindExtra(unsigned type, unsigned &recordDataSize) const
// There was BUG in RAR 5.21- : it stored (size-1) instead of (size)
// for Subdata record in Service header.
// That record always was last in bad archives, so we can fix that case.
- if (type2 == NExtraRecordType::kSubdata
+ if (id == NExtraID::kSubdata
&& RecordType == NHeaderType::kService
&& rem + 1 == Extra.Size() - offset)
rem++;
- if (type2 == type)
+ if (id == extraID)
{
recordDataSize = (unsigned)rem;
return (int)offset;
@@ -164,19 +249,118 @@ int CItem::FindExtra(unsigned type, unsigned &recordDataSize) const
}
+void CItem::PrintInfo(AString &s) const
+{
+ size_t offset = 0;
+
+ for (;;)
+ {
+ size_t rem = Extra.Size() - offset;
+ if (rem == 0)
+ return;
+
+ {
+ UInt64 size;
+ unsigned num = ReadVarInt(Extra + offset, rem, &size);
+ if (num == 0)
+ return;
+ offset += num;
+ rem -= num;
+ if (size > rem)
+ break;
+ rem = (size_t)size;
+ }
+ {
+ UInt64 id;
+ {
+ unsigned num = ReadVarInt(Extra + offset, rem, &id);
+ if (num == 0)
+ break;
+ offset += num;
+ rem -= num;
+ }
+
+ // There was BUG in RAR 5.21- : it stored (size-1) instead of (size)
+ // for Subdata record in Service header.
+ // That record always was last in bad archives, so we can fix that case.
+ if (id == NExtraID::kSubdata
+ && RecordType == NHeaderType::kService
+ && rem + 1 == Extra.Size() - offset)
+ rem++;
+
+ s.Add_Space_if_NotEmpty();
+ PrintType(s, g_ExtraTypes, ARRAY_SIZE(g_ExtraTypes), id);
+
+ if (id == NExtraID::kTime)
+ {
+ const Byte *p = Extra + offset;
+ UInt64 flags;
+ unsigned num = ReadVarInt(p, rem, &flags);
+ if (num != 0)
+ {
+ s += ':';
+ for (unsigned i = 0; i < ARRAY_SIZE(g_ExtraTimeFlags); i++)
+ if ((flags & ((UInt64)1 << i)) != 0)
+ s += g_ExtraTimeFlags[i];
+ flags &= ~(((UInt64)1 << ARRAY_SIZE(g_ExtraTimeFlags)) - 1);
+ if (flags != 0)
+ {
+ s += '_';
+ AddHex64(s, flags);
+ }
+ }
+ }
+ else if (id == NExtraID::kLink)
+ {
+ CLinkInfo linkInfo;
+ if (linkInfo.Parse(Extra + offset, (unsigned)rem))
+ {
+ s += ':';
+ PrintType(s, g_LinkTypes, ARRAY_SIZE(g_LinkTypes), linkInfo.Type);
+ UInt64 flags = linkInfo.Flags;
+ if (flags != 0)
+ {
+ s += ':';
+ if (flags & NLinkFlags::kTargetIsDir)
+ {
+ s += 'D';
+ flags &= ~((UInt64)NLinkFlags::kTargetIsDir);
+ }
+ if (flags != 0)
+ {
+ s += '_';
+ AddHex64(s, flags);
+ }
+ }
+ }
+ }
+
+ offset += rem;
+ }
+ }
+
+ s.Add_OptSpaced("ERROR");
+}
+
+
bool CCryptoInfo::Parse(const Byte *p, size_t size)
{
+ Algo = 0;
+ Flags = 0;
+ Cnt = 0;
+
unsigned num = ReadVarInt(p, size, &Algo);
if (num == 0) return false; p += num; size -= num;
num = ReadVarInt(p, size, &Flags);
if (num == 0) return false; p += num; size -= num;
+ if (size > 0)
+ Cnt = p[0];
+
if (size != 1 + 16 + 16 + (unsigned)(IsThereCheck() ? 12 : 0))
return false;
- Cnt = p[0];
-
return true;
}
@@ -184,7 +368,7 @@ bool CCryptoInfo::Parse(const Byte *p, size_t size)
bool CItem::FindExtra_Version(UInt64 &version) const
{
unsigned size;
- int offset = FindExtra(NExtraRecordType::kVersion, size);
+ int offset = FindExtra(NExtraID::kVersion, size);
if (offset < 0)
return false;
const Byte *p = Extra + (unsigned)offset;
@@ -202,26 +386,12 @@ bool CItem::FindExtra_Version(UInt64 &version) const
bool CItem::FindExtra_Link(CLinkInfo &link) const
{
unsigned size;
- int offset = FindExtra(NExtraRecordType::kLink, size);
+ int offset = FindExtra(NExtraID::kLink, size);
if (offset < 0)
return false;
- const Byte *p = Extra + (unsigned)offset;
-
- unsigned num = ReadVarInt(p, size, &link.Type);
- if (num == 0) return false; p += num; size -= num;
-
- num = ReadVarInt(p, size, &link.Flags);
- if (num == 0) return false; p += num; size -= num;
-
- UInt64 len;
- num = ReadVarInt(p, size, &len);
- if (num == 0) return false; p += num; size -= num;
-
- if (size != len)
+ if (!link.Parse(Extra + (unsigned)offset, size))
return false;
-
- link.NameLen = (unsigned)len;
- link.NameOffset = (unsigned)(p - Extra);
+ link.NameOffset += offset;
return true;
}
@@ -268,14 +438,14 @@ void CItem::Link_to_Prop(unsigned linkType, NWindows::NCOM::CPropVariant &prop)
UString unicode;
if (ConvertUTF8ToUnicode(s, unicode))
- prop = NItemName::GetOSName(unicode);
+ prop = NItemName::GetOsPath(unicode);
}
bool CItem::GetAltStreamName(AString &name) const
{
name.Empty();
unsigned size;
- int offset = FindExtra(NExtraRecordType::kSubdata, size);
+ int offset = FindExtra(NExtraID::kSubdata, size);
if (offset < 0)
return false;
name.SetFrom_CalcLen((const char *)(Extra + (unsigned)offset), size);
@@ -578,7 +748,7 @@ HRESULT CInArchive::ReadBlockHeader(CHeader &h)
/*
-int CInArcInfo::FindExtra(unsigned type, unsigned &recordDataSize) const
+int CInArcInfo::FindExtra(unsigned extraID, unsigned &recordDataSize) const
{
recordDataSize = 0;
size_t offset = 0;
@@ -601,14 +771,14 @@ int CInArcInfo::FindExtra(unsigned type, unsigned &recordDataSize) const
rem = (size_t)size;
}
{
- UInt64 type2;
- unsigned num = ReadVarInt(Extra + offset, rem, &type2);
+ UInt64 id;
+ unsigned num = ReadVarInt(Extra + offset, rem, &id);
if (num == 0)
return -1;
offset += num;
rem -= num;
- if (type2 == type)
+ if (id == extraID)
{
recordDataSize = (unsigned)rem;
return (int)offset;
@@ -929,7 +1099,7 @@ HRESULT CUnpacker::Create(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, bool
}
unsigned cryptoSize = 0;
- int cryptoOffset = item.FindExtra(NExtraRecordType::kCrypto, cryptoSize);
+ int cryptoOffset = item.FindExtra(NExtraID::kCrypto, cryptoSize);
if (cryptoOffset >= 0)
{
@@ -1023,7 +1193,7 @@ HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSiz
// if (res == S_OK)
{
unsigned cryptoSize = 0;
- int cryptoOffset = lastItem.FindExtra(NExtraRecordType::kCrypto, cryptoSize);
+ int cryptoOffset = lastItem.FindExtra(NExtraID::kCrypto, cryptoSize);
NCrypto::NRar5::CDecoder *crypto = NULL;
if (cryptoOffset >= 0)
@@ -1190,7 +1360,7 @@ static const Byte kProps[] =
kpidCRC,
kpidHostOS,
kpidMethod,
-
+ kpidCharacts,
kpidSymLink,
kpidHardLink,
kpidCopyLink,
@@ -1308,8 +1478,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
if (/* &_missingVol || */ !_missingVolName.IsEmpty())
{
- UString s;
- s.SetFromAscii("Missing volume : ");
+ UString s ("Missing volume : ");
s += _missingVolName;
prop = s;
}
@@ -1339,13 +1508,11 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
if (arcInfo->IsVolume())
{
- char sz[32];
- ConvertUInt64ToString(arcInfo->GetVolIndex() + 1, sz);
- unsigned len = MyStringLen(sz);
- AString s = "part";
- for (; len < 2; len++)
+ AString s ("part");
+ UInt32 v = (UInt32)arcInfo->GetVolIndex() + 1;
+ if (v < 10)
s += '0';
- s += sz;
+ s.Add_UInt32(v);
s += ".rar";
prop = s;
}
@@ -1452,7 +1619,7 @@ STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data
static void TimeRecordToProp(const CItem &item, unsigned stampIndex, NCOM::CPropVariant &prop)
{
unsigned size;
- int offset = item.FindExtra(NExtraRecordType::kTime, size);
+ int offset = item.FindExtra(NExtraID::kTime, size);
if (offset < 0)
return;
@@ -1470,29 +1637,43 @@ static void TimeRecordToProp(const CItem &item, unsigned stampIndex, NCOM::CProp
return;
unsigned numStamps = 0;
+ unsigned curStamp = 0;
unsigned i;
for (i = 0; i < 3; i++)
if ((flags & (NTimeRecord::NFlags::kMTime << i)) != 0)
+ {
+ if (i == stampIndex)
+ curStamp = numStamps;
numStamps++;
- unsigned stampSizeLog = ((flags & NTimeRecord::NFlags::kUnixTime) != 0) ? 2 : 3;
-
- if ((numStamps << stampSizeLog) != size)
- return;
-
- numStamps = 0;
- for (i = 0; i < stampIndex; i++)
- if ((flags & (NTimeRecord::NFlags::kMTime << i)) != 0)
- numStamps++;
-
- p += (numStamps << stampSizeLog);
+ }
FILETIME ft;
+
if ((flags & NTimeRecord::NFlags::kUnixTime) != 0)
- NWindows::NTime::UnixTimeToFileTime(Get32(p), ft);
+ {
+ curStamp *= 4;
+ if (curStamp + 4 > size)
+ return;
+ const Byte *p2 = p + curStamp;
+ UInt64 val = NTime::UnixTimeToFileTime64(Get32(p2));
+ numStamps *= 4;
+ if ((flags & NTimeRecord::NFlags::kUnixNs) != 0 && numStamps * 2 <= size)
+ {
+ const UInt32 ns = Get32(p2 + numStamps) & 0x3FFFFFFF;
+ if (ns < 1000000000)
+ val += ns / 100;
+ }
+ ft.dwLowDateTime = (DWORD)val;
+ ft.dwHighDateTime = (DWORD)(val >> 32);
+ }
else
{
- ft.dwLowDateTime = Get32(p);
- ft.dwHighDateTime = Get32(p + 4);
+ curStamp *= 8;
+ if (curStamp + 8 > size)
+ return;
+ const Byte *p2 = p + curStamp;
+ ft.dwLowDateTime = Get32(p2);
+ ft.dwHighDateTime = Get32(p2 + 4);
}
prop = ft;
@@ -1537,19 +1718,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break;
if (item.Version_Defined)
{
- wchar_t temp[32];
+ char temp[32];
// temp[0] = ';';
// ConvertUInt64ToString(item.Version, temp + 1);
// unicodeName += temp;
ConvertUInt64ToString(item.Version, temp);
- UString s2 = L"[VER]" WSTRING_PATH_SEPARATOR;
+ UString s2 ("[VER]" STRING_PATH_SEPARATOR);
s2 += temp;
s2.Add_PathSepar();
unicodeName.Insert(0, s2);
}
}
- NItemName::ConvertToOSName2(unicodeName);
+ NItemName::ReplaceToOsSlashes_Remove_TailSlash(unicodeName);
prop = unicodeName;
break;
@@ -1623,7 +1804,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidMethod:
{
- char temp[64];
+ char temp[128];
unsigned algo = item.GetAlgoVersion();
char *s = temp;
if (algo != 0)
@@ -1645,16 +1826,28 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
unsigned cryptoSize = 0;
- int cryptoOffset = item.FindExtra(NExtraRecordType::kCrypto, cryptoSize);
+ int cryptoOffset = item.FindExtra(NExtraID::kCrypto, cryptoSize);
if (cryptoOffset >= 0)
{
s = temp + strlen(temp);
*s++ = ' ';
- strcpy(s, "AES:");
+
CCryptoInfo cryptoInfo;
- if (cryptoInfo.Parse(item.Extra + (unsigned)cryptoOffset, cryptoSize))
+
+ bool isOK = cryptoInfo.Parse(item.Extra + (unsigned)cryptoOffset, cryptoSize);
+
+ if (cryptoInfo.Algo == 0)
+ s = MyStpCpy(s, "AES");
+ else
{
+ s = MyStpCpy(s, "Crypto_");
+ ConvertUInt64ToString(cryptoInfo.Algo, s);
s += strlen(s);
+ }
+
+ if (isOK)
+ {
+ *s++ = ':';
ConvertUInt32ToString(cryptoInfo.Cnt, s);
s += strlen(s);
*s++ = ':';
@@ -1666,6 +1859,35 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break;
}
+ case kpidCharacts:
+ {
+ AString s;
+
+ if (item.ACL >= 0)
+ {
+ s.Add_OptSpaced("ACL");
+ }
+
+ UInt32 flags = item.Flags;
+ // flags &= ~(6); // we don't need compression related bits here.
+
+ if (flags != 0)
+ {
+ AString s2 = FlagsToString(k_FileFlags, ARRAY_SIZE(k_FileFlags), flags);
+ if (!s2.IsEmpty())
+ {
+ s.Add_OptSpaced(s2);
+ }
+ }
+
+ item.PrintInfo(s);
+
+ if (!s.IsEmpty())
+ prop = s;
+ break;
+ }
+
+
case kpidHostOS:
if (item.HostOS < ARRAY_SIZE(kHostOS))
prop = kHostOS[(size_t)item.HostOS];
@@ -1788,7 +2010,7 @@ void CHandler::FillLinks()
const CItem &item = _items[ref.Item];
if (item.IsDir() || item.IsService() || item.PackSize != 0)
continue;
- CItem::CLinkInfo linkInfo;
+ CLinkInfo linkInfo;
if (!item.FindExtra_Link(linkInfo) || linkInfo.Type != NLinkType::kFileCopy)
continue;
link.SetFrom_CalcLen((const char *)(item.Extra + linkInfo.NameOffset), linkInfo.NameLen);
diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.h b/CPP/7zip/Archive/Rar/Rar5Handler.h
index 27e937de..d3e33d7c 100644
--- a/CPP/7zip/Archive/Rar/Rar5Handler.h
+++ b/CPP/7zip/Archive/Rar/Rar5Handler.h
@@ -85,7 +85,7 @@ enum EHostOS
// ---------- Extra ----------
-namespace NExtraRecordType
+namespace NExtraID
{
enum
{
@@ -99,7 +99,7 @@ namespace NExtraRecordType
};
}
-// const unsigned kCryptoAlgo_AES = 0;
+const unsigned kCryptoAlgo_AES = 0;
namespace NCryptoFlags
{
@@ -133,8 +133,9 @@ namespace NTimeRecord
{
const unsigned kUnixTime = 1 << 0;
const unsigned kMTime = 1 << 1;
- // const unsigned kCTime = 1 << 2;
- // const unsigned kATime = 1 << 3;
+ const unsigned kCTime = 1 << 2;
+ const unsigned kATime = 1 << 3;
+ const unsigned kUnixNs = 1 << 4;
}
}
@@ -156,6 +157,17 @@ namespace NLinkFlags
}
+struct CLinkInfo
+{
+ UInt64 Type;
+ UInt64 Flags;
+ unsigned NameOffset;
+ unsigned NameLen;
+
+ bool Parse(const Byte *p, unsigned size);
+};
+
+
struct CItem
{
UInt32 CommonFlags;
@@ -230,18 +242,20 @@ struct CItem
bool Is_ACL() const { return IsService() && Name == "ACL"; }
// bool Is_QO() const { return IsService() && Name == "QO"; }
- int FindExtra(unsigned type, unsigned &recordDataSize) const;
+ int FindExtra(unsigned extraID, unsigned &recordDataSize) const;
+ void PrintInfo(AString &s) const;
+
bool IsEncrypted() const
{
unsigned size;
- return FindExtra(NExtraRecordType::kCrypto, size) >= 0;
+ return FindExtra(NExtraID::kCrypto, size) >= 0;
}
int FindExtra_Blake() const
{
unsigned size = 0;
- int offset = FindExtra(NExtraRecordType::kHash, size);
+ int offset = FindExtra(NExtraID::kHash, size);
if (offset >= 0
&& size == BLAKE2S_DIGEST_SIZE + 1
&& Extra[(unsigned)offset] == kHashID_Blake2sp)
@@ -251,14 +265,6 @@ struct CItem
bool FindExtra_Version(UInt64 &version) const;
- struct CLinkInfo
- {
- UInt64 Type;
- UInt64 Flags;
- unsigned NameOffset;
- unsigned NameLen;
- };
-
bool FindExtra_Link(CLinkInfo &link) const;
void Link_to_Prop(unsigned linkType, NWindows::NCOM::CPropVariant &prop) const;
bool Is_CopyLink() const;
@@ -313,7 +319,7 @@ struct CInArcInfo
bool Is_Recovery() const { return (Flags & NLocatorFlags::kRecovery) != 0; }
};
- int FindExtra(unsigned type, unsigned &recordDataSize) const;
+ int FindExtra(unsigned extraID, unsigned &recordDataSize) const;
bool FindExtra_Locator(CLocator &locator) const;
*/
diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp
index e858c1ea..c097b15c 100644
--- a/CPP/7zip/Archive/Rar/RarHandler.cpp
+++ b/CPP/7zip/Archive/Rar/RarHandler.cpp
@@ -104,20 +104,18 @@ static const char * const kHostOS[] =
, "BeOS"
};
-static const char *kUnknownOS = "Unknown";
-
-static const CUInt32PCharPair k_Flags[] =
+static const char * const k_Flags[] =
{
- { 0, "Volume" },
- { 1, "Comment" },
- { 2, "Lock" },
- { 3, "Solid" },
- { 4, "NewVolName" }, // pack_comment in old versuons
- { 5, "Authenticity" },
- { 6, "Recovery" },
- { 7, "BlockEncryption" },
- { 8, "FirstVolume" },
- { 9, "EncryptVer" }
+ "Volume"
+ , "Comment"
+ , "Lock"
+ , "Solid"
+ , "NewVolName" // pack_comment in old versuons
+ , "Authenticity"
+ , "Recovery"
+ , "BlockEncryption"
+ , "FirstVolume"
+ , "EncryptVer" // 9
};
enum EErrorType
@@ -132,13 +130,13 @@ class CInArchive
{
IInStream *m_Stream;
UInt64 m_StreamStartPosition;
- CBuffer<wchar_t> _unicodeNameBuffer;
+ UString _unicodeNameBuffer;
CByteBuffer _comment;
CByteBuffer m_FileHeaderData;
NHeader::NBlock::CBlock m_BlockHeader;
NCrypto::NRar3::CDecoder *m_RarAESSpec;
CMyComPtr<ICompressFilter> m_RarAES;
- CBuffer<Byte> m_DecryptedData;
+ CByteBuffer m_DecryptedData;
Byte *m_DecryptedDataAligned;
UInt32 m_DecryptedDataSize;
bool m_CryptoMode;
@@ -272,14 +270,19 @@ bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size)
return processed == size;
}
-static void DecodeUnicodeFileName(const Byte *name, const Byte *encName,
+
+static unsigned DecodeUnicodeFileName(const Byte *name, const Byte *encName,
unsigned encSize, wchar_t *unicodeName, unsigned maxDecSize)
{
unsigned encPos = 0;
unsigned decPos = 0;
unsigned flagBits = 0;
Byte flags = 0;
- Byte highByte = encName[encPos++];
+
+ if (encPos >= encSize)
+ return 0; // error
+ const unsigned highBits = ((unsigned)encName[encPos++]) << 8;
+
while (encPos < encSize && decPos < maxDecSize)
{
if (flagBits == 0)
@@ -287,40 +290,46 @@ static void DecodeUnicodeFileName(const Byte *name, const Byte *encName,
flags = encName[encPos++];
flagBits = 8;
}
- switch (flags >> 6)
+
+ if (encPos >= encSize)
+ break; // error
+ unsigned len = encName[encPos++];
+
+ flagBits -= 2;
+ const unsigned mode = (flags >> flagBits) & 3;
+
+ if (mode != 3)
{
- case 0:
- unicodeName[decPos++] = encName[encPos++];
- break;
- case 1:
- unicodeName[decPos++] = (wchar_t)(encName[encPos++] + (highByte << 8));
- break;
- case 2:
- unicodeName[decPos++] = (wchar_t)(encName[encPos] + (encName[encPos + 1] << 8));
- encPos += 2;
- break;
- case 3:
- {
- unsigned len = encName[encPos++];
- if (len & 0x80)
- {
- Byte correction = encName[encPos++];
- for (len = (len & 0x7f) + 2;
- len > 0 && decPos < maxDecSize; len--, decPos++)
- unicodeName[decPos] = (wchar_t)(((name[decPos] + correction) & 0xff) + (highByte << 8));
- }
- else
- for (len += 2; len > 0 && decPos < maxDecSize; len--, decPos++)
- unicodeName[decPos] = name[decPos];
- }
- break;
+ if (mode == 1)
+ len += highBits;
+ else if (mode == 2)
+ {
+ if (encPos >= encSize)
+ break; // error
+ len += ((unsigned)encName[encPos++] << 8);
+ }
+ unicodeName[decPos++] = (wchar_t)len;
+ }
+ else
+ {
+ if (len & 0x80)
+ {
+ if (encPos >= encSize)
+ break; // error
+ Byte correction = encName[encPos++];
+ for (len = (len & 0x7f) + 2; len > 0 && decPos < maxDecSize; len--, decPos++)
+ unicodeName[decPos] = (wchar_t)(((name[decPos] + correction) & 0xff) + highBits);
+ }
+ else
+ for (len += 2; len > 0 && decPos < maxDecSize; len--, decPos++)
+ unicodeName[decPos] = name[decPos];
}
- flags <<= 2;
- flagBits -= 2;
}
- unicodeName[decPos < maxDecSize ? decPos : maxDecSize - 1] = 0;
+
+ return decPos < maxDecSize ? decPos : maxDecSize - 1;
}
+
void CInArchive::ReadName(const Byte *p, unsigned nameSize, CItem &item)
{
item.UnicodeName.Empty();
@@ -336,8 +345,8 @@ void CInArchive::ReadName(const Byte *p, unsigned nameSize, CItem &item)
{
i++;
unsigned uNameSizeMax = MyMin(nameSize, (unsigned)0x400);
- _unicodeNameBuffer.AllocAtLeast(uNameSizeMax + 1);
- DecodeUnicodeFileName(p, p + i, nameSize - i, _unicodeNameBuffer, uNameSizeMax);
+ unsigned len = DecodeUnicodeFileName(p, p + i, nameSize - i, _unicodeNameBuffer.GetBuf(uNameSizeMax), uNameSizeMax);
+ _unicodeNameBuffer.ReleaseBuf_SetEnd(len);
item.UnicodeName = _unicodeNameBuffer;
}
else if (!ConvertUTF8ToUnicode(item.Name, item.UnicodeName))
@@ -818,7 +827,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidSolid: prop = _arcInfo.IsSolid(); break;
case kpidCharacts:
{
- AString s = FlagsToString(k_Flags, ARRAY_SIZE(k_Flags), _arcInfo.Flags);
+ AString s (FlagsToString(k_Flags, ARRAY_SIZE(k_Flags), _arcInfo.Flags));
// FLAGS_TO_PROP(k_Flags, _arcInfo.Flags, prop);
if (_arcInfo.Is_DataCRC_Defined())
{
@@ -871,8 +880,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (/* &_missingVol || */ !_missingVolName.IsEmpty())
{
- UString s;
- s.SetFromAscii("Missing volume : ");
+ UString s ("Missing volume : ");
s += _missingVolName;
prop = s;
}
@@ -900,13 +908,11 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
if (_arcInfo.Is_VolNumber_Defined())
{
- char sz[16];
- ConvertUInt32ToString((UInt32)_arcInfo.VolNumber + 1, sz);
- unsigned len = MyStringLen(sz);
- AString s = "part";
- for (; len < 2; len++)
+ AString s ("part");
+ UInt32 v = (UInt32)_arcInfo.VolNumber + 1;
+ if (v < 10)
s += '0';
- s += sz;
+ s.Add_UInt32(v);
s += ".rar";
prop = s;
}
@@ -974,7 +980,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
u = mainItem->GetName();
u += item.GetName();
*/
- prop = (const wchar_t *)NItemName::WinNameToOSName(item.GetName());
+ prop = (const wchar_t *)NItemName::WinPathToOsPath(item.GetName());
break;
}
case kpidIsDir: prop = item.IsDir(); break;
@@ -1015,7 +1021,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = s;
break;
}
- case kpidHostOS: prop = (item.HostOS < ARRAY_SIZE(kHostOS)) ? kHostOS[item.HostOS] : kUnknownOS; break;
+ case kpidHostOS:
+ TYPE_TO_PROP(kHostOS, item.HostOS, prop);
+ break;
}
prop.Detach(value);
return S_OK;
@@ -1324,7 +1332,13 @@ STDMETHODIMP CVolsInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
if (_curIndex >= _refItem.NumItems)
break;
const CItem &item = (*_items)[_refItem.ItemIndex + _curIndex];
- IInStream *s = (*_arcs)[_refItem.VolumeIndex + _curIndex].Stream;
+ unsigned volIndex = _refItem.VolumeIndex + _curIndex;
+ if (volIndex >= _arcs->Size())
+ {
+ return S_OK;
+ // return S_FALSE;
+ }
+ IInStream *s = (*_arcs)[volIndex].Stream;
RINOK(s->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
_stream = s;
_calcCrc = (CrcIsOK && item.IsSplitAfter());
diff --git a/CPP/7zip/Archive/Rar/RarVol.h b/CPP/7zip/Archive/Rar/RarVol.h
index 2d2ce473..310369d4 100644
--- a/CPP/7zip/Archive/Rar/RarVol.h
+++ b/CPP/7zip/Archive/Rar/RarVol.h
@@ -41,7 +41,7 @@ public:
}
else if (ext.IsEqualTo_Ascii_NoCase("exe"))
{
- _after.SetFromAscii(".rar");
+ _after = ".rar";
base.DeleteFrom(dotPos);
}
else if (!newStyle)
@@ -76,8 +76,8 @@ public:
_after.Empty();
_before = base;
- _before += L'.';
- _changed.SetFromAscii("r00");
+ _before += '.';
+ _changed = "r00";
_needChangeForNext = false;
return true;
}
diff --git a/CPP/7zip/Archive/RpmHandler.cpp b/CPP/7zip/Archive/RpmHandler.cpp
index 08df1ae7..e0ec28ce 100644
--- a/CPP/7zip/Archive/RpmHandler.cpp
+++ b/CPP/7zip/Archive/RpmHandler.cpp
@@ -11,6 +11,7 @@
#include "../../Common/UTFConvert.h"
#include "../../Windows/PropVariant.h"
+#include "../../Windows/PropVariantUtils.h"
#include "../../Windows/TimeUtils.h"
#include "../Common/RegisterArc.h"
@@ -167,6 +168,16 @@ struct CEntry
}
};
+
+#ifdef _SHOW_RPM_METADATA
+struct CMetaFile
+{
+ UInt32 Tag;
+ UInt32 Offset;
+ UInt32 Size;
+};
+#endif
+
class CHandler: public CHandlerCont
{
UInt64 _headersSize; // is equal to start offset of payload data
@@ -198,6 +209,7 @@ class CHandler: public CHandlerCont
#ifdef _SHOW_RPM_METADATA
AString _metadata;
+ CRecordVector<CMetaFile> _metaFiles;
#endif
void SetTime(NCOM::CPropVariant &prop) const
@@ -205,8 +217,8 @@ class CHandler: public CHandlerCont
if (_time_Defined && _buildTime != 0)
{
FILETIME ft;
- if (NTime::UnixTime64ToFileTime(_buildTime, ft))
- prop = ft;
+ NTime::UnixTimeToFileTime(_buildTime, ft);
+ prop = ft;
}
}
@@ -266,16 +278,10 @@ void CHandler::AddCPU(AString &s) const
{
if (_lead.Type == kRpmType_Bin)
{
- char temp[16];
- const char *p;
if (_lead.Cpu < ARRAY_SIZE(k_CPUs))
- p = k_CPUs[_lead.Cpu];
+ s += k_CPUs[_lead.Cpu];
else
- {
- ConvertUInt32ToString(_lead.Cpu, temp);
- p = temp;
- }
- s += p;
+ s.Add_UInt32(_lead.Cpu);
}
}
}
@@ -376,29 +382,18 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
SetStringProp(_os, prop);
else
{
- char temp[16];
- const char *p;
- if (_lead.Os < ARRAY_SIZE(k_OS))
- p = k_OS[_lead.Os];
- else
- {
- ConvertUInt32ToString(_lead.Os, temp);
- p = temp;
- }
- prop = p;
+ TYPE_TO_PROP(k_OS, _lead.Os, prop);
}
break;
}
#ifdef _SHOW_RPM_METADATA
- case kpidComment: SetStringProp(_metadata, prop); break;
+ // case kpidComment: SetStringProp(_metadata, prop); break;
#endif
case kpidName:
{
- AString s = GetBaseName();
- s += ".rpm";
- SetStringProp(s, prop);
+ SetStringProp(GetBaseName() + ".rpm", prop);
break;
}
}
@@ -408,9 +403,10 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
}
-STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
NWindows::NCOM::CPropVariant prop;
+ if (index == 0)
switch (propID)
{
case kpidSize:
@@ -425,7 +421,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
case kpidPath:
{
- AString s = GetBaseName();
+ AString s (GetBaseName());
s += '.';
AddSubFileExtension(s);
SetStringProp(s, prop);
@@ -440,6 +436,37 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
}
*/
}
+ #ifdef _SHOW_RPM_METADATA
+ else
+ {
+ index--;
+ if (index > _metaFiles.Size())
+ return E_INVALIDARG;
+ const CMetaFile &meta = _metaFiles[index];
+ switch (propID)
+ {
+ case kpidSize:
+ case kpidPackSize:
+ prop = meta.Size;
+ break;
+
+ case kpidMTime:
+ case kpidCTime:
+ SetTime(prop);
+ break;
+
+ case kpidPath:
+ {
+ AString s ("[META]");
+ s.Add_PathSepar();
+ s.Add_UInt32(meta.Tag);
+ prop = s;
+ break;
+ }
+ }
+ }
+ #endif
+
prop.Detach(value);
return S_OK;
}
@@ -499,10 +526,7 @@ HRESULT CHandler::ReadHeader(ISequentialInStream *stream, bool isMainHeader)
{
#ifdef _SHOW_RPM_METADATA
{
- char temp[16];
- ConvertUInt32ToString(entry.Tag, temp);
-
- _metadata += temp;
+ _metadata.Add_UInt32(entry.Tag);
_metadata += ": ";
}
#endif
@@ -515,7 +539,7 @@ HRESULT CHandler::ReadHeader(ISequentialInStream *stream, bool isMainHeader)
for (j = 0; j < rem && p[j] != 0; j++);
if (j == rem)
return S_FALSE;
- AString s = (const char *)p;
+ AString s((const char *)p);
switch (entry.Tag)
{
case RPMTAG_NAME: _name = s; break;
@@ -548,9 +572,7 @@ HRESULT CHandler::ReadHeader(ISequentialInStream *stream, bool isMainHeader)
{
if (t != 0)
_metadata.Add_Space();
- char temp[16];
- ConvertUInt32ToString(Get32(p + t * 4), temp);
- _metadata += temp;
+ _metadata.Add_UInt32(Get32(p + t * 4));
}
#endif
}
@@ -587,9 +609,7 @@ HRESULT CHandler::ReadHeader(ISequentialInStream *stream, bool isMainHeader)
{
if (t != 0)
_metadata.Add_Space();
- char temp[16];
- ConvertUInt32ToString(Get16(p + t * 2), temp);
- _metadata += temp;
+ _metadata.Add_UInt32(Get16(p + t * 2));
}
}
else if (entry.Type == k_EntryType_BIN)
@@ -607,9 +627,18 @@ HRESULT CHandler::ReadHeader(ISequentialInStream *stream, bool isMainHeader)
{
// p = p;
}
+
_metadata += '\n';
#endif
}
+
+ #ifdef _SHOW_RPM_METADATA
+ CMetaFile meta;
+ meta.Offset = entry.Offset;
+ meta.Tag = entry.Tag;
+ meta.Size = entry.Count;
+ _metaFiles.Add(meta);
+ #endif
}
headerSize += k_HeaderSig_Size;
@@ -715,6 +744,7 @@ STDMETHODIMP CHandler::Close()
#ifdef _SHOW_RPM_METADATA
_metadata.Empty();
+ _metaFiles.Size();
#endif
_stream.Release();
@@ -723,7 +753,12 @@ STDMETHODIMP CHandler::Close()
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
- *numItems = 1;
+ *numItems = 1
+ #ifdef _SHOW_RPM_METADATA
+ + _metaFiles.Size()
+ #endif
+ ;
+
return S_OK;
}
diff --git a/CPP/7zip/Archive/SplitHandler.cpp b/CPP/7zip/Archive/SplitHandler.cpp
index 72b52fe7..f4a10b1d 100644
--- a/CPP/7zip/Archive/SplitHandler.cpp
+++ b/CPP/7zip/Archive/SplitHandler.cpp
@@ -181,7 +181,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
seqName._splitStyle = splitStyle;
if (prefix.Len() < 1)
- _subName.SetFromAscii("file");
+ _subName = "file";
else
_subName.SetFrom(prefix, prefix.Len() - 1);
diff --git a/CPP/7zip/Archive/SquashfsHandler.cpp b/CPP/7zip/Archive/SquashfsHandler.cpp
index 3bcb2862..29e3bb6c 100644
--- a/CPP/7zip/Archive/SquashfsHandler.cpp
+++ b/CPP/7zip/Archive/SquashfsHandler.cpp
@@ -11,6 +11,7 @@
#include "../../Common/MyLinux.h"
#include "../../Common/IntToString.h"
#include "../../Common/StringConvert.h"
+#include "../../Common/UTFConvert.h"
#include "../../Windows/PropVariantUtils.h"
#include "../../Windows/TimeUtils.h"
@@ -67,7 +68,7 @@ static const UInt32 kSignature32_LZ = 0x71736873;
static const char * const k_Methods[] =
{
- "Unknown"
+ "0"
, "ZLIB"
, "LZMA"
, "LZO"
@@ -109,16 +110,16 @@ enum
kFlag_EXPORT
};
-static const CUInt32PCharPair k_Flags[] =
+static const char * const k_Flags[] =
{
- { kFlag_UNC_INODES, "UNCOMPRESSED_INODES" },
- { kFlag_UNC_DATA, "UNCOMPRESSED_DATA" },
- { kFlag_CHECK, "CHECK" },
- { kFlag_UNC_FRAGS, "UNCOMPRESSED_FRAGMENTS" },
- { kFlag_NO_FRAGS, "NO_FRAGMENTS" },
- { kFlag_ALWAYS_FRAG, "ALWAYS_FRAGMENTS" },
- { kFlag_DUPLICATE, "DUPLICATES_REMOVED" },
- { kFlag_EXPORT, "EXPORTABLE" }
+ "UNCOMPRESSED_INODES"
+ , "UNCOMPRESSED_DATA"
+ , "CHECK"
+ , "UNCOMPRESSED_FRAGMENTS"
+ , "NO_FRAGMENTS"
+ , "ALWAYS_FRAGMENTS"
+ , "DUPLICATES_REMOVED"
+ , "EXPORTABLE"
};
static const UInt32 kNotCompressedBit16 = (1 << 15);
@@ -841,6 +842,8 @@ class CHandler:
CHeader _h;
bool _noPropsLZMA;
bool _needCheckLzma;
+
+ UInt32 _openCodePage;
CMyComPtr<IInStream> _stream;
UInt64 _sizeCalculated;
@@ -944,7 +947,8 @@ static const Byte kArcProps[] =
kpidClusterSize,
kpidBigEndian,
kpidCTime,
- kpidCharacts
+ kpidCharacts,
+ kpidCodePage
// kpidNumBlocks
};
@@ -1333,6 +1337,8 @@ HRESULT CHandler::OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned
return S_FALSE;
rem = fileSize;
+ AString tempString;
+
CRecordVector<CTempItem> tempItems;
while (rem != 0)
{
@@ -1398,7 +1404,7 @@ HRESULT CHandler::OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned
}
CItem item;
- item.Ptr = (UInt32)(p - _dirs.Data);
+ item.Ptr = (UInt32)(p - (const Byte *)_dirs.Data);
UInt32 size;
if (_h.IsOldVersion())
@@ -1432,6 +1438,14 @@ HRESULT CHandler::OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned
size++;
if (rem < size)
return S_FALSE;
+
+ if (_openCodePage == CP_UTF8)
+ {
+ tempString.SetFrom_CalcLen((const char *)p, size);
+ if (!CheckUTF8(tempString))
+ _openCodePage = CP_OEMCP;
+ }
+
p += size;
rem -= size;
item.Parent = parent;
@@ -1706,6 +1720,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallb
STDMETHODIMP CHandler::Close()
{
+ _openCodePage = CP_UTF8;
_sizeCalculated = 0;
_limitedInStreamSpec->ReleaseStream();
@@ -1829,6 +1844,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
case kpidMethod:
{
+ char sz[16];
const char *s;
if (_noPropsLZMA)
s = "LZMA Spec";
@@ -1836,25 +1852,27 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
s = "LZMA ZLIB";
else
{
- s = k_Methods[0];
+ s = NULL;
if (_h.Method < ARRAY_SIZE(k_Methods))
s = k_Methods[_h.Method];
+ if (!s)
+ {
+ ConvertUInt32ToString(_h.Method, sz);
+ s = sz;
+ }
}
prop = s;
break;
}
case kpidFileSystem:
{
- AString res = "SquashFS";
+ AString res ("SquashFS");
if (_h.SeveralMethods)
res += "-LZMA";
res.Add_Space();
- char s[16];
- ConvertUInt32ToString(_h.Major, s);
- res += s;
+ res.Add_UInt32(_h.Major);
res += '.';
- ConvertUInt32ToString(_h.Minor, s);
- res += s;
+ res.Add_UInt32(_h.Minor);
prop = res;
break;
}
@@ -1875,6 +1893,24 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (_sizeCalculated >= _h.InodeTable)
prop = _sizeCalculated - _h.InodeTable;
break;
+
+ case kpidCodePage:
+ {
+ char sz[16];
+ const char *name = NULL;
+ switch (_openCodePage)
+ {
+ case CP_OEMCP: name = "OEM"; break;
+ case CP_UTF8: name = "UTF-8"; break;
+ }
+ if (!name)
+ {
+ ConvertUInt32ToString(_openCodePage, sz);
+ name = sz;
+ }
+ prop = name;
+ break;
+ }
}
prop.Detach(value);
return S_OK;
@@ -1892,7 +1928,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
switch (propID)
{
- case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break;
+ case kpidPath:
+ {
+ AString path (GetPath(index));
+ UString s;
+ if (_openCodePage == CP_UTF8)
+ ConvertUTF8ToUnicode(path, s);
+ else
+ MultiByteToUnicodeString2(s, path, _openCodePage);
+ prop = s;
+ break;
+ }
case kpidIsDir: prop = isDir; break;
// case kpidOffset: if (!node.IsLink()) prop = (UInt64)node.StartBlock; break;
case kpidSize: if (!isDir) prop = node.GetSize(); break;
diff --git a/CPP/7zip/Archive/SwfHandler.cpp b/CPP/7zip/Archive/SwfHandler.cpp
index 06ed2106..16a6e6f9 100644
--- a/CPP/7zip/Archive/SwfHandler.cpp
+++ b/CPP/7zip/Archive/SwfHandler.cpp
@@ -10,6 +10,7 @@
#include "../../Common/MyString.h"
#include "../../Windows/PropVariant.h"
+#include "../../Windows/PropVariantUtils.h"
#include "../Common/InBuffer.h"
#include "../Common/LimitedStreams.h"
@@ -562,14 +563,13 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
{
_lzmaMode = false;
RINOK(_props.SetProperties(names, values, numProps));
- AString m = _props.MethodName;
- m.MakeLower_Ascii();
- if (m.IsEqualTo("lzma"))
+ const AString &m = _props.MethodName;
+ if (m.IsEqualTo_Ascii_NoCase("lzma"))
{
return E_NOTIMPL;
// _lzmaMode = true;
}
- else if (m.IsEqualTo("deflate") || m.IsEmpty())
+ else if (m.IsEqualTo_Ascii_NoCase("Deflate") || m.IsEmpty())
_lzmaMode = false;
else
return E_INVALIDARG;
@@ -762,12 +762,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPackSize:
prop = (UInt64)tag.Buf.Size(); break;
case kpidComment:
- if (tag.Type < ARRAY_SIZE(g_TagDesc))
- {
- const char *s = g_TagDesc[tag.Type];
- if (s != NULL)
- prop = s;
- }
+ TYPE_TO_PROP(g_TagDesc, tag.Type, prop);
break;
}
prop.Detach(value);
diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp
index baa43c79..72fbf74e 100644
--- a/CPP/7zip/Archive/Tar/TarHandler.cpp
+++ b/CPP/7zip/Archive/Tar/TarHandler.cpp
@@ -81,20 +81,19 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidCodePage:
{
+ char sz[16];
const char *name = NULL;
switch (_openCodePage)
{
case CP_OEMCP: name = "OEM"; break;
- case CP_UTF8: name = "UTF-8"; break;
+ case CP_UTF8: name = "UTF-8"; break;
}
- if (name != NULL)
- prop = name;
- else
+ if (!name)
{
- char sz[16];
ConvertUInt32ToString(_openCodePage, sz);
- prop = sz;
- };
+ name = sz;
+ }
+ prop = name;
break;
}
}
@@ -316,7 +315,7 @@ void CHandler::TarStringToUnicode(const AString &s, NWindows::NCOM::CPropVariant
else
MultiByteToUnicodeString2(dest, s, _curCodePage);
if (toOs)
- NItemName::ConvertToOSName2(dest);
+ NItemName::ReplaceToOsSlashes_Remove_TailSlash(dest);
prop = dest;
}
@@ -353,7 +352,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = ft;
}
break;
- case kpidPosixAttrib: prop = item->Mode; break;
+ case kpidPosixAttrib: prop = item->Get_Combined_Mode(); break;
case kpidUser: TarStringToUnicode(item->User, prop); break;
case kpidGroup: TarStringToUnicode(item->Group, prop); break;
case kpidSymLink: if (item->LinkFlag == NFileHeader::NLinkFlag::kSymLink && !item->LinkName.IsEmpty()) TarStringToUnicode(item->LinkName, prop); break;
diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
index 0b67a285..41934339 100644
--- a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
+++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
@@ -35,7 +35,7 @@ HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID pro
{
UString s = prop.bstrVal;
if (convertSlash)
- s = NItemName::MakeLegalName(s);
+ NItemName::ReplaceSlashes_OsToUnix(s);
if (codePage == CP_UTF8)
{
@@ -123,6 +123,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
else
ui.Mode = prop.ulVal;
+ // FIXME : we can clear high file type bits to be more compatible with tars created by GNU TAR.
+ // ui.Mode &= ~(UInt32)MY_LIN_S_IFMT;
}
{
diff --git a/CPP/7zip/Archive/Tar/TarHeader.cpp b/CPP/7zip/Archive/Tar/TarHeader.cpp
index 70be09f3..a22f36bd 100644
--- a/CPP/7zip/Archive/Tar/TarHeader.cpp
+++ b/CPP/7zip/Archive/Tar/TarHeader.cpp
@@ -8,15 +8,15 @@ namespace NArchive {
namespace NTar {
namespace NFileHeader {
- const char *kLongLink = "././@LongLink";
- const char *kLongLink2 = "@LongLink";
+ const char * const kLongLink = "././@LongLink";
+ const char * const kLongLink2 = "@LongLink";
// The magic field is filled with this if uname and gname are valid.
namespace NMagic
{
- // const char *kUsTar = "ustar"; // 5 chars
- // const char *kGNUTar = "GNUtar "; // 7 chars and a null
- // const char *kEmpty = "\0\0\0\0\0\0\0\0";
+ // const char * const kUsTar = "ustar"; // 5 chars
+ // const char * const kGNUTar = "GNUtar "; // 7 chars and a null
+ // const char * const kEmpty = "\0\0\0\0\0\0\0\0";
const char kUsTar_00[8] = { 'u', 's', 't', 'a', 'r', 0, '0', '0' } ;
}
diff --git a/CPP/7zip/Archive/Tar/TarHeader.h b/CPP/7zip/Archive/Tar/TarHeader.h
index df594d81..47971b58 100644
--- a/CPP/7zip/Archive/Tar/TarHeader.h
+++ b/CPP/7zip/Archive/Tar/TarHeader.h
@@ -67,15 +67,15 @@ namespace NFileHeader
the last file name. */
}
- extern const char *kLongLink; // = "././@LongLink";
- extern const char *kLongLink2; // = "@LongLink";
+ extern const char * const kLongLink; // = "././@LongLink";
+ extern const char * const kLongLink2; // = "@LongLink";
namespace NMagic
{
- // extern const char *kUsTar; // = "ustar"; // 5 chars
- // extern const char *kGNUTar; // = "GNUtar "; // 7 chars and a null
- // extern const char *kEmpty; // = "\0\0\0\0\0\0\0\0"
- extern const char kUsTar_00[];
+ // extern const char * const kUsTar; // = "ustar"; // 5 chars
+ // extern const char * const kGNUTar; // = "GNUtar "; // 7 chars and a null
+ // extern const char * const kEmpty; // = "\0\0\0\0\0\0\0\0"
+ extern const char kUsTar_00[8];
}
}
diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp
index 57e18ac0..64807bfc 100644
--- a/CPP/7zip/Archive/Tar/TarIn.cpp
+++ b/CPP/7zip/Archive/Tar/TarIn.cpp
@@ -91,6 +91,16 @@ static bool ParseInt64(const char *p, Int64 &val)
return res;
}
+static bool ParseInt64_MTime(const char *p, Int64 &val)
+{
+ // rare case tar contains spaces instead of MTime
+ for (unsigned i = 0; i < 12; i++)
+ if (p[i] != ' ')
+ return ParseInt64(p, val);
+ val = 0;
+ return true;
+}
+
static bool ParseSize(const char *p, UInt64 &val)
{
if (GetBe32(p) == (UInt32)1 << 31)
@@ -124,7 +134,7 @@ API_FUNC_IsArc IsArc_Tar(const Byte *p2, size_t size)
Int64 time;
UInt32 checkSum;
CHECK(ParseSize(p, packSize)); p += 12;
- CHECK(ParseInt64(p, time)); p += 12;
+ CHECK(ParseInt64_MTime(p, time)); p += 12;
CHECK(OctalToNumber32(p, 8, checkSum));
return k_IsArc_Res_YES;
}
@@ -192,7 +202,7 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
RIF(ParseSize(p, item.PackSize));
item.Size = item.PackSize;
p += 12;
- RIF(ParseInt64(p, item.MTime)); p += 12;
+ RIF(ParseInt64_MTime(p, item.MTime)); p += 12;
UInt32 checkSum;
RIF(OctalToNumber32(p, 8, checkSum));
diff --git a/CPP/7zip/Archive/Tar/TarItem.h b/CPP/7zip/Archive/Tar/TarItem.h
index 5245aaa4..bc3b4084 100644
--- a/CPP/7zip/Archive/Tar/TarItem.h
+++ b/CPP/7zip/Archive/Tar/TarItem.h
@@ -3,6 +3,8 @@
#ifndef __ARCHIVE_TAR_ITEM_H
#define __ARCHIVE_TAR_ITEM_H
+#include "../../../Common/MyLinux.h"
+
#include "../Common/ItemNameUtils.h"
#include "TarHeader.h"
@@ -56,6 +58,32 @@ struct CItem
return false;
}
+ UInt32 Get_Combined_Mode() const
+ {
+ return (Mode & ~(UInt32)MY_LIN_S_IFMT) | Get_FileTypeMode_from_LinkFlag();
+ }
+
+ UInt32 Get_FileTypeMode_from_LinkFlag() const
+ {
+ switch (LinkFlag)
+ {
+ /*
+ case NFileHeader::NLinkFlag::kDirectory:
+ case NFileHeader::NLinkFlag::kDumpDir:
+ return MY_LIN_S_IFDIR;
+ */
+ case NFileHeader::NLinkFlag::kSymLink: return MY_LIN_S_IFLNK;
+ case NFileHeader::NLinkFlag::kBlock: return MY_LIN_S_IFBLK;
+ case NFileHeader::NLinkFlag::kCharacter: return MY_LIN_S_IFCHR;
+ case NFileHeader::NLinkFlag::kFIFO: return MY_LIN_S_IFIFO;
+ // case return MY_LIN_S_IFSOCK;
+ }
+
+ if (IsDir())
+ return MY_LIN_S_IFDIR;
+ return MY_LIN_S_IFREG;
+ }
+
bool IsDir() const
{
switch (LinkFlag)
diff --git a/CPP/7zip/Archive/Udf/UdfIn.cpp b/CPP/7zip/Archive/Udf/UdfIn.cpp
index d52db9f4..cfe6c5ad 100644
--- a/CPP/7zip/Archive/Udf/UdfIn.cpp
+++ b/CPP/7zip/Archive/Udf/UdfIn.cpp
@@ -51,13 +51,13 @@ void MY_FAST_CALL Crc16GenerateTable(void)
for (i = 0; i < 256; i++)
{
UInt32 r = (i << 8);
- for (int j = 8; j > 0; j--)
- r = ((r & 0x8000) ? ((r << 1) ^ kCrc16Poly) : (r << 1)) & 0xFFFF;
+ for (unsigned j = 0; j < 8; j++)
+ r = ((r << 1) ^ (kCrc16Poly & ((UInt32)0 - (r >> 15)))) & 0xFFFF;
g_Crc16Table[i] = (UInt16)r;
}
}
-UInt16 MY_FAST_CALL Crc16_Update(UInt16 v, const void *data, size_t size)
+UInt32 MY_FAST_CALL Crc16_Update(UInt32 v, const void *data, size_t size)
{
const Byte *p = (const Byte *)data;
for (; size > 0 ; size--, p++)
@@ -65,12 +65,12 @@ UInt16 MY_FAST_CALL Crc16_Update(UInt16 v, const void *data, size_t size)
return v;
}
-UInt16 MY_FAST_CALL Crc16Calc(const void *data, size_t size)
+UInt32 MY_FAST_CALL Crc16Calc(const void *data, size_t size)
{
return Crc16_Update(CRC16_INIT_VAL, data, size);
}
-struct CCrc16TableInit { CCrc16TableInit() { Crc16GenerateTable(); } } g_Crc16TableInit;
+static struct CCrc16TableInit { CCrc16TableInit() { Crc16GenerateTable(); } } g_Crc16TableInit;
@@ -109,7 +109,7 @@ static UString ParseDString(const Byte *data, unsigned size)
}
}
else
- return L"[unknow]";
+ return UString("[unknow]");
*p = 0;
res.ReleaseBuf_SetLen((unsigned)(p - (const wchar_t *)res));
}
@@ -179,12 +179,12 @@ HRESULT CTag::Parse(const Byte *buf, size_t size)
Id = Get16(buf);
Version = Get16(buf + 2);
// SerialNumber = Get16(buf + 6);
- UInt16 crc = Get16(buf + 8);
- UInt16 crcLen = Get16(buf + 10);
+ UInt32 crc = Get16(buf + 8);
+ UInt32 crcLen = Get16(buf + 10);
// TagLocation = Get32(buf + 12);
- if (size >= 16 + (size_t)crcLen)
- if (crc == Crc16Calc(buf + 16, crcLen))
+ if (size >= 16 + crcLen)
+ if (crc == Crc16Calc(buf + 16, (size_t)crcLen))
return S_OK;
return S_FALSE;
}
@@ -1077,14 +1077,7 @@ static UString GetSpecName(const UString &name)
UString name2 = name;
name2.Trim();
if (name2.IsEmpty())
- {
- /*
- wchar_t s[32];
- ConvertUInt64ToString(id, s);
- return L"[" + (UString)s + L"]";
- */
- return L"[]";
- }
+ return UString("[]");
return name;
}
@@ -1116,22 +1109,19 @@ UString CInArchive::GetItemPath(int volIndex, int fsIndex, int refIndex,
if (showFsName)
{
- wchar_t s[32];
- ConvertUInt32ToString(fsIndex, s);
- UString newName = L"File Set ";
- newName += s;
+ UString newName ("File Set ");
+ newName.Add_UInt32(fsIndex);
UpdateWithName(name, newName);
}
if (showVolName)
{
- wchar_t s[32];
- ConvertUInt32ToString(volIndex, s);
- UString newName = s;
+ UString newName;
+ newName.Add_UInt32(volIndex);
UString newName2 = vol.GetName();
if (newName2.IsEmpty())
- newName2 = L"Volume";
- newName += L'-';
+ newName2 = "Volume";
+ newName += '-';
newName += newName2;
UpdateWithName(name, newName);
}
diff --git a/CPP/7zip/Archive/UefiHandler.cpp b/CPP/7zip/Archive/UefiHandler.cpp
index ff0737a0..f49b62c8 100644
--- a/CPP/7zip/Archive/UefiHandler.cpp
+++ b/CPP/7zip/Archive/UefiHandler.cpp
@@ -46,20 +46,58 @@ static const size_t kBufTotalSizeMax = (1 << 29);
static const unsigned kNumFilesMax = (1 << 18);
static const unsigned kLevelMax = 64;
+static const Byte k_IntelMeSignature[] =
+{
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x5A, 0xA5, 0xF0, 0x0F
+};
+
+bool IsIntelMe(const Byte *p)
+{
+ return memcmp(p, k_IntelMeSignature, sizeof(k_IntelMeSignature)) == 0;
+}
+
static const unsigned kFvHeaderSize = 0x38;
static const unsigned kGuidSize = 16;
-#define CAPSULE_SIGNATURE \
- { 0xBD,0x86,0x66,0x3B,0x76,0x0D,0x30,0x40,0xB7,0x0E,0xB5,0x51,0x9E,0x2F,0xC5,0xA0 }
-static const Byte kCapsuleSig[kGuidSize] = CAPSULE_SIGNATURE;
+
+#define CAPSULE_SIGNATURE 0xBD,0x86,0x66,0x3B,0x76,0x0D,0x30,0x40,0xB7,0x0E,0xB5,0x51,0x9E,0x2F,0xC5,0xA0
+#define CAPSULE2_SIGNATURE 0x8B,0xA6,0x3C,0x4A,0x23,0x77,0xFB,0x48,0x80,0x3D,0x57,0x8C,0xC1,0xFE,0xC4,0x4D
+#define CAPSULE_UEFI_SIGNATURE 0xB9,0x82,0x91,0x53,0xB5,0xAB,0x91,0x43,0xB6,0x9A,0xE3,0xA9,0x43,0xF7,0x2F,0xCC
+/*
+ 6dcbd5ed-e82d-4c44-bda1-7194199ad92a : Firmware Management `
+*/
+
+static const Byte k_Guids_Capsules[][kGuidSize] =
+{
+ { CAPSULE_SIGNATURE },
+ { CAPSULE2_SIGNATURE },
+ { CAPSULE_UEFI_SIGNATURE }
+};
+
static const unsigned kFfsGuidOffset = 16;
-#define FFS_SIGNATURE \
- { 0xD9,0x54,0x93,0x7A,0x68,0x04,0x4A,0x44,0x81,0xCE,0x0B,0xF6,0x17,0xD8,0x90,0xDF }
-static const Byte k_FFS_Guid[kGuidSize] = FFS_SIGNATURE;
-static const Byte k_MacFS_Guid[kGuidSize] =
- { 0xAD,0xEE,0xAD,0x04,0xFF,0x61,0x31,0x4D,0xB6,0xBA,0x64,0xF8,0xBF,0x90,0x1F,0x5A };
+#define FFS1_SIGNATURE 0xD9,0x54,0x93,0x7A,0x68,0x04,0x4A,0x44,0x81,0xCE,0x0B,0xF6,0x17,0xD8,0x90,0xDF
+#define FFS2_SIGNATURE 0x78,0xE5,0x8C,0x8C,0x3D,0x8A,0x1C,0x4F,0x99,0x35,0x89,0x61,0x85,0xC3,0x2D,0xD3
+#define MACFS_SIGNATURE 0xAD,0xEE,0xAD,0x04,0xFF,0x61,0x31,0x4D,0xB6,0xBA,0x64,0xF8,0xBF,0x90,0x1F,0x5A
+// APPLE_BOOT
+/*
+ "FFS3": "5473c07a-3dcb-4dca-bd6f-1e9689e7349a",
+ "NVRAM_EVSA": "fff12b8d-7696-4c8b-a985-2747075b4f50",
+ "NVRAM_NVAR": "cef5b9a3-476d-497f-9fdc-e98143e0422c",
+ "NVRAM_EVSA2": "00504624-8a59-4eeb-bd0f-6b36e96128e0",
+static const Byte k_NVRAM_NVAR_Guid[kGuidSize] =
+ { 0xA3,0xB9,0xF5,0xCE,0x6D,0x47,0x7F,0x49,0x9F,0xDC,0xE9,0x81,0x43,0xE0,0x42,0x2C };
+*/
+
+static const Byte k_Guids_FS[][kGuidSize] =
+{
+ { FFS1_SIGNATURE },
+ { FFS2_SIGNATURE },
+ { MACFS_SIGNATURE }
+};
+
static const UInt32 kFvSignature = 0x4856465F; // "_FVH"
@@ -80,6 +118,8 @@ static const Byte kGuids[][kGuidSize] =
{ 0x18,0x88,0x53,0x4A,0xE0,0x5A,0xB2,0x4E,0xB2,0xEB,0x48,0x8B,0x23,0x65,0x70,0x22 }
};
+static const Byte k_Guid_LZMA_COMPRESSED[kGuidSize] =
+ { 0x98,0x58,0x4E,0xEE,0x14,0x39,0x59,0x42,0x9D,0x6E,0xDC,0x7B,0xD7,0x94,0x03,0xCF };
static const char * const kGuidNames[] =
{
@@ -180,7 +220,12 @@ static int FindGuid(const Byte *p)
static bool IsFfs(const Byte *p)
{
- return (Get32(p + 0x28) == kFvSignature && AreGuidsEq(p + kFfsGuidOffset, k_FFS_Guid));
+ if (Get32(p + 0x28) != kFvSignature)
+ return false;
+ for (unsigned i = 0; i < ARRAY_SIZE(k_Guids_FS); i++)
+ if (AreGuidsEq(p + kFfsGuidOffset, k_Guids_FS[i]))
+ return true;
+ return false;
}
#define FVB_ERASE_POLARITY (1 << 11)
@@ -329,39 +374,15 @@ static const char * const g_Methods[] =
, "LZMA"
};
-static AString UInt32ToString(UInt32 val)
-{
- char sz[16];
- ConvertUInt32ToString(val, sz);
- return sz;
-}
-static void ConvertByteToHex(unsigned value, char *s)
+static void AddGuid(AString &dest, const Byte *p, bool full)
{
- for (int i = 0; i < 2; i++)
- {
- unsigned t = value & 0xF;
- value >>= 4;
- s[1 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
- }
-}
-
-static AString GuidToString(const Byte *p, bool full)
-{
- char s[16 * 2 + 8];
- int i;
- for (i = 0; i < 4; i++)
- ConvertByteToHex(p[3 - i], s + i * 2);
- s[8] = 0;
-
- if (full)
- {
- s[8] = '-';
- for (i = 4; i < kGuidSize; i++)
- ConvertByteToHex(p[i], s + 1 + i * 2);
- s[32 + 1] = 0;
- }
- return s;
+ char s[64];
+ ::RawLeGuidToString(p, s);
+ // MyStringUpper_Ascii(s);
+ if (!full)
+ s[8] = 0;
+ dest += s;
}
static const char * const kExpressionCommands[] =
@@ -383,7 +404,7 @@ static bool ParseDepedencyExpression(const Byte *p, UInt32 size, AString &res)
if (i + kGuidSize > size)
return false;
res.Add_Space();
- res += GuidToString(p + i, false);
+ AddGuid(res, p + i, false);
i += kGuidSize;
}
res += "; ";
@@ -433,6 +454,7 @@ static void AddSpaceAndString(AString &res, const AString &newString)
class CFfsFileHeader
{
+PRF(public:)
Byte CheckHeader;
Byte CheckFile;
Byte Attrib;
@@ -530,7 +552,7 @@ public:
if (align != 0)
{
s += " Align:";
- s += UInt32ToString((UInt32)1 << g_Allignment[align]);
+ s.Add_UInt32((UInt32)1 << g_Allignment[align]);
}
*/
return s;
@@ -538,6 +560,7 @@ public:
};
#define G32(_offs_, dest) dest = Get32(p + (_offs_));
+#define G16(_offs_, dest) dest = Get16(p + (_offs_));
struct CCapsuleHeader
{
@@ -557,23 +580,51 @@ struct CCapsuleHeader
void Clear() { memset(this, 0, sizeof(*this)); }
- void Parse(const Byte *p)
+ bool Parse(const Byte *p)
{
+ Clear();
G32(0x10, HeaderSize);
G32(0x14, Flags);
G32(0x18, CapsuleImageSize);
- G32(0x1C, SequenceNumber);
- G32(0x30, OffsetToSplitInformation);
- G32(0x34, OffsetToCapsuleBody);
- G32(0x38, OffsetToOemDefinedHeader);
- G32(0x3C, OffsetToAuthorInformation);
- G32(0x40, OffsetToRevisionInformation);
- G32(0x44, OffsetToShortDescription);
- G32(0x48, OffsetToLongDescription);
- G32(0x4C, OffsetToApplicableDevices);
+ if (HeaderSize < 0x1C)
+ return false;
+ if (AreGuidsEq(p, k_Guids_Capsules[0]))
+ {
+ const unsigned kHeaderSize = 80;
+ if (HeaderSize != kHeaderSize)
+ return false;
+ G32(0x1C, SequenceNumber);
+ G32(0x30, OffsetToSplitInformation);
+ G32(0x34, OffsetToCapsuleBody);
+ G32(0x38, OffsetToOemDefinedHeader);
+ G32(0x3C, OffsetToAuthorInformation);
+ G32(0x40, OffsetToRevisionInformation);
+ G32(0x44, OffsetToShortDescription);
+ G32(0x48, OffsetToLongDescription);
+ G32(0x4C, OffsetToApplicableDevices);
+ return true;
+ }
+ else if (AreGuidsEq(p, k_Guids_Capsules[1]))
+ {
+ // capsule v2
+ G16(0x1C, OffsetToCapsuleBody);
+ G16(0x1E, OffsetToOemDefinedHeader);
+ return true;
+ }
+ else if (AreGuidsEq(p, k_Guids_Capsules[2]))
+ {
+ OffsetToCapsuleBody = HeaderSize;
+ return true;
+ }
+ else
+ {
+ // here we must check for another capsule types
+ return false;
+ }
}
};
+
struct CItem
{
AString Name;
@@ -605,7 +656,10 @@ void CItem::SetGuid(const Byte *guidName, bool full)
if (index >= 0)
Name = kGuidNames[(unsigned)index];
else
- Name = GuidToString(guidName, full);
+ {
+ Name.Empty();
+ AddGuid(Name, guidName, full);
+ }
}
AString CItem::GetName(int numChildsInParent) const
@@ -616,11 +670,14 @@ AString CItem::GetName(int numChildsInParent) const
char sz2[32];
ConvertUInt32ToString(NameIndex, sz);
ConvertUInt32ToString(numChildsInParent - 1, sz2);
- unsigned numZeros = (unsigned)strlen(sz2) - (unsigned)strlen(sz);
+ int numZeros = (int)strlen(sz2) - (int)strlen(sz);
AString res;
- for (unsigned i = 0; i < numZeros; i++)
+ for (int i = 0; i < numZeros; i++)
res += '0';
- return res + (AString)sz + '.' + Name;
+ res += sz;
+ res += '.';
+ res += Name;
+ return res;
}
struct CItem2
@@ -644,21 +701,30 @@ class CHandler:
UString _comment;
UInt32 _methodsMask;
bool _capsuleMode;
+ bool _headersError;
size_t _totalBufsSize;
CCapsuleHeader _h;
UInt64 _phySize;
- void AddCommentString(const wchar_t *name, UInt32 pos);
+ void AddCommentString(const char *name, UInt32 pos);
int AddItem(const CItem &item);
int AddFileItemWithIndex(CItem &item);
int AddDirItem(CItem &item);
unsigned AddBuf(size_t size);
- HRESULT ParseSections(int bufIndex, UInt32 pos, UInt32 size, int parent, int method, unsigned level);
+ HRESULT DecodeLzma(const Byte *data, size_t inputSize);
+
+ HRESULT ParseSections(int bufIndex, UInt32 pos, UInt32 size, int parent, int method, unsigned level, bool &error);
+
+ HRESULT ParseIntelMe(int bufIndex, UInt32 posBase,
+ UInt32 exactSize, UInt32 limitSize,
+ int parent, int method, int level);
+
HRESULT ParseVolume(int bufIndex, UInt32 posBase,
UInt32 exactSize, UInt32 limitSize,
int parent, int method, int level);
+
HRESULT OpenCapsule(IInStream *stream);
HRESULT OpenFv(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback);
HRESULT Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback);
@@ -674,6 +740,7 @@ static const Byte kProps[] =
kpidPath,
kpidIsDir,
kpidSize,
+ // kpidOffset,
kpidMethod,
kpidCharacts
};
@@ -698,7 +765,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath:
{
- AString path = item2.Name;
+ AString path (item2.Name);
int cur = item2.Parent;
while (cur >= 0)
{
@@ -714,13 +781,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidMethod: if (item.Method >= 0) prop = g_Methods[(unsigned)item.Method]; break;
case kpidCharacts: if (!item2.Characts.IsEmpty()) prop = item2.Characts; break;
case kpidSize: if (!item.IsDir) prop = (UInt64)item.Size; break;
+ // case kpidOffset: if (!item.IsDir) prop = item.Offset; break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
-void CHandler::AddCommentString(const wchar_t *name, UInt32 pos)
+void CHandler::AddCommentString(const char *name, UInt32 pos)
{
UString s;
const Byte *buf = _bufs[0];
@@ -747,7 +815,7 @@ void CHandler::AddCommentString(const wchar_t *name, UInt32 pos)
return;
_comment.Add_LF();
_comment += name;
- _comment.AddAscii(": ");
+ _comment += ": ";
_comment += s;
}
@@ -762,13 +830,22 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
AString s;
for (unsigned i = 0; i < 32; i++)
if ((_methodsMask & ((UInt32)1 << i)) != 0)
- AddSpaceAndString(s, g_Methods[i]);
+ AddSpaceAndString(s, (AString)g_Methods[i]);
if (!s.IsEmpty())
prop = s;
break;
}
case kpidComment: if (!_comment.IsEmpty()) prop = _comment; break;
case kpidPhySize: prop = (UInt64)_phySize; break;
+
+ case kpidErrorFlags:
+ {
+ UInt32 v = 0;
+ if (!_headersError) v |= kpv_ErrorFlags_HeadersError;
+ if (v != 0)
+ prop = v;
+ break;
+ }
}
prop.Detach(value);
return S_OK;
@@ -785,7 +862,7 @@ static void PrintLevel(int level)
static void MyPrint(UInt32 posBase, UInt32 size, int level, const char *name)
{
PrintLevel(level);
- PRF(printf("%s, pos = %6x, size = %6d", name, posBase, size));
+ PRF(printf("%s, pos = %6x, size = %6x", name, posBase, size));
}
#else
#define PrintLevel(level)
@@ -829,8 +906,36 @@ unsigned CHandler::AddBuf(size_t size)
return index;
}
-HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int parent, int method, unsigned level)
+
+HRESULT CHandler::DecodeLzma(const Byte *data, size_t inputSize)
+{
+ if (inputSize < 5 + 8)
+ return S_FALSE;
+ const UInt64 unpackSize = Get64(data + 5);
+ if (unpackSize > ((UInt32)1 << 30))
+ return S_FALSE;
+ SizeT destLen = (SizeT)unpackSize;
+ const unsigned newBufIndex = AddBuf((size_t)unpackSize);
+ CByteBuffer &buf = _bufs[newBufIndex];
+ ELzmaStatus status;
+ SizeT srcLen = inputSize - (5 + 8);
+ const SizeT srcLen2 = srcLen;
+ SRes res = LzmaDecode(buf, &destLen, data + 13, &srcLen,
+ data, 5, LZMA_FINISH_END, &status, &g_Alloc);
+ if (res != 0)
+ return S_FALSE;
+ if (srcLen != srcLen2 || destLen != unpackSize || (
+ status != LZMA_STATUS_FINISHED_WITH_MARK &&
+ status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
+ return S_FALSE;
+ return S_OK;
+}
+
+
+HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int parent, int method, unsigned level, bool &error)
{
+ error = false;
+
if (level > kLevelMax)
return S_FALSE;
MyPrint(posBase, size, level, "Sections");
@@ -842,7 +947,7 @@ HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int p
if (size == pos)
return S_OK;
PrintLevel(level);
- PRF(printf("%s, pos = %6x", "Sect", pos));
+ PRF(printf("%s, abs = %6x, relat = %6x", "Sect", posBase + pos, pos));
pos = (pos + 3) & ~(UInt32)3;
if (pos > size)
return S_FALSE;
@@ -851,14 +956,23 @@ HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int p
return S_OK;
if (rem < 4)
return S_FALSE;
+
const Byte *p = bufData + posBase + pos;
- UInt32 sectSize = Get24(p);
- if (sectSize > rem || sectSize < 4)
- return S_FALSE;
- Byte type = p[3];
- PrintLevel(level);
- PRF(printf("%s, type = %2x, pos = %6x, size = %6d", "Sect", type, pos, sectSize));
+ const UInt32 sectSize = Get24(p);
+ const Byte type = p[3];
+
+ // PrintLevel(level);
+ PRF(printf(" type = %2x, sectSize = %6x", type, sectSize));
+
+ if (sectSize > rem || sectSize < 4)
+ {
+ _headersError = true;
+ error = true;
+ return S_OK;
+ // return S_FALSE;
+ }
+
CItem item;
item.Method = method;
item.BufIndex = bufIndex;
@@ -891,7 +1005,8 @@ HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int p
// int parent = AddDirItem(item);
if (compressionType == COMPRESSION_TYPE_NONE)
{
- RINOK(ParseSections(bufIndex, newOffset, newSectSize, parent, method, level));
+ bool error2;
+ RINOK(ParseSections(bufIndex, newOffset, newSectSize, parent, method, level, error2));
}
else if (compressionType == COMPRESSION_TYPE_LZH)
{
@@ -910,6 +1025,9 @@ HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int p
return S_FALSE;
UInt32 packSize = Get32(src);
UInt32 unpackSize = Get32(src + 4);
+
+ PRF(printf(" LZH packSize = %6x, unpackSize = %6x", packSize, unpackSize));
+
if (uncompressedSize != unpackSize || newSectSize - 8 != packSize)
return S_FALSE;
if (packSize < 1)
@@ -921,30 +1039,34 @@ HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int p
CBufInStream *inStreamSpec = new CBufInStream;
CMyComPtr<IInStream> inStream = inStreamSpec;
- inStreamSpec->Init(src, packSize);
CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
- outStreamSpec->Init(buf, uncompressedSize);
UInt64 uncompressedSize64 = uncompressedSize;
lzhDecoderSpec->FinishMode = true;
/*
- EFI 1.1 probably used small dictionary and (pbit = 4) in LZH. We don't support such archives.
+ EFI 1.1 probably used LZH with small dictionary and (pbit = 4). It was named "Efi compression".
New version of compression code (named Tiano) uses LZH with (1 << 19) dictionary.
But maybe LZH decoder in UEFI decoder supports larger than (1 << 19) dictionary.
+ We check both LZH versions: Tiano and then Efi.
*/
- lzhDecoderSpec->SetDictSize(1 << 19);
-
- HRESULT res = lzhDecoder->Code(inStream, outStream, NULL, &uncompressedSize64, NULL);
- if (res != S_OK)
- return res;
-
- if (lzhDecoderSpec->GetInputProcessedSize() != packSize)
- return S_FALSE;
+ HRESULT res = S_FALSE;
+
+ for (unsigned m = 0 ; m < 2; m++)
+ {
+ inStreamSpec->Init(src, packSize);
+ outStreamSpec->Init(buf, uncompressedSize);
+ lzhDecoderSpec->SetDictSize((m == 0) ? ((UInt32)1 << 19) : ((UInt32)1 << 14));
+ res = lzhDecoder->Code(inStream, outStream, NULL, &uncompressedSize64, NULL);
+ if (res == S_OK)
+ break;
+ }
+ RINOK(res);
}
- RINOK(ParseSections(newBufIndex, 0, uncompressedSize, parent, compressionType, level));
+ bool error2;
+ RINOK(ParseSections(newBufIndex, 0, uncompressedSize, parent, compressionType, level, error2));
}
else
{
@@ -964,26 +1086,14 @@ HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int p
// firstSectType can be 0 in some archives
}
pStart += addSize;
- UInt64 lzmaUncompressedSize = Get64(pStart + 5);
- if (lzmaUncompressedSize > (1 << 30))
- return S_FALSE;
+
+ RINOK(DecodeLzma(pStart, newSectSize - addSize));
+ const size_t lzmaUncompressedSize = _bufs.Back().Size();
+ // if (lzmaUncompressedSize != uncompressedSize)
if (lzmaUncompressedSize < uncompressedSize)
return S_FALSE;
- SizeT destLen = (SizeT)lzmaUncompressedSize;
- unsigned newBufIndex = AddBuf((size_t)lzmaUncompressedSize);
- CByteBuffer &buf = _bufs[newBufIndex];
- ELzmaStatus status;
- SizeT srcLen = newSectSize - (addSize + 5 + 8);
- SizeT srcLen2 = srcLen;
- SRes res = LzmaDecode(buf, &destLen, pStart + 13, &srcLen,
- pStart, 5, LZMA_FINISH_END, &status, &g_Alloc);
- if (res != 0)
- return S_FALSE;
- if (srcLen != srcLen2 || destLen != lzmaUncompressedSize || (
- status != LZMA_STATUS_FINISHED_WITH_MARK &&
- status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
- return S_FALSE;
- RINOK(ParseSections(newBufIndex, 0, (UInt32)lzmaUncompressedSize, parent, compressionType, level));
+ bool error2;
+ RINOK(ParseSections(_bufs.Size() - 1, 0, (UInt32)lzmaUncompressedSize, parent, compressionType, level, error2));
}
_methodsMask |= (1 << compressionType);
}
@@ -1003,9 +1113,26 @@ HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int p
UInt32 newOffset = posBase + pos + dataOffset;
item.Offset = newOffset;
UInt32 propsSize = dataOffset - kHeaderSize;
- bool needDir = true;
AddSpaceAndString(item.Characts, FLAGS_TO_STRING(g_GUIDED_SECTION_ATTRIBUTES, attrib));
- if (AreGuidsEq(p + 0x4, kGuids[kGuidIndex_CRC]) && propsSize == 4)
+
+ bool needDir = true;
+ unsigned newBufIndex = bufIndex;
+ int newMethod = method;
+
+ if (AreGuidsEq(p + 0x4, k_Guid_LZMA_COMPRESSED))
+ {
+ // item.Name = "guid.lzma";
+ // AddItem(item);
+ const Byte *pStart = bufData + newOffset;
+ // do we need correct pStart here for lzma steram offset?
+ RINOK(DecodeLzma(pStart, newSectSize));
+ _methodsMask |= (1 << COMPRESSION_TYPE_LZMA);
+ newBufIndex = _bufs.Size() - 1;
+ newOffset = 0;
+ newSectSize = (UInt32)_bufs.Back().Size();
+ newMethod = COMPRESSION_TYPE_LZMA;
+ }
+ else if (AreGuidsEq(p + 0x4, kGuids[kGuidIndex_CRC]) && propsSize == 4)
{
needDir = false;
item.KeepName = false;
@@ -1023,10 +1150,12 @@ HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int p
AddItem(item2);
}
}
+
int newParent = parent;
if (needDir)
newParent = AddDirItem(item);
- RINOK(ParseSections(bufIndex, newOffset, newSectSize, newParent, method, level));
+ bool error2;
+ RINOK(ParseSections(newBufIndex, newOffset, newSectSize, newParent, newMethod, level, error2));
}
else if (type == SECTION_FIRMWARE_VOLUME_IMAGE)
{
@@ -1100,8 +1229,8 @@ HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int p
AString s;
if (ParseUtf16zString2(p + 6, sectDataSize - 2, s))
{
- AString s2 = "ver:";
- s2 += UInt32ToString(Get16(p + 4));
+ AString s2 ("ver:");
+ s2.Add_UInt32(Get16(p + 4));
s2.Add_Space();
s2 += s;
AddSpaceAndString(_items[item.Parent].Characts, s2);
@@ -1135,6 +1264,7 @@ HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int p
if (needAdd)
AddFileItemWithIndex(item);
}
+
pos += sectSize;
}
}
@@ -1174,6 +1304,7 @@ bool CVolFfsHeader::Parse(const Byte *p)
return true;
};
+
HRESULT CHandler::ParseVolume(
int bufIndex, UInt32 posBase,
UInt32 exactSize, UInt32 limitSize,
@@ -1181,14 +1312,13 @@ HRESULT CHandler::ParseVolume(
{
if (level > kLevelMax)
return S_FALSE;
- MyPrint(posBase, size, level, "Volume");
+ MyPrint(posBase, exactSize, level, "Volume");
level++;
if (exactSize < kFvHeaderSize)
return S_FALSE;
const Byte *p = _bufs[bufIndex] + posBase;
// first 16 bytes must be zeros, but they are not zeros sometimes.
- if (!AreGuidsEq(p + kFfsGuidOffset, k_FFS_Guid) &&
- !AreGuidsEq(p + kFfsGuidOffset, k_MacFS_Guid))
+ if (!IsFfs(p))
{
CItem item;
item.Method = method;
@@ -1196,8 +1326,10 @@ HRESULT CHandler::ParseVolume(
item.Parent = parent;
item.Offset = posBase;
item.Size = exactSize;
- item.SetGuid(p + kFfsGuidOffset);
- item.Name += " [VOLUME]";
+ if (!Is_FF_Stream(p + kFfsGuidOffset, 16))
+ item.SetGuid(p + kFfsGuidOffset);
+ // if (item.Name.IsEmpty())
+ item.Name += "[VOL]";
AddItem(item);
return S_OK;
}
@@ -1268,9 +1400,13 @@ HRESULT CHandler::ParseVolume(
item.Size = rem - num_FF_bytes;
AddItem(item);
}
+ PrintLevel(level); PRF(printf("== FF FF reminder"));
+
break;
}
- PrintLevel(level); PRF(printf("%s, pos = %6x, size = %6d", "FILE", posBase + pos, fh.Size));
+
+ PrintLevel(level); PRF(printf("%s, type = %3d, pos = %7x, size = %7x", "FILE", fh.Type, posBase + pos, fh.Size));
+
if (!fh.Check(pFile, rem))
return S_FALSE;
@@ -1295,9 +1431,16 @@ HRESULT CHandler::ParseVolume(
item.SetGuid(fh.GuidName, full);
item.Characts = fh.GetCharacts();
- PrintLevel(level);
- PRF(printf("%s", item.Characts));
-
+ // PrintLevel(level);
+ PRF(printf(" : %s", item.Characts));
+
+ {
+ PRF(printf(" attrib = %2d State = %3d ", (unsigned)fh.Attrib, (unsigned)fh.State));
+ PRF(char s[64]);
+ PRF(RawLeGuidToString(fh.GuidName, s));
+ PRF(printf(" : %s ", s));
+ }
+
if (fh.Type == FV_FILETYPE_FFS_PAD ||
fh.Type == FV_FILETYPE_RAW)
{
@@ -1321,23 +1464,127 @@ HRESULT CHandler::ParseVolume(
}
else
{
- int newParent = AddDirItem(item);
- RINOK(ParseSections(bufIndex, offset, sectSize, newParent, method, level));
+ /*
+ if (fh.Type == FV_FILETYPE_FREEFORM)
+ {
+ // in intel bio example: one FV_FILETYPE_FREEFORM file is wav file (not sections)
+ // AddItem(item);
+ }
+ else
+ */
+ {
+ int newParent = AddDirItem(item);
+ bool error2;
+ RINOK(ParseSections(bufIndex, offset, sectSize, newParent, method, level + 1, error2));
+ if (error2)
+ {
+ // in intel bio example: one FV_FILETYPE_FREEFORM file is wav file (not sections)
+ item.IsDir = false;
+ item.Size = sectSize;
+ item.Name.Insert(0, "[ERROR]");
+ AddItem(item);
+ }
+ }
}
}
+
+ return S_OK;
+}
+
+
+static const char * const kRegionName[] =
+{
+ "Descriptor"
+ , "BIOS"
+ , "ME"
+ , "GbE"
+ , "PDR"
+ , "Region5"
+ , "Region6"
+ , "Region7"
+};
+
+
+HRESULT CHandler::ParseIntelMe(
+ int bufIndex, UInt32 posBase,
+ UInt32 exactSize, UInt32 limitSize,
+ int parent, int method, int level)
+{
+ UNUSED_VAR(limitSize)
+ level++;
+ const Byte *p = _bufs[bufIndex] + posBase;
+ if (exactSize < 16 + 16)
+ return S_FALSE;
+ if (!IsIntelMe(p))
+ return S_FALSE;
+
+ UInt32 v0 = GetUi32(p + 20);
+ // UInt32 numRegions = (v0 >> 24) & 0x7;
+ UInt32 regAddr = (v0 >> 12) & 0xFF0;
+ // UInt32 numComps = (v0 >> 8) & 0x3;
+ // UInt32 fcba = (v0 << 4) & 0xFF0;
+
+ // (numRegions == 0) in header in some new images.
+ // So we don't use the value from header
+ UInt32 numRegions = 7;
+
+ for (unsigned i = 0; i <= numRegions; i++)
+ {
+ UInt32 offset = regAddr + i * 4;
+ if (offset + 4 > exactSize)
+ break;
+ UInt32 val = GetUi32(p + offset);
+
+ // only 12 bits probably are OK.
+ // How does it work for files larger than 16 MB?
+ const UInt32 kMask = 0xFFF;
+ // const UInt32 kMask = 0xFFFF; // 16-bit is more logical
+ const UInt32 lim = (val >> 16) & kMask;
+ const UInt32 base = (val & kMask);
+
+ /*
+ strange combinations:
+ PDR: base = 0x1FFF lim = 0;
+ empty: base = 0xFFFF lim = 0xFFFF;
+
+ PDR: base = 0x7FFF lim = 0;
+ empty: base = 0x7FFF lim = 0;
+ */
+ if (base == kMask && lim == 0)
+ continue; // unused
+
+ if (lim < base)
+ continue; // unused
+
+ CItem item;
+ item.Name = kRegionName[i];
+ item.Method = method;
+ item.BufIndex = bufIndex;
+ item.Parent = parent;
+ item.Offset = posBase + (base << 12);
+ if (item.Offset > exactSize)
+ continue;
+ item.Size = (lim + 1 - base) << 12;
+ // item.SetGuid(p + kFfsGuidOffset);
+ // item.Name += " [VOLUME]";
+ AddItem(item);
+ }
return S_OK;
}
+
HRESULT CHandler::OpenCapsule(IInStream *stream)
{
const unsigned kHeaderSize = 80;
Byte buf[kHeaderSize];
RINOK(ReadStream_FALSE(stream, buf, kHeaderSize));
- _h.Parse(buf);
- if (_h.HeaderSize != kHeaderSize ||
- _h.CapsuleImageSize < kHeaderSize ||
- _h.OffsetToCapsuleBody < kHeaderSize ||
- _h.OffsetToCapsuleBody > _h.CapsuleImageSize)
+ if (!_h.Parse(buf))
+ return S_FALSE;
+ if (_h.CapsuleImageSize < kHeaderSize
+ || _h.CapsuleImageSize < _h.HeaderSize
+ || _h.OffsetToCapsuleBody < _h.HeaderSize
+ || _h.OffsetToCapsuleBody > _h.CapsuleImageSize
+ )
return S_FALSE;
_phySize = _h.CapsuleImageSize;
@@ -1350,17 +1597,21 @@ HRESULT CHandler::OpenCapsule(IInStream *stream)
memcpy(buf0, buf, kHeaderSize);
ReadStream_FALSE(stream, buf0 + kHeaderSize, _h.CapsuleImageSize - kHeaderSize);
- AddCommentString(L"Author", _h.OffsetToAuthorInformation);
- AddCommentString(L"Revision", _h.OffsetToRevisionInformation);
- AddCommentString(L"Short Description", _h.OffsetToShortDescription);
- AddCommentString(L"Long Description", _h.OffsetToLongDescription);
+ AddCommentString("Author", _h.OffsetToAuthorInformation);
+ AddCommentString("Revision", _h.OffsetToRevisionInformation);
+ AddCommentString("Short Description", _h.OffsetToShortDescription);
+ AddCommentString("Long Description", _h.OffsetToLongDescription);
+
+
+ const UInt32 size = _h.CapsuleImageSize - _h.OffsetToCapsuleBody;
- return ParseVolume(bufIndex, _h.OffsetToCapsuleBody,
- _h.CapsuleImageSize - _h.OffsetToCapsuleBody,
- _h.CapsuleImageSize - _h.OffsetToCapsuleBody,
- -1, -1, 0);
+ if (size >= 32 && IsIntelMe(buf0 + _h.OffsetToCapsuleBody))
+ return ParseIntelMe(bufIndex, _h.OffsetToCapsuleBody, size, size, -1, -1, 0);
+
+ return ParseVolume(bufIndex, _h.OffsetToCapsuleBody, size, size, -1, -1, 0);
}
+
HRESULT CHandler::OpenFv(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback * /* callback */)
{
Byte buf[kFvHeaderSize];
@@ -1380,6 +1631,7 @@ HRESULT CHandler::OpenFv(IInStream *stream, const UInt64 * /* maxCheckStartPosit
return ParseVolume(bufIndex, 0, fvSize32, fvSize32, -1, -1, 0);
}
+
HRESULT CHandler::Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
{
if (_capsuleMode)
@@ -1432,8 +1684,8 @@ HRESULT CHandler::Open2(IInStream *stream, const UInt64 *maxCheckStartPosition,
int parent = item.Parent;
if (parent >= 0)
numItems = numChilds[(unsigned)parent];
- AString name2 = item.GetName(numItems);
- AString characts2 = item.Characts;
+ AString name2 (item.GetName(numItems));
+ AString characts2 (item.Characts);
if (item.KeepName)
name = name2;
@@ -1444,7 +1696,7 @@ HRESULT CHandler::Open2(IInStream *stream, const UInt64 *maxCheckStartPosition,
break;
if (item3.KeepName)
{
- AString name3 = item3.GetName(-1);
+ AString name3 (item3.GetName(-1));
if (name.IsEmpty())
name = name3;
else
@@ -1500,6 +1752,7 @@ STDMETHODIMP CHandler::Close()
_items2.Clear();
_bufs.Clear();
_comment.Empty();
+ _headersError = false;
_h.Clear();
return S_OK;
}
@@ -1580,11 +1833,12 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
CBufInStream *streamSpec = new CBufInStream;
CMyComPtr<IInStream> streamTemp = streamSpec;
const CByteBuffer &buf = _bufs[item.BufIndex];
- /*
- if (item.Offset + item.Size > buf.GetCapacity())
+ if (item.Offset > buf.Size())
return S_FALSE;
- */
- streamSpec->Init(buf + item.Offset, item.Size, (IInArchive *)this);
+ size_t size = buf.Size() - item.Offset;
+ if (size > item.Size)
+ size = item.Size;
+ streamSpec->Init(buf + item.Offset, size, (IInArchive *)this);
*stream = streamTemp.Detach();
return S_OK;
COM_TRY_END
@@ -1593,11 +1847,19 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
namespace UEFIc {
+static const Byte k_Capsule_Signatures[] =
+{
+ 16, CAPSULE_SIGNATURE,
+ 16, CAPSULE2_SIGNATURE,
+ 16, CAPSULE_UEFI_SIGNATURE
+};
+
REGISTER_ARC_I_CLS(
CHandler(true),
"UEFIc", "scap", 0, 0xD0,
- kCapsuleSig,
+ k_Capsule_Signatures,
0,
+ NArcInfoFlags::kMultiSignature |
NArcInfoFlags::kFindSignature,
NULL)
@@ -1605,11 +1867,19 @@ REGISTER_ARC_I_CLS(
namespace UEFIf {
+static const Byte k_FFS_Signatures[] =
+{
+ 16, FFS1_SIGNATURE,
+ 16, FFS2_SIGNATURE
+};
+
+
REGISTER_ARC_I_CLS(
CHandler(false),
"UEFIf", "uefif", 0, 0xD1,
- k_FFS_Guid,
+ k_FFS_Signatures,
kFfsGuidOffset,
+ NArcInfoFlags::kMultiSignature |
NArcInfoFlags::kFindSignature,
NULL)
diff --git a/CPP/7zip/Archive/VdiHandler.cpp b/CPP/7zip/Archive/VdiHandler.cpp
index a8d3fe36..b8ef35bb 100644
--- a/CPP/7zip/Archive/VdiHandler.cpp
+++ b/CPP/7zip/Archive/VdiHandler.cpp
@@ -11,12 +11,14 @@
#include "../../Common/MyBuffer.h"
#include "../../Windows/PropVariant.h"
+#include "../../Windows/PropVariantUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "HandlerCont.h"
+#define Get16(p) GetUi16(p)
#define Get32(p) GetUi32(p)
#define Get64(p) GetUi64(p)
@@ -33,6 +35,7 @@ static const unsigned k_ClusterBits = 20;
static const UInt32 k_ClusterSize = (UInt32)1 << k_ClusterBits;
static const UInt32 k_UnusedCluster = 0xFFFFFFFF;
+
// static const UInt32 kDiskType_Dynamic = 1;
// static const UInt32 kDiskType_Static = 2;
@@ -41,8 +44,38 @@ static const char * const kDiskTypes[] =
"0"
, "Dynamic"
, "Static"
+ , "Undo"
+ , "Diff"
+};
+
+
+enum EGuidType
+{
+ k_GuidType_Creat,
+ k_GuidType_Modif,
+ k_GuidType_Link,
+ k_GuidType_PModif
};
+static const unsigned kNumGuids = 4;
+static const char * const kGuidNames[kNumGuids] =
+{
+ "Creat "
+ , "Modif "
+ , "Link "
+ , "PModif"
+};
+
+static bool IsEmptyGuid(const Byte *data)
+{
+ for (unsigned i = 0; i < 16; i++)
+ if (data[i] != 0)
+ return false;
+ return true;
+}
+
+
+
class CHandler: public CHandlerImg
{
UInt32 _dataOffset;
@@ -52,6 +85,8 @@ class CHandler: public CHandlerImg
bool _isArc;
bool _unsupported;
+ Byte Guids[kNumGuids][16];
+
HRESULT Seek(UInt64 offset)
{
_posInArc = offset;
@@ -137,7 +172,9 @@ static const Byte kProps[] =
static const Byte kArcProps[] =
{
kpidHeadersSize,
- kpidMethod
+ kpidMethod,
+ kpidComment,
+ kpidName
};
IMP_IInArchive_Props
@@ -156,16 +193,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidMethod:
{
- char s[16];
- const char *ptr;
- if (_imageType < ARRAY_SIZE(kDiskTypes))
- ptr = kDiskTypes[_imageType];
- else
- {
- ConvertUInt32ToString(_imageType, s);
- ptr = s;
- }
- prop = ptr;
+ TYPE_TO_PROP(kDiskTypes, _imageType, prop);
break;
}
@@ -181,6 +209,42 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = v;
break;
}
+
+ case kpidComment:
+ {
+ AString s;
+ for (unsigned i = 0; i < kNumGuids; i++)
+ {
+ const Byte *guid = Guids[i];
+ if (!IsEmptyGuid(guid))
+ {
+ s.Add_LF();
+ s += kGuidNames[i];
+ s += " : ";
+ char temp[64];
+ RawLeGuidToString_Braced(guid, temp);
+ MyStringLower_Ascii(temp);
+ s += temp;
+ }
+ }
+ if (!s.IsEmpty())
+ prop = s;
+ break;
+ }
+
+ case kpidName:
+ {
+ const Byte *guid = Guids[k_GuidType_Creat];
+ if (!IsEmptyGuid(guid))
+ {
+ char temp[64];
+ RawLeGuidToString_Braced(guid, temp);
+ MyStringLower_Ascii(temp);
+ strcat(temp, ".vdi");
+ prop = temp;
+ }
+ break;
+ }
}
prop.Detach(value);
@@ -207,15 +271,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
}
-static bool IsEmptyGuid(const Byte *data)
-{
- for (unsigned i = 0; i < 16; i++)
- if (data[i] != 0)
- return false;
- return true;
-}
-
-
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback * /* openCallback */)
{
const unsigned kHeaderSize = 512;
@@ -225,45 +280,65 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback * /* openCallbac
if (memcmp(buf + 0x40, k_Signature, sizeof(k_Signature)) != 0)
return S_FALSE;
- UInt32 version = Get32(buf + 0x44);
+ const UInt32 version = Get32(buf + 0x44);
if (version >= 0x20000)
return S_FALSE;
+ if (version < 0x10000)
+ {
+ _unsupported = true;
+ return S_FALSE;
+ }
- UInt32 headerSize = Get32(buf + 0x48);
- if (headerSize < 0x140 || headerSize > 0x1B8)
+ const unsigned kHeaderOffset = 0x48;
+ const unsigned kGuidsOffsets = 0x188;
+ const UInt32 headerSize = Get32(buf + kHeaderOffset);
+ if (headerSize < kGuidsOffsets - kHeaderOffset || headerSize > 0x200 - kHeaderOffset)
return S_FALSE;
_imageType = Get32(buf + 0x4C);
- _dataOffset = Get32(buf + 0x158);
+ // Int32 flags = Get32(buf + 0x50);
+ // Byte Comment[0x100]
- UInt32 tableOffset = Get32(buf + 0x154);
+ const UInt32 tableOffset = Get32(buf + 0x154);
if (tableOffset < 0x200)
return S_FALSE;
+
+ _dataOffset = Get32(buf + 0x158);
+
+ // UInt32 geometry[3];
- UInt32 sectorSize = Get32(buf + 0x168);
+ const UInt32 sectorSize = Get32(buf + 0x168);
if (sectorSize != 0x200)
return S_FALSE;
_size = Get64(buf + 0x170);
+ const UInt32 blockSize = Get32(buf + 0x178);
+ const UInt32 totalBlocks = Get32(buf + 0x180);
+ const UInt32 numAllocatedBlocks = Get32(buf + 0x184);
+
_isArc = true;
- if (_imageType > 2)
- {
- _unsupported = true;
- return S_FALSE;
- }
-
if (_dataOffset < tableOffset)
return S_FALSE;
- UInt32 blockSize = Get32(buf + 0x178);
- if (blockSize != ((UInt32)1 << k_ClusterBits))
+ if (_imageType > 4)
+ _unsupported = true;
+
+ if (blockSize != k_ClusterSize)
{
_unsupported = true;
return S_FALSE;
}
- UInt32 totalBlocks = Get32(buf + 0x180);
+ if (headerSize >= kGuidsOffsets + kNumGuids * 16 - kHeaderOffset)
+ {
+ for (unsigned i = 0; i < kNumGuids; i++)
+ memcpy(Guids[i], buf + kGuidsOffsets + 16 * i, 16);
+
+ if (!IsEmptyGuid(Guids[k_GuidType_Link]) ||
+ !IsEmptyGuid(Guids[k_GuidType_PModif]))
+ _unsupported = true;
+ }
{
UInt64 size2 = (UInt64)totalBlocks << k_ClusterBits;
@@ -278,18 +353,6 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback * /* openCallbac
*/
}
- if (headerSize >= 0x180)
- {
- if (!IsEmptyGuid(buf + 0x1A8) ||
- !IsEmptyGuid(buf + 0x1B8))
- {
- _unsupported = true;
- return S_FALSE;
- }
- }
-
- UInt32 numAllocatedBlocks = Get32(buf + 0x184);
-
{
UInt32 tableReserved = _dataOffset - tableOffset;
if ((tableReserved >> 2) < totalBlocks)
@@ -298,11 +361,11 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback * /* openCallbac
_phySize = _dataOffset + ((UInt64)numAllocatedBlocks << k_ClusterBits);
- size_t numBytes = (size_t)totalBlocks * 4;
+ const size_t numBytes = (size_t)totalBlocks * 4;
if ((numBytes >> 2) != totalBlocks)
{
_unsupported = true;
- return S_FALSE;
+ return E_OUTOFMEMORY;
}
_table.Alloc(numBytes);
@@ -316,7 +379,10 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback * /* openCallbac
if (v == k_UnusedCluster)
continue;
if (v >= numAllocatedBlocks)
+ {
+ _unsupported = true;
return S_FALSE;
+ }
}
Stream = stream;
@@ -332,6 +398,9 @@ STDMETHODIMP CHandler::Close()
_isArc = false;
_unsupported = false;
+ for (unsigned i = 0; i < kNumGuids; i++)
+ memset(Guids[i], 0, 16);
+
_imgExt = NULL;
Stream.Release();
return S_OK;
diff --git a/CPP/7zip/Archive/VhdHandler.cpp b/CPP/7zip/Archive/VhdHandler.cpp
index 12cbfa04..d79ae907 100644
--- a/CPP/7zip/Archive/VhdHandler.cpp
+++ b/CPP/7zip/Archive/VhdHandler.cpp
@@ -5,7 +5,6 @@
#include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h"
-#include "../../Common/IntToString.h"
#include "../../Windows/PropVariant.h"
@@ -69,17 +68,16 @@ struct CFooter
UInt32 NumCyls() const { return DiskGeometry >> 16; }
UInt32 NumHeads() const { return (DiskGeometry >> 8) & 0xFF; }
UInt32 NumSectorsPerTrack() const { return DiskGeometry & 0xFF; }
- AString GetTypeString() const;
+ void AddTypeString(AString &s) const;
bool Parse(const Byte *p);
};
-AString CFooter::GetTypeString() const
+void CFooter::AddTypeString(AString &s) const
{
if (Type < ARRAY_SIZE(kDiskTypes))
- return kDiskTypes[Type];
- char s[16];
- ConvertUInt32ToString(Type, s);
- return s;
+ s += kDiskTypes[Type];
+ else
+ s.Add_UInt32(Type);
}
static bool CheckBlock(const Byte *p, unsigned size, unsigned checkSumOffset, unsigned zeroOffset)
@@ -234,12 +232,15 @@ class CHandler: public CHandlerImg
UString _errorMessage;
// bool _unexpectedEnd;
- void AddErrorMessage(const wchar_t *s)
+ void AddErrorMessage(const char *message, const wchar_t *name = NULL)
{
if (!_errorMessage.IsEmpty())
_errorMessage.Add_LF();
- _errorMessage += s;
+ _errorMessage += message;
+ if (name)
+ _errorMessage += name;
}
+
void UpdatePhySize(UInt64 value)
{
if (_phySize < value)
@@ -262,7 +263,7 @@ class CHandler: public CHandlerImg
while (p && p->NeedParent())
{
if (!res.IsEmpty())
- res.AddAscii(" -> ");
+ res += " -> ";
UString mainName;
UString anotherName;
if (Dyn.RelativeNameWasUsed)
@@ -279,9 +280,9 @@ class CHandler: public CHandlerImg
if (mainName != anotherName && !anotherName.IsEmpty())
{
res.Add_Space();
- res += L'(';
+ res += '(';
res += anotherName;
- res += L')';
+ res += ')';
}
p = p->Parent;
}
@@ -522,7 +523,7 @@ HRESULT CHandler::Open3()
}
_posInArcLimit = _phySize;
_phySize += kHeaderSize;
- AddErrorMessage(L"Can't find footer");
+ AddErrorMessage("Can't find footer");
return S_OK;
}
@@ -679,7 +680,8 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidShortComment:
case kpidMethod:
{
- AString s = Footer.GetTypeString();
+ AString s;
+ Footer.AddTypeString(s);
if (NeedParent())
{
s += " -> ";
@@ -689,7 +691,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (!p)
s += '?';
else
- s += p->Footer.GetTypeString();
+ p->Footer.AddTypeString(s);
}
prop = s;
break;
@@ -698,14 +700,12 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
char s[16];
StringToAString(s, Footer.CreatorApp);
- AString res = s;
+ AString res (s);
res.Trim();
- ConvertUInt32ToString(Footer.CreatorVersion >> 16, s);
res.Add_Space();
- res += s;
+ res.Add_UInt32(Footer.CreatorVersion >> 16);
res += '.';
- ConvertUInt32ToString(Footer.CreatorVersion & 0xFFFF, s);
- res += s;
+ res.Add_UInt32(Footer.CreatorVersion & 0xFFFF);
prop = res;
break;
}
@@ -806,10 +806,7 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
if (res == S_FALSE || !nextStream)
{
- UString s;
- s.SetFromAscii("Missing volume : ");
- s += name;
- AddErrorMessage(s);
+ AddErrorMessage("Missing volume : ", name);
return S_OK;
}
@@ -837,8 +834,7 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
p = p->Parent;
if (!p)
{
- AddErrorMessage(L"Can't open parent VHD file:");
- AddErrorMessage(Dyn.ParentName);
+ AddErrorMessage("Can't open parent VHD file : ", Dyn.ParentName);
break;
}
}
diff --git a/CPP/7zip/Archive/VmdkHandler.cpp b/CPP/7zip/Archive/VmdkHandler.cpp
index 5f93c738..942bd792 100644
--- a/CPP/7zip/Archive/VmdkHandler.cpp
+++ b/CPP/7zip/Archive/VmdkHandler.cpp
@@ -296,10 +296,15 @@ bool CDescriptor::Parse(const Byte *p, size_t size)
AString name;
AString val;
- for (size_t i = 0;; i++)
+ for (;;)
{
- const char c = p[i];
- if (i == size || c == 0 || c == 0xA || c == 0xD)
+ char c = 0;
+ if (size != 0)
+ {
+ size--;
+ c = *p++;
+ }
+ if (c == 0 || c == 0xA || c == 0xD)
{
if (!s.IsEmpty() && s[0] != '#')
{
@@ -322,14 +327,12 @@ bool CDescriptor::Parse(const Byte *p, size_t size)
}
s.Empty();
- if (c == 0 || i >= size)
- break;
+ if (c == 0)
+ return true;
}
else
s += (char)c;
}
-
- return true;
}
@@ -819,9 +822,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
else if (algo != (int)h.algo)
{
s.Add_Space_if_NotEmpty();
- char temp[16];
- ConvertUInt32ToString(h.algo, temp);
- s += temp;
+ s.Add_UInt32(h.algo);
algo = h.algo;
}
}
@@ -831,16 +832,10 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
}
if (zlib)
- {
- s.Add_Space_if_NotEmpty();
- s += "zlib";
- }
+ s.Add_OptSpaced("zlib");
if (marker)
- {
- s.Add_Space_if_NotEmpty();
- s += "Marker";
- }
+ s.Add_OptSpaced("Marker");
if (!s.IsEmpty())
prop = s;
@@ -888,8 +883,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
if (_missingVol || !_missingVolName.IsEmpty())
{
- UString s;
- s.SetFromAscii("Missing volume : ");
+ UString s ("Missing volume : ");
if (!_missingVolName.IsEmpty())
s += _missingVolName;
prop = s;
@@ -983,6 +977,9 @@ void CHandler::CloseAtError()
}
+static const char * const kSignature_Descriptor = "# Disk DescriptorFile";
+
+
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
{
const unsigned kSectoreSize = 512;
@@ -997,7 +994,6 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
if (memcmp(buf, k_Signature, sizeof(k_Signature)) != 0)
{
- const char *kSignature_Descriptor = "# Disk DescriptorFile";
const size_t k_SigDesc_Size = strlen(kSignature_Descriptor);
if (headerSize < k_SigDesc_Size)
return S_FALSE;
diff --git a/CPP/7zip/Archive/Wim/WimHandler.cpp b/CPP/7zip/Archive/Wim/WimHandler.cpp
index 234780dd..927a0b38 100644
--- a/CPP/7zip/Archive/Wim/WimHandler.cpp
+++ b/CPP/7zip/Archive/Wim/WimHandler.cpp
@@ -94,15 +94,6 @@ static void AddErrorMessage(AString &s, const char *message)
s += message;
}
-static void ConvertByteToHex(unsigned value, char *s)
-{
- for (int i = 0; i < 2; i++)
- {
- unsigned t = value & 0xF;
- value >>= 4;
- s[1 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
- }
-}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
@@ -177,17 +168,14 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
UInt32 ver2 = (_version >> 8) & 0xFF;
UInt32 ver3 = (_version) & 0xFF;
- char s[16];
- ConvertUInt32ToString(ver1, s);
- AString res = s;
+ AString res;
+ res.Add_UInt32(ver1);
res += '.';
- ConvertUInt32ToString(ver2, s);
- res += s;
+ res.Add_UInt32(ver2);
if (ver3 != 0)
{
res += '.';
- ConvertUInt32ToString(ver3, s);
- res += s;
+ res.Add_UInt32(ver3);
}
prop = res;
break;
@@ -229,22 +217,16 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
const CHeader &h = _volumes[_firstVolumeIndex].Header;
if (GetUi32(h.Guid) != 0)
{
- char temp[16 * 2 + 4];
- int i;
- for (i = 0; i < 4; i++)
- ConvertByteToHex(h.Guid[i], temp + i * 2);
- temp[i * 2] = 0;
- AString s = temp;
+ char temp[64];
+ RawLeGuidToString(h.Guid, temp);
+ temp[8] = 0; // for reduced GUID
+ AString s (temp);
const char *ext = ".wim";
if (h.NumParts != 1)
{
s += '_';
if (h.PartNumber != 1)
- {
- char sz[16];
- ConvertUInt32ToString(h.PartNumber, sz);
- s += sz;
- }
+ s.Add_UInt32(h.PartNumber);
ext = ".swm";
}
s += ext;
@@ -262,9 +244,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
AString s;
if (h.PartNumber != 1)
{
- char sz[16];
- ConvertUInt32ToString(h.PartNumber, sz);
- s = sz;
+ s.Add_UInt32(h.PartNumber);
s += '.';
}
s += "swm";
@@ -312,19 +292,15 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (methodUnknown != 0)
{
- char temp[32];
- ConvertUInt32ToString(methodUnknown, temp);
res.Add_Space_if_NotEmpty();
- res += temp;
+ res.Add_UInt32(methodUnknown);
numMethods++;
}
if (numMethods == 1 && chunkSizeBits != 0)
{
- char temp[32];
- temp[0] = ':';
- ConvertUInt32ToString((UInt32)chunkSizeBits, temp + 1);
- res += temp;
+ res += ':';
+ res.Add_UInt32((UInt32)chunkSizeBits);
}
prop = res;
@@ -391,7 +367,7 @@ static void MethodToProp(int method, int chunksSizeBits, NCOM::CPropVariant &pro
if ((unsigned)method < ARRAY_SIZE(k_Methods))
strcpy(temp, k_Methods[(unsigned)method]);
else
- ConvertUInt32ToString((unsigned)method, temp);
+ ConvertUInt32ToString((UInt32)(unsigned)method, temp);
if (chunksSizeBits >= 0)
{
@@ -436,9 +412,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
_db.GetItemPath(realIndex, _showImageNumber, prop);
else
{
- char sz[16];
- ConvertUInt32ToString(item.StreamIndex, sz);
- AString s = sz;
/*
while (s.Len() < _nameLenForStreams)
s = '0' + s;
@@ -448,7 +421,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
s = (AString)("[Free]" STRING_PATH_SEPARATOR) + sz;
else
*/
- s = (AString)(FILES_DIR_NAME STRING_PATH_SEPARATOR) + sz;
+ AString s (FILES_DIR_NAME STRING_PATH_SEPARATOR);
+ s.Add_UInt32(item.StreamIndex);
prop = s;
}
break;
@@ -874,9 +848,10 @@ public:
UString GetNextName(UInt32 index) const
{
- wchar_t s[16];
- ConvertUInt32ToString(index, s);
- return _before + (UString)s + _after;
+ UString s = _before;
+ s.Add_UInt32(index);
+ s += _after;
+ return s;
}
};
@@ -970,11 +945,9 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCal
if (_xmls.IsEmpty() || xml.Data != _xmls[0].Data)
{
- char sz[16];
- ConvertUInt32ToString(xml.VolIndex, sz);
- xml.FileName = L'[';
- xml.FileName.AddAscii(sz);
- xml.FileName.AddAscii("].xml");
+ xml.FileName = '[';
+ xml.FileName.Add_UInt32(xml.VolIndex);
+ xml.FileName += "].xml";
_xmls.Add(xml);
}
diff --git a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
index 1d198df0..99fd46ef 100644
--- a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
+++ b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
@@ -1828,7 +1828,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu
curPos += kStreamInfoSize;
}
- AString xml = "<WIM>";
+ AString xml ("<WIM>");
AddTagUInt64_ToString(xml, "TOTALBYTES", curPos);
for (i = 0; i < trees.Size(); i++)
{
diff --git a/CPP/7zip/Archive/Wim/WimIn.cpp b/CPP/7zip/Archive/Wim/WimIn.cpp
index f35c2d50..b934478e 100644
--- a/CPP/7zip/Archive/Wim/WimIn.cpp
+++ b/CPP/7zip/Archive/Wim/WimIn.cpp
@@ -442,7 +442,7 @@ static inline void ParseStream(bool oldVersion, const Byte *p, CStreamInfo &s)
}
-static const char *kLongPath = "[LongPath]";
+#define kLongPath "[LongPath]"
void CDatabase::GetShortName(unsigned index, NWindows::NCOM::CPropVariant &name) const
{
diff --git a/CPP/7zip/Archive/Wim/WimRegister.cpp b/CPP/7zip/Archive/Wim/WimRegister.cpp
index 6ad28acc..ecebe8d9 100644
--- a/CPP/7zip/Archive/Wim/WimRegister.cpp
+++ b/CPP/7zip/Archive/Wim/WimRegister.cpp
@@ -10,7 +10,7 @@ namespace NArchive {
namespace NWim {
REGISTER_ARC_IO(
- "wim", "wim swm esd", 0, 0xE6,
+ "wim", "wim swm esd ppkg", 0, 0xE6,
kSignature,
0,
NArcInfoFlags::kAltStreams |
diff --git a/CPP/7zip/Archive/XarHandler.cpp b/CPP/7zip/Archive/XarHandler.cpp
index 96386809..f20b1eb9 100644
--- a/CPP/7zip/Archive/XarHandler.cpp
+++ b/CPP/7zip/Archive/XarHandler.cpp
@@ -153,7 +153,7 @@ IMP_IInArchive_ArcProps
static bool ParseUInt64(const CXmlItem &item, const char *name, UInt64 &res)
{
- const AString s = item.GetSubStringForTag(name);
+ const AString s (item.GetSubStringForTag(name));
if (s.IsEmpty())
return false;
const char *end;
@@ -163,7 +163,7 @@ static bool ParseUInt64(const CXmlItem &item, const char *name, UInt64 &res)
static UInt64 ParseTime(const CXmlItem &item, const char *name)
{
- const AString s = item.GetSubStringForTag(name);
+ const AString s (item.GetSubStringForTag(name));
if (s.Len() < 20)
return 0;
const char *p = s;
@@ -198,10 +198,10 @@ static bool ParseSha1(const CXmlItem &item, const char *name, Byte *digest)
if (index < 0)
return false;
const CXmlItem &checkItem = item.SubItems[index];
- const AString style = checkItem.GetPropVal("style");
+ const AString style (checkItem.GetPropVal("style"));
if (style == "SHA1")
{
- const AString s = checkItem.GetSubString();
+ const AString s (checkItem.GetSubString());
if (s.Len() != SHA1_DIGEST_SIZE * 2)
return false;
for (unsigned i = 0; i < s.Len(); i += 2)
@@ -227,7 +227,7 @@ static bool AddItem(const CXmlItem &item, CObjectVector<CFile> &files, int paren
file.Parent = parent;
parent = files.Size();
file.Name = item.GetSubStringForTag("name");
- AString type = item.GetSubStringForTag("type");
+ const AString type (item.GetSubStringForTag("type"));
if (type == "directory")
file.IsDir = true;
else if (type == "file")
@@ -254,14 +254,14 @@ static bool AddItem(const CXmlItem &item, CObjectVector<CFile> &files, int paren
const CXmlItem &encodingItem = dataItem.SubItems[encodingIndex];
if (encodingItem.IsTag)
{
- AString s = encodingItem.GetPropVal("style");
+ AString s (encodingItem.GetPropVal("style"));
if (!s.IsEmpty())
{
- const AString appl = "application/";
+ const AString appl ("application/");
if (s.IsPrefixedBy(appl))
{
s.DeleteFrontal(appl.Len());
- const AString xx = "x-";
+ const AString xx ("x-");
if (s.IsPrefixedBy(xx))
{
s.DeleteFrontal(xx.Len());
@@ -280,7 +280,7 @@ static bool AddItem(const CXmlItem &item, CObjectVector<CFile> &files, int paren
file.ATime = ParseTime(item, "atime");
{
- const AString s = item.GetSubStringForTag("mode");
+ const AString s (item.GetSubStringForTag("mode"));
if (s[0] == '0')
{
const char *end;
diff --git a/CPP/7zip/Archive/XzHandler.cpp b/CPP/7zip/Archive/XzHandler.cpp
index 318be190..fd90c88d 100644
--- a/CPP/7zip/Archive/XzHandler.cpp
+++ b/CPP/7zip/Archive/XzHandler.cpp
@@ -3,8 +3,6 @@
#include "StdAfx.h"
#include "../../../C/Alloc.h"
-#include "../../../C/XzCrc64.h"
-#include "../../../C/XzEnc.h"
#include "../../Common/ComTry.h"
#include "../../Common/Defs.h"
@@ -12,14 +10,14 @@
#include "../../Windows/PropVariant.h"
-#include "../ICoder.h"
-
#include "../Common/CWrappers.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "../Compress/CopyCoder.h"
+#include "../Compress/XzDecoder.h"
+#include "../Compress/XzEncoder.h"
#include "IArchive.h"
@@ -27,46 +25,13 @@
#include "Common/HandlerOut.h"
#endif
-#include "XzHandler.h"
-
using namespace NWindows;
-namespace NCompress {
-namespace NLzma2 {
-
-HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props);
-
-}}
-
namespace NArchive {
namespace NXz {
-struct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit;
-
-static const char *k_LZMA2_Name = "LZMA2";
+#define 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,
@@ -78,7 +43,7 @@ class CHandler:
#endif
public CMyUnknownImp
{
- CStatInfo _stat;
+ NCompress::NXz::CStatInfo _stat;
bool _isArc;
bool _needSeekToStart;
@@ -104,9 +69,12 @@ class CHandler:
HRESULT Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback);
HRESULT Decode2(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
- CDecoder &decoder, ICompressProgressInfo *progress)
+ NCompress::NXz::CDecoder &decoder, ICompressProgressInfo *progress)
{
- RINOK(decoder.Decode(seqInStream, outStream, progress));
+ RINOK(decoder.Decode(seqInStream, outStream,
+ NULL, // *outSizeLimit
+ true, // finishStream
+ progress));
_stat = decoder;
_phySize_Defined = true;
return S_OK;
@@ -169,13 +137,6 @@ static inline void AddHexToString(AString &s, Byte value)
s += GetHex(value & 0xF);
}
-static void AddUInt32ToString(AString &s, UInt32 value)
-{
- char temp[16];
- ConvertUInt32ToString(value, temp);
- s += temp;
-}
-
static void Lzma2PropToString(AString &s, unsigned prop)
{
char c = 0;
@@ -192,7 +153,7 @@ static void Lzma2PropToString(AString &s, unsigned prop)
c = 'm';
}
}
- AddUInt32ToString(s, size);
+ s.Add_UInt32(size);
if (c != 0)
s += c;
}
@@ -232,7 +193,7 @@ static AString GetMethodString(const CXzFilter &f)
p = temp;
}
- AString s = p;
+ AString s (p);
if (f.propsSize > 0)
{
@@ -240,7 +201,7 @@ static AString GetMethodString(const CXzFilter &f)
if (f.id == XZ_ID_LZMA2 && f.propsSize == 1)
Lzma2PropToString(s, f.props[0]);
else if (f.id == XZ_ID_Delta && f.propsSize == 1)
- AddUInt32ToString(s, (UInt32)f.props[0] + 1);
+ s.Add_UInt32((UInt32)f.props[0] + 1);
else
{
s += '[';
@@ -294,7 +255,7 @@ static AString GetCheckString(const CXzs &xzs)
else
{
s2 = "Check-";
- AddUInt32ToString(s2, (UInt32)i);
+ s2.Add_UInt32((UInt32)i);
}
AddString(s, s2);
}
@@ -354,27 +315,28 @@ STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)
struct COpenCallbackWrap
{
- ICompressProgress p;
+ ICompressProgress vt;
IArchiveOpenCallback *OpenCallback;
HRESULT Res;
COpenCallbackWrap(IArchiveOpenCallback *progress);
};
-static SRes OpenCallbackProgress(void *pp, UInt64 inSize, UInt64 /* outSize */)
+static SRes OpenCallbackProgress(const ICompressProgress *pp, UInt64 inSize, UInt64 /* outSize */)
{
- COpenCallbackWrap *p = (COpenCallbackWrap *)pp;
+ COpenCallbackWrap *p = CONTAINER_FROM_VTBL(pp, COpenCallbackWrap, vt);
if (p->OpenCallback)
p->Res = p->OpenCallback->SetCompleted(NULL, &inSize);
- return (SRes)p->Res;
+ return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS);
}
COpenCallbackWrap::COpenCallbackWrap(IArchiveOpenCallback *callback)
{
- p.Progress = OpenCallbackProgress;
+ vt.Progress = OpenCallbackProgress;
OpenCallback = callback;
Res = SZ_OK;
}
+
struct CXzsCPP
{
CXzs p;
@@ -382,6 +344,30 @@ struct CXzsCPP
~CXzsCPP() { Xzs_Free(&p, &g_Alloc); }
};
+#define kInputBufSize ((size_t)1 << 10)
+
+struct CLookToRead2_CPP: public CLookToRead2
+{
+ CLookToRead2_CPP()
+ {
+ buf = NULL;
+ LookToRead2_CreateVTable(this,
+ True // Lookahead ?
+ );
+ }
+ void Alloc(size_t allocSize)
+ {
+ buf = (Byte *)MyAlloc(allocSize);
+ if (buf)
+ this->bufSize = allocSize;
+ }
+ ~CLookToRead2_CPP()
+ {
+ MyFree(buf);
+ }
+};
+
+
static HRESULT SRes_to_Open_HRESULT(SRes res)
{
switch (res)
@@ -401,14 +387,18 @@ static HRESULT SRes_to_Open_HRESULT(SRes res)
return S_FALSE;
}
+
+
HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback)
{
_needSeekToStart = true;
{
CXzStreamFlags st;
- CSeqInStreamWrap inStreamWrap(inStream);
- SRes res = Xz_ReadHeader(&st, &inStreamWrap.p);
+ CSeqInStreamWrap inStreamWrap;
+
+ inStreamWrap.Init(inStream);
+ SRes res = Xz_ReadHeader(&st, &inStreamWrap.vt);
if (res != SZ_OK)
return SRes_to_Open_HRESULT(res);
@@ -416,7 +406,7 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
CXzBlock block;
Bool isIndex;
UInt32 headerSizeRes;
- SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.p, &isIndex, &headerSizeRes);
+ SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.vt, &isIndex, &headerSizeRes);
if (res2 == SZ_OK && !isIndex)
{
unsigned numFilters = XzBlock_GetNumFilters(&block);
@@ -432,18 +422,25 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
RINOK(callback->SetTotal(NULL, &_stat.PhySize));
}
- CSeekInStreamWrap inStreamImp(inStream);
+ CSeekInStreamWrap inStreamImp;;
+
+ inStreamImp.Init(inStream);
+
+ CLookToRead2_CPP lookStream;
+
+ lookStream.Alloc(kInputBufSize);
+
+ if (!lookStream.buf)
+ return E_OUTOFMEMORY;
- CLookToRead lookStream;
- LookToRead_CreateVTable(&lookStream, True);
- lookStream.realStream = &inStreamImp.p;
- LookToRead_Init(&lookStream);
+ lookStream.realStream = &inStreamImp.vt;
+ LookToRead2_Init(&lookStream);
COpenCallbackWrap openWrap(callback);
CXzsCPP xzs;
Int64 startPosition;
- SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.s, &startPosition, &openWrap.p, &g_Alloc);
+ SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.vt, &startPosition, &openWrap.vt, &g_Alloc);
if (res == SZ_ERROR_PROGRESS)
return (openWrap.Res == S_OK) ? E_FAIL : openWrap.Res;
/*
@@ -511,6 +508,8 @@ STDMETHODIMP CHandler::Close()
return S_OK;
}
+
+
class CSeekToSeqStream:
public IInStream,
public CMyUnknownImp
@@ -530,169 +529,12 @@ STDMETHODIMP CSeekToSeqStream::Read(void *data, UInt32 size, UInt32 *processedSi
STDMETHODIMP CSeekToSeqStream::Seek(Int64, UInt32, UInt64 *) { return E_NOTIMPL; }
-CXzUnpackerCPP::CXzUnpackerCPP(): InBuf(0), OutBuf(0)
-{
- XzUnpacker_Construct(&p, &g_Alloc);
-}
-
-CXzUnpackerCPP::~CXzUnpackerCPP()
-{
- XzUnpacker_Free(&p);
- MyFree(InBuf);
- MyFree(OutBuf);
-}
-
-HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
-{
- const size_t kInBufSize = 1 << 15;
- const size_t kOutBufSize = 1 << 21;
-
- Clear();
- DecodeRes = SZ_OK;
-
- XzUnpacker_Init(&xzu.p);
- if (!xzu.InBuf)
- xzu.InBuf = (Byte *)MyAlloc(kInBufSize);
- if (!xzu.OutBuf)
- xzu.OutBuf = (Byte *)MyAlloc(kOutBufSize);
-
- UInt32 inSize = 0;
- SizeT inPos = 0;
- SizeT outPos = 0;
-
- for (;;)
- {
- if (inPos == inSize)
- {
- inPos = inSize = 0;
- RINOK(seqInStream->Read(xzu.InBuf, kInBufSize, &inSize));
- }
-
- SizeT inLen = inSize - inPos;
- SizeT outLen = kOutBufSize - outPos;
- ECoderStatus status;
-
- SRes res = XzUnpacker_Code(&xzu.p,
- xzu.OutBuf + outPos, &outLen,
- xzu.InBuf + inPos, &inLen,
- (inSize == 0 ? CODER_FINISH_END : CODER_FINISH_ANY), &status);
- inPos += inLen;
- outPos += outLen;
- InSize += inLen;
- OutSize += outLen;
- DecodeRes = res;
- bool finished = ((inLen == 0 && outLen == 0) || res != SZ_OK);
- if (outStream)
- {
- if (outPos == kOutBufSize || finished)
- {
- if (outPos != 0)
- {
- RINOK(WriteStream(outStream, xzu.OutBuf, outPos));
- outPos = 0;
- }
- }
- }
- else
- outPos = 0;
-
- if (progress)
- {
- RINOK(progress->SetRatioInfo(&InSize, &OutSize));
- }
-
- if (finished)
- {
- PhySize = InSize;
- NumStreams = xzu.p.numStartedStreams;
- if (NumStreams > 0)
- IsArc = true;
- NumBlocks = xzu.p.numTotalBlocks;
- UnpackSize_Defined = true;
- NumStreams_Defined = true;
- NumBlocks_Defined = true;
-
- UInt64 extraSize = XzUnpacker_GetExtraSize(&xzu.p);
-
- if (res == SZ_OK)
- {
- if (status == CODER_STATUS_NEEDS_MORE_INPUT)
- {
- extraSize = 0;
- if (!XzUnpacker_IsStreamWasFinished(&xzu.p))
- {
- // finished at padding bytes, but padding is not aligned for 4
- UnexpectedEnd = true;
- res = SZ_ERROR_DATA;
- }
- }
- else // status == CODER_STATUS_NOT_FINISHED
- res = SZ_ERROR_DATA;
- }
- else if (res == SZ_ERROR_NO_ARCHIVE)
- {
- if (InSize == extraSize)
- IsArc = false;
- else
- {
- if (extraSize != 0 || inPos != inSize)
- {
- DataAfterEnd = true;
- res = SZ_OK;
- }
- }
- }
-
- 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;
- 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)
@@ -733,7 +575,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
else
_needSeekToStart = true;
- CDecoder decoder;
+ NCompress::NXz::CDecoder decoder;
RINOK(Decode2(_seqStream, realOutStream, decoder, lpsRef));
Int32 opRes = decoder.Get_Extract_OperationResult();
@@ -755,11 +597,13 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
COM_TRY_BEGIN
- CSeqOutStreamWrap seqOutStream(outStream);
if (numItems == 0)
{
- SRes res = Xz_EncodeEmpty(&seqOutStream.p);
+ CSeqOutStreamWrap seqOutStream;
+
+ seqOutStream.Init(outStream);
+ SRes res = Xz_EncodeEmpty(&seqOutStream.vt);
return SResToHRESULT(res);
}
@@ -795,34 +639,36 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
RINOK(updateCallback->SetTotal(size));
}
- CLzma2EncProps lzma2Props;
- Lzma2EncProps_Init(&lzma2Props);
+ NCompress::NXz::CEncoder *encoderSpec = new NCompress::NXz::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
+ CLzma2EncProps &lzma2Props = encoderSpec->_lzma2Props;
lzma2Props.lzmaProps.level = GetLevel();
CMyComPtr<ISequentialInStream> fileInStream;
RINOK(updateCallback->GetStream(0, &fileInStream));
- CSeqInStreamWrap seqInStream(fileInStream);
-
{
NCOM::CPropVariant prop = (UInt64)size;
- RINOK(NCompress::NLzma2::SetLzma2Prop(NCoderPropID::kReduceSize, prop, lzma2Props));
+ RINOK(encoderSpec->SetCoderProp(NCoderPropID::kReduceSize, prop));
}
FOR_VECTOR (i, _methods)
{
COneMethodInfo &m = _methods[i];
- SetGlobalLevelAndThreads(m
+
+ /*
+ SetGlobalLevelTo(m);
#ifndef _7ZIP_ST
- , _numThreads
+ CMultiMethodProps::SetMethodThreads(m, _numThreads);
#endif
- );
+ */
+
{
FOR_VECTOR (j, m.Props)
{
const CProp &prop = m.Props[j];
- RINOK(NCompress::NLzma2::SetLzma2Prop(prop.Id, prop.Value, lzma2Props));
+ RINOK(encoderSpec->SetCoderProp(prop.Id, prop.Value));
}
}
}
@@ -835,11 +681,12 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
- CCompressProgressWrap progressWrap(progress);
- CXzProps xzProps;
- CXzFilterProps filter;
+ CXzProps &xzProps = encoderSpec->xzProps;
+ CXzFilterProps &filter = encoderSpec->filter;
+
XzProps_Init(&xzProps);
XzFilterProps_Init(&filter);
+
xzProps.lzma2Props = &lzma2Props;
xzProps.filterProps = (_filterId != 0 ? &filter : NULL);
switch (_crcSize)
@@ -869,10 +716,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (!deltaDefined)
return E_INVALIDARG;
}
- SRes res = Xz_Encode(&seqOutStream.p, &seqInStream.p, &xzProps, &progressWrap.p);
- if (res == SZ_OK)
- return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
- return SResToHRESULT(res);
+
+ return encoderSpec->Code(fileInStream, outStream, NULL, NULL, progress);
}
if (indexInArchive != 0)
@@ -901,6 +746,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
COM_TRY_END
}
+
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
COM_TRY_BEGIN
diff --git a/CPP/7zip/Archive/XzHandler.h b/CPP/7zip/Archive/XzHandler.h
index 4a59e356..24e8eeb4 100644
--- a/CPP/7zip/Archive/XzHandler.h
+++ b/CPP/7zip/Archive/XzHandler.h
@@ -3,63 +3,9 @@
#ifndef __XZ_HANDLER_H
#define __XZ_HANDLER_H
-#include "../../../C/Xz.h"
-
-#include "../ICoder.h"
-
namespace NArchive {
namespace NXz {
-struct CXzUnpackerCPP
-{
- Byte *InBuf;
- Byte *OutBuf;
- CXzUnpacker p;
-
- CXzUnpackerCPP();
- ~CXzUnpackerCPP();
-};
-
-struct CStatInfo
-{
- UInt64 InSize;
- UInt64 OutSize;
- UInt64 PhySize;
-
- UInt64 NumStreams;
- UInt64 NumBlocks;
-
- bool UnpackSize_Defined;
-
- bool NumStreams_Defined;
- bool NumBlocks_Defined;
-
- bool IsArc;
- bool UnexpectedEnd;
- bool DataAfterEnd;
- bool Unsupported;
- bool HeadersError;
- bool DataError;
- bool CrcError;
-
- CStatInfo() { Clear(); }
-
- void Clear();
-};
-
-struct CDecoder: public CStatInfo
-{
- CXzUnpackerCPP xzu;
- SRes DecodeRes; // it's not HRESULT
-
- CDecoder(): DecodeRes(SZ_OK) {}
-
- /* Decode() can return ERROR code only if there is progress or stream error.
- Decode() returns S_OK in case of xz decoding error, but DecodeRes and CStatInfo contain error information */
- HRESULT Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, ICompressProgressInfo *compressProgress);
- Int32 Get_Extract_OperationResult() const;
-};
-
}}
#endif
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
index 06fbe22f..dd83f87f 100644
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
@@ -17,6 +17,7 @@
#include "../../Compress/LzmaEncoder.h"
#include "../../Compress/PpmdZip.h"
+#include "../../Compress/XzEncoder.h"
#include "../Common/InStreamWithCRC.h"
@@ -26,8 +27,8 @@
namespace NArchive {
namespace NZip {
-static const CMethodId kMethodId_ZipBase = 0x040100;
-static const CMethodId kMethodId_BZip2 = 0x040202;
+using namespace NFileHeader;
+
static const UInt32 kLzmaPropsSize = 5;
static const UInt32 kLzmaHeaderSize = 4 + kLzmaPropsSize;
@@ -37,10 +38,11 @@ class CLzmaEncoder:
public ICompressSetCoderProperties,
public CMyUnknownImp
{
+public:
NCompress::NLzma::CEncoder *EncoderSpec;
CMyComPtr<ICompressCoder> Encoder;
Byte Header[kLzmaHeaderSize];
-public:
+
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
@@ -81,7 +83,8 @@ CAddCommon::CAddCommon(const CCompressionMethodMode &options):
_options(options),
_copyCoderSpec(NULL),
_cryptoStreamSpec(NULL),
- _buf(NULL)
+ _buf(NULL),
+ _isLzmaEos(false)
{}
CAddCommon::~CAddCommon()
@@ -114,49 +117,100 @@ HRESULT CAddCommon::CalcStreamCRC(ISequentialInStream *inStream, UInt32 &resultC
}
}
+
+HRESULT CAddCommon::Set_Pre_CompressionResult(bool seqMode, UInt64 unpackSize, CCompressingResult &opRes) const
+{
+ // We use Zip64, if unPackSize size is larger than 0xF8000000 to support
+ // cases when compressed size can be about 3% larger than uncompressed size
+
+ const UInt32 kUnpackZip64Limit = 0xF8000000;
+
+ opRes.UnpackSize = unpackSize;
+ opRes.PackSize = (UInt64)1 << 60; // we use big value to force Zip64 mode.
+
+ if (unpackSize < kUnpackZip64Limit)
+ opRes.PackSize = (UInt32)0xFFFFFFFF - 1; // it will not use Zip64 for that size
+
+ if (opRes.PackSize < unpackSize)
+ opRes.PackSize = unpackSize;
+
+ Byte method = _options.MethodSequence[0];
+
+ if (method == NCompressionMethod::kStore && !_options.PasswordIsDefined)
+ opRes.PackSize = unpackSize;
+
+ opRes.CRC = 0;
+
+ opRes.LzmaEos = false;
+
+ opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default;
+ opRes.FileTimeWasUsed = false;
+
+ if (_options.PasswordIsDefined)
+ {
+ opRes.ExtractVersion = NCompressionMethod::kExtractVersion_ZipCrypto;
+ if (_options.IsAesMode)
+ opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Aes;
+ else
+ {
+ if (seqMode)
+ opRes.FileTimeWasUsed = true;
+ }
+ }
+
+ opRes.Method = method;
+ Byte ver = 0;
+
+ switch (method)
+ {
+ case NCompressionMethod::kStore: break;
+ case NCompressionMethod::kDeflate: ver = NCompressionMethod::kExtractVersion_Deflate; break;
+ case NCompressionMethod::kDeflate64: ver = NCompressionMethod::kExtractVersion_Deflate64; break;
+ case NCompressionMethod::kXz : ver = NCompressionMethod::kExtractVersion_Xz; break;
+ case NCompressionMethod::kPPMd : ver = NCompressionMethod::kExtractVersion_PPMd; break;
+ case NCompressionMethod::kBZip2: ver = NCompressionMethod::kExtractVersion_BZip2; break;
+ case NCompressionMethod::kLZMA :
+ {
+ ver = NCompressionMethod::kExtractVersion_LZMA;
+ const COneMethodInfo *oneMethodMain = &_options._methods[0];
+ opRes.LzmaEos = oneMethodMain->Get_Lzma_Eos();
+ break;
+ }
+ }
+ if (opRes.ExtractVersion < ver)
+ opRes.ExtractVersion = ver;
+
+ return S_OK;
+}
+
+
HRESULT CAddCommon::Compress(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream, IOutStream *outStream,
- UInt32 /* fileTime */,
+ bool seqMode, UInt32 fileTime,
ICompressProgressInfo *progress, CCompressingResult &opRes)
{
+ opRes.LzmaEos = false;
+
if (!inStream)
{
// We can create empty stream here. But it was already implemented in caller code in 9.33+
return E_INVALIDARG;
}
- // CSequentialInStreamWithCRC *inSecCrcStreamSpec = NULL;
- CInStreamWithCRC *inCrcStreamSpec = NULL;
- CMyComPtr<ISequentialInStream> inCrcStream;
- {
- CMyComPtr<IInStream> inStream2;
-
+ CSequentialInStreamWithCRC *inSecCrcStreamSpec = new CSequentialInStreamWithCRC;
+ CMyComPtr<ISequentialInStream> inCrcStream = inSecCrcStreamSpec;
+
+ CMyComPtr<IInStream> inStream2;
+ if (!seqMode)
inStream->QueryInterface(IID_IInStream, (void **)&inStream2);
- if (inStream2)
- {
- inCrcStreamSpec = new CInStreamWithCRC;
- inCrcStream = inCrcStreamSpec;
- inCrcStreamSpec->SetStream(inStream2);
- inCrcStreamSpec->Init();
- }
- else
- {
- // we don't support stdin, since stream from stdin can require 64-bit size header
- return E_NOTIMPL;
- /*
- inSecCrcStreamSpec = new CSequentialInStreamWithCRC;
- inCrcStream = inSecCrcStreamSpec;
- inSecCrcStreamSpec->SetStream(inStream);
- inSecCrcStreamSpec->Init();
- */
- }
- }
+ inSecCrcStreamSpec->SetStream(inStream);
+ inSecCrcStreamSpec->Init();
unsigned numTestMethods = _options.MethodSequence.Size();
- if (numTestMethods > 1 && !inCrcStreamSpec)
+ if (seqMode || (numTestMethods > 1 && !inStream2))
numTestMethods = 1;
UInt32 crc = 0;
@@ -164,20 +218,24 @@ HRESULT CAddCommon::Compress(
Byte method = 0;
CFilterCoder::C_OutStream_Releaser outStreamReleaser;
- opRes.ExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_Default;
+ opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default;
opRes.FileTimeWasUsed = false;
for (unsigned i = 0; i < numTestMethods; i++)
{
- opRes.ExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_Default;
- if (inCrcStreamSpec)
- RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL));
+ opRes.LzmaEos = false;
+ opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default;
+ if (inStream2 && i != 0)
+ {
+ inSecCrcStreamSpec->Init();
+ RINOK(inStream2->Seek(0, STREAM_SEEK_SET, NULL));
+ }
RINOK(outStream->SetSize(0));
RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL));
if (_options.PasswordIsDefined)
{
- opRes.ExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_ZipCrypto;
+ opRes.ExtractVersion = NCompressionMethod::kExtractVersion_ZipCrypto;
if (!_cryptoStream)
{
@@ -187,7 +245,7 @@ HRESULT CAddCommon::Compress(
if (_options.IsAesMode)
{
- opRes.ExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_Aes;
+ opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Aes;
if (!_cryptoStreamSpec->Filter)
{
_cryptoStreamSpec->Filter = _filterAesSpec = new NCrypto::NWzAes::CEncoder;
@@ -206,23 +264,22 @@ HRESULT CAddCommon::Compress(
UInt32 check;
- // if (inCrcStreamSpec)
+ if (inStream2)
{
if (!crc_IsCalculated)
{
RINOK(CalcStreamCRC(inStream, crc));
crc_IsCalculated = true;
- RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(inStream2->Seek(0, STREAM_SEEK_SET, NULL));
+ inSecCrcStreamSpec->Init();
}
check = (crc >> 16);
}
- /*
else
{
opRes.FileTimeWasUsed = true;
check = (fileTime & 0xFFFF);
}
- */
RINOK(_filterSpec->WriteHeader_Check16(outStream, (UInt16)check));
}
@@ -236,7 +293,7 @@ HRESULT CAddCommon::Compress(
switch (method)
{
- case NFileHeader::NCompressionMethod::kStored:
+ case NCompressionMethod::kStore:
{
if (_copyCoderSpec == NULL)
{
@@ -256,15 +313,22 @@ HRESULT CAddCommon::Compress(
{
if (!_compressEncoder)
{
- if (method == NFileHeader::NCompressionMethod::kLZMA)
+ CLzmaEncoder *_lzmaEncoder = NULL;
+ if (method == NCompressionMethod::kLZMA)
{
- _compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_LZMA;
- CLzmaEncoder *_lzmaEncoder = new CLzmaEncoder();
+ _compressExtractVersion = NCompressionMethod::kExtractVersion_LZMA;
+ _lzmaEncoder = new CLzmaEncoder();
_compressEncoder = _lzmaEncoder;
}
- else if (method == NFileHeader::NCompressionMethod::kPPMd)
+ else if (method == NCompressionMethod::kXz)
+ {
+ _compressExtractVersion = NCompressionMethod::kExtractVersion_Xz;
+ NCompress::NXz::CEncoder *encoder = new NCompress::NXz::CEncoder();
+ _compressEncoder = encoder;
+ }
+ else if (method == NCompressionMethod::kPPMd)
{
- _compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_PPMd;
+ _compressExtractVersion = NCompressionMethod::kExtractVersion_PPMd;
NCompress::NPpmdZip::CEncoder *encoder = new NCompress::NPpmdZip::CEncoder();
_compressEncoder = encoder;
}
@@ -273,14 +337,14 @@ HRESULT CAddCommon::Compress(
CMethodId methodId;
switch (method)
{
- case NFileHeader::NCompressionMethod::kBZip2:
+ case NCompressionMethod::kBZip2:
methodId = kMethodId_BZip2;
- _compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_BZip2;
+ _compressExtractVersion = NCompressionMethod::kExtractVersion_BZip2;
break;
default:
- _compressExtractVersion = ((method == NFileHeader::NCompressionMethod::kDeflated64) ?
- NFileHeader::NCompressionMethod::kExtractVersion_Deflate64 :
- NFileHeader::NCompressionMethod::kExtractVersion_Deflate);
+ _compressExtractVersion = ((method == NCompressionMethod::kDeflate64) ?
+ NCompressionMethod::kExtractVersion_Deflate64 :
+ NCompressionMethod::kExtractVersion_Deflate);
methodId = kMethodId_ZipBase + method;
break;
}
@@ -290,11 +354,11 @@ HRESULT CAddCommon::Compress(
if (!_compressEncoder)
return E_NOTIMPL;
- if (method == NFileHeader::NCompressionMethod::kDeflated ||
- method == NFileHeader::NCompressionMethod::kDeflated64)
+ if (method == NCompressionMethod::kDeflate ||
+ method == NCompressionMethod::kDeflate64)
{
}
- else if (method == NFileHeader::NCompressionMethod::kBZip2)
+ else if (method == NCompressionMethod::kBZip2)
{
}
}
@@ -303,11 +367,22 @@ HRESULT CAddCommon::Compress(
_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProps);
if (setCoderProps)
{
- RINOK(_options.MethodInfo.SetCoderProps(setCoderProps,
- _options._dataSizeReduceDefined ? &_options._dataSizeReduce : NULL));
+ if (!_options._methods.IsEmpty())
+ {
+ COneMethodInfo *oneMethodMain = &_options._methods[0];
+
+ RINOK(oneMethodMain->SetCoderProps(setCoderProps,
+ _options._dataSizeReduceDefined ? &_options._dataSizeReduce : NULL));
+ }
}
}
+ if (method == NCompressionMethod::kLZMA)
+ _isLzmaEos = _lzmaEncoder->EncoderSpec->IsWriteEndMark();
}
+
+ if (method == NCompressionMethod::kLZMA)
+ opRes.LzmaEos = _isLzmaEos;
+
CMyComPtr<ISequentialOutStream> outStreamNew;
if (_options.PasswordIsDefined)
outStreamNew = _cryptoStream;
@@ -332,18 +407,10 @@ HRESULT CAddCommon::Compress(
RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &opRes.PackSize));
- // if (inCrcStreamSpec)
- {
- opRes.CRC = inCrcStreamSpec->GetCRC();
- opRes.UnpackSize = inCrcStreamSpec->GetSize();
- }
- /*
- else
{
opRes.CRC = inSecCrcStreamSpec->GetCRC();
opRes.UnpackSize = inSecCrcStreamSpec->GetSize();
}
- */
if (_options.PasswordIsDefined)
{
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.h b/CPP/7zip/Archive/Zip/ZipAddCommon.h
index 1e0c3bfa..ea5f8180 100644
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.h
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.h
@@ -27,6 +27,7 @@ struct CCompressingResult
UInt16 Method;
Byte ExtractVersion;
bool FileTimeWasUsed;
+ bool LzmaEos;
};
class CAddCommon
@@ -37,6 +38,7 @@ class CAddCommon
CMyComPtr<ICompressCoder> _compressEncoder;
Byte _compressExtractVersion;
+ bool _isLzmaEos;
CFilterCoder *_cryptoStreamSpec;
CMyComPtr<ISequentialOutStream> _cryptoStream;
@@ -50,11 +52,14 @@ class CAddCommon
public:
CAddCommon(const CCompressionMethodMode &options);
~CAddCommon();
+
+ HRESULT Set_Pre_CompressionResult(bool seqMode, UInt64 unpackSize, CCompressingResult &opRes) const;
+
HRESULT Compress(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream, IOutStream *outStream,
- UInt32 fileTime,
- ICompressProgressInfo *progress, CCompressingResult &operationResult);
+ bool seqMode, UInt32 fileTime,
+ ICompressProgressInfo *progress, CCompressingResult &opRes);
};
}}
diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
index 86548d95..1125f6ed 100644
--- a/CPP/7zip/Archive/Zip/ZipCompressionMode.h
+++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
@@ -14,26 +14,18 @@
namespace NArchive {
namespace NZip {
-struct CBaseProps
-{
- CMethodProps MethodInfo;
- Int32 Level;
+const CMethodId kMethodId_ZipBase = 0x040100;
+const CMethodId kMethodId_BZip2 = 0x040202;
- #ifndef _7ZIP_ST
- UInt32 NumThreads;
- bool NumThreadsWasChanged;
- #endif
+struct CBaseProps: public CMultiMethodProps
+{
bool IsAesMode;
Byte AesKeyMode;
void Init()
{
- MethodInfo.Clear();
- Level = -1;
- #ifndef _7ZIP_ST
- NumThreads = NWindows::NSystem::GetNumberOfProcessors();;
- NumThreadsWasChanged = false;
- #endif
+ CMultiMethodProps::Init();
+
IsAesMode = false;
AesKeyMode = 3;
}
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp
index 75034de0..75fad760 100644
--- a/CPP/7zip/Archive/Zip/ZipHandler.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp
@@ -3,10 +3,10 @@
#include "StdAfx.h"
#include "../../../Common/ComTry.h"
-#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/PropVariantUtils.h"
#include "../../../Windows/TimeUtils.h"
#include "../../IPassword.h"
@@ -22,6 +22,7 @@
#include "../../Compress/ImplodeDecoder.h"
#include "../../Compress/PpmdZip.h"
#include "../../Compress/ShrinkDecoder.h"
+#include "../../Compress/XzDecoder.h"
#include "../../Crypto/WzAes.h"
#include "../../Crypto/ZipCrypto.h"
@@ -30,7 +31,6 @@
#include "../Common/ItemNameUtils.h"
#include "../Common/OutStreamWithCRC.h"
-#include "../XzHandler.h"
#include "ZipHandler.h"
@@ -39,9 +39,6 @@ using namespace NWindows;
namespace NArchive {
namespace NZip {
-static const CMethodId kMethodId_ZipBase = 0x040100;
-static const CMethodId kMethodId_BZip2 = 0x040202;
-
static const char * const kHostOS[] =
{
"FAT"
@@ -66,24 +63,57 @@ static const char * const kHostOS[] =
, "OS/X"
};
-static const char * const kMethods[] =
+
+const char * const kMethodNames1[kNumMethodNames1] =
{
"Store"
, "Shrink"
- , "Reduced1"
- , "Reduced2"
- , "Reduced3"
- , "Reduced4"
+ , "Reduce1"
+ , "Reduce2"
+ , "Reduce3"
+ , "Reduce4"
, "Implode"
- , "Tokenizing"
+ , NULL // "Tokenize"
, "Deflate"
, "Deflate64"
, "PKImploding"
+ , NULL
+ , "BZip2"
+ , NULL
+ , "LZMA"
+};
+
+
+const char * const kMethodNames2[kNumMethodNames2] =
+{
+ "xz"
+ , "Jpeg"
+ , "WavPack"
+ , "PPMd"
+ , "WzAES"
};
-static const char *kMethod_AES = "AES";
-static const char *kMethod_ZipCrypto = "ZipCrypto";
-static const char *kMethod_StrongCrypto = "StrongCrypto";
+#define kMethod_AES "AES"
+#define kMethod_ZipCrypto "ZipCrypto"
+#define kMethod_StrongCrypto "StrongCrypto"
+
+static const char * const kDeflateLevels[4] =
+{
+ "Normal"
+ , "Maximum"
+ , "Fast"
+ , "Fastest"
+};
+
+
+static const CUInt32PCharPair g_HeaderCharacts[] =
+{
+ { 0, "Encrypt" },
+ { 3, "Descriptor" },
+ // { 5, "Patched" },
+ { 6, kMethod_StrongCrypto },
+ { 11, "UTF8" }
+};
struct CIdToNamePair
{
@@ -91,15 +121,6 @@ struct CIdToNamePair
const char *Name;
};
-static const CIdToNamePair k_MethodIdNamePairs[] =
-{
- { NFileHeader::NCompressionMethod::kBZip2, "BZip2" },
- { NFileHeader::NCompressionMethod::kLZMA, "LZMA" },
- { NFileHeader::NCompressionMethod::kXz, "xz" },
- { NFileHeader::NCompressionMethod::kJpeg, "Jpeg" },
- { NFileHeader::NCompressionMethod::kWavPack, "WavPack" },
- { NFileHeader::NCompressionMethod::kPPMd, "PPMd" }
-};
static const CIdToNamePair k_StrongCryptoPairs[] =
{
@@ -116,7 +137,7 @@ static const CIdToNamePair k_StrongCryptoPairs[] =
{ NStrongCrypto_AlgId::kRC4, "RC4" }
};
-const char *FindNameForId(const CIdToNamePair *pairs, unsigned num, unsigned id)
+static const char *FindNameForId(const CIdToNamePair *pairs, unsigned num, unsigned id)
{
for (unsigned i = 0; i < num; i++)
{
@@ -127,6 +148,7 @@ const char *FindNameForId(const CIdToNamePair *pairs, unsigned num, unsigned id)
return NULL;
}
+
static const Byte kProps[] =
{
kpidPath,
@@ -142,9 +164,11 @@ static const Byte kProps[] =
kpidComment,
kpidCRC,
kpidMethod,
+ kpidCharacts,
kpidHostOS,
kpidUnpackVer,
- kpidVolumeIndex
+ kpidVolumeIndex,
+ kpidOffset
};
static const Byte kArcProps[] =
@@ -152,6 +176,7 @@ static const Byte kArcProps[] =
kpidEmbeddedStubSize,
kpidBit64,
kpidComment,
+ kpidCharacts,
kpidTotalPhySize,
kpidIsVolume,
kpidVolumeIndex,
@@ -193,11 +218,34 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
break;
}
- case kpidTotalPhySize: if (m_Archive.IsMultiVol) prop = m_Archive.Vols.GetTotalSize(); break;
+ case kpidTotalPhySize: if (m_Archive.IsMultiVol) prop = m_Archive.Vols.TotalBytesSize; break;
case kpidVolumeIndex: if (m_Archive.IsMultiVol) prop = (UInt32)m_Archive.Vols.StartVolIndex; break;
case kpidIsVolume: if (m_Archive.IsMultiVol) prop = true; break;
case kpidNumVolumes: if (m_Archive.IsMultiVol) prop = (UInt32)m_Archive.Vols.Streams.Size(); break;
+ case kpidCharacts:
+ {
+ AString s;
+
+ if (m_Archive.LocalsWereRead)
+ {
+ s.Add_OptSpaced("Local");
+
+ if (m_Archive.LocalsCenterMerged)
+ s.Add_OptSpaced("Central");
+ }
+
+ if (m_Archive.IsZip64)
+ s.Add_OptSpaced("Zip64");
+
+ if (m_Archive.ExtraMinorError)
+ s.Add_OptSpaced("Minor_Extra_ERROR");
+
+ if (!s.IsEmpty())
+ prop = s;
+ break;
+ }
+
case kpidWarningFlags:
{
UInt32 v = 0;
@@ -208,12 +256,23 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
break;
}
+ case kpidWarning:
+ {
+ AString s;
+ if (m_Archive.Overflow32bit)
+ s.Add_OptSpaced("32-bit overflow in headers");
+ if (m_Archive.Cd_NumEntries_Overflow_16bit)
+ s.Add_OptSpaced("16-bit overflow for number of files in headers");
+ if (!s.IsEmpty())
+ prop = s;
+ break;
+ }
+
case kpidError:
{
if (!m_Archive.Vols.MissingName.IsEmpty())
{
- UString s;
- s.SetFromAscii("Missing volume : ");
+ UString s("Missing volume : ");
s += m_Archive.Vols.MissingName;
prop = s;
}
@@ -273,13 +332,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
UString res;
item.GetUnicodeString(res, item.Name, false, _forceCodePage, _specifiedCodePage);
- NItemName::ConvertToOSName2(res);
+ NItemName::ReplaceToOsSlashes_Remove_TailSlash(res);
prop = res;
break;
}
case kpidIsDir: prop = item.IsDir(); break;
- case kpidSize: prop = item.Size; break;
+ case kpidSize:
+ {
+ if (item.FromCentral || !item.FromLocal || !item.HasDescriptor() || item.DescriptorWasRead)
+ prop = item.Size;
+ break;
+ }
+
case kpidPackSize: prop = item.PackSize; break;
case kpidTimeType:
@@ -299,17 +364,36 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidCTime:
{
- FILETIME ft;
- if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft))
- prop = ft;
+ FILETIME utc;
+ bool defined = true;
+ if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, utc))
+ {
+ UInt32 unixTime = 0;
+ if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kCTime, unixTime))
+ NTime::UnixTimeToFileTime(unixTime, utc);
+ else
+ defined = false;
+ }
+ if (defined)
+ prop = utc;
break;
}
case kpidATime:
{
- FILETIME ft;
- if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft))
- prop = ft;
+ FILETIME utc;
+ bool defined = true;
+ if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, utc))
+ {
+ UInt32 unixTime = 0;
+ if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kATime, unixTime))
+ NTime::UnixTimeToFileTime(unixTime, utc);
+ else
+ defined = false;
+ }
+ if (defined)
+ prop = utc;
+
break;
}
@@ -375,10 +459,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
CWzAesExtra aesField;
if (extra.GetWzAes(aesField))
{
- char s[16];
- s[0] = '-';
- ConvertUInt32ToString(((unsigned)aesField.Strength + 1) * 64 , s + 1);
- m += s;
+ m += '-';
+ m.Add_UInt32(((unsigned)aesField.Strength + 1) * 64);
id = aesField.Method;
}
}
@@ -394,10 +476,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
else
{
m += kMethod_StrongCrypto;
- char temp[16];
- temp[0] = ':';
- ConvertUInt32ToString(f.AlgId, temp + 1);
- m += temp;
+ m += ':';
+ m.Add_UInt32(f.AlgId);
}
if (f.CertificateIsUsed())
m += "-Cert";
@@ -411,41 +491,96 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
{
- char temp[16];
const char *s = NULL;
- if (id < ARRAY_SIZE(kMethods))
- s = kMethods[id];
+ if (id < kNumMethodNames1)
+ s = kMethodNames1[id];
else
{
- s = FindNameForId(k_MethodIdNamePairs, ARRAY_SIZE(k_MethodIdNamePairs), id);
- if (!s)
+ int id2 = (int)id - (int)kMethodNames2Start;
+ if (id2 >= 0 && id2 < kNumMethodNames2)
+ s = kMethodNames2[id2];
+ }
+ if (s)
+ m += s;
+ else
+ m.Add_UInt32(id);
+ }
+ {
+ unsigned level = item.GetDeflateLevel();
+ if (level != 0)
+ {
+ if (id == NFileHeader::NCompressionMethod::kLZMA)
+ {
+ if (level & 1)
+ m += ":eos";
+ level &= ~1;
+ }
+ else if (id == NFileHeader::NCompressionMethod::kDeflate)
{
- ConvertUInt32ToString(id, temp);
- s = temp;
+ m += ':';
+ m += kDeflateLevels[level];
+ level = 0;
+ }
+
+ if (level != 0)
+ {
+ m += ":v";
+ m.Add_UInt32(level);
}
}
- m += s;
- if (id == NFileHeader::NCompressionMethod::kLZMA && item.IsLzmaEOS())
- m += ":EOS";
}
prop = m;
break;
}
- case kpidHostOS:
+ case kpidCharacts:
{
- Byte hostOS = item.GetHostOS();
- char temp[16];
- const char *s = NULL;
- if (hostOS < ARRAY_SIZE(kHostOS))
- s = kHostOS[hostOS];
- else
+ AString s;
+
+ if (item.FromLocal)
+ {
+ s.Add_OptSpaced("Local");
+
+ item.LocalExtra.PrintInfo(s);
+
+ if (item.FromCentral)
+ {
+ s.Add_OptSpaced(":");
+ s.Add_OptSpaced("Central");
+ }
+ }
+
+ if (item.FromCentral)
{
- ConvertUInt32ToString(hostOS, temp);
- s = temp;
+ item.CentralExtra.PrintInfo(s);
}
- prop = s;
+
+ UInt32 flags = item.Flags;
+ flags &= ~(6); // we don't need compression related bits here.
+
+ if (flags != 0)
+ {
+ AString s2 = FlagsToString(g_HeaderCharacts, ARRAY_SIZE(g_HeaderCharacts), flags);
+ if (!s2.IsEmpty())
+ {
+ s.Add_OptSpaced(":");
+ s.Add_OptSpaced(s2);
+ }
+ }
+
+ if (!item.FromCentral && item.FromLocal && item.HasDescriptor() && !item.DescriptorWasRead)
+ s.Add_OptSpaced("Descriptor_ERROR");
+
+ if (!s.IsEmpty())
+ prop = s;
+ break;
+ }
+
+ case kpidHostOS:
+ {
+ const Byte hostOS = item.GetHostOS();
+ TYPE_TO_PROP(kHostOS, hostOS, prop);
break;
}
@@ -456,6 +591,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidVolumeIndex:
prop = item.Disk;
break;
+
+ case kpidOffset:
+ prop = item.LocalHeaderPos;
+ break;
}
prop.Detach(value);
@@ -475,7 +614,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
if (res != S_OK)
{
m_Items.Clear();
- m_Archive.ClearRefs();
+ m_Archive.ClearRefs(); // we don't want to clear error flags
}
return res;
}
@@ -493,16 +632,24 @@ STDMETHODIMP CHandler::Close()
class CLzmaDecoder:
public ICompressCoder,
+ public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
public CMyUnknownImp
{
+public:
NCompress::NLzma::CDecoder *DecoderSpec;
CMyComPtr<ICompressCoder> Decoder;
-public:
- CLzmaDecoder();
+
+ MY_UNKNOWN_IMP2(
+ ICompressSetFinishMode,
+ ICompressGetInStreamProcessedSize)
+
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
- MY_UNKNOWN_IMP
+ CLzmaDecoder();
};
CLzmaDecoder::CLzmaDecoder()
@@ -511,44 +658,45 @@ CLzmaDecoder::CLzmaDecoder()
Decoder = DecoderSpec;
}
+static const unsigned kZipLzmaPropsSize = 4 + LZMA_PROPS_SIZE;
+
HRESULT CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
- const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
- Byte buf[9];
- RINOK(ReadStream_FALSE(inStream, buf, 9));
- if (buf[2] != 5 || buf[3] != 0)
+ Byte buf[kZipLzmaPropsSize];
+ RINOK(ReadStream_FALSE(inStream, buf, kZipLzmaPropsSize));
+ if (buf[2] != LZMA_PROPS_SIZE || buf[3] != 0)
return E_NOTIMPL;
- RINOK(DecoderSpec->SetDecoderProperties2(buf + 4, 5));
- return Decoder->Code(inStream, outStream, NULL, outSize, progress);
+ RINOK(DecoderSpec->SetDecoderProperties2(buf + 4, LZMA_PROPS_SIZE));
+ UInt64 inSize2 = 0;
+ if (inSize)
+ {
+ inSize2 = *inSize;
+ if (inSize2 < kZipLzmaPropsSize)
+ return S_FALSE;
+ inSize2 -= kZipLzmaPropsSize;
+ }
+ return Decoder->Code(inStream, outStream, inSize ? &inSize2 : NULL, outSize, progress);
}
-
-class CXzDecoder:
- public ICompressCoder,
- public CMyUnknownImp
+STDMETHODIMP CLzmaDecoder::SetFinishMode(UInt32 finishMode)
{
- NArchive::NXz::CDecoder _decoder;
-public:
-
- STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
- const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
-
- MY_UNKNOWN_IMP
-};
+ DecoderSpec->FinishStream = (finishMode != 0);
+ return S_OK;
+}
-HRESULT CXzDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
- const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
+STDMETHODIMP CLzmaDecoder::GetInStreamProcessedSize(UInt64 *value)
{
- RINOK(_decoder.Decode(inStream, outStream, progress));
- Int32 opRes = _decoder.Get_Extract_OperationResult();
- if (opRes == NExtract::NOperationResult::kUnsupportedMethod)
- return E_NOTIMPL;
- if (opRes != NExtract::NOperationResult::kOK)
- return S_FALSE;
+ *value = DecoderSpec->GetInputProcessedSize() + kZipLzmaPropsSize;
return S_OK;
}
+
+
+
+
+
struct CMethodItem
{
unsigned ZipMethod;
@@ -572,12 +720,15 @@ class CZipDecoder
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
CObjectVector<CMethodItem> methodItems;
+ CLzmaDecoder *lzmaDecoderSpec;
public:
CZipDecoder():
_zipCryptoDecoderSpec(0),
_pkAesDecoderSpec(0),
_wzAesDecoderSpec(0),
- filterStreamSpec(0) {}
+ filterStreamSpec(0),
+ lzmaDecoderSpec(0)
+ {}
HRESULT Decode(
DECL_EXTERNAL_CODECS_LOC_VARS
@@ -592,19 +743,18 @@ public:
};
-static HRESULT SkipStreamData(ISequentialInStream *stream, UInt64 size)
+static HRESULT SkipStreamData(ISequentialInStream *stream, bool &thereAreData)
{
+ thereAreData = false;
const size_t kBufSize = 1 << 12;
Byte buf[kBufSize];
for (;;)
{
+ size_t size = kBufSize;
+ RINOK(ReadStream(stream, buf, &size));
if (size == 0)
return S_OK;
- size_t curSize = kBufSize;
- if (curSize > size)
- curSize = (size_t)size;
- RINOK(ReadStream_FALSE(stream, buf, curSize));
- size -= curSize;
+ thereAreData = true;
}
}
@@ -620,12 +770,15 @@ HRESULT CZipDecoder::Decode(
#endif
Int32 &res)
{
- res = NExtract::NOperationResult::kDataError;
+ res = NExtract::NOperationResult::kHeadersError;
+
CFilterCoder::C_InStream_Releaser inStreamReleaser;
+ CFilterCoder::C_Filter_Releaser filterReleaser;
bool needCRC = true;
bool wzAesMode = false;
bool pkAesMode = false;
+
unsigned id = item.Method;
if (item.IsEncrypted())
@@ -633,27 +786,23 @@ HRESULT CZipDecoder::Decode(
if (item.IsStrongEncrypted())
{
CStrongCryptoExtra f;
- if (item.CentralExtra.GetStrongCrypto(f))
- {
- pkAesMode = true;
- }
- if (!pkAesMode)
+ if (!item.CentralExtra.GetStrongCrypto(f))
{
res = NExtract::NOperationResult::kUnsupportedMethod;
return S_OK;
}
+ pkAesMode = true;
}
- if (!pkAesMode && id == NFileHeader::NCompressionMethod::kWzAES)
+ else if (id == NFileHeader::NCompressionMethod::kWzAES)
{
CWzAesExtra aesField;
- if (item.GetMainExtra().GetWzAes(aesField))
- {
- wzAesMode = true;
- needCRC = aesField.NeedCrc();
- }
+ if (!item.GetMainExtra().GetWzAes(aesField))
+ return S_OK;
+ wzAesMode = true;
+ needCRC = aesField.NeedCrc();
}
}
-
+
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->SetStream(realOutStream);
@@ -681,6 +830,9 @@ HRESULT CZipDecoder::Decode(
limitedStreamSpec->SetStream(packStream);
limitedStreamSpec->Init(packSize);
}
+
+
+ res = NExtract::NOperationResult::kDataError;
CMyComPtr<ICompressFilter> cryptoFilter;
@@ -725,6 +877,8 @@ HRESULT CZipDecoder::Decode(
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword));
+ if (!cryptoSetPassword)
+ return E_FAIL;
if (!getTextPassword)
extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword);
@@ -736,39 +890,35 @@ HRESULT CZipDecoder::Decode(
AString charPassword;
if (password)
{
+ UnicodeStringToMultiByte2(charPassword, (const wchar_t *)password, CP_ACP);
+ /*
if (wzAesMode || pkAesMode)
{
- charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_ACP);
- /*
- for (unsigned i = 0;; i++)
- {
- wchar_t c = password[i];
- if (c == 0)
- break;
- if (c >= 0x80)
- {
- res = NExtract::NOperationResult::kDataError;
- return S_OK;
- }
- charPassword += (char)c;
- }
- */
}
else
{
- /* pkzip25 / WinZip / Windows probably use ANSI for some files
- We use OEM for compatibility with previous versions of 7-Zip? */
- charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP);
+ // PASSWORD encoding for ZipCrypto:
+ // pkzip25 / WinZip / Windows probably use ANSI
+ // 7-Zip < 4.43 creates ZIP archives with OEM encoding in password
+ // 7-Zip >= 4.43 creates ZIP archives only with ASCII characters in password
+ // 7-Zip < 17.00 uses CP_OEMCP for password decoding
+ // 7-Zip >= 17.00 uses CP_ACP for password decoding
}
+ */
}
HRESULT result = cryptoSetPassword->CryptoSetPassword(
(const Byte *)(const char *)charPassword, charPassword.Len());
if (result != S_OK)
+ {
+ res = NExtract::NOperationResult::kWrongPassword;
return S_OK;
+ }
}
else
{
- RINOK(cryptoSetPassword->CryptoSetPassword(0, 0));
+ res = NExtract::NOperationResult::kWrongPassword;
+ return S_OK;
+ // RINOK(cryptoSetPassword->CryptoSetPassword(NULL, 0));
}
}
@@ -781,16 +931,19 @@ HRESULT CZipDecoder::Decode(
{
CMethodItem mi;
mi.ZipMethod = id;
- if (id == NFileHeader::NCompressionMethod::kStored)
+ if (id == NFileHeader::NCompressionMethod::kStore)
mi.Coder = new NCompress::CCopyCoder;
- else if (id == NFileHeader::NCompressionMethod::kShrunk)
+ else if (id == NFileHeader::NCompressionMethod::kShrink)
mi.Coder = new NCompress::NShrink::CDecoder;
- else if (id == NFileHeader::NCompressionMethod::kImploded)
+ else if (id == NFileHeader::NCompressionMethod::kImplode)
mi.Coder = new NCompress::NImplode::NDecoder::CCoder;
else if (id == NFileHeader::NCompressionMethod::kLZMA)
- mi.Coder = new CLzmaDecoder;
+ {
+ lzmaDecoderSpec = new CLzmaDecoder;
+ mi.Coder = lzmaDecoderSpec;
+ }
else if (id == NFileHeader::NCompressionMethod::kXz)
- mi.Coder = new CXzDecoder;
+ mi.Coder = new NCompress::NXz::CComDecoder;
else if (id == NFileHeader::NCompressionMethod::kPPMd)
mi.Coder = new NCompress::NPpmdZip::CDecoder(true);
else
@@ -810,7 +963,7 @@ HRESULT CZipDecoder::Decode(
RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS szMethodID, false, mi.Coder));
- if (mi.Coder == 0)
+ if (!mi.Coder)
{
res = NExtract::NOperationResult::kUnsupportedMethod;
return S_OK;
@@ -842,9 +995,17 @@ HRESULT CZipDecoder::Decode(
}
#endif
+ CMyComPtr<ISequentialInStream> inStreamNew;
+
+ bool isFullStreamExpected = (!item.HasDescriptor() || item.PackSize != 0);
+ bool needReminderCheck = false;
+
+ bool dataAfterEnd = false;
+ bool truncatedError = false;
+ bool lzmaEosError = false;
+
{
HRESULT result = S_OK;
- CMyComPtr<ISequentialInStream> inStreamNew;
if (item.IsEncrypted())
{
if (!filterStream)
@@ -853,6 +1014,7 @@ HRESULT CZipDecoder::Decode(
filterStream = filterStreamSpec;
}
+ filterReleaser.FilterCoder = filterStreamSpec;
filterStreamSpec->Filter = cryptoFilter;
if (wzAesMode)
@@ -869,6 +1031,7 @@ HRESULT CZipDecoder::Decode(
}
else if (pkAesMode)
{
+ isFullStreamExpected = false;
result =_pkAesDecoderSpec->ReadHeader(inStream, item.Crc, item.Size);
if (result == S_OK)
{
@@ -926,7 +1089,70 @@ HRESULT CZipDecoder::Decode(
inStreamNew = inStream;
if (result == S_OK)
- result = coder->Code(inStreamNew, outStream, NULL, &item.Size, compressProgress);
+ {
+ CMyComPtr<ICompressSetFinishMode> setFinishMode;
+ coder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
+ if (setFinishMode)
+ {
+ RINOK(setFinishMode->SetFinishMode(BoolToInt(true)));
+ }
+
+ const UInt64 coderPackSize = limitedStreamSpec->GetRem();
+
+ bool useUnpackLimit = (id == 0
+ || !item.HasDescriptor()
+ || item.Size >= ((UInt64)1 << 32)
+ || item.LocalExtra.IsZip64
+ || item.CentralExtra.IsZip64
+ );
+
+ result = coder->Code(inStreamNew, outStream,
+ isFullStreamExpected ? &coderPackSize : NULL,
+ // NULL,
+ useUnpackLimit ? &item.Size : NULL,
+ compressProgress);
+
+ if (result == S_OK)
+ {
+ CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
+ coder->QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize);
+ if (getInStreamProcessedSize && setFinishMode)
+ {
+ UInt64 processed;
+ RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed));
+ if (processed != (UInt64)(Int64)-1)
+ {
+ if (pkAesMode)
+ {
+ const UInt32 padSize = _pkAesDecoderSpec->GetPadSize((UInt32)processed);
+ if (processed + padSize > coderPackSize)
+ truncatedError = true;
+ else
+ {
+ if (processed + padSize < coderPackSize)
+ dataAfterEnd = true;
+ // also here we can check PKCS7 padding data from reminder (it can be inside stream buffer in coder).
+ }
+ }
+ else
+ {
+ if (processed < coderPackSize)
+ {
+ if (isFullStreamExpected)
+ dataAfterEnd = true;
+ }
+ else if (processed > coderPackSize)
+ truncatedError = true;
+ needReminderCheck = isFullStreamExpected;
+ }
+ }
+ }
+ }
+
+ if (result == S_OK && id == NFileHeader::NCompressionMethod::kLZMA)
+ if (!lzmaDecoderSpec->DecoderSpec->CheckFinishStatus(item.IsLzmaEOS()))
+ lzmaEosError = true;
+ }
if (result == S_FALSE)
return S_OK;
@@ -947,19 +1173,40 @@ HRESULT CZipDecoder::Decode(
if (wzAesMode)
{
- const UInt64 rem = limitedStreamSpec->GetRem();
- if (rem != 0)
- if (SkipStreamData(inStream, rem) != S_OK)
- authOk = false;
+ bool thereAreData = false;
+ if (SkipStreamData(inStreamNew, thereAreData) != S_OK)
+ authOk = false;
+ if (needReminderCheck && thereAreData)
+ dataAfterEnd = true;
+
limitedStreamSpec->Init(NCrypto::NWzAes::kMacSize);
if (_wzAesDecoderSpec->CheckMac(inStream, authOk) != S_OK)
authOk = false;
}
-
- res = ((crcOK && authOk) ?
- NExtract::NOperationResult::kOK :
- NExtract::NOperationResult::kCRCError);
+
+ res = NExtract::NOperationResult::kCRCError;
+
+ if (crcOK && authOk)
+ {
+ res = NExtract::NOperationResult::kOK;
+
+ if (dataAfterEnd)
+ res = NExtract::NOperationResult::kDataAfterEnd;
+ else if (truncatedError)
+ res = NExtract::NOperationResult::kUnexpectedEnd;
+ else if (lzmaEosError)
+ res = NExtract::NOperationResult::kHeadersError;
+
+ // CheckDescriptor() supports only data descriptor with signature and
+ // it doesn't support "old" pkzip's data descriptor without signature.
+ // So we disable that check.
+ /*
+ if (item.HasDescriptor() && archive.CheckDescriptor(item) != S_OK)
+ res = NExtract::NOperationResult::kHeadersError;
+ */
+ }
+
return S_OK;
}
@@ -1026,11 +1273,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable));
continue;
}
+
+ bool headersError = false;
if (!item.FromLocal)
{
bool isAvail = true;
- HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item, isAvail);
+ HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item, isAvail, headersError);
if (res == S_FALSE)
{
if (item.IsDir() || realOutStream || testMode)
@@ -1069,12 +1318,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
m_Archive, item, realOutStream, extractCallback,
progress,
#ifndef _7ZIP_ST
- _props.NumThreads,
+ _props._numThreads,
#endif
res);
+
RINOK(hres);
realOutStream.Release();
+ if (res == NExtract::NOperationResult::kOK && headersError)
+ res = NExtract::NOperationResult::kHeadersError;
+
RINOK(extractCallback->SetOperationResult(res))
}
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h
index c2a362a7..53e6a460 100644
--- a/CPP/7zip/Archive/Zip/ZipHandler.h
+++ b/CPP/7zip/Archive/Zip/ZipHandler.h
@@ -9,12 +9,20 @@
#include "../../Common/CreateCoder.h"
-#include "ZipIn.h"
#include "ZipCompressionMode.h"
+#include "ZipIn.h"
namespace NArchive {
namespace NZip {
+const unsigned kNumMethodNames1 = NFileHeader::NCompressionMethod::kLZMA + 1;
+const unsigned kMethodNames2Start = NFileHeader::NCompressionMethod::kXz;
+const unsigned kNumMethodNames2 = NFileHeader::NCompressionMethod::kWzAES + 1 - kMethodNames2Start;
+
+extern const char * const kMethodNames1[kNumMethodNames1];
+extern const char * const kMethodNames2[kNumMethodNames2];
+
+
class CHandler:
public IInArchive,
public IOutArchive,
diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
index 8a8de511..8ecf7942 100644
--- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
@@ -46,6 +46,30 @@ static bool IsSimpleAsciiString(const wchar_t *s)
}
}
+
+static int FindZipMethod(const char *s, const char * const *names, unsigned num)
+{
+ for (unsigned i = 0; i < num; i++)
+ {
+ const char *name = names[i];
+ if (name && StringsAreEqualNoCase_Ascii(s, name))
+ return i;
+ }
+ return -1;
+}
+
+static int FindZipMethod(const char *s)
+{
+ int k = FindZipMethod(s, kMethodNames1, kNumMethodNames1);
+ if (k >= 0)
+ return k;
+ k = FindZipMethod(s, kMethodNames2, kNumMethodNames2);
+ if (k >= 0)
+ return kMethodNames2Start + k;
+ return -1;
+}
+
+
#define COM_TRY_BEGIN2 try {
#define COM_TRY_END2 } \
catch(const CSystemException &e) { return e.ErrorCode; } \
@@ -63,6 +87,7 @@ static HRESULT GetTime(IArchiveUpdateCallback *callback, int index, PROPID propI
return S_OK;
}
+
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *callback)
{
@@ -75,31 +100,46 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
CObjectVector<CUpdateItem> updateItems;
+ updateItems.ClearAndReserve(numItems);
+
bool thereAreAesUpdates = false;
UInt64 largestSize = 0;
bool largestSizeDefined = false;
+ UString name;
+ CUpdateItem ui;
+
for (UInt32 i = 0; i < numItems; i++)
{
- CUpdateItem ui;
Int32 newData;
Int32 newProps;
- UInt32 indexInArchive;
+ UInt32 indexInArc;
+
if (!callback)
return E_FAIL;
- RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive));
+
+ RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc));
+
+ name.Empty();
+ ui.Clear();
+
ui.NewProps = IntToBool(newProps);
ui.NewData = IntToBool(newData);
- ui.IndexInArc = indexInArchive;
+ ui.IndexInArc = indexInArc;
ui.IndexInClient = i;
- bool existInArchive = (indexInArchive != (UInt32)(Int32)-1);
- if (existInArchive && newData)
- if (m_Items[indexInArchive].IsAesEncrypted())
+
+ bool existInArchive = (indexInArc != (UInt32)(Int32)-1);
+ if (existInArchive)
+ {
+ const CItemEx &inputItem = m_Items[indexInArc];
+ if (inputItem.IsAesEncrypted())
thereAreAesUpdates = true;
+ if (!IntToBool(newProps))
+ ui.IsDir = inputItem.IsDir();
+ }
if (IntToBool(newProps))
{
- UString name;
{
NCOM::CPropVariant prop;
RINOK(callback->GetProperty(i, kpidAttrib, &prop));
@@ -115,12 +155,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
NCOM::CPropVariant prop;
RINOK(callback->GetProperty(i, kpidPath, &prop));
if (prop.vt == VT_EMPTY)
- name.Empty();
+ {
+ // name.Empty();
+ }
else if (prop.vt != VT_BSTR)
return E_INVALIDARG;
else
name = prop.bstrVal;
}
+
{
NCOM::CPropVariant prop;
RINOK(callback->GetProperty(i, kpidIsDir, &prop));
@@ -153,7 +196,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
FileTimeToDosTime(localFileTime, ui.Time);
}
- name = NItemName::MakeLegalName(name);
+ NItemName::ReplaceSlashes_OsToUnix(name);
+
bool needSlash = ui.IsDir;
const wchar_t kSlash = L'/';
if (!name.IsEmpty())
@@ -188,11 +232,37 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (ui.Name.Len() >= (1 << 16))
return E_INVALIDARG;
- ui.IndexInClient = i;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(callback->GetProperty(i, kpidComment, &prop));
+ if (prop.vt == VT_EMPTY)
+ {
+ // ui.Comment.Free();
+ }
+ else if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
+ else
+ {
+ UString s = prop.bstrVal;
+ AString a;
+ if (ui.IsUtf8)
+ ConvertUnicodeToUTF8(s, a);
+ else
+ {
+ bool defaultCharWasUsed;
+ a = UnicodeStringToMultiByte(s, codePage, '_', defaultCharWasUsed);
+ }
+ if (a.Len() >= (1 << 16))
+ return E_INVALIDARG;
+ ui.Comment.CopyFrom((const Byte *)(const char *)a, a.Len());
+ }
+ }
+
+
/*
if (existInArchive)
{
- const CItemEx &itemInfo = m_Items[indexInArchive];
+ const CItemEx &itemInfo = m_Items[indexInArc];
// ui.Commented = itemInfo.IsCommented();
ui.Commented = false;
if (ui.Commented)
@@ -205,6 +275,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
ui.Commented = false;
*/
}
+
+
if (IntToBool(newData))
{
UInt64 size = 0;
@@ -220,12 +292,12 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
largestSizeDefined = true;
}
ui.Size = size;
-
- // ui.Size -= ui.Size / 2;
}
+
updateItems.Add(ui);
}
+
CMyComPtr<ICryptoGetTextPassword2> getTextPassword;
{
CMyComPtr<IArchiveUpdateCallback> udateCallBack2(callback);
@@ -261,16 +333,52 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
}
- Byte mainMethod;
- if (m_MainMethod < 0)
- mainMethod = (Byte)(((_props.Level == 0) ?
- NFileHeader::NCompressionMethod::kStored :
- NFileHeader::NCompressionMethod::kDeflated));
+
+ int mainMethod = m_MainMethod;
+
+ if (mainMethod < 0)
+ {
+ if (!_props._methods.IsEmpty())
+ {
+ const AString &methodName = _props._methods.Front().MethodName;
+ if (!methodName.IsEmpty())
+ {
+ mainMethod = FindZipMethod(methodName);
+ if (mainMethod < 0)
+ {
+ CMethodId methodId;
+ UInt32 numStreams;
+ if (!FindMethod(EXTERNAL_CODECS_VARS methodName, methodId, numStreams))
+ return E_NOTIMPL;
+ if (numStreams != 1)
+ return E_NOTIMPL;
+ if (methodId == kMethodId_BZip2)
+ mainMethod = NFileHeader::NCompressionMethod::kBZip2;
+ else
+ {
+ if (methodId < kMethodId_ZipBase)
+ return E_NOTIMPL;
+ methodId -= kMethodId_ZipBase;
+ if (methodId > 0xFF)
+ return E_NOTIMPL;
+ mainMethod = (int)methodId;
+ }
+ }
+ }
+ }
+ }
+
+ if (mainMethod < 0)
+ mainMethod = (Byte)(((_props.GetLevel() == 0) ?
+ NFileHeader::NCompressionMethod::kStore :
+ NFileHeader::NCompressionMethod::kDeflate));
else
- mainMethod = (Byte)m_MainMethod;
- options.MethodSequence.Add(mainMethod);
- if (mainMethod != NFileHeader::NCompressionMethod::kStored)
- options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored);
+ mainMethod = (Byte)mainMethod;
+
+ options.MethodSequence.Add((Byte)mainMethod);
+
+ if (mainMethod != NFileHeader::NCompressionMethod::kStore)
+ options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStore);
return Update(
EXTERNAL_CODECS_VARS
@@ -281,28 +389,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
COM_TRY_END2
}
-struct CMethodIndexToName
-{
- unsigned Method;
- const char *Name;
-};
-static const CMethodIndexToName k_SupportedMethods[] =
-{
- { NFileHeader::NCompressionMethod::kStored, "copy" },
- { NFileHeader::NCompressionMethod::kDeflated, "deflate" },
- { NFileHeader::NCompressionMethod::kDeflated64, "deflate64" },
- { NFileHeader::NCompressionMethod::kBZip2, "bzip2" },
- { NFileHeader::NCompressionMethod::kLZMA, "lzma" },
- { NFileHeader::NCompressionMethod::kPPMd, "ppmd" }
-};
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
InitMethodProps();
- #ifndef _7ZIP_ST
- const UInt32 numProcessors = _props.NumThreads;
- #endif
for (UInt32 i = 0; i < numProps; i++)
{
@@ -313,82 +404,27 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
const PROPVARIANT &prop = values[i];
- if (name[0] == L'x')
- {
- UInt32 level = 9;
- RINOK(ParsePropToUInt32(name.Ptr(1), prop, level));
- _props.Level = level;
- _props.MethodInfo.AddProp_Level(level);
- }
- else if (name == L"m")
- {
- if (prop.vt == VT_BSTR)
- {
- UString m = prop.bstrVal, m2;
- m.MakeLower_Ascii();
- int colonPos = m.Find(L':');
- if (colonPos >= 0)
- {
- m2 = m.Ptr(colonPos + 1);
- m.DeleteFrom(colonPos);
- }
- unsigned k;
- for (k = 0; k < ARRAY_SIZE(k_SupportedMethods); k++)
- {
- const CMethodIndexToName &pair = k_SupportedMethods[k];
- if (m.IsEqualTo(pair.Name))
- {
- if (!m2.IsEmpty())
- {
- RINOK(_props.MethodInfo.ParseParamsFromString(m2));
- }
- m_MainMethod = pair.Method;
- break;
- }
- }
- if (k == ARRAY_SIZE(k_SupportedMethods))
- return E_INVALIDARG;
- }
- else if (prop.vt == VT_UI4)
- {
- unsigned k;
- for (k = 0; k < ARRAY_SIZE(k_SupportedMethods); k++)
- {
- unsigned method = k_SupportedMethods[k].Method;
- if (prop.ulVal == method)
- {
- m_MainMethod = method;
- break;
- }
- }
- if (k == ARRAY_SIZE(k_SupportedMethods))
- return E_INVALIDARG;
- }
- else
- return E_INVALIDARG;
- }
- else if (name.IsPrefixedBy(L"em"))
+ if (name.IsEqualTo_Ascii_NoCase("em"))
{
if (prop.vt != VT_BSTR)
return E_INVALIDARG;
{
- UString m = prop.bstrVal;
- m.MakeLower_Ascii();
- if (m.IsPrefixedBy(L"aes"))
+ const wchar_t *m = prop.bstrVal;
+ if (IsString1PrefixedByString2_NoCase_Ascii(m, "aes"))
{
- m.DeleteFrontal(3);
- if (m == L"128")
+ m += 3;
+ if (StringsAreEqual_Ascii(m, "128"))
_props.AesKeyMode = 1;
- else if (m == L"192")
+ else if (StringsAreEqual_Ascii(m, "192"))
_props.AesKeyMode = 2;
- else if (m == L"256" || m.IsEmpty())
+ else if (StringsAreEqual_Ascii(m, "256") || m[0] == 0)
_props.AesKeyMode = 3;
else
return E_INVALIDARG;
_props.IsAesMode = true;
m_ForceAesMode = true;
}
- else if (m == L"zipcrypto")
+ else if (StringsAreEqualNoCase_Ascii(m, "ZipCrypto"))
{
_props.IsAesMode = false;
m_ForceAesMode = true;
@@ -397,13 +433,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
return E_INVALIDARG;
}
}
- else if (name.IsPrefixedBy(L"mt"))
- {
- #ifndef _7ZIP_ST
- RINOK(ParseMtProp(name.Ptr(2), prop, numProcessors, _props.NumThreads));
- _props.NumThreadsWasChanged = true;
- #endif
- }
else if (name.IsEqualTo("tc"))
{
RINOK(PROPVARIANT_to_bool(prop, m_WriteNtfsTimeExtra));
@@ -433,9 +462,39 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
}
else
{
- RINOK(_props.MethodInfo.ParseParamsFromPROPVARIANT(name, prop));
+ if (name.IsEqualTo_Ascii_NoCase("m") && prop.vt == VT_UI4)
+ {
+ UInt32 id = prop.ulVal;
+ if (id > 0xFF)
+ return E_INVALIDARG;
+ m_MainMethod = id;
+ }
+ else
+ {
+ RINOK(_props.SetProperty(name, prop));
+ }
+ // RINOK(_props.MethodInfo.ParseParamsFromPROPVARIANT(name, prop));
}
}
+
+ _props._methods.DeleteFrontal(_props.GetNumEmptyMethods());
+ if (_props._methods.Size() > 1)
+ return E_INVALIDARG;
+ if (_props._methods.Size() == 1)
+ {
+ const AString &methodName = _props._methods[0].MethodName;
+
+ if (!methodName.IsEmpty())
+ {
+ const char *end;
+ UInt32 id = ConvertStringToUInt32(methodName, &end);
+ if (*end == 0 && id <= 0xFF)
+ m_MainMethod = id;
+ else if (methodName.IsEqualTo_Ascii_NoCase("Copy")) // it's alias for "Store"
+ m_MainMethod = 0;
+ }
+ }
+
return S_OK;
}
diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h
index fead0192..61b4ea4b 100644
--- a/CPP/7zip/Archive/Zip/ZipHeader.h
+++ b/CPP/7zip/Archive/Zip/ZipHeader.h
@@ -23,7 +23,8 @@ namespace NSignature
}
const unsigned kLocalHeaderSize = 4 + 26; // including signature
-const unsigned kDataDescriptorSize = 4 + 12; // including signature
+const unsigned kDataDescriptorSize32 = 4 + 4 + 4 * 2; // including signature
+const unsigned kDataDescriptorSize64 = 4 + 4 + 8 * 2; // including signature
const unsigned kCentralHeaderSize = 4 + 42; // including signature
const unsigned kEcdSize = 22; // including signature
@@ -37,28 +38,30 @@ namespace NFileHeader
{
enum EType
{
- kStored = 0,
- kShrunk = 1,
- kReduced1 = 2,
- kReduced2 = 3,
- kReduced3 = 4,
- kReduced4 = 5,
- kImploded = 6,
- kReservedTokenizing = 7, // reserved for tokenizing
- kDeflated = 8,
- kDeflated64 = 9,
+ kStore = 0,
+ kShrink = 1,
+ kReduce1 = 2,
+ kReduce2 = 3,
+ kReduce3 = 4,
+ kReduce4 = 5,
+ kImplode = 6,
+ kTokenize = 7,
+ kDeflate = 8,
+ kDeflate64 = 9,
kPKImploding = 10,
kBZip2 = 12,
+
kLZMA = 14,
+
kTerse = 18,
kLz77 = 19,
- kXz = 0x5F,
- kJpeg = 0x60,
- kWavPack = 0x61,
- kPPMd = 0x62,
- kWzAES = 0x63
+ kXz = 95,
+ kJpeg = 96,
+ kWavPack = 97,
+ kPPMd = 98,
+ kWzAES = 99
};
const Byte kMadeByProgramVersion = 63;
@@ -73,6 +76,7 @@ namespace NFileHeader
const Byte kExtractVersion_Aes = 51;
const Byte kExtractVersion_LZMA = 63;
const Byte kExtractVersion_PPMd = 63;
+ const Byte kExtractVersion_Xz = 20; // test it
}
namespace NExtraID
@@ -83,6 +87,7 @@ namespace NFileHeader
kNTFS = 0x0A,
kStrongEncrypt = 0x17,
kUnixTime = 0x5455,
+ kUnixExtra = 0x5855,
kIzUnicodeComment = 0x6375,
kIzUnicodeName = 0x7075,
kWzAES = 0x9901
@@ -110,6 +115,15 @@ namespace NFileHeader
};
}
+ namespace NUnixExtra
+ {
+ enum
+ {
+ kATime = 0,
+ kMTime
+ };
+ }
+
namespace NFlags
{
const unsigned kEncrypted = 1 << 0;
@@ -121,10 +135,12 @@ namespace NFileHeader
const unsigned kImplodeDictionarySizeMask = 1 << 1;
const unsigned kImplodeLiteralsOnMask = 1 << 2;
+ /*
const unsigned kDeflateTypeBitStart = 1;
const unsigned kNumDeflateTypeBits = 2;
const unsigned kNumDeflateTypes = (1 << kNumDeflateTypeBits);
const unsigned kDeflateTypeMask = (1 << kNumDeflateTypeBits) - 1;
+ */
}
namespace NHostOS
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
index 6361dc5c..09443a61 100644
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -6,6 +6,7 @@
#include "../../../Common/DynamicBuffer.h"
#include "../../../Common/IntToString.h"
+#include "../../../Common/MyException.h"
#include "../../../Common/StringToInt.h"
#include "../../../Windows/PropVariant.h"
@@ -27,6 +28,19 @@
namespace NArchive {
namespace NZip {
+// (kBufferSize >= kDataDescriptorSize64 + 4)
+
+static const size_t kSeqBufferSize = (size_t)1 << 14;
+
+/*
+ if (not defined ZIP_SELF_CHECK) : it reads CD and if error in first pass CD reading, it reads LOCALS-CD-MODE
+ if ( defined ZIP_SELF_CHECK) : it always reads CD and LOCALS-CD-MODE
+ use ZIP_SELF_CHECK to check LOCALS-CD-MODE for any zip archive
+*/
+
+// #define ZIP_SELF_CHECK
+
+
struct CEcd
{
UInt16 ThisDisk;
@@ -66,6 +80,7 @@ void CEcd::Parse(const Byte *p)
void CCdInfo::ParseEcd32(const Byte *p)
{
+ IsFromEcd64 = false;
// (p) includes signature
p += 4;
G16(0, ThisDisk);
@@ -79,6 +94,7 @@ void CCdInfo::ParseEcd32(const Byte *p)
void CCdInfo::ParseEcd64e(const Byte *p)
{
+ IsFromEcd64 = true;
// (p) exclude signature
G16(0, VersionMade);
G16(2, VersionNeedExtract);
@@ -106,9 +122,14 @@ struct CLocator
G64(4, Ecd64Offset);
G32(12, NumDisks);
}
-};
+ bool IsEmptyArc() const
+ {
+ return Ecd64Disk == 0 && NumDisks == 0 && Ecd64Offset == 0;
+ }
+};
+
void CInArchive::ClearRefs()
@@ -123,27 +144,174 @@ void CInArchive::ClearRefs()
void CInArchive::Close()
{
- _processedCnt = 0;
- IsArc = false;
+ _cnt = 0;
+ DisableBufMode();
+
IsArcOpen = false;
- IsMultiVol = false;
- UseDisk_in_SingleVol = false;
- EcdVolIndex = 0;
+
+ IsArc = false;
+ IsZip64 = false;
+
HeadersError = false;
HeadersWarning = false;
ExtraMinorError = false;
UnexpectedEnd = false;
+ LocalsWereRead = false;
+ LocalsCenterMerged = false;
NoCentralDir = false;
- IsZip64 = false;
+ Overflow32bit = false;
+ Cd_NumEntries_Overflow_16bit = false;
+
MarkerIsFound = false;
+ MarkerIsSafe = false;
+
+ IsMultiVol = false;
+ UseDisk_in_SingleVol = false;
+ EcdVolIndex = 0;
+ ArcInfo.Clear();
+
ClearRefs();
}
-HRESULT CInArchive::Seek(UInt64 offset)
+
+HRESULT CInArchive::Seek_SavePos(UInt64 offset)
+{
+ // InitBuf();
+ // if (!Stream) return S_FALSE;
+ return Stream->Seek(offset, STREAM_SEEK_SET, &_streamPos);
+}
+
+HRESULT CInArchive::SeekToVol(int volIndex, UInt64 offset)
+{
+ if (volIndex != Vols.StreamIndex)
+ {
+ InitBuf();
+ if (IsMultiVol && volIndex >= 0)
+ {
+ if ((unsigned)volIndex >= Vols.Streams.Size())
+ return S_FALSE;
+ if (!Vols.Streams[volIndex].Stream)
+ return S_FALSE;
+ Stream = Vols.Streams[volIndex].Stream;
+ }
+ else if (volIndex == -2)
+ {
+ if (!Vols.ZipStream)
+ return S_FALSE;
+ Stream = Vols.ZipStream;
+ }
+ else
+ Stream = StartStream;
+ Vols.StreamIndex = volIndex;
+ }
+ else
+ {
+ if (offset <= _streamPos)
+ {
+ const UInt64 back = _streamPos - offset;
+ if (back <= _bufCached)
+ {
+ _bufPos = _bufCached - (size_t)back;
+ return S_OK;
+ }
+ }
+ InitBuf();
+ }
+ return Seek_SavePos(offset);
+}
+
+
+// ---------- ReadFromCache ----------
+// reads from cache and from Stream
+// move to next volume can be allowed if (CanStartNewVol) and only before first byte reading
+
+HRESULT CInArchive::ReadFromCache(Byte *data, unsigned size, unsigned &processed)
{
- return Stream->Seek(offset, STREAM_SEEK_SET, NULL);
+ HRESULT result = S_OK;
+ processed = 0;
+
+ for (;;)
+ {
+ if (size == 0)
+ return S_OK;
+
+ const size_t avail = GetAvail();
+
+ if (avail != 0)
+ {
+ unsigned cur = size;
+ if (cur > avail)
+ cur = (unsigned)avail;
+ memcpy(data, (const Byte *)Buffer + _bufPos, cur);
+
+ data += cur;
+ size -= cur;
+ processed += cur;
+
+ _bufPos += cur;
+ _cnt += cur;
+
+ CanStartNewVol = false;
+
+ continue;
+ }
+
+ InitBuf();
+
+ if (_inBufMode)
+ {
+ UInt32 cur = 0;
+ result = Stream->Read(Buffer, (UInt32)Buffer.Size(), &cur);
+ _bufPos = 0;
+ _bufCached = cur;
+ _streamPos += cur;
+ if (cur != 0)
+ CanStartNewVol = false;
+ if (result != S_OK)
+ break;
+ if (cur != 0)
+ continue;
+ }
+ else
+ {
+ UInt32 cur = 0;
+ result = Stream->Read(data, size, &cur);
+ data += cur;
+ size -= cur;
+ processed += cur;
+ _streamPos += cur;
+ _cnt += cur;
+ if (cur != 0)
+ {
+ CanStartNewVol = false;
+ break;
+ }
+ if (result != S_OK)
+ break;
+ }
+
+ if ( !IsMultiVol
+ || !CanStartNewVol
+ || Vols.StreamIndex < 0
+ || (unsigned)Vols.StreamIndex + 1 >= Vols.Streams.Size())
+ break;
+
+ const CVols::CSubStreamInfo &s = Vols.Streams[Vols.StreamIndex + 1];
+ if (!s.Stream)
+ break;
+ result = s.SeekToStart();
+ if (result != S_OK)
+ break;
+ Vols.StreamIndex++;
+ _streamPos = 0;
+ // Vols.NeedSeek = false;
+
+ Stream = s.Stream;
+ }
+
+ return result;
}
@@ -168,18 +336,33 @@ API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size)
if (p[0] != 'P')
return k_IsArc_Res_NO;
- UInt32 value = Get32(p);
+ UInt32 sig = Get32(p);
- if (value == NSignature::kNoSpan
- || value == NSignature::kSpan)
+ if (sig == NSignature::kNoSpan || sig == NSignature::kSpan)
{
p += 4;
size -= 4;
}
- value = Get32(p);
+ sig = Get32(p);
- if (value == NSignature::kEcd)
+ if (sig == NSignature::kEcd64)
+ {
+ if (size < kEcd64_FullSize)
+ return k_IsArc_Res_NEED_MORE;
+
+ const UInt64 recordSize = Get64(p + 4);
+ if ( recordSize < kEcd64_MainSize
+ || recordSize > kEcd64_MainSize + (1 << 20))
+ return k_IsArc_Res_NO;
+ CCdInfo cdInfo;
+ cdInfo.ParseEcd64e(p + 12);
+ if (!cdInfo.IsEmptyArc())
+ return k_IsArc_Res_NO;
+ return k_IsArc_Res_YES; // k_IsArc_Res_YES_2;
+ }
+
+ if (sig == NSignature::kEcd)
{
if (size < kEcdSize)
return k_IsArc_Res_NEED_MORE;
@@ -190,8 +373,8 @@ API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size)
return k_IsArc_Res_NO;
return k_IsArc_Res_YES; // k_IsArc_Res_YES_2;
}
-
- if (value != NSignature::kLocalFileHeader)
+
+ if (sig != NSignature::kLocalFileHeader)
return k_IsArc_Res_NO;
if (size < kLocalHeaderSize)
@@ -240,8 +423,17 @@ API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size)
const Byte *p2 = p + kLocalHeaderSize;
for (size_t i = 0; i < rem; i++)
if (p2[i] == 0)
+ {
+ // we support some "bad" zip archives that contain zeros after name
+ for (size_t k = i + 1; k < rem; k++)
+ if (p2[k] != 0)
+ return k_IsArc_Res_NO;
+ break;
+ /*
if (i != nameSize - 1)
return k_IsArc_Res_NO;
+ */
+ }
}
if (size < extraOffset)
@@ -288,398 +480,562 @@ static UInt32 IsArc_Zip_2(const Byte *p, size_t size, bool isFinal)
}
+
+MY_NO_INLINE
+static const Byte *FindPK(const Byte *p, const Byte *limit)
+{
+ for (;;)
+ {
+ for (;;)
+ {
+ Byte b0 = p[0];
+ if (p >= limit)
+ return p;
+ p++;
+ if (b0 == 0x50)
+ break;
+ }
+ if (p[0] == 0x4B)
+ return p - 1;
+ }
+}
+
-HRESULT CInArchive::FindMarker(IInStream *stream, const UInt64 *searchLimit)
+/*
+---------- FindMarker ----------
+returns:
+ S_OK:
+ ArcInfo.MarkerVolIndex : volume of marker
+ ArcInfo.MarkerPos : Pos of first signature
+ ArcInfo.MarkerPos2 : Pos of main signature (local item signature in most cases)
+ _streamPos : stream pos
+ _cnt : The number of virtal Bytes after start of search to offset after signature
+ _signature : main signature
+
+ S_FALSE: can't find marker, or there is some non-zip data after marker
+
+ Error code: stream reading error.
+*/
+
+HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
{
- ArcInfo.MarkerPos = m_Position;
- ArcInfo.MarkerPos2 = m_Position;
+ ArcInfo.MarkerPos = GetVirtStreamPos();
+ ArcInfo.MarkerPos2 = ArcInfo.MarkerPos;
+ ArcInfo.MarkerVolIndex = Vols.StreamIndex;
+
+ _cnt = 0;
+
+ CanStartNewVol = false;
if (searchLimit && *searchLimit == 0)
{
Byte startBuf[kMarkerSize];
- {
- size_t processed = kMarkerSize;
- RINOK(ReadStream(stream, startBuf, &processed));
- m_Position += processed;
- if (processed != kMarkerSize)
- return S_FALSE;
- }
+ unsigned processed;
+ RINOK(ReadFromCache(startBuf, kMarkerSize, processed));
+ if (processed != kMarkerSize)
+ return S_FALSE;
- m_Signature = Get32(startBuf);
+ UInt32 marker = Get32(startBuf);
+ _signature = marker;
- if (m_Signature != NSignature::kEcd &&
- m_Signature != NSignature::kLocalFileHeader)
+ if ( marker == NSignature::kNoSpan
+ || marker == NSignature::kSpan)
{
- if (m_Signature != NSignature::kNoSpan)
- {
- if (m_Signature != NSignature::kSpan)
- return S_FALSE;
- if (m_Position != 4) // we don't support multivol archives with sfx stub
- return S_FALSE;
- ArcInfo.IsSpanMode = true;
- }
- size_t processed = kMarkerSize;
- RINOK(ReadStream(stream, startBuf, &processed));
- m_Position += processed;
+ RINOK(ReadFromCache(startBuf, kMarkerSize, processed));
if (processed != kMarkerSize)
return S_FALSE;
- m_Signature = Get32(startBuf);
- if (m_Signature != NSignature::kEcd &&
- m_Signature != NSignature::kLocalFileHeader)
- return S_FALSE;
- ArcInfo.MarkerPos2 += 4;
+ _signature = Get32(startBuf);
}
+
+ if ( _signature != NSignature::kEcd
+ && _signature != NSignature::kEcd64
+ && _signature != NSignature::kLocalFileHeader)
+ return S_FALSE;
+
+ ArcInfo.MarkerPos2 = GetVirtStreamPos() - 4;
+ ArcInfo.IsSpanMode = (marker == NSignature::kSpan);
// we use weak test in case of (*searchLimit == 0)
// since error will be detected later in Open function
- return S_OK; // maybe we need to search backward.
+ return S_OK;
}
- const size_t kBufSize = (size_t)1 << 18; // must be larger than kCheckSize
const size_t kCheckSize = (size_t)1 << 16; // must be smaller than kBufSize
- CByteArr buffer(kBufSize);
-
- size_t numBytesInBuffer = 0;
- UInt64 curScanPos = 0;
+ const size_t kBufSize = (size_t)1 << 17; // must be larger than kCheckSize
+
+ if (Buffer.Size() < kBufSize)
+ {
+ InitBuf();
+ Buffer.AllocAtLeast(kBufSize);
+ if (!Buffer.IsAllocated())
+ return E_OUTOFMEMORY;
+ }
+
+ _inBufMode = true;
+
+ UInt64 progressPrev = 0;
for (;;)
{
- size_t numReadBytes = kBufSize - numBytesInBuffer;
- RINOK(ReadStream(stream, buffer + numBytesInBuffer, &numReadBytes));
- m_Position += numReadBytes;
- numBytesInBuffer += numReadBytes;
- const bool isFinished = (numBytesInBuffer != kBufSize);
+ RINOK(LookAhead(kBufSize));
- size_t limit = numBytesInBuffer;;
+ const size_t avail = GetAvail();
+
+ size_t limitPos;
+ const bool isFinished = (avail != kBufSize);
if (isFinished)
{
- if (limit == 0)
- break;
- limit--;
+ const unsigned kMinAllowed = 4;
+ if (avail <= kMinAllowed)
+ {
+ if ( !IsMultiVol
+ || Vols.StreamIndex < 0
+ || (unsigned)Vols.StreamIndex + 1 >= Vols.Streams.Size())
+ break;
+
+ SkipLookahed(avail);
+
+ const CVols::CSubStreamInfo &s = Vols.Streams[Vols.StreamIndex + 1];
+ if (!s.Stream)
+ break;
+
+ RINOK(s.SeekToStart());
+
+ InitBuf();
+ Vols.StreamIndex++;
+ _streamPos = 0;
+ Stream = s.Stream;
+ continue;
+ }
+ limitPos = avail - kMinAllowed;
}
else
- limit -= kCheckSize;
+ limitPos = (avail - kCheckSize);
- if (searchLimit && curScanPos + limit > *searchLimit)
- limit = (size_t)(*searchLimit - curScanPos + 1);
+ // we don't check at (limitPos) for good fast aligned operations
- if (limit < 1)
+ if (searchLimit)
+ {
+ if (_cnt > *searchLimit)
+ break;
+ UInt64 rem = *searchLimit - _cnt;
+ if (limitPos > rem)
+ limitPos = (size_t)rem + 1;
+ }
+
+ if (limitPos == 0)
break;
- const Byte *buf = buffer;
- for (size_t pos = 0; pos < limit; pos++)
+ const Byte * const pStart = Buffer + _bufPos;
+ const Byte * p = pStart;
+ const Byte * const limit = pStart + limitPos;
+
+ for (;; p++)
{
- if (buf[pos] != 0x50)
- continue;
- if (buf[pos + 1] != 0x4B)
- continue;
- size_t rem = numBytesInBuffer - pos;
- UInt32 res = IsArc_Zip_2(buf + pos, rem, isFinished);
+ p = FindPK(p, limit);
+ if (p >= limit)
+ break;
+ const size_t rem = pStart + avail - p;
+ UInt32 res = IsArc_Zip_2(p, rem, isFinished);
if (res != k_IsArc_Res_NO)
{
if (rem < kMarkerSize)
return S_FALSE;
- m_Signature = Get32(buf + pos);
- ArcInfo.MarkerPos += curScanPos + pos;
+ _signature = Get32(p);
+ SkipLookahed(p - pStart);
+ ArcInfo.MarkerVolIndex = Vols.StreamIndex;
+ ArcInfo.MarkerPos = GetVirtStreamPos();
ArcInfo.MarkerPos2 = ArcInfo.MarkerPos;
- if (m_Signature == NSignature::kNoSpan
- || m_Signature == NSignature::kSpan)
+ SkipLookahed(4);
+ if ( _signature == NSignature::kNoSpan
+ || _signature == NSignature::kSpan)
{
- m_Signature = Get32(buf + pos + 4);
+ if (rem < kMarkerSize * 2)
+ return S_FALSE;
+ ArcInfo.IsSpanMode = (_signature == NSignature::kSpan);
+ _signature = Get32(p + 4);
ArcInfo.MarkerPos2 += 4;
+ SkipLookahed(4);
}
- m_Position = ArcInfo.MarkerPos2 + kMarkerSize;
return S_OK;
}
}
- if (isFinished)
+ if (!IsMultiVol && isFinished)
break;
- curScanPos += limit;
- numBytesInBuffer -= limit;
- memmove(buffer, buffer + limit, numBytesInBuffer);
+ SkipLookahed(p - pStart);
+
+ if (Callback && (_cnt - progressPrev) >= ((UInt32)1 << 23))
+ {
+ progressPrev = _cnt;
+ // const UInt64 numFiles64 = 0;
+ RINOK(Callback->SetCompleted(NULL, &_cnt));
+ }
}
return S_FALSE;
}
-HRESULT CInArchive::IncreaseRealPosition(Int64 addValue, bool &isFinished)
+/*
+---------- IncreaseRealPosition ----------
+moves virtual offset in virtual stream.
+changing to new volumes is allowed
+*/
+
+HRESULT CInArchive::IncreaseRealPosition(UInt64 offset, bool &isFinished)
{
isFinished = false;
+
+ for (;;)
+ {
+ const size_t avail = GetAvail();
+
+ if (offset <= avail)
+ {
+ _bufPos += (size_t)offset;
+ _cnt += offset;
+ return S_OK;
+ }
+
+ _cnt += avail;
+ offset -= avail;
+
+ _bufCached = 0;
+ _bufPos = 0;
+
+ if (!_inBufMode)
+ break;
+
+ CanStartNewVol = true;
+ LookAhead(1);
+
+ if (GetAvail() == 0)
+ return S_OK;
+ }
+
if (!IsMultiVol)
- return Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position);
+ {
+ _cnt += offset;
+ return Stream->Seek(offset, STREAM_SEEK_CUR, &_streamPos);
+ }
for (;;)
{
- if (addValue == 0)
+ if (offset == 0)
return S_OK;
- if (addValue > 0)
+
+ if (Vols.StreamIndex < 0)
+ return S_FALSE;
+ if ((unsigned)Vols.StreamIndex >= Vols.Streams.Size())
{
- if (Vols.StreamIndex < 0)
- return S_FALSE;
- if ((unsigned)Vols.StreamIndex >= Vols.Streams.Size())
+ isFinished = true;
+ return S_OK;
+ }
+ {
+ const CVols::CSubStreamInfo &s = Vols.Streams[Vols.StreamIndex];
+ if (!s.Stream)
{
isFinished = true;
return S_OK;
}
+ if (_streamPos > s.Size)
+ return S_FALSE;
+ const UInt64 rem = s.Size - _streamPos;
+ if ((UInt64)offset <= rem)
{
- const CVols::CSubStreamInfo &s = Vols.Streams[Vols.StreamIndex];
- if (!s.Stream)
- {
- isFinished = true;
- return S_OK;
- }
- if (m_Position > s.Size)
- return S_FALSE;
- UInt64 rem = s.Size - m_Position;
- if ((UInt64)addValue <= rem)
- return Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position);
- RINOK(Stream->Seek(s.Size, STREAM_SEEK_SET, &m_Position));
- addValue -= rem;
- Stream = NULL;
- Vols.StreamIndex++;
- if ((unsigned)Vols.StreamIndex >= Vols.Streams.Size())
- {
- isFinished = true;
- return S_OK;
- }
- }
- const CVols::CSubStreamInfo &s2 = Vols.Streams[Vols.StreamIndex];
- if (!s2.Stream)
- {
- isFinished = true;
- return S_OK;
+ _cnt += offset;
+ return Stream->Seek(offset, STREAM_SEEK_CUR, &_streamPos);
}
- Stream = s2.Stream;
- m_Position = 0;
- RINOK(Stream->Seek(0, STREAM_SEEK_SET, &m_Position));
+ RINOK(Seek_SavePos(s.Size));
+ offset -= rem;
+ _cnt += rem;
}
- else
+
+ Stream = NULL;
+ _streamPos = 0;
+ Vols.StreamIndex++;
+ if ((unsigned)Vols.StreamIndex >= Vols.Streams.Size())
{
- if (!Stream)
- return S_FALSE;
- {
- if (m_Position >= (UInt64)(-addValue))
- return Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position);
- addValue += m_Position;
- RINOK(Stream->Seek(0, STREAM_SEEK_SET, &m_Position));
- m_Position = 0;
- Stream = NULL;
- if (--Vols.StreamIndex < 0)
- return S_FALSE;
- }
- const CVols::CSubStreamInfo &s2 = Vols.Streams[Vols.StreamIndex];
- if (!s2.Stream)
- return S_FALSE;
- Stream = s2.Stream;
- m_Position = s2.Size;
- RINOK(Stream->Seek(s2.Size, STREAM_SEEK_SET, &m_Position));
+ isFinished = true;
+ return S_OK;
+ }
+ const CVols::CSubStreamInfo &s2 = Vols.Streams[Vols.StreamIndex];
+ if (!s2.Stream)
+ {
+ isFinished = true;
+ return S_OK;
}
+ Stream = s2.Stream;
+ RINOK(Seek_SavePos(0));
}
}
-class CUnexpectEnd {};
+/*
+---------- LookAhead ----------
+Reads data to buffer, if required.
-HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
-{
- size_t realProcessedSize = size;
- HRESULT result = S_OK;
- if (_inBufMode)
- {
- try { realProcessedSize = _inBuffer.ReadBytes((Byte *)data, size); }
- catch (const CInBufferException &e) { return e.ErrorCode; }
- }
- else
- result = ReadStream(Stream, data, &realProcessedSize);
- if (processedSize)
- *processedSize = (UInt32)realProcessedSize;
- m_Position += realProcessedSize;
- return result;
-}
+It can read from volumes as long as Buffer.Size().
+But it moves to new volume, only if it's required to provide minRequired bytes in buffer.
-void CInArchive::SafeReadBytes(void *data, unsigned size)
-{
- size_t processed = size;
-
- HRESULT result = S_OK;
+in:
+ (minRequired <= Buffer.Size())
- if (!_inBufMode)
- result = ReadStream(Stream, data, &processed);
- else
+return:
+ S_OK : if (GetAvail() < minRequired) after function return, it's end of stream(s) data, or no new volume stream.
+ Error codes: IInStream::Read() error or IInStream::Seek() error for multivol
+*/
+
+HRESULT CInArchive::LookAhead(size_t minRequired)
+{
+ for (;;)
{
- for (;;)
+ const size_t avail = GetAvail();
+
+ if (minRequired <= avail)
+ return S_OK;
+
+ if (_bufPos != 0)
{
- processed = _inBuffer.ReadBytes((Byte *)data, size);
- if (processed != 0
- || IsMultiVol
- || !CanStartNewVol
- || Vols.StreamIndex < 0
- || (unsigned)Vols.StreamIndex >= Vols.Streams.Size())
- break;
- Vols.StreamIndex++;
- const CVols::CSubStreamInfo &s = Vols.Streams[Vols.StreamIndex];
- if (!s.Stream)
- break;
- // if (Vols.NeedSeek)
- {
- result = s.Stream->Seek(0, STREAM_SEEK_SET, NULL);
- m_Position = 0;
- if (result != S_OK)
- break;
- Vols.NeedSeek = false;
- }
- _inBuffer.SetStream(s.Stream);
- _inBuffer.Init();
+ if (avail != 0)
+ memmove(Buffer, Buffer + _bufPos, avail);
+ _bufPos = 0;
+ _bufCached = avail;
}
- CanStartNewVol = false;
+
+ const size_t pos = _bufCached;
+ UInt32 processed = 0;
+ HRESULT res = Stream->Read(Buffer + pos, (UInt32)(Buffer.Size() - pos), &processed);
+ _streamPos += processed;
+ _bufCached += processed;
+
+ if (res != S_OK)
+ return res;
+
+ if (processed != 0)
+ continue;
+
+ if ( !IsMultiVol
+ || !CanStartNewVol
+ || Vols.StreamIndex < 0
+ || (unsigned)Vols.StreamIndex + 1 >= Vols.Streams.Size())
+ return S_OK;
+
+ const CVols::CSubStreamInfo &s = Vols.Streams[Vols.StreamIndex + 1];
+ if (!s.Stream)
+ return S_OK;
+
+ RINOK(s.SeekToStart());
+
+ Vols.StreamIndex++;
+ _streamPos = 0;
+ Stream = s.Stream;
+ // Vols.NeedSeek = false;
}
+}
+
+
+class CUnexpectEnd {};
+
+
+/*
+---------- SafeRead ----------
+
+reads data of exact size from stream(s)
- m_Position += processed;
- _processedCnt += processed;
+in:
+ _inBufMode
+ if (CanStartNewVol) it can go to next volume before first byte reading, if there is end of volume data.
+in, out:
+ _streamPos : position in Stream
+ Stream
+ Vols : if (IsMultiVol)
+ _cnt
+
+out:
+ (CanStartNewVol == false), if some data was read
+
+return:
+ S_OK : success reading of requested data
+
+exceptions:
+ CSystemException() - stream reading error
+ CUnexpectEnd() : could not read data of requested size
+*/
+
+void CInArchive::SafeRead(Byte *data, unsigned size)
+{
+ unsigned processed;
+ HRESULT result = ReadFromCache(data, size, processed);
if (result != S_OK)
throw CSystemException(result);
-
- if (processed != size)
+ if (size != processed)
throw CUnexpectEnd();
}
void CInArchive::ReadBuffer(CByteBuffer &buffer, unsigned size)
{
buffer.Alloc(size);
- if (size > 0)
- SafeReadBytes(buffer, size);
+ if (size != 0)
+ SafeRead(buffer, size);
}
-Byte CInArchive::ReadByte()
+// Byte CInArchive::ReadByte () { Byte b; SafeRead(&b, 1); return b; }
+// UInt16 CInArchive::ReadUInt16() { Byte buf[2]; SafeRead(buf, 2); return Get16(buf); }
+UInt32 CInArchive::ReadUInt32() { Byte buf[4]; SafeRead(buf, 4); return Get32(buf); }
+UInt64 CInArchive::ReadUInt64() { Byte buf[8]; SafeRead(buf, 8); return Get64(buf); }
+
+void CInArchive::ReadSignature()
{
- Byte b;
- SafeReadBytes(&b, 1);
- return b;
+ CanStartNewVol = true;
+ _signature = ReadUInt32();
+ // CanStartNewVol = false; // it's already changed in SafeRead
}
-UInt16 CInArchive::ReadUInt16() { Byte buf[2]; SafeReadBytes(buf, 2); return Get16(buf); }
-UInt32 CInArchive::ReadUInt32() { Byte buf[4]; SafeReadBytes(buf, 4); return Get32(buf); }
-UInt64 CInArchive::ReadUInt64() { Byte buf[8]; SafeReadBytes(buf, 8); return Get64(buf); }
-// we use Skip() inside headers only, so no need for stream change in multivol.
+// we Skip() inside headers only, so no need for stream change in multivol.
-void CInArchive::Skip(unsigned num)
+void CInArchive::Skip(size_t num)
{
- if (_inBufMode)
- {
- size_t skip = _inBuffer.Skip(num);
- m_Position += skip;
- _processedCnt += skip;
- if (skip != num)
- throw CUnexpectEnd();
- }
- else
+ while (num != 0)
{
- for (unsigned i = 0; i < num; i++)
- ReadByte();
+ const unsigned kBufSize = (size_t)1 << 10;
+ Byte buf[kBufSize];
+ unsigned step = kBufSize;
+ if (step > num)
+ step = (unsigned)num;
+ SafeRead(buf, step);
+ num -= step;
}
}
-void CInArchive::Skip64(UInt64 num)
+/*
+HRESULT CInArchive::Callback_Completed(unsigned numFiles)
+{
+ const UInt64 numFiles64 = numFiles;
+ return Callback->SetCompleted(&numFiles64, &_cnt);
+}
+*/
+
+HRESULT CInArchive::Skip64(UInt64 num, unsigned numFiles)
{
- for (UInt64 i = 0; i < num; i++)
- ReadByte();
+ if (num == 0)
+ return S_OK;
+
+ for (;;)
+ {
+ size_t step = (size_t)1 << 24;
+ if (step > num)
+ step = (size_t)num;
+ Skip(step);
+ num -= step;
+ if (num == 0)
+ return S_OK;
+ if (Callback)
+ {
+ const UInt64 numFiles64 = numFiles;
+ RINOK(Callback->SetCompleted(&numFiles64, &_cnt));
+ }
+ }
}
-void CInArchive::ReadFileName(unsigned size, AString &s)
+bool CInArchive::ReadFileName(unsigned size, AString &s)
{
if (size == 0)
{
s.Empty();
- return;
+ return true;
+ }
+ char *p = s.GetBuf(size);
+ SafeRead((Byte *)p, size);
+ unsigned i = size;
+ do
+ {
+ if (p[i - 1] != 0)
+ break;
}
- SafeReadBytes(s.GetBuf(size), size);
+ while (--i);
s.ReleaseBuf_CalcLen(size);
+ return s.Len() == i;
}
-bool CInArchive::ReadExtra(unsigned extraSize, CExtraBlock &extraBlock,
- UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber)
+#define ZIP64_IS_32_MAX(n) ((n) == 0xFFFFFFFF)
+#define ZIP64_IS_16_MAX(n) ((n) == 0xFFFF)
+
+
+bool CInArchive::ReadExtra(unsigned extraSize, CExtraBlock &extra,
+ UInt64 &unpackSize, UInt64 &packSize, UInt64 &localOffset, UInt32 &disk)
{
- extraBlock.Clear();
+ extra.Clear();
- UInt32 remain = extraSize;
-
- while (remain >= 4)
+ while (extraSize >= 4)
{
CExtraSubBlock subBlock;
- subBlock.ID = ReadUInt16();
- unsigned dataSize = ReadUInt16();
- remain -= 4;
- if (dataSize > remain) // it's bug
+ const UInt32 pair = ReadUInt32();
+ subBlock.ID = (pair & 0xFFFF);
+ unsigned size = (unsigned)(pair >> 16);
+
+ extraSize -= 4;
+
+ if (size > extraSize)
{
+ // it's error in extra
HeadersWarning = true;
- Skip(remain);
+ extra.Error = true;
+ Skip(extraSize);
return false;
}
+
+ extraSize -= size;
+
if (subBlock.ID == NFileHeader::NExtraID::kZip64)
{
- if (unpackSize == 0xFFFFFFFF)
- {
- if (dataSize < 8)
- {
- HeadersWarning = true;
- Skip(remain);
- return false;
- }
- unpackSize = ReadUInt64();
- remain -= 8;
- dataSize -= 8;
- }
- if (packSize == 0xFFFFFFFF)
- {
- if (dataSize < 8)
- break;
- packSize = ReadUInt64();
- remain -= 8;
- dataSize -= 8;
- }
- if (localHeaderOffset == 0xFFFFFFFF)
- {
- if (dataSize < 8)
- break;
- localHeaderOffset = ReadUInt64();
- remain -= 8;
- dataSize -= 8;
- }
- if (diskStartNumber == 0xFFFF)
+ extra.IsZip64 = true;
+ bool isOK = true;
+
+ if (ZIP64_IS_32_MAX(unpackSize))
+ if (size < 8) isOK = false; else { size -= 8; unpackSize = ReadUInt64(); }
+
+ if (isOK && ZIP64_IS_32_MAX(packSize))
+ if (size < 8) isOK = false; else { size -= 8; packSize = ReadUInt64(); }
+
+ if (isOK && ZIP64_IS_32_MAX(localOffset))
+ if (size < 8) isOK = false; else { size -= 8; localOffset = ReadUInt64(); }
+
+ if (isOK && ZIP64_IS_16_MAX(disk))
+ if (size < 4) isOK = false; else { size -= 4; disk = ReadUInt32(); }
+
+ if (!isOK || size != 0)
{
- if (dataSize < 4)
- break;
- diskStartNumber = ReadUInt32();
- remain -= 4;
- dataSize -= 4;
+ HeadersWarning = true;
+ extra.Error = true;
+ extra.IsZip64_Error = true;
+ Skip(size);
}
- Skip(dataSize);
}
else
{
- ReadBuffer(subBlock.Data, dataSize);
- extraBlock.SubBlocks.Add(subBlock);
+ ReadBuffer(subBlock.Data, size);
+ extra.SubBlocks.Add(subBlock);
}
- remain -= dataSize;
}
- if (remain != 0)
+ if (extraSize != 0)
{
ExtraMinorError = true;
+ extra.MinorError = true;
// 7-Zip before 9.31 created incorrect WsAES Extra in folder's local headers.
// so we don't return false, but just set warning flag
// return false;
+ Skip(extraSize);
}
-
- Skip(remain);
+
return true;
}
@@ -691,7 +1047,7 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
item.Disk = Vols.StreamIndex;
const unsigned kPureHeaderSize = kLocalHeaderSize - 4;
Byte p[kPureHeaderSize];
- SafeReadBytes(p, kPureHeaderSize);
+ SafeRead(p, kPureHeaderSize);
{
unsigned i;
for (i = 0; i < kPureHeaderSize && p[i] == 0; i++);
@@ -709,8 +1065,9 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
G32(18, item.Size);
const unsigned nameSize = Get16(p + 22);
const unsigned extraSize = Get16(p + 24);
- ReadFileName(nameSize, item.Name);
+ bool isOkName = ReadFileName(nameSize, item.Name);
item.LocalFullHeaderSize = kLocalHeaderSize + (UInt32)nameSize + extraSize;
+ item.DescriptorWasRead = false;
/*
if (item.IsDir())
@@ -719,10 +1076,9 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
if (extraSize > 0)
{
- UInt64 localHeaderOffset = 0;
- UInt32 diskStartNumber = 0;
- if (!ReadExtra(extraSize, item.LocalExtra, item.Size, item.PackSize,
- localHeaderOffset, diskStartNumber))
+ UInt64 localOffset = 0;
+ UInt32 disk = 0;
+ if (!ReadExtra(extraSize, item.LocalExtra, item.Size, item.PackSize, localOffset, disk))
{
/* Most of archives are OK for Extra. But there are some rare cases
that have error. And if error in first item, it can't open archive.
@@ -739,8 +1095,8 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
if (item.Name.Len() != nameSize)
{
- // we support "bad" archives with null-terminated name.
- if (item.Name.Len() + 1 != nameSize)
+ // we support some "bad" zip archives that contain zeros after name
+ if (!isOkName)
return false;
HeadersWarning = true;
}
@@ -758,11 +1114,11 @@ static bool FlagsAreSame(const CItem &i1, const CItem &i2)
UInt32 mask = 0xFFFF;
switch (i1.Method)
{
- case NFileHeader::NCompressionMethod::kDeflated:
+ case NFileHeader::NCompressionMethod::kDeflate:
mask = 0x7FF9;
break;
default:
- if (i1.Method <= NFileHeader::NCompressionMethod::kImploded)
+ if (i1.Method <= NFileHeader::NCompressionMethod::kImplode)
mask = 0x7FFF;
}
@@ -805,9 +1161,9 @@ static bool AreItemsEqual(const CItemEx &localItem, const CItemEx &cdItem)
return false;
if (!localItem.HasDescriptor())
{
- if (cdItem.Crc != localItem.Crc ||
- cdItem.PackSize != localItem.PackSize ||
- cdItem.Size != localItem.Size)
+ if (cdItem.PackSize != localItem.PackSize
+ || cdItem.Size != localItem.Size
+ || cdItem.Crc != localItem.Crc && cdItem.Crc != 0) // some program writes 0 to crc field in central directory
return false;
}
/* pkzip 2.50 creates incorrect archives. It uses
@@ -833,7 +1189,8 @@ static bool AreItemsEqual(const CItemEx &localItem, const CItemEx &cdItem)
// pkzip 2.50 uses DOS encoding in central dir and WIN encoding in local header.
// so we ignore that error
if (hostOs != NFileHeader::NHostOS::kFAT
- || cdItem.MadeByVersion.Version != 25)
+ || cdItem.MadeByVersion.Version < 25
+ || cdItem.MadeByVersion.Version > 40)
return false;
}
}
@@ -847,9 +1204,13 @@ static bool AreItemsEqual(const CItemEx &localItem, const CItemEx &cdItem)
}
-HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail)
+HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail, bool &headersError)
{
+ InitBuf();
+ _inBufMode = false;
+
isAvail = true;
+ headersError = false;
if (item.FromLocal)
return S_OK;
try
@@ -863,15 +1224,13 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail)
isAvail = false;
return S_FALSE;
}
- IInStream *str2 = Vols.Streams[item.Disk].Stream;
- if (!str2)
+ Stream = Vols.Streams[item.Disk].Stream;
+ Vols.StreamIndex = item.Disk;
+ if (!Stream)
{
isAvail = false;
return S_FALSE;
}
- RINOK(str2->Seek(offset, STREAM_SEEK_SET, NULL));
- Stream = str2;
- Vols.StreamIndex = item.Disk;
}
else
{
@@ -888,9 +1247,16 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail)
isAvail = false;
return S_FALSE;
}
- RINOK(Seek(offset));
}
+ RINOK(Seek_SavePos(offset));
+
+ /*
+ // we can check buf mode
+ InitBuf();
+ _inBufMode = true;
+ Buffer.AllocAtLeast(1 << 10);
+ */
CItemEx localItem;
if (ReadUInt32() != NSignature::kLocalFileHeader)
@@ -900,6 +1266,11 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail)
return S_FALSE;
item.LocalFullHeaderSize = localItem.LocalFullHeaderSize;
item.LocalExtra = localItem.LocalExtra;
+ if (item.Crc != localItem.Crc && !localItem.HasDescriptor())
+ {
+ item.Crc = localItem.Crc;
+ headersError = true;
+ }
item.FromLocal = true;
}
catch(...) { return S_FALSE; }
@@ -907,53 +1278,202 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail)
}
-HRESULT CInArchive::ReadLocalItemDescriptor(CItemEx &item)
+/*
+---------- FindDescriptor ----------
+
+in:
+ _streamPos : position in Stream
+ Stream :
+ Vols : if (IsMultiVol)
+
+action:
+ searches descriptor in input stream(s).
+ sets
+ item.DescriptorWasRead = true;
+ item.Size
+ item.PackSize
+ item.Crc
+ if descriptor was found
+
+out:
+ S_OK:
+ if ( item.DescriptorWasRead) : if descriptor was found
+ if (!item.DescriptorWasRead) : if descriptor was not found : unexpected end of stream(s)
+
+ S_FALSE: if no items or there is just one item with strange properies that doesn't look like real archive.
+
+ another error code: Callback error.
+
+exceptions :
+ CSystemException() : stream reading error
+*/
+
+HRESULT CInArchive::FindDescriptor(CItemEx &item, unsigned numFiles)
{
- const unsigned kBufSize = (1 << 12);
- Byte buf[kBufSize];
+ // const size_t kBufSize = (size_t)1 << 5; // don't increase it too much. It reads data look ahead.
+
+ // Buffer.Alloc(kBufSize);
+ // Byte *buf = Buffer;
- UInt32 numBytesInBuffer = 0;
- UInt32 packedSize = 0;
+ UInt64 packedSize = 0;
+ UInt64 progressPrev = _cnt;
+
for (;;)
{
- UInt32 processedSize;
- RINOK(ReadBytes(buf + numBytesInBuffer, kBufSize - numBytesInBuffer, &processedSize));
- numBytesInBuffer += processedSize;
- if (numBytesInBuffer < kDataDescriptorSize)
- return S_FALSE;
+ /* appnote specification claims that we must use 64-bit descriptor, if there is zip64 extra.
+ But some old third-party xps archives used 64-bit descriptor without zip64 extra. */
+ // unsigned descriptorSize = kDataDescriptorSize64 + kNextSignatureSize;
+
+ // const unsigned kNextSignatureSize = 0; // we can disable check for next signatuire
+ const unsigned kNextSignatureSize = 4; // we check also for signature for next File headear
+
+ const unsigned descriptorSize4 = item.GetDescriptorSize() + kNextSignatureSize;
+
+ if (descriptorSize4 > Buffer.Size()) return E_FAIL;
+
+ // size_t processedSize;
+ CanStartNewVol = true;
+ RINOK(LookAhead(descriptorSize4));
+ const size_t avail = GetAvail();
+
+ if (avail < descriptorSize4)
+ {
+ // we write to packSize all these available bytes.
+ // later it's simpler to work with such value than with 0
+ if (item.PackSize == 0)
+ item.PackSize = packedSize + avail;
+ return S_OK;
+ }
+
+ const Byte * const pStart = Buffer + _bufPos;
+ const Byte * p = pStart;
+ const Byte * const limit = pStart + (avail - descriptorSize4);
- UInt32 i;
- for (i = 0; i <= numBytesInBuffer - kDataDescriptorSize; i++)
+ for (; p <= limit; p++)
{
// descriptor signature field is Info-ZIP's extension to pkware Zip specification.
// New ZIP specification also allows descriptorSignature.
- if (buf[i] != 0x50)
+
+ p = FindPK(p, limit + 1);
+ if (p > limit)
+ break;
+
+ /*
+ if (*p != 0x50)
+ continue;
+ */
+
+ if (Get32(p) != NSignature::kDataDescriptor)
continue;
- // !!!! It must be fixed for Zip64 archives
- if (Get32(buf + i) == NSignature::kDataDescriptor)
+
+ // we check next signatuire after descriptor
+ // maybe we need check only 2 bytes "PK" instead of 4 bytes, if some another type of header is possible after descriptor
+ const UInt32 sig = Get32(p + descriptorSize4 - kNextSignatureSize);
+ if ( sig != NSignature::kLocalFileHeader
+ && sig != NSignature::kCentralFileHeader)
+ continue;
+
+ const UInt64 packSizeCur = packedSize + (p - pStart);
+ if (descriptorSize4 == kDataDescriptorSize64 + kNextSignatureSize) // if (item.LocalExtra.IsZip64)
{
- UInt32 descriptorPackSize = Get32(buf + i + 8);
- if (descriptorPackSize == packedSize + i)
- {
- item.Crc = Get32(buf + i + 4);
- item.PackSize = descriptorPackSize;
- item.Size = Get32(buf + i + 12);
- bool isFinished;
- return IncreaseRealPosition((Int64)(Int32)(0 - (numBytesInBuffer - i - kDataDescriptorSize)), isFinished);
- }
+ const UInt64 descriptorPackSize = Get64(p + 8);
+ if (descriptorPackSize != packSizeCur)
+ continue;
+ item.Size = Get64(p + 16);
}
+ else
+ {
+ const UInt32 descriptorPackSize = Get32(p + 8);
+ if (descriptorPackSize != (UInt32)packSizeCur)
+ continue;
+ item.Size = Get32(p + 12);
+ // that item.Size can be truncated to 32-bit value here
+ }
+ // We write calculated 64-bit packSize, even if descriptor64 was not used
+ item.PackSize = packSizeCur;
+
+ item.DescriptorWasRead = true;
+ item.Crc = Get32(p + 4);
+
+ const size_t skip = (p - pStart) + descriptorSize4 - kNextSignatureSize;
+
+ SkipLookahed(skip);
+
+ return S_OK;
}
- packedSize += i;
- unsigned j;
- for (j = 0; i < numBytesInBuffer; i++, j++)
- buf[j] = buf[i];
- numBytesInBuffer = j;
+ const size_t skip = (p - pStart);
+ SkipLookahed(skip);
+
+ packedSize += skip;
+
+ if (Callback)
+ if (_cnt - progressPrev >= ((UInt32)1 << 22))
+ {
+ progressPrev = _cnt;
+ const UInt64 numFiles64 = numFiles;
+ RINOK(Callback->SetCompleted(&numFiles64, &_cnt));
+ }
}
}
+HRESULT CInArchive::CheckDescriptor(const CItemEx &item)
+{
+ if (!item.HasDescriptor())
+ return S_OK;
+
+ // pkzip's version without descriptor signature is not supported
+
+ bool isFinished = false;
+ RINOK(IncreaseRealPosition(item.PackSize, isFinished));
+ if (isFinished)
+ return S_FALSE;
+
+ /*
+ if (!IsMultiVol)
+ {
+ RINOK(Seek_SavePos(ArcInfo.Base + item.GetDataPosition() + item.PackSize));
+ }
+ */
+
+ Byte buf[kDataDescriptorSize64];
+ try
+ {
+ CanStartNewVol = true;
+ SafeRead(buf, item.GetDescriptorSize());
+ }
+ catch (const CSystemException &e) { return e.ErrorCode; }
+ // catch (const CUnexpectEnd &)
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ // RINOK(ReadStream_FALSE(Stream, buf, item.GetDescriptorSize()));
+
+ if (Get32(buf) != NSignature::kDataDescriptor)
+ return S_FALSE;
+ UInt32 crc = Get32(buf + 4);
+ UInt64 packSize, unpackSize;
+
+ if (item.LocalExtra.IsZip64)
+ {
+ packSize = Get64(buf + 8);
+ unpackSize = Get64(buf + 16);
+ }
+ else
+ {
+ packSize = Get32(buf + 8);
+ unpackSize = Get32(buf + 12);
+ }
+
+ if (crc != item.Crc || item.PackSize != packSize || item.Size != unpackSize)
+ return S_FALSE;
+ return S_OK;
+}
+
+
HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item)
{
if (item.FromLocal)
@@ -961,32 +1481,12 @@ HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item)
try
{
bool isAvail = true;
- RINOK(ReadLocalItemAfterCdItem(item, isAvail));
+ bool headersError = false;
+ RINOK(ReadLocalItemAfterCdItem(item, isAvail, headersError));
+ if (headersError)
+ return S_FALSE;
if (item.HasDescriptor())
- {
- // pkzip's version without descriptor is not supported
- RINOK(Seek(ArcInfo.Base + item.GetDataPosition() + item.PackSize));
- if (ReadUInt32() != NSignature::kDataDescriptor)
- return S_FALSE;
- UInt32 crc = ReadUInt32();
- UInt64 packSize, unpackSize;
-
- /*
- if (IsZip64)
- {
- packSize = ReadUInt64();
- unpackSize = ReadUInt64();
- }
- else
- */
- {
- packSize = ReadUInt32();
- unpackSize = ReadUInt32();
- }
-
- if (crc != item.Crc || item.PackSize != packSize || item.Size != unpackSize)
- return S_FALSE;
- }
+ return CheckDescriptor(item);
}
catch(...) { return S_FALSE; }
return S_OK;
@@ -997,7 +1497,7 @@ HRESULT CInArchive::ReadCdItem(CItemEx &item)
{
item.FromCentral = true;
Byte p[kCentralHeaderSize - 4];
- SafeReadBytes(p, kCentralHeaderSize - 4);
+ SafeRead(p, kCentralHeaderSize - 4);
item.MadeByVersion.Version = p[0];
item.MadeByVersion.HostOS = p[1];
@@ -1036,15 +1536,19 @@ HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo)
{
if (offset >= ((UInt64)1 << 63))
return S_FALSE;
- RINOK(Seek(offset));
Byte buf[kEcd64_FullSize];
- RINOK(ReadStream_FALSE(Stream, buf, kEcd64_FullSize));
+ RINOK(SeekToVol(Vols.StreamIndex, offset));
+ unsigned processed = 0;
+ ReadFromCache(buf, kEcd64_FullSize, processed);
+
+ if (processed != kEcd64_FullSize)
+ return S_FALSE;
if (Get32(buf) != NSignature::kEcd64)
return S_FALSE;
UInt64 mainSize = Get64(buf + 4);
- if (mainSize < kEcd64_MainSize || mainSize > ((UInt64)1 << 32))
+ if (mainSize < kEcd64_MainSize || mainSize > ((UInt64)1 << 40))
return S_FALSE;
cdInfo.ParseEcd64e(buf + 12);
return S_OK;
@@ -1057,27 +1561,49 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode)
UInt64 endPos;
+ // There are no useful data in cache in most cases here.
+ // So here we don't use cache data from previous operations .
+
+ InitBuf();
RINOK(Stream->Seek(0, STREAM_SEEK_END, &endPos));
+ _streamPos = endPos;
+
+ // const UInt32 kBufSizeMax2 = ((UInt32)1 << 16) + kEcdSize + kEcd64Locator_Size + kEcd64_FullSize;
+ const size_t kBufSizeMax = ((size_t)1 << 17); // must be larger than kBufSizeMax2
- const UInt32 kBufSizeMax = ((UInt32)1 << 16) + kEcdSize + kEcd64Locator_Size + kEcd64_FullSize;
- const UInt32 bufSize = (endPos < kBufSizeMax) ? (UInt32)endPos : kBufSizeMax;
+ const size_t bufSize = (endPos < kBufSizeMax) ? (size_t)endPos : kBufSizeMax;
if (bufSize < kEcdSize)
return S_FALSE;
- CByteArr byteBuffer(bufSize);
+ // CByteArr byteBuffer(bufSize);
+
+ if (Buffer.Size() < kBufSizeMax)
+ {
+ // InitBuf();
+ Buffer.AllocAtLeast(kBufSizeMax);
+ if (!Buffer.IsAllocated())
+ return E_OUTOFMEMORY;
+ }
- const UInt64 startPos = endPos - bufSize;
- RINOK(Stream->Seek(startPos, STREAM_SEEK_SET, &m_Position));
- if (m_Position != startPos)
+ RINOK(Seek_SavePos(endPos - bufSize));
+
+ size_t processed = bufSize;
+ HRESULT res = ReadStream(Stream, Buffer, &processed);
+ _streamPos += processed;
+ _bufCached = processed;
+ _bufPos = 0;
+ _cnt += processed;
+ if (res != S_OK)
+ return res;
+ if (processed != bufSize)
return S_FALSE;
+
- RINOK(ReadStream_FALSE(Stream, byteBuffer, bufSize));
-
- for (UInt32 i = bufSize - kEcdSize + 1;;)
+ for (size_t i = bufSize - kEcdSize + 1;;)
{
if (i == 0)
return S_FALSE;
- const Byte *buf = byteBuffer;
+ const Byte *buf = Buffer;
for (;;)
{
@@ -1095,24 +1621,26 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode)
if (i >= kEcd64Locator_Size)
{
- const Byte *locatorPtr = buf + i - kEcd64Locator_Size;
- if (Get32(locatorPtr) == NSignature::kEcd64Locator)
+ const size_t locatorIndex = i - kEcd64Locator_Size;
+ if (Get32(buf + locatorIndex) == NSignature::kEcd64Locator)
{
CLocator locator;
- locator.Parse(locatorPtr + 4);
- if ((cdInfo.ThisDisk == locator.NumDisks - 1 || cdInfo.ThisDisk == 0xFFFF)
+ locator.Parse(buf + locatorIndex + 4);
+ if ((cdInfo.ThisDisk == locator.NumDisks - 1 || ZIP64_IS_16_MAX(cdInfo.ThisDisk))
&& locator.Ecd64Disk < locator.NumDisks)
{
- if (locator.Ecd64Disk != cdInfo.ThisDisk && cdInfo.ThisDisk != 0xFFFF)
+ if (locator.Ecd64Disk != cdInfo.ThisDisk && !ZIP64_IS_16_MAX(cdInfo.ThisDisk))
return E_NOTIMPL;
// Most of the zip64 use fixed size Zip64 ECD
// we try relative backward reading.
UInt64 absEcd64 = endPos - bufSize + i - (kEcd64Locator_Size + kEcd64_FullSize);
+
+ if (locatorIndex >= kEcd64_FullSize)
if (checkOffsetMode || absEcd64 == locator.Ecd64Offset)
{
- const Byte *ecd64 = locatorPtr - kEcd64_FullSize;
+ const Byte *ecd64 = buf + locatorIndex - kEcd64_FullSize;
if (Get32(ecd64) == NSignature::kEcd64)
{
UInt64 mainEcd64Size = Get64(ecd64 + 4);
@@ -1193,42 +1721,25 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdIn
{
items.Clear();
- ISequentialInStream *stream;
-
- if (!IsMultiVol)
- {
- stream = this->StartStream;
- Vols.StreamIndex = -1;
- RINOK(this->StartStream->Seek(cdOffset, STREAM_SEEK_SET, &m_Position));
- if (m_Position != cdOffset)
- return S_FALSE;
- }
- else
- {
- if (cdInfo.CdDisk >= Vols.Streams.Size())
- return S_FALSE;
- IInStream *str2 = Vols.Streams[cdInfo.CdDisk].Stream;
- if (!str2)
- return S_FALSE;
- RINOK(str2->Seek(cdOffset, STREAM_SEEK_SET, NULL));
- stream = str2;
- Vols.NeedSeek = false;
- Vols.StreamIndex = cdInfo.CdDisk;
- m_Position = cdOffset;
- }
+ RINOK(SeekToVol(IsMultiVol ? cdInfo.CdDisk : -1, cdOffset));
- _inBuffer.SetStream(stream);
-
- _inBuffer.Init();
_inBufMode = true;
+ _cnt = 0;
- _processedCnt = 0;
+ if (Callback)
+ {
+ RINOK(Callback->SetTotal(&cdInfo.NumEntries, IsMultiVol ? &Vols.TotalBytesSize : NULL));
+ }
+ UInt64 numFileExpected = cdInfo.NumEntries;
+ const UInt64 *totalFilesPtr = &numFileExpected;
+ bool isCorrect_NumEntries = (cdInfo.IsFromEcd64 || numFileExpected >= ((UInt32)1 << 16));
- while (_processedCnt < cdSize)
+ while (_cnt < cdSize)
{
CanStartNewVol = true;
if (ReadUInt32() != NSignature::kCentralFileHeader)
return S_FALSE;
+ CanStartNewVol = false;
{
CItemEx cdItem;
RINOK(ReadCdItem(cdItem));
@@ -1237,13 +1748,24 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdIn
if (Callback && (items.Size() & 0xFFF) == 0)
{
const UInt64 numFiles = items.Size();
- RINOK(Callback->SetCompleted(&numFiles, NULL));
+
+ if (numFiles > numFileExpected && totalFilesPtr)
+ {
+ if (isCorrect_NumEntries)
+ totalFilesPtr = NULL;
+ else
+ while (numFiles > numFileExpected)
+ numFileExpected += (UInt32)1 << 16;
+ RINOK(Callback->SetTotal(totalFilesPtr, NULL));
+ }
+
+ RINOK(Callback->SetCompleted(&numFiles, &_cnt));
}
}
CanStartNewVol = true;
- return (_processedCnt == cdSize) ? S_OK : S_FALSE;
+ return (_cnt == cdSize) ? S_OK : S_FALSE;
}
@@ -1275,11 +1797,12 @@ HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt32 &cdDisk, UInt64
cdOffset = cdInfo.Offset;
cdDisk = cdInfo.CdDisk;
- if (Callback)
+ if (!IsMultiVol)
{
- RINOK(Callback->SetTotal(&cdInfo.NumEntries, NULL));
+ if (cdInfo.ThisDisk != cdInfo.CdDisk)
+ return S_FALSE;
}
-
+
const UInt64 base = (IsMultiVol ? 0 : ArcInfo.Base);
res = TryReadCd(items, cdInfo, base + cdOffset, cdSize);
@@ -1323,47 +1846,83 @@ static bool IsStrangeItem(const CItem &item)
}
+
+/*
+ ---------- ReadLocals ----------
+
+in:
+ (_signature == NSignature::kLocalFileHeader)
+ VirtStreamPos : after _signature : position in Stream
+ Stream :
+ Vols : if (IsMultiVol)
+ (_inBufMode == false)
+
+action:
+ it parses local items.
+
+ if ( IsMultiVol) it writes absolute offsets to CItemEx::LocalHeaderPos
+ if (!IsMultiVol) it writes relative (from ArcInfo.Base) offsets to CItemEx::LocalHeaderPos
+ later we can correct CItemEx::LocalHeaderPos values, if
+ some new value for ArcInfo.Base will be detected
+out:
+ S_OK:
+ (_signature != NSignature::kLocalFileHeade)
+ _streamPos : after _signature
+
+ S_FALSE: if no items or there is just one item with strange properies that doesn't look like real archive.
+
+ another error code: stream reading error or Callback error.
+
+ CUnexpectEnd() exception : it's not fatal exception here.
+ It means that reading was interrupted by unexpected end of input stream,
+ but some CItemEx items were parsed OK.
+ We can stop further archive parsing.
+ But we can use all filled CItemEx items.
+*/
+
HRESULT CInArchive::ReadLocals(CObjectVector<CItemEx> &items)
{
items.Clear();
+
+ UInt64 progressPrev = _cnt;
- while (m_Signature == NSignature::kLocalFileHeader)
+ if (Callback)
+ {
+ RINOK(Callback->SetTotal(NULL, IsMultiVol ? &Vols.TotalBytesSize : NULL));
+ }
+
+ while (_signature == NSignature::kLocalFileHeader)
{
CItemEx item;
- item.LocalHeaderPos = m_Position - 4;
- if (!IsMultiVol)
- item.LocalHeaderPos -= ArcInfo.MarkerPos;
- // we write ralative LocalHeaderPos here. Later we can correct it to real Base.
+ item.LocalHeaderPos = GetVirtStreamPos() - 4;
+ if (!IsMultiVol)
+ item.LocalHeaderPos -= ArcInfo.Base;
try
{
ReadLocalItem(item);
item.FromLocal = true;
bool isFinished = false;
-
+
if (item.HasDescriptor())
- ReadLocalItemDescriptor(item);
+ {
+ RINOK(FindDescriptor(item, items.Size()));
+ isFinished = !item.DescriptorWasRead;
+ }
else
{
- /*
- if (IsMultiVol)
- {
- const int kStep = 10000;
- RINOK(IncreaseRealPosition(-kStep, isFinished));
- RINOK(IncreaseRealPosition(item.PackSize + kStep, isFinished));
- }
- else
- */
+ if (item.PackSize >= ((UInt64)1 << 62))
+ throw CUnexpectEnd();
RINOK(IncreaseRealPosition(item.PackSize, isFinished));
}
-
+
items.Add(item);
if (isFinished)
throw CUnexpectEnd();
-
- m_Signature = ReadUInt32();
+
+ ReadSignature();
}
catch (CUnexpectEnd &)
{
@@ -1372,17 +1931,18 @@ HRESULT CInArchive::ReadLocals(CObjectVector<CItemEx> &items)
throw;
}
- if (Callback && (items.Size() & 0xFF) == 0)
+
+ if (Callback)
+ if ((items.Size() & 0xFF) == 0
+ || _cnt - progressPrev >= ((UInt32)1 << 22))
{
+ progressPrev = _cnt;
const UInt64 numFiles = items.Size();
- UInt64 numBytes = 0;
- // if (!sMultiVol)
- numBytes = item.LocalHeaderPos;
- RINOK(Callback->SetCompleted(&numFiles, &numBytes));
+ RINOK(Callback->SetCompleted(&numFiles, &_cnt));
}
}
- if (items.Size() == 1 && m_Signature != NSignature::kCentralFileHeader)
+ if (items.Size() == 1 && _signature != NSignature::kCentralFileHeader)
if (IsStrangeItem(items[0]))
return S_FALSE;
@@ -1402,26 +1962,22 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
name = prop.bstrVal;
}
- UString base = name;
int dotPos = name.ReverseFind_Dot();
-
if (dotPos < 0)
return S_OK;
-
- base.DeleteFrom(dotPos + 1);
-
const UString ext = name.Ptr(dotPos + 1);
+ name.DeleteFrom(dotPos + 1);
+
StartVolIndex = (Int32)(-1);
if (ext.IsEmpty())
return S_OK;
- else
{
wchar_t c = ext[0];
IsUpperCase = (c >= 'A' && c <= 'Z');
if (ext.IsEqualTo_Ascii_NoCase("zip"))
{
- BaseName = base;
+ BaseName = name;
StartIsZ = true;
StartIsZip = true;
return S_OK;
@@ -1429,8 +1985,13 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
else if (ext.IsEqualTo_Ascii_NoCase("exe"))
{
StartIsExe = true;
- BaseName = base;
+ BaseName = name;
StartVolIndex = 0;
+ /* sfx-zip can use both arc.exe and arc.zip
+ We can open arc.zip, if it was requesed to open arc.exe.
+ But it's possible that arc.exe and arc.zip are not parts of same archive.
+ So we can disable such operation */
+ return S_FALSE; // don't open arc.zip instead of arc.exe
}
else if (ext[0] == 'z' || ext[0] == 'Z')
{
@@ -1441,7 +2002,7 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
if (*end != 0 || volNum < 1 || volNum > ((UInt32)1 << 30))
return S_OK;
StartVolIndex = volNum - 1;
- BaseName = base;
+ BaseName = name;
StartIsZ = true;
}
else
@@ -1449,9 +2010,11 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
}
UString volName = BaseName;
- volName.AddAscii(IsUpperCase ? "ZIP" : "zip");
- HRESULT result = volCallback->GetStream(volName, &ZipStream);
- if (result == S_FALSE || !ZipStream)
+ volName += (IsUpperCase ? "ZIP" : "zip");
+
+ HRESULT res = volCallback->GetStream(volName, &ZipStream);
+
+ if (res == S_FALSE || !ZipStream)
{
if (MissingName.IsEmpty())
{
@@ -1461,7 +2024,7 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
return S_OK;
}
- return result;
+ return res;
}
@@ -1493,24 +2056,30 @@ HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback,
{
UString volName = Vols.BaseName;
{
- volName += (wchar_t)(Vols.IsUpperCase ? 'Z' : 'z');
+ volName += (char)(Vols.IsUpperCase ? 'Z' : 'z');
+ unsigned v = i + 1;
+ if (v < 10)
+ volName += '0';
+ volName.Add_UInt32(v);
+ }
+
+ HRESULT res = volCallback->GetStream(volName, &stream);
+ if (res != S_OK && res != S_FALSE)
+ return res;
+ if (res == S_FALSE || !stream)
+ {
+ if (i == 0)
{
- char s[32];
- ConvertUInt32ToString(i + 1, s);
- unsigned len = (unsigned)strlen(s);
- while (len < 2)
- {
- volName += (wchar_t)'0';
- len++;
- }
- volName.AddAscii(s);
+ UString volName_exe = Vols.BaseName;
+ volName_exe += (Vols.IsUpperCase ? "EXE" : "exe");
+
+ HRESULT res2 = volCallback->GetStream(volName_exe, &stream);
+ if (res2 != S_OK && res2 != S_FALSE)
+ return res2;
+ res = res2;
}
}
-
- HRESULT result = volCallback->GetStream(volName, &stream);
- if (result != S_OK && result != S_FALSE)
- return result;
- if (result == S_FALSE || !stream)
+ if (res == S_FALSE || !stream)
{
if (Vols.MissingName.IsEmpty())
Vols.MissingName = volName;
@@ -1524,7 +2093,6 @@ HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback,
}
UInt64 size;
-
UInt64 pos;
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &pos));
RINOK(stream->Seek(0, STREAM_SEEK_END, &size));
@@ -1535,6 +2103,8 @@ HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback,
CVols::CSubStreamInfo &ss = Vols.Streams[i];
Vols.NumVols++;
+ Vols.TotalBytesSize += size;
+
ss.Stream = stream;
ss.Size = size;
@@ -1559,11 +2129,11 @@ HRESULT CInArchive::ReadVols()
RINOK(Vols.ParseArcName(volCallback));
- int startZIndex = Vols.StartVolIndex;
+ // const int startZIndex = Vols.StartVolIndex;
if (!Vols.StartIsZ)
{
- // if (!Vols.StartIsExe)
+ if (!Vols.StartIsExe)
return S_OK;
}
@@ -1573,35 +2143,46 @@ HRESULT CInArchive::ReadVols()
if (Vols.StartIsZip)
Vols.ZipStream = StartStream;
- // bool cdOK = false;
-
if (Vols.ZipStream)
{
Stream = Vols.ZipStream;
+
+ if (Vols.StartIsZip)
+ Vols.StreamIndex = -1;
+ else
+ {
+ Vols.StreamIndex = -2;
+ InitBuf();
+ }
+
HRESULT res = FindCd(true);
+
CCdInfo &ecd = Vols.ecd;
if (res == S_OK)
{
zipDisk = ecd.ThisDisk;
Vols.ecd_wasRead = true;
+
+ // if is not multivol or bad multivol, we return to main single stream code
if (ecd.ThisDisk == 0
|| ecd.ThisDisk >= ((UInt32)1 << 30)
|| ecd.ThisDisk < ecd.CdDisk)
return S_OK;
+
cdDisk = ecd.CdDisk;
if (Vols.StartVolIndex < 0)
Vols.StartVolIndex = ecd.ThisDisk;
+ else if ((UInt32)Vols.StartVolIndex >= ecd.ThisDisk)
+ return S_OK;
+
// Vols.StartVolIndex = ecd.ThisDisk;
// Vols.EndVolIndex = ecd.ThisDisk;
unsigned numMissingVols;
- if (cdDisk == zipDisk)
- {
- // cdOK = true;
- }
- else
+ if (cdDisk != zipDisk)
{
+ // get volumes required for cd.
RINOK(ReadVols2(volCallback, cdDisk, zipDisk, zipDisk, 0, numMissingVols));
- if (numMissingVols == 0)
+ if (numMissingVols != 0)
{
// cdOK = false;
}
@@ -1611,25 +2192,50 @@ HRESULT CInArchive::ReadVols()
return res;
}
- if (Vols.Streams.Size() > 0)
- IsMultiVol = true;
-
if (Vols.StartVolIndex < 0)
+ {
+ // is not mutivol;
return S_OK;
+ }
+ /*
+ if (!Vols.Streams.IsEmpty())
+ IsMultiVol = true;
+ */
+
unsigned numMissingVols;
if (cdDisk != 0)
{
- RINOK(ReadVols2(volCallback, 0, cdDisk < 0 ? -1 : cdDisk, zipDisk, 1 << 10, numMissingVols));
+ // get volumes that were no requested still
+ const unsigned kNumMissingVolsMax = 1 << 12;
+ RINOK(ReadVols2(volCallback, 0, cdDisk < 0 ? -1 : cdDisk, zipDisk, kNumMissingVolsMax, numMissingVols));
+ }
+
+ // if (Vols.StartVolIndex >= 0)
+ {
+ if (Vols.Streams.IsEmpty())
+ if (Vols.StartVolIndex > (1 << 20))
+ return S_OK;
+ if ((unsigned)Vols.StartVolIndex >= Vols.Streams.Size()
+ || !Vols.Streams[Vols.StartVolIndex].Stream)
+ {
+ // we get volumes starting from StartVolIndex, if they we not requested before know the volume index (if FindCd() was ok)
+ RINOK(ReadVols2(volCallback, Vols.StartVolIndex, zipDisk, zipDisk, 0, numMissingVols));
+ }
}
if (Vols.ZipStream)
{
+ // if there is no another volumes and volumeIndex is too big, we don't use multivol mode
if (Vols.Streams.IsEmpty())
if (zipDisk > (1 << 10))
return S_OK;
- RINOK(ReadVols2(volCallback, zipDisk, zipDisk + 1, zipDisk, 0, numMissingVols));
+ if (zipDisk >= 0)
+ {
+ // we create item in Streams for ZipStream, if we know the volume index (if FindCd() was ok)
+ RINOK(ReadVols2(volCallback, zipDisk, zipDisk + 1, zipDisk, 0, numMissingVols));
+ }
}
if (!Vols.Streams.IsEmpty())
@@ -1639,11 +2245,14 @@ HRESULT CInArchive::ReadVols()
if (cdDisk)
IsMultiVol = true;
*/
+ const int startZIndex = Vols.StartVolIndex;
if (startZIndex >= 0)
{
- if (Vols.Streams.Size() >= (unsigned)startZIndex)
+ // if all volumes before start volume are OK, we can start parsing from 0
+ // if there are missing volumes before startZIndex, we start parsing in current startZIndex
+ if ((unsigned)startZIndex < Vols.Streams.Size())
{
- for (unsigned i = 0; i < (unsigned)startZIndex; i++)
+ for (unsigned i = 0; i <= (unsigned)startZIndex; i++)
if (!Vols.Streams[i].Stream)
{
Vols.StartParsingVol = startZIndex;
@@ -1658,10 +2267,6 @@ HRESULT CInArchive::ReadVols()
-
-
-
-
HRESULT CVols::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
@@ -1680,7 +2285,7 @@ HRESULT CVols::Read(void *data, UInt32 size, UInt32 *processedSize)
return S_FALSE;
if (NeedSeek)
{
- RINOK(s.Stream->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(s.SeekToStart());
NeedSeek = false;
}
UInt32 realProcessedSize = 0;
@@ -1704,47 +2309,112 @@ STDMETHODIMP CVolStream::Read(void *data, UInt32 size, UInt32 *processedSize)
-#define COPY_ECD_ITEM_16(n) if (!isZip64 || ecd. n != 0xFFFF) ecd64. n = ecd. n;
-#define COPY_ECD_ITEM_32(n) if (!isZip64 || ecd. n != 0xFFFFFFFF) ecd64. n = ecd. n;
+#define COPY_ECD_ITEM_16(n) if (!isZip64 || !ZIP64_IS_16_MAX(ecd. n)) cdInfo. n = ecd. n;
+#define COPY_ECD_ITEM_32(n) if (!isZip64 || !ZIP64_IS_32_MAX(ecd. n)) cdInfo. n = ecd. n;
-HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
+HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
{
+ if (Buffer.Size() < kSeqBufferSize)
+ {
+ InitBuf();
+ Buffer.AllocAtLeast(kSeqBufferSize);
+ if (!Buffer.IsAllocated())
+ return E_OUTOFMEMORY;
+ }
+
+ _inBufMode = false;
+
HRESULT res = S_OK;
bool localsWereRead = false;
- UInt64 cdSize = 0, cdRelatOffset = 0, cdAbsOffset = 0;
+
+ /* we try to open archive with the following modes:
+ 1) CD-MODE : fast mode : we read backward ECD and CD, compare CD items with first Local item.
+ 2) LOCALS-CD-MODE : slow mode, if CD-MODE fails : we sequentially read all Locals and then CD.
+ Then we read sequentially ECD64, Locator, ECD again at the end.
+
+ - in LOCALS-CD-MODE we use use the following
+ variables (with real cd properties) to set Base archive offset
+ and check real cd properties with values from ECD/ECD64.
+ */
+
+ UInt64 cdSize = 0;
+ UInt64 cdRelatOffset = 0;
UInt32 cdDisk = 0;
- if (!_inBuffer.Create(1 << 15))
- return E_OUTOFMEMORY;
+ UInt64 cdAbsOffset = 0; // absolute cd offset, for LOCALS-CD-MODE only.
- if (!MarkerIsFound)
+ if (!MarkerIsFound || !MarkerIsSafe)
{
IsArc = true;
res = ReadCd(items, cdDisk, cdRelatOffset, cdSize);
if (res == S_OK)
- m_Signature = ReadUInt32();
+ ReadSignature();
+ else if (res != S_FALSE)
+ return res;
}
else
{
- // m_Signature must be kLocalFileHeader or kEcd
- // m_Position points to next byte after signature
- RINOK(Stream->Seek(m_Position, STREAM_SEEK_SET, NULL));
+ // _signature must be kLocalFileHeader or kEcd or kEcd64
+
+ SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2 + 4);
+
+ CanStartNewVol = false;
+
+ if (_signature == NSignature::kEcd64)
+ {
+ // UInt64 ecd64Offset = GetVirtStreamPos() - 4;
+ IsZip64 = true;
- _inBuffer.SetStream(Stream);
+ {
+ const UInt64 recordSize = ReadUInt64();
+ if (recordSize < kEcd64_MainSize)
+ return S_FALSE;
+ if (recordSize >= ((UInt64)1 << 62))
+ return S_FALSE;
+
+ {
+ const unsigned kBufSize = kEcd64_MainSize;
+ Byte buf[kBufSize];
+ SafeRead(buf, kBufSize);
+ CCdInfo cdInfo;
+ cdInfo.ParseEcd64e(buf);
+ if (!cdInfo.IsEmptyArc())
+ return S_FALSE;
+ }
+
+ RINOK(Skip64(recordSize - kEcd64_MainSize, 0));
+ }
+
+ ReadSignature();
+ if (_signature != NSignature::kEcd64Locator)
+ return S_FALSE;
- bool needReadCd = true;
+ {
+ const unsigned kBufSize = 16;
+ Byte buf[kBufSize];
+ SafeRead(buf, kBufSize);
+ CLocator locator;
+ locator.Parse(buf);
+ if (!locator.IsEmptyArc())
+ return S_FALSE;
+ }
- if (m_Signature == NSignature::kEcd)
+ ReadSignature();
+ if (_signature != NSignature::kEcd)
+ return S_FALSE;
+ }
+
+ if (_signature == NSignature::kEcd)
{
// It must be empty archive or backware archive
// we don't support backware archive still
const unsigned kBufSize = kEcdSize - 4;
Byte buf[kBufSize];
- SafeReadBytes(buf, kBufSize);
+ SafeRead(buf, kBufSize);
CEcd ecd;
ecd.Parse(buf);
// if (ecd.cdSize != 0)
@@ -1753,15 +2423,15 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
return S_FALSE;
ArcInfo.Base = ArcInfo.MarkerPos;
- needReadCd = false;
IsArc = true; // check it: we need more tests?
- RINOK(Stream->Seek(ArcInfo.MarkerPos2 + 4, STREAM_SEEK_SET, &m_Position));
- }
- if (needReadCd)
+ RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2));
+ ReadSignature();
+ }
+ else
{
CItemEx firstItem;
- // try
+ try
{
try
{
@@ -1776,9 +2446,10 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
IsArc = true;
res = ReadCd(items, cdDisk, cdRelatOffset, cdSize);
if (res == S_OK)
- m_Signature = ReadUInt32();
+ ReadSignature();
}
- // catch() { res = S_FALSE; }
+ catch(CUnexpectEnd &) { res = S_FALSE; }
+
if (res != S_FALSE && res != S_OK)
return res;
@@ -1812,52 +2483,93 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
CObjectVector<CItemEx> cdItems;
- bool needSetBase = false;
+ bool needSetBase = false; // we set needSetBase only for LOCALS_CD_MODE
unsigned numCdItems = items.Size();
- if (res == S_FALSE)
+ #ifdef ZIP_SELF_CHECK
+ res = S_FALSE; // if uncommented, it uses additional LOCALS-CD-MODE mode to check the code
+ #endif
+
+ if (res != S_OK)
{
+ // ---------- LOCALS-CD-MODE ----------
// CD doesn't match firstItem,
- // so we clear items and read Locals.
+ // so we clear items and read Locals and CD.
+
items.Clear();
localsWereRead = true;
+
+ // we can use any mode: with buffer and without buffer
+ // without buffer : skips packed data : fast for big files : slow for small files
+ // with buffer : reads packed data : slow for big files : fast for small files
+
_inBufMode = false;
- ArcInfo.Base = ArcInfo.MarkerPos;
+ // _inBufMode = true;
- if (IsMultiVol)
+ InitBuf();
+
+ ArcInfo.Base = 0;
+
+ if (!MarkerIsFound)
{
- Vols.StreamIndex = Vols.StartParsingVol;
- if (Vols.StartParsingVol >= (int)Vols.Streams.Size())
+ if (!IsMultiVol)
return S_FALSE;
- Stream = Vols.Streams[Vols.StartParsingVol].Stream;
- if (!Stream)
+ if (Vols.StartParsingVol != 0)
return S_FALSE;
+ // if (StartParsingVol == 0) and we didn't find marker, we use default zero marker.
+ // so we suppose that there is no sfx stub
+ RINOK(SeekToVol(0, ArcInfo.MarkerPos2));
}
+ else
+ {
+ if (ArcInfo.MarkerPos != 0)
+ {
+ /*
+ If multi-vol or there is (No)Span-marker at start of stream, we set (Base) as 0.
+ In another caes:
+ (No)Span-marker is supposed as false positive. So we set (Base) as main marker (MarkerPos2).
+ The (Base) can be corrected later after ECD reading.
+ But sfx volume with stub and (No)Span-marker in (!IsMultiVol) mode will have incorrect (Base) here.
+ */
+ ArcInfo.Base = ArcInfo.MarkerPos2;
+ }
+
+ RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2));
+ }
+
+ _cnt = 0;
- RINOK(Stream->Seek(ArcInfo.MarkerPos2, STREAM_SEEK_SET, &m_Position));
- m_Signature = ReadUInt32();
+ ReadSignature();
+ LocalsWereRead = true;
+
RINOK(ReadLocals(items));
- if (m_Signature != NSignature::kCentralFileHeader)
+ if (_signature != NSignature::kCentralFileHeader)
{
- // if (!UnexpectedEnd)
- m_Position -= 4;
+ // GetVirtStreamPos() - 4
+ if (items.IsEmpty())
+ return S_FALSE;
NoCentralDir = true;
HeadersError = true;
return S_OK;
}
_inBufMode = true;
- _inBuffer.Init();
-
- cdAbsOffset = m_Position - 4;
+
+ cdAbsOffset = GetVirtStreamPos() - 4;
cdDisk = Vols.StreamIndex;
+ #ifdef ZIP_SELF_CHECK
+ if (!IsMultiVol && _cnt != GetVirtStreamPos() - ArcInfo.MarkerPos2)
+ return E_FAIL;
+ #endif
+
+ const UInt64 processedCnt_start = _cnt;
+
for (;;)
{
CItemEx cdItem;
- CanStartNewVol = true;
RINOK(ReadCdItem(cdItem));
@@ -1865,17 +2577,29 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
if (Callback && (cdItems.Size() & 0xFFF) == 0)
{
const UInt64 numFiles = items.Size();
- RINOK(Callback->SetCompleted(&numFiles, NULL));
+ const UInt64 numBytes = _cnt;
+ RINOK(Callback->SetCompleted(&numFiles, &numBytes));
}
- CanStartNewVol = true;
- m_Signature = ReadUInt32();
- if (m_Signature != NSignature::kCentralFileHeader)
+ ReadSignature();
+ if (_signature != NSignature::kCentralFileHeader)
break;
}
- cdSize = (m_Position - 4) - cdAbsOffset;
+ cdSize = _cnt - processedCnt_start;
+
+ #ifdef ZIP_SELF_CHECK
+ if (!IsMultiVol)
+ {
+ if (_cnt != GetVirtStreamPos() - ArcInfo.MarkerPos2)
+ return E_FAIL;
+ if (cdSize != (GetVirtStreamPos() - 4) - cdAbsOffset)
+ return E_FAIL;
+ }
+ #endif
+
needSetBase = true;
numCdItems = cdItems.Size();
+ cdRelatOffset = cdAbsOffset - ArcInfo.Base;
if (!cdItems.IsEmpty())
{
@@ -1886,13 +2610,13 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
- CCdInfo ecd64;
+ CCdInfo cdInfo;
CLocator locator;
bool isZip64 = false;
- const UInt64 ecd64AbsOffset = m_Position - 4;
+ const UInt64 ecd64AbsOffset = GetVirtStreamPos() - 4;
int ecd64Disk = -1;
- if (m_Signature == NSignature::kEcd64)
+ if (_signature == NSignature::kEcd64)
{
ecd64Disk = Vols.StreamIndex;
@@ -1900,26 +2624,27 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
{
const UInt64 recordSize = ReadUInt64();
- if (recordSize < kEcd64_MainSize)
+ if (recordSize < kEcd64_MainSize
+ || recordSize >= ((UInt64)1 << 62))
{
HeadersError = true;
return S_OK;
}
-
+
{
const unsigned kBufSize = kEcd64_MainSize;
Byte buf[kBufSize];
- SafeReadBytes(buf, kBufSize);
- ecd64.ParseEcd64e(buf);
+ SafeRead(buf, kBufSize);
+ cdInfo.ParseEcd64e(buf);
}
- Skip64(recordSize - kEcd64_MainSize);
+ RINOK(Skip64(recordSize - kEcd64_MainSize, items.Size()));
}
- m_Signature = ReadUInt32();
+ ReadSignature();
- if (m_Signature != NSignature::kEcd64Locator)
+ if (_signature != NSignature::kEcd64Locator)
{
HeadersError = true;
return S_OK;
@@ -1928,28 +2653,30 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
{
const unsigned kBufSize = 16;
Byte buf[kBufSize];
- SafeReadBytes(buf, kBufSize);
+ SafeRead(buf, kBufSize);
locator.Parse(buf);
}
- m_Signature = ReadUInt32();
+ ReadSignature();
}
- if (m_Signature != NSignature::kEcd)
+ if (_signature != NSignature::kEcd)
{
HeadersError = true;
return S_OK;
}
+ CanStartNewVol = false;
+
// ---------- ECD ----------
CEcd ecd;
{
const unsigned kBufSize = kEcdSize - 4;
Byte buf[kBufSize];
- SafeReadBytes(buf, kBufSize);
+ SafeRead(buf, kBufSize);
ecd.Parse(buf);
}
@@ -1960,34 +2687,103 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
COPY_ECD_ITEM_32(Size);
COPY_ECD_ITEM_32(Offset);
+ bool cdOK = true;
+
+ if ((UInt32)cdInfo.Size != (UInt32)cdSize)
+ {
+ // return S_FALSE;
+ cdOK = false;
+ }
+
+ if (isZip64)
+ {
+ if (cdInfo.NumEntries != numCdItems
+ || cdInfo.Size != cdSize)
+ {
+ cdOK = false;
+ }
+ }
+
+
if (IsMultiVol)
{
- if (cdDisk != (int)ecd64.CdDisk)
+ if (cdDisk != (int)cdInfo.CdDisk)
HeadersError = true;
}
- else if (needSetBase)
+ else if (needSetBase && cdOK)
{
+ const UInt64 oldBase = ArcInfo.Base;
+ // localsWereRead == true
+ // ArcInfo.Base == ArcInfo.MarkerPos2
+ // cdRelatOffset == (cdAbsOffset - ArcInfo.Base)
+
if (isZip64)
{
if (ecd64Disk == Vols.StartVolIndex)
{
- ArcInfo.Base = ecd64AbsOffset - locator.Ecd64Offset;
- // cdRelatOffset = ecd64.Offset;
- needSetBase = false;
+ const Int64 newBase = (Int64)ecd64AbsOffset - locator.Ecd64Offset;
+ if (newBase <= (Int64)ecd64AbsOffset)
+ {
+ if (!localsWereRead || newBase <= (Int64)ArcInfo.MarkerPos2)
+ {
+ ArcInfo.Base = newBase;
+ cdRelatOffset = cdAbsOffset - newBase;
+ }
+ else
+ cdOK = false;
+ }
}
}
- else
+ else if (numCdItems != 0) // we can't use ecd.Offset in empty archive?
{
if ((int)cdDisk == Vols.StartVolIndex)
{
- ArcInfo.Base = cdAbsOffset - ecd64.Offset;
- cdRelatOffset = ecd64.Offset;
- needSetBase = false;
+ const Int64 newBase = (Int64)cdAbsOffset - cdInfo.Offset;
+ if (newBase <= (Int64)cdAbsOffset)
+ {
+ if (!localsWereRead || newBase <= (Int64)ArcInfo.MarkerPos2)
+ {
+ // cd can be more accurate, when it points before Locals
+ // so we change Base and cdRelatOffset
+ ArcInfo.Base = newBase;
+ cdRelatOffset = cdInfo.Offset;
+ }
+ else
+ {
+ // const UInt64 delta = ((UInt64)cdRelatOffset - cdInfo.Offset);
+ const UInt64 delta = ((UInt64)(newBase - ArcInfo.Base));
+ if ((UInt32)delta == 0)
+ {
+ // we set Overflow32bit mode, only if there is (x<<32) offset
+ // between real_CD_offset_from_MarkerPos and CD_Offset_in_ECD.
+ // Base and cdRelatOffset unchanged
+ Overflow32bit = true;
+ }
+ else
+ cdOK = false;
+ }
+ }
+ else
+ cdOK = false;
+ }
+ }
+ // cdRelatOffset = cdAbsOffset - ArcInfo.Base;
+
+ if (localsWereRead)
+ {
+ const UInt64 delta = oldBase - ArcInfo.Base;
+ if (delta != 0)
+ {
+ FOR_VECTOR (i, items)
+ items[i].LocalHeaderPos += delta;
}
}
}
- EcdVolIndex = ecd64.ThisDisk;
+ if (!cdOK)
+ HeadersError = true;
+
+ EcdVolIndex = cdInfo.ThisDisk;
if (!IsMultiVol)
{
@@ -1997,54 +2793,80 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
Vols.MissingZip = false;
}
- UseDisk_in_SingleVol = true;
-
if (localsWereRead)
{
- if ((UInt64)ArcInfo.Base != ArcInfo.MarkerPos)
- {
- const UInt64 delta = ArcInfo.MarkerPos - ArcInfo.Base;
- FOR_VECTOR (i, items)
- items[i].LocalHeaderPos += delta;
- }
-
if (EcdVolIndex != 0)
{
FOR_VECTOR (i, items)
items[i].Disk = EcdVolIndex;
}
}
+
+ UseDisk_in_SingleVol = true;
}
if (isZip64)
{
- if (ecd64.ThisDisk == 0 && ecd64AbsOffset != ArcInfo.Base + locator.Ecd64Offset
- // || ecd64.NumEntries_in_ThisDisk != numCdItems
- || ecd64.NumEntries != numCdItems
- || ecd64.Size != cdSize
- || (ecd64.Offset != cdRelatOffset && !items.IsEmpty()))
+ if (cdInfo.ThisDisk == 0 && ecd64AbsOffset != ArcInfo.Base + locator.Ecd64Offset
+ // || cdInfo.NumEntries_in_ThisDisk != numCdItems
+ || cdInfo.NumEntries != numCdItems
+ || cdInfo.Size != cdSize
+ || (cdInfo.Offset != cdRelatOffset && !items.IsEmpty()))
{
HeadersError = true;
return S_OK;
}
}
- // ---------- merge Central Directory Items ----------
-
- if (!cdItems.IsEmpty())
+ if (cdOK && !cdItems.IsEmpty())
{
- CObjectVector<CItemEx> items2;
+ // ---------- merge Central Directory Items ----------
+
+ CRecordVector<unsigned> items2;
+
+ int nextLocalIndex = 0;
+
+ LocalsCenterMerged = true;
FOR_VECTOR (i, cdItems)
{
+ if (Callback)
+ if ((i & 0x3FFF) == 0)
+ {
+ const UInt64 numFiles64 = items.Size() + items2.Size();
+ RINOK(Callback->SetCompleted(&numFiles64, &_cnt));
+ }
+
const CItemEx &cdItem = cdItems[i];
- int index = FindItem(items, cdItem);
+
+ int index = -1;
+
+ if (nextLocalIndex != -1)
+ {
+ if ((unsigned)nextLocalIndex < items.Size())
+ {
+ CItemEx &item = items[nextLocalIndex];
+ if (item.Disk == cdItem.Disk &&
+ (item.LocalHeaderPos == cdItem.LocalHeaderPos
+ || Overflow32bit && (UInt32)item.LocalHeaderPos == cdItem.LocalHeaderPos))
+ index = nextLocalIndex++;
+ else
+ nextLocalIndex = -1;
+ }
+ }
+
+ if (index == -1)
+ index = FindItem(items, cdItem);
+
+ // index = -1;
+
if (index == -1)
{
- items2.Add(cdItem);
+ items2.Add(i);
HeadersError = true;
continue;
}
+
CItemEx &item = items[index];
if (item.Name != cdItem.Name
// || item.Name.Len() != cdItem.Name.Len()
@@ -2067,10 +2889,10 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
item.FromCentral = cdItem.FromCentral;
}
- items += items2;
+ FOR_VECTOR (k, items2)
+ items.Add(cdItems[items2[k]]);
}
-
if (ecd.NumEntries < ecd.NumEntries_in_ThisDisk)
HeadersError = true;
@@ -2083,35 +2905,56 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
}
}
- if (ecd.NumEntries > items.Size())
- HeadersError = true;
-
if (isZip64)
{
- if (ecd64.NumEntries != items.Size())
+ if (cdInfo.NumEntries != items.Size()
+ || ecd.NumEntries != items.Size() && ecd.NumEntries != 0xFFFF)
HeadersError = true;
}
else
{
// old 7-zip could store 32-bit number of CD items to 16-bit field.
- /*
- if ((UInt16)ecd64.NumEntries == (UInt16)items.Size())
+ // if (ecd.NumEntries != items.Size())
+ if (ecd.NumEntries > items.Size())
HeadersError = true;
- */
+
+ if (cdInfo.NumEntries != numCdItems)
+ {
+ if ((UInt16)cdInfo.NumEntries != (UInt16)numCdItems)
+ HeadersError = true;
+ else
+ Cd_NumEntries_Overflow_16bit = true;
+ }
}
ReadBuffer(ArcInfo.Comment, ecd.CommentSize);
+
_inBufMode = false;
- _inBuffer.Free();
- if ((UInt16)ecd64.NumEntries != (UInt16)numCdItems
- || (UInt32)ecd64.Size != (UInt32)cdSize
- || ((UInt32)ecd64.Offset != (UInt32)cdRelatOffset && !items.IsEmpty()))
+ // DisableBufMode();
+ // Buffer.Free();
+ /* we can't clear buf varibles. we need them to calculate PhySize of archive */
+
+ if ((UInt16)cdInfo.NumEntries != (UInt16)numCdItems
+ || (UInt32)cdInfo.Size != (UInt32)cdSize
+ || ((UInt32)cdInfo.Offset != (UInt32)cdRelatOffset && !items.IsEmpty()))
{
// return S_FALSE;
HeadersError = true;
}
-
+
+ #ifdef ZIP_SELF_CHECK
+ if (localsWereRead)
+ {
+ const UInt64 endPos = ArcInfo.MarkerPos2 + _cnt;
+ if (endPos != (IsMultiVol ? Vols.TotalBytesSize : ArcInfo.FileEndPos))
+ {
+ // there are some data after the end of archive or error in code;
+ return E_FAIL;
+ }
+ }
+ #endif
+
// printf("\nOpen OK");
return S_OK;
}
@@ -2121,40 +2964,47 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
IArchiveOpenCallback *callback, CObjectVector<CItemEx> &items)
{
- _inBufMode = false;
items.Clear();
Close();
- ArcInfo.Clear();
UInt64 startPos;
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &startPos));
RINOK(stream->Seek(0, STREAM_SEEK_END, &ArcInfo.FileEndPos));
- m_Position = ArcInfo.FileEndPos;
+ _streamPos = ArcInfo.FileEndPos;
StartStream = stream;
+ Stream = stream;
Callback = callback;
+
+ DisableBufMode();
bool volWasRequested = false;
if (callback
&& (startPos == 0 || !searchLimit || *searchLimit != 0))
{
+ // we try to read volumes only if it's first call (offset == 0) or scan is allowed.
volWasRequested = true;
RINOK(ReadVols());
}
- if (IsMultiVol && Vols.StartVolIndex != 0)
+ if (IsMultiVol && Vols.StartParsingVol == 0 && (unsigned)Vols.StartParsingVol < Vols.Streams.Size())
{
- Stream = Vols.Streams[0].Stream;
- if (Stream)
+ // only StartParsingVol = 0 is safe search.
+ RINOK(SeekToVol(0, 0));
+ // if (Stream)
{
- m_Position = 0;
- RINOK(Stream->Seek(0, STREAM_SEEK_SET, NULL));
- UInt64 limit = 0;
- HRESULT res = FindMarker(Stream, &limit);
+ // UInt64 limit = 1 << 22; // for sfx
+ UInt64 limit = 0; // without sfx
+
+ HRESULT res = FindMarker(&limit);
+
if (res == S_OK)
+ {
MarkerIsFound = true;
+ MarkerIsSafe = true;
+ }
else if (res != S_FALSE)
return res;
}
@@ -2162,56 +3012,93 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
else
{
// printf("\nOpen offset = %u\n", (unsigned)startPos);
- RINOK(stream->Seek(startPos, STREAM_SEEK_SET, NULL));
- m_Position = startPos;
- HRESULT res = FindMarker(stream, searchLimit);
- UInt64 curPos = m_Position;
+ if (IsMultiVol && (unsigned)Vols.StartParsingVol < Vols.Streams.Size() && Vols.Streams[Vols.StartParsingVol].Stream)
+ {
+ RINOK(SeekToVol(Vols.StartParsingVol, Vols.StreamIndex == Vols.StartVolIndex ? startPos : 0));
+ }
+ else
+ {
+ RINOK(SeekToVol(-1, startPos));
+ }
+
+ // UInt64 limit = 1 << 22;
+ // HRESULT res = FindMarker(&limit);
+
+ HRESULT res = FindMarker(searchLimit);
+
+ // const UInt64 curPos = GetVirtStreamPos();
+ const UInt64 curPos = ArcInfo.MarkerPos2 + 4;
+
if (res == S_OK)
MarkerIsFound = true;
- else
+ else if (!IsMultiVol)
{
- // if (res != S_FALSE)
+ /*
+ // if (startPos != 0), probably CD copuld be already tested with another call with (startPos == 0).
+ // so we don't want to try to open CD again in that ase.
+ if (startPos != 0)
+ return res;
+ // we can try to open CD, if there is no Marker and (startPos == 0).
+ // is it OK to open such files as ZIP, or big number of false positive, when CD can be find in end of file ?
+ */
return res;
}
-
- MarkerIsFound = true;
if (ArcInfo.IsSpanMode && !volWasRequested)
{
RINOK(ReadVols());
+ if (IsMultiVol && MarkerIsFound && ArcInfo.MarkerVolIndex < 0)
+ ArcInfo.MarkerVolIndex = Vols.StartVolIndex;
}
+
+ MarkerIsSafe = !IsMultiVol
+ || (ArcInfo.MarkerVolIndex == 0 && ArcInfo.MarkerPos == 0)
+ ;
- if (IsMultiVol && (unsigned)Vols.StartVolIndex < Vols.Streams.Size())
+
+ if (IsMultiVol)
{
- Stream = Vols.Streams[Vols.StartVolIndex].Stream;
- if (!Stream)
- IsMultiVol = false;
- else
+ if ((unsigned)Vols.StartVolIndex < Vols.Streams.Size())
{
- RINOK(Stream->Seek(curPos, STREAM_SEEK_SET, NULL));
- m_Position = curPos;
+ Stream = Vols.Streams[Vols.StartVolIndex].Stream;
+ if (Stream)
+ {
+ RINOK(Seek_SavePos(curPos));
+ }
+ else
+ IsMultiVol = false;
}
+ else
+ IsMultiVol = false;
}
- else
- IsMultiVol = false;
if (!IsMultiVol)
{
- RINOK(stream->Seek(curPos, STREAM_SEEK_SET, NULL));
- m_Position = curPos;
+ if (Vols.StreamIndex != -1)
+ {
+ Stream = StartStream;
+ Vols.StreamIndex = -1;
+ InitBuf();
+ RINOK(Seek_SavePos(curPos));
+ }
+
+ ArcInfo.MarkerVolIndex = -1;
StreamRef = stream;
Stream = stream;
}
}
+ if (!IsMultiVol)
+ Vols.ClearRefs();
+
{
HRESULT res;
try
{
- res = ReadHeaders2(items);
+ res = ReadHeaders(items);
}
- catch (const CInBufferException &e) { res = e.ErrorCode; }
+ catch (const CSystemException &e) { res = e.ErrorCode; }
catch (const CUnexpectEnd &)
{
if (items.IsEmpty())
@@ -2221,7 +3108,7 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
}
catch (...)
{
- _inBufMode = false;
+ DisableBufMode();
throw;
}
@@ -2229,16 +3116,17 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
{
ArcInfo.FinishPos = ArcInfo.FileEndPos;
if ((unsigned)Vols.StreamIndex < Vols.Streams.Size())
- if (m_Position < Vols.Streams[Vols.StreamIndex].Size)
+ if (GetVirtStreamPos() < Vols.Streams[Vols.StreamIndex].Size)
ArcInfo.ThereIsTail = true;
}
else
{
- ArcInfo.FinishPos = m_Position;
- ArcInfo.ThereIsTail = (ArcInfo.FileEndPos > m_Position);
+ ArcInfo.FinishPos = GetVirtStreamPos();
+ ArcInfo.ThereIsTail = (ArcInfo.FileEndPos > ArcInfo.FinishPos);
}
- _inBufMode = false;
+ DisableBufMode();
+
IsArcOpen = true;
if (!IsMultiVol)
Vols.Streams.Clear();
diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h
index 9b0afe28..a312c36a 100644
--- a/CPP/7zip/Archive/Zip/ZipIn.h
+++ b/CPP/7zip/Archive/Zip/ZipIn.h
@@ -3,12 +3,11 @@
#ifndef __ZIP_IN_H
#define __ZIP_IN_H
+#include "../../../Common/MyBuffer2.h"
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
-#include "../../Common/InBuffer.h"
-
#include "ZipHeader.h"
#include "ZipItem.h"
@@ -22,8 +21,12 @@ class CItemEx: public CItem
public:
UInt32 LocalFullHeaderSize; // including Name and Extra
+ bool DescriptorWasRead;
+
+ CItemEx(): DescriptorWasRead(false) {}
+
UInt64 GetLocalFullSize() const
- { return LocalFullHeaderSize + PackSize + (HasDescriptor() ? kDataDescriptorSize : 0); }
+ { return LocalFullHeaderSize + GetPackSizeWithDescriptor(); }
UInt64 GetDataPosition() const
{ return LocalHeaderPos + LocalFullHeaderSize; }
};
@@ -52,6 +55,10 @@ struct CInArchiveInfo
UInt64 FirstItemRelatOffset; /* Relative offset of first local (read from cd) (relative to Base).
= 0 in most archives
= size of stub for some SFXs */
+
+
+ int MarkerVolIndex;
+
bool CdWasRead;
bool IsSpanMode;
bool ThereIsTail;
@@ -68,6 +75,7 @@ struct CInArchiveInfo
FinishPos(0),
FileEndPos(0),
FirstItemRelatOffset(0),
+ MarkerVolIndex(-1),
CdWasRead(false),
IsSpanMode(false),
ThereIsTail(false)
@@ -82,6 +90,7 @@ struct CInArchiveInfo
MarkerPos2 = 0;
FinishPos = 0;
FileEndPos = 0;
+ MarkerVolIndex = -1;
ThereIsTail = false;
FirstItemRelatOffset = 0;
@@ -96,6 +105,10 @@ struct CInArchiveInfo
struct CCdInfo
{
+ bool IsFromEcd64;
+
+ UInt16 CommentSize;
+
// 64
UInt16 VersionMade;
UInt16 VersionNeedExtract;
@@ -108,39 +121,55 @@ struct CCdInfo
UInt64 Size;
UInt64 Offset;
- UInt16 CommentSize;
-
- CCdInfo() { memset(this, 0, sizeof(*this)); }
+ CCdInfo() { memset(this, 0, sizeof(*this)); IsFromEcd64 = false; }
void ParseEcd32(const Byte *p); // (p) includes signature
void ParseEcd64e(const Byte *p); // (p) exclude signature
+
+ bool IsEmptyArc() const
+ {
+ return ThisDisk == 0
+ && CdDisk == 0
+ && NumEntries_in_ThisDisk == 0
+ && NumEntries == 0
+ && Size == 0
+ && Offset == 0 // test it
+ ;
+ }
};
-class CVols
+struct CVols
{
-public:
-
struct CSubStreamInfo
{
CMyComPtr<IInStream> Stream;
UInt64 Size;
+ HRESULT SeekToStart() const { return Stream->Seek(0, STREAM_SEEK_SET, NULL); }
+
CSubStreamInfo(): Size(0) {}
};
CObjectVector<CSubStreamInfo> Streams;
- int StreamIndex;
+
+ int StreamIndex; // -1 for StartStream
+ // -2 for ZipStream at multivol detection code
+ // >=0 volume index in multivol
+
bool NeedSeek;
- CMyComPtr<IInStream> ZipStream;
-
bool StartIsExe; // is .exe
bool StartIsZ; // is .zip or .zNN
bool StartIsZip; // is .zip
bool IsUpperCase;
bool MissingZip;
- Int32 StartVolIndex; // = (NN - 1), if StartStream is .zNN
+
+ bool ecd_wasRead;
+
+ Int32 StartVolIndex; // -1, if unknown vol index
+ // = (NN - 1), if StartStream is .zNN
+ // = 0, if start vol is exe
Int32 StartParsingVol; // if we need local parsing, we must use that stream
unsigned NumVols;
@@ -148,19 +177,27 @@ public:
int EndVolIndex; // index of last volume (ecd volume),
// -1, if is not multivol
- UString BaseName; // including '.'
-
+ UString BaseName; // name of archive including '.'
UString MissingName;
+ CMyComPtr<IInStream> ZipStream;
+
CCdInfo ecd;
- bool ecd_wasRead;
+
+ UInt64 TotalBytesSize; // for MultiVol only
+
+ void ClearRefs()
+ {
+ Streams.Clear();
+ ZipStream.Release();
+ TotalBytesSize = 0;
+ }
void Clear()
{
StreamIndex = -1;
NeedSeek = false;
-
StartIsExe = false;
StartIsZ = false;
StartIsZip = false;
@@ -177,21 +214,12 @@ public:
MissingZip = false;
ecd_wasRead = false;
- Streams.Clear();
- ZipStream.Release();
+ ClearRefs();
}
HRESULT ParseArcName(IArchiveOpenVolumeCallback *volCallback);
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
-
- UInt64 GetTotalSize() const
- {
- UInt64 total = 0;
- FOR_VECTOR (i, Streams)
- total += Streams[i].Size;
- return total;
- }
};
@@ -210,44 +238,69 @@ public:
class CInArchive
{
- CInBuffer _inBuffer;
+ CMidBuffer Buffer;
+ size_t _bufPos;
+ size_t _bufCached;
+
+ UInt64 _streamPos;
+ UInt64 _cnt;
+
+ size_t GetAvail() const { return _bufCached - _bufPos; }
+
+ void InitBuf() { _bufPos = 0; _bufCached = 0; }
+ void DisableBufMode() { InitBuf(); _inBufMode = false; }
+
+ void SkipLookahed(size_t skip)
+ {
+ _bufPos += skip;
+ _cnt += skip;
+ }
+
+ UInt64 GetVirtStreamPos() { return _streamPos - _bufCached + _bufPos; }
+
bool _inBufMode;
- UInt32 m_Signature;
- UInt64 m_Position;
- UInt64 _processedCnt;
-
+ bool IsArcOpen;
bool CanStartNewVol;
+ UInt32 _signature;
+
CMyComPtr<IInStream> StreamRef;
IInStream *Stream;
IInStream *StartStream;
+ IArchiveOpenCallback *Callback;
- bool IsArcOpen;
+ HRESULT Seek_SavePos(UInt64 offset);
+ HRESULT SeekToVol(int volIndex, UInt64 offset);
+
+ HRESULT ReadFromCache(Byte *data, unsigned size, unsigned &processed);
HRESULT ReadVols2(IArchiveOpenVolumeCallback *volCallback,
unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols);
HRESULT ReadVols();
- HRESULT Seek(UInt64 offset);
- HRESULT FindMarker(IInStream *stream, const UInt64 *searchLimit);
- HRESULT IncreaseRealPosition(Int64 addValue, bool &isFinished);
+ HRESULT FindMarker(const UInt64 *searchLimit);
+ HRESULT IncreaseRealPosition(UInt64 addValue, bool &isFinished);
- HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize);
- void SafeReadBytes(void *data, unsigned size);
+ HRESULT LookAhead(size_t minRequiredInBuffer);
+ void SafeRead(Byte *data, unsigned size);
void ReadBuffer(CByteBuffer &buffer, unsigned size);
- Byte ReadByte();
- UInt16 ReadUInt16();
+ // Byte ReadByte();
+ // UInt16 ReadUInt16();
UInt32 ReadUInt32();
UInt64 ReadUInt64();
- void Skip(unsigned num);
- void Skip64(UInt64 num);
- void ReadFileName(unsigned nameSize, AString &dest);
- bool ReadExtra(unsigned extraSize, CExtraBlock &extraBlock,
- UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber);
+ void ReadSignature();
+
+ void Skip(size_t num);
+ HRESULT Skip64(UInt64 num, unsigned numFiles);
+
+ bool ReadFileName(unsigned nameSize, AString &dest);
+
+ bool ReadExtra(unsigned extraSize, CExtraBlock &extra,
+ UInt64 &unpackSize, UInt64 &packSize, UInt64 &localOffset, UInt32 &disk);
bool ReadLocalItem(CItemEx &item);
- HRESULT ReadLocalItemDescriptor(CItemEx &item);
+ HRESULT FindDescriptor(CItemEx &item, unsigned numFiles);
HRESULT ReadCdItem(CItemEx &item);
HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo);
HRESULT FindCd(bool checkOffsetMode);
@@ -255,21 +308,28 @@ class CInArchive
HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt32 &cdDisk, UInt64 &cdOffset, UInt64 &cdSize);
HRESULT ReadLocals(CObjectVector<CItemEx> &localItems);
- HRESULT ReadHeaders2(CObjectVector<CItemEx> &items);
+ HRESULT ReadHeaders(CObjectVector<CItemEx> &items);
HRESULT GetVolStream(unsigned vol, UInt64 pos, CMyComPtr<ISequentialInStream> &stream);
+
public:
CInArchiveInfo ArcInfo;
bool IsArc;
bool IsZip64;
+
bool HeadersError;
bool HeadersWarning;
bool ExtraMinorError;
bool UnexpectedEnd;
+ bool LocalsWereRead;
+ bool LocalsCenterMerged;
bool NoCentralDir;
+ bool Overflow32bit; // = true, if zip without Zip64 extension support and it has some fields values truncated to 32-bits.
+ bool Cd_NumEntries_Overflow_16bit; // = true, if no Zip64 and 16-bit ecd:NumEntries was overflowed.
bool MarkerIsFound;
+ bool MarkerIsSafe;
bool IsMultiVol;
bool UseDisk_in_SingleVol;
@@ -277,9 +337,7 @@ public:
CVols Vols;
- IArchiveOpenCallback *Callback;
-
- CInArchive(): Stream(NULL), Callback(NULL), IsArcOpen(false) {}
+ CInArchive(): Stream(NULL), StartStream(NULL), Callback(NULL), IsArcOpen(false) {}
UInt64 GetPhySize() const
{
@@ -301,7 +359,6 @@ public:
void ClearRefs();
void Close();
HRESULT Open(IInStream *stream, const UInt64 *searchLimit, IArchiveOpenCallback *callback, CObjectVector<CItemEx> &items);
- HRESULT ReadHeaders(CObjectVector<CItemEx> &items);
bool IsOpen() const { return IsArcOpen; }
@@ -329,7 +386,8 @@ public:
}
- HRESULT ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail);
+ HRESULT CheckDescriptor(const CItemEx &item);
+ HRESULT ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail, bool &headersError);
HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item);
HRESULT GetItemStream(const CItemEx &item, bool seekPackData, CMyComPtr<ISequentialInStream> &stream);
diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp
index e732df7c..4fc59f79 100644
--- a/CPP/7zip/Archive/Zip/ZipItem.cpp
+++ b/CPP/7zip/Archive/Zip/ZipItem.cpp
@@ -5,9 +5,12 @@
#include "../../../../C/CpuArch.h"
#include "../../../../C/7zCrc.h"
+#include "../../../Common/IntToString.h"
#include "../../../Common/MyLinux.h"
#include "../../../Common/StringConvert.h"
+#include "../../../Windows/PropVariantUtils.h"
+
#include "../Common/ItemNameUtils.h"
#include "ZipItem.h"
@@ -17,6 +20,62 @@ namespace NZip {
using namespace NFileHeader;
+static const CUInt32PCharPair g_ExtraTypes[] =
+{
+ { NExtraID::kZip64, "Zip64" },
+ { NExtraID::kNTFS, "NTFS" },
+ { NExtraID::kStrongEncrypt, "StrongCrypto" },
+ { NExtraID::kUnixTime, "UT" },
+ { NExtraID::kUnixExtra, "UX" },
+ { NExtraID::kIzUnicodeComment, "uc" },
+ { NExtraID::kIzUnicodeName, "up" },
+ { NExtraID::kWzAES, "WzAES" }
+};
+
+void CExtraSubBlock::PrintInfo(AString &s) const
+{
+ for (unsigned i = 0; i < ARRAY_SIZE(g_ExtraTypes); i++)
+ {
+ const CUInt32PCharPair &pair = g_ExtraTypes[i];
+ if (pair.Value == ID)
+ {
+ s += pair.Name;
+ return;
+ }
+ }
+ {
+ char sz[32];
+ sz[0] = '0';
+ sz[1] = 'x';
+ ConvertUInt32ToHex(ID, sz + 2);
+ s += sz;
+ }
+}
+
+
+void CExtraBlock::PrintInfo(AString &s) const
+{
+ if (Error)
+ s.Add_OptSpaced("Extra_ERROR");
+
+ if (MinorError)
+ s.Add_OptSpaced("Minor_Extra_ERROR");
+
+ if (IsZip64 || IsZip64_Error)
+ {
+ s.Add_OptSpaced("Zip64");
+ if (IsZip64_Error)
+ s += "_ERROR";
+ }
+
+ FOR_VECTOR (i, SubBlocks)
+ {
+ s.Add_Space_if_NotEmpty();
+ SubBlocks[i].PrintInfo(s);
+ }
+}
+
+
bool CExtraSubBlock::ExtractNtfsTime(unsigned index, FILETIME &ft) const
{
ft.dwHighDateTime = ft.dwLowDateTime = 0;
@@ -83,6 +142,19 @@ bool CExtraSubBlock::ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res
}
+bool CExtraSubBlock::ExtractUnixExtraTime(unsigned index, UInt32 &res) const
+{
+ res = 0;
+ const size_t size = Data.Size();
+ unsigned offset = index * 4;
+ if (ID != NExtraID::kUnixExtra || size < offset + 4)
+ return false;
+ const Byte *p = (const Byte *)Data + offset;
+ res = GetUi32(p);
+ return true;
+}
+
+
bool CExtraBlock::GetNtfsTime(unsigned index, FILETIME &ft) const
{
FOR_VECTOR (i, SubBlocks)
@@ -96,11 +168,29 @@ bool CExtraBlock::GetNtfsTime(unsigned index, FILETIME &ft) const
bool CExtraBlock::GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
- FOR_VECTOR (i, SubBlocks)
{
- const CExtraSubBlock &sb = SubBlocks[i];
- if (sb.ID == NFileHeader::NExtraID::kUnixTime)
- return sb.ExtractUnixTime(isCentral, index, res);
+ FOR_VECTOR (i, SubBlocks)
+ {
+ const CExtraSubBlock &sb = SubBlocks[i];
+ if (sb.ID == NFileHeader::NExtraID::kUnixTime)
+ return sb.ExtractUnixTime(isCentral, index, res);
+ }
+ }
+
+ switch (index)
+ {
+ case NUnixTime::kMTime: index = NUnixExtra::kMTime; break;
+ case NUnixTime::kATime: index = NUnixExtra::kATime; break;
+ default: return false;
+ }
+
+ {
+ FOR_VECTOR (i, SubBlocks)
+ {
+ const CExtraSubBlock &sb = SubBlocks[i];
+ if (sb.ID == NFileHeader::NExtraID::kUnixExtra)
+ return sb.ExtractUnixExtraTime(index, res);
+ }
}
return false;
}
diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h
index c134ec79..0cf9bd09 100644
--- a/CPP/7zip/Archive/Zip/ZipItem.h
+++ b/CPP/7zip/Archive/Zip/ZipItem.h
@@ -22,11 +22,12 @@ struct CVersion
struct CExtraSubBlock
{
- UInt16 ID;
+ UInt32 ID;
CByteBuffer Data;
bool ExtractNtfsTime(unsigned index, FILETIME &ft) const;
bool ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
+ bool ExtractUnixExtraTime(unsigned index, UInt32 &res) const;
bool ExtractIzUnicode(UInt32 crc, AString &name) const
{
@@ -44,6 +45,8 @@ struct CExtraSubBlock
return false;
return CheckUTF8(name, false);
}
+
+ void PrintInfo(AString &s) const;
};
const unsigned k_WzAesExtra_Size = 7;
@@ -129,11 +132,22 @@ struct CStrongCryptoExtra
bool CertificateIsUsed() const { return (Flags > 0x0001); }
};
+
struct CExtraBlock
{
CObjectVector<CExtraSubBlock> SubBlocks;
+ bool Error;
+ bool MinorError;
+ bool IsZip64;
+ bool IsZip64_Error;
- void Clear() { SubBlocks.Clear(); }
+ CExtraBlock(): Error(false), MinorError(false), IsZip64(false), IsZip64_Error(false) {}
+
+ void Clear()
+ {
+ SubBlocks.Clear();
+ IsZip64 = false;
+ }
size_t GetSize() const
{
@@ -176,6 +190,8 @@ struct CExtraBlock
bool GetNtfsTime(unsigned index, FILETIME &ft) const;
bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
+ void PrintInfo(AString &s) const;
+
void RemoveUnknownSubBlocks()
{
for (unsigned i = SubBlocks.Size(); i != 0;)
@@ -206,12 +222,19 @@ public:
CExtraBlock LocalExtra;
+ unsigned GetDescriptorSize() const { return LocalExtra.IsZip64 ? kDataDescriptorSize64 : kDataDescriptorSize32; }
+
+ UInt64 GetPackSizeWithDescriptor() const
+ { return PackSize + (HasDescriptor() ? GetDescriptorSize() : 0); }
+
bool IsUtf8() const { return (Flags & NFileHeader::NFlags::kUtf8) != 0; }
bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kEncrypted) != 0; }
bool IsStrongEncrypted() const { return IsEncrypted() && (Flags & NFileHeader::NFlags::kStrongEncrypted) != 0; }
bool IsAesEncrypted() const { return IsEncrypted() && (IsStrongEncrypted() || Method == NFileHeader::NCompressionMethod::kWzAES); }
bool IsLzmaEOS() const { return (Flags & NFileHeader::NFlags::kLzmaEOS) != 0; }
bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; }
+
+ unsigned GetDeflateLevel() const { return (Flags >> 1) & 3; }
bool IsDir() const;
diff --git a/CPP/7zip/Archive/Zip/ZipOut.cpp b/CPP/7zip/Archive/Zip/ZipOut.cpp
index 2a1ba2c4..1fdc24f8 100644
--- a/CPP/7zip/Archive/Zip/ZipOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipOut.cpp
@@ -21,48 +21,20 @@ HRESULT COutArchive::Create(IOutStream *outStream)
return m_Stream->Seek(0, STREAM_SEEK_CUR, &m_Base);
}
-void COutArchive::MoveCurPos(UInt64 distanceToMove)
-{
- m_CurPos += distanceToMove; // test overflow
-}
-
-void COutArchive::SeekToRelatPos(UInt64 offset)
+void COutArchive::SeekToCurPos()
{
- HRESULT res = m_Stream->Seek(m_Base + offset, STREAM_SEEK_SET, NULL);
+ HRESULT res = m_Stream->Seek(m_Base + m_CurPos, STREAM_SEEK_SET, NULL);
if (res != S_OK)
throw CSystemException(res);
}
-void COutArchive::PrepareWriteCompressedDataZip64(unsigned fileNameLen, bool isZip64, bool aesEncryption)
-{
- m_IsZip64 = isZip64;
- m_ExtraSize = isZip64 ? (4 + 8 + 8) : 0;
- if (aesEncryption)
- m_ExtraSize += 4 + k_WzAesExtra_Size;
- m_LocalFileHeaderSize = kLocalHeaderSize + fileNameLen + m_ExtraSize;
-}
-
-void COutArchive::PrepareWriteCompressedData(unsigned fileNameLen, UInt64 unPackSize, bool aesEncryption)
-{
- // We use Zip64, if unPackSize size is larger than 0xF8000000 to support
- // cases when compressed size can be about 3% larger than uncompressed size
-
- PrepareWriteCompressedDataZip64(fileNameLen, unPackSize >= (UInt32)0xF8000000, aesEncryption);
-}
-
#define DOES_NEED_ZIP64(v) (v >= (UInt32)0xFFFFFFFF)
+// #define DOES_NEED_ZIP64(v) (v >= 0)
-void COutArchive::PrepareWriteCompressedData2(unsigned fileNameLen, UInt64 unPackSize, UInt64 packSize, bool aesEncryption)
-{
- bool isZip64 =
- DOES_NEED_ZIP64(unPackSize) ||
- DOES_NEED_ZIP64(packSize);
- PrepareWriteCompressedDataZip64(fileNameLen, isZip64, aesEncryption);
-}
-void COutArchive::WriteBytes(const void *buffer, UInt32 size)
+void COutArchive::WriteBytes(const void *data, size_t size)
{
- m_OutBuffer.WriteBytes(buffer, size);
+ m_OutBuffer.WriteBytes(data, size);
m_CurPos += size;
}
@@ -74,11 +46,8 @@ void COutArchive::Write8(Byte b)
void COutArchive::Write16(UInt16 val)
{
- for (int i = 0; i < 2; i++)
- {
- Write8((Byte)val);
- val >>= 8;
- }
+ Write8((Byte)val);
+ Write8((Byte)(val >> 8));
}
void COutArchive::Write32(UInt32 val)
@@ -101,15 +70,12 @@ void COutArchive::Write64(UInt64 val)
void COutArchive::WriteExtra(const CExtraBlock &extra)
{
- if (extra.SubBlocks.Size() != 0)
+ FOR_VECTOR (i, extra.SubBlocks)
{
- FOR_VECTOR (i, extra.SubBlocks)
- {
- const CExtraSubBlock &subBlock = extra.SubBlocks[i];
- Write16(subBlock.ID);
- Write16((UInt16)subBlock.Data.Size());
- WriteBytes(subBlock.Data, (UInt32)subBlock.Data.Size());
- }
+ const CExtraSubBlock &subBlock = extra.SubBlocks[i];
+ Write16((UInt16)subBlock.ID);
+ Write16((UInt16)subBlock.Data.Size());
+ WriteBytes(subBlock.Data, (UInt16)subBlock.Data.Size());
}
}
@@ -125,40 +91,65 @@ void COutArchive::WriteCommonItemInfo(const CLocalItem &item, bool isZip64)
Write16(item.Flags);
Write16(item.Method);
Write32(item.Time);
- Write32(item.Crc);
}
+
#define WRITE_32_VAL_SPEC(__v, __isZip64) Write32((__isZip64) ? 0xFFFFFFFF : (UInt32)(__v));
-void COutArchive::WriteLocalHeader(const CLocalItem &item)
+
+void COutArchive::WriteLocalHeader(CItemOut &item, bool needCheck)
{
- SeekToCurPos();
+ m_LocalHeaderPos = m_CurPos;
+ item.LocalHeaderPos = m_CurPos;
- bool isZip64 = m_IsZip64 ||
+ bool isZip64 =
DOES_NEED_ZIP64(item.PackSize) ||
DOES_NEED_ZIP64(item.Size);
-
+
+ if (needCheck && m_IsZip64)
+ isZip64 = true;
+
+ const UInt32 localExtraSize = (UInt32)((isZip64 ? (4 + 8 + 8): 0) + item.LocalExtra.GetSize());
+ if ((UInt16)localExtraSize != localExtraSize)
+ throw CSystemException(E_FAIL);
+ if (needCheck && m_ExtraSize != localExtraSize)
+ throw CSystemException(E_FAIL);
+
+ m_IsZip64 = isZip64;
+ m_ExtraSize = localExtraSize;
+
+ item.LocalExtra.IsZip64 = isZip64;
+
Write32(NSignature::kLocalFileHeader);
+
WriteCommonItemInfo(item, isZip64);
+
+ Write32(item.HasDescriptor() ? 0 : item.Crc);
- WRITE_32_VAL_SPEC(item.PackSize, isZip64);
- WRITE_32_VAL_SPEC(item.Size, isZip64);
-
- Write16((UInt16)item.Name.Len());
+ UInt64 packSize = item.PackSize;
+ UInt64 size = item.Size;
+
+ if (item.HasDescriptor())
{
- UInt16 localExtraSize = (UInt16)((isZip64 ? (4 + 8 + 8): 0) + item.LocalExtra.GetSize());
- if (localExtraSize != m_ExtraSize)
- throw CSystemException(E_FAIL);
+ packSize = 0;
+ size = 0;
}
- Write16((UInt16)m_ExtraSize);
- WriteBytes((const char *)item.Name, item.Name.Len());
+
+ WRITE_32_VAL_SPEC(packSize, isZip64);
+ WRITE_32_VAL_SPEC(size, isZip64);
+
+ Write16((UInt16)item.Name.Len());
+
+ Write16((UInt16)localExtraSize);
+
+ WriteBytes((const char *)item.Name, (UInt16)item.Name.Len());
if (isZip64)
{
Write16(NFileHeader::NExtraID::kZip64);
Write16(8 + 8);
- Write64(item.Size);
- Write64(item.PackSize);
+ Write64(size);
+ Write64(packSize);
}
WriteExtra(item.LocalExtra);
@@ -166,10 +157,57 @@ void COutArchive::WriteLocalHeader(const CLocalItem &item)
// Why don't we write NTFS timestamps to local header?
// Probably we want to reduce size of archive?
+ const UInt32 localFileHeaderSize = (UInt32)(m_CurPos - m_LocalHeaderPos);
+ if (needCheck && m_LocalFileHeaderSize != localFileHeaderSize)
+ throw CSystemException(E_FAIL);
+ m_LocalFileHeaderSize = localFileHeaderSize;
+
m_OutBuffer.FlushWithCheck();
- MoveCurPos(item.PackSize);
}
+
+void COutArchive::WriteLocalHeader_Replace(CItemOut &item)
+{
+ m_CurPos = m_LocalHeaderPos + m_LocalFileHeaderSize + item.PackSize;
+
+ if (item.HasDescriptor())
+ {
+ WriteDescriptor(item);
+ m_OutBuffer.FlushWithCheck();
+ }
+
+ const UInt64 nextPos = m_CurPos;
+ m_CurPos = m_LocalHeaderPos;
+ SeekToCurPos();
+ WriteLocalHeader(item, true);
+ m_CurPos = nextPos;
+ SeekToCurPos();
+}
+
+
+void COutArchive::WriteDescriptor(const CItemOut &item)
+{
+ Byte buf[kDataDescriptorSize64];
+ SetUi32(buf, NSignature::kDataDescriptor);
+ SetUi32(buf + 4, item.Crc);
+ unsigned descriptorSize;
+ if (m_IsZip64)
+ {
+ SetUi64(buf + 8, item.PackSize);
+ SetUi64(buf + 16, item.Size);
+ descriptorSize = kDataDescriptorSize64;
+ }
+ else
+ {
+ SetUi32(buf + 8, (UInt32)item.PackSize);
+ SetUi32(buf + 12, (UInt32)item.Size);
+ descriptorSize = kDataDescriptorSize32;
+ }
+ WriteBytes(buf, descriptorSize);
+}
+
+
+
void COutArchive::WriteCentralHeader(const CItemOut &item)
{
bool isUnPack64 = DOES_NEED_ZIP64(item.Size);
@@ -182,6 +220,7 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
Write8(item.MadeByVersion.HostOS);
WriteCommonItemInfo(item, isZip64);
+ Write32(item.Crc);
WRITE_32_VAL_SPEC(item.PackSize, isPack64);
WRITE_32_VAL_SPEC(item.Size, isUnPack64);
@@ -196,7 +235,10 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
item.CentralExtra.GetSize());
Write16(centralExtraSize); // test it;
- Write16((UInt16)item.Comment.Size());
+
+ const UInt16 commentSize = (UInt16)item.Comment.Size();
+
+ Write16(commentSize);
Write16(0); // DiskNumberStart;
Write16(item.InternalAttrib);
Write32(item.ExternalAttrib);
@@ -228,14 +270,12 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
}
WriteExtra(item.CentralExtra);
- if (item.Comment.Size() > 0)
- WriteBytes(item.Comment, (UInt32)item.Comment.Size());
+ if (commentSize != 0)
+ WriteBytes(item.Comment, commentSize);
}
void COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const CByteBuffer *comment)
{
- SeekToCurPos();
-
UInt64 cdOffset = GetCurPos();
FOR_VECTOR (i, items)
WriteCentralHeader(items[i]);
@@ -252,6 +292,11 @@ void COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const CB
{
Write32(NSignature::kEcd64);
Write64(kEcd64_MainSize);
+
+ // to test extra block:
+ // const UInt32 extraSize = 1 << 26;
+ // Write64(kEcd64_MainSize + extraSize);
+
Write16(45); // made by version
Write16(45); // extract version
Write32(0); // ThisDiskNumber = 0;
@@ -261,6 +306,8 @@ void COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const CB
Write64((UInt64)cdSize);
Write64((UInt64)cdOffset);
+ // for (UInt32 iii = 0; iii < extraSize; iii++) Write8(1);
+
Write32(NSignature::kEcd64Locator);
Write32(0); // number of the disk with the start of the zip64 end of central directory
Write64(cd64EndOffset);
@@ -276,37 +323,23 @@ void COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const CB
WRITE_32_VAL_SPEC(cdSize, cdSize64);
WRITE_32_VAL_SPEC(cdOffset, cdOffset64);
- UInt32 commentSize = (UInt32)(comment ? comment->Size() : 0);
+ const UInt16 commentSize = (UInt16)(comment ? comment->Size() : 0);
Write16((UInt16)commentSize);
- if (commentSize > 0)
+ if (commentSize != 0)
WriteBytes((const Byte *)*comment, commentSize);
m_OutBuffer.FlushWithCheck();
}
-void COutArchive::CreateStreamForCompressing(IOutStream **outStream)
+void COutArchive::CreateStreamForCompressing(CMyComPtr<IOutStream> &outStream)
{
COffsetOutStream *streamSpec = new COffsetOutStream;
- CMyComPtr<IOutStream> tempStream(streamSpec);
- streamSpec->Init(m_Stream, m_Base + m_CurPos + m_LocalFileHeaderSize);
- *outStream = tempStream.Detach();
-}
-
-/*
-void COutArchive::SeekToPackedDataPosition()
-{
- SeekTo(m_BasePosition + m_LocalFileHeaderSize);
-}
-*/
-
-void COutArchive::SeekToCurPos()
-{
- SeekToRelatPos(m_CurPos);
+ outStream = streamSpec;
+ streamSpec->Init(m_Stream, m_Base + m_CurPos);
}
-void COutArchive::CreateStreamForCopying(ISequentialOutStream **outStream)
+void COutArchive::CreateStreamForCopying(CMyComPtr<ISequentialOutStream> &outStream)
{
- CMyComPtr<ISequentialOutStream> tempStream(m_Stream);
- *outStream = tempStream.Detach();
+ outStream = m_Stream;
}
}}
diff --git a/CPP/7zip/Archive/Zip/ZipOut.h b/CPP/7zip/Archive/Zip/ZipOut.h
index 056d0d09..0a0ac0c8 100644
--- a/CPP/7zip/Archive/Zip/ZipOut.h
+++ b/CPP/7zip/Archive/Zip/ZipOut.h
@@ -5,7 +5,6 @@
#include "../../../Common/MyCom.h"
-#include "../../IStream.h"
#include "../../Common/OutBuffer.h"
#include "ZipItem.h"
@@ -13,8 +12,6 @@
namespace NArchive {
namespace NZip {
-// can throw CSystemException and COutBufferException
-
class CItemOut: public CItem
{
public:
@@ -28,21 +25,23 @@ public:
CItemOut(): NtfsTimeIsDefined(false) {}
};
+
+// COutArchive can throw CSystemException and COutBufferException
+
class COutArchive
{
- CMyComPtr<IOutStream> m_Stream;
COutBuffer m_OutBuffer;
+ CMyComPtr<IOutStream> m_Stream;
- UInt64 m_Base; // Base of arc (offset in output Stream)
+ UInt64 m_Base; // Base of archive (offset in output Stream)
UInt64 m_CurPos; // Curent position in archive (relative from m_Base)
+ UInt64 m_LocalHeaderPos; // LocalHeaderPos (relative from m_Base) for last WriteLocalHeader() call
UInt32 m_LocalFileHeaderSize;
UInt32 m_ExtraSize;
bool m_IsZip64;
- void SeekToRelatPos(UInt64 offset);
-
- void WriteBytes(const void *buffer, UInt32 size);
+ void WriteBytes(const void *data, size_t size);
void Write8(Byte b);
void Write16(UInt16 val);
void Write32(UInt32 val);
@@ -57,30 +56,26 @@ class COutArchive
void WriteCommonItemInfo(const CLocalItem &item, bool isZip64);
void WriteCentralHeader(const CItemOut &item);
- void PrepareWriteCompressedDataZip64(unsigned fileNameLen, bool isZip64, bool aesEncryption);
-
+ void SeekToCurPos();
public:
HRESULT Create(IOutStream *outStream);
- void MoveCurPos(UInt64 distanceToMove);
UInt64 GetCurPos() const { return m_CurPos; }
- void SeekToCurPos();
-
- void PrepareWriteCompressedData(unsigned fileNameLen, UInt64 unPackSize, bool aesEncryption);
- void PrepareWriteCompressedData2(unsigned fileNameLen, UInt64 unPackSize, UInt64 packSize, bool aesEncryption);
- void WriteLocalHeader(const CLocalItem &item);
-
- void WriteLocalHeader_And_SeekToNextFile(const CLocalItem &item)
+ void MoveCurPos(UInt64 distanceToMove)
{
- WriteLocalHeader(item);
- SeekToCurPos();
+ m_CurPos += distanceToMove;
}
+ void WriteLocalHeader(CItemOut &item, bool needCheck = false);
+ void WriteLocalHeader_Replace(CItemOut &item);
+
+ void WriteDescriptor(const CItemOut &item);
+
void WriteCentralDir(const CObjectVector<CItemOut> &items, const CByteBuffer *comment);
- void CreateStreamForCompressing(IOutStream **outStream);
- void CreateStreamForCopying(ISequentialOutStream **outStream);
+ void CreateStreamForCompressing(CMyComPtr<IOutStream> &outStream);
+ void CreateStreamForCopying(CMyComPtr<ISequentialOutStream> &outStream);
};
}}
diff --git a/CPP/7zip/Archive/Zip/ZipRegister.cpp b/CPP/7zip/Archive/Zip/ZipRegister.cpp
index 6674189f..e6929f1b 100644
--- a/CPP/7zip/Archive/Zip/ZipRegister.cpp
+++ b/CPP/7zip/Archive/Zip/ZipRegister.cpp
@@ -10,13 +10,14 @@ namespace NArchive {
namespace NZip {
static const Byte k_Signature[] = {
- 4, 0x50, 0x4B, 0x03, 0x04,
- 4, 0x50, 0x4B, 0x05, 0x06,
- 6, 0x50, 0x4B, 0x07, 0x08, 0x50, 0x4B,
- 6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B };
+ 4, 0x50, 0x4B, 0x03, 0x04, // Local
+ 4, 0x50, 0x4B, 0x05, 0x06, // Ecd
+ 4, 0x50, 0x4B, 0x06, 0x06, // Ecd64
+ 6, 0x50, 0x4B, 0x07, 0x08, 0x50, 0x4B, // Span / Descriptor
+ 6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B }; // NoSpan
REGISTER_ARC_IO(
- "zip", "zip z01 zipx jar xpi odt ods docx xlsx epub", 0, 1,
+ "zip", "zip z01 zipx jar xpi odt ods docx xlsx epub ipa apk appx", 0, 1,
k_Signature,
0,
NArcInfoFlags::kFindSignature |
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
index bc50c1d7..81f48a2a 100644
--- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
@@ -42,32 +42,38 @@ static const Byte kHostOS =
static const Byte kMadeByHostOS = kHostOS;
static const Byte kExtractHostOS = kHostOS;
-static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStored;
+static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStore;
-static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, UInt64 size,
- COutArchive &outArchive, ICompressProgressInfo *progress)
+
+static void AddAesExtra(CItem &item, Byte aesKeyMode, UInt16 method)
{
- CMyComPtr<ISequentialOutStream> outStream;
- outArchive.CreateStreamForCopying(&outStream);
- return NCompress::CopyStream_ExactSize(inStream, outStream, size, progress);
+ CWzAesExtra wzAesField;
+ wzAesField.Strength = aesKeyMode;
+ wzAesField.Method = method;
+ item.Method = NFileHeader::NCompressionMethod::kWzAES;
+ item.Crc = 0;
+ CExtraSubBlock sb;
+ wzAesField.SetSubBlock(sb);
+ item.LocalExtra.SubBlocks.Add(sb);
+ item.CentralExtra.SubBlocks.Add(sb);
}
+
static void SetFileHeader(
- COutArchive &archive,
const CCompressionMethodMode &options,
const CUpdateItem &ui,
// bool isSeqMode,
CItemOut &item)
{
item.Size = ui.Size;
- bool isDir;
+ bool isDir = ui.IsDir;
item.ClearFlags();
if (ui.NewProps)
{
- isDir = ui.IsDir;
item.Name = ui.Name;
+ item.Comment = ui.Comment;
item.SetUtf8(ui.IsUtf8);
item.ExternalAttrib = ui.Attrib;
item.Time = ui.Time;
@@ -76,10 +82,11 @@ static void SetFileHeader(
item.Ntfs_CTime = ui.Ntfs_CTime;
item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined;
}
+ /*
else
isDir = item.IsDir();
+ */
- item.LocalHeaderPos = archive.GetCurPos();
item.MadeByVersion.HostOS = kMadeByHostOS;
item.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion;
@@ -97,14 +104,32 @@ static void SetFileHeader(
item.Size = 0;
item.Crc = 0;
}
+
+ item.LocalExtra.Clear();
+ item.CentralExtra.Clear();
+
+ if (isDir)
+ {
+ item.ExtractVersion.Version = NFileHeader::NCompressionMethod::kExtractVersion_Dir;
+ item.Method = kMethodForDirectory;
+ item.PackSize = 0;
+ item.Size = 0;
+ item.Crc = 0;
+ }
+ else if (options.IsRealAesMode())
+ AddAesExtra(item, options.AesKeyMode, (Byte)(options.MethodSequence.IsEmpty() ? 8 : options.MethodSequence[0]));
}
+// we call SetItemInfoFromCompressingResult() after SetFileHeader()
+
static void SetItemInfoFromCompressingResult(const CCompressingResult &compressingResult,
bool isAesMode, Byte aesKeyMode, CItem &item)
{
item.ExtractVersion.Version = compressingResult.ExtractVersion;
item.Method = compressingResult.Method;
+ if (compressingResult.Method == NFileHeader::NCompressionMethod::kLZMA && compressingResult.LzmaEos)
+ item.Flags |= NFileHeader::NFlags::kLzmaEOS;
item.Crc = compressingResult.CRC;
item.Size = compressingResult.UnpackSize;
item.PackSize = compressingResult.PackSize;
@@ -113,17 +138,7 @@ static void SetItemInfoFromCompressingResult(const CCompressingResult &compressi
item.CentralExtra.Clear();
if (isAesMode)
- {
- CWzAesExtra wzAesField;
- wzAesField.Strength = aesKeyMode;
- wzAesField.Method = compressingResult.Method;
- item.Method = NFileHeader::NCompressionMethod::kWzAES;
- item.Crc = 0;
- CExtraSubBlock sb;
- wzAesField.SetSubBlock(sb);
- item.LocalExtra.SubBlocks.Add(sb);
- item.CentralExtra.SubBlocks.Add(sb);
- }
+ AddAesExtra(item, aesKeyMode, compressingResult.Method);
}
@@ -151,6 +166,7 @@ struct CThreadInfo
HRESULT Result;
CCompressingResult CompressingResult;
+ bool SeqMode;
bool IsFree;
UInt32 UpdateIndex;
UInt32 FileTime;
@@ -160,6 +176,7 @@ struct CThreadInfo
ProgressSpec(0),
OutStreamSpec(0),
Coder(options),
+ SeqMode(false),
FileTime(0)
{}
@@ -193,7 +210,7 @@ void CThreadInfo::WaitAndCode()
Result = Coder.Compress(
EXTERNAL_CODECS_LOC_VARS
- InStream, OutStream, FileTime, Progress, CompressingResult);
+ InStream, OutStream, SeqMode, FileTime, Progress, CompressingResult);
if (Result == S_OK && Progress)
Result = Progress->SetRatioInfo(&CompressingResult.UnpackSize, &CompressingResult.PackSize);
@@ -342,6 +359,8 @@ static HRESULT UpdateItemOldData(
NUpdateNotifyOp::kReplicate))
}
+ UInt64 rangeSize;
+
if (ui.NewProps)
{
if (item.HasDescriptor())
@@ -349,14 +368,11 @@ static HRESULT UpdateItemOldData(
// use old name size.
- CMyComPtr<ISequentialInStream> packStream;
- RINOK(inArchive->GetItemStream(itemEx, true, packStream));
- if (!packStream)
- return E_NOTIMPL;
-
// we keep ExternalAttrib and some another properties from old archive
// item.ExternalAttrib = ui.Attrib;
+ // if we don't change Comment, we keep Comment from OldProperties
+ item.Comment = ui.Comment;
item.Name = ui.Name;
item.SetUtf8(ui.IsUtf8);
item.Time = ui.Time;
@@ -367,46 +383,37 @@ static HRESULT UpdateItemOldData(
item.CentralExtra.RemoveUnknownSubBlocks();
item.LocalExtra.RemoveUnknownSubBlocks();
- item.LocalHeaderPos = archive.GetCurPos();
- archive.PrepareWriteCompressedData2(item.Name.Len(), item.Size, item.PackSize, item.LocalExtra.HasWzAes());
archive.WriteLocalHeader(item);
-
- RINOK(CopyBlockToArchive(packStream, itemEx.PackSize, archive, progress));
-
- complexity += itemEx.PackSize;
+ rangeSize = item.GetPackSizeWithDescriptor();
}
else
{
- CMyComPtr<ISequentialInStream> packStream;
- RINOK(inArchive->GetItemStream(itemEx, false, packStream));
- if (!packStream)
- return E_NOTIMPL;
-
- // set new header position
item.LocalHeaderPos = archive.GetCurPos();
-
- const UInt64 rangeSize = itemEx.GetLocalFullSize();
-
- RINOK(CopyBlockToArchive(packStream, rangeSize, archive, progress));
-
- complexity += rangeSize;
- archive.MoveCurPos(rangeSize);
+ rangeSize = itemEx.GetLocalFullSize();
}
- return S_OK;
+ CMyComPtr<ISequentialInStream> packStream;
+
+ RINOK(inArchive->GetItemStream(itemEx, ui.NewProps, packStream));
+ if (!packStream)
+ return E_NOTIMPL;
+
+ complexity += rangeSize;
+
+ CMyComPtr<ISequentialOutStream> outStream;
+ archive.CreateStreamForCopying(outStream);
+ HRESULT res = NCompress::CopyStream_ExactSize(packStream, outStream, rangeSize, progress);
+ archive.MoveCurPos(rangeSize);
+ return res;
}
static void WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options,
const CUpdateItem &ui, CItemOut &item)
{
- SetFileHeader(archive, *options, ui, item);
- archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size,
- // options->IsRealAesMode()
- false // fixed 9.31
- );
- archive.WriteLocalHeader_And_SeekToNextFile(item);
+ SetFileHeader(*options, ui, item);
+ archive.WriteLocalHeader(item);
}
@@ -490,6 +497,8 @@ static HRESULT Update2St(
if (!ui.NewProps || !ui.NewData)
{
+ // Note: for (ui.NewProps && !ui.NewData) it copies Props from old archive,
+ // But we will rewrite all important properties later. But we can keep some properties like Comment
itemEx = inputItems[ui.IndexInArc];
if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK)
return E_NOTIMPL;
@@ -498,7 +507,8 @@ static HRESULT Update2St(
if (ui.NewData)
{
- bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir());
+ // bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir());
+ bool isDir = ui.IsDir;
if (isDir)
{
WriteDirHeader(archive, options, ui, item);
@@ -517,28 +527,39 @@ static HRESULT Update2St(
if (!fileInStream)
return E_INVALIDARG;
- // bool isSeqMode = false;
- /*
+ bool seqMode;
{
CMyComPtr<IInStream> inStream2;
fileInStream->QueryInterface(IID_IInStream, (void **)&inStream2);
- isSeqMode = (inStream2 == NULL);
+ seqMode = (inStream2 == NULL);
}
- */
+ // seqMode = true; // to test seqMode
UpdatePropsFromStream(ui, fileInStream, updateCallback, totalComplexity);
- SetFileHeader(archive, *options, ui, item);
+ SetFileHeader(*options, ui, item);
+
+ item.SetDescriptorMode(seqMode);
// file Size can be 64-bit !!!
- archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, options->IsRealAesMode());
+
CCompressingResult compressingResult;
+
+ RINOK(compressor.Set_Pre_CompressionResult(
+ seqMode,
+ ui.Size,
+ compressingResult));
+
+ SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item);
+
+ archive.WriteLocalHeader(item);
+
CMyComPtr<IOutStream> outStream;
- archive.CreateStreamForCompressing(&outStream);
+ archive.CreateStreamForCompressing(outStream);
RINOK(compressor.Compress(
EXTERNAL_CODECS_LOC_VARS
fileInStream, outStream,
- ui.Time,
+ seqMode, ui.Time,
progress, compressingResult));
if (compressingResult.FileTimeWasUsed)
@@ -551,7 +572,9 @@ static HRESULT Update2St(
}
SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item);
- archive.WriteLocalHeader_And_SeekToNextFile(item);
+
+ archive.WriteLocalHeader_Replace(item);
+
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
unpackSizeTotal += item.Size;
packSizeTotal += item.PackSize;
@@ -561,7 +584,9 @@ static HRESULT Update2St(
{
UInt64 complexity = 0;
lps->SendRatio = false;
+
RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity));
+
lps->SendRatio = true;
lps->ProgressOffset += complexity;
}
@@ -591,6 +616,7 @@ static HRESULT Update2(
CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
+ bool unknownComplexity = false;
UInt64 complexity = 0;
UInt64 numFilesToCompress = 0;
UInt64 numBytesToCompress = 0;
@@ -602,7 +628,10 @@ static HRESULT Update2(
const CUpdateItem &ui = updateItems[i];
if (ui.NewData)
{
- complexity += ui.Size;
+ if (ui.Size == (UInt64)(Int64)-1)
+ unknownComplexity = true;
+ else
+ complexity += ui.Size;
numBytesToCompress += ui.Size;
numFilesToCompress++;
/*
@@ -625,19 +654,49 @@ static HRESULT Update2(
if (comment)
complexity += comment->Size();
complexity++; // end of central
- updateCallback->SetTotal(complexity);
+
+ if (!unknownComplexity)
+ updateCallback->SetTotal(complexity);
UInt64 totalComplexity = complexity;
- CAddCommon compressor(options);
+ CCompressionMethodMode options2 = options;
+
+ if (options2._methods.IsEmpty())
+ {
+ // we need method item, if default method was used
+ options2._methods.AddNew();
+ }
+
+ CAddCommon compressor(options2);
complexity = 0;
- CCompressionMethodMode options2 = options;
+ const Byte method = options.MethodSequence.Front();
+
+ COneMethodInfo *oneMethodMain = NULL;
+ if (!options2._methods.IsEmpty())
+ oneMethodMain = &options2._methods[0];
+
+ {
+ FOR_VECTOR (mi, options2._methods)
+ {
+ options2.SetGlobalLevelTo(options2._methods[mi]);
+ }
+ }
+
+ if (oneMethodMain)
+ {
+ // appnote recommends to use EOS marker for LZMA.
+ if (method == NFileHeader::NCompressionMethod::kLZMA)
+ oneMethodMain->AddProp_EndMarker_if_NotFound(true);
+ }
+
#ifndef _7ZIP_ST
- UInt32 numThreads = options.NumThreads;
+ UInt32 numThreads = options._numThreads;
+
const UInt32 kNumMaxThreads = 64;
if (numThreads > kNumMaxThreads)
numThreads = kNumMaxThreads;
@@ -646,7 +705,6 @@ static HRESULT Update2(
if (numThreads < 1)
numThreads = 1;
-
const size_t kMemPerThread = (1 << 25);
const size_t kBlockSize = 1 << 16;
@@ -655,44 +713,69 @@ static HRESULT Update2(
if (numFilesToCompress <= 1)
mtMode = false;
- Byte method = options.MethodSequence.Front();
-
if (!mtMode)
{
- if (options2.MethodInfo.FindProp(NCoderPropID::kNumThreads) < 0)
+ FOR_VECTOR (mi, options2._methods)
{
- // fixed for 9.31. bzip2 default is just one thread.
- if (options2.NumThreadsWasChanged || method == NFileHeader::NCompressionMethod::kBZip2)
- options2.MethodInfo.AddProp_NumThreads(numThreads);
+ COneMethodInfo &onem = options2._methods[mi];
+
+ if (onem.FindProp(NCoderPropID::kNumThreads) < 0)
+ {
+ // fixed for 9.31. bzip2 default is just one thread.
+ onem.AddProp_NumThreads(numThreads);
+ }
}
}
else
{
- if (method == NFileHeader::NCompressionMethod::kStored && !options.PasswordIsDefined)
+ if (method == NFileHeader::NCompressionMethod::kStore && !options.PasswordIsDefined)
numThreads = 1;
+
+ if (oneMethodMain)
+ {
+
if (method == NFileHeader::NCompressionMethod::kBZip2)
{
bool fixedNumber;
- UInt32 numBZip2Threads = options2.MethodInfo.Get_BZip2_NumThreads(fixedNumber);
+ UInt32 numBZip2Threads = oneMethodMain->Get_BZip2_NumThreads(fixedNumber);
if (!fixedNumber)
{
- UInt64 averageSize = numBytesToCompress / numFilesToCompress;
- UInt32 blockSize = options2.MethodInfo.Get_BZip2_BlockSize();
- UInt64 averageNumberOfBlocks = averageSize / blockSize + 1;
+ const UInt64 averageSize = numBytesToCompress / numFilesToCompress;
+ const UInt32 blockSize = oneMethodMain->Get_BZip2_BlockSize();
+ const UInt64 averageNumberOfBlocks = averageSize / blockSize + 1;
numBZip2Threads = 32;
- if (averageNumberOfBlocks < numBZip2Threads)
+ if (numBZip2Threads > averageNumberOfBlocks)
numBZip2Threads = (UInt32)averageNumberOfBlocks;
- options2.MethodInfo.AddProp_NumThreads(numBZip2Threads);
+ oneMethodMain->AddProp_NumThreads(numBZip2Threads);
}
numThreads /= numBZip2Threads;
}
- if (method == NFileHeader::NCompressionMethod::kLZMA)
+
+ if (method == NFileHeader::NCompressionMethod::kXz)
{
bool fixedNumber;
+ UInt32 numLzma2Threads = oneMethodMain->Get_Lzma2_NumThreads(fixedNumber);
+ if (!fixedNumber)
+ {
+ const UInt64 averageSize = numBytesToCompress / numFilesToCompress;
+ const UInt64 blockSize = oneMethodMain->Get_Lzma2_BlockSize();
+ const UInt64 averageNumberOfBlocks = averageSize / blockSize + 1;
+ numLzma2Threads = 2;
+ if (numLzma2Threads > averageNumberOfBlocks)
+ numLzma2Threads = (UInt32)averageNumberOfBlocks;
+ oneMethodMain->AddProp_NumThreads(numLzma2Threads);
+ }
+ numThreads /= numLzma2Threads;
+ }
+
+ if (method == NFileHeader::NCompressionMethod::kLZMA)
+ {
// we suppose that default LZMA is 2 thread. So we don't change it
- UInt32 numLZMAThreads = options2.MethodInfo.Get_Lzma_NumThreads(fixedNumber);
+ UInt32 numLZMAThreads = oneMethodMain->Get_Lzma_NumThreads();
numThreads /= numLZMAThreads;
}
+ }
+
if (numThreads > numFilesToCompress)
numThreads = (UInt32)numFilesToCompress;
if (numThreads <= 1)
@@ -747,6 +830,7 @@ static HRESULT Update2(
threadInfo.ProgressSpec = new CMtCompressProgress();
threadInfo.Progress = threadInfo.ProgressSpec;
threadInfo.ProgressSpec->Init(&mtCompressProgressMixer, (int)i);
+ threadInfo.SeqMode = false; // fix it !
threadInfo.FileTime = 0; // fix it !
RINOK(threadInfo.CreateThread());
}
@@ -777,7 +861,9 @@ static HRESULT Update2(
if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK)
return E_NOTIMPL;
(CItem &)item = itemEx;
- if (item.IsDir())
+ if (item.IsDir() != ui.IsDir)
+ return E_NOTIMPL;
+ if (ui.IsDir)
continue;
}
@@ -849,7 +935,8 @@ static HRESULT Update2(
if (ui.NewData)
{
- bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir());
+ // bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir());
+ bool isDir = ui.IsDir;
if (isDir)
{
@@ -857,39 +944,51 @@ static HRESULT Update2(
}
else
{
- if (lastRealStreamItemIndex < (int)itemIndex)
- {
- lastRealStreamItemIndex = itemIndex;
- SetFileHeader(archive, options, ui, item);
- // file Size can be 64-bit !!!
- archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, options.IsRealAesMode());
- }
-
CMemBlocks2 &memRef = refs.Refs[itemIndex];
if (memRef.Defined)
{
- CMyComPtr<IOutStream> outStream;
- archive.CreateStreamForCompressing(&outStream);
- memRef.WriteToStream(memManager.GetBlockSize(), outStream);
- SetFileHeader(archive, options, ui, item);
+ if (lastRealStreamItemIndex < (int)itemIndex)
+ lastRealStreamItemIndex = itemIndex;
+
+ SetFileHeader(options, ui, item);
// the BUG was fixed in 9.26:
// SetItemInfoFromCompressingResult must be after SetFileHeader
// to write correct Size.
SetItemInfoFromCompressingResult(memRef.CompressingResult,
options.IsRealAesMode(), options.AesKeyMode, item);
- archive.WriteLocalHeader_And_SeekToNextFile(item);
+ archive.WriteLocalHeader(item);
// RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ CMyComPtr<ISequentialOutStream> outStream;
+ archive.CreateStreamForCopying(outStream);
+ memRef.WriteToStream(memManager.GetBlockSize(), outStream);
+ archive.MoveCurPos(item.PackSize);
memRef.FreeOpt(&memManager);
}
else
{
+ if (lastRealStreamItemIndex < (int)itemIndex)
+ {
+ lastRealStreamItemIndex = itemIndex;
+ SetFileHeader(options, ui, item);
+
+ CCompressingResult compressingResult;
+ RINOK(compressor.Set_Pre_CompressionResult(
+ false, // seqMode
+ ui.Size,
+ compressingResult));
+ SetItemInfoFromCompressingResult(compressingResult, options.IsRealAesMode(), options.AesKeyMode, item);
+
+ // file Size can be 64-bit !!!
+ archive.WriteLocalHeader(item);
+ }
+
{
CThreadInfo &thread = threads.Threads[threadIndices.Front()];
if (!thread.OutStreamSpec->WasUnlockEventSent())
{
CMyComPtr<IOutStream> outStream;
- archive.CreateStreamForCompressing(&outStream);
+ archive.CreateStreamForCompressing(outStream);
thread.OutStreamSpec->SetOutStream(outStream);
thread.OutStreamSpec->SetRealStreamMode();
}
@@ -918,10 +1017,10 @@ static HRESULT Update2(
{
RINOK(threadInfo.OutStreamSpec->WriteToRealStream());
threadInfo.OutStreamSpec->ReleaseOutStream();
- SetFileHeader(archive, options, ui, item);
+ SetFileHeader(options, ui, item);
SetItemInfoFromCompressingResult(threadInfo.CompressingResult,
options.IsRealAesMode(), options.AesKeyMode, item);
- archive.WriteLocalHeader_And_SeekToNextFile(item);
+ archive.WriteLocalHeader_Replace(item);
}
else
{
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.h b/CPP/7zip/Archive/Zip/ZipUpdate.h
index 15cbf69d..d5fda855 100644
--- a/CPP/7zip/Archive/Zip/ZipUpdate.h
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.h
@@ -14,6 +14,7 @@
namespace NArchive {
namespace NZip {
+/*
struct CUpdateRange
{
UInt64 Position;
@@ -22,6 +23,7 @@ struct CUpdateRange
// CUpdateRange() {};
CUpdateRange(UInt64 position, UInt64 size): Position(position), Size(size) {};
};
+*/
struct CUpdateItem
{
@@ -36,12 +38,23 @@ struct CUpdateItem
UInt32 Time;
UInt64 Size;
AString Name;
+ CByteBuffer Comment;
// bool Commented;
// CUpdateRange CommentRange;
FILETIME Ntfs_MTime;
FILETIME Ntfs_ATime;
FILETIME Ntfs_CTime;
+ void Clear()
+ {
+ IsDir = false;
+ NtfsTimeIsDefined = false;
+ IsUtf8 = false;
+ Size = 0;
+ Name.Empty();
+ Comment.Free();
+ }
+
CUpdateItem(): NtfsTimeIsDefined(false), IsUtf8(false), Size(0) {}
};
diff --git a/CPP/7zip/Asm.mak b/CPP/7zip/Asm.mak
index 4f77dddf..c4073e89 100644
--- a/CPP/7zip/Asm.mak
+++ b/CPP/7zip/Asm.mak
@@ -2,7 +2,7 @@
!IF "$(CPU)" == "ARM"
$(ASM_OBJS): ../../../../Asm/Arm/$(*B).asm
$(COMPL_ASM)
-!ELSEIF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS"
+!ELSEIF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM64"
$(ASM_OBJS): ../../../../Asm/x86/$(*B).asm
$(COMPL_ASM)
!ENDIF
diff --git a/CPP/7zip/Bundles/Alone/Alone.dsp b/CPP/7zip/Bundles/Alone/Alone.dsp
index b16ab914..f959e4a1 100644
--- a/CPP/7zip/Bundles/Alone/Alone.dsp
+++ b/CPP/7zip/Bundles/Alone/Alone.dsp
@@ -410,6 +410,10 @@ SOURCE=..\..\..\Common\Wildcard.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Common\XzCrc64Init.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Common\XzCrc64Reg.cpp
# End Source File
# End Group
@@ -514,6 +518,14 @@ SOURCE=..\..\..\Windows\PropVariantConv.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Windows\PropVariantUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantUtils.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Windows\Synchronization.cpp
# End Source File
# Begin Source File
@@ -903,14 +915,6 @@ SOURCE=..\..\Compress\ImplodeDecoder.cpp
SOURCE=..\..\Compress\ImplodeDecoder.h
# End Source File
-# Begin Source File
-
-SOURCE=..\..\Compress\ImplodeHuffmanDecoder.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\Compress\ImplodeHuffmanDecoder.h
-# End Source File
# End Group
# Begin Group "LZMA"
@@ -1232,6 +1236,22 @@ SOURCE=..\..\Compress\LzOutWindow.cpp
SOURCE=..\..\Compress\LzOutWindow.h
# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzEncoder.h
+# End Source File
# End Group
# Begin Group "Archive"
diff --git a/CPP/7zip/Bundles/Alone/makefile b/CPP/7zip/Bundles/Alone/makefile
index 91ecfce4..8e9d59a6 100644
--- a/CPP/7zip/Bundles/Alone/makefile
+++ b/CPP/7zip/Bundles/Alone/makefile
@@ -22,6 +22,7 @@ COMMON_OBJS = \
$O\UTFConvert.obj \
$O\MyVector.obj \
$O\Wildcard.obj \
+ $O\XzCrc64Init.obj \
$O\XzCrc64Reg.obj \
$O\Sha1Reg.obj \
$O\Sha256Reg.obj \
@@ -38,6 +39,7 @@ WIN_OBJS = \
$O\MemoryLock.obj \
$O\PropVariant.obj \
$O\PropVariantConv.obj \
+ $O\PropVariantUtils.obj \
$O\Synchronization.obj \
$O\System.obj \
$O\TimeUtils.obj \
@@ -151,7 +153,6 @@ COMPRESS_OBJS = \
$O\DeflateRegister.obj \
$O\DeltaFilter.obj \
$O\ImplodeDecoder.obj \
- $O\ImplodeHuffmanDecoder.obj \
$O\Lzma2Decoder.obj \
$O\Lzma2Encoder.obj \
$O\Lzma2Register.obj \
@@ -166,6 +167,8 @@ COMPRESS_OBJS = \
$O\PpmdZip.obj \
$O\QuantumDecoder.obj \
$O\ShrinkDecoder.obj \
+ $O\XzDecoder.obj \
+ $O\XzEncoder.obj \
$O\ZDecoder.obj \
CRYPTO_OBJS = \
diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsp b/CPP/7zip/Bundles/Alone7z/Alone.dsp
index d220b198..334b6635 100644
--- a/CPP/7zip/Bundles/Alone7z/Alone.dsp
+++ b/CPP/7zip/Bundles/Alone7z/Alone.dsp
@@ -406,6 +406,10 @@ SOURCE=..\..\..\Common\Wildcard.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Common\XzCrc64Init.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Common\XzCrc64Reg.cpp
# End Source File
# End Group
@@ -804,6 +808,22 @@ SOURCE=..\..\Compress\LzmaEncoder.h
SOURCE=..\..\Compress\LzmaRegister.cpp
# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzEncoder.h
+# End Source File
# End Group
# Begin Group "Archive"
diff --git a/CPP/7zip/Bundles/Alone7z/makefile b/CPP/7zip/Bundles/Alone7z/makefile
index 15c51f91..d8335818 100644
--- a/CPP/7zip/Bundles/Alone7z/makefile
+++ b/CPP/7zip/Bundles/Alone7z/makefile
@@ -22,6 +22,7 @@ COMMON_OBJS = \
$O\UTFConvert.obj \
$O\MyVector.obj \
$O\Wildcard.obj \
+ $O\XzCrc64Init.obj \
$O\XzCrc64Reg.obj \
WIN_OBJS = \
@@ -109,6 +110,8 @@ COMPRESS_OBJS = \
$O\LzmaDecoder.obj \
$O\LzmaEncoder.obj \
$O\LzmaRegister.obj \
+ $O\XzDecoder.obj \
+ $O\XzEncoder.obj \
CRYPTO_OBJS = \
$O\7zAes.obj \
diff --git a/CPP/7zip/Bundles/Fm/FM.dsp b/CPP/7zip/Bundles/Fm/FM.dsp
index eb1aa103..7ebf37ef 100644
--- a/CPP/7zip/Bundles/Fm/FM.dsp
+++ b/CPP/7zip/Bundles/Fm/FM.dsp
@@ -995,6 +995,24 @@ SOURCE=..\..\..\..\C\LzFindMt.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\Lzma2Enc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Lzma2Enc.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\LzmaDec.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -1013,6 +1031,15 @@ SOURCE=..\..\..\..\C\LzmaEnc.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\MtCoder.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\MtCoder.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\Sha256.c
!IF "$(CFG)" == "FM - Win32 Release"
@@ -1911,6 +1938,26 @@ SOURCE=..\..\Compress\CopyRegister.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\Lzma2Encoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzma2Encoder.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
diff --git a/CPP/7zip/Bundles/Format7zF/Arc.mak b/CPP/7zip/Bundles/Format7zF/Arc.mak
index 44bd023b..97f6596e 100644
--- a/CPP/7zip/Bundles/Format7zF/Arc.mak
+++ b/CPP/7zip/Bundles/Format7zF/Arc.mak
@@ -14,6 +14,7 @@ COMMON_OBJS = \
$O\StringToInt.obj \
$O\UTFConvert.obj \
$O\Wildcard.obj \
+ $O\XzCrc64Init.obj \
$O\XzCrc64Reg.obj \
WIN_OBJS = \
@@ -197,7 +198,6 @@ COMPRESS_OBJS = \
$O\DeflateRegister.obj \
$O\DeltaFilter.obj \
$O\ImplodeDecoder.obj \
- $O\ImplodeHuffmanDecoder.obj \
$O\LzhDecoder.obj \
$O\Lzma2Decoder.obj \
$O\Lzma2Encoder.obj \
@@ -220,10 +220,13 @@ COMPRESS_OBJS = \
$O\Rar5Decoder.obj \
$O\RarCodecsRegister.obj \
$O\ShrinkDecoder.obj \
+ $O\XpressDecoder.obj \
+ $O\XzDecoder.obj \
+ $O\XzEncoder.obj \
$O\ZlibDecoder.obj \
$O\ZlibEncoder.obj \
$O\ZDecoder.obj \
- $O\XPressDecoder.obj \
+
CRYPTO_OBJS = \
$O\7zAes.obj \
diff --git a/CPP/7zip/Bundles/Format7zF/Format7z.dsp b/CPP/7zip/Bundles/Format7zF/Format7z.dsp
index 69d4f3a0..f2a8fcc8 100644
--- a/CPP/7zip/Bundles/Format7zF/Format7z.dsp
+++ b/CPP/7zip/Bundles/Format7zF/Format7z.dsp
@@ -271,6 +271,10 @@ SOURCE=..\..\..\Common\MyBuffer.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Common\MyBuffer2.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Common\MyCom.h
# End Source File
# Begin Source File
@@ -383,6 +387,10 @@ SOURCE=..\..\..\Common\Wildcard.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Common\XzCrc64Init.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Common\XzCrc64Reg.cpp
# End Source File
# End Group
@@ -419,6 +427,16 @@ SOURCE=..\..\Compress\BitmEncoder.h
# Begin Source File
SOURCE=..\..\Compress\Rar1Decoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -427,6 +445,16 @@ SOURCE=..\..\Compress\Rar1Decoder.h
# Begin Source File
SOURCE=..\..\Compress\Rar2Decoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -453,6 +481,16 @@ SOURCE=..\..\Compress\Rar3Decoder.h
# Begin Source File
SOURCE=..\..\Compress\Rar3Vm.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -479,6 +517,16 @@ SOURCE=..\..\Compress\Rar5Decoder.h
# Begin Source File
SOURCE=..\..\Compress\RarCodecsRegister.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# End Group
# Begin Group "BZip2 Compress"
@@ -491,6 +539,16 @@ SOURCE=..\..\Compress\BZip2Const.h
# Begin Source File
SOURCE=..\..\Compress\BZip2Crc.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -499,6 +557,16 @@ SOURCE=..\..\Compress\BZip2Crc.h
# Begin Source File
SOURCE=..\..\Compress\BZip2Decoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -507,6 +575,16 @@ SOURCE=..\..\Compress\BZip2Decoder.h
# Begin Source File
SOURCE=..\..\Compress\BZip2Encoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -515,6 +593,16 @@ SOURCE=..\..\Compress\BZip2Encoder.h
# Begin Source File
SOURCE=..\..\Compress\BZip2Register.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -527,6 +615,16 @@ SOURCE=..\..\Compress\Mtf8.h
# Begin Source File
SOURCE=..\..\Compress\Deflate64Register.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -535,6 +633,16 @@ SOURCE=..\..\Compress\DeflateConst.h
# Begin Source File
SOURCE=..\..\Compress\DeflateDecoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -543,6 +651,16 @@ SOURCE=..\..\Compress\DeflateDecoder.h
# Begin Source File
SOURCE=..\..\Compress\DeflateEncoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -551,26 +669,48 @@ SOURCE=..\..\Compress\DeflateEncoder.h
# Begin Source File
SOURCE=..\..\Compress\DeflateRegister.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
SOURCE=..\..\Compress\ImplodeDecoder.cpp
-# End Source File
-# Begin Source File
-SOURCE=..\..\Compress\ImplodeDecoder.h
-# End Source File
-# Begin Source File
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
-SOURCE=..\..\Compress\ImplodeHuffmanDecoder.cpp
# End Source File
# Begin Source File
-SOURCE=..\..\Compress\ImplodeHuffmanDecoder.h
+SOURCE=..\..\Compress\ImplodeDecoder.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\PpmdZip.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -579,6 +719,16 @@ SOURCE=..\..\Compress\PpmdZip.h
# Begin Source File
SOURCE=..\..\Compress\ShrinkDecoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -587,6 +737,16 @@ SOURCE=..\..\Compress\ShrinkDecoder.h
# Begin Source File
SOURCE=..\..\Compress\ZlibDecoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -595,6 +755,16 @@ SOURCE=..\..\Compress\ZlibDecoder.h
# Begin Source File
SOURCE=..\..\Compress\ZlibEncoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
@@ -843,6 +1013,22 @@ SOURCE=..\..\Compress\XpressDecoder.h
# End Source File
# Begin Source File
+SOURCE=..\..\Compress\XzDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzEncoder.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Compress\ZDecoder.cpp
# End Source File
# Begin Source File
@@ -1300,6 +1486,10 @@ SOURCE=..\..\..\..\C\XzIn.c
# End Group
# Begin Source File
+SOURCE=..\..\..\..\C\7zBuf.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\7zBuf2.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
diff --git a/CPP/7zip/Bundles/Format7zF/resource.rc b/CPP/7zip/Bundles/Format7zF/resource.rc
index 1caf7301..705814f5 100644
--- a/CPP/7zip/Bundles/Format7zF/resource.rc
+++ b/CPP/7zip/Bundles/Format7zF/resource.rc
@@ -1,6 +1,6 @@
#include "../../MyVersionInfo.rc"
-MY_VERSION_INFO_DLL("7z Plugin", "7z")
+MY_VERSION_INFO_DLL("7z Plugin" , "7z")
0 ICON "../../Archive/Icons/7z.ico"
diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp b/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
index 178753e5..62d3a84c 100644
--- a/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
+++ b/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
@@ -4,6 +4,8 @@
#include <stdio.h>
+#include "../../../../C/CpuArch.h"
+
#if (defined(_WIN32) || defined(OS2) || defined(MSDOS)) && !defined(UNDER_CE)
#include <fcntl.h>
#include <io.h>
@@ -39,14 +41,16 @@
#include "../../UI/Console/BenchCon.h"
#include "../../UI/Console/ConsoleClose.h"
+bool g_LargePagesMode = false;
+
using namespace NCommandLineParser;
static const unsigned kDictSizeLog = 24;
-static const char *kCopyrightString = "\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n\n";
+#define kCopyrightString "\nLZMA " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n"
-static const char *kHelpString =
- "Usage: LZMA <command> [inputFile] [outputFile] [<switches>...]\n"
+static const char * const kHelpString =
+ "Usage: lzma <command> [inputFile] [outputFile] [<switches>...]\n"
"\n"
"<command>\n"
" e : Encode file\n"
@@ -67,9 +71,9 @@ static const char *kHelpString =
" -so : write data to stdout\n";
-static const char *kCantAllocate = "Can not allocate memory";
-static const char *kReadError = "Read error";
-static const char *kWriteError = "Write error";
+static const char * const kCantAllocate = "Can not allocate memory";
+static const char * const kReadError = "Read error";
+static const char * const kWriteError = "Write error";
namespace NKey {
@@ -117,6 +121,21 @@ static const CSwitchForm kSwitchForms[] =
};
+static void Convert_UString_to_AString(const UString &s, AString &temp)
+{
+ int codePage = CP_OEMCP;
+ /*
+ int g_CodePage = -1;
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8(s, temp);
+ else
+ */
+ UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
+}
+
static void PrintErr(const char *s)
{
fputs(s, stderr);
@@ -135,10 +154,12 @@ static void PrintError(const char *s)
PrintErr_LF(s);
}
-static void PrintError2(const char *s1, const wchar_t *s2)
+static void PrintError2(const char *s1, const UString &s2)
{
PrintError(s1);
- PrintErr_LF(GetOemString(s2));
+ AString a;
+ Convert_UString_to_AString(s2, a);
+ PrintErr_LF(a);
}
static void PrintError_int(const char *s, int code)
@@ -208,7 +229,7 @@ public:
#define BACK_STR \
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
-static const char *kBackSpaces =
+static const char * const kBackSpaces =
BACK_STR
" "
BACK_STR;
@@ -298,7 +319,7 @@ static int Error_HRESULT(const char *s, HRESULT res)
static void AddProp(CObjectVector<CProperty> &props2, const char *name, const wchar_t *val)
{
CProperty &prop = props2.AddNew();
- prop.Name.SetFromAscii(name);
+ prop.Name = name;
prop.Value = val;
}
@@ -322,10 +343,10 @@ static int main2(int numArgs, const char *args[])
for (int i = 1; i < numArgs; i++)
commandStrings.Add(MultiByteToUnicodeString(args[i]));
- CParser parser(ARRAY_SIZE(kSwitchForms));
+ CParser parser;
try
{
- if (!parser.ParseStrings(kSwitchForms, commandStrings))
+ if (!parser.ParseStrings(kSwitchForms, ARRAY_SIZE(kSwitchForms), commandStrings))
{
PrintError2(parser.ErrorMessage, parser.ErrorLine);
return 1;
@@ -376,7 +397,7 @@ static int main2(int numArgs, const char *args[])
AddProp(props2, "x", s);
}
- UString mf = L"BT4";
+ UString mf ("BT4");
if (parser[NKey::kMatchFinder].ThereIs)
mf = parser[NKey::kMatchFinder].PostStrings[0];
diff --git a/CPP/7zip/Bundles/SFXCon/SfxCon.cpp b/CPP/7zip/Bundles/SFXCon/SfxCon.cpp
index d828922f..3209a01c 100644
--- a/CPP/7zip/Bundles/SFXCon/SfxCon.cpp
+++ b/CPP/7zip/Bundles/SFXCon/SfxCon.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../../../../C/CpuArch.h"
+
#include "../../../Common/MyWindows.h"
#include "../../../Common/MyInitGuid.h"
@@ -37,8 +39,8 @@ HINSTANCE g_hInstance = 0;
int g_CodePage = -1;
extern CStdOutStream *g_StdStream;
-static const char *kCopyrightString =
-"\n7-Zip SFX " MY_VERSION_COPYRIGHT_DATE "\n";
+static const char * const kCopyrightString =
+"\n7-Zip SFX " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n";
static const int kNumSwitches = 6;
@@ -65,7 +67,6 @@ enum EEnum
}
/*
static const char kRecursedIDChar = 'R';
-static const wchar_t *kRecursedPostCharSet = L"0-";
namespace NRecursedPostCharIndex {
enum EEnum
@@ -101,10 +102,10 @@ static const NRecursedType::EEnum kCommandRecursedDefault[kNumCommandForms] =
// static const bool kTestExtractRecursedDefault = true;
// static const bool kAddRecursedDefault = false;
-static const wchar_t *kUniversalWildcard = L"*";
+static const char * const kUniversalWildcard = "*";
static const int kCommandIndex = 0;
-static const char *kHelpString =
+static const char * const kHelpString =
"\nUsage: 7zSFX [<command>] [<switches>...] [<file_name>...]\n"
"\n"
"<Commands>\n"
@@ -121,16 +122,16 @@ static const char *kHelpString =
// ---------------------------
// exception messages
-static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError
-// static const char *kIncorrectListFile = "Incorrect wildcard in listfile";
-static const char *kIncorrectWildcardInCommandLine = "Incorrect wildcard in command line";
+static const char * const kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError
+// static const char * const kIncorrectListFile = "Incorrect wildcard in listfile";
+static const char * const kIncorrectWildcardInCommandLine = "Incorrect wildcard in command line";
// static const CSysString kFileIsNotArchiveMessageBefore = "File \"";
// static const CSysString kFileIsNotArchiveMessageAfter = "\" is not archive";
-// static const char *kProcessArchiveMessage = " archive: ";
+// static const char * const kProcessArchiveMessage = " archive: ";
-static const char *kCantFindSFX = " cannot find sfx";
+static const char * const kCantFindSFX = " cannot find sfx";
namespace NCommandType
{
@@ -280,13 +281,16 @@ int Main2(
#endif
- commandStrings.Delete(0);
+ #ifndef UNDER_CE
+ if (commandStrings.Size() > 0)
+ commandStrings.Delete(0);
+ #endif
- NCommandLineParser::CParser parser(kNumSwitches);
+ NCommandLineParser::CParser parser;
try
{
- if (!parser.ParseStrings(kSwitchForms, commandStrings))
+ if (!parser.ParseStrings(kSwitchForms, kNumSwitches, commandStrings))
{
g_StdOut << "Command line error:" << endl
<< parser.ErrorMessage << endl
@@ -331,7 +335,7 @@ int Main2(
{
if (nonSwitchStrings.Size() == curCommandIndex)
- AddCommandLineWildcardToCensor(wildcardCensor, kUniversalWildcard, true, recursedType);
+ AddCommandLineWildcardToCensor(wildcardCensor, (UString)kUniversalWildcard, true, recursedType);
for (; curCommandIndex < nonSwitchStrings.Size(); curCommandIndex++)
{
const UString &s = nonSwitchStrings[curCommandIndex];
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp
index 79330630..00e3ba53 100644
--- a/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp
@@ -15,9 +15,9 @@ using namespace NWindows;
using namespace NFile;
using namespace NDir;
-static LPCWSTR kCantDeleteFile = L"Can not delete output file";
-static LPCWSTR kCantOpenFile = L"Can not open output file";
-static LPCWSTR kUnsupportedMethod = L"Unsupported Method";
+static LPCSTR const kCantDeleteFile = "Can not delete output file";
+static LPCSTR const kCantOpenFile = "Can not open output file";
+static LPCSTR const kUnsupportedMethod = "Unsupported Method";
void CExtractCallbackImp::Init(IInArchive *archiveHandler,
const FString &directoryPath,
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
index b1592993..e510e5c8 100644
--- a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
@@ -18,8 +18,8 @@ using namespace NWindows;
using namespace NFile;
using namespace NDir;
-static LPCWSTR kCantFindArchive = L"Can not find archive file";
-static LPCWSTR kCantOpenArchive = L"Can not open the file as archive";
+static LPCSTR const kCantFindArchive = "Can not find archive file";
+static LPCSTR const kCantOpenArchive = "Can not open the file as archive";
struct CThreadExtracting
{
@@ -73,7 +73,7 @@ struct CThreadExtracting
return;
}
- ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, L"Default", fi.MTime, 0);
+ ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, (UString)"Default", fi.MTime, 0);
Result = ArchiveLink.GetArchive()->Extract(0, (UInt32)(Int32)-1 , BoolToInt(false), ExtractCallback);
}
diff --git a/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp b/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp
index aef2e196..0c302332 100644
--- a/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp
@@ -33,7 +33,7 @@ using namespace NDir;
HINSTANCE g_hInstance;
-static CFSTR kTempDirPrefix = FTEXT("7zS");
+static CFSTR const kTempDirPrefix = FTEXT("7zS");
#define _SHELL_EXECUTE
@@ -169,7 +169,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
return 1;
}
- UString dirPrefix = L"." WSTRING_PATH_SEPARATOR;
+ UString dirPrefix ("." STRING_PATH_SEPARATOR);
UString appLaunched;
bool showProgress = true;
if (!config.IsEmpty())
@@ -181,12 +181,12 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
ShowErrorMessage(L"Config failed");
return 1;
}
- UString friendlyName = GetTextConfigValue(pairs, L"Title");
- UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt");
- UString progress = GetTextConfigValue(pairs, L"Progress");
+ UString friendlyName = GetTextConfigValue(pairs, "Title");
+ UString installPrompt = GetTextConfigValue(pairs, "BeginPrompt");
+ UString progress = GetTextConfigValue(pairs, "Progress");
if (progress.IsEqualTo_Ascii_NoCase("no"))
showProgress = false;
- int index = FindTextConfigItem(pairs, L"Directory");
+ int index = FindTextConfigItem(pairs, "Directory");
if (index >= 0)
dirPrefix = pairs[index].String;
if (!installPrompt.IsEmpty() && !assumeYes)
@@ -195,11 +195,11 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
MB_ICONQUESTION) != IDYES)
return 0;
}
- appLaunched = GetTextConfigValue(pairs, L"RunProgram");
+ appLaunched = GetTextConfigValue(pairs, "RunProgram");
#ifdef _SHELL_EXECUTE
- executeFile = GetTextConfigValue(pairs, L"ExecuteFile");
- executeParameters = GetTextConfigValue(pairs, L"ExecuteParameters");
+ executeFile = GetTextConfigValue(pairs, "ExecuteFile");
+ executeParameters = GetTextConfigValue(pairs, "ExecuteParameters");
#endif
}
@@ -260,7 +260,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
#ifdef _SHELL_EXECUTE
if (!executeFile.IsEmpty())
{
- CSysString filePath = GetSystemString(executeFile);
+ CSysString filePath (GetSystemString(executeFile));
SHELLEXECUTEINFO execInfo;
execInfo.cbSize = sizeof(execInfo);
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS
@@ -278,7 +278,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
executeParameters += switches;
}
- CSysString parametersSys = GetSystemString(executeParameters);
+ CSysString parametersSys (GetSystemString(executeParameters));
if (parametersSys.IsEmpty())
execInfo.lpParameters = NULL;
else
@@ -337,7 +337,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
PROCESS_INFORMATION processInformation;
- CSysString appLaunchedSys = GetSystemString(dirPrefix + appLaunched);
+ CSysString appLaunchedSys (GetSystemString(dirPrefix + appLaunched));
BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys,
NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */,
diff --git a/CPP/7zip/Bundles/SFXWin/SfxWin.cpp b/CPP/7zip/Bundles/SFXWin/SfxWin.cpp
index db7acfef..3c77356e 100644
--- a/CPP/7zip/Bundles/SFXWin/SfxWin.cpp
+++ b/CPP/7zip/Bundles/SFXWin/SfxWin.cpp
@@ -65,7 +65,7 @@ static DWORD GetDllVersion(LPCTSTR dllName)
bool g_LVN_ITEMACTIVATE_Support = true;
-static const wchar_t *kUnknownExceptionMessage = L"ERROR: Unknown Error!";
+static const wchar_t * const kUnknownExceptionMessage = L"ERROR: Unknown Error!";
void ErrorMessageForHRESULT(HRESULT res)
{
diff --git a/CPP/7zip/Common/CWrappers.cpp b/CPP/7zip/Common/CWrappers.cpp
index a77b67e8..d85aa238 100644
--- a/CPP/7zip/Common/CWrappers.cpp
+++ b/CPP/7zip/Common/CWrappers.cpp
@@ -8,43 +8,61 @@
#include "StreamUtils.h"
+SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) throw()
+{
+ switch (res)
+ {
+ case S_OK: return SZ_OK;
+ case E_OUTOFMEMORY: return SZ_ERROR_MEM;
+ case E_INVALIDARG: return SZ_ERROR_PARAM;
+ case E_ABORT: return SZ_ERROR_PROGRESS;
+ case S_FALSE: return SZ_ERROR_DATA;
+ case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED;
+ }
+ return defaultRes;
+}
+
+
+HRESULT SResToHRESULT(SRes res) throw()
+{
+ switch (res)
+ {
+ case SZ_OK: return S_OK;
+ case SZ_ERROR_MEM: return E_OUTOFMEMORY;
+ case SZ_ERROR_PARAM: return E_INVALIDARG;
+ case SZ_ERROR_PROGRESS: return E_ABORT;
+ case SZ_ERROR_DATA: return S_FALSE;
+ case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
+ // case SZ_ERROR_READ: return E_NOTIMPL;
+ }
+ return E_FAIL;
+}
+
+
#define PROGRESS_UNKNOWN_VALUE ((UInt64)(Int64)-1)
#define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x)
-static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize) throw()
+
+static SRes CompressProgress(const ICompressProgress *pp, UInt64 inSize, UInt64 outSize) throw()
{
- CCompressProgressWrap *p = (CCompressProgressWrap *)pp;
+ CCompressProgressWrap *p = CONTAINER_FROM_VTBL(pp, CCompressProgressWrap, vt);
p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize));
- return (SRes)p->Res;
+ return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS);
}
-CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress) throw()
+void CCompressProgressWrap::Init(ICompressProgressInfo *progress) throw()
{
- p.Progress = CompressProgress;
+ vt.Progress = CompressProgress;
Progress = progress;
Res = SZ_OK;
}
static const UInt32 kStreamStepSize = (UInt32)1 << 31;
-SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes)
+static SRes MyRead(const ISeqInStream *pp, void *data, size_t *size) throw()
{
- switch (res)
- {
- case S_OK: return SZ_OK;
- case E_OUTOFMEMORY: return SZ_ERROR_MEM;
- case E_INVALIDARG: return SZ_ERROR_PARAM;
- case E_ABORT: return SZ_ERROR_PROGRESS;
- case S_FALSE: return SZ_ERROR_DATA;
- case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED;
- }
- return defaultRes;
-}
-
-static SRes MyRead(void *object, void *data, size_t *size) throw()
-{
- CSeqInStreamWrap *p = (CSeqInStreamWrap *)object;
+ CSeqInStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeqInStreamWrap, vt);
UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
p->Res = (p->Stream->Read(data, curSize, &curSize));
*size = curSize;
@@ -54,9 +72,9 @@ static SRes MyRead(void *object, void *data, size_t *size) throw()
return HRESULT_To_SRes(p->Res, SZ_ERROR_READ);
}
-static size_t MyWrite(void *object, const void *data, size_t size) throw()
+static size_t MyWrite(const ISeqOutStream *pp, const void *data, size_t size) throw()
{
- CSeqOutStreamWrap *p = (CSeqOutStreamWrap *)object;
+ CSeqOutStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeqOutStreamWrap, vt);
if (p->Stream)
{
p->Res = WriteStream(p->Stream, data, size);
@@ -69,47 +87,36 @@ static size_t MyWrite(void *object, const void *data, size_t size) throw()
return size;
}
-CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream) throw()
+
+void CSeqInStreamWrap::Init(ISequentialInStream *stream) throw()
{
- p.Read = MyRead;
+ vt.Read = MyRead;
Stream = stream;
Processed = 0;
+ Res = S_OK;
}
-CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw()
+void CSeqOutStreamWrap::Init(ISequentialOutStream *stream) throw()
{
- p.Write = MyWrite;
+ vt.Write = MyWrite;
Stream = stream;
Res = SZ_OK;
Processed = 0;
}
-HRESULT SResToHRESULT(SRes res) throw()
-{
- switch (res)
- {
- case SZ_OK: return S_OK;
- case SZ_ERROR_MEM: return E_OUTOFMEMORY;
- case SZ_ERROR_PARAM: return E_INVALIDARG;
- case SZ_ERROR_PROGRESS: return E_ABORT;
- case SZ_ERROR_DATA: return S_FALSE;
- case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
- }
- return E_FAIL;
-}
-static SRes InStreamWrap_Read(void *pp, void *data, size_t *size) throw()
+static SRes InStreamWrap_Read(const ISeekInStream *pp, void *data, size_t *size) throw()
{
- CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;
+ CSeekInStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeekInStreamWrap, vt);
UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
p->Res = p->Stream->Read(data, curSize, &curSize);
*size = curSize;
return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
}
-static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw()
+static SRes InStreamWrap_Seek(const ISeekInStream *pp, Int64 *offset, ESzSeek origin) throw()
{
- CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;
+ CSeekInStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeekInStreamWrap, vt);
UInt32 moveMethod;
switch (origin)
{
@@ -124,11 +131,11 @@ static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw()
return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
}
-CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw()
+void CSeekInStreamWrap::Init(IInStream *stream) throw()
{
Stream = stream;
- p.Read = InStreamWrap_Read;
- p.Seek = InStreamWrap_Seek;
+ vt.Read = InStreamWrap_Read;
+ vt.Seek = InStreamWrap_Seek;
Res = S_OK;
}
@@ -168,9 +175,9 @@ Byte CByteInBufWrap::ReadByteFromNewBlock() throw()
return 0;
}
-static Byte Wrap_ReadByte(void *pp) throw()
+static Byte Wrap_ReadByte(const IByteIn *pp) throw()
{
- CByteInBufWrap *p = (CByteInBufWrap *)pp;
+ CByteInBufWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CByteInBufWrap, vt);
if (p->Cur != p->Lim)
return *p->Cur++;
return p->ReadByteFromNewBlock();
@@ -178,7 +185,7 @@ static Byte Wrap_ReadByte(void *pp) throw()
CByteInBufWrap::CByteInBufWrap(): Buf(0)
{
- p.Read = Wrap_ReadByte;
+ vt.Read = Wrap_ReadByte;
}
@@ -214,9 +221,9 @@ HRESULT CByteOutBufWrap::Flush() throw()
return Res;
}
-static void Wrap_WriteByte(void *pp, Byte b) throw()
+static void Wrap_WriteByte(const IByteOut *pp, Byte b) throw()
{
- CByteOutBufWrap *p = (CByteOutBufWrap *)pp;
+ CByteOutBufWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CByteOutBufWrap, vt);
Byte *dest = p->Cur;
*dest = b;
p->Cur = ++dest;
@@ -226,5 +233,5 @@ static void Wrap_WriteByte(void *pp, Byte b) throw()
CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0)
{
- p.Write = Wrap_WriteByte;
+ vt.Write = Wrap_WriteByte;
}
diff --git a/CPP/7zip/Common/CWrappers.h b/CPP/7zip/Common/CWrappers.h
index acadc170..e5c890d8 100644
--- a/CPP/7zip/Common/CWrappers.h
+++ b/CPP/7zip/Common/CWrappers.h
@@ -6,49 +6,54 @@
#include "../ICoder.h"
#include "../../Common/MyCom.h"
+SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) throw();
+HRESULT SResToHRESULT(SRes res) throw();
+
struct CCompressProgressWrap
{
- ICompressProgress p;
+ ICompressProgress vt;
ICompressProgressInfo *Progress;
HRESULT Res;
- CCompressProgressWrap(ICompressProgressInfo *progress) throw();
+ void Init(ICompressProgressInfo *progress) throw();
};
+
struct CSeqInStreamWrap
{
- ISeqInStream p;
+ ISeqInStream vt;
ISequentialInStream *Stream;
HRESULT Res;
UInt64 Processed;
- CSeqInStreamWrap(ISequentialInStream *stream) throw();
+ void Init(ISequentialInStream *stream) throw();
};
+
struct CSeekInStreamWrap
{
- ISeekInStream p;
+ ISeekInStream vt;
IInStream *Stream;
HRESULT Res;
- CSeekInStreamWrap(IInStream *stream) throw();
+ void Init(IInStream *stream) throw();
};
+
struct CSeqOutStreamWrap
{
- ISeqOutStream p;
+ ISeqOutStream vt;
ISequentialOutStream *Stream;
HRESULT Res;
UInt64 Processed;
- CSeqOutStreamWrap(ISequentialOutStream *stream) throw();
+ void Init(ISequentialOutStream *stream) throw();
};
-HRESULT SResToHRESULT(SRes res) throw();
struct CByteInBufWrap
{
- IByteIn p;
+ IByteIn vt;
const Byte *Cur;
const Byte *Lim;
Byte *Buf;
@@ -79,9 +84,10 @@ struct CByteInBufWrap
}
};
+
struct CByteOutBufWrap
{
- IByteOut p;
+ IByteOut vt;
Byte *Cur;
const Byte *Lim;
Byte *Buf;
diff --git a/CPP/7zip/Common/FilePathAutoRename.cpp b/CPP/7zip/Common/FilePathAutoRename.cpp
index d186e599..0904e696 100644
--- a/CPP/7zip/Common/FilePathAutoRename.cpp
+++ b/CPP/7zip/Common/FilePathAutoRename.cpp
@@ -2,9 +2,6 @@
#include "StdAfx.h"
-#include "../../Common/Defs.h"
-#include "../../Common/IntToString.h"
-
#include "../../Windows/FileFind.h"
#include "FilePathAutoRename.h"
@@ -14,10 +11,8 @@ using namespace NWindows;
static bool MakeAutoName(const FString &name,
const FString &extension, UInt32 value, FString &path)
{
- char temp[16];
- ConvertUInt32ToString(value, temp);
path = name;
- path.AddAscii(temp);
+ path.Add_UInt32(value);
path += extension;
return NFile::NFind::DoesFileOrDirExist(path);
}
@@ -34,7 +29,7 @@ bool AutoRenamePath(FString &path)
name.DeleteFrom(dotPos);
extension = path.Ptr(dotPos);
}
- name += FTEXT('_');
+ name += '_';
FString temp;
diff --git a/CPP/7zip/Common/FilterCoder.h b/CPP/7zip/Common/FilterCoder.h
index 224ff2ca..85963f59 100644
--- a/CPP/7zip/Common/FilterCoder.h
+++ b/CPP/7zip/Common/FilterCoder.h
@@ -153,6 +153,15 @@ public:
~C_OutStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); }
};
+ class C_Filter_Releaser
+ {
+ public:
+ CFilterCoder *FilterCoder;
+ C_Filter_Releaser(): FilterCoder(NULL) {}
+ ~C_Filter_Releaser() { if (FilterCoder) FilterCoder->Filter.Release(); }
+ };
+
+
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
diff --git a/CPP/7zip/Common/InBuffer.h b/CPP/7zip/Common/InBuffer.h
index 4b8662bb..4b9c2c32 100644
--- a/CPP/7zip/Common/InBuffer.h
+++ b/CPP/7zip/Common/InBuffer.h
@@ -59,7 +59,8 @@ public:
}
void Init() throw();
-
+
+ MY_FORCE_INLINE
bool ReadByte(Byte &b)
{
if (_buf >= _bufLim)
@@ -68,6 +69,7 @@ public:
return true;
}
+ MY_FORCE_INLINE
Byte ReadByte()
{
if (_buf >= _bufLim)
diff --git a/CPP/7zip/Common/InOutTempBuffer.cpp b/CPP/7zip/Common/InOutTempBuffer.cpp
index 85d6a1aa..7523f3a3 100644
--- a/CPP/7zip/Common/InOutTempBuffer.cpp
+++ b/CPP/7zip/Common/InOutTempBuffer.cpp
@@ -15,7 +15,7 @@ using namespace NDir;
static const size_t kTempBufSize = (1 << 20);
-static CFSTR kTempFilePrefixString = FTEXT("7zt");
+#define kTempFilePrefixString FTEXT("7zt")
CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { }
diff --git a/CPP/7zip/Common/MethodProps.cpp b/CPP/7zip/Common/MethodProps.cpp
index 09f7b29c..ef6f2e3f 100644
--- a/CPP/7zip/Common/MethodProps.cpp
+++ b/CPP/7zip/Common/MethodProps.cpp
@@ -8,9 +8,9 @@
using namespace NWindows;
-bool StringToBool(const UString &s, bool &res)
+bool StringToBool(const wchar_t *s, bool &res)
{
- if (s.IsEmpty() || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON"))
+ if (s[0] == 0 || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON"))
{
res = true;
return true;
@@ -95,7 +95,7 @@ static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp)
{
const wchar_t *end;
UInt32 number = ConvertStringToUInt32(s, &end);
- unsigned numDigits = (unsigned)(end - s);
+ unsigned numDigits = (unsigned)(end - s.Ptr());
if (numDigits == 0 || s.Len() > numDigits + 1)
return E_INVALIDARG;
@@ -144,17 +144,29 @@ static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVaria
return S_OK;
}
if (prop.vt == VT_BSTR)
- return StringToDictSize(prop.bstrVal, destProp);
+ {
+ UString s;
+ s = prop.bstrVal;
+ return StringToDictSize(s, destProp);
+ }
return E_INVALIDARG;
}
-void CProps::AddProp32(PROPID propid, UInt32 level)
+void CProps::AddProp32(PROPID propid, UInt32 val)
{
CProp &prop = Props.AddNew();
prop.IsOptional = true;
prop.Id = propid;
- prop.Value = (UInt32)level;
+ prop.Value = (UInt32)val;
+}
+
+void CProps::AddPropBool(PROPID propid, bool val)
+{
+ CProp &prop = Props.AddNew();
+ prop.IsOptional = true;
+ prop.Id = propid;
+ prop.Value = val;
}
class CCoderProps
@@ -454,5 +466,7 @@ HRESULT COneMethodInfo::ParseMethodFromPROPVARIANT(const UString &realName, cons
// -m{N}=method
if (value.vt != VT_BSTR)
return E_INVALIDARG;
- return ParseMethodFromString(value.bstrVal);
+ UString s;
+ s = value.bstrVal;
+ return ParseMethodFromString(s);
}
diff --git a/CPP/7zip/Common/MethodProps.h b/CPP/7zip/Common/MethodProps.h
index 765e425d..b634a04e 100644
--- a/CPP/7zip/Common/MethodProps.h
+++ b/CPP/7zip/Common/MethodProps.h
@@ -5,11 +5,13 @@
#include "../../Common/MyString.h"
+#include "../../Windows/Defs.h"
+
#include "../../Windows/PropVariant.h"
#include "../ICoder.h"
-bool StringToBool(const UString &s, bool &res);
+bool StringToBool(const wchar_t *s, bool &res);
HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest);
unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number);
HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
@@ -38,7 +40,9 @@ struct CProps
return false;
}
- void AddProp32(PROPID propid, UInt32 level);
+ void AddProp32(PROPID propid, UInt32 val);
+
+ void AddPropBool(PROPID propid, bool val);
void AddProp_Ascii(PROPID propid, const char *s)
{
@@ -99,6 +103,18 @@ public:
return level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26));
}
+ bool Get_Lzma_Eos() const
+ {
+ int i = FindProp(NCoderPropID::kEndMarker);
+ if (i >= 0)
+ {
+ const NWindows::NCOM::CPropVariant &val = Props[i].Value;
+ if (val.vt == VT_BOOL)
+ return VARIANT_BOOLToBool(val.boolVal);
+ }
+ return false;
+ }
+
bool Are_Lzma_Model_Props_Defined() const
{
if (FindProp(NCoderPropID::kPosStateBits) >= 0) return true;
@@ -107,18 +123,52 @@ public:
return false;
}
- UInt32 Get_Lzma_NumThreads(bool &fixedNumber) const
+ UInt32 Get_Lzma_NumThreads() const
+ {
+ if (Get_Lzma_Algo() == 0)
+ return 1;
+ int numThreads = Get_NumThreads();
+ if (numThreads >= 0)
+ return numThreads < 2 ? 1 : 2;
+ return 2;
+ }
+
+ UInt32 Get_Lzma2_NumThreads(bool &fixedNumber) const
{
fixedNumber = false;
int numThreads = Get_NumThreads();
if (numThreads >= 0)
{
fixedNumber = true;
- return numThreads < 2 ? 1 : 2;
+ if (numThreads < 1) return 1;
+ const unsigned kNumLzma2ThreadsMax = 32;
+ if (numThreads > kNumLzma2ThreadsMax) return kNumLzma2ThreadsMax;
+ return numThreads;
}
- return Get_Lzma_Algo() == 0 ? 1 : 2;
+ return 1;
}
+ UInt64 Get_Lzma2_BlockSize() const
+ {
+ int i = FindProp(NCoderPropID::kBlockSize);
+ if (i >= 0)
+ {
+ const NWindows::NCOM::CPropVariant &val = Props[i].Value;
+ if (val.vt == VT_UI4) return val.ulVal;
+ if (val.vt == VT_UI8) return val.uhVal.QuadPart;
+ }
+
+ UInt32 dictSize = Get_Lzma_DicSize();
+ UInt64 blockSize = (UInt64)dictSize << 2;
+ const UInt32 kMinSize = (UInt32)1 << 20;
+ const UInt32 kMaxSize = (UInt32)1 << 28;
+ if (blockSize < kMinSize) blockSize = kMinSize;
+ if (blockSize > kMaxSize) blockSize = kMaxSize;
+ if (blockSize < dictSize) blockSize = dictSize;
+ return blockSize;
+ }
+
+
UInt32 Get_BZip2_NumThreads(bool &fixedNumber) const
{
fixedNumber = false;
@@ -127,7 +177,8 @@ public:
{
fixedNumber = true;
if (numThreads < 1) return 1;
- if (numThreads > 64) return 64;
+ const unsigned kNumBZip2ThreadsMax = 64;
+ if (numThreads > kNumBZip2ThreadsMax) return kNumBZip2ThreadsMax;
return numThreads;
}
return 1;
@@ -170,6 +221,12 @@ public:
AddProp32(NCoderPropID::kNumThreads, numThreads);
}
+ void AddProp_EndMarker_if_NotFound(bool eos)
+ {
+ if (FindProp(NCoderPropID::kEndMarker) < 0)
+ AddPropBool(NCoderPropID::kEndMarker, eos);
+ }
+
HRESULT ParseParamsFromString(const UString &srcString);
HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
};
diff --git a/CPP/7zip/Common/OutBuffer.h b/CPP/7zip/Common/OutBuffer.h
index 3bdfb87c..d7ca9f6a 100644
--- a/CPP/7zip/Common/OutBuffer.h
+++ b/CPP/7zip/Common/OutBuffer.h
@@ -47,8 +47,11 @@ public:
void WriteByte(Byte b)
{
- _buf[_pos++] = b;
- if (_pos == _limitPos)
+ UInt32 pos = _pos;
+ _buf[pos] = b;
+ pos++;
+ _pos = pos;
+ if (pos == _limitPos)
FlushWithCheck();
}
void WriteBytes(const void *data, size_t size)
diff --git a/CPP/7zip/Compress/BZip2Crc.cpp b/CPP/7zip/Compress/BZip2Crc.cpp
index 4e4741f4..bf8e540f 100644
--- a/CPP/7zip/Compress/BZip2Crc.cpp
+++ b/CPP/7zip/Compress/BZip2Crc.cpp
@@ -13,8 +13,8 @@ void CBZip2Crc::InitTable()
for (UInt32 i = 0; i < 256; i++)
{
UInt32 r = (i << 24);
- for (int j = 8; j > 0; j--)
- r = (r & 0x80000000) ? ((r << 1) ^ kBZip2CrcPoly) : (r << 1);
+ for (unsigned j = 0; j < 8; j++)
+ r = (r << 1) ^ (kBZip2CrcPoly & ((UInt32)0 - (r >> 31)));
Table[i] = r;
}
}
diff --git a/CPP/7zip/Compress/BZip2Decoder.cpp b/CPP/7zip/Compress/BZip2Decoder.cpp
index 56f1b02f..62fa26d0 100644
--- a/CPP/7zip/Compress/BZip2Decoder.cpp
+++ b/CPP/7zip/Compress/BZip2Decoder.cpp
@@ -2,20 +2,47 @@
#include "StdAfx.h"
+// #include "CopyCoder.h"
+
+/*
+#include <stdio.h>
+#include "../../../C/CpuTicks.h"
+*/
+#define TICKS_START
+#define TICKS_UPDATE(n)
+
+
+/*
+#define PRIN(s) printf(s "\n"); fflush(stdout);
+#define PRIN_VAL(s, val) printf(s " = %u \n", val); fflush(stdout);
+*/
+
+#define PRIN(s)
+#define PRIN_VAL(s, val)
+
+#define PRIN_MT(s) PRIN(" " s)
+
#include "../../../C/Alloc.h"
+#include "../Common/StreamUtils.h"
+
#include "BZip2Decoder.h"
-#include "Mtf8.h"
+
namespace NCompress {
namespace NBZip2 {
-#undef NO_INLINE
-#define NO_INLINE
-
-static const UInt32 kNumThreadsMax = 4;
+// #undef NO_INLINE
+#define NO_INLINE MY_NO_INLINE
+
+#define BZIP2_BYTE_MODE
+
+
+static const UInt32 kInBufSize = (UInt32)1 << 17;
+static const size_t kOutBufSize = (size_t)1 << 20;
+
+static const UInt32 kProgressStep = (UInt32)1 << 16;
-static const UInt32 kBufferSize = (1 << 17);
static const UInt16 kRandNums[512] = {
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
@@ -72,923 +99,1643 @@ static const UInt16 kRandNums[512] = {
936, 638
};
-bool CState::Alloc()
+
+
+enum EState
+{
+ STATE_STREAM_SIGNATURE,
+ STATE_BLOCK_SIGNATURE,
+
+ STATE_BLOCK_START,
+ STATE_ORIG_BITS,
+ STATE_IN_USE,
+ STATE_IN_USE2,
+ STATE_NUM_TABLES,
+ STATE_NUM_SELECTORS,
+ STATE_SELECTORS,
+ STATE_LEVELS,
+
+ STATE_BLOCK_SYMBOLS,
+
+ STATE_STREAM_FINISHED
+};
+
+
+#define UPDATE_VAL_2(val) { \
+ val |= (UInt32)(*_buf) << (24 - _numBits); \
+ _numBits += 8; \
+ _buf++; \
+}
+
+#define UPDATE_VAL UPDATE_VAL_2(VAL)
+
+#define READ_BITS(res, num) { \
+ while (_numBits < num) { \
+ if (_buf == _lim) return SZ_OK; \
+ UPDATE_VAL_2(_value) } \
+ res = _value >> (32 - num); \
+ _value <<= num; \
+ _numBits -= num; \
+}
+
+#define READ_BITS_8(res, num) { \
+ if (_numBits < num) { \
+ if (_buf == _lim) return SZ_OK; \
+ UPDATE_VAL_2(_value) } \
+ res = _value >> (32 - num); \
+ _value <<= num; \
+ _numBits -= num; \
+}
+
+#define READ_BIT(res) READ_BITS_8(res, 1)
+
+
+
+#define VAL _value2
+#define BLOCK_SIZE blockSize2
+#define RUN_COUNTER runCounter2
+
+#define LOAD_LOCAL \
+ UInt32 VAL = this->_value; \
+ UInt32 BLOCK_SIZE = this->blockSize; \
+ UInt32 RUN_COUNTER = this->runCounter; \
+
+#define SAVE_LOCAL \
+ this->_value = VAL; \
+ this->blockSize = BLOCK_SIZE; \
+ this->runCounter = RUN_COUNTER; \
+
+
+
+SRes CBitDecoder::ReadByte(int &b)
+{
+ b = -1;
+ READ_BITS_8(b, 8);
+ return SZ_OK;
+}
+
+
+NO_INLINE
+SRes CBase::ReadStreamSignature2()
{
- if (!Counters)
- Counters = (UInt32 *)::BigAlloc((256 + kBlockSizeMax) * sizeof(UInt32));
- return (Counters != 0);
+ for (;;)
+ {
+ unsigned b;
+ READ_BITS_8(b, 8);
+
+ if ( state2 == 0 && b != kArSig0
+ || state2 == 1 && b != kArSig1
+ || state2 == 2 && b != kArSig2
+ || state2 == 3 && (b <= kArSig3 || b > kArSig3 + kBlockSizeMultMax))
+ return SZ_ERROR_DATA;
+ state2++;
+
+ if (state2 == 4)
+ {
+ blockSizeMax = (UInt32)(b - kArSig3) * kBlockSizeStep;
+ CombinedCrc.Init();
+ state = STATE_BLOCK_SIGNATURE;
+ state2 = 0;
+ return SZ_OK;
+ }
+ }
}
-void CState::Free()
+
+bool IsEndSig(const Byte *p) throw()
{
- ::BigFree(Counters);
- Counters = 0;
+ return
+ p[0] == kFinSig0 &&
+ p[1] == kFinSig1 &&
+ p[2] == kFinSig2 &&
+ p[3] == kFinSig3 &&
+ p[4] == kFinSig4 &&
+ p[5] == kFinSig5;
}
-Byte CDecoder::ReadByte() { return (Byte)Base.ReadBits(8); }
+bool IsBlockSig(const Byte *p) throw()
+{
+ return
+ p[0] == kBlockSig0 &&
+ p[1] == kBlockSig1 &&
+ p[2] == kBlockSig2 &&
+ p[3] == kBlockSig3 &&
+ p[4] == kBlockSig4 &&
+ p[5] == kBlockSig5;
+}
-UInt32 CBase::ReadBits(unsigned numBits) { return BitDecoder.ReadBits(numBits); }
-unsigned CBase::ReadBit() { return (unsigned)BitDecoder.ReadBits(1); }
-HRESULT CBase::ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps *props)
+NO_INLINE
+SRes CBase::ReadBlockSignature2()
{
- NumBlocks++;
+ while (state2 < 10)
+ {
+ unsigned b;
+ READ_BITS_8(b, 8);
+ temp[state2] = (Byte)b;
+ state2++;
+ }
- if (props->randMode)
- props->randMode = ReadBit() ? true : false;
- props->origPtr = ReadBits(kNumOrigBits);
+ crc = 0;
+ for (unsigned i = 0; i < 4; i++)
+ {
+ crc <<= 8;
+ crc |= temp[6 + i];
+ }
+
+ if (IsBlockSig(temp))
+ {
+ if (!IsBz)
+ NumStreams++;
+ NumBlocks++;
+ IsBz = true;
+ CombinedCrc.Update(crc);
+ state = STATE_BLOCK_START;
+ return SZ_OK;
+ }
- // in original code it compares OrigPtr to (UInt32)(10 + blockSizeMax)) : why ?
- if (props->origPtr >= blockSizeMax)
- return S_FALSE;
+ if (!IsEndSig(temp))
+ return SZ_ERROR_DATA;
+
+ if (!IsBz)
+ NumStreams++;
+ IsBz = true;
- CMtf8Decoder mtf;
- mtf.StartInit();
+ if (_value != 0)
+ MinorError = true;
+
+ AlignToByte();
+
+ state = STATE_STREAM_FINISHED;
+ if (crc != CombinedCrc.GetDigest())
+ {
+ StreamCrcError = true;
+ return SZ_ERROR_DATA;
+ }
+ return SZ_OK;
+}
+
+
+NO_INLINE
+SRes CBase::ReadBlock2()
+{
+ if (state != STATE_BLOCK_SYMBOLS) {
+ PRIN("ReadBlock2")
+
+ if (state == STATE_BLOCK_START)
+ {
+ if (Props.randMode)
+ {
+ READ_BIT(Props.randMode);
+ }
+ state = STATE_ORIG_BITS;
+ // g_Tick = GetCpuTicks();
+ }
+
+ if (state == STATE_ORIG_BITS)
+ {
+ READ_BITS(Props.origPtr, kNumOrigBits);
+ if (Props.origPtr >= blockSizeMax)
+ return SZ_ERROR_DATA;
+ state = STATE_IN_USE;
+ }
- unsigned numInUse = 0;
- {
- Byte inUse16[16];
- unsigned i;
- for (i = 0; i < 16; i++)
- inUse16[i] = (Byte)ReadBit();
- for (i = 0; i < 256; i++)
- if (inUse16[i >> 4])
+ // why original code compares origPtr to (UInt32)(10 + blockSizeMax)) ?
+
+ if (state == STATE_IN_USE)
+ {
+ READ_BITS(state2, 16);
+ state = STATE_IN_USE2;
+ state3 = 0;
+ numInUse = 0;
+ mtf.StartInit();
+ }
+
+ if (state == STATE_IN_USE2)
+ {
+ for (; state3 < 256; state3++)
+ if (state2 & ((UInt32)0x8000 >> (state3 >> 4)))
{
- if (ReadBit())
- mtf.Add(numInUse++, (Byte)i);
+ unsigned b;
+ READ_BIT(b);
+ if (b)
+ mtf.Add(numInUse++, (Byte)state3);
}
if (numInUse == 0)
- return S_FALSE;
- // mtf.Init(numInUse);
+ return SZ_ERROR_DATA;
+ state = STATE_NUM_TABLES;
}
- unsigned alphaSize = numInUse + 2;
- unsigned numTables = ReadBits(kNumTablesBits);
- if (numTables < kNumTablesMin || numTables > kNumTablesMax)
- return S_FALSE;
- UInt32 numSelectors = ReadBits(kNumSelectorsBits);
- if (numSelectors < 1 || numSelectors > kNumSelectorsMax)
- return S_FALSE;
-
+ if (state == STATE_NUM_TABLES)
{
- Byte mtfPos[kNumTablesMax];
- unsigned t = 0;
- do
- mtfPos[t] = (Byte)t;
- while (++t < numTables);
- UInt32 i = 0;
- do
- {
- unsigned j = 0;
- while (ReadBit())
- if (++j >= numTables)
- return S_FALSE;
- Byte tmp = mtfPos[j];
- for (;j > 0; j--)
- mtfPos[j] = mtfPos[j - 1];
- m_Selectors[i] = mtfPos[0] = tmp;
- }
- while (++i < numSelectors);
+ READ_BITS_8(numTables, kNumTablesBits);
+ state = STATE_NUM_SELECTORS;
+ if (numTables < kNumTablesMin || numTables > kNumTablesMax)
+ return SZ_ERROR_DATA;
+ }
+
+ if (state == STATE_NUM_SELECTORS)
+ {
+ READ_BITS(numSelectors, kNumSelectorsBits);
+ state = STATE_SELECTORS;
+ state2 = 0x543210;
+ state3 = 0;
+ state4 = 0;
+ if (numSelectors == 0 || numSelectors > kNumSelectorsMax)
+ return SZ_ERROR_DATA;
}
- unsigned t = 0;
- do
+ if (state == STATE_SELECTORS)
{
- Byte lens[kMaxAlphaSize];
- unsigned len = (unsigned)ReadBits(kNumLevelsBits);
- unsigned i;
- for (i = 0; i < alphaSize; i++)
+ const unsigned kMtfBits = 4;
+ const UInt32 kMtfMask = (1 << kMtfBits) - 1;
+ do
{
for (;;)
{
- if (len < 1 || len > kMaxHuffmanLen)
- return S_FALSE;
- if (!ReadBit())
+ unsigned b;
+ READ_BIT(b);
+ if (!b)
break;
- len++;
- len -= (ReadBit() << 1);
+ if (++state4 >= numTables)
+ return SZ_ERROR_DATA;
}
- lens[i] = (Byte)len;
+ UInt32 tmp = (state2 >> (kMtfBits * state4)) & kMtfMask;
+ UInt32 mask = ((UInt32)1 << ((state4 + 1) * kMtfBits)) - 1;
+ state4 = 0;
+ state2 = ((state2 << kMtfBits) & mask) | (state2 & ~mask) | tmp;
+ selectors[state3] = (Byte)tmp;
}
- for (; i < kMaxAlphaSize; i++)
- lens[i] = 0;
- if (!m_HuffmanDecoders[t].Build(lens))
- return S_FALSE;
+ while (++state3 < numSelectors);
+
+ state = STATE_LEVELS;
+ state2 = 0;
+ state3 = 0;
}
- while (++t < numTables);
+ if (state == STATE_LEVELS)
{
- for (unsigned i = 0; i < 256; i++)
- charCounters[i] = 0;
+ do
+ {
+ if (state3 == 0)
+ {
+ READ_BITS_8(state3, kNumLevelsBits);
+ state4 = 0;
+ state5 = 0;
+ }
+ const unsigned alphaSize = numInUse + 2;
+ for (; state4 < alphaSize; state4++)
+ {
+ for (;;)
+ {
+ if (state3 < 1 || state3 > kMaxHuffmanLen)
+ return SZ_ERROR_DATA;
+
+ if (state5 == 0)
+ {
+ unsigned b;
+ READ_BIT(b);
+ if (!b)
+ break;
+ }
+
+ state5 = 1;
+ unsigned b;
+ READ_BIT(b);
+
+ state5 = 0;
+ state3++;
+ state3 -= (b << 1);
+ }
+ lens[state4] = (Byte)state3;
+ state5 = 0;
+ }
+ /*
+ for (unsigned i = state4; i < kMaxAlphaSize; i++)
+ lens[i] = 0;
+ */
+ if (!huffs[state2].BuildFull(lens, state4))
+ return SZ_ERROR_DATA;
+ state3 = 0;
+ }
+ while (++state2 < numTables);
+
+ {
+ UInt32 *counters = this->Counters;
+ for (unsigned i = 0; i < 256; i++)
+ counters[i] = 0;
+ }
+
+ state = STATE_BLOCK_SYMBOLS;
+
+ groupIndex = 0;
+ groupSize = kGroupSize;
+ runPower = 0;
+ runCounter = 0;
+ blockSize = 0;
}
- UInt32 blockSize = 0;
+ if (state != STATE_BLOCK_SYMBOLS)
+ return SZ_ERROR_DATA;
+
+ // g_Ticks[3] += GetCpuTicks() - g_Tick;
+
+ }
+
{
- UInt32 groupIndex = 0;
- UInt32 groupSize = 0;
- CHuffmanDecoder *huffmanDecoder = 0;
- unsigned runPower = 0;
- UInt32 runCounter = 0;
-
+ LOAD_LOCAL
+ const CHuffmanDecoder *huff = &huffs[selectors[groupIndex]];
+
for (;;)
{
if (groupSize == 0)
{
- if (groupIndex >= numSelectors)
- return S_FALSE;
+ if (++groupIndex >= numSelectors)
+ return SZ_ERROR_DATA;
+ huff = &huffs[selectors[groupIndex]];
groupSize = kGroupSize;
- huffmanDecoder = &m_HuffmanDecoders[m_Selectors[groupIndex++]];
}
+
+ if (_numBits <= 8 &&
+ _buf != _lim) { UPDATE_VAL
+ if (_buf != _lim) { UPDATE_VAL
+ if (_buf != _lim) { UPDATE_VAL }}}
+
+ UInt32 sym;
+ UInt32 val = VAL >> (32 - kMaxHuffmanLen);
+ if (val >= huff->_limits[kNumTableBits])
+ {
+ if (_numBits <= kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL
+ if (_numBits <= kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL }}
+
+ val = VAL >> (32 - kMaxHuffmanLen);
+ unsigned len;
+ for (len = kNumTableBits + 1; val >= huff->_limits[len]; len++);
+ /*
+ if (len > kNumBitsMax)
+ return SZ_ERROR_DATA;
+ */
+ if (_numBits < len)
+ {
+ SAVE_LOCAL
+ return SZ_OK;
+ }
+ sym = huff->_symbols[huff->_poses[len] + ((val - huff->_limits[(size_t)len - 1]) >> (kNumBitsMax - len))];
+ VAL <<= len;
+ _numBits -= len;
+ }
+ else
+ {
+ sym = huff->_lens[val >> (kMaxHuffmanLen - kNumTableBits)];
+ unsigned len = (sym & NHuffman::kPairLenMask);
+ sym >>= NHuffman::kNumPairLenBits;
+ if (_numBits < len)
+ {
+ SAVE_LOCAL
+ return SZ_OK;
+ }
+ VAL <<= len;
+ _numBits -= len;
+ }
+
groupSize--;
-
- if (BitDecoder.ExtraBitsWereRead_Fast())
- break;
- UInt32 nextSym = huffmanDecoder->Decode(&BitDecoder);
-
- if (nextSym < 2)
+ if (sym < 2)
{
- runCounter += ((UInt32)(nextSym + 1) << runPower++);
- if (blockSizeMax - blockSize < runCounter)
- return S_FALSE;
+ RUN_COUNTER += ((UInt32)(sym + 1) << runPower);
+ runPower++;
+ if (blockSizeMax - BLOCK_SIZE < RUN_COUNTER)
+ return SZ_ERROR_DATA;
continue;
}
- if (runCounter != 0)
+
+ UInt32 *counters = this->Counters;
+ if (RUN_COUNTER != 0)
{
- UInt32 b = (UInt32)mtf.GetHead();
- charCounters[b] += runCounter;
- do
- charCounters[256 + blockSize++] = b;
- while (--runCounter != 0);
+ UInt32 b = (UInt32)(mtf.Buf[0] & 0xFF);
+ counters[b] += RUN_COUNTER;
runPower = 0;
+ #ifdef BZIP2_BYTE_MODE
+ Byte *dest = (Byte *)(&counters[256 + kBlockSizeMax]) + BLOCK_SIZE;
+ const Byte *limit = dest + RUN_COUNTER;
+ BLOCK_SIZE += RUN_COUNTER;
+ RUN_COUNTER = 0;
+ do
+ {
+ dest[0] = (Byte)b;
+ dest[1] = (Byte)b;
+ dest[2] = (Byte)b;
+ dest[3] = (Byte)b;
+ dest += 4;
+ }
+ while (dest < limit);
+ #else
+ UInt32 *dest = &counters[256 + BLOCK_SIZE];
+ const UInt32 *limit = dest + RUN_COUNTER;
+ BLOCK_SIZE += RUN_COUNTER;
+ RUN_COUNTER = 0;
+ do
+ {
+ dest[0] = b;
+ dest[1] = b;
+ dest[2] = b;
+ dest[3] = b;
+ dest += 4;
+ }
+ while (dest < limit);
+ #endif
}
- if (nextSym <= (UInt32)numInUse)
+
+ sym -= 1;
+ if (sym < numInUse)
{
- UInt32 b = (UInt32)mtf.GetAndMove((unsigned)nextSym - 1);
- if (blockSize >= blockSizeMax)
- return S_FALSE;
- charCounters[b]++;
- charCounters[256 + blockSize++] = b;
+ if (BLOCK_SIZE >= blockSizeMax)
+ return SZ_ERROR_DATA;
+
+ // UInt32 b = (UInt32)mtf.GetAndMove((unsigned)sym);
+
+ const unsigned lim = sym >> MTF_MOVS;
+ const unsigned pos = (sym & MTF_MASK) << 3;
+ CMtfVar next = mtf.Buf[lim];
+ CMtfVar prev = (next >> pos) & 0xFF;
+
+ #ifdef BZIP2_BYTE_MODE
+ ((Byte *)(counters + 256 + kBlockSizeMax))[BLOCK_SIZE++] = (Byte)prev;
+ #else
+ (counters + 256)[BLOCK_SIZE++] = (UInt32)prev;
+ #endif
+ counters[prev]++;
+
+ CMtfVar *m = mtf.Buf;
+ CMtfVar *mLim = m + lim;
+ if (lim != 0)
+ {
+ do
+ {
+ CMtfVar n0 = *m;
+ *m = (n0 << 8) | prev;
+ prev = (n0 >> (MTF_MASK << 3));
+ }
+ while (++m != mLim);
+ }
+
+ CMtfVar mask = (((CMtfVar)0x100 << pos) - 1);
+ *mLim = (next & ~mask) | (((next << 8) | prev) & mask);
+ continue;
}
- else if (nextSym == (UInt32)numInUse + 1)
- break;
- else
- return S_FALSE;
+
+ if (sym != numInUse)
+ return SZ_ERROR_DATA;
+ break;
}
- if (BitDecoder.ExtraBitsWereRead())
- return S_FALSE;
+ // we write additional item that will be read in DecodeBlock1 for prefetching
+ #ifdef BZIP2_BYTE_MODE
+ ((Byte *)(Counters + 256 + kBlockSizeMax))[BLOCK_SIZE] = 0;
+ #else
+ (counters + 256)[BLOCK_SIZE] = 0;
+ #endif
+
+ SAVE_LOCAL
+ Props.blockSize = blockSize;
+ state = STATE_BLOCK_SIGNATURE;
+ state2 = 0;
+
+ PRIN_VAL("origPtr", Props.origPtr);
+ PRIN_VAL("blockSize", Props.blockSize);
+
+ return (Props.origPtr < Props.blockSize) ? SZ_OK : SZ_ERROR_DATA;
}
- props->blockSize = blockSize;
- return (props->origPtr < props->blockSize) ? S_OK : S_FALSE;
}
-static void NO_INLINE DecodeBlock1(UInt32 *charCounters, UInt32 blockSize)
+
+NO_INLINE
+static void DecodeBlock1(UInt32 *counters, UInt32 blockSize)
{
{
UInt32 sum = 0;
for (UInt32 i = 0; i < 256; i++)
{
- sum += charCounters[i];
- charCounters[i] = sum - charCounters[i];
+ const UInt32 v = counters[i];
+ counters[i] = sum;
+ sum += v;
}
}
- UInt32 *tt = charCounters + 256;
+ UInt32 *tt = counters + 256;
// Compute the T^(-1) vector
- UInt32 i = 0;
- do
- tt[charCounters[tt[i] & 0xFF]++] |= (i << 8);
- while (++i < blockSize);
+
+ // blockSize--;
+
+ #ifdef BZIP2_BYTE_MODE
+
+ unsigned c = ((const Byte *)(tt + kBlockSizeMax))[0];
+
+ for (UInt32 i = 0; i < blockSize; i++)
+ {
+ unsigned c1 = c;
+ const UInt32 pos = counters[c];
+ c = ((const Byte *)(tt + kBlockSizeMax))[(size_t)i + 1];
+ counters[c1] = pos + 1;
+ tt[pos] = (i << 8) | ((const Byte *)(tt + kBlockSizeMax))[pos];
+ }
+
+ /*
+ // last iteration without next character prefetching
+ {
+ const UInt32 pos = counters[c];
+ counters[c] = pos + 1;
+ tt[pos] = (blockSize << 8) | ((const Byte *)(tt + kBlockSizeMax))[pos];
+ }
+ */
+
+ #else
+
+ unsigned c = (unsigned)(tt[0] & 0xFF);
+
+ for (UInt32 i = 0; i < blockSize; i++)
+ {
+ unsigned c1 = c;
+ const UInt32 pos = counters[c];
+ c = (unsigned)(tt[(size_t)i + 1] & 0xFF);
+ counters[c1] = pos + 1;
+ tt[pos] |= (i << 8);
+ }
+
+ /*
+ {
+ const UInt32 pos = counters[c];
+ counters[c] = pos + 1;
+ tt[pos] |= (blockSize << 8);
+ }
+ */
+
+ #endif
+
+
+ /*
+ for (UInt32 i = 0; i < blockSize; i++)
+ {
+ #ifdef BZIP2_BYTE_MODE
+ const unsigned c = ((const Byte *)(tt + kBlockSizeMax))[i];
+ const UInt32 pos = counters[c]++;
+ tt[pos] = (i << 8) | ((const Byte *)(tt + kBlockSizeMax))[pos];
+ #else
+ const unsigned c = (unsigned)(tt[i] & 0xFF);
+ const UInt32 pos = counters[c]++;
+ tt[pos] |= (i << 8);
+ #endif
+ }
+ */
}
-static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream)
+
+void CSpecState::Init(UInt32 origPtr, unsigned randMode) throw()
{
- CBZip2Crc crc;
+ _tPos = _tt[_tt[origPtr] >> 8];
+ _prevByte = (unsigned)(_tPos & 0xFF);
+ _reps = 0;
+ _randIndex = 0;
+ _randToGo = -1;
+ if (randMode)
+ {
+ _randIndex = 1;
+ _randToGo = kRandNums[0] - 2;
+ }
+ _crc.Init();
+}
- // it's for speed optimization: prefetch & prevByte_init;
- UInt32 tPos = tt[tt[OrigPtr] >> 8];
- unsigned prevByte = (unsigned)(tPos & 0xFF);
-
- unsigned numReps = 0;
- do
+
+NO_INLINE
+Byte * CSpecState::Decode(Byte *data, size_t size) throw()
+{
+ if (size == 0)
+ return data;
+
+ unsigned prevByte = _prevByte;
+ int reps = _reps;
+ CBZip2Crc crc = _crc;
+ const Byte *lim = data + size;
+
+ while (reps > 0)
+ {
+ reps--;
+ *data++ = (Byte)prevByte;
+ crc.UpdateByte(prevByte);
+ if (data == lim)
+ break;
+ }
+
+ UInt32 tPos = _tPos;
+ UInt32 blockSize = _blockSize;
+ const UInt32 *tt = _tt;
+
+ if (data != lim && blockSize)
+
+ for (;;)
{
unsigned b = (unsigned)(tPos & 0xFF);
tPos = tt[tPos >> 8];
-
- if (numReps == kRleModeRepSize)
+ blockSize--;
+
+ if (_randToGo >= 0)
{
- for (; b > 0; b--)
+ if (_randToGo == 0)
{
- crc.UpdateByte(prevByte);
- m_OutStream.WriteByte((Byte)prevByte);
+ b ^= 1;
+ _randToGo = kRandNums[_randIndex];
+ _randIndex++;
+ _randIndex &= 0x1FF;
}
- numReps = 0;
- continue;
+ _randToGo--;
}
- if (b != prevByte)
- numReps = 0;
- numReps++;
- prevByte = b;
- crc.UpdateByte(b);
- m_OutStream.WriteByte((Byte)b);
-
- /*
- prevByte = b;
- crc.UpdateByte(b);
- m_OutStream.WriteByte((Byte)b);
- for (; --blockSize != 0;)
- {
- b = (unsigned)(tPos & 0xFF);
- tPos = tt[tPos >> 8];
- crc.UpdateByte(b);
- m_OutStream.WriteByte((Byte)b);
+
+ if (reps != -(int)kRleModeRepSize)
+ {
if (b != prevByte)
- {
- prevByte = b;
- continue;
- }
- if (--blockSize == 0)
- break;
-
- b = (unsigned)(tPos & 0xFF);
- tPos = tt[tPos >> 8];
+ reps = 0;
+ reps--;
+ prevByte = b;
+ *data++ = (Byte)b;
crc.UpdateByte(b);
- m_OutStream.WriteByte((Byte)b);
- if (b != prevByte)
- {
- prevByte = b;
- continue;
- }
- if (--blockSize == 0)
+ if (data == lim || blockSize == 0)
+ break;
+ continue;
+ }
+
+ reps = b;
+ while (reps)
+ {
+ reps--;
+ *data++ = (Byte)prevByte;
+ crc.UpdateByte(prevByte);
+ if (data == lim)
break;
-
- b = (unsigned)(tPos & 0xFF);
- tPos = tt[tPos >> 8];
- crc.UpdateByte(b);
- m_OutStream.WriteByte((Byte)b);
- if (b != prevByte)
- {
- prevByte = b;
- continue;
- }
- --blockSize;
- break;
}
+ if (data == lim)
+ break;
if (blockSize == 0)
break;
+ }
- b = (unsigned)(tPos & 0xFF);
+ if (blockSize == 1 && reps == -(int)kRleModeRepSize)
+ {
+ unsigned b = (unsigned)(tPos & 0xFF);
tPos = tt[tPos >> 8];
-
- for (; b > 0; b--)
+ blockSize--;
+
+ if (_randToGo >= 0)
{
- crc.UpdateByte(prevByte);
- m_OutStream.WriteByte((Byte)prevByte);
+ if (_randToGo == 0)
+ {
+ b ^= 1;
+ _randToGo = kRandNums[_randIndex];
+ _randIndex++;
+ _randIndex &= 0x1FF;
+ }
+ _randToGo--;
}
- */
+
+ reps = b;
}
- while (--blockSize != 0);
- return crc.GetDigest();
+
+ _tPos = tPos;
+ _prevByte = prevByte;
+ _reps = reps;
+ _crc = crc;
+ _blockSize = blockSize;
+
+ return data;
}
-static UInt32 NO_INLINE DecodeBlock2Rand(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream)
+
+HRESULT CDecoder::Flush()
{
- CBZip2Crc crc;
-
- UInt32 randIndex = 1;
- UInt32 randToGo = kRandNums[0] - 2;
-
- unsigned numReps = 0;
+ if (_writeRes == S_OK)
+ {
+ _writeRes = WriteStream(_outStream, _outBuf, _outPos);
+ _outWritten += _outPos;
+ _outPos = 0;
+ }
+ return _writeRes;
+}
- // it's for speed optimization: prefetch & prevByte_init;
- UInt32 tPos = tt[tt[OrigPtr] >> 8];
- unsigned prevByte = (unsigned)(tPos & 0xFF);
-
- do
+
+NO_INLINE
+HRESULT CDecoder::DecodeBlock(const CBlockProps &props)
+{
+ _calcedBlockCrc = 0;
+ _blockFinished = false;
+
+ CSpecState block;
+
+ block._blockSize = props.blockSize;
+ block._tt = _counters + 256;
+
+ block.Init(props.origPtr, props.randMode);
+
+ for (;;)
{
- unsigned b = (unsigned)(tPos & 0xFF);
- tPos = tt[tPos >> 8];
+ Byte *data = _outBuf + _outPos;
+ size_t size = kOutBufSize - _outPos;
+ if (_outSizeDefined)
{
- if (randToGo == 0)
+ const UInt64 rem = _outSize - _outPosTotal;
+ if (size >= rem)
{
- b ^= 1;
- randToGo = kRandNums[randIndex++];
- randIndex &= 0x1FF;
+ size = (size_t)rem;
+ if (size == 0)
+ return FinishMode ? S_FALSE : S_OK;
}
- randToGo--;
+ }
+
+ TICKS_START
+ const size_t processed = block.Decode(data, size) - data;
+ TICKS_UPDATE(2)
+
+ _outPosTotal += processed;
+ _outPos += processed;
+
+ if (processed >= size)
+ {
+ RINOK(Flush());
}
- if (numReps == kRleModeRepSize)
+ if (block.Finished())
{
- for (; b > 0; b--)
- {
- crc.UpdateByte(prevByte);
- m_OutStream.WriteByte((Byte)prevByte);
- }
- numReps = 0;
- continue;
+ _blockFinished = true;
+ _calcedBlockCrc = block._crc.GetDigest();
+ return S_OK;
}
- if (b != prevByte)
- numReps = 0;
- numReps++;
- prevByte = b;
- crc.UpdateByte(b);
- m_OutStream.WriteByte((Byte)b);
}
- while (--blockSize != 0);
- return crc.GetDigest();
}
-static UInt32 NO_INLINE DecodeBlock(const CBlockProps &props, UInt32 *tt, COutBuffer &m_OutStream)
-{
- if (props.randMode)
- return DecodeBlock2Rand(tt, props.blockSize, props.origPtr, m_OutStream);
- else
- return DecodeBlock2 (tt, props.blockSize, props.origPtr, m_OutStream);
-}
-CDecoder::CDecoder()
+CDecoder::CDecoder():
+ _inBuf(NULL),
+ _outBuf(NULL),
+ _counters(NULL),
+ FinishMode(false),
+ _outSizeDefined(false)
{
#ifndef _7ZIP_ST
- m_States = 0;
- m_NumThreadsPrev = 0;
- NumThreads = 1;
+ MtMode = false;
+ NeedWaitScout = false;
+ // ScoutRes = S_OK;
#endif
- _needInStreamInit = true;
}
-#ifndef _7ZIP_ST
CDecoder::~CDecoder()
{
- Free();
-}
-
-#define RINOK_THREAD(x) { WRes __result_ = (x); if (__result_ != 0) return __result_; }
+ PRIN("\n~CDecoder()");
-HRESULT CDecoder::Create()
-{
- RINOK_THREAD(CanProcessEvent.CreateIfNotCreated());
- RINOK_THREAD(CanStartWaitingEvent.CreateIfNotCreated());
- if (m_States != 0 && m_NumThreadsPrev == NumThreads)
- return S_OK;
- Free();
- MtMode = (NumThreads > 1);
- m_NumThreadsPrev = NumThreads;
- try
- {
- m_States = new CState[NumThreads];
- if (!m_States)
- return E_OUTOFMEMORY;
- }
- catch(...) { return E_OUTOFMEMORY; }
- for (UInt32 t = 0; t < NumThreads; t++)
+ #ifndef _7ZIP_ST
+
+ if (Thread.IsCreated())
{
- CState &ti = m_States[t];
- ti.Decoder = this;
- if (MtMode)
- {
- HRESULT res = ti.Create();
- if (res != S_OK)
- {
- NumThreads = t;
- Free();
- return res;
- }
- }
+ WaitScout();
+
+ _block.StopScout = true;
+
+ PRIN("\nScoutEvent.Set()");
+ ScoutEvent.Set();
+
+ PRIN("\nThread.Wait()()");
+ Thread.Wait();
+ PRIN("\n after Thread.Wait()()");
+ Thread.Close();
+
+ // if (ScoutRes != S_OK) throw ScoutRes;
}
- return S_OK;
+
+ #endif
+
+ BigFree(_counters);
+ MidFree(_outBuf);
+ MidFree(_inBuf);
}
-void CDecoder::Free()
+
+HRESULT CDecoder::ReadInput()
{
- if (!m_States)
- return;
- CloseThreads = true;
- CanProcessEvent.Set();
- for (UInt32 t = 0; t < NumThreads; t++)
- {
- CState &s = m_States[t];
- if (MtMode)
- s.Thread.Wait();
- s.Free();
- }
- delete []m_States;
- m_States = 0;
+ if (Base._buf != Base._lim || _inputFinished || _inputRes != S_OK)
+ return _inputRes;
+
+ _inProcessed += (Base._buf - _inBuf);
+ Base._buf = _inBuf;
+ Base._lim = _inBuf;
+ UInt32 size = 0;
+ _inputRes = Base.InStream->Read(_inBuf, kInBufSize, &size);
+ _inputFinished = (size == 0);
+ Base._lim = _inBuf + size;
+ return _inputRes;
}
-#endif
-bool IsEndSig(const Byte *p) throw()
+void CDecoder::StartNewStream()
{
- return
- p[0] == kFinSig0 &&
- p[1] == kFinSig1 &&
- p[2] == kFinSig2 &&
- p[3] == kFinSig3 &&
- p[4] == kFinSig4 &&
- p[5] == kFinSig5;
+ Base.state = STATE_STREAM_SIGNATURE;
+ Base.state2 = 0;
+ Base.IsBz = false;
}
-bool IsBlockSig(const Byte *p) throw()
+
+HRESULT CDecoder::ReadStreamSignature()
{
- return
- p[0] == kBlockSig0 &&
- p[1] == kBlockSig1 &&
- p[2] == kBlockSig2 &&
- p[3] == kBlockSig3 &&
- p[4] == kBlockSig4 &&
- p[5] == kBlockSig5;
+ for (;;)
+ {
+ RINOK(ReadInput());
+ SRes res = Base.ReadStreamSignature2();
+ if (res != SZ_OK)
+ return S_FALSE;
+ if (Base.state == STATE_BLOCK_SIGNATURE)
+ return S_OK;
+ if (_inputFinished)
+ {
+ Base.NeedMoreInput = true;
+ return S_FALSE;
+ }
+ }
}
-HRESULT CDecoder::ReadSignature(UInt32 &crc)
-{
- BzWasFinished = false;
- crc = 0;
- Byte s[10];
- unsigned i;
- for (i = 0; i < 10; i++)
- s[i] = ReadByte();
+HRESULT CDecoder::StartRead()
+{
+ StartNewStream();
+ return ReadStreamSignature();
+}
- if (Base.BitDecoder.ExtraBitsWereRead())
- return S_FALSE;
- UInt32 v = 0;
- for (i = 0; i < 4; i++)
+HRESULT CDecoder::ReadBlockSignature()
+{
+ for (;;)
{
- v <<= 8;
- v |= s[6 + i];
+ RINOK(ReadInput());
+
+ SRes res = Base.ReadBlockSignature2();
+
+ if (Base.state == STATE_STREAM_FINISHED)
+ Base.FinishedPackSize = GetInputProcessedSize();
+ if (res != SZ_OK)
+ return S_FALSE;
+ if (Base.state != STATE_BLOCK_SIGNATURE)
+ return S_OK;
+ if (_inputFinished)
+ {
+ Base.NeedMoreInput = true;
+ return S_FALSE;
+ }
}
+}
- crc = v;
- if (IsBlockSig(s))
+HRESULT CDecoder::ReadBlock()
+{
+ for (;;)
{
- IsBz = true;
- CombinedCrc.Update(crc);
- return S_OK;
- }
+ RINOK(ReadInput());
- if (!IsEndSig(s))
- return S_FALSE;
+ SRes res = Base.ReadBlock2();
- IsBz = true;
- BzWasFinished = true;
- if (crc != CombinedCrc.GetDigest())
- {
- CrcError = true;
- return S_FALSE;
+ if (res != SZ_OK)
+ return S_FALSE;
+ if (Base.state == STATE_BLOCK_SIGNATURE)
+ return S_OK;
+ if (_inputFinished)
+ {
+ Base.NeedMoreInput = true;
+ return S_FALSE;
+ }
}
- return S_OK;
}
-HRESULT CDecoder::DecodeFile(ICompressProgressInfo *progress)
+
+
+HRESULT CDecoder::DecodeStreams(ICompressProgressInfo *progress)
{
- Progress = progress;
- #ifndef _7ZIP_ST
- RINOK(Create());
- for (UInt32 t = 0; t < NumThreads; t++)
{
- CState &s = m_States[t];
- if (!s.Alloc())
- return E_OUTOFMEMORY;
- if (MtMode)
- {
- RINOK(s.StreamWasFinishedEvent.Reset());
- RINOK(s.WaitingWasStartedEvent.Reset());
- RINOK(s.CanWriteEvent.Reset());
- }
+ #ifndef _7ZIP_ST
+ _block.StopScout = false;
+ #endif
}
- #else
- if (!m_States[0].Alloc())
- return E_OUTOFMEMORY;
- #endif
- IsBz = false;
+ RINOK(StartRead());
- /*
- if (Base.BitDecoder.ExtraBitsWereRead())
- return E_FAIL;
- */
+ UInt64 inPrev = 0;
+ UInt64 outPrev = 0;
- Byte s[4];
- unsigned i;
- for (i = 0; i < 4; i++)
- s[i] = ReadByte();
- if (Base.BitDecoder.ExtraBitsWereRead())
- return S_FALSE;
+ {
+ #ifndef _7ZIP_ST
+ CWaitScout_Releaser waitScout_Releaser(this);
- if (s[0] != kArSig0 ||
- s[1] != kArSig1 ||
- s[2] != kArSig2 ||
- s[3] <= kArSig3 ||
- s[3] > kArSig3 + kBlockSizeMultMax)
- return S_FALSE;
+ bool useMt = false;
+ #endif
- UInt32 dicSize = (UInt32)(s[3] - kArSig3) * kBlockSizeStep;
+ bool wasFinished = false;
+
+ UInt32 crc = 0;
+ UInt32 nextCrc = 0;
+ HRESULT nextRes = S_OK;
+
+ UInt64 packPos = 0;
+
+ CBlockProps props;
+
+ props.blockSize = 0;
- CombinedCrc.Init();
- #ifndef _7ZIP_ST
- if (MtMode)
- {
- NextBlockIndex = 0;
- StreamWasFinished1 = StreamWasFinished2 = false;
- CloseThreads = false;
- CanStartWaitingEvent.Reset();
- m_States[0].CanWriteEvent.Set();
- BlockSizeMax = dicSize;
- Result1 = Result2 = S_OK;
- CanProcessEvent.Set();
- UInt32 t;
- for (t = 0; t < NumThreads; t++)
- m_States[t].StreamWasFinishedEvent.Lock();
- CanProcessEvent.Reset();
- CanStartWaitingEvent.Set();
- for (t = 0; t < NumThreads; t++)
- m_States[t].WaitingWasStartedEvent.Lock();
- CanStartWaitingEvent.Reset();
- RINOK(Result2);
- RINOK(Result1);
- }
- else
- #endif
- {
- CState &state = m_States[0];
for (;;)
{
- RINOK(SetRatioProgress(Base.BitDecoder.GetProcessedSize()));
- UInt32 crc;
- RINOK(ReadSignature(crc));
- if (BzWasFinished)
- return S_OK;
-
- CBlockProps props;
- props.randMode = true;
- RINOK(Base.ReadBlock(state.Counters, dicSize, &props));
- DecodeBlock1(state.Counters, props.blockSize);
- if (DecodeBlock(props, state.Counters + 256, m_OutStream) != crc)
+ if (progress)
+ {
+ const UInt64 outCur = GetOutProcessedSize();
+ if (packPos - inPrev >= kProgressStep || outCur - outPrev >= kProgressStep)
+ {
+ RINOK(progress->SetRatioInfo(&packPos, &outCur));
+ inPrev = packPos;
+ outPrev = outCur;
+ }
+ }
+
+ if (props.blockSize == 0)
+ if (wasFinished || nextRes != S_OK)
+ return nextRes;
+
+ if (
+ #ifndef _7ZIP_ST
+ !useMt &&
+ #endif
+ !wasFinished && Base.state == STATE_BLOCK_SIGNATURE)
+ {
+ nextRes = ReadBlockSignature();
+ nextCrc = Base.crc;
+ packPos = GetInputProcessedSize();
+
+ wasFinished = true;
+
+ if (nextRes != S_OK)
+ continue;
+
+ if (Base.state == STATE_STREAM_FINISHED)
+ {
+ if (!Base.DecodeAllStreams)
+ {
+ wasFinished = true;
+ continue;
+ }
+
+ nextRes = StartRead();
+
+ if (Base.NeedMoreInput)
+ {
+ if (Base.state2 == 0)
+ Base.NeedMoreInput = false;
+ wasFinished = true;
+ nextRes = S_OK;
+ continue;
+ }
+
+ if (nextRes != S_OK)
+ continue;
+
+ wasFinished = false;
+ continue;
+ }
+
+ wasFinished = false;
+
+ #ifndef _7ZIP_ST
+ if (MtMode)
+ if (props.blockSize != 0)
+ {
+ // we start multithreading, if next block is big enough.
+ const UInt32 k_Mt_BlockSize_Threshold = (1 << 12); // (1 << 13)
+ if (props.blockSize > k_Mt_BlockSize_Threshold)
+ {
+ if (!Thread.IsCreated())
+ {
+ PRIN("=== MT_MODE");
+ RINOK(CreateThread());
+ }
+ useMt = true;
+ }
+ }
+ #endif
+ }
+
+ if (props.blockSize == 0)
{
- CrcError = true;
+ crc = nextCrc;
+
+ #ifndef _7ZIP_ST
+ if (useMt)
+ {
+ PRIN("DecoderEvent.Lock()");
+ RINOK(DecoderEvent.Lock());
+ NeedWaitScout = false;
+ PRIN("-- DecoderEvent.Lock()");
+ props = _block.Props;
+ nextCrc = _block.NextCrc;
+ if (_block.Crc_Defined)
+ crc = _block.Crc;
+ packPos = _block.PackPos;
+ wasFinished = _block.WasFinished;
+ RINOK(_block.Res);
+ }
+ else
+ #endif
+ {
+ if (Base.state != STATE_BLOCK_START)
+ return E_FAIL;
+
+ TICKS_START
+ Base.Props.randMode = 1;
+ RINOK(ReadBlock());
+ TICKS_UPDATE(0)
+
+ props = Base.Props;
+ continue;
+ }
+ }
+
+ if (props.blockSize != 0)
+ {
+ TICKS_START
+ DecodeBlock1(_counters, props.blockSize);
+ TICKS_UPDATE(1)
+ }
+
+ #ifndef _7ZIP_ST
+ if (useMt && !wasFinished)
+ {
+ /*
+ if (props.blockSize == 0)
+ {
+ // this codes switches back to single-threadMode
+ useMt = false;
+ PRIN("=== ST_MODE");
+ continue;
+ }
+ */
+
+ PRIN("ScoutEvent.Set()");
+ RINOK(ScoutEvent.Set());
+ NeedWaitScout = true;
+ }
+ #endif
+
+ if (props.blockSize == 0)
+ continue;
+
+ RINOK(DecodeBlock(props));
+
+ if (!_blockFinished)
+ return nextRes;
+
+ props.blockSize = 0;
+ if (_calcedBlockCrc != crc)
+ {
+ BlockCrcError = true;
return S_FALSE;
}
}
}
- return SetRatioProgress(Base.BitDecoder.GetProcessedSize());
}
-HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
- ICompressProgressInfo *progress)
-{
- IsBz = false;
- BzWasFinished = false;
- CrcError = false;
- try
+
+
+bool CDecoder::CreateInputBufer()
+{
+ if (!_inBuf)
{
+ _inBuf = (Byte *)MidAlloc(kInBufSize);
+ if (!_inBuf)
+ return false;
+ }
+ if (!_counters)
+ {
+ _counters = (UInt32 *)::BigAlloc((256 + kBlockSizeMax) * sizeof(UInt32)
+ #ifdef BZIP2_BYTE_MODE
+ + kBlockSizeMax
+ #endif
+ + 256);
+ if (!_counters)
+ return false;
+ Base.Counters = _counters;
+ }
+ return true;
+}
- if (!Base.BitDecoder.Create(kBufferSize))
- return E_OUTOFMEMORY;
- if (!m_OutStream.Create(kBufferSize))
- return E_OUTOFMEMORY;
- if (inStream)
- Base.BitDecoder.SetStream(inStream);
+void CDecoder::InitOutSize(const UInt64 *outSize)
+{
+ _outPosTotal = 0;
+
+ _outSizeDefined = false;
+ _outSize = 0;
+ if (outSize)
+ {
+ _outSize = *outSize;
+ _outSizeDefined = true;
+ }
+
+ BlockCrcError = false;
+
+ Base.InitNumStreams2();
+}
- CDecoderFlusher flusher(this);
- if (_needInStreamInit)
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
+{
+ /*
{
- Base.BitDecoder.Init();
- _needInStreamInit = false;
+ RINOK(SetInStream(inStream));
+ RINOK(SetOutStreamSize(outSize));
+
+ RINOK(CopyStream(this, outStream, progress));
+ return ReleaseInStream();
}
- _inStart = Base.BitDecoder.GetProcessedSize();
+ */
+
+ InitOutSize(outSize);
- Base.BitDecoder.AlignToByte();
+ _inputFinished = false;
+ _inputRes = S_OK;
+ _writeRes = S_OK;
- m_OutStream.SetStream(outStream);
- m_OutStream.Init();
+ try {
- RINOK(DecodeFile(progress));
- flusher.NeedFlush = false;
- return Flush();
+ if (!CreateInputBufer())
+ return E_OUTOFMEMORY;
+ if (!_outBuf)
+ {
+ _outBuf = (Byte *)MidAlloc(kOutBufSize);
+ if (!_outBuf)
+ return E_OUTOFMEMORY;
}
- catch(const CInBufferException &e) { return e.ErrorCode; }
- catch(const COutBufferException &e) { return e.ErrorCode; }
- catch(...) { return E_FAIL; }
-}
-STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
- const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
-{
- _needInStreamInit = true;
- return CodeReal(inStream, outStream, progress);
-}
+ Base.InStream = inStream;
+
+ InitInputBuffer();
+
+ _outStream = outStream;
+ _outWritten = 0;
+ _outPos = 0;
-HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, ICompressProgressInfo *progress)
-{
- return CodeReal(NULL, outStream, progress);
+ HRESULT res = DecodeStreams(progress);
+
+ Flush();
+
+ Base.InStream = NULL;
+ _outStream = NULL;
+
+ /*
+ if (res == S_OK)
+ if (FinishMode && inSize && *inSize != GetInputProcessedSize())
+ res = S_FALSE;
+ */
+
+ if (res != S_OK)
+ return res;
+
+ } catch(...) { return E_FAIL; }
+
+ return _writeRes;
}
-STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
+
+STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
{
- Base.InStreamRef = inStream;
- Base.BitDecoder.SetStream(inStream);
+ FinishMode = (finishMode != 0);
return S_OK;
}
-STDMETHODIMP CDecoder::ReleaseInStream()
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
{
- Base.InStreamRef.Release();
+ *value = GetInputProcessedSize();
return S_OK;
}
+
#ifndef _7ZIP_ST
-static THREAD_FUNC_DECL MFThread(void *p) { ((CState *)p)->ThreadFunc(); return 0; }
+#define RINOK_THREAD(x) { WRes __result_ = (x); if (__result_ != 0) return __result_; }
-HRESULT CState::Create()
-{
- RINOK_THREAD(StreamWasFinishedEvent.CreateIfNotCreated());
- RINOK_THREAD(WaitingWasStartedEvent.CreateIfNotCreated());
- RINOK_THREAD(CanWriteEvent.CreateIfNotCreated());
- RINOK_THREAD(Thread.Create(MFThread, this));
- return S_OK;
-}
+static THREAD_FUNC_DECL RunScout2(void *p) { ((CDecoder *)p)->RunScout(); return 0; }
-void CState::FinishStream()
+HRESULT CDecoder::CreateThread()
{
- Decoder->StreamWasFinished1 = true;
- StreamWasFinishedEvent.Set();
- Decoder->CS.Leave();
- Decoder->CanStartWaitingEvent.Lock();
- WaitingWasStartedEvent.Set();
+ RINOK_THREAD(DecoderEvent.CreateIfNotCreated());
+ RINOK_THREAD(ScoutEvent.CreateIfNotCreated());
+ RINOK_THREAD(Thread.Create(RunScout2, this));
+ return S_OK;
}
-void CState::ThreadFunc()
+void CDecoder::RunScout()
{
for (;;)
{
- Decoder->CanProcessEvent.Lock();
- Decoder->CS.Enter();
- if (Decoder->CloseThreads)
{
- Decoder->CS.Leave();
- return;
- }
- if (Decoder->StreamWasFinished1)
- {
- FinishStream();
- continue;
- }
- HRESULT res = S_OK;
-
- UInt32 blockIndex = Decoder->NextBlockIndex;
- UInt32 nextBlockIndex = blockIndex + 1;
- if (nextBlockIndex == Decoder->NumThreads)
- nextBlockIndex = 0;
- Decoder->NextBlockIndex = nextBlockIndex;
- UInt32 crc;
- UInt64 packSize = 0;
- CBlockProps props;
-
- try
- {
- res = Decoder->ReadSignature(crc);
- if (res != S_OK)
- {
- Decoder->Result1 = res;
- FinishStream();
- continue;
- }
- if (Decoder->BzWasFinished)
- {
- Decoder->Result1 = res;
- FinishStream();
- continue;
- }
-
- props.randMode = true;
- res = Decoder->Base.ReadBlock(Counters, Decoder->BlockSizeMax, &props);
- if (res != S_OK)
+ PRIN_MT("ScoutEvent.Lock()");
+ WRes wres = ScoutEvent.Lock();
+ PRIN_MT("-- ScoutEvent.Lock()");
+ if (wres != 0)
{
- Decoder->Result1 = res;
- FinishStream();
- continue;
+ // ScoutRes = wres;
+ return;
}
- packSize = Decoder->Base.BitDecoder.GetProcessedSize();
}
- catch(const CInBufferException &e) { res = e.ErrorCode; if (res == S_OK) res = E_FAIL; }
- catch(...) { res = E_FAIL; }
- if (res != S_OK)
+
+ CBlock &block = _block;
+
+ if (block.StopScout)
{
- Decoder->Result1 = res;
- FinishStream();
- continue;
+ // ScoutRes = S_OK;
+ return;
}
- Decoder->CS.Leave();
+ block.Res = S_OK;
+ block.WasFinished = false;
- DecodeBlock1(Counters, props.blockSize);
+ HRESULT res = S_OK;
- bool needFinish = true;
try
{
- Decoder->m_States[blockIndex].CanWriteEvent.Lock();
- needFinish = Decoder->StreamWasFinished2;
- if (!needFinish)
+ UInt64 packPos = GetInputProcessedSize();
+
+ block.Props.blockSize = 0;
+ block.Crc_Defined = false;
+ // block.NextCrc_Defined = false;
+ block.NextCrc = 0;
+
+ for (;;)
{
- if (DecodeBlock(props, Counters + 256, Decoder->m_OutStream) == crc)
- res = Decoder->SetRatioProgress(packSize);
- else
- res = S_FALSE;
+ if (Base.state == STATE_BLOCK_SIGNATURE)
+ {
+ res = ReadBlockSignature();
+
+ if (res != S_OK)
+ break;
+
+ if (block.Props.blockSize == 0)
+ {
+ block.Crc = Base.crc;
+ block.Crc_Defined = true;
+ }
+ else
+ {
+ block.NextCrc = Base.crc;
+ // block.NextCrc_Defined = true;
+ }
+
+ continue;
+ }
+
+ if (Base.state == STATE_BLOCK_START)
+ {
+ if (block.Props.blockSize != 0)
+ break;
+
+ Base.Props.randMode = 1;
+
+ res = ReadBlock();
+
+ PRIN_MT("-- Base.ReadBlock");
+ if (res != S_OK)
+ break;
+ block.Props = Base.Props;
+ continue;
+ }
+
+ if (Base.state == STATE_STREAM_FINISHED)
+ {
+ if (!Base.DecodeAllStreams)
+ {
+ block.WasFinished = true;
+ break;
+ }
+
+ res = StartRead();
+
+ if (Base.NeedMoreInput)
+ {
+ if (Base.state2 == 0)
+ Base.NeedMoreInput = false;
+ block.WasFinished = true;
+ res = S_OK;
+ break;
+ }
+
+ if (res != S_OK)
+ break;
+
+ if (GetInputProcessedSize() - packPos > 0) // kProgressStep
+ break;
+ continue;
+ }
+
+ // throw 1;
+ res = E_FAIL;
+ break;
}
}
- catch(const COutBufferException &e) { res = e.ErrorCode; if (res == S_OK) res = E_FAIL; }
- catch(...) { res = E_FAIL; }
+
+ catch (...) { res = E_FAIL; }
+
if (res != S_OK)
{
- Decoder->Result2 = res;
- Decoder->StreamWasFinished2 = true;
+ PRIN_MT("error");
+ block.Res = res;
+ block.WasFinished = true;
}
- Decoder->m_States[nextBlockIndex].CanWriteEvent.Set();
- if (res != S_OK || needFinish)
+
+ block.PackPos = GetInputProcessedSize();
+ PRIN_MT("DecoderEvent.Set()");
+ WRes wres = DecoderEvent.Set();
+ if (wres != 0)
{
- StreamWasFinishedEvent.Set();
- Decoder->CanStartWaitingEvent.Lock();
- WaitingWasStartedEvent.Set();
+ // ScoutRes = wres;
+ return;
}
}
}
+
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)
{
- NumThreads = numThreads;
- if (NumThreads < 1)
- NumThreads = 1;
- if (NumThreads > kNumThreadsMax)
- NumThreads = kNumThreadsMax;
+ MtMode = (numThreads > 1);
+
+ #ifndef BZIP2_BYTE_MODE
+ MtMode = false;
+ #endif
+
+ // MtMode = false;
return S_OK;
}
#endif
-HRESULT CDecoder::SetRatioProgress(UInt64 packSize)
-{
- if (!Progress)
- return S_OK;
- packSize -= _inStart;
- UInt64 unpackSize = m_OutStream.GetProcessedSize();
- return Progress->SetRatioInfo(&packSize, &unpackSize);
-}
-// ---------- NSIS ----------
+#ifndef NO_READ_FROM_CODER
-enum
-{
- NSIS_STATE_INIT,
- NSIS_STATE_NEW_BLOCK,
- NSIS_STATE_DATA,
- NSIS_STATE_FINISHED,
- NSIS_STATE_ERROR
-};
-STDMETHODIMP CNsisDecoder::SetInStream(ISequentialInStream *inStream)
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
{
Base.InStreamRef = inStream;
- Base.BitDecoder.SetStream(inStream);
+ Base.InStream = inStream;
return S_OK;
}
-STDMETHODIMP CNsisDecoder::ReleaseInStream()
+
+
+STDMETHODIMP CDecoder::ReleaseInStream()
{
Base.InStreamRef.Release();
+ Base.InStream = NULL;
return S_OK;
}
-STDMETHODIMP CNsisDecoder::SetOutStreamSize(const UInt64 * /* outSize */)
+
+
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
- _nsisState = NSIS_STATE_INIT;
+ InitOutSize(outSize);
+
+ if (!CreateInputBufer())
+ return E_OUTOFMEMORY;
+
+ InitInputBuffer();
+
+ StartNewStream();
+
+ _blockFinished = true;
+
+ ErrorResult = S_OK;
+
+ _inputFinished = false;
+ _inputRes = S_OK;
+
return S_OK;
}
-STDMETHODIMP CNsisDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
-{
- try {
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
*processedSize = 0;
- if (_nsisState == NSIS_STATE_FINISHED)
- return S_OK;
- if (_nsisState == NSIS_STATE_ERROR)
- return S_FALSE;
- if (size == 0)
- return S_OK;
- CState &state = m_State;
+ try {
- if (_nsisState == NSIS_STATE_INIT)
- {
- if (!Base.BitDecoder.Create(kBufferSize))
- return E_OUTOFMEMORY;
- if (!state.Alloc())
- return E_OUTOFMEMORY;
- Base.BitDecoder.Init();
- _nsisState = NSIS_STATE_NEW_BLOCK;
- }
+ if (ErrorResult != S_OK)
+ return ErrorResult;
- if (_nsisState == NSIS_STATE_NEW_BLOCK)
+ for (;;)
{
- Byte b = (Byte)Base.ReadBits(8);
- if (b == kFinSig0)
+ if (Base.state == STATE_STREAM_FINISHED)
+ {
+ if (!Base.DecodeAllStreams)
+ return ErrorResult;
+ StartNewStream();
+ continue;
+ }
+
+ if (Base.state == STATE_STREAM_SIGNATURE)
{
- _nsisState = NSIS_STATE_FINISHED;
+ ErrorResult = ReadStreamSignature();
+
+ if (Base.NeedMoreInput)
+ if (Base.state2 == 0 && Base.NumStreams != 0)
+ {
+ Base.NeedMoreInput = false;
+ ErrorResult = S_OK;
+ return S_OK;
+ }
+ if (ErrorResult != S_OK)
+ return ErrorResult;
+ continue;
+ }
+
+ if (_blockFinished && Base.state == STATE_BLOCK_SIGNATURE)
+ {
+ ErrorResult = ReadBlockSignature();
+
+ if (ErrorResult != S_OK)
+ return ErrorResult;
+
+ continue;
+ }
+
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _outPosTotal;
+ if (size >= rem)
+ size = (UInt32)rem;
+ }
+ if (size == 0)
return S_OK;
+
+ if (_blockFinished)
+ {
+ if (Base.state != STATE_BLOCK_START)
+ {
+ ErrorResult = E_FAIL;
+ return ErrorResult;
+ }
+
+ Base.Props.randMode = 1;
+ ErrorResult = ReadBlock();
+
+ if (ErrorResult != S_OK)
+ return ErrorResult;
+
+ DecodeBlock1(_counters, Base.Props.blockSize);
+
+ _spec._blockSize = Base.Props.blockSize;
+ _spec._tt = _counters + 256;
+ _spec.Init(Base.Props.origPtr, Base.Props.randMode);
+
+ _blockFinished = false;
}
- if (b != kBlockSig0)
+
{
- _nsisState = NSIS_STATE_ERROR;
- return S_FALSE;
+ Byte *ptr = _spec.Decode((Byte *)data, size);
+
+ const UInt32 processed = (UInt32)(ptr - (Byte *)data);
+ data = ptr;
+ size -= processed;
+ (*processedSize) += processed;
+ _outPosTotal += processed;
+
+ if (_spec.Finished())
+ {
+ _blockFinished = true;
+ if (Base.crc != _spec._crc.GetDigest())
+ {
+ BlockCrcError = true;
+ ErrorResult = S_FALSE;
+ return ErrorResult;
+ }
+ }
}
- CBlockProps props;
- props.randMode = false;
- RINOK(Base.ReadBlock(state.Counters, 9 * kBlockSizeStep, &props));
- _blockSize = props.blockSize;
- DecodeBlock1(state.Counters, props.blockSize);
- const UInt32 *tt = state.Counters + 256;
- _tPos = tt[tt[props.origPtr] >> 8];
- _prevByte = (unsigned)(_tPos & 0xFF);
- _numReps = 0;
- _repRem = 0;
- _nsisState = NSIS_STATE_DATA;
}
- UInt32 tPos = _tPos;
- unsigned prevByte = _prevByte;
- unsigned numReps = _numReps;
- UInt32 blockSize = _blockSize;
- const UInt32 *tt = state.Counters + 256;
+ } catch(...) { ErrorResult = S_FALSE; return S_FALSE; }
+}
- while (_repRem)
- {
- _repRem--;
- *(Byte *)data = (Byte)prevByte;
- data = (Byte *)data + 1;
- (*processedSize)++;
- if (--size == 0)
- return S_OK;
- }
- if (blockSize == 0)
- {
- _nsisState = NSIS_STATE_NEW_BLOCK;
+
+// ---------- NSIS ----------
+
+STDMETHODIMP CNsisDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ *processedSize = 0;
+
+ try {
+
+ if (ErrorResult != S_OK)
+ return ErrorResult;
+
+ if (Base.state == STATE_STREAM_FINISHED)
return S_OK;
+
+ if (Base.state == STATE_STREAM_SIGNATURE)
+ {
+ Base.blockSizeMax = 9 * kBlockSizeStep;
+ Base.state = STATE_BLOCK_SIGNATURE;
+ // Base.state2 = 0;
}
- do
+ for (;;)
{
- unsigned b = (unsigned)(tPos & 0xFF);
- tPos = tt[tPos >> 8];
- blockSize--;
+ if (_blockFinished && Base.state == STATE_BLOCK_SIGNATURE)
+ {
+ ErrorResult = ReadInput();
+ if (ErrorResult != S_OK)
+ return ErrorResult;
+
+ int b;
+ Base.ReadByte(b);
+ if (b < 0)
+ {
+ ErrorResult = S_FALSE;
+ return ErrorResult;
+ }
+
+ if (b == kFinSig0)
+ {
+ /*
+ if (!Base.AreRemainByteBitsEmpty())
+ ErrorResult = S_FALSE;
+ */
+ Base.state = STATE_STREAM_FINISHED;
+ return ErrorResult;
+ }
+
+ if (b != kBlockSig0)
+ {
+ ErrorResult = S_FALSE;
+ return ErrorResult;
+ }
+
+ Base.state = STATE_BLOCK_START;
+ }
+
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _outPosTotal;
+ if (size >= rem)
+ size = (UInt32)rem;
+ }
+ if (size == 0)
+ return S_OK;
- if (numReps == kRleModeRepSize)
+ if (_blockFinished)
{
- numReps = 0;
- while (b)
+ if (Base.state != STATE_BLOCK_START)
{
- b--;
- *(Byte *)data = (Byte)prevByte;
- data = (Byte *)data + 1;
- (*processedSize)++;
- if (--size == 0)
- break;
+ ErrorResult = E_FAIL;
+ return ErrorResult;
}
- _repRem = b;
- continue;
+
+ Base.Props.randMode = 0;
+ ErrorResult = ReadBlock();
+
+ if (ErrorResult != S_OK)
+ return ErrorResult;
+
+ DecodeBlock1(_counters, Base.Props.blockSize);
+
+ _spec._blockSize = Base.Props.blockSize;
+ _spec._tt = _counters + 256;
+ _spec.Init(Base.Props.origPtr, Base.Props.randMode);
+
+ _blockFinished = false;
+ }
+
+ {
+ Byte *ptr = _spec.Decode((Byte *)data, size);
+
+ const UInt32 processed = (UInt32)(ptr - (Byte *)data);
+ data = ptr;
+ size -= processed;
+ (*processedSize) += processed;
+ _outPosTotal += processed;
+
+ if (_spec.Finished())
+ _blockFinished = true;
}
- if (b != prevByte)
- numReps = 0;
- numReps++;
- prevByte = b;
- *(Byte *)data = (Byte)b;
- data = (Byte *)data + 1;
- (*processedSize)++;
- size--;
}
- while (size && blockSize);
- _tPos = tPos;
- _prevByte = prevByte;
- _numReps = numReps;
- _blockSize = blockSize;
- return S_OK;
- }
- catch(const CInBufferException &e) { return e.ErrorCode; }
- catch(...) { return S_FALSE; }
+ } catch(...) { ErrorResult = S_FALSE; return S_FALSE; }
}
+#endif
+
}}
diff --git a/CPP/7zip/Compress/BZip2Decoder.h b/CPP/7zip/Compress/BZip2Decoder.h
index 8703d572..68aa7094 100644
--- a/CPP/7zip/Compress/BZip2Decoder.h
+++ b/CPP/7zip/Compress/BZip2Decoder.h
@@ -5,6 +5,9 @@
#include "../../Common/MyCom.h"
+// #define NO_READ_FROM_CODER
+// #define _7ZIP_ST
+
#ifndef _7ZIP_ST
#include "../../Windows/Synchronization.h"
#include "../../Windows/Thread.h"
@@ -12,13 +15,10 @@
#include "../ICoder.h"
-#include "../Common/InBuffer.h"
-#include "../Common/OutBuffer.h"
-
-#include "BitmDecoder.h"
#include "BZip2Const.h"
#include "BZip2Crc.h"
#include "HuffmanDecoder.h"
+#include "Mtf8.h"
namespace NCompress {
namespace NBZip2 {
@@ -26,154 +26,311 @@ namespace NBZip2 {
bool IsEndSig(const Byte *p) throw();
bool IsBlockSig(const Byte *p) throw();
-typedef NCompress::NHuffman::CDecoder<kMaxHuffmanLen, kMaxAlphaSize> CHuffmanDecoder;
+const unsigned kNumTableBits = 9;
+const unsigned kNumBitsMax = kMaxHuffmanLen;
-class CDecoder;
+typedef NHuffman::CDecoder<kMaxHuffmanLen, kMaxAlphaSize, kNumTableBits> CHuffmanDecoder;
-struct CState
-{
- UInt32 *Counters;
- #ifndef _7ZIP_ST
-
- CDecoder *Decoder;
- NWindows::CThread Thread;
- bool m_OptimizeNumTables;
+struct CBlockProps
+{
+ UInt32 blockSize;
+ UInt32 origPtr;
+ unsigned randMode;
+
+ CBlockProps(): blockSize(0), origPtr(0), randMode(0) {}
+};
- NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent;
- NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent;
- // it's not member of this thread. We just need one event per thread
- NWindows::NSynchronization::CAutoResetEvent CanWriteEvent;
+struct CBitDecoder
+{
+ unsigned _numBits;
+ UInt32 _value;
+ const Byte *_buf;
+ const Byte *_lim;
- Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
+ void InitBitDecoder()
+ {
+ _numBits = 0;
+ _value = 0;
+ }
- HRESULT Create();
- void FinishStream();
- void ThreadFunc();
+ void AlignToByte()
+ {
+ unsigned bits = _numBits & 7;
+ _numBits -= bits;
+ _value <<= bits;
+ }
- #endif
+ /*
+ bool AreRemainByteBitsEmpty() const
+ {
+ unsigned bits = _numBits & 7;
+ if (bits != 0)
+ return (_value >> (32 - bits)) == 0;
+ return true;
+ }
+ */
- CState(): Counters(0) {}
- ~CState() { Free(); }
- bool Alloc();
- void Free();
+ SRes ReadByte(int &b);
};
-struct CBlockProps
+
+struct CBase: public CBitDecoder
{
+ unsigned numInUse;
+ UInt32 groupIndex;
+ UInt32 groupSize;
+ unsigned runPower;
+ UInt32 runCounter;
UInt32 blockSize;
- UInt32 origPtr;
- bool randMode;
-
- CBlockProps(): blockSize(0), origPtr(0), randMode(false) {}
-};
-struct CBase
-{
- CMyComPtr<ISequentialInStream> InStreamRef;
- NBitm::CDecoder<CInBuffer> BitDecoder;
+ UInt32 *Counters;
+ UInt32 blockSizeMax;
+
+ unsigned state;
+ unsigned state2;
+ unsigned state3;
+ unsigned state4;
+ unsigned state5;
+ unsigned numTables;
+ UInt32 numSelectors;
+
+ CBlockProps Props;
private:
- Byte m_Selectors[kNumSelectorsMax];
- CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax];
+ CMtf8Decoder mtf;
+ Byte selectors[kNumSelectorsMax];
+ CHuffmanDecoder huffs[kNumTablesMax];
+
+ Byte lens[kMaxAlphaSize];
+
+ Byte temp[10];
public:
+ UInt32 crc;
+ CBZip2CombinedCrc CombinedCrc;
+
+ bool IsBz;
+ bool StreamCrcError;
+ bool MinorError;
+ bool NeedMoreInput;
+
+ bool DecodeAllStreams;
+
+ UInt64 NumStreams;
UInt64 NumBlocks;
+ UInt64 FinishedPackSize;
- CBase(): NumBlocks(0) {}
- UInt32 ReadBits(unsigned numBits);
- unsigned ReadBit();
- void InitNumBlocks() { NumBlocks = 0; }
+ ISequentialInStream *InStream;
- /*
- ReadBlock() props->randMode:
- in: need read randMode bit,
- out: randMode status
- */
- HRESULT ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps *props);
+ #ifndef NO_READ_FROM_CODER
+ CMyComPtr<ISequentialInStream> InStreamRef;
+ #endif
+
+ CBase():
+ StreamCrcError(false),
+ MinorError(false),
+ NeedMoreInput(false),
+
+ DecodeAllStreams(false),
+
+ NumStreams(0),
+ NumBlocks(0),
+ FinishedPackSize(0)
+ {}
+
+ void InitNumStreams2()
+ {
+ StreamCrcError = false;
+ MinorError = false;
+ NeedMoreInput = 0;
+ NumStreams = 0;
+ NumBlocks = 0;
+ FinishedPackSize = 0;
+ }
+
+ SRes ReadStreamSignature2();
+ SRes ReadBlockSignature2();
+
+ /* ReadBlock2() : Props->randMode:
+ in: need read randMode bit
+ out: randMode status */
+ SRes ReadBlock2();
+};
+
+
+class CSpecState
+{
+ UInt32 _tPos;
+ unsigned _prevByte;
+ int _reps;
+
+public:
+ CBZip2Crc _crc;
+ UInt32 _blockSize;
+ UInt32 *_tt;
+
+ int _randToGo;
+ unsigned _randIndex;
+
+ void Init(UInt32 origPtr, unsigned randMode) throw();
+
+ bool Finished() const { return _reps <= 0 && _blockSize == 0; }
+
+ Byte *Decode(Byte *data, size_t size) throw();
};
+
+
+
class CDecoder :
public ICompressCoder,
+ public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
+
+ #ifndef NO_READ_FROM_CODER
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
+
#ifndef _7ZIP_ST
public ICompressSetCoderMt,
#endif
+
public CMyUnknownImp
{
+ Byte *_outBuf;
+ size_t _outPos;
+ UInt64 _outWritten;
+ ISequentialOutStream *_outStream;
+ HRESULT _writeRes;
+
+protected:
+ HRESULT ErrorResult; // for ISequentialInStream::Read mode only
+
public:
- COutBuffer m_OutStream;
- Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
- CBase Base;
+ UInt32 _calcedBlockCrc;
+ bool _blockFinished;
+ bool BlockCrcError;
- UInt64 _inStart;
+ bool FinishMode;
+ bool _outSizeDefined;
+ UInt64 _outSize;
+ UInt64 _outPosTotal;
-private:
+ CSpecState _spec;
+ UInt32 *_counters;
- bool _needInStreamInit;
+ #ifndef _7ZIP_ST
- Byte ReadByte();
+ struct CBlock
+ {
+ bool StopScout;
+
+ bool WasFinished;
+ bool Crc_Defined;
+ // bool NextCrc_Defined;
+
+ UInt32 Crc;
+ UInt32 NextCrc;
+ HRESULT Res;
+ UInt64 PackPos;
+
+ CBlockProps Props;
+ };
+
+ CBlock _block;
+
+ bool NeedWaitScout;
+ bool MtMode;
- HRESULT DecodeFile(ICompressProgressInfo *progress);
- HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
+ NWindows::CThread Thread;
+ NWindows::NSynchronization::CAutoResetEvent DecoderEvent;
+ NWindows::NSynchronization::CAutoResetEvent ScoutEvent;
+ // HRESULT ScoutRes;
- class CDecoderFlusher
+ Byte MtPad[1 << 7]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
+
+
+ void RunScout();
+
+ void WaitScout()
{
- CDecoder *_decoder;
- public:
- bool NeedFlush;
- CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
- ~CDecoderFlusher()
+ if (NeedWaitScout)
{
- if (NeedFlush)
- _decoder->Flush();
+ DecoderEvent.Lock();
+ NeedWaitScout = false;
}
+ }
+
+ class CWaitScout_Releaser
+ {
+ CDecoder *_decoder;
+ public:
+ CWaitScout_Releaser(CDecoder *decoder): _decoder(decoder) {}
+ ~CWaitScout_Releaser() { _decoder->WaitScout(); }
};
-public:
- CBZip2CombinedCrc CombinedCrc;
- ICompressProgressInfo *Progress;
+ HRESULT CreateThread();
- #ifndef _7ZIP_ST
- CState *m_States;
- UInt32 m_NumThreadsPrev;
+ #endif
- NWindows::NSynchronization::CManualResetEvent CanProcessEvent;
- NWindows::NSynchronization::CCriticalSection CS;
- UInt32 NumThreads;
- bool MtMode;
- UInt32 NextBlockIndex;
- bool CloseThreads;
- bool StreamWasFinished1;
- bool StreamWasFinished2;
- NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent;
+ Byte *_inBuf;
+ UInt64 _inProcessed;
+ bool _inputFinished;
+ HRESULT _inputRes;
- HRESULT Result1;
- HRESULT Result2;
+ CBase Base;
- UInt32 BlockSizeMax;
+ bool GetCrcError() const { return BlockCrcError || Base.StreamCrcError; }
- ~CDecoder();
- HRESULT Create();
- void Free();
+ void InitOutSize(const UInt64 *outSize);
+
+ bool CreateInputBufer();
- #else
- CState m_States[1];
- #endif
+ void InitInputBuffer()
+ {
+ _inProcessed = 0;
+ Base._buf = _inBuf;
+ Base._lim = _inBuf;
+ Base.InitBitDecoder();
+ }
- bool IsBz;
- bool BzWasFinished; // bzip stream was finished with end signature
- bool CrcError; // it can CRC error of block or CRC error of whole stream.
+ UInt64 GetInputProcessedSize() const
+ {
+ // for NSIS case : we need also look the number of bits in bitDecoder
+ return _inProcessed + (Base._buf - _inBuf);
+ }
- CDecoder();
+ UInt64 GetOutProcessedSize() const { return _outWritten + _outPos; }
+
+ HRESULT ReadInput();
- HRESULT SetRatioProgress(UInt64 packSize);
- HRESULT ReadSignature(UInt32 &crc);
+ void StartNewStream();
+
+ HRESULT ReadStreamSignature();
+ HRESULT StartRead();
- HRESULT Flush() { return m_OutStream.Flush(); }
+ HRESULT ReadBlockSignature();
+ HRESULT ReadBlock();
+
+ HRESULT Flush();
+ HRESULT DecodeBlock(const CBlockProps &props);
+ HRESULT DecodeStreams(ICompressProgressInfo *progress);
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
+ MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
+
+ #ifndef NO_READ_FROM_CODER
+ MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
+ MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
+ #endif
+
#ifndef _7ZIP_ST
MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)
#endif
@@ -185,54 +342,41 @@ public:
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+ UInt64 GetNumStreams() const { return Base.NumStreams; }
+ UInt64 GetNumBlocks() const { return Base.NumBlocks; }
+
+ #ifndef NO_READ_FROM_CODER
+
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- HRESULT CodeResume(ISequentialOutStream *outStream, ICompressProgressInfo *progress);
-
- UInt64 GetStreamSize() const { return Base.BitDecoder.GetStreamSize(); }
- UInt64 GetInputProcessedSize() const { return Base.BitDecoder.GetProcessedSize(); }
+ #endif
- void InitNumBlocks() { Base.InitNumBlocks(); }
- UInt64 GetNumBlocks() const { return Base.NumBlocks; }
-
#ifndef _7ZIP_ST
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
#endif
+
+ CDecoder();
+ ~CDecoder();
};
-class CNsisDecoder :
- public ISequentialInStream,
- public ICompressSetInStream,
- public ICompressSetOutStreamSize,
- public CMyUnknownImp
-{
- CBase Base;
- CState m_State;
-
- int _nsisState;
- UInt32 _tPos;
- unsigned _prevByte;
- unsigned _repRem;
- unsigned _numReps;
- UInt32 _blockSize;
+#ifndef NO_READ_FROM_CODER
+class CNsisDecoder : public CDecoder
+{
public:
-
- MY_QUERYINTERFACE_BEGIN2(ISequentialInStream)
- MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
- MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
- MY_QUERYINTERFACE_END
- MY_ADDREF_RELEASE
-
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(SetInStream)(ISequentialInStream *inStream);
- STDMETHOD(ReleaseInStream)();
- STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
};
+#endif
+
}}
#endif
diff --git a/CPP/7zip/Compress/BZip2Encoder.cpp b/CPP/7zip/Compress/BZip2Encoder.cpp
index e2225134..c9f9c664 100644
--- a/CPP/7zip/Compress/BZip2Encoder.cpp
+++ b/CPP/7zip/Compress/BZip2Encoder.cpp
@@ -337,7 +337,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize)
}
else
mtfs[mtfArraySize++] = (Byte)(pos + 1);
- symbolCounts[pos + 1]++;
+ symbolCounts[(size_t)pos + 1]++;
}
}
while (++i < blockSize);
@@ -357,7 +357,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize)
mtfs[mtfArraySize++] = 0xFF;
mtfs[mtfArraySize++] = (Byte)(alphaSize - 256);
}
- symbolCounts[alphaSize - 1]++;
+ symbolCounts[(size_t)alphaSize - 1]++;
}
UInt32 numSymbols = 0;
@@ -412,7 +412,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize)
if (ge > gs + 1 && t != numTables && t != 1 && (((numTables - t) & 1) == 1))
aFreq -= symbolCounts[--ge];
- Byte *lens = Lens[t - 1];
+ Byte *lens = Lens[(size_t)t - 1];
unsigned i = 0;
do
lens[i] = (Byte)((i >= gs && i < ge) ? 0 : 1);
@@ -507,7 +507,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize)
WriteBit2(1);
WriteBit2(0);
for (; pos > 0; pos--)
- mtfSel[pos] = mtfSel[pos - 1];
+ mtfSel[pos] = mtfSel[(size_t)pos - 1];
mtfSel[0] = sel;
}
while (++i < numSelectors);
@@ -634,10 +634,13 @@ void CThreadInfo::EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPa
UInt32 endPos = 0;
if (numPasses > 1 && blockSize >= (1 << 10))
{
- UInt32 blockSize0 = blockSize / 2;
- for (;(block[blockSize0] == block[blockSize0 - 1] ||
- block[blockSize0 - 1] == block[blockSize0 - 2]) &&
- blockSize0 < blockSize; blockSize0++);
+ UInt32 blockSize0 = blockSize / 2; // ????
+
+ for (; (block[blockSize0] == block[(size_t)blockSize0 - 1]
+ || block[(size_t)blockSize0 - 1] == block[(size_t)blockSize0 - 2])
+ && blockSize0 < blockSize;
+ blockSize0++);
+
if (blockSize0 < blockSize)
{
EncodeBlock2(block, blockSize0, numPasses - 1);
diff --git a/CPP/7zip/Compress/Bcj2Coder.cpp b/CPP/7zip/Compress/Bcj2Coder.cpp
index 96150c5f..4906e78c 100644
--- a/CPP/7zip/Compress/Bcj2Coder.cpp
+++ b/CPP/7zip/Compress/Bcj2Coder.cpp
@@ -463,10 +463,10 @@ HRESULT CDecoder::Code(ISequentialInStream * const *inStreams, const UInt64 * co
if (progress)
{
- UInt64 outSize2 = outSizeProcessed + (dec.dest - _bufs[BCJ2_NUM_STREAMS]);
+ const UInt64 outSize2 = outSizeProcessed + (dec.dest - _bufs[BCJ2_NUM_STREAMS]);
if (outSize2 - prevProgress >= (1 << 22))
{
- UInt64 inSize2 = outSize2 + _inStreamsProcessed[BCJ2_STREAM_RC] - (dec.lims[BCJ2_STREAM_RC] - dec.bufs[BCJ2_STREAM_RC]);
+ const UInt64 inSize2 = outSize2 + _inStreamsProcessed[BCJ2_STREAM_RC] - (dec.lims[BCJ2_STREAM_RC] - dec.bufs[BCJ2_STREAM_RC]);
RINOK(progress->SetRatioInfo(&inSize2, &outSize2));
prevProgress = outSize2;
}
@@ -655,4 +655,12 @@ STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
return res;
}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value)
+{
+ const size_t rem = dec.lims[streamIndex] - dec.bufs[streamIndex] + _extraReadSizes[streamIndex];
+ *value = _inStreamsProcessed[streamIndex] - rem;
+ return S_OK;
+}
+
}}
diff --git a/CPP/7zip/Compress/Bcj2Coder.h b/CPP/7zip/Compress/Bcj2Coder.h
index 381b9f54..ca6a1e4e 100644
--- a/CPP/7zip/Compress/Bcj2Coder.h
+++ b/CPP/7zip/Compress/Bcj2Coder.h
@@ -62,6 +62,7 @@ public:
class CDecoder:
public ICompressCoder2,
public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize2,
public ICompressSetInStream2,
public ISequentialInStream,
public ICompressSetOutStreamSize,
@@ -84,9 +85,10 @@ class CDecoder:
// HRESULT ReadSpec();
public:
- MY_UNKNOWN_IMP6(
+ MY_UNKNOWN_IMP7(
ICompressCoder2,
ICompressSetFinishMode,
+ ICompressGetInStreamProcessedSize2,
ICompressSetInStream2,
ISequentialInStream,
ICompressSetOutStreamSize,
@@ -98,6 +100,7 @@ public:
ICompressProgressInfo *progress);
STDMETHOD(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize2)(UInt32 streamIndex, UInt64 *value);
STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream2)(UInt32 streamIndex);
diff --git a/CPP/7zip/Compress/BitlDecoder.h b/CPP/7zip/Compress/BitlDecoder.h
index 41e22fe7..f3b8248f 100644
--- a/CPP/7zip/Compress/BitlDecoder.h
+++ b/CPP/7zip/Compress/BitlDecoder.h
@@ -42,13 +42,15 @@ public:
UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() - ((kNumBigValueBits - _bitPos) >> 3); }
bool ThereAreDataInBitsBuffer() const { return this->_bitPos != kNumBigValueBits; }
-
+
+ MY_FORCE_INLINE
void Normalize()
{
for (; _bitPos >= 8; _bitPos -= 8)
_value = ((UInt32)_stream.ReadByte() << (kNumBigValueBits - _bitPos)) | _value;
}
+ MY_FORCE_INLINE
UInt32 ReadBits(unsigned numBits)
{
Normalize();
@@ -88,7 +90,8 @@ public:
CBaseDecoder<TInByte>::Init();
_normalValue = 0;
}
-
+
+ MY_FORCE_INLINE
void Normalize()
{
for (; this->_bitPos >= 8; this->_bitPos -= 8)
@@ -99,18 +102,21 @@ public:
}
}
+ MY_FORCE_INLINE
UInt32 GetValue(unsigned numBits)
{
Normalize();
return ((this->_value >> (8 - this->_bitPos)) & kMask) >> (kNumValueBits - numBits);
}
-
+
+ MY_FORCE_INLINE
void MovePos(unsigned numBits)
{
this->_bitPos += numBits;
_normalValue >>= numBits;
}
+ MY_FORCE_INLINE
UInt32 ReadBits(unsigned numBits)
{
Normalize();
@@ -120,9 +126,11 @@ public:
}
void AlignToByte() { MovePos((32 - this->_bitPos) & 7); }
-
+
+ MY_FORCE_INLINE
Byte ReadDirectByte() { return this->_stream.ReadByte(); }
-
+
+ MY_FORCE_INLINE
Byte ReadAlignedByte()
{
if (this->_bitPos == kNumBigValueBits)
diff --git a/CPP/7zip/Compress/BitmDecoder.h b/CPP/7zip/Compress/BitmDecoder.h
index 9b1c540e..9ce41bd1 100644
--- a/CPP/7zip/Compress/BitmDecoder.h
+++ b/CPP/7zip/Compress/BitmDecoder.h
@@ -46,25 +46,29 @@ public:
{
return (_stream.NumExtraBytes > 4);
}
-
+
+ MY_FORCE_INLINE
void Normalize()
{
for (; _bitPos >= 8; _bitPos -= 8)
_value = (_value << 8) | _stream.ReadByte();
}
+ MY_FORCE_INLINE
UInt32 GetValue(unsigned numBits) const
{
// return (_value << _bitPos) >> (kNumBigValueBits - numBits);
return ((_value >> (8 - _bitPos)) & kMask) >> (kNumValueBits - numBits);
}
-
+
+ MY_FORCE_INLINE
void MovePos(unsigned numBits)
{
_bitPos += numBits;
Normalize();
}
-
+
+ MY_FORCE_INLINE
UInt32 ReadBits(unsigned numBits)
{
UInt32 res = GetValue(numBits);
@@ -87,6 +91,7 @@ public:
void AlignToByte() { MovePos((kNumBigValueBits - _bitPos) & 7); }
+ MY_FORCE_INLINE
UInt32 ReadAlignBits() { return ReadBits((kNumBigValueBits - _bitPos) & 7); }
};
diff --git a/CPP/7zip/Compress/CopyCoder.cpp b/CPP/7zip/Compress/CopyCoder.cpp
index ac6ab2e7..d8487ad5 100644
--- a/CPP/7zip/Compress/CopyCoder.cpp
+++ b/CPP/7zip/Compress/CopyCoder.cpp
@@ -15,6 +15,11 @@ CCopyCoder::~CCopyCoder()
::MidFree(_buf);
}
+STDMETHODIMP CCopyCoder::SetFinishMode(UInt32 /* finishMode */)
+{
+ return S_OK;
+}
+
STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize,
diff --git a/CPP/7zip/Compress/CopyCoder.h b/CPP/7zip/Compress/CopyCoder.h
index a21c0988..a9d0b6db 100644
--- a/CPP/7zip/Compress/CopyCoder.h
+++ b/CPP/7zip/Compress/CopyCoder.h
@@ -13,6 +13,7 @@ class CCopyCoder:
public ICompressCoder,
public ICompressSetInStream,
public ISequentialInStream,
+ public ICompressSetFinishMode,
public ICompressGetInStreamProcessedSize,
public CMyUnknownImp
{
@@ -24,10 +25,11 @@ public:
CCopyCoder(): _buf(0), TotalSize(0) {};
~CCopyCoder();
- MY_UNKNOWN_IMP4(
+ MY_UNKNOWN_IMP5(
ICompressCoder,
ICompressSetInStream,
ISequentialInStream,
+ ICompressSetFinishMode,
ICompressGetInStreamProcessedSize)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
@@ -35,6 +37,7 @@ public:
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(SetFinishMode)(UInt32 finishMode);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
};
diff --git a/CPP/7zip/Compress/DeflateDecoder.cpp b/CPP/7zip/Compress/DeflateDecoder.cpp
index 60c9aea6..88ab1f91 100644
--- a/CPP/7zip/Compress/DeflateDecoder.cpp
+++ b/CPP/7zip/Compress/DeflateDecoder.cpp
@@ -14,6 +14,8 @@ CCoder::CCoder(bool deflate64Mode):
_keepHistory(false),
_needFinishInput(false),
_needInitInStream(true),
+ _outSizeDefined(false),
+ _outStartPos(0),
ZlibMode(false) {}
UInt32 CCoder::ReadBits(unsigned numBits)
@@ -50,7 +52,7 @@ bool CCoder::DecodeLevels(Byte *levels, unsigned numSymbols)
return false;
numBits = 2;
num = 0;
- symbol = levels[i - 1];
+ symbol = levels[(size_t)i - 1];
}
else
{
@@ -145,10 +147,28 @@ bool CCoder::ReadTables(void)
return m_DistDecoder.Build(levels.distLevels);
}
-HRESULT CCoder::CodeSpec(UInt32 curSize, bool finishInputStream)
+
+HRESULT CCoder::InitInStream(bool needInit)
+{
+ if (needInit)
+ {
+ // for HDD-Windows:
+ // (1 << 15) - best for reading only prefetch
+ // (1 << 22) - best for real reading / writing
+ if (!m_InBitStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ m_InBitStream.Init();
+ _needInitInStream = false;
+ }
+ return S_OK;
+}
+
+
+HRESULT CCoder::CodeSpec(UInt32 curSize, bool finishInputStream, UInt32 inputProgressLimit)
{
if (_remainLen == kLenIdFinished)
return S_OK;
+
if (_remainLen == kLenIdNeedInit)
{
if (!_keepHistory)
@@ -156,6 +176,7 @@ HRESULT CCoder::CodeSpec(UInt32 curSize, bool finishInputStream)
return E_OUTOFMEMORY;
RINOK(InitInStream(_needInitInStream));
m_OutWindowStream.Init(_keepHistory);
+
m_FinalBlock = false;
_remainLen = 0;
_needReadTable = true;
@@ -169,6 +190,10 @@ HRESULT CCoder::CodeSpec(UInt32 curSize, bool finishInputStream)
curSize--;
}
+ UInt64 inputStart = 0;
+ if (inputProgressLimit != 0)
+ inputStart = m_InBitStream.GetProcessedSize();
+
while (curSize > 0 || finishInputStream)
{
if (m_InBitStream.ExtraBitsWereRead())
@@ -181,6 +206,11 @@ HRESULT CCoder::CodeSpec(UInt32 curSize, bool finishInputStream)
_remainLen = kLenIdFinished;
break;
}
+
+ if (inputProgressLimit != 0)
+ if (m_InBitStream.GetProcessedSize() - inputStart >= inputProgressLimit)
+ return S_OK;
+
if (!ReadTables())
return S_FALSE;
if (m_InBitStream.ExtraBitsWereRead())
@@ -284,31 +314,34 @@ HRESULT CCoder::CodeSpec(UInt32 curSize, bool finishInputStream)
#define DEFLATE_TRY_BEGIN try {
#define DEFLATE_TRY_END(res) } \
- catch(const CInBufferException &e) { res = e.ErrorCode; } \
- catch(const CLzOutWindowException &e) { res = e.ErrorCode; } \
+ catch(const CSystemException &e) { res = e.ErrorCode; } \
catch(...) { res = S_FALSE; }
+ // catch(const CInBufferException &e) { res = e.ErrorCode; }
+ // catch(const CLzOutWindowException &e) { res = e.ErrorCode; }
+
#endif
-HRESULT CCoder::CodeReal(ISequentialOutStream *outStream,
- const UInt64 *outSize, ICompressProgressInfo *progress)
+HRESULT CCoder::CodeReal(ISequentialOutStream *outStream, ICompressProgressInfo *progress)
{
HRESULT res;
+
DEFLATE_TRY_BEGIN
+
m_OutWindowStream.SetStream(outStream);
CCoderReleaser flusher(this);
const UInt64 inStart = _needInitInStream ? 0 : m_InBitStream.GetProcessedSize();
- const UInt64 start = m_OutWindowStream.GetProcessedSize();
for (;;)
{
- UInt32 curSize = 1 << 18;
+ const UInt32 kInputProgressLimit = 1 << 21;
+ UInt32 curSize = 1 << 20;
bool finishInputStream = false;
- if (outSize)
+ if (_outSizeDefined)
{
- const UInt64 rem = *outSize - (m_OutWindowStream.GetProcessedSize() - start);
+ const UInt64 rem = _outSize - GetOutProcessedCur();
if (curSize >= rem)
{
curSize = (UInt32)rem;
@@ -318,13 +351,16 @@ HRESULT CCoder::CodeReal(ISequentialOutStream *outStream,
}
if (!finishInputStream && curSize == 0)
break;
- RINOK(CodeSpec(curSize, finishInputStream));
+
+ RINOK(CodeSpec(curSize, finishInputStream, progress ? kInputProgressLimit : 0));
+
if (_remainLen == kLenIdFinished)
break;
+
if (progress)
{
const UInt64 inSize = m_InBitStream.GetProcessedSize() - inStart;
- const UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start;
+ const UInt64 nowPos64 = GetOutProcessedCur();
RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
}
}
@@ -340,20 +376,36 @@ HRESULT CCoder::CodeReal(ISequentialOutStream *outStream,
res = Flush();
if (res == S_OK && _remainLen != kLenIdNeedInit && InputEofError())
return S_FALSE;
+
DEFLATE_TRY_END(res)
+
return res;
}
+
HRESULT CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
{
SetInStream(inStream);
SetOutStreamSize(outSize);
- HRESULT res = CodeReal(outStream, outSize, progress);
+ HRESULT res = CodeReal(outStream, progress);
ReleaseInStream();
+ /*
+ if (res == S_OK)
+ if (_needFinishInput && inSize && *inSize != m_InBitStream.GetProcessedSize())
+ res = S_FALSE;
+ */
return res;
}
+
+STDMETHODIMP CCoder::SetFinishMode(UInt32 finishMode)
+{
+ Set_NeedFinishInput(finishMode != 0);
+ return S_OK;
+}
+
+
STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value)
{
if (!value)
@@ -362,6 +414,7 @@ STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value)
return S_OK;
}
+
STDMETHODIMP CCoder::SetInStream(ISequentialInStream *inStream)
{
m_InStreamRef = inStream;
@@ -369,49 +422,88 @@ STDMETHODIMP CCoder::SetInStream(ISequentialInStream *inStream)
return S_OK;
}
+
STDMETHODIMP CCoder::ReleaseInStream()
{
m_InStreamRef.Release();
return S_OK;
}
-STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 * /* outSize */)
+
+void CCoder::SetOutStreamSizeResume(const UInt64 *outSize)
{
+ _outSizeDefined = (outSize != NULL);
+ _outSize = 0;
+ if (_outSizeDefined)
+ _outSize = *outSize;
+
+ m_OutWindowStream.Init(_keepHistory);
+ _outStartPos = m_OutWindowStream.GetProcessedSize();
+
_remainLen = kLenIdNeedInit;
+}
+
+
+STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 *outSize)
+{
_needInitInStream = true;
- m_OutWindowStream.Init(_keepHistory);
+ SetOutStreamSizeResume(outSize);
return S_OK;
}
+
#ifndef NO_READ_FROM_CODER
STDMETHODIMP CCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
HRESULT res;
- DEFLATE_TRY_BEGIN
+
if (processedSize)
*processedSize = 0;
- const UInt64 startPos = m_OutWindowStream.GetProcessedSize();
- m_OutWindowStream.SetMemStream((Byte *)data);
- res = CodeSpec(size, false);
- if (res == S_OK)
+ const UInt64 outPos = GetOutProcessedCur();
+
+ bool finishInputStream = false;
+ if (_outSizeDefined)
{
- res = Flush();
- if (processedSize)
- *processedSize = (UInt32)(m_OutWindowStream.GetProcessedSize() - startPos);
+ const UInt64 rem = _outSize - outPos;
+ if (size >= rem)
+ {
+ size = (UInt32)rem;
+ if (ZlibMode || _needFinishInput)
+ finishInputStream = true;
+ }
}
+ if (!finishInputStream && size == 0)
+ return S_OK;
+
+ DEFLATE_TRY_BEGIN
+
+ m_OutWindowStream.SetMemStream((Byte *)data);
+
+ res = CodeSpec(size, finishInputStream);
+
DEFLATE_TRY_END(res)
+
+ {
+ HRESULT res2 = Flush();
+ if (res2 != S_OK)
+ res = res2;
+ }
+
+ if (processedSize)
+ *processedSize = (UInt32)(GetOutProcessedCur() - outPos);
+
m_OutWindowStream.SetMemStream(NULL);
return res;
}
#endif
-STDMETHODIMP CCoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress)
+
+HRESULT CCoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress)
{
- _remainLen = kLenIdNeedInit;
- m_OutWindowStream.Init(_keepHistory);
- return CodeReal(outStream, outSize, progress);
+ SetOutStreamSizeResume(outSize);
+ return CodeReal(outStream, progress);
}
}}}
diff --git a/CPP/7zip/Compress/DeflateDecoder.h b/CPP/7zip/Compress/DeflateDecoder.h
index 09f84eb4..0a724247 100644
--- a/CPP/7zip/Compress/DeflateDecoder.h
+++ b/CPP/7zip/Compress/DeflateDecoder.h
@@ -23,6 +23,7 @@ const int kLenIdNeedInit = -2;
class CCoder:
public ICompressCoder,
+ public ICompressSetFinishMode,
public ICompressGetInStreamProcessedSize,
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
@@ -54,6 +55,13 @@ class CCoder:
Int32 _remainLen;
UInt32 _rep0;
+ bool _outSizeDefined;
+ UInt64 _outSize;
+ UInt64 _outStartPos;
+
+ void SetOutStreamSizeResume(const UInt64 *outSize);
+ UInt64 GetOutProcessedCur() const { return m_OutWindowStream.GetProcessedSize() - _outStartPos; }
+
UInt32 ReadBits(unsigned numBits);
bool DecodeLevels(Byte *levels, unsigned numSymbols);
@@ -74,7 +82,7 @@ class CCoder:
};
friend class CCoderReleaser;
- HRESULT CodeSpec(UInt32 curSize, bool finishInputStream);
+ HRESULT CodeSpec(UInt32 curSize, bool finishInputStream, UInt32 inputProgressLimit = 0);
public:
bool ZlibMode;
Byte ZlibFooter[4];
@@ -90,26 +98,28 @@ public:
bool IsFinished() const { return _remainLen == kLenIdFinished;; }
bool IsFinalBlock() const { return m_FinalBlock; }
- HRESULT CodeReal(ISequentialOutStream *outStream,
- const UInt64 *outSize, ICompressProgressInfo *progress);
+ HRESULT CodeReal(ISequentialOutStream *outStream, ICompressProgressInfo *progress);
+
+ MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
+ MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
#ifndef NO_READ_FROM_CODER
- MY_UNKNOWN_IMP5(
- ICompressCoder,
- ICompressGetInStreamProcessedSize,
- ICompressSetInStream,
- ICompressSetOutStreamSize,
- ISequentialInStream
- )
- #else
- MY_UNKNOWN_IMP2(
- ICompressCoder,
- 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(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
@@ -118,19 +128,9 @@ public:
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
#endif
- STDMETHOD(CodeResume)(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
+ HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
- HRESULT InitInStream(bool needInit)
- {
- if (!m_InBitStream.Create(1 << 17))
- return E_OUTOFMEMORY;
- if (needInit)
- {
- m_InBitStream.Init();
- _needInitInStream = false;
- }
- return S_OK;
- }
+ HRESULT InitInStream(bool needInit);
void AlignToByte() { m_InBitStream.AlignToByte(); }
Byte ReadAlignedByte();
@@ -143,9 +143,6 @@ public:
UInt64 GetStreamSize() const { return m_InBitStream.GetStreamSize(); }
UInt64 GetInputProcessedSize() const { return m_InBitStream.GetProcessedSize(); }
-
- // IGetInStreamProcessedSize
- STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
};
class CCOMCoder : public CCoder { public: CCOMCoder(): CCoder(false) {} };
diff --git a/CPP/7zip/Compress/DeflateEncoder.cpp b/CPP/7zip/Compress/DeflateEncoder.cpp
index 538e7b5e..7cf59cc0 100644
--- a/CPP/7zip/Compress/DeflateEncoder.cpp
+++ b/CPP/7zip/Compress/DeflateEncoder.cpp
@@ -7,6 +7,8 @@
#include "../../Common/ComTry.h"
+#include "../Common/CWrappers.h"
+
#include "DeflateEncoder.h"
#undef NO_INLINE
@@ -262,19 +264,19 @@ NO_INLINE void CCoder::GetMatches()
UInt32 i;
for (i = 0; i < numPairs; i += 2)
{
- m_MatchDistances[i + 1] = (UInt16)distanceTmp[i];
- m_MatchDistances[i + 2] = (UInt16)distanceTmp[i + 1];
+ m_MatchDistances[(size_t)i + 1] = (UInt16)distanceTmp[i];
+ m_MatchDistances[(size_t)i + 2] = (UInt16)distanceTmp[(size_t)i + 1];
}
- UInt32 len = distanceTmp[numPairs - 2];
+ UInt32 len = distanceTmp[(size_t)numPairs - 2];
if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen)
{
UInt32 numAvail = Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) + 1;
const Byte *pby = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - 1;
- const Byte *pby2 = pby - (distanceTmp[numPairs - 1] + 1);
+ const Byte *pby2 = pby - (distanceTmp[(size_t)numPairs - 1] + 1);
if (numAvail > m_MatchMaxLen)
numAvail = m_MatchMaxLen;
for (; len < numAvail && pby[len] == pby2[len]; len++);
- m_MatchDistances[i - 1] = (UInt16)len;
+ m_MatchDistances[(size_t)i - 1] = (UInt16)len;
}
}
if (m_IsMultiPass)
@@ -337,11 +339,11 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes)
if (numDistancePairs == 0)
return 1;
const UInt16 *matchDistances = m_MatchDistances + 1;
- lenEnd = matchDistances[numDistancePairs - 2];
+ lenEnd = matchDistances[(size_t)numDistancePairs - 2];
if (lenEnd > m_NumFastBytes)
{
- backRes = matchDistances[numDistancePairs - 1];
+ backRes = matchDistances[(size_t)numDistancePairs - 1];
MovePos(lenEnd - 1);
return lenEnd;
}
@@ -356,10 +358,10 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes)
for (UInt32 i = kMatchMinLen; i <= lenEnd; i++)
{
- UInt32 distance = matchDistances[offs + 1];
+ UInt32 distance = matchDistances[(size_t)offs + 1];
m_Optimum[i].PosPrev = 0;
m_Optimum[i].BackPrev = (UInt16)distance;
- m_Optimum[i].Price = m_LenPrices[i - kMatchMinLen] + m_PosPrices[GetPosSlot(distance)];
+ m_Optimum[i].Price = m_LenPrices[(size_t)i - kMatchMinLen] + m_PosPrices[GetPosSlot(distance)];
if (i == matchDistances[offs])
offs += 2;
}
@@ -378,11 +380,11 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes)
UInt32 newLen = 0;
if (numDistancePairs != 0)
{
- newLen = matchDistances[numDistancePairs - 2];
+ newLen = matchDistances[(size_t)numDistancePairs - 2];
if (newLen > m_NumFastBytes)
{
UInt32 len = Backward(backRes, cur);
- m_Optimum[cur].BackPrev = matchDistances[numDistancePairs - 1];
+ m_Optimum[cur].BackPrev = matchDistances[(size_t)numDistancePairs - 1];
m_OptimumEndIndex = cur + newLen;
m_Optimum[cur].PosPrev = (UInt16)m_OptimumEndIndex;
MovePos(newLen - 1);
@@ -392,7 +394,7 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes)
UInt32 curPrice = m_Optimum[cur].Price;
{
const UInt32 curAnd1Price = curPrice + m_LiteralPrices[*(Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) + cur - m_AdditionalOffset)];
- COptimal &optimum = m_Optimum[cur + 1];
+ COptimal &optimum = m_Optimum[(size_t)cur + 1];
if (curAnd1Price < optimum.Price)
{
optimum.Price = curAnd1Price;
@@ -404,11 +406,11 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes)
while (lenEnd < cur + newLen)
m_Optimum[++lenEnd].Price = kIfinityPrice;
UInt32 offs = 0;
- UInt32 distance = matchDistances[offs + 1];
+ UInt32 distance = matchDistances[(size_t)offs + 1];
curPrice += m_PosPrices[GetPosSlot(distance)];
for (UInt32 lenTest = kMatchMinLen; ; lenTest++)
{
- UInt32 curAndLenPrice = curPrice + m_LenPrices[lenTest - kMatchMinLen];
+ UInt32 curAndLenPrice = curPrice + m_LenPrices[(size_t)lenTest - kMatchMinLen];
COptimal &optimum = m_Optimum[cur + lenTest];
if (curAndLenPrice < optimum.Price)
{
@@ -422,7 +424,7 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes)
if (offs == numDistancePairs)
break;
curPrice -= m_PosPrices[GetPosSlot(distance)];
- distance = matchDistances[offs + 1];
+ distance = matchDistances[(size_t)offs + 1];
curPrice += m_PosPrices[GetPosSlot(distance)];
}
}
@@ -435,7 +437,7 @@ UInt32 CCoder::GetOptimalFast(UInt32 &backRes)
UInt32 numDistancePairs = m_MatchDistances[0];
if (numDistancePairs == 0)
return 1;
- UInt32 lenMain = m_MatchDistances[numDistancePairs - 1];
+ UInt32 lenMain = m_MatchDistances[(size_t)numDistancePairs - 1];
backRes = m_MatchDistances[numDistancePairs];
MovePos(lenMain - 1);
return lenMain;
@@ -470,7 +472,7 @@ NO_INLINE void CCoder::LevelTableDummy(const Byte *levels, unsigned numLevels, U
for (unsigned n = 0; n < numLevels; n++)
{
unsigned curLen = nextLen;
- nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF;
+ nextLen = (n < numLevels - 1) ? levels[(size_t)n + 1] : 0xFF;
count++;
if (count < maxCount && curLen == nextLen)
continue;
@@ -537,7 +539,7 @@ NO_INLINE void CCoder::LevelTableCode(const Byte *levels, unsigned numLevels, co
for (unsigned n = 0; n < numLevels; n++)
{
unsigned curLen = nextLen;
- nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF;
+ nextLen = (n < numLevels - 1) ? levels[(size_t)n + 1] : 0xFF;
count++;
if (count < maxCount && curLen == nextLen)
continue;
@@ -642,7 +644,7 @@ NO_INLINE void CCoder::TryBlock()
{
UInt32 newLen = len - kMatchMinLen;
codeValue.Len = (UInt16)newLen;
- mainFreqs[kSymbolMatch + g_LenSlots[newLen]]++;
+ mainFreqs[kSymbolMatch + (size_t)g_LenSlots[newLen]]++;
codeValue.Pos = (UInt16)pos;
distFreqs[GetPosSlot(pos)]++;
}
@@ -675,7 +677,7 @@ NO_INLINE void CCoder::SetPrices(const CLevels &levels)
for (i = 0; i < m_NumLenCombinations; i++)
{
UInt32 slot = g_LenSlots[i];
- Byte price = levels.litLenLevels[kSymbolMatch + slot];
+ Byte price = levels.litLenLevels[kSymbolMatch + (size_t)slot];
m_LenPrices[i] = (Byte)(((price != 0) ? price : kNoLenStatPrice) + m_LenDirectBits[slot]);
}
@@ -780,11 +782,11 @@ NO_INLINE UInt32 CCoder::TryDynBlock(unsigned tableIndex, UInt32 numPasses)
(CLevels &)t = m_NewLevels;
m_NumLitLenLevels = kMainTableSize;
- while (m_NumLitLenLevels > kNumLitLenCodesMin && m_NewLevels.litLenLevels[m_NumLitLenLevels - 1] == 0)
+ while (m_NumLitLenLevels > kNumLitLenCodesMin && m_NewLevels.litLenLevels[(size_t)m_NumLitLenLevels - 1] == 0)
m_NumLitLenLevels--;
m_NumDistLevels = kDistTableSize64;
- while (m_NumDistLevels > kNumDistCodesMin && m_NewLevels.distLevels[m_NumDistLevels - 1] == 0)
+ while (m_NumDistLevels > kNumDistCodesMin && m_NewLevels.distLevels[(size_t)m_NumDistLevels - 1] == 0)
m_NumDistLevels--;
UInt32 levelFreqs[kLevelTableSize];
@@ -923,14 +925,6 @@ void CCoder::CodeBlock(unsigned tableIndex, bool finalBlock)
}
}
-SRes Read(void *object, void *data, size_t *size)
-{
- const UInt32 kStepSize = (UInt32)1 << 31;
- UInt32 curSize = ((*size < kStepSize) ? (UInt32)*size : kStepSize);
- HRESULT res = ((CSeqInStream *)object)->RealStream->Read(data, curSize, &curSize);
- *size = curSize;
- return (SRes)res;
-}
HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */ , const UInt64 * /* outSize */ , ICompressProgressInfo *progress)
@@ -944,9 +938,11 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *ou
UInt64 nowPos = 0;
- _seqInStream.RealStream = inStream;
- _seqInStream.SeqInStream.Read = Read;
- _lzInWindow.stream = &_seqInStream.SeqInStream;
+ CSeqInStreamWrap _seqInStream;
+
+ _seqInStream.Init(inStream);
+
+ _lzInWindow.stream = &_seqInStream.vt;
MatchFinder_Init(&_lzInWindow);
m_OutStream.SetStream(outStream);
@@ -974,7 +970,7 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *ou
}
while (Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) != 0);
if (_lzInWindow.result != SZ_OK)
- return _lzInWindow.result;
+ return SResToHRESULT(_lzInWindow.result);
return m_OutStream.Flush();
}
diff --git a/CPP/7zip/Compress/DeflateEncoder.h b/CPP/7zip/Compress/DeflateEncoder.h
index 6c4ae4fc..94d250ec 100644
--- a/CPP/7zip/Compress/DeflateEncoder.h
+++ b/CPP/7zip/Compress/DeflateEncoder.h
@@ -46,11 +46,6 @@ struct CTables: public CLevels
void InitStructures();
};
-typedef struct _CSeqInStream
-{
- ISeqInStream SeqInStream;
- ISequentialInStream *RealStream;
-} CSeqInStream;
struct CEncProps
{
@@ -76,8 +71,6 @@ class CCoder
CMatchFinder _lzInWindow;
CBitlEncoder m_OutStream;
- CSeqInStream _seqInStream;
-
public:
CCodeValue *m_Values;
diff --git a/CPP/7zip/Compress/HuffmanDecoder.h b/CPP/7zip/Compress/HuffmanDecoder.h
index 04364c14..f0529876 100644
--- a/CPP/7zip/Compress/HuffmanDecoder.h
+++ b/CPP/7zip/Compress/HuffmanDecoder.h
@@ -8,45 +8,52 @@
namespace NCompress {
namespace NHuffman {
+const unsigned kNumPairLenBits = 4;
+const unsigned kPairLenMask = (1 << kNumPairLenBits) - 1;
+
template <unsigned kNumBitsMax, UInt32 m_NumSymbols, unsigned kNumTableBits = 9>
class CDecoder
{
+public:
UInt32 _limits[kNumBitsMax + 2];
UInt32 _poses[kNumBitsMax + 1];
UInt16 _lens[1 << kNumTableBits];
UInt16 _symbols[m_NumSymbols];
-public:
bool Build(const Byte *lens) throw()
{
- UInt32 lenCounts[kNumBitsMax + 1];
- UInt32 tmpPoses[kNumBitsMax + 1];
+ UInt32 counts[kNumBitsMax + 1];
unsigned i;
for (i = 0; i <= kNumBitsMax; i++)
- lenCounts[i] = 0;
+ counts[i] = 0;
UInt32 sym;
for (sym = 0; sym < m_NumSymbols; sym++)
- lenCounts[lens[sym]]++;
+ counts[lens[sym]]++;
- lenCounts[0] = 0;
- _poses[0] = 0;
+ const UInt32 kMaxValue = (UInt32)1 << kNumBitsMax;
+
_limits[0] = 0;
+
UInt32 startPos = 0;
- const UInt32 kMaxValue = (UInt32)1 << kNumBitsMax;
+ UInt32 sum = 0;
for (i = 1; i <= kNumBitsMax; i++)
{
- startPos += lenCounts[i] << (kNumBitsMax - i);
+ const UInt32 cnt = counts[i];
+ startPos += cnt << (kNumBitsMax - i);
if (startPos > kMaxValue)
return false;
_limits[i] = startPos;
- _poses[i] = _poses[i - 1] + lenCounts[i - 1];
- tmpPoses[i] = _poses[i];
+ counts[i] = sum;
+ _poses[i] = sum;
+ sum += cnt;
}
+ counts[0] = sum;
+ _poses[0] = sum;
_limits[kNumBitsMax + 1] = kMaxValue;
for (sym = 0; sym < m_NumSymbols; sym++)
@@ -55,16 +62,15 @@ public:
if (len == 0)
continue;
- unsigned offset = tmpPoses[len];
+ unsigned offset = counts[len]++;
_symbols[offset] = (UInt16)sym;
- tmpPoses[len] = offset + 1;
if (len <= kNumTableBits)
{
offset -= _poses[len];
UInt32 num = (UInt32)1 << (kNumTableBits - len);
- UInt16 val = (UInt16)((sym << 4) | len);
- UInt16 *dest = _lens + (_limits[len - 1] >> (kNumBitsMax - kNumTableBits)) + (offset << (kNumTableBits - len));
+ UInt16 val = (UInt16)((sym << kNumPairLenBits) | len);
+ UInt16 *dest = _lens + (_limits[(size_t)len - 1] >> (kNumBitsMax - kNumTableBits)) + (offset << (kNumTableBits - len));
for (UInt32 k = 0; k < num; k++)
dest[k] = val;
}
@@ -73,36 +79,41 @@ public:
return true;
}
+
bool BuildFull(const Byte *lens, UInt32 numSymbols = m_NumSymbols) throw()
{
- UInt32 lenCounts[kNumBitsMax + 1];
- UInt32 tmpPoses[kNumBitsMax + 1];
+ UInt32 counts[kNumBitsMax + 1];
unsigned i;
for (i = 0; i <= kNumBitsMax; i++)
- lenCounts[i] = 0;
+ counts[i] = 0;
UInt32 sym;
for (sym = 0; sym < numSymbols; sym++)
- lenCounts[lens[sym]]++;
+ counts[lens[sym]]++;
- lenCounts[0] = 0;
- _poses[0] = 0;
+ const UInt32 kMaxValue = (UInt32)1 << kNumBitsMax;
+
_limits[0] = 0;
+
UInt32 startPos = 0;
- const UInt32 kMaxValue = (UInt32)1 << kNumBitsMax;
+ UInt32 sum = 0;
for (i = 1; i <= kNumBitsMax; i++)
{
- startPos += lenCounts[i] << (kNumBitsMax - i);
+ const UInt32 cnt = counts[i];
+ startPos += cnt << (kNumBitsMax - i);
if (startPos > kMaxValue)
return false;
_limits[i] = startPos;
- _poses[i] = _poses[i - 1] + lenCounts[i - 1];
- tmpPoses[i] = _poses[i];
+ counts[i] = sum;
+ _poses[i] = sum;
+ sum += cnt;
}
+ counts[0] = sum;
+ _poses[0] = sum;
_limits[kNumBitsMax + 1] = kMaxValue;
for (sym = 0; sym < numSymbols; sym++)
@@ -111,16 +122,15 @@ public:
if (len == 0)
continue;
- unsigned offset = tmpPoses[len];
+ unsigned offset = counts[len]++;
_symbols[offset] = (UInt16)sym;
- tmpPoses[len] = offset + 1;
if (len <= kNumTableBits)
{
offset -= _poses[len];
UInt32 num = (UInt32)1 << (kNumTableBits - len);
- UInt16 val = (UInt16)((sym << 4) | len);
- UInt16 *dest = _lens + (_limits[len - 1] >> (kNumBitsMax - kNumTableBits)) + (offset << (kNumTableBits - len));
+ UInt16 val = (UInt16)((sym << kNumPairLenBits) | len);
+ UInt16 *dest = _lens + (_limits[(size_t)len - 1] >> (kNumBitsMax - kNumTableBits)) + (offset << (kNumTableBits - len));
for (UInt32 k = 0; k < num; k++)
dest[k] = val;
}
@@ -129,16 +139,18 @@ public:
return startPos == kMaxValue;
}
+
template <class TBitDecoder>
- UInt32 Decode(TBitDecoder *bitStream) const throw()
+ MY_FORCE_INLINE
+ UInt32 Decode(TBitDecoder *bitStream) const
{
UInt32 val = bitStream->GetValue(kNumBitsMax);
if (val < _limits[kNumTableBits])
{
UInt32 pair = _lens[val >> (kNumBitsMax - kNumTableBits)];
- bitStream->MovePos((unsigned)(pair & 0xF));
- return pair >> 4;
+ bitStream->MovePos((unsigned)(pair & kPairLenMask));
+ return pair >> kNumPairLenBits;
}
unsigned numBits;
@@ -148,27 +160,29 @@ public:
return 0xFFFFFFFF;
bitStream->MovePos(numBits);
- UInt32 index = _poses[numBits] + ((val - _limits[numBits - 1]) >> (kNumBitsMax - numBits));
+ UInt32 index = _poses[numBits] + ((val - _limits[(size_t)numBits - 1]) >> (kNumBitsMax - numBits));
return _symbols[index];
}
+
template <class TBitDecoder>
- UInt32 DecodeFull(TBitDecoder *bitStream) const throw()
+ MY_FORCE_INLINE
+ UInt32 DecodeFull(TBitDecoder *bitStream) const
{
UInt32 val = bitStream->GetValue(kNumBitsMax);
if (val < _limits[kNumTableBits])
{
UInt32 pair = _lens[val >> (kNumBitsMax - kNumTableBits)];
- bitStream->MovePos((unsigned)(pair & 0xF));
- return pair >> 4;
+ bitStream->MovePos((unsigned)(pair & kPairLenMask));
+ return pair >> kNumPairLenBits;
}
unsigned numBits;
for (numBits = kNumTableBits + 1; val >= _limits[numBits]; numBits++);
bitStream->MovePos(numBits);
- UInt32 index = _poses[numBits] + ((val - _limits[numBits - 1]) >> (kNumBitsMax - numBits));
+ UInt32 index = _poses[numBits] + ((val - _limits[(size_t)numBits - 1]) >> (kNumBitsMax - numBits));
return _symbols[index];
}
};
@@ -185,50 +199,54 @@ public:
{
const unsigned kNumBitsMax = 7;
- UInt32 lenCounts[kNumBitsMax + 1];
- UInt32 tmpPoses[kNumBitsMax + 1];
+ UInt32 counts[kNumBitsMax + 1];
UInt32 _poses[kNumBitsMax + 1];
UInt32 _limits[kNumBitsMax + 1];
unsigned i;
for (i = 0; i <= kNumBitsMax; i++)
- lenCounts[i] = 0;
+ counts[i] = 0;
UInt32 sym;
for (sym = 0; sym < m_NumSymbols; sym++)
- lenCounts[lens[sym]]++;
+ counts[lens[sym]]++;
- lenCounts[0] = 0;
- _poses[0] = 0;
+ const UInt32 kMaxValue = (UInt32)1 << kNumBitsMax;
+
_limits[0] = 0;
+
UInt32 startPos = 0;
- const UInt32 kMaxValue = (UInt32)1 << kNumBitsMax;
+ UInt32 sum = 0;
for (i = 1; i <= kNumBitsMax; i++)
{
- startPos += lenCounts[i] << (kNumBitsMax - i);
+ const UInt32 cnt = counts[i];
+ startPos += cnt << (kNumBitsMax - i);
if (startPos > kMaxValue)
return false;
_limits[i] = startPos;
- _poses[i] = _poses[i - 1] + lenCounts[i - 1];
- tmpPoses[i] = _poses[i];
+ counts[i] = sum;
+ _poses[i] = sum;
+ sum += cnt;
}
+ counts[0] = sum;
+ _poses[0] = sum;
+
for (sym = 0; sym < m_NumSymbols; sym++)
{
unsigned len = lens[sym];
if (len == 0)
continue;
- unsigned offset = tmpPoses[len];
- tmpPoses[len] = offset + 1;
+ unsigned offset = counts[len]++;
{
offset -= _poses[len];
UInt32 num = (UInt32)1 << (kNumBitsMax - len);
Byte val = (Byte)((sym << 3) | len);
- Byte *dest = _lens + (_limits[len - 1]) + (offset << (kNumBitsMax - len));
+ Byte *dest = _lens + (_limits[(size_t)len - 1]) + (offset << (kNumBitsMax - len));
for (UInt32 k = 0; k < num; k++)
dest[k] = val;
}
@@ -246,7 +264,7 @@ public:
}
template <class TBitDecoder>
- UInt32 Decode(TBitDecoder *bitStream) const throw()
+ UInt32 Decode(TBitDecoder *bitStream) const
{
UInt32 val = bitStream->GetValue(7);
UInt32 pair = _lens[val];
diff --git a/CPP/7zip/Compress/ImplodeDecoder.cpp b/CPP/7zip/Compress/ImplodeDecoder.cpp
index e1d68a43..736c832e 100644
--- a/CPP/7zip/Compress/ImplodeDecoder.cpp
+++ b/CPP/7zip/Compress/ImplodeDecoder.cpp
@@ -10,214 +10,248 @@ namespace NCompress {
namespace NImplode {
namespace NDecoder {
-class CException
+bool CHuffmanDecoder::Build(const Byte *lens, unsigned numSymbols) throw()
{
-public:
- enum ECauseType
- {
- kData
- } m_Cause;
- CException(ECauseType cause): m_Cause(cause) {}
-};
+ unsigned counts[kNumHuffmanBits + 1];
+
+ unsigned i;
+ for (i = 0; i <= kNumHuffmanBits; i++)
+ counts[i] = 0;
+
+ unsigned sym;
+ for (sym = 0; sym < numSymbols; sym++)
+ counts[lens[sym]]++;
-static const int kNumDistanceLowDirectBitsForBigDict = 7;
-static const int kNumDistanceLowDirectBitsForSmallDict = 6;
+ const UInt32 kMaxValue = (UInt32)1 << kNumHuffmanBits;
+
+ // _limits[0] = kMaxValue;
-static const int kNumBitsInByte = 8;
+ UInt32 startPos = kMaxValue;
+ UInt32 sum = 0;
-// static const int kLevelStructuresNumberFieldSize = kNumBitsInByte;
-static const int kLevelStructuresNumberAdditionalValue = 1;
+ for (i = 1; i <= kNumHuffmanBits; i++)
+ {
+ const UInt32 cnt = counts[i];
+ const UInt32 range = cnt << (kNumHuffmanBits - i);
+ if (startPos < range)
+ return false;
+ startPos -= range;
+ _limits[i] = startPos;
+ _poses[i] = sum;
+ sum += cnt;
+ counts[i] = sum;
+ }
-static const int kNumLevelStructureLevelBits = 4;
-static const int kLevelStructureLevelAdditionalValue = 1;
+ // counts[0] += sum;
-static const int kNumLevelStructureRepNumberBits = 4;
-static const int kLevelStructureRepNumberAdditionalValue = 1;
+ if (startPos != 0)
+ return false;
+ for (sym = 0; sym < numSymbols; sym++)
+ {
+ unsigned len = lens[sym];
+ if (len != 0)
+ _symbols[--counts[len]] = (Byte)sym;
+ }
-static const int kLiteralTableSize = (1 << kNumBitsInByte);
-static const int kDistanceTableSize = 64;
-static const int kLengthTableSize = 64;
+ return true;
+}
-static const UInt32 kHistorySize =
- (1 << MyMax(kNumDistanceLowDirectBitsForBigDict,
- kNumDistanceLowDirectBitsForSmallDict)) *
- kDistanceTableSize; // = 8 KB;
-static const int kNumAdditionalLengthBits = 8;
+UInt32 CHuffmanDecoder::Decode(CInBit *inStream) const throw()
+{
+ UInt32 val = inStream->GetValue(kNumHuffmanBits);
+ unsigned numBits;
+ for (numBits = 1; val < _limits[numBits]; numBits++);
+ UInt32 sym = _symbols[_poses[numBits] + ((val - _limits[numBits]) >> (kNumHuffmanBits - numBits))];
+ inStream->MovePos(numBits);
+ return sym;
+}
-static const UInt32 kMatchMinLenWhenLiteralsOn = 3;
-static const UInt32 kMatchMinLenWhenLiteralsOff = 2;
-static const UInt32 kMatchMinLenMax = MyMax(kMatchMinLenWhenLiteralsOn,
- kMatchMinLenWhenLiteralsOff); // 3
-// static const UInt32 kMatchMaxLenMax = kMatchMinLenMax + (kLengthTableSize - 1) + (1 << kNumAdditionalLengthBits) - 1; // or 2
+static const unsigned kNumLenDirectBits = 8;
-enum
-{
- kMatchId = 0,
- kLiteralId = 1
-};
+static const unsigned kNumDistDirectBitsSmall = 6;
+static const unsigned kNumDistDirectBitsBig = 7;
+static const unsigned kLitTableSize = (1 << 8);
+static const unsigned kDistTableSize = 64;
+static const unsigned kLenTableSize = 64;
-CCoder::CCoder():
- m_LiteralDecoder(kLiteralTableSize),
- m_LengthDecoder(kLengthTableSize),
- m_DistanceDecoder(kDistanceTableSize)
-{
-}
+static const UInt32 kHistorySize = (1 << kNumDistDirectBitsBig) * kDistTableSize; // 8 KB
-/*
-void CCoder::ReleaseStreams()
-{
- m_OutWindowStream.ReleaseStream();
- m_InBitStream.ReleaseStream();
-}
-*/
-bool CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder,
- Byte *levels, int numLevelItems)
-{
- int numCodedStructures = m_InBitStream.ReadBits(kNumBitsInByte) +
- kLevelStructuresNumberAdditionalValue;
- int currentIndex = 0;
- for (int i = 0; i < numCodedStructures; i++)
- {
- int level = m_InBitStream.ReadBits(kNumLevelStructureLevelBits) +
- kLevelStructureLevelAdditionalValue;
- int rep = m_InBitStream.ReadBits(kNumLevelStructureRepNumberBits) +
- kLevelStructureRepNumberAdditionalValue;
- if (currentIndex + rep > numLevelItems)
- throw CException(CException::kData);
- for (int j = 0; j < rep; j++)
- levels[currentIndex++] = (Byte)level;
- }
- if (currentIndex != numLevelItems)
- return false;
- return decoder.SetCodeLengths(levels);
-}
+CCoder::CCoder():
+ _fullStreamMode(false),
+ _flags(0)
+{}
-bool CCoder::ReadTables(void)
+bool CCoder::BuildHuff(CHuffmanDecoder &decoder, unsigned numSymbols)
{
- if (m_LiteralsOn)
+ Byte levels[kMaxHuffTableSize];
+ unsigned numRecords = (unsigned)_inBitStream.ReadAlignedByte() + 1;
+ unsigned index = 0;
+ do
{
- Byte literalLevels[kLiteralTableSize];
- if (!ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize))
+ unsigned b = (unsigned)_inBitStream.ReadAlignedByte();
+ Byte level = (Byte)((b & 0xF) + 1);
+ unsigned rep = ((unsigned)b >> 4) + 1;
+ if (index + rep > numSymbols)
return false;
+ for (unsigned j = 0; j < rep; j++)
+ levels[index++] = level;
}
+ while (--numRecords);
- Byte lengthLevels[kLengthTableSize];
- if (!ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize))
+ if (index != numSymbols)
return false;
-
- Byte distanceLevels[kDistanceTableSize];
- return ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize);
+ return decoder.Build(levels, numSymbols);
}
-/*
-class CCoderReleaser
-{
- CCoder *m_Coder;
-public:
- CCoderReleaser(CCoder *coder): m_Coder(coder) {}
- ~CCoderReleaser() { m_Coder->ReleaseStreams(); }
-};
-*/
HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
- const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
- if (!m_InBitStream.Create(1 << 20))
+ if (!_inBitStream.Create(1 << 18))
return E_OUTOFMEMORY;
- if (!m_OutWindowStream.Create(kHistorySize))
+ if (!_outWindowStream.Create(kHistorySize << 1)) // 16 KB
return E_OUTOFMEMORY;
- if (outSize == NULL)
+ if (!outSize)
return E_INVALIDARG;
- UInt64 pos = 0, unPackSize = *outSize;
- m_OutWindowStream.SetStream(outStream);
- m_OutWindowStream.Init(false);
- m_InBitStream.SetStream(inStream);
- m_InBitStream.Init();
- // CCoderReleaser coderReleaser(this);
-
- if (!ReadTables())
+ _outWindowStream.SetStream(outStream);
+ _outWindowStream.Init(false);
+ _inBitStream.SetStream(inStream);
+ _inBitStream.Init();
+
+ const unsigned numDistDirectBits = (_flags & 2) ?
+ kNumDistDirectBitsBig:
+ kNumDistDirectBitsSmall;
+ const bool literalsOn = ((_flags & 4) != 0);
+ const UInt32 minMatchLen = (literalsOn ? 3 : 2);
+
+ if (literalsOn)
+ if (!BuildHuff(_litDecoder, kLitTableSize))
+ return S_FALSE;
+ if (!BuildHuff(_lenDecoder, kLenTableSize))
return S_FALSE;
-
+ if (!BuildHuff(_distDecoder, kDistTableSize))
+ return S_FALSE;
+
+ UInt64 prevProgress = 0;
+ bool moreOut = false;
+ UInt64 pos = 0, unPackSize = *outSize;
+
while (pos < unPackSize)
{
- if (progress != NULL && pos % (1 << 16) == 0)
+ if (progress && (pos - prevProgress) >= (1 << 18))
{
- UInt64 packSize = m_InBitStream.GetProcessedSize();
+ const UInt64 packSize = _inBitStream.GetProcessedSize();
RINOK(progress->SetRatioInfo(&packSize, &pos));
+ prevProgress = pos;
}
- if (m_InBitStream.ReadBits(1) == kMatchId) // match
+
+ if (_inBitStream.ReadBits(1) != 0)
{
- UInt32 lowDistBits = m_InBitStream.ReadBits(m_NumDistanceLowDirectBits);
- UInt32 distance = m_DistanceDecoder.DecodeSymbol(&m_InBitStream);
- if (distance >= kDistanceTableSize)
- return S_FALSE;
- distance = (distance << m_NumDistanceLowDirectBits) + lowDistBits;
- UInt32 lengthSymbol = m_LengthDecoder.DecodeSymbol(&m_InBitStream);
- if (lengthSymbol >= kLengthTableSize)
- return S_FALSE;
- UInt32 length = lengthSymbol + m_MinMatchLength;
- if (lengthSymbol == kLengthTableSize - 1) // special symbol = 63
- length += m_InBitStream.ReadBits(kNumAdditionalLengthBits);
- while (distance >= pos && length > 0)
+ Byte b;
+ if (literalsOn)
{
- m_OutWindowStream.PutByte(0);
- pos++;
- length--;
+ UInt32 sym = _litDecoder.Decode(&_inBitStream);
+ // if (sym >= kLitTableSize) break;
+ b = (Byte)sym;
}
- if (length > 0)
- m_OutWindowStream.CopyBlock(distance, length);
- pos += length;
+ else
+ b = (Byte)_inBitStream.ReadBits(8);
+ _outWindowStream.PutByte(b);
+ pos++;
}
else
{
- Byte b;
- if (m_LiteralsOn)
+ UInt32 lowDistBits = _inBitStream.ReadBits(numDistDirectBits);
+ UInt32 dist = _distDecoder.Decode(&_inBitStream);
+ // if (dist >= kDistTableSize) break;
+ dist = (dist << numDistDirectBits) + lowDistBits;
+ UInt32 len = _lenDecoder.Decode(&_inBitStream);
+ // if (len >= kLenTableSize) break;
+ if (len == kLenTableSize - 1)
+ len += _inBitStream.ReadBits(kNumLenDirectBits);
+ len += minMatchLen;
+
{
- UInt32 temp = m_LiteralDecoder.DecodeSymbol(&m_InBitStream);
- if (temp >= kLiteralTableSize)
- return S_FALSE;
- b = (Byte)temp;
+ const UInt64 limit = unPackSize - pos;
+ if (len > limit)
+ {
+ moreOut = true;
+ len = (UInt32)limit;
+ }
+ }
+
+ while (dist >= pos && len != 0)
+ {
+ _outWindowStream.PutByte(0);
+ pos++;
+ len--;
+ }
+
+ if (len != 0)
+ {
+ _outWindowStream.CopyBlock(dist, len);
+ pos += len;
}
- else
- b = (Byte)m_InBitStream.ReadBits(kNumBitsInByte);
- m_OutWindowStream.PutByte(b);
- pos++;
}
}
- if (pos > unPackSize)
- return S_FALSE;
- return m_OutWindowStream.Flush();
+
+ HRESULT res = _outWindowStream.Flush();
+
+ if (res == S_OK)
+ {
+ if (_fullStreamMode)
+ {
+ if (moreOut)
+ res = S_FALSE;
+ if (inSize && *inSize != _inBitStream.GetProcessedSize())
+ res = S_FALSE;
+ }
+ if (pos != unPackSize)
+ res = S_FALSE;
+ }
+
+ return res;
}
+
STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
- catch(const CLzOutWindowException &e) { return e.ErrorCode; }
+ // catch(const CInBufferException &e) { return e.ErrorCode; }
+ // catch(const CLzOutWindowException &e) { return e.ErrorCode; }
+ catch(const CSystemException &e) { return e.ErrorCode; }
catch(...) { return S_FALSE; }
}
+
STDMETHODIMP CCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
{
- if (size < 1)
- return E_INVALIDARG;
- Byte flag = data[0];
- m_BigDictionaryOn = ((flag & 2) != 0);
- m_NumDistanceLowDirectBits = m_BigDictionaryOn ?
- kNumDistanceLowDirectBitsForBigDict:
- kNumDistanceLowDirectBitsForSmallDict;
- m_LiteralsOn = ((flag & 4) != 0);
- m_MinMatchLength = m_LiteralsOn ?
- kMatchMinLenWhenLiteralsOn :
- kMatchMinLenWhenLiteralsOff;
+ if (size == 0)
+ return E_NOTIMPL;
+ _flags = data[0];
+ return S_OK;
+}
+
+
+STDMETHODIMP CCoder::SetFinishMode(UInt32 finishMode)
+{
+ _fullStreamMode = (finishMode != 0);
+ return S_OK;
+}
+
+
+STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _inBitStream.GetProcessedSize();
return S_OK;
}
diff --git a/CPP/7zip/Compress/ImplodeDecoder.h b/CPP/7zip/Compress/ImplodeDecoder.h
index 5876ecac..a73c143c 100644
--- a/CPP/7zip/Compress/ImplodeDecoder.h
+++ b/CPP/7zip/Compress/ImplodeDecoder.h
@@ -7,48 +7,65 @@
#include "../ICoder.h"
-#include "ImplodeHuffmanDecoder.h"
+#include "../Common/InBuffer.h"
+
+#include "BitlDecoder.h"
#include "LzOutWindow.h"
namespace NCompress {
namespace NImplode {
namespace NDecoder {
+typedef NBitl::CDecoder<CInBuffer> CInBit;
+
+const unsigned kNumHuffmanBits = 16;
+const unsigned kMaxHuffTableSize = 1 << 8;
+
+class CHuffmanDecoder
+{
+ UInt32 _limits[kNumHuffmanBits + 1];
+ UInt32 _poses[kNumHuffmanBits + 1];
+ Byte _symbols[kMaxHuffTableSize];
+public:
+ bool Build(const Byte *lens, unsigned numSymbols) throw();
+ UInt32 Decode(CInBit *inStream) const throw();
+};
+
+
class CCoder:
public ICompressCoder,
public ICompressSetDecoderProperties2,
+ public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
public CMyUnknownImp
{
- CLzOutWindow m_OutWindowStream;
- NBitl::CDecoder<CInBuffer> m_InBitStream;
+ CLzOutWindow _outWindowStream;
+ CInBit _inBitStream;
- NImplode::NHuffman::CDecoder m_LiteralDecoder;
- NImplode::NHuffman::CDecoder m_LengthDecoder;
- NImplode::NHuffman::CDecoder m_DistanceDecoder;
+ CHuffmanDecoder _litDecoder;
+ CHuffmanDecoder _lenDecoder;
+ CHuffmanDecoder _distDecoder;
- bool m_BigDictionaryOn;
- bool m_LiteralsOn;
+ Byte _flags;
+ bool _fullStreamMode;
- int m_NumDistanceLowDirectBits;
- UInt32 m_MinMatchLength;
-
- bool ReadLevelItems(NImplode::NHuffman::CDecoder &table, Byte *levels, int numLevelItems);
- bool ReadTables();
- void DeCodeLevelTable(Byte *newLevels, int numLevels);
-public:
- CCoder();
-
- MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
-
- // void ReleaseStreams();
-
+ bool BuildHuff(CHuffmanDecoder &table, unsigned numSymbols);
HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+public:
+ MY_UNKNOWN_IMP3(
+ ICompressSetDecoderProperties2,
+ ICompressSetFinishMode,
+ ICompressGetInStreamProcessedSize)
+
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);
+
+ CCoder();
};
}}}
diff --git a/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp b/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp
index d385d7b1..7d31bb94 100644
--- a/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp
+++ b/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp
@@ -1,89 +1,3 @@
// ImplodeHuffmanDecoder.cpp
#include "StdAfx.h"
-
-#include "ImplodeHuffmanDecoder.h"
-
-namespace NCompress {
-namespace NImplode {
-namespace NHuffman {
-
-CDecoder::CDecoder(UInt32 numSymbols):
- m_NumSymbols(numSymbols)
-{
- m_Symbols = new UInt32[m_NumSymbols];
-}
-
-CDecoder::~CDecoder()
-{
- delete []m_Symbols;
-}
-
-bool CDecoder::SetCodeLengths(const Byte *codeLengths)
-{
- // unsigned lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1];
- unsigned lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1];
- unsigned i;
- for (i = 0; i <= kNumBitsInLongestCode; i++)
- lenCounts[i] = 0;
- UInt32 symbolIndex;
- for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++)
- lenCounts[codeLengths[symbolIndex]]++;
- // lenCounts[0] = 0;
-
- // tmpPositions[0] = m_Positions[0] = m_Limitits[0] = 0;
- m_Limitits[kNumBitsInLongestCode + 1] = 0;
- m_Positions[kNumBitsInLongestCode + 1] = 0;
- lenCounts[kNumBitsInLongestCode + 1] = 0;
-
-
- UInt32 startPos = 0;
- static const UInt32 kMaxValue = (1 << kNumBitsInLongestCode);
-
- for (i = kNumBitsInLongestCode; i > 0; i--)
- {
- startPos += lenCounts[i] << (kNumBitsInLongestCode - i);
- if (startPos > kMaxValue)
- return false;
- m_Limitits[i] = startPos;
- m_Positions[i] = m_Positions[i + 1] + lenCounts[i + 1];
- tmpPositions[i] = m_Positions[i] + lenCounts[i];
-
- }
-
- // if _ZIP_MODE do not throw exception for trees containing only one node
- // #ifndef _ZIP_MODE
- if (startPos != kMaxValue)
- return false;
- // #endif
-
- for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++)
- if (codeLengths[symbolIndex] != 0)
- m_Symbols[--tmpPositions[codeLengths[symbolIndex]]] = symbolIndex;
- return true;
-}
-
-UInt32 CDecoder::DecodeSymbol(CInBit *inStream)
-{
- UInt32 numBits = 0;
- UInt32 value = inStream->GetValue(kNumBitsInLongestCode);
- unsigned i;
- for (i = kNumBitsInLongestCode; i > 0; i--)
- {
- if (value < m_Limitits[i])
- {
- numBits = i;
- break;
- }
- }
- if (i == 0)
- return 0xFFFFFFFF;
- inStream->MovePos(numBits);
- UInt32 index = m_Positions[numBits] +
- ((value - m_Limitits[numBits + 1]) >> (kNumBitsInLongestCode - numBits));
- if (index >= m_NumSymbols)
- return 0xFFFFFFFF;
- return m_Symbols[index];
-}
-
-}}}
diff --git a/CPP/7zip/Compress/ImplodeHuffmanDecoder.h b/CPP/7zip/Compress/ImplodeHuffmanDecoder.h
index 691a8e93..ea25211a 100644
--- a/CPP/7zip/Compress/ImplodeHuffmanDecoder.h
+++ b/CPP/7zip/Compress/ImplodeHuffmanDecoder.h
@@ -3,32 +3,4 @@
#ifndef __IMPLODE_HUFFMAN_DECODER_H
#define __IMPLODE_HUFFMAN_DECODER_H
-#include "../Common/InBuffer.h"
-
-#include "BitlDecoder.h"
-
-namespace NCompress {
-namespace NImplode {
-namespace NHuffman {
-
-const unsigned kNumBitsInLongestCode = 16;
-
-typedef NBitl::CDecoder<CInBuffer> CInBit;
-
-class CDecoder
-{
- UInt32 m_Limitits[kNumBitsInLongestCode + 2]; // m_Limitits[i] = value limit for symbols with length = i
- UInt32 m_Positions[kNumBitsInLongestCode + 2]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i
- UInt32 m_NumSymbols; // number of symbols in m_Symbols
- UInt32 *m_Symbols; // symbols: at first with len=1 then 2, ... 15.
-public:
- CDecoder(UInt32 numSymbols);
- ~CDecoder();
-
- bool SetCodeLengths(const Byte *codeLengths);
- UInt32 DecodeSymbol(CInBit *inStream);
-};
-
-}}}
-
#endif
diff --git a/CPP/7zip/Compress/Lzma2Decoder.cpp b/CPP/7zip/Compress/Lzma2Decoder.cpp
index 1a378bbe..98af203d 100644
--- a/CPP/7zip/Compress/Lzma2Decoder.cpp
+++ b/CPP/7zip/Compress/Lzma2Decoder.cpp
@@ -15,7 +15,7 @@ static HRESULT SResToHRESULT(SRes res)
case SZ_OK: return S_OK;
case SZ_ERROR_MEM: return E_OUTOFMEMORY;
case SZ_ERROR_PARAM: return E_INVALIDARG;
- // case SZ_ERROR_PROGRESS: return E_ABORT;
+ case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
case SZ_ERROR_DATA: return S_FALSE;
}
return E_FAIL;
@@ -26,30 +26,31 @@ namespace NLzma2 {
CDecoder::CDecoder():
_inBuf(NULL),
- _inBufSize(0),
- _inBufSizeNew(1 << 20),
- _outStepSize(1 << 22),
+ _finishMode(false),
_outSizeDefined(false),
- _finishMode(false)
+ _outStep(1 << 22),
+ _inBufSize(0),
+ _inBufSizeNew(1 << 20)
{
Lzma2Dec_Construct(&_state);
}
-STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; }
-STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStepSize = size; return S_OK; }
-
CDecoder::~CDecoder()
{
Lzma2Dec_Free(&_state, &g_Alloc);
MidFree(_inBuf);
}
+STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; }
+STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStep = size; return S_OK; }
+
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
{
if (size != 1)
return E_NOTIMPL;
RINOK(SResToHRESULT(Lzma2Dec_Allocate(&_state, prop[0], &g_Alloc)));
+
if (!_inBuf || _inBufSize != _inBufSizeNew)
{
MidFree(_inBuf);
@@ -63,9 +64,6 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
return S_OK;
}
-STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) { *value = _inSizeProcessed; return S_OK; }
-STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
-STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
@@ -73,191 +71,197 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
_outSize = 0;
if (_outSizeDefined)
_outSize = *outSize;
+ _inPos = _inLim = 0;
+ _inProcessed = 0;
+ _outProcessed = 0;
Lzma2Dec_Init(&_state);
-
- _inPos = _inSize = 0;
- _inSizeProcessed = _outSizeProcessed = 0;
+
return S_OK;
}
+
STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
{
_finishMode = (finishMode != 0);
return S_OK;
}
-STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize,
- const UInt64 *outSize, ICompressProgressInfo *progress)
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _inProcessed;
+ return S_OK;
+}
+
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
if (!_inBuf)
return S_FALSE;
+
SetOutStreamSize(outSize);
- UInt32 step = _outStepSize;
- const UInt32 kOutStepSize_Min = 1 << 12;
- if (step < kOutStepSize_Min)
- step = kOutStepSize_Min;
-
SizeT wrPos = _state.decoder.dicPos;
-
- SizeT next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ?
- _state.decoder.dicBufSize :
- _state.decoder.dicPos + step;
-
- HRESULT hres = S_OK;
+ HRESULT readRes = S_OK;
for (;;)
{
- if (_inPos == _inSize)
+ if (_inPos == _inLim && readRes == S_OK)
{
- _inPos = _inSize = 0;
- hres = inStream->Read(_inBuf, _inBufSize, &_inSize);
- if (hres != S_OK)
- break;
+ _inPos = _inLim = 0;
+ readRes = inStream->Read(_inBuf, _inBufSize, &_inLim);
+ }
+
+ const SizeT dicPos = _state.decoder.dicPos;
+ SizeT size;
+ {
+ SizeT next = _state.decoder.dicBufSize;
+ if (next - wrPos > _outStep)
+ next = wrPos + _outStep;
+ size = next - dicPos;
}
- SizeT dicPos = _state.decoder.dicPos;
- SizeT curSize = next - dicPos;
-
ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
if (_outSizeDefined)
{
- const UInt64 rem = _outSize - _outSizeProcessed;
- if (curSize >= rem)
+ const UInt64 rem = _outSize - _outProcessed;
+ if (size >= rem)
{
- curSize = (SizeT)rem;
+ size = (SizeT)rem;
if (_finishMode)
finishMode = LZMA_FINISH_END;
}
}
- SizeT inSizeProcessed = _inSize - _inPos;
+ SizeT inProcessed = _inLim - _inPos;
ELzmaStatus status;
- SRes res = Lzma2Dec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status);
+
+ SRes res = Lzma2Dec_DecodeToDic(&_state, dicPos + size, _inBuf + _inPos, &inProcessed, finishMode, &status);
- _inPos += (UInt32)inSizeProcessed;
- _inSizeProcessed += inSizeProcessed;
- SizeT outSizeProcessed = _state.decoder.dicPos - dicPos;
- _outSizeProcessed += outSizeProcessed;
+
+ _inPos += (UInt32)inProcessed;
+ _inProcessed += inProcessed;
+ const SizeT outProcessed = _state.decoder.dicPos - dicPos;
+ _outProcessed += outProcessed;
+
+
+ bool outFinished = (_outSizeDefined && _outProcessed >= _outSize);
- bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0
- || status == LZMA_STATUS_FINISHED_WITH_MARK);
- bool outFinished = (_outSizeDefined && _outSizeProcessed >= _outSize);
+ bool needStop = (res != 0
+ || (inProcessed == 0 && outProcessed == 0)
+ || status == LZMA_STATUS_FINISHED_WITH_MARK
+ || (!_finishMode && outFinished));
- if (res != 0
- || _state.decoder.dicPos >= next
- || finished
- || outFinished)
+ if (needStop || outProcessed >= size)
{
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 (finished)
+ if (needStop)
{
+ if (res != 0)
+ return S_FALSE;
+
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;
+ if (_finishMode)
+ {
+ if (inSize && *inSize != _inProcessed)
+ return S_FALSE;
+ if (_outSizeDefined && _outSize != _outProcessed)
+ return S_FALSE;
+ }
+ return readRes;
}
- return (finishMode == LZMA_FINISH_END) ? S_FALSE : S_OK;
- }
- if (outFinished && finishMode == LZMA_FINISH_ANY)
- return S_OK;
+ if (!_finishMode && outFinished)
+ return readRes;
+
+ return S_FALSE;
+ }
}
if (progress)
{
- RINOK(progress->SetRatioInfo(&_inSizeProcessed, &_outSizeProcessed));
+ RINOK(progress->SetRatioInfo(&_inProcessed, &_outProcessed));
}
}
-
- 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::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
+STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
+
+
STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- UInt32 totalProcessed = 0;
-
if (processedSize)
*processedSize = 0;
- for (;;)
+ ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
+ if (_outSizeDefined)
{
- if (_inPos == _inSize)
+ const UInt64 rem = _outSize - _outProcessed;
+ if (size >= rem)
{
- _inPos = _inSize = 0;
- RINOK(_inStream->Read(_inBuf, _inBufSize, &_inSize));
+ size = (UInt32)rem;
+ if (_finishMode)
+ finishMode = LZMA_FINISH_END;
}
+ }
+
+ HRESULT readRes = S_OK;
+
+ for (;;)
+ {
+ if (_inPos == _inLim && readRes == S_OK)
{
- ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
- if (_outSizeDefined)
- {
- const UInt64 rem = _outSize - _outSizeProcessed;
- if (rem <= size)
- {
- size = (UInt32)rem;
- if (_finishMode)
- finishMode = LZMA_FINISH_END;
- }
- }
+ _inPos = _inLim = 0;
+ readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim);
+ }
+
+ SizeT inProcessed = _inLim - _inPos;
+ SizeT outProcessed = size;
+ ELzmaStatus status;
- SizeT outProcessed = size;
- SizeT inProcessed = _inSize - _inPos;
-
- ELzmaStatus status;
- SRes res = Lzma2Dec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,
- _inBuf + _inPos, &inProcessed, finishMode, &status);
-
- _inPos += (UInt32)inProcessed;
- _inSizeProcessed += inProcessed;
- _outSizeProcessed += outProcessed;
- size -= (UInt32)outProcessed;
- data = (Byte *)data + outProcessed;
-
- totalProcessed += (UInt32)outProcessed;
- if (processedSize)
- *processedSize = totalProcessed;
-
- if (res != SZ_OK)
- {
- if (totalProcessed != 0)
- return S_OK;
- return SResToHRESULT(res);
- }
-
- if (inProcessed == 0 && outProcessed == 0)
- return S_OK;
- if (status == LZMA_STATUS_FINISHED_WITH_MARK)
- return S_OK;
- if (outProcessed != 0)
- {
- if (finishMode != LZMA_FINISH_END || _outSize != _outSizeProcessed)
- return S_OK;
- }
+ SRes res = Lzma2Dec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,
+ _inBuf + _inPos, &inProcessed, finishMode, &status);
+
+
+ _inPos += (UInt32)inProcessed;
+ _inProcessed += inProcessed;
+ _outProcessed += outProcessed;
+ size -= (UInt32)outProcessed;
+ data = (Byte *)data + outProcessed;
+ if (processedSize)
+ *processedSize += (UInt32)outProcessed;
+
+ if (res != 0)
+ return S_FALSE;
+
+ /*
+ if (status == LZMA_STATUS_FINISHED_WITH_MARK)
+ return readRes;
+
+ if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT)
+ {
+ if (_finishMode && _outSizeDefined && _outProcessed >= _outSize)
+ return S_FALSE;
+ return readRes;
}
+ */
+
+ if (inProcessed == 0 && outProcessed == 0)
+ return readRes;
}
}
diff --git a/CPP/7zip/Compress/Lzma2Decoder.h b/CPP/7zip/Compress/Lzma2Decoder.h
index a87912fb..440914e7 100644
--- a/CPP/7zip/Compress/Lzma2Decoder.h
+++ b/CPP/7zip/Compress/Lzma2Decoder.h
@@ -6,7 +6,6 @@
#include "../../../C/Lzma2Dec.h"
#include "../../Common/MyCom.h"
-
#include "../ICoder.h"
namespace NCompress {
@@ -25,25 +24,23 @@ class CDecoder:
#endif
public CMyUnknownImp
{
- CMyComPtr<ISequentialInStream> _inStream;
Byte *_inBuf;
UInt32 _inPos;
- UInt32 _inSize;
+ UInt32 _inLim;
bool _finishMode;
bool _outSizeDefined;
UInt64 _outSize;
-
- UInt64 _inSizeProcessed;
- UInt64 _outSizeProcessed;
+ UInt64 _inProcessed;
+ UInt64 _outProcessed;
+ UInt32 _outStep;
UInt32 _inBufSize;
UInt32 _inBufSizeNew;
- UInt32 _outStepSize;
CLzma2Dec _state;
-public:
+public:
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
@@ -59,28 +56,27 @@ 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(GetInStreamProcessedSize)(UInt64 *value);
-
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
+ #ifndef NO_READ_FROM_CODER
+
+private:
+ CMyComPtr<ISequentialInStream> _inStream;
+public:
+
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
-
- STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
-
- #ifndef NO_READ_FROM_CODER
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
#endif
CDecoder();
virtual ~CDecoder();
-
};
}}
diff --git a/CPP/7zip/Compress/Lzma2Encoder.cpp b/CPP/7zip/Compress/Lzma2Encoder.cpp
index 06a11f10..9b3258cd 100644
--- a/CPP/7zip/Compress/Lzma2Encoder.cpp
+++ b/CPP/7zip/Compress/Lzma2Encoder.cpp
@@ -82,11 +82,15 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
- CSeqInStreamWrap inWrap(inStream);
- CSeqOutStreamWrap outWrap(outStream);
- CCompressProgressWrap progressWrap(progress);
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
+
+ inWrap.Init(inStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
- SRes res = Lzma2Enc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL);
+ SRes res = Lzma2Enc_Encode(_encoder, &outWrap.vt, &inWrap.vt, progress ? &progressWrap.vt : NULL);
if (res == SZ_ERROR_READ && inWrap.Res != S_OK)
return inWrap.Res;
if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK)
diff --git a/CPP/7zip/Compress/LzmaDecoder.cpp b/CPP/7zip/Compress/LzmaDecoder.cpp
index 9002678a..2fbe0589 100644
--- a/CPP/7zip/Compress/LzmaDecoder.cpp
+++ b/CPP/7zip/Compress/LzmaDecoder.cpp
@@ -24,14 +24,19 @@ static HRESULT SResToHRESULT(SRes res)
namespace NCompress {
namespace NLzma {
-CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false),
- _inBufSize(1 << 20),
- _outBufSize(1 << 22),
+CDecoder::CDecoder():
+ _inBuf(NULL),
+ _lzmaStatus(LZMA_STATUS_NOT_SPECIFIED),
FinishStream(false),
- NeedMoreInput(false)
+ _propsWereSet(false),
+ _outSizeDefined(false),
+ _outStep(1 << 22),
+ _inBufSize(0),
+ _inBufSizeNew(1 << 20)
{
- _inSizeProcessed = 0;
- _inPos = _inSize = 0;
+ _inProcessed = 0;
+ _inPos = _inLim = 0;
+
LzmaDec_Construct(&_state);
}
@@ -41,22 +46,24 @@ CDecoder::~CDecoder()
MyFree(_inBuf);
}
-STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; }
-STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; }
+STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; }
+STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStep = size; return S_OK; }
HRESULT CDecoder::CreateInputBuffer()
{
- if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated)
+ if (!_inBuf || _inBufSizeNew != _inBufSize)
{
MyFree(_inBuf);
- _inBuf = (Byte *)MyAlloc(_inBufSize);
- if (_inBuf == 0)
+ _inBufSize = 0;
+ _inBuf = (Byte *)MyAlloc(_inBufSizeNew);
+ if (!_inBuf)
return E_OUTOFMEMORY;
- _inBufSizeAllocated = _inBufSize;
+ _inBufSize = _inBufSizeNew;
}
return S_OK;
}
+
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
{
RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_Alloc)));
@@ -64,203 +71,266 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
return CreateInputBuffer();
}
+
void CDecoder::SetOutStreamSizeResume(const UInt64 *outSize)
{
_outSizeDefined = (outSize != NULL);
+ _outSize = 0;
if (_outSizeDefined)
_outSize = *outSize;
- _outSizeProcessed = 0;
- _wrPos = 0;
+ _outProcessed = 0;
+ _lzmaStatus = LZMA_STATUS_NOT_SPECIFIED;
+
LzmaDec_Init(&_state);
}
+
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
- _inSizeProcessed = 0;
- _inPos = _inSize = 0;
- NeedMoreInput = false;
+ _inProcessed = 0;
+ _inPos = _inLim = 0;
SetOutStreamSizeResume(outSize);
return S_OK;
}
+
STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
{
FinishStream = (finishMode != 0);
return S_OK;
}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _inProcessed;
+ return S_OK;
+}
+
+
HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
{
- if (_inBuf == 0 || !_propsWereSet)
+ if (!_inBuf || !_propsWereSet)
return S_FALSE;
+
+ const UInt64 startInProgress = _inProcessed;
+ SizeT wrPos = _state.dicPos;
+ HRESULT readRes = S_OK;
- UInt64 startInProgress = _inSizeProcessed;
-
- SizeT next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize);
for (;;)
{
- if (_inPos == _inSize)
+ if (_inPos == _inLim && readRes == S_OK)
{
- _inPos = _inSize = 0;
- RINOK(inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));
+ _inPos = _inLim = 0;
+ readRes = inStream->Read(_inBuf, _inBufSize, &_inLim);
+ }
+
+ const SizeT dicPos = _state.dicPos;
+ SizeT size;
+ {
+ SizeT next = _state.dicBufSize;
+ if (next - wrPos > _outStep)
+ next = wrPos + _outStep;
+ size = next - dicPos;
}
- SizeT dicPos = _state.dicPos;
- SizeT curSize = next - dicPos;
-
ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
if (_outSizeDefined)
{
- const UInt64 rem = _outSize - _outSizeProcessed;
- if (rem <= curSize)
+ const UInt64 rem = _outSize - _outProcessed;
+ if (size >= rem)
{
- curSize = (SizeT)rem;
+ size = (SizeT)rem;
if (FinishStream)
finishMode = LZMA_FINISH_END;
}
}
- SizeT inSizeProcessed = _inSize - _inPos;
+ SizeT inProcessed = _inLim - _inPos;
ELzmaStatus status;
- SRes res = LzmaDec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status);
+
+ SRes res = LzmaDec_DecodeToDic(&_state, dicPos + size, _inBuf + _inPos, &inProcessed, finishMode, &status);
+
+ _lzmaStatus = status;
+ _inPos += (UInt32)inProcessed;
+ _inProcessed += inProcessed;
+ const SizeT outProcessed = _state.dicPos - dicPos;
+ _outProcessed += outProcessed;
- _inPos += (UInt32)inSizeProcessed;
- _inSizeProcessed += inSizeProcessed;
- SizeT outSizeProcessed = _state.dicPos - dicPos;
- _outSizeProcessed += outSizeProcessed;
+ // we check for LZMA_STATUS_NEEDS_MORE_INPUT to allow RangeCoder initialization, if (_outSizeDefined && _outSize == 0)
+ bool outFinished = (_outSizeDefined && _outProcessed >= _outSize);
- bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0);
- bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize);
+ bool needStop = (res != 0
+ || (inProcessed == 0 && outProcessed == 0)
+ || status == LZMA_STATUS_FINISHED_WITH_MARK
+ || (outFinished && status != LZMA_STATUS_NEEDS_MORE_INPUT));
- if (res != 0 || _state.dicPos == next || finished || stopDecoding)
+ if (needStop || outProcessed >= size)
{
- HRESULT res2 = WriteStream(outStream, _state.dic + _wrPos, _state.dicPos - _wrPos);
+ HRESULT res2 = WriteStream(outStream, _state.dic + wrPos, _state.dicPos - wrPos);
- _wrPos = _state.dicPos;
if (_state.dicPos == _state.dicBufSize)
- {
_state.dicPos = 0;
- _wrPos = 0;
- }
- next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize);
-
- if (res != 0)
- return S_FALSE;
+ wrPos = _state.dicPos;
+
RINOK(res2);
- if (stopDecoding)
+
+ if (needStop)
{
- if (status == LZMA_STATUS_NEEDS_MORE_INPUT)
- NeedMoreInput = true;
- if (FinishStream &&
- status != LZMA_STATUS_FINISHED_WITH_MARK &&
- status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
+ if (res != 0)
return S_FALSE;
- return S_OK;
- }
- if (finished)
- {
- if (status == LZMA_STATUS_NEEDS_MORE_INPUT)
- NeedMoreInput = true;
- return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE);
+
+ if (status == LZMA_STATUS_FINISHED_WITH_MARK)
+ {
+ if (FinishStream)
+ if (_outSizeDefined && _outSize != _outProcessed)
+ return S_FALSE;
+ return readRes;
+ }
+
+ if (outFinished && status != LZMA_STATUS_NEEDS_MORE_INPUT)
+ if (!FinishStream || status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
+ return readRes;
+
+ return S_FALSE;
}
}
+
if (progress)
{
- UInt64 inSize = _inSizeProcessed - startInProgress;
- RINOK(progress->SetRatioInfo(&inSize, &_outSizeProcessed));
+ const UInt64 inSize = _inProcessed - startInProgress;
+ RINOK(progress->SetRatioInfo(&inSize, &_outProcessed));
}
}
}
+
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
- const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
- if (_inBuf == 0)
+ if (!_inBuf)
return E_INVALIDARG;
SetOutStreamSize(outSize);
- return CodeSpec(inStream, outStream, progress);
+ HRESULT res = CodeSpec(inStream, outStream, progress);
+ if (res == S_OK)
+ if (FinishStream && inSize && *inSize != _inProcessed)
+ res = S_FALSE;
+ return res;
}
+
#ifndef NO_READ_FROM_CODER
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
+
STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
- do
+
+ ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
+ if (_outSizeDefined)
{
- if (_inPos == _inSize)
+ const UInt64 rem = _outSize - _outProcessed;
+ if (size >= rem)
{
- _inPos = _inSize = 0;
- RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));
+ size = (UInt32)rem;
+ if (FinishStream)
+ finishMode = LZMA_FINISH_END;
}
+ }
+
+ HRESULT readRes = S_OK;
+
+ for (;;)
+ {
+ if (_inPos == _inLim && readRes == S_OK)
{
- SizeT inProcessed = _inSize - _inPos;
+ _inPos = _inLim = 0;
+ readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim);
+ }
- if (_outSizeDefined)
- {
- const UInt64 rem = _outSize - _outSizeProcessed;
- if (rem < size)
- size = (UInt32)rem;
- }
+ SizeT inProcessed = _inLim - _inPos;
+ SizeT outProcessed = size;
+ ELzmaStatus status;
+
+ SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,
+ _inBuf + _inPos, &inProcessed, finishMode, &status);
+
+ _lzmaStatus = status;
+ _inPos += (UInt32)inProcessed;
+ _inProcessed += inProcessed;
+ _outProcessed += outProcessed;
+ size -= (UInt32)outProcessed;
+ data = (Byte *)data + outProcessed;
+ if (processedSize)
+ *processedSize += (UInt32)outProcessed;
+
+ if (res != 0)
+ return S_FALSE;
+
+ /*
+ if (status == LZMA_STATUS_FINISHED_WITH_MARK)
+ return readRes;
- SizeT outProcessed = size;
- ELzmaStatus status;
- SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,
- _inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status);
- _inPos += (UInt32)inProcessed;
- _inSizeProcessed += inProcessed;
- _outSizeProcessed += outProcessed;
- size -= (UInt32)outProcessed;
- data = (Byte *)data + outProcessed;
- if (processedSize)
- *processedSize += (UInt32)outProcessed;
- RINOK(SResToHRESULT(res));
- if (inProcessed == 0 && outProcessed == 0)
- return S_OK;
+ if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT)
+ {
+ if (FinishStream
+ && _outSizeDefined && _outProcessed >= _outSize
+ && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
+ return S_FALSE;
+ return readRes;
}
+ */
+
+ if (inProcessed == 0 && outProcessed == 0)
+ return readRes;
}
- while (size != 0);
- return S_OK;
}
+
HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress)
{
SetOutStreamSizeResume(outSize);
return CodeSpec(_inStream, outStream, progress);
}
+
HRESULT CDecoder::ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize)
{
RINOK(CreateInputBuffer());
+
if (processedSize)
*processedSize = 0;
- while (size > 0)
+
+ HRESULT readRes = S_OK;
+
+ while (size != 0)
{
- if (_inPos == _inSize)
+ if (_inPos == _inLim)
{
- _inPos = _inSize = 0;
- RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));
- if (_inSize == 0)
+ _inPos = _inLim = 0;
+ if (readRes == S_OK)
+ readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim);
+ if (_inLim == 0)
break;
}
- {
- UInt32 curSize = _inSize - _inPos;
- if (curSize > size)
- curSize = size;
- memcpy(data, _inBuf + _inPos, curSize);
- _inPos += curSize;
- _inSizeProcessed += curSize;
- size -= curSize;
- data = (Byte *)data + curSize;
- if (processedSize)
- *processedSize += curSize;
- }
+
+ UInt32 cur = _inLim - _inPos;
+ if (cur > size)
+ cur = size;
+ memcpy(data, _inBuf + _inPos, cur);
+ _inPos += cur;
+ _inProcessed += cur;
+ size -= cur;
+ data = (Byte *)data + cur;
+ if (processedSize)
+ *processedSize += cur;
}
- return S_OK;
+
+ return readRes;
}
#endif
diff --git a/CPP/7zip/Compress/LzmaDecoder.h b/CPP/7zip/Compress/LzmaDecoder.h
index f1f839a4..e73925ed 100644
--- a/CPP/7zip/Compress/LzmaDecoder.h
+++ b/CPP/7zip/Compress/LzmaDecoder.h
@@ -15,6 +15,7 @@ class CDecoder:
public ICompressCoder,
public ICompressSetDecoderProperties2,
public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
public ICompressSetBufSize,
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
@@ -23,21 +24,26 @@ class CDecoder:
#endif
public CMyUnknownImp
{
- CMyComPtr<ISequentialInStream> _inStream;
Byte *_inBuf;
UInt32 _inPos;
- UInt32 _inSize;
+ UInt32 _inLim;
+
CLzmaDec _state;
+ ELzmaStatus _lzmaStatus;
+
+public:
+ bool FinishStream; // set it before decoding, if you need to decode full LZMA stream
+
+private:
bool _propsWereSet;
bool _outSizeDefined;
UInt64 _outSize;
- UInt64 _inSizeProcessed;
- UInt64 _outSizeProcessed;
+ UInt64 _inProcessed;
+ UInt64 _outProcessed;
- UInt32 _inBufSizeAllocated;
+ UInt32 _outStep;
UInt32 _inBufSize;
- UInt32 _outBufSize;
- SizeT _wrPos;
+ UInt32 _inBufSizeNew;
HRESULT CreateInputBuffer();
HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
@@ -47,6 +53,7 @@ public:
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
+ MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize)
#ifndef NO_READ_FROM_CODER
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
@@ -60,11 +67,16 @@ public:
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
STDMETHOD(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
#ifndef NO_READ_FROM_CODER
+
+private:
+ CMyComPtr<ISequentialInStream> _inStream;
+public:
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
@@ -72,18 +84,24 @@ public:
HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
HRESULT ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize);
- UInt64 GetInputProcessedSize() const { return _inSizeProcessed; }
-
+
#endif
- bool FinishStream; // set it before decoding, if you need to decode full LZMA stream
-
- bool NeedMoreInput; // it's set by decoder, if it needs more input data to decode stream
+ UInt64 GetInputProcessedSize() const { return _inProcessed; }
CDecoder();
virtual ~CDecoder();
- UInt64 GetOutputProcessedSize() const { return _outSizeProcessed; }
+ UInt64 GetOutputProcessedSize() const { return _outProcessed; }
+
+ bool NeedsMoreInput() const { return _lzmaStatus == LZMA_STATUS_NEEDS_MORE_INPUT; }
+
+ bool CheckFinishStatus(bool withEndMark) const
+ {
+ return _lzmaStatus == (withEndMark ?
+ LZMA_STATUS_FINISHED_WITH_MARK :
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK);
+ }
};
}}
diff --git a/CPP/7zip/Compress/LzmaEncoder.cpp b/CPP/7zip/Compress/LzmaEncoder.cpp
index 0a7e294d..38966f6f 100644
--- a/CPP/7zip/Compress/LzmaEncoder.cpp
+++ b/CPP/7zip/Compress/LzmaEncoder.cpp
@@ -134,11 +134,16 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
- CSeqInStreamWrap inWrap(inStream);
- CSeqOutStreamWrap outWrap(outStream);
- CCompressProgressWrap progressWrap(progress);
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
+
+ inWrap.Init(inStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
+
+ SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, progress ? &progressWrap.vt : NULL, &g_Alloc, &g_BigAlloc);
- SRes res = LzmaEnc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL, &g_Alloc, &g_BigAlloc);
_inputProcessed = inWrap.Processed;
if (res == SZ_ERROR_READ && inWrap.Res != S_OK)
return inWrap.Res;
diff --git a/CPP/7zip/Compress/LzmaEncoder.h b/CPP/7zip/Compress/LzmaEncoder.h
index f919ac2c..3d472d67 100644
--- a/CPP/7zip/Compress/LzmaEncoder.h
+++ b/CPP/7zip/Compress/LzmaEncoder.h
@@ -30,7 +30,9 @@ public:
CEncoder();
virtual ~CEncoder();
+
UInt64 GetInputProcessedSize() const { return _inputProcessed; }
+ bool IsWriteEndMark() const { return LzmaEnc_IsWriteEndMark(_encoder) != 0; }
};
}}
diff --git a/CPP/7zip/Compress/LzmsDecoder.cpp b/CPP/7zip/Compress/LzmsDecoder.cpp
index 0e823446..02a7f5dc 100644
--- a/CPP/7zip/Compress/LzmsDecoder.cpp
+++ b/CPP/7zip/Compress/LzmsDecoder.cpp
@@ -114,8 +114,8 @@ static void x86_Filter(Byte *data, UInt32 size, Int32 *history)
size -= 16;
const unsigned kSave = 6;
- const Byte savedByte = data[size + kSave];
- data[size + kSave] = 0xE8;
+ const Byte savedByte = data[(size_t)size + kSave];
+ data[(size_t)size + kSave] = 0xE8;
Int32 last_x86_pos = -k_x86_TransOffset - 1;
// first byte is ignored
@@ -215,7 +215,7 @@ static void x86_Filter(Byte *data, UInt32 size, Int32 *history)
*target = i;
}
- data[size + kSave] = savedByte;
+ data[(size_t)size + kSave] = savedByte;
}
diff --git a/CPP/7zip/Compress/LzxDecoder.cpp b/CPP/7zip/Compress/LzxDecoder.cpp
index 55231ce5..a7bba903 100644
--- a/CPP/7zip/Compress/LzxDecoder.cpp
+++ b/CPP/7zip/Compress/LzxDecoder.cpp
@@ -27,8 +27,8 @@ static void x86_Filter(Byte *data, UInt32 size, UInt32 processedSize, UInt32 tra
return;
size -= kResidue;
- Byte save = data[size + 4];
- data[size + 4] = 0xE8;
+ Byte save = data[(size_t)size + 4];
+ data[(size_t)size + 4] = 0xE8;
for (UInt32 i = 0;;)
{
@@ -57,7 +57,7 @@ static void x86_Filter(Byte *data, UInt32 size, UInt32 processedSize, UInt32 tra
}
}
- data[size + 4] = save;
+ data[(size_t)size + 4] = save;
}
diff --git a/CPP/7zip/Compress/Mtf8.h b/CPP/7zip/Compress/Mtf8.h
index 5d49fe44..50a84cee 100644
--- a/CPP/7zip/Compress/Mtf8.h
+++ b/CPP/7zip/Compress/Mtf8.h
@@ -11,11 +11,11 @@ struct CMtf8Encoder
{
Byte Buf[256];
- unsigned FindAndMove(Byte v)
+ unsigned FindAndMove(Byte v) throw()
{
- unsigned pos;
+ size_t pos;
for (pos = 0; Buf[pos] != v; pos++);
- unsigned resPos = pos;
+ unsigned resPos = (unsigned)pos;
for (; pos >= 8; pos -= 8)
{
Buf[pos] = Buf[pos - 1];
@@ -39,9 +39,10 @@ struct CMtf8Decoder
{
Byte Buf[256];
- void Init(int) {};
+ void StartInit() { memset(Buf, 0, sizeof(Buf)); }
+ void Add(unsigned pos, Byte val) { Buf[pos] = val; }
Byte GetHead() const { return Buf[0]; }
- Byte GetAndMove(int pos)
+ Byte GetAndMove(unsigned pos)
{
Byte res = Buf[pos];
for (; pos >= 8; pos -= 8)
@@ -64,11 +65,11 @@ struct CMtf8Decoder
*/
#ifdef MY_CPU_64BIT
-typedef UInt64 CMtfVar;
-#define MTF_MOVS 3
+ typedef UInt64 CMtfVar;
+ #define MTF_MOVS 3
#else
-typedef UInt32 CMtfVar;
-#define MTF_MOVS 2
+ typedef UInt32 CMtfVar;
+ #define MTF_MOVS 2
#endif
#define MTF_MASK ((1 << MTF_MOVS) - 1)
@@ -81,13 +82,18 @@ struct CMtf8Decoder
void StartInit() { memset(Buf, 0, sizeof(Buf)); }
void Add(unsigned pos, Byte val) { Buf[pos >> MTF_MOVS] |= ((CMtfVar)val << ((pos & MTF_MASK) << 3)); }
Byte GetHead() const { return (Byte)Buf[0]; }
- Byte GetAndMove(unsigned pos)
+
+ MY_FORCE_INLINE
+ Byte GetAndMove(unsigned pos) throw()
{
UInt32 lim = ((UInt32)pos >> MTF_MOVS);
pos = (pos & MTF_MASK) << 3;
CMtfVar prev = (Buf[lim] >> pos) & 0xFF;
UInt32 i = 0;
+
+
+ /*
if ((lim & 1) != 0)
{
CMtfVar next = Buf[0];
@@ -104,6 +110,16 @@ struct CMtf8Decoder
Buf[i + 1] = (n1 << 8) | (n0 >> (MTF_MASK << 3));
prev = (n1 >> (MTF_MASK << 3));
}
+ */
+
+ for (; i < lim; i++)
+ {
+ CMtfVar n0 = Buf[i];
+ Buf[i ] = (n0 << 8) | prev;
+ prev = (n0 >> (MTF_MASK << 3));
+ }
+
+
CMtfVar next = Buf[i];
CMtfVar mask = (((CMtfVar)0x100 << pos) - 1);
Buf[i] = (next & ~mask) | (((next << 8) | prev) & mask);
@@ -117,7 +133,7 @@ class CMtf8Decoder
{
Byte SmallBuffer[kSmallSize];
int SmallSize;
- Byte Counts[16];
+ int Counts[16];
int Size;
public:
Byte Buf[256];
@@ -140,6 +156,11 @@ public:
}
}
+ void Add(unsigned pos, Byte val)
+ {
+ Buf[pos] = val;
+ }
+
Byte GetAndMove(int pos)
{
if (pos < SmallSize)
diff --git a/CPP/7zip/Compress/PpmdDecoder.cpp b/CPP/7zip/Compress/PpmdDecoder.cpp
index c868730e..ed0e9e29 100644
--- a/CPP/7zip/Compress/PpmdDecoder.cpp
+++ b/CPP/7zip/Compress/PpmdDecoder.cpp
@@ -75,7 +75,7 @@ HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size)
int sym = 0;
for (i = 0; i != size; i++)
{
- sym = Ppmd7_DecodeSymbol(&_ppmd, &_rangeDec.p);
+ sym = Ppmd7_DecodeSymbol(&_ppmd, &_rangeDec.vt);
if (_inStream.Extra || sym < 0)
break;
memStream[i] = (Byte)sym;
@@ -134,6 +134,13 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
return S_OK;
}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _inStream.GetProcessed();
+ return S_OK;
+}
+
#ifndef NO_READ_FROM_CODER
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
diff --git a/CPP/7zip/Compress/PpmdDecoder.h b/CPP/7zip/Compress/PpmdDecoder.h
index 8ebcd700..2b6213c0 100644
--- a/CPP/7zip/Compress/PpmdDecoder.h
+++ b/CPP/7zip/Compress/PpmdDecoder.h
@@ -18,6 +18,7 @@ namespace NPpmd {
class CDecoder :
public ICompressCoder,
public ICompressSetDecoderProperties2,
+ public ICompressGetInStreamProcessedSize,
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
public ICompressSetOutStreamSize,
@@ -42,19 +43,26 @@ public:
#ifndef NO_READ_FROM_CODER
CMyComPtr<ISequentialInStream> InSeqStream;
- MY_UNKNOWN_IMP4(
- ICompressSetDecoderProperties2,
- ICompressSetInStream,
- ICompressSetOutStreamSize,
- ISequentialInStream)
- #else
- MY_UNKNOWN_IMP1(
- ICompressSetDecoderProperties2)
#endif
+ MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
+ // MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
+ MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
+ #ifndef NO_READ_FROM_CODER
+ MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
+ MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
+ #endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
#ifndef NO_READ_FROM_CODER
@@ -66,7 +74,7 @@ public:
CDecoder(): _outBuf(NULL), _outSizeDefined(false)
{
Ppmd7z_RangeDec_CreateVTable(&_rangeDec);
- _rangeDec.Stream = &_inStream.p;
+ _rangeDec.Stream = &_inStream.vt;
Ppmd7_Construct(&_ppmd);
}
diff --git a/CPP/7zip/Compress/PpmdEncoder.cpp b/CPP/7zip/Compress/PpmdEncoder.cpp
index 00ea9668..34e6d361 100644
--- a/CPP/7zip/Compress/PpmdEncoder.cpp
+++ b/CPP/7zip/Compress/PpmdEncoder.cpp
@@ -43,7 +43,7 @@ CEncoder::CEncoder():
_inBuf(NULL)
{
_props.Normalize(-1);
- _rangeEnc.Stream = &_outStream.p;
+ _rangeEnc.Stream = &_outStream.vt;
Ppmd7_Construct(&_ppmd);
}
diff --git a/CPP/7zip/Compress/PpmdZip.cpp b/CPP/7zip/Compress/PpmdZip.cpp
index 24dd32f2..d9ce218a 100644
--- a/CPP/7zip/Compress/PpmdZip.cpp
+++ b/CPP/7zip/Compress/PpmdZip.cpp
@@ -15,7 +15,7 @@ namespace NPpmdZip {
CDecoder::CDecoder(bool fullFileMode):
_fullFileMode(fullFileMode)
{
- _ppmd.Stream.In = &_inStream.p;
+ _ppmd.Stream.In = &_inStream.vt;
Ppmd8_Construct(&_ppmd);
}
@@ -25,7 +25,7 @@ CDecoder::~CDecoder()
}
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
- const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
if (!_outStream.Alloc())
return E_OUTOFMEMORY;
@@ -64,15 +64,21 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
bool wasFinished = false;
UInt64 processedSize = 0;
- while (!outSize || processedSize < *outSize)
+
+ for (;;)
{
size_t size = kBufSize;
- if (outSize != NULL)
+ if (outSize)
{
const UInt64 rem = *outSize - processedSize;
if (size > rem)
+ {
size = (size_t)rem;
+ if (size == 0)
+ break;
+ }
}
+
Byte *data = _outStream.Buf;
size_t i = 0;
int sym = 0;
@@ -84,6 +90,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
data[i] = (Byte)sym;
}
while (++i != size);
+
processedSize += i;
RINOK(WriteStream(outStream, _outStream.Buf, i));
@@ -99,13 +106,16 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
wasFinished = true;
break;
}
+
if (progress)
{
- UInt64 inSize = _inStream.GetProcessed();
- RINOK(progress->SetRatioInfo(&inSize, &processedSize));
+ const UInt64 inProccessed = _inStream.GetProcessed();
+ RINOK(progress->SetRatioInfo(&inProccessed, &processedSize));
}
}
+
RINOK(_inStream.Res);
+
if (_fullFileMode)
{
if (!wasFinished)
@@ -117,11 +127,29 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
}
if (!Ppmd8_RangeDec_IsFinishedOK(&_ppmd))
return S_FALSE;
+
+ if (inSize && *inSize != _inStream.GetProcessed())
+ return S_FALSE;
}
+
+ return S_OK;
+}
+
+
+STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
+{
+ _fullFileMode = (finishMode != 0);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _inStream.GetProcessed();
return S_OK;
}
+
// ---------- Encoder ----------
void CEncProps::Normalize(int level)
@@ -206,7 +234,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA
CEncoder::CEncoder()
{
_props.Normalize(-1);
- _ppmd.Stream.Out = &_outStream.p;
+ _ppmd.Stream.Out = &_outStream.vt;
Ppmd8_Construct(&_ppmd);
}
@@ -248,10 +276,10 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
RINOK(_outStream.Res);
}
processed += size;
- if (progress != NULL)
+ if (progress)
{
- UInt64 outSize = _outStream.GetProcessed();
- RINOK(progress->SetRatioInfo(&processed, &outSize));
+ const UInt64 outProccessed = _outStream.GetProcessed();
+ RINOK(progress->SetRatioInfo(&processed, &outProccessed));
}
}
}
diff --git a/CPP/7zip/Compress/PpmdZip.h b/CPP/7zip/Compress/PpmdZip.h
index e15a060d..b8c7aae0 100644
--- a/CPP/7zip/Compress/PpmdZip.h
+++ b/CPP/7zip/Compress/PpmdZip.h
@@ -31,8 +31,11 @@ struct CBuf
}
};
+
class CDecoder :
public ICompressCoder,
+ public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
public CMyUnknownImp
{
CByteInBufWrap _inStream;
@@ -40,13 +43,20 @@ class CDecoder :
CPpmd8 _ppmd;
bool _fullFileMode;
public:
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP2(
+ ICompressSetFinishMode,
+ ICompressGetInStreamProcessedSize)
+
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
CDecoder(bool fullFileMode);
~CDecoder();
};
+
struct CEncProps
{
UInt32 MemSizeMB;
diff --git a/CPP/7zip/Compress/QuantumDecoder.cpp b/CPP/7zip/Compress/QuantumDecoder.cpp
index 2adb9053..64e35bf2 100644
--- a/CPP/7zip/Compress/QuantumDecoder.cpp
+++ b/CPP/7zip/Compress/QuantumDecoder.cpp
@@ -37,7 +37,7 @@ unsigned CModelDecoder::Decode(CRangeDecoder *rc)
unsigned i;
for (i = 1; Freqs[i] > threshold; i++);
- rc->Decode(Freqs[i], Freqs[i - 1], Freqs[0]);
+ rc->Decode(Freqs[i], Freqs[(size_t)i - 1], Freqs[0]);
unsigned res = Vals[--i];
do
@@ -50,7 +50,7 @@ unsigned CModelDecoder::Decode(CRangeDecoder *rc)
{
ReorderCount = kReorderCount;
for (i = 0; i < NumItems; i++)
- Freqs[i] = (UInt16)(((Freqs[i] - Freqs[i + 1]) + 1) >> 1);
+ Freqs[i] = (UInt16)(((Freqs[i] - Freqs[(size_t)i + 1]) + 1) >> 1);
for (i = 0; i < NumItems - 1; i++)
for (unsigned j = i + 1; j < NumItems; j++)
if (Freqs[i] < Freqs[j])
@@ -64,7 +64,7 @@ unsigned CModelDecoder::Decode(CRangeDecoder *rc)
}
do
- Freqs[i] = (UInt16)(Freqs[i] + Freqs[i + 1]);
+ Freqs[i] = (UInt16)(Freqs[i] + Freqs[(size_t)i + 1]);
while (i--);
}
else
@@ -73,8 +73,8 @@ unsigned CModelDecoder::Decode(CRangeDecoder *rc)
do
{
Freqs[i] >>= 1;
- if (Freqs[i] <= Freqs[i + 1])
- Freqs[i] = (UInt16)(Freqs[i + 1] + 1);
+ if (Freqs[i] <= Freqs[(size_t)i + 1])
+ Freqs[i] = (UInt16)(Freqs[(size_t)i + 1] + 1);
}
while (i--);
}
diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp
index 1aaedcc1..0a552506 100644
--- a/CPP/7zip/Compress/Rar1Decoder.cpp
+++ b/CPP/7zip/Compress/Rar1Decoder.cpp
@@ -57,7 +57,7 @@ UInt32 CDecoder::DecodeNum(const UInt32 *posTab)
UInt32 num = m_InBitStream.GetValue(12);
for (;;)
{
- UInt32 cur = (posTab[startPos + 1] - posTab[startPos]) << (12 - startPos);
+ UInt32 cur = (posTab[(size_t)startPos + 1] - posTab[startPos]) << (12 - startPos);
if (num < cur)
break;
startPos++;
@@ -149,7 +149,7 @@ HRESULT CDecoder::ShortLZ()
PlaceA[dist]--;
UInt32 lastDistance = ChSetA[(unsigned)distancePlace];
PlaceA[lastDistance]++;
- ChSetA[(unsigned)distancePlace + 1] = lastDistance;
+ ChSetA[(size_t)(unsigned)distancePlace + 1] = lastDistance;
ChSetA[(unsigned)distancePlace] = dist;
}
len += 2;
diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp
index db67433a..e906deef 100644
--- a/CPP/7zip/Compress/Rar2Decoder.cpp
+++ b/CPP/7zip/Compress/Rar2Decoder.cpp
@@ -104,7 +104,8 @@ bool CDecoder::ReadTables(void)
m_TablesOK = false;
Byte levelLevels[kLevelTableSize];
- Byte newLevels[kMaxTableSize];
+ Byte lens[kMaxTableSize];
+
m_AudioMode = (ReadBits(1) == 1);
if (ReadBits(1) == 0)
@@ -134,16 +135,29 @@ bool CDecoder::ReadTables(void)
UInt32 sym = m_LevelDecoder.Decode(&m_InBitStream);
if (sym < kTableDirectLevels)
{
- newLevels[i] = (Byte)((sym + m_LastLevels[i]) & kLevelMask);
+ lens[i] = (Byte)((sym + m_LastLevels[i]) & kLevelMask);
i++;
}
else
{
if (sym == kTableLevelRepNumber)
{
- unsigned t = ReadBits(2) + 3;
- for (unsigned reps = t; reps > 0 && i < numLevels; reps--, i++)
- newLevels[i] = newLevels[i - 1];
+ unsigned num = ReadBits(2) + 3;
+ if (i == 0)
+ {
+ // return false;
+ continue; // original unRAR
+ }
+ num += i;
+ if (num > numLevels)
+ {
+ // return false;
+ num = numLevels; // original unRAR
+ }
+ Byte v = lens[(size_t)i - 1];
+ do
+ lens[i++] = v;
+ while (i < num);
}
else
{
@@ -154,8 +168,15 @@ bool CDecoder::ReadTables(void)
num = ReadBits(7) + 11;
else
return false;
- for (; num > 0 && i < numLevels; num--)
- newLevels[i++] = 0;
+ num += i;
+ if (num > numLevels)
+ {
+ // return false;
+ num = numLevels; // original unRAR
+ }
+ do
+ lens[i++] = 0;
+ while (i < num);
}
}
}
@@ -163,16 +184,16 @@ bool CDecoder::ReadTables(void)
if (m_AudioMode)
for (i = 0; i < m_NumChannels; i++)
{
- RIF(m_MMDecoders[i].Build(&newLevels[i * kMMTableSize]));
+ RIF(m_MMDecoders[i].Build(&lens[i * kMMTableSize]));
}
else
{
- RIF(m_MainDecoder.Build(&newLevels[0]));
- RIF(m_DistDecoder.Build(&newLevels[kMainTableSize]));
- RIF(m_LenDecoder.Build(&newLevels[kMainTableSize + kDistTableSize]));
+ RIF(m_MainDecoder.Build(&lens[0]));
+ RIF(m_DistDecoder.Build(&lens[kMainTableSize]));
+ RIF(m_LenDecoder.Build(&lens[kMainTableSize + kDistTableSize]));
}
- memcpy(m_LastLevels, newLevels, kMaxTableSize);
+ memcpy(m_LastLevels, lens, kMaxTableSize);
m_TablesOK = true;
@@ -220,13 +241,11 @@ public:
bool CDecoder::DecodeMm(UInt32 pos)
{
- while (pos-- > 0)
+ while (pos-- != 0)
{
UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].Decode(&m_InBitStream);
- if (symbol == 256)
- return true;
- if (symbol >= kMMTableSize)
- return false;
+ if (symbol >= 256)
+ return symbol == 256;
/*
Byte byPredict = m_Predictor.Predict();
Byte byReal = (Byte)(byPredict - (Byte)symbol);
@@ -254,6 +273,8 @@ bool CDecoder::DecodeLz(Int32 pos)
}
else if (sym >= kMatchNumber)
{
+ if (sym >= kMainTableSize)
+ return false;
sym -= kMatchNumber;
length = kNormalMatchMinLen + UInt32(kLenStart[sym]) +
m_InBitStream.ReadBits(kLenDirectBits[sym]);
@@ -302,10 +323,9 @@ bool CDecoder::DecodeLz(Int32 pos)
m_InBitStream.ReadBits(kLen2DistDirectBits[sym]);
length = 2;
}
- else if (sym == kReadTableNumber)
+ else // (sym == kReadTableNumber)
return true;
- else
- return false;
+
m_RepDists[m_RepDistPtr++ & 3] = distance;
m_LastLength = length;
if (!m_OutWindowStream.CopyBlock(distance, length))
diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp
index 3bf25132..a4f23524 100644
--- a/CPP/7zip/Compress/Rar3Decoder.cpp
+++ b/CPP/7zip/Compress/Rar3Decoder.cpp
@@ -44,15 +44,17 @@ static const UInt32 kVmCodeSizeMax = 1 << 16;
extern "C" {
-static UInt32 Range_GetThreshold(void *pp, UInt32 total)
+#define GET_RangeDecoder CRangeDecoder *p = CONTAINER_FROM_VTBL_CLS(pp, CRangeDecoder, vt);
+
+static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total)
{
- CRangeDecoder *p = (CRangeDecoder *)pp;
+ GET_RangeDecoder;
return p->Code / (p->Range /= total);
}
-static void Range_Decode(void *pp, UInt32 start, UInt32 size)
+static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size)
{
- CRangeDecoder *p = (CRangeDecoder *)pp;
+ GET_RangeDecoder;
start *= p->Range;
p->Low += start;
p->Code -= start;
@@ -60,28 +62,28 @@ static void Range_Decode(void *pp, UInt32 start, UInt32 size)
p->Normalize();
}
-static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
+static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0)
{
- CRangeDecoder *p = (CRangeDecoder *)pp;
+ GET_RangeDecoder;
if (p->Code / (p->Range >>= 14) < size0)
{
- Range_Decode(p, 0, size0);
+ Range_Decode(&p->vt, 0, size0);
return 0;
}
else
{
- Range_Decode(p, size0, (1 << 14) - size0);
+ Range_Decode(&p->vt, size0, (1 << 14) - size0);
return 1;
}
}
}
-CRangeDecoder::CRangeDecoder()
+CRangeDecoder::CRangeDecoder() throw()
{
- s.GetThreshold = Range_GetThreshold;
- s.Decode = Range_Decode;
- s.DecodeBit = Range_DecodeBit;
+ vt.GetThreshold = Range_GetThreshold;
+ vt.Decode = Range_Decode;
+ vt.DecodeBit = Range_DecodeBit;
}
CDecoder::CDecoder():
@@ -445,7 +447,7 @@ HRESULT CDecoder::InitPPM()
return S_OK;
}
-int CDecoder::DecodePpmSymbol() { return Ppmd7_DecodeSymbol(&_ppmd, &m_InBitStream.s); }
+int CDecoder::DecodePpmSymbol() { return Ppmd7_DecodeSymbol(&_ppmd, &m_InBitStream.vt); }
HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing)
{
@@ -545,6 +547,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
return InitPPM();
}
+ TablesRead = false;
+ TablesOK = false;
+
_lzMode = true;
PrevAlignBits = 0;
PrevAlignCount = 0;
@@ -597,7 +602,7 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
if (i == 0)
return S_FALSE;
for (; num > 0 && i < kTablesSizesSum; num--, i++)
- newLevels[i] = newLevels[i - 1];
+ newLevels[i] = newLevels[(size_t)i - 1];
}
else
{
@@ -606,6 +611,7 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
}
}
}
+
TablesRead = true;
// original code has check here:
@@ -623,6 +629,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
RIF(m_LenDecoder.Build(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize]));
memcpy(m_LastLevels, newLevels, kTablesSizesSum);
+
+ TablesOK = true;
+
return S_OK;
}
@@ -641,16 +650,15 @@ public:
HRESULT CDecoder::ReadEndOfBlock(bool &keepDecompressing)
{
- if (ReadBits(1) != 0)
+ if (ReadBits(1) == 0)
{
- // old file
- TablesRead = false;
- return ReadTables(keepDecompressing);
+ // new file
+ keepDecompressing = false;
+ TablesRead = (ReadBits(1) == 0);
+ return S_OK;
}
- // new file
- keepDecompressing = false;
- TablesRead = (ReadBits(1) == 0);
- return S_OK;
+ TablesRead = false;
+ return ReadTables(keepDecompressing);
}
UInt32 kDistStart[kDistTableSize];
@@ -807,10 +815,12 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
return S_OK;
}
+
HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
{
_writtenFileSize = 0;
_unsupportedFilter = false;
+
if (!m_IsSolid)
{
_lzSize = 0;
@@ -825,6 +835,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
PpmError = true;
InitFilters();
}
+
if (!m_IsSolid || !TablesRead)
{
bool keepDecompressing;
@@ -838,6 +849,8 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
bool keepDecompressing;
if (_lzMode)
{
+ if (!TablesOK)
+ return S_FALSE;
RINOK(DecodeLZ(keepDecompressing))
}
else
diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h
index c130cec6..f2a9e345 100644
--- a/CPP/7zip/Compress/Rar3Decoder.h
+++ b/CPP/7zip/Compress/Rar3Decoder.h
@@ -102,7 +102,7 @@ const UInt32 kBot = (1 << 15);
struct CRangeDecoder
{
- IPpmd7_RangeDec s;
+ IPpmd7_RangeDec vt;
UInt32 Range;
UInt32 Code;
UInt32 Low;
@@ -130,7 +130,7 @@ public:
}
}
- CRangeDecoder();
+ CRangeDecoder() throw();
};
struct CFilter: public NVm::CProgram
@@ -200,6 +200,7 @@ class CDecoder:
UInt32 PrevAlignCount;
bool TablesRead;
+ bool TablesOK;
CPpmd7 _ppmd;
int PpmEscChar;
diff --git a/CPP/7zip/Compress/Rar3Vm.cpp b/CPP/7zip/Compress/Rar3Vm.cpp
index 5dca9eab..84e44a8e 100644
--- a/CPP/7zip/Compress/Rar3Vm.cpp
+++ b/CPP/7zip/Compress/Rar3Vm.cpp
@@ -891,53 +891,47 @@ static void E8E9Decode(Byte *data, UInt32 dataSize, UInt32 fileOffset, bool e9)
}
}
-static inline UInt32 ItaniumGetOpType(const Byte *data, unsigned bitPos)
-{
- return (data[bitPos >> 3] >> (bitPos & 7)) & 0xF;
-}
-
-static const Byte kCmdMasks[16] = {4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0};
static void ItaniumDecode(Byte *data, UInt32 dataSize, UInt32 fileOffset)
{
- UInt32 curPos = 0;
+ if (dataSize <= 21)
+ return;
fileOffset >>= 4;
- while (curPos < dataSize - 21)
+ dataSize -= 21;
+ dataSize += 15;
+ dataSize >>= 4;
+ dataSize += fileOffset;
+ do
{
- int b = (data[0] & 0x1F) - 0x10;
- if (b >= 0)
+ unsigned m = ((UInt32)0x334B0000 >> (data[0] & 0x1E)) & 3;
+ if (m)
{
- Byte cmdMask = kCmdMasks[b];
- if (cmdMask != 0)
- for (unsigned i = 0; i < 3; i++)
- if (cmdMask & (1 << i))
- {
- unsigned startPos = i * 41 + 18;
- if (ItaniumGetOpType(data, startPos + 24) == 5)
- {
- const UInt32 kMask = 0xFFFFF;
- Byte *p = data + (startPos >> 3);
- UInt32 bitField = ((UInt32)p[0]) | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16);
- unsigned inBit = (startPos & 7);
- UInt32 offset = (bitField >> inBit) & kMask;
- UInt32 andMask = ~(kMask << inBit);
- bitField = ((offset - fileOffset) & kMask) << inBit;
- for (unsigned j = 0; j < 3; j++)
- {
- p[j] &= andMask;
- p[j] |= bitField;
- andMask >>= 8;
- bitField >>= 8;
- }
- }
- }
+ m++;
+ do
+ {
+ Byte *p = data + ((size_t)m * 5 - 8);
+ if (((p[3] >> m) & 15) == 5)
+ {
+ const UInt32 kMask = 0xFFFFF;
+ // UInt32 raw = ((UInt32)p[0]) | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16);
+ UInt32 raw = GetUi32(p);
+ UInt32 v = raw >> m;
+ v -= fileOffset;
+ v &= kMask;
+ raw &= ~(kMask << m);
+ raw |= (v << m);
+ // p[0] = (Byte)raw; p[1] = (Byte)(raw >> 8); p[2] = (Byte)(raw >> 16);
+ SetUi32(p, raw);
+ }
+ }
+ while (++m <= 4);
}
data += 16;
- curPos += 16;
- fileOffset++;
}
+ while (++fileOffset != dataSize);
}
+
static void DeltaDecode(Byte *data, UInt32 dataSize, UInt32 numChannels)
{
UInt32 srcPos = 0;
diff --git a/CPP/7zip/Compress/Rar5Decoder.cpp b/CPP/7zip/Compress/Rar5Decoder.cpp
index fdd65a11..6b6e80d1 100644
--- a/CPP/7zip/Compress/Rar5Decoder.cpp
+++ b/CPP/7zip/Compress/Rar5Decoder.cpp
@@ -448,7 +448,7 @@ HRESULT CDecoder::ReadTables(CBitDecoder &_bitStream)
// return S_FALSE;
continue; // original unRAR
}
- Byte v = lens[i - 1];
+ Byte v = lens[(size_t)i - 1];
do
lens[i++] = v;
while (i < num);
@@ -475,7 +475,7 @@ HRESULT CDecoder::ReadTables(CBitDecoder &_bitStream)
_useAlignBits = false;
// _useAlignBits = true;
for (i = 0; i < kAlignTableSize; i++)
- if (lens[kMainTableSize + kDistTableSize + i] != kNumAlignBits)
+ if (lens[kMainTableSize + kDistTableSize + (size_t)i] != kNumAlignBits)
{
_useAlignBits = true;
break;
diff --git a/CPP/7zip/Compress/Rar5Decoder.h b/CPP/7zip/Compress/Rar5Decoder.h
index b0a4dd12..c37cb0e0 100644
--- a/CPP/7zip/Compress/Rar5Decoder.h
+++ b/CPP/7zip/Compress/Rar5Decoder.h
@@ -5,10 +5,9 @@
#ifndef __COMPRESS_RAR5_DECODER_H
#define __COMPRESS_RAR5_DECODER_H
-#include "../../../C/Alloc.h"
#include "../../../C/CpuArch.h"
-#include "../../Common/MyBuffer.h"
+#include "../../Common/MyBuffer2.h"
#include "../../Common/MyCom.h"
#include "../../Common/MyException.h"
#include "../../Common/MyVector.h"
@@ -20,35 +19,6 @@
namespace NCompress {
namespace NRar5 {
-class CMidBuffer
-{
- Byte *_data;
- size_t _size;
-
- CLASS_NO_COPY(CMidBuffer)
-
-public:
- CMidBuffer(): _data(NULL), _size(0) {};
- ~CMidBuffer() { ::MidFree(_data); }
-
- bool IsAllocated() const { return _data != NULL; }
- operator Byte *() { return _data; }
- operator const Byte *() const { return _data; }
- size_t Size() const { return _size; }
-
- void AllocAtLeast(size_t size)
- {
- if (size > _size)
- {
- const size_t kMinSize = (1 << 16);
- if (size < kMinSize)
- size = kMinSize;
- ::MidFree(_data);
- _data = (Byte *)::MidAlloc(size);
- _size = size;
- }
- }
-};
/*
struct CInBufferException: public CSystemException
diff --git a/CPP/7zip/Compress/ShrinkDecoder.cpp b/CPP/7zip/Compress/ShrinkDecoder.cpp
index 80b7e67c..bd7c2461 100644
--- a/CPP/7zip/Compress/ShrinkDecoder.cpp
+++ b/CPP/7zip/Compress/ShrinkDecoder.cpp
@@ -1,10 +1,7 @@
// ShrinkDecoder.cpp
-
#include "StdAfx.h"
-#include <stdio.h>
-
#include "../../../C/Alloc.h"
#include "../Common/InBuffer.h"
@@ -20,18 +17,19 @@ static const UInt32 kBufferSize = (1 << 18);
static const unsigned kNumMinBits = 9;
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
- const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
NBitl::CBaseDecoder<CInBuffer> inBuffer;
COutBuffer outBuffer;
if (!inBuffer.Create(kBufferSize))
return E_OUTOFMEMORY;
+ if (!outBuffer.Create(kBufferSize))
+ return E_OUTOFMEMORY;
+
inBuffer.SetStream(inStream);
inBuffer.Init();
- if (!outBuffer.Create(kBufferSize))
- return E_OUTOFMEMORY;
outBuffer.SetStream(outStream);
outBuffer.Init();
@@ -45,31 +43,69 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
_suffixes[i] = 0;
}
- UInt64 prevPos = 0;
+ UInt64 prevPos = 0, inPrev = 0;
unsigned numBits = kNumMinBits;
unsigned head = 257;
int lastSym = -1;
Byte lastChar2 = 0;
+ bool moreOut = false;
+
+ HRESULT res = S_FALSE;
for (;;)
{
+ _inProcessed = inBuffer.GetProcessedSize();
+ const UInt64 nowPos = outBuffer.GetProcessedSize();
+
+ bool eofCheck = false;
+
+ if (outSize && nowPos >= *outSize)
+ {
+ if (!_fullStreamMode || moreOut)
+ {
+ res = S_OK;
+ break;
+ }
+ eofCheck = true;
+ // Is specSym(=256) allowed after end of stream
+ // Do we need to read it here
+ }
+
+ if (progress)
+ {
+ if (nowPos - prevPos >= (1 << 18)
+ || _inProcessed - inPrev >= (1 << 20))
+ {
+ prevPos = nowPos;
+ inPrev = _inProcessed;
+ RINOK(progress->SetRatioInfo(&_inProcessed, &nowPos));
+ }
+ }
+
UInt32 sym = inBuffer.ReadBits(numBits);
-
+
if (inBuffer.ExtraBitsWereRead())
+ {
+ res = S_OK;
break;
+ }
if (sym == 256)
{
sym = inBuffer.ReadBits(numBits);
+
+ if (inBuffer.ExtraBitsWereRead())
+ break;
+
if (sym == 1)
{
if (numBits >= kNumMaxBits)
- return S_FALSE;
+ break;
numBits++;
continue;
}
if (sym != 2)
- return S_FALSE;
+ break;
{
unsigned i;
for (i = 257; i < kNumItems; i++)
@@ -90,6 +126,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
}
}
+ if (eofCheck)
+ {
+ // It's can be error case.
+ // That error can be detected later in (*inSize != _inProcessed) check.
+ res = S_OK;
+ break;
+ }
+
bool needPrev = false;
if (head < kNumItems && lastSym >= 0)
{
@@ -101,7 +145,8 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
{
// we need to fix the code for that case
// _parents[head] is not allowed to link to itself
- return E_NOTIMPL;
+ res = E_NOTIMPL;
+ break;
}
needPrev = true;
_parents[head] = (UInt16)lastSym;
@@ -111,7 +156,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
}
if (_parents[sym] == kNumItems)
- return S_FALSE;
+ break;
lastSym = sym;
unsigned cur = sym;
@@ -127,34 +172,64 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
lastChar2 = (Byte)cur;
if (needPrev)
- _suffixes[head - 1] = (Byte)cur;
+ _suffixes[(size_t)head - 1] = (Byte)cur;
+
+ if (outSize)
+ {
+ const UInt64 limit = *outSize - nowPos;
+ if (i > limit)
+ {
+ moreOut = true;
+ i = (unsigned)limit;
+ }
+ }
do
outBuffer.WriteByte(_stack[--i]);
while (i);
-
- if (progress)
+ }
+
+ RINOK(outBuffer.Flush());
+
+ if (res == S_OK)
+ if (_fullStreamMode)
{
+ if (moreOut)
+ res = S_FALSE;
const UInt64 nowPos = outBuffer.GetProcessedSize();
- if (nowPos - prevPos >= (1 << 18))
- {
- prevPos = nowPos;
- const UInt64 packSize = inBuffer.GetProcessedSize();
- RINOK(progress->SetRatioInfo(&packSize, &nowPos));
- }
+ if (outSize && *outSize != nowPos)
+ res = S_FALSE;
+ if (inSize && *inSize != _inProcessed)
+ res = S_FALSE;
}
- }
- return outBuffer.Flush();
+ return res;
}
-STDMETHODIMP CDecoder ::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
- catch(const CInBufferException &e) { return e.ErrorCode; }
- catch(const COutBufferException &e) { return e.ErrorCode; }
+ // catch(const CInBufferException &e) { return e.ErrorCode; }
+ // catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(const CSystemException &e) { return e.ErrorCode; }
catch(...) { return S_FALSE; }
}
+
+STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
+{
+ _fullStreamMode = (finishMode != 0);
+ return S_OK;
+}
+
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _inProcessed;
+ return S_OK;
+}
+
+
}}
diff --git a/CPP/7zip/Compress/ShrinkDecoder.h b/CPP/7zip/Compress/ShrinkDecoder.h
index 42e5eee7..2f01596a 100644
--- a/CPP/7zip/Compress/ShrinkDecoder.h
+++ b/CPP/7zip/Compress/ShrinkDecoder.h
@@ -15,20 +15,29 @@ const unsigned kNumItems = 1 << kNumMaxBits;
class CDecoder :
public ICompressCoder,
+ public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
public CMyUnknownImp
{
+ UInt64 _inProcessed;
+ bool _fullStreamMode;
+
UInt16 _parents[kNumItems];
Byte _suffixes[kNumItems];
Byte _stack[kNumItems];
-public:
- MY_UNKNOWN_IMP
-
HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
-
+
+public:
+ MY_UNKNOWN_IMP2(
+ ICompressSetFinishMode,
+ ICompressGetInStreamProcessedSize)
+
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
};
}}
diff --git a/CPP/7zip/Compress/XpressDecoder.cpp b/CPP/7zip/Compress/XpressDecoder.cpp
index a4d45335..a38d9418 100644
--- a/CPP/7zip/Compress/XpressDecoder.cpp
+++ b/CPP/7zip/Compress/XpressDecoder.cpp
@@ -49,8 +49,8 @@ HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize)
for (unsigned i = 0; i < kNumSyms / 2; i++)
{
Byte b = in[i];
- levels[i * 2] = (Byte)(b & 0xF);
- levels[i * 2 + 1] = (Byte)(b >> 4);
+ levels[(size_t)i * 2] = (Byte)(b & 0xF);
+ levels[(size_t)i * 2 + 1] = (Byte)(b >> 4);
}
if (!huff.BuildFull(levels))
return S_FALSE;
diff --git a/CPP/7zip/Compress/XzDecoder.cpp b/CPP/7zip/Compress/XzDecoder.cpp
new file mode 100644
index 00000000..e7ee6046
--- /dev/null
+++ b/CPP/7zip/Compress/XzDecoder.cpp
@@ -0,0 +1,260 @@
+// XzDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+
+#include "../Common/StreamUtils.h"
+
+#include "../Archive/IArchive.h"
+
+#include "XzDecoder.h"
+
+using namespace NArchive;
+
+namespace NCompress {
+namespace NXz {
+
+
+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;
+}
+
+
+CXzUnpackerCPP::CXzUnpackerCPP(): InBuf(0), OutBuf(0)
+{
+ XzUnpacker_Construct(&p, &g_Alloc);
+}
+
+CXzUnpackerCPP::~CXzUnpackerCPP()
+{
+ XzUnpacker_Free(&p);
+ MidFree(InBuf);
+ MidFree(OutBuf);
+}
+
+
+
+HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
+ const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress)
+{
+ const size_t kInBufSize = (size_t)1 << 20;
+ const size_t kOutBufSize = (size_t)1 << 21;
+
+ Clear();
+ DecodeRes = SZ_OK;
+
+ XzUnpacker_Init(&xzu.p);
+
+ if (!xzu.InBuf)
+ {
+ xzu.InBuf = (Byte *)MidAlloc(kInBufSize);
+ if (!xzu.InBuf)
+ return E_OUTOFMEMORY;
+ }
+ if (!xzu.OutBuf)
+ {
+ xzu.OutBuf = (Byte *)MidAlloc(kOutBufSize);
+ if (!xzu.OutBuf)
+ return E_OUTOFMEMORY;
+ }
+
+ UInt32 inSize = 0;
+ UInt32 inPos = 0;
+ SizeT outPos = 0;
+
+ HRESULT readRes = S_OK;
+
+ for (;;)
+ {
+ if (inPos == inSize && readRes == S_OK)
+ {
+ inPos = inSize = 0;
+ readRes = seqInStream->Read(xzu.InBuf, kInBufSize, &inSize);
+ }
+
+ SizeT inLen = inSize - inPos;
+ SizeT outLen = kOutBufSize - outPos;
+ ECoderFinishMode finishMode = CODER_FINISH_ANY;
+ if (inSize == 0)
+ finishMode = CODER_FINISH_END;
+
+ if (outSizeLimit)
+ {
+ const UInt64 rem = *outSizeLimit - OutSize;
+ if (outLen >= rem)
+ {
+ outLen = (SizeT)rem;
+ if (finishStream)
+ finishMode = CODER_FINISH_END;
+ }
+ }
+
+ ECoderStatus status;
+
+ const SizeT outLenRequested = outLen;
+
+ SRes res = XzUnpacker_Code(&xzu.p,
+ xzu.OutBuf + outPos, &outLen,
+ xzu.InBuf + inPos, &inLen,
+ finishMode, &status);
+
+ DecodeRes = res;
+
+ inPos += (UInt32)inLen;
+ outPos += outLen;
+
+ InSize += inLen;
+ OutSize += outLen;
+
+ bool finished = ((inLen == 0 && outLen == 0) || res != SZ_OK);
+
+ if (outLen >= outLenRequested || finished)
+ {
+ if (outStream && outPos != 0)
+ {
+ RINOK(WriteStream(outStream, xzu.OutBuf, outPos));
+ }
+ outPos = 0;
+ }
+
+ if (progress)
+ {
+ RINOK(progress->SetRatioInfo(&InSize, &OutSize));
+ }
+
+ if (!finished)
+ continue;
+
+ {
+ 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)
+ {
+ extraSize = 0;
+ if (!XzUnpacker_IsStreamWasFinished(&xzu.p))
+ {
+ // finished at padding bytes, but padding is not aligned for 4
+ UnexpectedEnd = true;
+ res = SZ_ERROR_DATA;
+ }
+ }
+ else // status == CODER_STATUS_NOT_FINISHED
+ res = SZ_ERROR_DATA;
+ }
+ else if (res == SZ_ERROR_NO_ARCHIVE)
+ {
+ if (InSize == extraSize)
+ IsArc = false;
+ else
+ {
+ if (extraSize != 0 || inPos != inSize)
+ {
+ DataAfterEnd = true;
+ res = SZ_OK;
+ }
+ }
+ }
+
+ 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;
+ }
+
+ return readRes;
+ }
+ }
+}
+
+
+Int32 CDecoder::Get_Extract_OperationResult() const
+{
+ Int32 opRes;
+ 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;
+}
+
+
+
+HRESULT CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
+{
+ RINOK(_decoder.Decode(inStream, outStream, outSize, _finishStream, progress));
+ Int32 opRes = _decoder.Get_Extract_OperationResult();
+ if (opRes == NArchive::NExtract::NOperationResult::kUnsupportedMethod)
+ return E_NOTIMPL;
+ if (opRes != NArchive::NExtract::NOperationResult::kOK)
+ return S_FALSE;
+ return S_OK;
+}
+
+STDMETHODIMP CComDecoder::SetFinishMode(UInt32 finishMode)
+{
+ _finishStream = (finishMode != 0);
+ return S_OK;
+}
+
+STDMETHODIMP CComDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _decoder.InSize;
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Compress/XzDecoder.h b/CPP/7zip/Compress/XzDecoder.h
new file mode 100644
index 00000000..00609412
--- /dev/null
+++ b/CPP/7zip/Compress/XzDecoder.h
@@ -0,0 +1,95 @@
+// XzDecoder.h
+
+#ifndef __XZ_DECODER_H
+#define __XZ_DECODER_H
+
+#include "../../Common/MyCom.h"
+#include "../ICoder.h"
+
+#include "../../../C/Xz.h"
+
+
+// #include "../../Archive/XzHandler.h"
+
+namespace NCompress {
+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,
+ const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *compressProgress);
+ Int32 Get_Extract_OperationResult() const;
+};
+
+
+class CComDecoder:
+ public ICompressCoder,
+ public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
+ public CMyUnknownImp
+{
+ CDecoder _decoder;
+ bool _finishStream;
+
+public:
+ MY_UNKNOWN_IMP2(
+ ICompressSetFinishMode,
+ ICompressGetInStreamProcessedSize)
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+ CComDecoder(): _finishStream(false) {}
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/XzEncoder.cpp b/CPP/7zip/Compress/XzEncoder.cpp
new file mode 100644
index 00000000..27194597
--- /dev/null
+++ b/CPP/7zip/Compress/XzEncoder.cpp
@@ -0,0 +1,190 @@
+// XzEncoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+
+#include "../Common/CWrappers.h"
+#include "../Common/StreamUtils.h"
+
+#include "XzEncoder.h"
+
+namespace NCompress {
+
+namespace NLzma2 {
+
+HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props);
+
+}
+
+namespace NXz {
+
+extern "C" {
+
+static void *SzBigAlloc(ISzAllocPtr, size_t size) { return BigAlloc(size); }
+static void SzBigFree(ISzAllocPtr, void *address) { BigFree(address); }
+static const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
+
+static void *SzAlloc(ISzAllocPtr, size_t size) { return MyAlloc(size); }
+static void SzFree(ISzAllocPtr, void *address) { MyFree(address); }
+static const ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+}
+
+void CEncoder::InitCoderProps()
+{
+ Lzma2EncProps_Init(&_lzma2Props);
+ XzProps_Init(&xzProps);
+ XzFilterProps_Init(&filter);
+
+ xzProps.lzma2Props = &_lzma2Props;
+ // xzProps.filterProps = (_filterId != 0 ? &filter : NULL);
+ xzProps.filterProps = NULL;
+}
+
+CEncoder::CEncoder()
+{
+ InitCoderProps();
+}
+
+CEncoder::~CEncoder()
+{
+}
+
+
+HRESULT CEncoder::SetCoderProp(PROPID propID, const PROPVARIANT &prop)
+{
+ return NLzma2::SetLzma2Prop(propID, prop, _lzma2Props);
+}
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ Lzma2EncProps_Init(&_lzma2Props);
+
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ RINOK(SetCoderProp(propIDs[i], coderProps[i]));
+ }
+ return S_OK;
+ // return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props));
+}
+
+
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */,
+ ICompressProgressInfo *progress)
+{
+ CSeqOutStreamWrap seqOutStream;
+
+ seqOutStream.Init(outStream);
+
+ // if (IntToBool(newData))
+ {
+ /*
+ UInt64 size;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
+ if (prop.vt != VT_UI8)
+ return E_INVALIDARG;
+ size = prop.uhVal.QuadPart;
+ RINOK(updateCallback->SetTotal(size));
+ }
+ */
+
+ /*
+ CLzma2EncProps lzma2Props;
+ Lzma2EncProps_Init(&lzma2Props);
+
+ lzma2Props.lzmaProps.level = GetLevel();
+ */
+
+ CSeqInStreamWrap seqInStream;
+
+ seqInStream.Init(inStream);
+
+
+ /*
+ {
+ NCOM::CPropVariant prop = (UInt64)size;
+ RINOK(NCompress::NLzma2::SetLzma2Prop(NCoderPropID::kReduceSize, prop, lzma2Props));
+ }
+
+ FOR_VECTOR (i, _methods)
+ {
+ COneMethodInfo &m = _methods[i];
+ SetGlobalLevelAndThreads(m
+ #ifndef _7ZIP_ST
+ , _numThreads
+ #endif
+ );
+ {
+ FOR_VECTOR (j, m.Props)
+ {
+ const CProp &prop = m.Props[j];
+ RINOK(NCompress::NLzma2::SetLzma2Prop(prop.Id, prop.Value, lzma2Props));
+ }
+ }
+ }
+
+ #ifndef _7ZIP_ST
+ lzma2Props.numTotalThreads = _numThreads;
+ #endif
+
+ */
+
+ CCompressProgressWrap progressWrap;
+
+ progressWrap.Init(progress);
+
+ xzProps.checkId = XZ_CHECK_CRC32;
+ // xzProps.checkId = XZ_CHECK_CRC64;
+ /*
+ CXzProps xzProps;
+ CXzFilterProps filter;
+ XzProps_Init(&xzProps);
+ XzFilterProps_Init(&filter);
+ xzProps.lzma2Props = &_lzma2Props;
+ */
+ /*
+ xzProps.filterProps = (_filterId != 0 ? &filter : NULL);
+ switch (_crcSize)
+ {
+ case 0: xzProps.checkId = XZ_CHECK_NO; break;
+ case 4: xzProps.checkId = XZ_CHECK_CRC32; break;
+ case 8: xzProps.checkId = XZ_CHECK_CRC64; break;
+ case 32: xzProps.checkId = XZ_CHECK_SHA256; break;
+ default: return E_INVALIDARG;
+ }
+ filter.id = _filterId;
+ if (_filterId == XZ_ID_Delta)
+ {
+ bool deltaDefined = false;
+ FOR_VECTOR (j, _filterMethod.Props)
+ {
+ const CProp &prop = _filterMethod.Props[j];
+ if (prop.Id == NCoderPropID::kDefaultProp && prop.Value.vt == VT_UI4)
+ {
+ UInt32 delta = (UInt32)prop.Value.ulVal;
+ if (delta < 1 || delta > 256)
+ return E_INVALIDARG;
+ filter.delta = delta;
+ deltaDefined = true;
+ }
+ }
+ if (!deltaDefined)
+ return E_INVALIDARG;
+ }
+ */
+ SRes res = Xz_Encode(&seqOutStream.vt, &seqInStream.vt, &xzProps, progress ? &progressWrap.vt : NULL);
+ /*
+ if (res == SZ_OK)
+ return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
+ */
+ return SResToHRESULT(res);
+ }
+}
+
+}}
diff --git a/CPP/7zip/Compress/XzEncoder.h b/CPP/7zip/Compress/XzEncoder.h
new file mode 100644
index 00000000..0e166ad3
--- /dev/null
+++ b/CPP/7zip/Compress/XzEncoder.h
@@ -0,0 +1,44 @@
+// XzEncoder.h
+
+#ifndef __XZ_ENCODER_H
+#define __XZ_ENCODER_H
+
+#include "../../../C/XzEnc.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+namespace NCompress {
+namespace NXz {
+
+
+class CEncoder:
+ public ICompressCoder,
+ public ICompressSetCoderProperties,
+ public CMyUnknownImp
+{
+ // CXzEncHandle _encoder;
+public:
+ CLzma2EncProps _lzma2Props;
+
+ CXzProps xzProps;
+ CXzFilterProps filter;
+
+ MY_UNKNOWN_IMP2(ICompressCoder, ICompressSetCoderProperties)
+
+ void InitCoderProps();
+
+ HRESULT SetCoderProp(PROPID propID, const PROPVARIANT &prop);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+
+ CEncoder();
+ virtual ~CEncoder();
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/ZDecoder.cpp b/CPP/7zip/Compress/ZDecoder.cpp
index 7308bc0b..06eab00e 100644
--- a/CPP/7zip/Compress/ZDecoder.cpp
+++ b/CPP/7zip/Compress/ZDecoder.cpp
@@ -100,7 +100,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
}
}
unsigned bytePos = bitPos >> 3;
- UInt32 symbol = buf[bytePos] | ((UInt32)buf[bytePos + 1] << 8) | ((UInt32)buf[bytePos + 2] << 16);
+ UInt32 symbol = buf[bytePos] | ((UInt32)buf[(size_t)bytePos + 1] << 8) | ((UInt32)buf[(size_t)bytePos + 2] << 16);
symbol >>= (bitPos & 7);
symbol &= (1 << numBits) - 1;
bitPos += numBits;
@@ -129,7 +129,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
_stack[i++] = (Byte)cur;
if (needPrev)
{
- _suffixes[head - 1] = (Byte)cur;
+ _suffixes[(size_t)head - 1] = (Byte)cur;
if (symbol == head - 1)
_stack[0] = (Byte)cur;
}
diff --git a/CPP/7zip/Crc.mak b/CPP/7zip/Crc.mak
index f2b0874c..2e0b92ef 100644
--- a/CPP/7zip/Crc.mak
+++ b/CPP/7zip/Crc.mak
@@ -1,6 +1,6 @@
C_OBJS = $(C_OBJS) \
$O\7zCrc.obj
-!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM"
+!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM" || "$(CPU)" == "ARM64"
C_OBJS = $(C_OBJS) \
!ELSE
ASM_OBJS = $(ASM_OBJS) \
diff --git a/CPP/7zip/Crc64.mak b/CPP/7zip/Crc64.mak
index 57301c22..1228a014 100644
--- a/CPP/7zip/Crc64.mak
+++ b/CPP/7zip/Crc64.mak
@@ -1,6 +1,6 @@
C_OBJS = $(C_OBJS) \
$O\XzCrc64.obj
-!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM"
+!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM" || "$(CPU)" == "ARM64"
C_OBJS = $(C_OBJS) \
!ELSE
ASM_OBJS = $(ASM_OBJS) \
diff --git a/CPP/7zip/Crypto/MyAes.h b/CPP/7zip/Crypto/MyAes.h
index 84c21de3..182411db 100644
--- a/CPP/7zip/Crypto/MyAes.h
+++ b/CPP/7zip/Crypto/MyAes.h
@@ -30,6 +30,8 @@ class CAesCbcCoder:
public:
CAesCbcCoder(bool encodeMode, unsigned keySize);
+ virtual ~CAesCbcCoder() {}; // we need virtual destructor for derived classes
+
MY_UNKNOWN_IMP3(ICompressFilter, ICryptoProperties, ICompressSetCoderProperties)
INTERFACE_ICompressFilter(;)
diff --git a/CPP/7zip/Crypto/Rar20Crypto.cpp b/CPP/7zip/Crypto/Rar20Crypto.cpp
index 346d969e..878dfc5c 100644
--- a/CPP/7zip/Crypto/Rar20Crypto.cpp
+++ b/CPP/7zip/Crypto/Rar20Crypto.cpp
@@ -68,7 +68,7 @@ void CData::SetPassword(const Byte *data, unsigned size)
for (unsigned i = 0; i < size; i += 2)
{
unsigned n1 = (Byte)g_CrcTable[(psw[i] - j) & 0xFF];
- unsigned n2 = (Byte)g_CrcTable[(psw[i + 1] + j) & 0xFF];
+ unsigned n2 = (Byte)g_CrcTable[(psw[(size_t)i + 1] + j) & 0xFF];
for (unsigned k = 1; (n1 & 0xFF) != n2; n1++, k++)
Swap(SubstTable[n1 & 0xFF], SubstTable[(n1 + i + k) & 0xFF]);
}
diff --git a/CPP/7zip/Crypto/Rar20Crypto.h b/CPP/7zip/Crypto/Rar20Crypto.h
index b3033700..6d1d0f5d 100644
--- a/CPP/7zip/Crypto/Rar20Crypto.h
+++ b/CPP/7zip/Crypto/Rar20Crypto.h
@@ -20,10 +20,10 @@ class CData
UInt32 SubstLong(UInt32 t) const
{
- return (UInt32)SubstTable[(unsigned)t & 255]
- | ((UInt32)SubstTable[(unsigned)(t >> 8) & 255] << 8)
+ return (UInt32)SubstTable[(unsigned)t & 255]
+ | ((UInt32)SubstTable[(unsigned)(t >> 8) & 255] << 8)
| ((UInt32)SubstTable[(unsigned)(t >> 16) & 255] << 16)
- | ((UInt32)SubstTable[(unsigned)(t >> 24) & 255] << 24);
+ | ((UInt32)SubstTable[(unsigned)(t >> 24) ] << 24);
}
void UpdateKeys(const Byte *data);
void CryptBlock(Byte *buf, bool encrypt);
diff --git a/CPP/7zip/Crypto/WzAes.h b/CPP/7zip/Crypto/WzAes.h
index 41f9949e..3b22bc16 100644
--- a/CPP/7zip/Crypto/WzAes.h
+++ b/CPP/7zip/Crypto/WzAes.h
@@ -105,6 +105,8 @@ public:
_key.KeySizeMode = (EKeySizeMode)mode;
return true;
}
+
+ virtual ~CBaseCoder() {}
};
class CEncoder:
diff --git a/CPP/7zip/Crypto/ZipCrypto.h b/CPP/7zip/Crypto/ZipCrypto.h
index b23d4216..acc0b031 100644
--- a/CPP/7zip/Crypto/ZipCrypto.h
+++ b/CPP/7zip/Crypto/ZipCrypto.h
@@ -50,6 +50,8 @@ public:
MY_UNKNOWN_IMP1(ICryptoSetPassword)
STDMETHOD(Init)();
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+
+ virtual ~CCipher() {}
};
class CEncoder: public CCipher
diff --git a/CPP/7zip/Crypto/ZipStrong.cpp b/CPP/7zip/Crypto/ZipStrong.cpp
index 6d73a34b..2a923bf5 100644
--- a/CPP/7zip/Crypto/ZipStrong.cpp
+++ b/CPP/7zip/Crypto/ZipStrong.cpp
@@ -15,10 +15,14 @@ namespace NZipStrong {
static const UInt16 kAES128 = 0x660E;
-// DeriveKey* function is similar to CryptDeriveKey() from Windows.
-// But MSDN tells that we need such scheme only if
-// "the required key length is longer than the hash value"
-// but ZipStrong uses it always.
+/*
+ DeriveKey() function is similar to CryptDeriveKey() from Windows.
+ New version of MSDN contains the following condition in CryptDeriveKey() description:
+ "If the hash is not a member of the SHA-2 family and the required key is for either 3DES or AES".
+ Now we support ZipStrong for AES only. And it uses SHA1.
+ Our DeriveKey() code is equal to CryptDeriveKey() in Windows for such conditions: (SHA1 + AES).
+ if (method != AES && method != 3DES), probably we need another code.
+*/
static void DeriveKey2(const Byte *digest, Byte c, Byte *dest)
{
@@ -116,7 +120,7 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
if ((flags & 0x4000) != 0)
{
- // Use 3DES
+ // Use 3DES for rd data
return E_NOTIMPL;
}
@@ -135,17 +139,21 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
if (rdSize + 16 > _remSize)
return E_NOTIMPL;
+ const unsigned kPadSize = kAesPadAllign; // is equal to blockSize of cipher for rd
+
/*
if (cert)
{
- // how to filter rd, if ((rdSize & 0xF) != 0) ?
if ((rdSize & 0x7) != 0)
return E_NOTIMPL;
}
else
*/
{
- if ((rdSize & 0xF) != 0)
+ // PKCS7 padding
+ if (rdSize < kPadSize)
+ return E_NOTIMPL;
+ if ((rdSize & (kPadSize - 1)) != 0)
return E_NOTIMPL;
}
@@ -198,13 +206,18 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
RINOK(SetInitVector(_iv, 16));
RINOK(Init());
Filter(p, rdSize);
+
+ rdSize -= kPadSize;
+ for (unsigned i = 0; i < kPadSize; i++)
+ if (p[(size_t)rdSize + i] != kPadSize)
+ return S_OK; // passwOK = false;
}
Byte fileKey[32];
NSha1::CContext sha;
sha.Init();
sha.Update(_iv, _ivSize);
- sha.Update(p, rdSize - 16); // we don't use last 16 bytes (PAD bytes)
+ sha.Update(p, rdSize);
DeriveKey(sha, fileKey);
RINOK(SetKey(fileKey, _key.KeySize));
diff --git a/CPP/7zip/Crypto/ZipStrong.h b/CPP/7zip/Crypto/ZipStrong.h
index c5809e7b..8e3c74e2 100644
--- a/CPP/7zip/Crypto/ZipStrong.h
+++ b/CPP/7zip/Crypto/ZipStrong.h
@@ -42,6 +42,8 @@ public:
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
};
+const unsigned kAesPadAllign = AES_BLOCK_SIZE;
+
class CDecoder: public CBaseCoder
{
UInt32 _ivSize;
@@ -51,6 +53,12 @@ public:
MY_UNKNOWN_IMP1(ICryptoSetPassword)
HRESULT ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize);
HRESULT Init_and_CheckPassword(bool &passwOK);
+ UInt32 GetPadSize(UInt32 packSize32) const
+ {
+ // Padding is to align to blockSize of cipher.
+ // Change it, if is not AES
+ return kAesPadAllign - (packSize32 & (kAesPadAllign - 1));
+ }
};
}}
diff --git a/CPP/7zip/Guid.txt b/CPP/7zip/Guid.txt
index 7edab6ea..a3360a86 100644
--- a/CPP/7zip/Guid.txt
+++ b/CPP/7zip/Guid.txt
@@ -47,6 +47,7 @@
24 ICompressGetInStreamProcessedSize
25 ICompressSetCoderMt
26 ICompressSetFinishMode
+ 27 ICompressGetInStreamProcessedSize2
30 ICompressGetSubStreamSize
31 ICompressSetInStream
diff --git a/CPP/7zip/ICoder.h b/CPP/7zip/ICoder.h
index 75db9399..28f5f6d8 100644
--- a/CPP/7zip/ICoder.h
+++ b/CPP/7zip/ICoder.h
@@ -170,6 +170,11 @@ CODER_INTERFACE(ICompressSetFinishMode, 0x26)
1 : full decoding. The stream must be finished at the end of decoding. */
};
+CODER_INTERFACE(ICompressGetInStreamProcessedSize2, 0x27)
+{
+ STDMETHOD(GetInStreamProcessedSize2)(UInt32 streamIndex, UInt64 *value) PURE;
+};
+
CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
{
diff --git a/CPP/7zip/UI/Agent/Agent.cpp b/CPP/7zip/UI/Agent/Agent.cpp
index a9021ef9..9b841ce2 100644
--- a/CPP/7zip/UI/Agent/Agent.cpp
+++ b/CPP/7zip/UI/Agent/Agent.cpp
@@ -523,6 +523,21 @@ static const wchar_t *GetExtension(const wchar_t *name)
}
}
+
+int CAgentFolder::CompareItems3(UInt32 index1, UInt32 index2, PROPID propID)
+{
+ NCOM::CPropVariant prop1, prop2;
+ // Name must be first property
+ GetProperty(index1, propID, &prop1);
+ GetProperty(index2, propID, &prop2);
+ if (prop1.vt != prop2.vt)
+ return MyCompare(prop1.vt, prop2.vt);
+ if (prop1.vt == VT_BSTR)
+ return MyStringCompareNoCase(prop1.bstrVal, prop2.bstrVal);
+ return prop1.Compare(prop2);
+}
+
+
int CAgentFolder::CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw)
{
unsigned realIndex1, realIndex2;
@@ -651,21 +666,10 @@ int CAgentFolder::CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int
if (propIsRaw)
return CompareRawProps(_agentSpec->_archiveLink.GetArchiveGetRawProps(), arcIndex1, arcIndex2, propID);
- NCOM::CPropVariant prop1, prop2;
- // Name must be first property
- GetProperty(index1, propID, &prop1);
- GetProperty(index2, propID, &prop2);
- if (prop1.vt != prop2.vt)
- {
- return MyCompare(prop1.vt, prop2.vt);
- }
- if (prop1.vt == VT_BSTR)
- {
- return _wcsicmp(prop1.bstrVal, prop2.bstrVal);
- }
- return prop1.Compare(prop2);
+ return CompareItems3(index1, index2, propID);
}
+
STDMETHODIMP_(Int32) CAgentFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw)
{
try {
@@ -811,23 +815,12 @@ STDMETHODIMP_(Int32) CAgentFolder::CompareItems(UInt32 index1, UInt32 index2, PR
return CompareRawProps(_agentSpec->_archiveLink.GetArchiveGetRawProps(), arcIndex1, arcIndex2, propID);
}
- NCOM::CPropVariant prop1, prop2;
- // Name must be first property
- GetProperty(index1, propID, &prop1);
- GetProperty(index2, propID, &prop2);
- if (prop1.vt != prop2.vt)
- {
- return MyCompare(prop1.vt, prop2.vt);
- }
- if (prop1.vt == VT_BSTR)
- {
- return _wcsicmp(prop1.bstrVal, prop2.bstrVal);
- }
- return prop1.Compare(prop2);
+ return CompareItems3(index1, index2, propID);
} catch(...) { return 0; }
}
+
HRESULT CAgentFolder::BindToFolder_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder)
{
/*
@@ -1246,7 +1239,7 @@ STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
case kpidNumSubFiles: prop = dir.NumSubFiles; break;
// case kpidName: prop = dir.Name; break;
// case kpidPath: prop = _proxy2->GetFullPathPrefix(_proxyDirIndex); break;
- case kpidType: prop = UString(L"7-Zip.") + _agentSpec->ArchiveType; break;
+ case kpidType: prop = UString("7-Zip.") + _agentSpec->ArchiveType; break;
case kpidCRC: if (dir.CrcIsDefined) prop = dir.Crc; break;
}
@@ -1262,7 +1255,7 @@ STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
case kpidNumSubFiles: prop = dir.NumSubFiles; break;
case kpidName: prop = dir.Name; break;
case kpidPath: prop = _proxy->GetDirPath_as_Prefix(_proxyDirIndex); break;
- case kpidType: prop = UString(L"7-Zip.") + _agentSpec->ArchiveType; break;
+ case kpidType: prop = UString("7-Zip.") + _agentSpec->ArchiveType; break;
case kpidCRC: if (dir.CrcIsDefined) prop = dir.Crc; break;
}
}
@@ -1582,9 +1575,9 @@ STDMETHODIMP CAgent::Open(
if (Read_ShowDeleted())
{
COptionalOpenProperties &optPair = optProps.AddNew();
- optPair.FormatName = L"ntfs";
- // optPair.Props.AddNew().Name = L"LS";
- optPair.Props.AddNew().Name = L"LD";
+ optPair.FormatName = "ntfs";
+ // optPair.Props.AddNew().Name = "LS";
+ optPair.Props.AddNew().Name = "LD";
}
*/
diff --git a/CPP/7zip/UI/Agent/Agent.h b/CPP/7zip/UI/Agent/Agent.h
index 9d70c7a1..ae4026d6 100644
--- a/CPP/7zip/UI/Agent/Agent.h
+++ b/CPP/7zip/UI/Agent/Agent.h
@@ -43,7 +43,8 @@ enum AGENT_OP
AGENT_OP_Delete,
AGENT_OP_CreateFolder,
AGENT_OP_Rename,
- AGENT_OP_CopyFromFile
+ AGENT_OP_CopyFromFile,
+ AGENT_OP_Comment
};
class CAgentFolder:
@@ -101,6 +102,7 @@ public:
STDMETHOD(GetFolderArcProps)(IFolderArcProps **object);
STDMETHOD_(Int32, CompareItems)(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw);
+ int CompareItems3(UInt32 index1, UInt32 index2, PROPID propID);
int CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw);
// IArchiveFolder
@@ -205,6 +207,10 @@ public:
const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName,
IFolderArchiveUpdateCallback *updateCallback100);
+ HRESULT CommentItem(ISequentialOutStream *outArchiveStream,
+ const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName,
+ IFolderArchiveUpdateCallback *updateCallback100);
+
HRESULT UpdateOneFile(ISequentialOutStream *outArchiveStream,
const UInt32 *indices, UInt32 numItems, const wchar_t *diskFilePath,
IFolderArchiveUpdateCallback *updateCallback100);
@@ -262,7 +268,7 @@ public:
UString GetTypeOfArc(const CArc &arc) const
{
if (arc.FormatIndex < 0)
- return L"Parser";
+ return UString("Parser");
return g_CodecsObj->GetFormatNamePtr(arc.FormatIndex);
}
@@ -277,12 +283,12 @@ public:
if (arc.ErrorInfo.ErrorFormatIndex >= 0)
{
if (arc.ErrorInfo.ErrorFormatIndex == arc.FormatIndex)
- s2.AddAscii("Warning: The archive is open with offset");
+ s2 += "Warning: The archive is open with offset";
else
{
- s2.AddAscii("Can not open the file as [");
+ s2 += "Can not open the file as [";
s2 += g_CodecsObj->GetFormatNamePtr(arc.ErrorInfo.ErrorFormatIndex);
- s2.AddAscii("] archive");
+ s2 += "] archive";
}
}
@@ -290,16 +296,16 @@ public:
{
if (!s2.IsEmpty())
s2.Add_LF();
- s2.AddAscii("\n[");
+ s2 += "\n[";
s2 += GetTypeOfArc(arc);
- s2.AddAscii("]: ");
+ s2 += "]: ";
s2 += arc.ErrorInfo.ErrorMessage;
}
if (!s2.IsEmpty())
{
if (!s.IsEmpty())
- s.AddAscii("--------------------\n");
+ s += "--------------------\n";
s += arc.Path;
s.Add_LF();
s += s2;
diff --git a/CPP/7zip/UI/Agent/AgentOut.cpp b/CPP/7zip/UI/Agent/AgentOut.cpp
index 1302d8c7..40876d76 100644
--- a/CPP/7zip/UI/Agent/AgentOut.cpp
+++ b/CPP/7zip/UI/Agent/AgentOut.cpp
@@ -589,6 +589,55 @@ HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
}
+
+HRESULT CAgent::CommentItem(ISequentialOutStream *outArchiveStream,
+ const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName,
+ IFolderArchiveUpdateCallback *updateCallback100)
+{
+ if (!CanUpdate())
+ return E_NOTIMPL;
+ if (numItems != 1)
+ return E_INVALIDARG;
+ if (!_archiveLink.IsOpen)
+ return E_FAIL;
+
+ CRecordVector<CUpdatePair2> updatePairs;
+ CUpdateCallbackAgent updateCallbackAgent;
+ updateCallbackAgent.SetCallback(updateCallback100);
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
+
+ const int mainRealIndex = _agentFolder->GetRealIndex(indices[0]);
+
+ if (mainRealIndex < 0)
+ return E_NOTIMPL;
+
+ UInt32 numItemsInArchive;
+ RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
+
+ UString newName = newItemName;
+
+ for (UInt32 i = 0; i < numItemsInArchive; i++)
+ {
+ CUpdatePair2 up2;
+ up2.SetAs_NoChangeArcItem(i);
+ if ((int)i == mainRealIndex)
+ up2.NewProps = true;
+ updatePairs.Add(up2);
+ }
+
+ updateCallbackSpec->Callback = &updateCallbackAgent;
+ updateCallbackSpec->UpdatePairs = &updatePairs;
+ updateCallbackSpec->CommentIndex = mainRealIndex;
+ updateCallbackSpec->Comment = &newName;
+
+ SetInArchiveInterfaces(this, updateCallbackSpec);
+
+ return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
+}
+
+
+
HRESULT CAgent::UpdateOneFile(ISequentialOutStream *outArchiveStream,
const UInt32 *indices, UInt32 numItems, const wchar_t *diskFilePath,
IFolderArchiveUpdateCallback *updateCallback100)
diff --git a/CPP/7zip/UI/Agent/AgentProxy.cpp b/CPP/7zip/UI/Agent/AgentProxy.cpp
index eb07efd8..7f550f75 100644
--- a/CPP/7zip/UI/Agent/AgentProxy.cpp
+++ b/CPP/7zip/UI/Agent/AgentProxy.cpp
@@ -316,7 +316,7 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
if (numLevels <= kLevelLimit)
{
if (numLevels == kLevelLimit)
- name.SetFromAscii("[LONG_PATH]");
+ name = "[LONG_PATH]";
else
name.SetFrom(s + namePos, j - namePos);
curItem = AddDir(curItem, -1, name);
@@ -569,7 +569,7 @@ HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress)
{
// Dirs[1] - for alt streams of root dir
CProxyDir2 &dir = Dirs.AddNew();
- dir.PathPrefix = L':';
+ dir.PathPrefix = ':';
}
Files.Alloc(numItems);
diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
index 325d6426..ecbfe58b 100644
--- a/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
+++ b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
@@ -30,9 +30,11 @@ void CAgentFolder::GetPathParts(UStringVector &pathParts, bool &isAltStreamFolde
static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path)
{
NFind::CFileInfo fileInfo;
- FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
+ FString pathPrefix = path;
+ pathPrefix.Add_PathSepar();
{
- NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK);
+ NFind::CEnumerator enumerator;
+ enumerator.SetDirPrefix(pathPrefix);
while (enumerator.Next(fileInfo))
{
if (fileInfo.IsDir())
@@ -112,6 +114,9 @@ HRESULT CAgentFolder::CommonUpdateOperation(
case AGENT_OP_Rename:
result = _agentSpec->RenameItem(tailStream, indices, numItems, newItemName, updateCallback100);
break;
+ case AGENT_OP_Comment:
+ result = _agentSpec->CommentItem(tailStream, indices, numItems, newItemName, updateCallback100);
+ break;
case AGENT_OP_CopyFromFile:
result = _agentSpec->UpdateOneFile(tailStream, indices, numItems, newItemName, updateCallback100);
break;
@@ -274,7 +279,7 @@ HRESULT CAgentFolder::CommonUpdateOperation(
{
if (updateCallback100)
{
- UString s2 = L"Error: ";
+ UString s2 ("Error: ");
s2 += s;
RINOK(updateCallback100->UpdateErrorMessage(s2));
return E_FAIL;
@@ -304,13 +309,9 @@ STDMETHODIMP CAgentFolder::CopyFrom(Int32 moveMode,
STDMETHODIMP CAgentFolder::CopyFromFile(UInt32 destIndex, const wchar_t *itemPath, IProgress *progress)
{
COM_TRY_BEGIN
- CUIntVector indices;
- indices.Add(destIndex);
- {
- return CommonUpdateOperation(AGENT_OP_CopyFromFile, false, itemPath,
- &NUpdateArchive::k_ActionSet_Add,
- &indices.Front(), indices.Size(), progress);
- }
+ return CommonUpdateOperation(AGENT_OP_CopyFromFile, false, itemPath,
+ &NUpdateArchive::k_ActionSet_Add,
+ &destIndex, 1, progress);
COM_TRY_END
}
@@ -347,10 +348,8 @@ STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress
STDMETHODIMP CAgentFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress)
{
COM_TRY_BEGIN
- CUIntVector indices;
- indices.Add(index);
return CommonUpdateOperation(AGENT_OP_Rename, false, newName, NULL,
- &indices.Front(), indices.Size(), progress);
+ &index, 1, progress);
COM_TRY_END
}
@@ -359,8 +358,16 @@ STDMETHODIMP CAgentFolder::CreateFile(const wchar_t * /* name */, IProgress * /*
return E_NOTIMPL;
}
-STDMETHODIMP CAgentFolder::SetProperty(UInt32 /* index */, PROPID /* propID */,
- const PROPVARIANT * /* value */, IProgress * /* progress */)
+STDMETHODIMP CAgentFolder::SetProperty(UInt32 index, PROPID propID,
+ const PROPVARIANT *value, IProgress *progress)
{
- return E_NOTIMPL;
+ COM_TRY_BEGIN
+ if (propID != kpidComment || value->vt != VT_BSTR)
+ return E_NOTIMPL;
+ if (!_agentSpec || !_agentSpec->GetTypeOfArc(_agentSpec->GetArc()).IsEqualTo_Ascii_NoCase("zip"))
+ return E_NOTIMPL;
+
+ return CommonUpdateOperation(AGENT_OP_Comment, false, value->bstrVal, NULL,
+ &index, 1, progress);
+ COM_TRY_END
}
diff --git a/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
index e2813c80..d450eefe 100644
--- a/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
+++ b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
@@ -22,10 +22,10 @@ void CUpdateCallbackAgent::SetCallback(IFolderArchiveUpdateCallback *callback)
}
}
-HRESULT CUpdateCallbackAgent::SetNumItems(UInt64 numItems)
+HRESULT CUpdateCallbackAgent::SetNumItems(const CArcToDoStat &stat)
{
if (Callback)
- return Callback->SetNumFiles(numItems);
+ return Callback->SetNumFiles(stat.Get_NumDataItems_Total());
return S_OK;
}
@@ -82,9 +82,9 @@ HRESULT CUpdateCallbackAgent::OpenFileError(const FString &path, DWORD systemErr
if (Callback)
{
- UString s = L"WARNING: ";
+ UString s ("WARNING: ");
s += NError::MyFormatMessage(systemError);
- s += L": ";
+ s += ": ";
s += fs2us(path);
RINOK(Callback->UpdateErrorMessage(s));
return S_FALSE;
@@ -106,9 +106,9 @@ HRESULT CUpdateCallbackAgent::ReadingFileError(const FString &path, DWORD system
}
else if (Callback)
{
- UString s = L"ERROR: ";
+ UString s ("ERROR: ");
s += NError::MyFormatMessage(systemError);
- s += L": ";
+ s += ": ";
s += fs2us(path);
RINOK(Callback->UpdateErrorMessage(s));
}
diff --git a/CPP/7zip/UI/Client7z/Client7z.cpp b/CPP/7zip/UI/Client7z/Client7z.cpp
index 55650cfa..1eb3909c 100644
--- a/CPP/7zip/UI/Client7z/Client7z.cpp
+++ b/CPP/7zip/UI/Client7z/Client7z.cpp
@@ -49,21 +49,35 @@ using namespace NDir;
#define kDllName "7z.dll"
-static const char *kCopyrightString = "\n7-Zip " MY_VERSION
-" (" kDllName " client) "
-MY_COPYRIGHT " " MY_DATE "\n";
-
-static const char *kHelpString =
-"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n"
+static const char * const kCopyrightString =
+ "\n"
+ "7-Zip"
+ " (" kDllName " client)"
+ " " MY_VERSION
+ " : " MY_COPYRIGHT_DATE
+ "\n";
+
+static const char * const kHelpString =
+"Usage: 7zcl.exe [a | l | x] archive.7z [fileName ...]\n"
"Examples:\n"
-" Client7z.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n"
-" Client7z.exe l archive.7z : List contents of archive.7z\n"
-" Client7z.exe x archive.7z : eXtract files from archive.7z\n";
+" 7zcl.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n"
+" 7zcl.exe l archive.7z : List contents of archive.7z\n"
+" 7zcl.exe x archive.7z : eXtract files from archive.7z\n";
-static AString FStringToConsoleString(const FString &s)
+static void Convert_UString_to_AString(const UString &s, AString &temp)
{
- return GetOemString(fs2us(s));
+ int codePage = CP_OEMCP;
+ /*
+ int g_CodePage = -1;
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8(s, temp);
+ else
+ */
+ UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
}
static FString CmdStringToFString(const char *s)
@@ -71,42 +85,54 @@ static FString CmdStringToFString(const char *s)
return us2fs(GetUnicodeString(s));
}
-static void PrintString(const UString &s)
+static void Print(const char *s)
+{
+ fputs(s, stdout);
+}
+
+static void Print(const AString &s)
{
- printf("%s", (LPCSTR)GetOemString(s));
+ Print(s.Ptr());
}
-static void PrintString(const AString &s)
+static void Print(const UString &s)
{
- printf("%s", (LPCSTR)s);
+ AString as;
+ Convert_UString_to_AString(s, as);
+ Print(as);
+}
+
+static void Print(const wchar_t *s)
+{
+ Print(UString(s));
}
static void PrintNewLine()
{
- PrintString("\n");
+ Print("\n");
}
-static void PrintStringLn(const AString &s)
+static void PrintStringLn(const char *s)
{
- PrintString(s);
+ Print(s);
PrintNewLine();
}
-static void PrintError(const char *message, const FString &name)
+static void PrintError(const char *message)
{
- printf("Error: %s", (LPCSTR)message);
+ Print("Error: ");
PrintNewLine();
- PrintString(FStringToConsoleString(name));
+ Print(message);
PrintNewLine();
}
-static void PrintError(const AString &s)
+static void PrintError(const char *message, const FString &name)
{
- PrintNewLine();
- PrintString(s);
- PrintNewLine();
+ PrintError(message);
+ Print(name);
}
+
static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
{
NCOM::CPropVariant prop;
@@ -126,7 +152,7 @@ static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &resu
}
-static const wchar_t *kEmptyFileAlias = L"[Content]";
+static const wchar_t * const kEmptyFileAlias = L"[Content]";
//////////////////////////////////////////////////////////////
@@ -176,21 +202,25 @@ STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)
}
+
+static const char * const kIncorrectCommand = "incorrect command";
+
//////////////////////////////////////////////////////////////
// Archive Extracting callback class
-static const char *kTestingString = "Testing ";
-static const char *kExtractingString = "Extracting ";
-static const char *kSkippingString = "Skipping ";
+static const char * const kTestingString = "Testing ";
+static const char * const kExtractingString = "Extracting ";
+static const char * const kSkippingString = "Skipping ";
+
+static const char * const kUnsupportedMethod = "Unsupported Method";
+static const char * const kCRCFailed = "CRC Failed";
+static const char * const kDataError = "Data Error";
+static const char * const kUnavailableData = "Unavailable data";
+static const char * const kUnexpectedEnd = "Unexpected end of data";
+static const char * const kDataAfterEnd = "There are some data after the end of the payload data";
+static const char * const kIsNotArc = "Is not archive";
+static const char * const kHeadersError = "Headers Error";
-static const char *kUnsupportedMethod = "Unsupported Method";
-static const char *kCRCFailed = "CRC Failed";
-static const char *kDataError = "Data Error";
-static const char *kUnavailableData = "Unavailable data";
-static const char *kUnexpectedEnd = "Unexpected end of data";
-static const char *kDataAfterEnd = "There are some data after the end of the payload data";
-static const char *kIsNotArc = "Is not archive";
-static const char *kHeadersError = "Headers Error";
class CArchiveExtractCallback:
public IArchiveExtractCallback,
@@ -380,11 +410,11 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
};
switch (askExtractMode)
{
- case NArchive::NExtract::NAskMode::kExtract: PrintString(kExtractingString); break;
- case NArchive::NExtract::NAskMode::kTest: PrintString(kTestingString); break;
- case NArchive::NExtract::NAskMode::kSkip: PrintString(kSkippingString); break;
+ case NArchive::NExtract::NAskMode::kExtract: Print(kExtractingString); break;
+ case NArchive::NExtract::NAskMode::kTest: Print(kTestingString); break;
+ case NArchive::NExtract::NAskMode::kSkip: Print(kSkippingString); break;
};
- PrintString(_filePath);
+ Print(_filePath);
return S_OK;
}
@@ -397,7 +427,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
default:
{
NumErrors++;
- PrintString(" : ");
+ Print(" : ");
const char *s = NULL;
switch (operationResult)
{
@@ -428,15 +458,15 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
}
if (s)
{
- PrintString("Error : ");
- PrintString(s);
+ Print("Error : ");
+ Print(s);
}
else
{
char temp[16];
ConvertUInt32ToString(operationResult, temp);
- PrintString("Error #");
- PrintString(temp);
+ Print("Error #");
+ Print(temp);
}
}
}
@@ -602,10 +632,10 @@ HRESULT CArchiveUpdateCallback::Finilize()
static void GetStream2(const wchar_t *name)
{
- PrintString("Compressing ");
+ Print("Compressing ");
if (name[0] == 0)
name = kEmptyFileAlias;
- PrintString(name);
+ Print(name);
}
STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
@@ -631,7 +661,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream
{
PrintNewLine();
PrintError("WARNING: can't open file");
- // PrintString(NError::MyFormatMessageW(systemError));
+ // Print(NError::MyFormatMessageW(systemError));
return S_FALSE;
}
// return sysError;
@@ -665,7 +695,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOu
while (res.Len() < 2)
res.InsertAtFront(L'0');
UString fileName = VolName;
- fileName += L'.';
+ fileName += '.';
fileName += res;
fileName += VolExt;
COutFileStream *streamSpec = new COutFileStream;
@@ -704,11 +734,18 @@ int MY_CDECL main(int numArgs, const char *args[])
PrintStringLn(kCopyrightString);
- if (numArgs < 3)
+ if (numArgs < 2)
{
PrintStringLn(kHelpString);
+ return 0;
+ }
+
+ if (numArgs < 3)
+ {
+ PrintError(kIncorrectCommand);
return 1;
}
+
NDLL::CLibrary lib;
if (!lib.Load(NDLL::GetModuleDirPrefix() + FTEXT(kDllName)))
@@ -726,10 +763,10 @@ int MY_CDECL main(int numArgs, const char *args[])
char c;
{
- AString command = args[1];
+ AString command (args[1]);
if (command.Len() != 1)
{
- PrintError("incorrect command");
+ PrintError(kIncorrectCommand);
return 1;
}
c = (char)MyCharLower_Ascii(command[0]);
@@ -742,7 +779,7 @@ int MY_CDECL main(int numArgs, const char *args[])
// create archive command
if (numArgs < 4)
{
- PrintStringLn(kHelpString);
+ PrintError(kIncorrectCommand);
return 1;
}
CObjectVector<CDirItem> dirItems;
@@ -839,7 +876,7 @@ int MY_CDECL main(int numArgs, const char *args[])
{
if (numArgs != 3)
{
- PrintStringLn(kHelpString);
+ PrintError(kIncorrectCommand);
return 1;
}
@@ -851,7 +888,7 @@ int MY_CDECL main(int numArgs, const char *args[])
listCommand = false;
else
{
- PrintError("incorrect command");
+ PrintError(kIncorrectCommand);
return 1;
}
@@ -899,17 +936,17 @@ int MY_CDECL main(int numArgs, const char *args[])
archive->GetProperty(i, kpidSize, &prop);
char s[32];
ConvertPropVariantToShortString(prop, s);
- PrintString(s);
- PrintString(" ");
+ Print(s);
+ Print(" ");
}
{
// Get name of file
NCOM::CPropVariant prop;
archive->GetProperty(i, kpidPath, &prop);
if (prop.vt == VT_BSTR)
- PrintString(prop.bstrVal);
+ Print(prop.bstrVal);
else if (prop.vt != VT_EMPTY)
- PrintString("ERROR!");
+ Print("ERROR!");
}
PrintNewLine();
}
@@ -919,10 +956,10 @@ int MY_CDECL main(int numArgs, const char *args[])
// Extract command
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
- extractCallbackSpec->Init(archive, FTEXT("")); // second parameter is output folder path
+ extractCallbackSpec->Init(archive, FString()); // second parameter is output folder path
extractCallbackSpec->PasswordIsDefined = false;
// extractCallbackSpec->PasswordIsDefined = true;
- // extractCallbackSpec->Password = L"1";
+ // extractCallbackSpec->Password = "1";
/*
const wchar_t *names[] =
diff --git a/CPP/7zip/UI/Client7z/Client7z.dsp b/CPP/7zip/UI/Client7z/Client7z.dsp
index 8ad7fb13..b412c8e9 100644
--- a/CPP/7zip/UI/Client7z/Client7z.dsp
+++ b/CPP/7zip/UI/Client7z/Client7z.dsp
@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
-# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /MDd /W4 /WX /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
diff --git a/CPP/7zip/UI/Client7z/resource.rc b/CPP/7zip/UI/Client7z/resource.rc
index a09bb044..462df6fa 100644
--- a/CPP/7zip/UI/Client7z/resource.rc
+++ b/CPP/7zip/UI/Client7z/resource.rc
@@ -1,3 +1,3 @@
#include "../../MyVersionInfo.rc"
-MY_VERSION_INFO_APP("7-Zip client", "7zcl")
+MY_VERSION_INFO_APP("7-Zip client" , "7zcl")
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
index 832ec66d..ad21bc88 100644
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -29,6 +29,7 @@
#include "UpdateAction.h"
extern bool g_CaseSensitive;
+extern bool g_PathTrailReplaceMode;
#ifdef UNDER_CE
@@ -61,10 +62,10 @@ static bool StringToUInt32(const wchar_t *s, UInt32 &v)
CArcCmdLineException::CArcCmdLineException(const char *a, const wchar_t *u)
{
- (*this) += MultiByteToUnicodeString(a);
+ (*this) += a;
if (u)
{
- this->Add_LF();
+ Add_LF();
(*this) += u;
}
}
@@ -133,10 +134,13 @@ enum Enum
kHardLinks,
kSymLinks,
kNtSecurity,
+
kAltStreams,
kReplaceColonForAltStream,
kWriteToAltStreamIfColon,
+ kNameTrailReplace,
+
kDeleteAfterCompressing,
kSetArcMTime
@@ -149,11 +153,11 @@ enum Enum
static const wchar_t kRecursedIDChar = 'r';
-static const char *kRecursedPostCharSet = "0-";
+static const char * const kRecursedPostCharSet = "0-";
-static const char *k_ArcNameMode_PostCharSet = "sea";
+static const char * const k_ArcNameMode_PostCharSet = "sea";
-static const char *k_Stream_PostCharSet = "012";
+static const char * const k_Stream_PostCharSet = "012";
static inline const EArcNameMode ParseArcNameMode(int postCharIndex)
{
@@ -180,7 +184,7 @@ static const char kFileListID = '@';
static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
-static const char *kOverwritePostCharSet = "asut";
+static const char * const kOverwritePostCharSet = "asut";
static const NExtract::NOverwriteMode::EEnum k_OverwriteModes[] =
{
@@ -251,10 +255,13 @@ static const CSwitchForm kSwitchForms[] =
{ "snh", NSwitchType::kMinus },
{ "snl", NSwitchType::kMinus },
{ "sni" },
+
{ "sns", NSwitchType::kMinus },
{ "snr" },
{ "snc" },
+ { "snt", NSwitchType::kMinus },
+
{ "sdel" },
{ "stl" }
@@ -263,17 +270,17 @@ static const CSwitchForm kSwitchForms[] =
#endif
};
-static const wchar_t *kUniversalWildcard = L"*";
+static const char * const kUniversalWildcard = "*";
static const unsigned kMinNonSwitchWords = 1;
static const unsigned kCommandIndex = 0;
-// static const char *kUserErrorMessage = "Incorrect command line";
-static const char *kCannotFindListFile = "Cannot find listfile";
-static const char *kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch.";
-static const char *kTerminalOutError = "I won't write compressed data to a terminal";
-static const char *kSameTerminalError = "I won't write data and program's messages to same stream";
-static const char *kEmptyFilePath = "Empty file path";
-static const char *kCannotFindArchive = "Cannot find archive";
+// static const char * const kUserErrorMessage = "Incorrect command line";
+static const char * const kCannotFindListFile = "Cannot find listfile";
+static const char * const kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch.";
+static const char * const kTerminalOutError = "I won't write compressed data to a terminal";
+static const char * const kSameTerminalError = "I won't write data and program's messages to same stream";
+static const char * const kEmptyFilePath = "Empty file path";
+static const char * const kCannotFindArchive = "Cannot find archive";
bool CArcCommand::IsFromExtractGroup() const
{
@@ -328,7 +335,7 @@ static const char *g_Commands = "audtexlbih";
static bool ParseArchiveCommand(const UString &commandString, CArcCommand &command)
{
- UString s = commandString;
+ UString s (commandString);
s.MakeLower_Ascii();
if (s.Len() == 1)
{
@@ -386,9 +393,9 @@ static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs,
val += pair.NewName;
val.Add_LF();
if (type == NRecursedType::kRecursed)
- val.AddAscii("-r");
+ val += "-r";
else if (type == NRecursedType::kWildcardOnlyRecursed)
- val.AddAscii("-r0");
+ val += "-r0";
throw CArcCmdLineException("Unsupported rename command:", val);
}
}
@@ -422,23 +429,28 @@ static void AddToCensorFromNonSwitchesStrings(
CObjectVector<CRenamePair> *renamePairs,
unsigned startIndex,
NWildcard::CCensor &censor,
- const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,
+ const UStringVector &nonSwitchStrings,
+ int stopSwitchIndex,
+ NRecursedType::EEnum type,
bool wildcardMatching,
bool thereAreSwitchIncludes, Int32 codePage)
{
if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes)
- AddNameToCensor(censor, kUniversalWildcard, true, type,
+ AddNameToCensor(censor, UString(kUniversalWildcard), true, type,
true // wildcardMatching
);
int oldIndex = -1;
+ if (stopSwitchIndex < 0)
+ stopSwitchIndex = nonSwitchStrings.Size();
+
for (unsigned i = startIndex; i < nonSwitchStrings.Size(); i++)
{
const UString &s = nonSwitchStrings[i];
if (s.IsEmpty())
throw CArcCmdLineException(kEmptyFilePath);
- if (s[0] == kFileListID)
+ if (i < (unsigned)stopSwitchIndex && s[0] == kFileListID)
AddToCensorFromListFile(renamePairs, censor, s.Ptr(1), true, type, wildcardMatching, codePage);
else if (renamePairs)
{
@@ -477,7 +489,7 @@ struct CEventSetEnd
}
};
-const char *k_IncorrectMapCommand = "Incorrect Map command";
+static const char * const k_IncorrectMapCommand = "Incorrect Map command";
static const char *ParseMapWithPaths(
NWildcard::CCensor &censor,
@@ -485,7 +497,7 @@ static const char *ParseMapWithPaths(
NRecursedType::EEnum commonRecursedType,
bool wildcardMatching)
{
- UString s = s2;
+ UString s (s2);
int pos = s.Find(L':');
if (pos < 0)
return k_IncorrectMapCommand;
@@ -577,7 +589,7 @@ static void AddSwitchWildcardsToCensor(
break;
}
- UString tail = name.Ptr(pos + 1);
+ const UString tail = name.Ptr(pos + 1);
if (name[pos] == kImmediateNameID)
AddNameToCensor(censor, tail, include, recursedType, wildcardMatching);
@@ -610,7 +622,7 @@ static void ConvertToLongName(const UString &prefix, UString &name)
if (name.IsEmpty() || DoesNameContainWildcard(name))
return;
NFind::CFileInfo fi;
- const FString path = us2fs(prefix + name);
+ const FString path (us2fs(prefix + name));
#ifndef UNDER_CE
if (NFile::NName::IsDevicePath(path))
return;
@@ -693,11 +705,11 @@ static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
}
*/
-static const wchar_t *kUpdatePairStateIDSet = L"pqrxyzw";
+static const char * const kUpdatePairStateIDSet = "pqrxyzw";
static const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
static const unsigned kNumUpdatePairActions = 4;
-static const char *kUpdateIgnoreItselfPostStringID = "-";
+static const char * const kUpdateIgnoreItselfPostStringID = "-";
static const wchar_t kUpdateNewArchivePostCharID = '!';
@@ -707,8 +719,8 @@ static bool ParseUpdateCommandString2(const UString &command,
for (unsigned i = 0; i < command.Len();)
{
wchar_t c = MyCharLower_Ascii(command[i]);
- int statePos = FindCharPosInString(kUpdatePairStateIDSet, c);
- if (statePos < 0)
+ int statePos = FindCharPosInString(kUpdatePairStateIDSet, (char)c);
+ if (c > 0x7F || statePos < 0)
{
postString = command.Ptr(i);
return true;
@@ -849,7 +861,6 @@ static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &pr
}
}
-CArcCmdLineParser::CArcCmdLineParser(): parser(ARRAY_SIZE(kSwitchForms)) {}
static inline void SetStreamMode(const CSwitchResult &sw, unsigned &res)
{
@@ -857,10 +868,11 @@ static inline void SetStreamMode(const CSwitchResult &sw, unsigned &res)
res = sw.PostCharIndex;
}
+
void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
CArcCmdLineOptions &options)
{
- if (!parser.ParseStrings(kSwitchForms, commandStrings))
+ if (!parser.ParseStrings(kSwitchForms, ARRAY_SIZE(kSwitchForms), commandStrings))
throw CArcCmdLineException(parser.ErrorMessage, parser.ErrorLine);
options.IsInTerminal = MY_IS_TERMINAL(stdin);
@@ -965,7 +977,7 @@ static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned key
if (!parser[keyIndex].ThereIs)
return defaultVal;
- UString name = parser[keyIndex].PostStrings.Back();
+ UString name (parser[keyIndex].PostStrings.Back());
UInt32 v;
if (StringToUInt32(name, v))
if (v < ((UInt32)1 << 16))
@@ -1051,7 +1063,7 @@ static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID,
void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
{
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
- unsigned numNonSwitchStrings = nonSwitchStrings.Size();
+ const unsigned numNonSwitchStrings = nonSwitchStrings.Size();
if (numNonSwitchStrings < kMinNonSwitchWords)
throw CArcCmdLineException("The command must be specified");
@@ -1082,6 +1094,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
}
}
+ if (parser[NKey::kNameTrailReplace].ThereIs)
+ g_PathTrailReplaceMode = !parser[NKey::kNameTrailReplace].WithMinus;
+
NRecursedType::EEnum recursedType;
if (parser[NKey::kRecursed].ThereIs)
recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
@@ -1138,7 +1153,8 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
AddToCensorFromNonSwitchesStrings(isRename ? &options.UpdateOptions.RenamePairs : NULL,
curCommandIndex, options.Censor,
- nonSwitchStrings, recursedType, wildcardMatching,
+ nonSwitchStrings, parser.StopSwitchIndex,
+ recursedType, wildcardMatching,
thereAreSwitchIncludes, codePage);
options.YesToAll = parser[NKey::kYes].ThereIs;
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h
index a345505c..1c96601a 100644
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.h
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h
@@ -130,7 +130,6 @@ class CArcCmdLineParser
{
NCommandLineParser::CParser parser;
public:
- CArcCmdLineParser();
void Parse1(const UStringVector &commandStrings, CArcCmdLineOptions &options);
void Parse2(CArcCmdLineOptions &options);
};
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
index bc116c93..8d645a29 100644
--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
@@ -5,7 +5,12 @@
#undef sprintf
#undef printf
+// #include <stdio.h>
+// #include "../../../../C/CpuTicks.h"
+
#include "../../../../C/Alloc.h"
+#include "../../../../C/CpuArch.h"
+
#include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h"
@@ -36,10 +41,14 @@ using namespace NWindows;
using namespace NFile;
using namespace NDir;
-static const char *kCantAutoRename = "Can not create file with auto name";
-static const char *kCantRenameFile = "Can not rename existing file";
-static const char *kCantDeleteOutputFile = "Can not delete output file";
-static const char *kCantDeleteOutputDir = "Can not delete output folder";
+static const char * const kCantAutoRename = "Can not create file with auto name";
+static const char * const kCantRenameFile = "Can not rename existing file";
+static const char * const kCantDeleteOutputFile = "Can not delete output file";
+static const char * const kCantDeleteOutputDir = "Can not delete output folder";
+static const char * const kCantCreateHardLink = "Can not create hard link";
+static const char * const kCantCreateSymLink = "Can not create symbolic link";
+static const char * const kCantOpenOutFile = "Can not open output file";
+static const char * const kCantSetFileLen = "Can not set length for output file";
#ifndef _SFX
@@ -381,14 +390,13 @@ HRESULT CArchiveExtractCallback::GetUnpackSize()
static void AddPathToMessage(UString &s, const FString &path)
{
- s.AddAscii(" : ");
+ s += " : ";
s += fs2us(path);
}
HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FString &path)
{
- UString s;
- s.AddAscii(message);
+ UString s (message);
AddPathToMessage(s, path);
return _extractCallback2->MessageError(s);
}
@@ -396,11 +404,10 @@ HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FSt
HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path)
{
DWORD errorCode = GetLastError();
- UString s;
- s.AddAscii(message);
+ UString s (message);
if (errorCode != 0)
{
- s.AddAscii(" : ");
+ s += " : ";
s += NError::MyFormatMessage(errorCode);
}
AddPathToMessage(s, path);
@@ -409,8 +416,7 @@ HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *mes
HRESULT CArchiveExtractCallback::SendMessageError2(const char *message, const FString &path1, const FString &path2)
{
- UString s;
- s.AddAscii(message);
+ UString s (message);
AddPathToMessage(s, path1);
AddPathToMessage(s, path2);
return _extractCallback2->MessageError(s);
@@ -440,7 +446,7 @@ STDMETHODIMP CGetProp::GetProp(PROPID propID, PROPVARIANT *value)
static UString GetDirPrefixOf(const UString &src)
{
- UString s = src;
+ UString s (src);
if (!s.IsEmpty())
{
if (IsPathSepar(s.Back()))
@@ -514,7 +520,7 @@ bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcIte
if (pathParts2.IsEmpty())
pathParts2.AddNew();
UString &back = pathParts2.Back();
- back += L':';
+ back += ':';
back += item.AltStreamName;
bool include2;
@@ -541,7 +547,7 @@ bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem
static FString MakePath_from_2_Parts(const FString &prefix, const FString &path)
{
- FString s = prefix;
+ FString s (prefix);
#if defined(_WIN32) && !defined(UNDER_CE)
if (!path.IsEmpty() && path[0] == ':' && !prefix.IsEmpty() && IsPathSepar(prefix.Back()))
{
@@ -596,6 +602,7 @@ HRESULT CArchiveExtractCallback::MyCopyFile(ISequentialOutStream *outStream)
#endif
*/
+
STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
{
COM_TRY_BEGIN
@@ -616,6 +623,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
_curSize = 0;
_curSizeDefined = false;
+ _fileLengthWasSet = false;
_index = index;
_diskFilePath.Empty();
@@ -928,13 +936,13 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
}
GetProp_Spec->Arc = _arc;
GetProp_Spec->IndexInArc = index;
- UString name = MakePathFromParts(pathParts);
+ UString name (MakePathFromParts(pathParts));
#ifdef SUPPORT_ALT_STREAMS
if (_item.IsAltStream)
{
if (!pathParts.IsEmpty() || (!_removePartsForAltStreams && _pathMode != NExtract::NPathMode::kNoPathsAlt))
- name += L':';
+ name += ':';
name += _item.AltStreamName;
}
#endif
@@ -986,7 +994,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
if (_item.IsAltStream)
{
- UString s = _item.AltStreamName;
+ UString s (_item.AltStreamName);
Correct_AltStream_Name(s);
bool needColon = true;
@@ -1002,13 +1010,13 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
UString &name = pathParts.Back();
if (needColon)
- name += (wchar_t)(_ntOptions.ReplaceColonForAltStream ? L'_' : L':');
+ name += (char)(_ntOptions.ReplaceColonForAltStream ? '_' : ':');
name += s;
}
#endif
- UString processedPath = MakePathFromParts(pathParts);
+ UString processedPath (MakePathFromParts(pathParts));
if (!isAnti)
{
@@ -1035,7 +1043,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
}
- FString fullProcessedPath = us2fs(processedPath);
+ FString fullProcessedPath (us2fs(processedPath));
if (_pathMode != NExtract::NPathMode::kAbsPaths
|| !NName::IsAbsolutePath(processedPath))
{
@@ -1051,8 +1059,8 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
{
const CIndexToPathPair &pair = _renamedFiles[renIndex];
fullProcessedPath = pair.Path;
- fullProcessedPath += (FChar)':';
- UString s = _item.AltStreamName;
+ fullProcessedPath += ':';
+ UString s (_item.AltStreamName);
Correct_AltStream_Name(s);
fullProcessedPath += us2fs(s);
}
@@ -1086,7 +1094,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
case NExtract::NOverwriteMode::kAsk:
{
int slashPos = fullProcessedPath.ReverseFind_PathSepar();
- FString realFullProcessedPath = fullProcessedPath.Left(slashPos + 1) + fileInfo.Name;
+ FString realFullProcessedPath (fullProcessedPath.Left(slashPos + 1) + fileInfo.Name);
Int32 overwriteResult;
RINOK(_extractCallback2->AskOverwrite(
@@ -1119,7 +1127,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
}
else if (_overwriteMode == NExtract::NOverwriteMode::kRenameExisting)
{
- FString existPath = fullProcessedPath;
+ FString existPath (fullProcessedPath);
if (!AutoRenamePath(existPath))
{
RINOK(SendMessageError(kCantAutoRename, fullProcessedPath));
@@ -1165,7 +1173,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
int colonPos = NName::FindAltStreamColon(fullProcessedPath);
if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0)
{
- FString parentFsPath = fullProcessedPath;
+ FString parentFsPath (fullProcessedPath);
parentFsPath.DeleteFrom(colonPos);
NFind::CFileInfo parentFi;
if (parentFi.Find(parentFsPath))
@@ -1222,7 +1230,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
{
if (!MyCreateHardLink(fullProcessedPath, existPath))
{
- RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, existPath));
+ RINOK(SendMessageError2(kCantCreateHardLink, fullProcessedPath, existPath));
// return S_OK;
}
}
@@ -1270,7 +1278,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
else
if (!NFile::NIO::SetReparseData(fullProcessedPath, _item.IsDir, data, (DWORD)data.Size()))
{
- RINOK(SendMessageError_with_LastError("Can not create symbolic link", fullProcessedPath));
+ RINOK(SendMessageError_with_LastError(kCantCreateSymLink, fullProcessedPath));
}
}
}
@@ -1304,7 +1312,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
{
if (!MyCreateHardLink(fullProcessedPath, hl))
{
- RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, hl));
+ RINOK(SendMessageError2(kCantCreateHardLink, fullProcessedPath, hl));
return S_OK;
}
needWriteFile = false;
@@ -1323,11 +1331,24 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
{
// if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
{
- RINOK(SendMessageError_with_LastError("Can not open output file", fullProcessedPath));
+ RINOK(SendMessageError_with_LastError(kCantOpenOutFile, fullProcessedPath));
return S_OK;
}
}
+ if (_ntOptions.PreAllocateOutFile && !_isSplit && _curSizeDefined && _curSize > (1 << 12))
+ {
+ // UInt64 ticks = GetCpuTicks();
+ bool res = _outFileStreamSpec->File.SetLength(_curSize);
+ _fileLengthWasSet = res;
+ _outFileStreamSpec->File.SeekToBegin();
+ // ticks = GetCpuTicks() - ticks;
+ // printf("\nticks = %10d\n", (unsigned)ticks);
+ if (!res)
+ {
+ RINOK(SendMessageError_with_LastError(kCantSetFileLen, fullProcessedPath));
+ }
+ }
#ifdef SUPPORT_ALT_STREAMS
if (isRenamed && !_item.IsAltStream)
@@ -1456,14 +1477,24 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes)
if (_outFileStream)
{
+ HRESULT hres = S_OK;
_outFileStreamSpec->SetTime(
(WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
(WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
(WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
- _curSize = _outFileStreamSpec->ProcessedSize;
+ const UInt64 processedSize = _outFileStreamSpec->ProcessedSize;
+ if (_fileLengthWasSet && _curSize > processedSize)
+ {
+ bool res = _outFileStreamSpec->File.SetLength(processedSize);
+ _fileLengthWasSet = res;
+ if (!res)
+ hres = SendMessageError_with_LastError(kCantSetFileLen, us2fs(_item.Path));
+ }
+ _curSize = processedSize;
_curSizeDefined = true;
RINOK(_outFileStreamSpec->Close());
_outFileStream.Release();
+ RINOK(hres);
}
#ifdef _USE_SECURITY_CODE
@@ -1525,23 +1556,19 @@ STDMETHODIMP CArchiveExtractCallback::ReportExtractResult(UInt32 indexType, UInt
if (_folderArchiveExtractCallback2)
{
bool isEncrypted = false;
- wchar_t temp[16];
- UString s2;
- const wchar_t *s = NULL;
+ UString s;
if (indexType == NArchive::NEventIndexType::kInArcIndex && index != (UInt32)(Int32)-1)
{
CReadArcItem item;
RINOK(_arc->GetItem(index, item));
- s2 = item.Path;
- s = s2;
+ s = item.Path;
RINOK(Archive_GetItemBoolProp(_arc->Archive, index, kpidEncrypted, isEncrypted));
}
else
{
- temp[0] = '#';
- ConvertUInt32ToString(index, temp + 1);
- s = temp;
+ s = '#';
+ s.Add_UInt32(index);
// if (indexType == NArchive::NEventIndexType::kBlockIndex) {}
}
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
index 7d4155fe..058ddbcf 100644
--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.h
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
@@ -57,6 +57,8 @@ struct CExtractNtOptions
bool ReplaceColonForAltStream;
bool WriteToAltStreamIfColon;
+ bool PreAllocateOutFile;
+
CExtractNtOptions():
ReplaceColonForAltStream(false),
WriteToAltStreamIfColon(false)
@@ -64,6 +66,13 @@ struct CExtractNtOptions
SymLinks.Val = true;
HardLinks.Val = true;
AltStreams.Val = true;
+
+ PreAllocateOutFile =
+ #ifdef _WIN32
+ true;
+ #else
+ false;
+ #endif
}
};
@@ -201,6 +210,7 @@ class CArchiveExtractCallback:
UInt32 _index;
UInt64 _curSize;
bool _curSizeDefined;
+ bool _fileLengthWasSet;
COutFileStream *_outFileStreamSpec;
CMyComPtr<ISequentialOutStream> _outFileStream;
diff --git a/CPP/7zip/UI/Common/ArchiveName.cpp b/CPP/7zip/UI/Common/ArchiveName.cpp
index 06d2ab80..a3a44ce2 100644
--- a/CPP/7zip/UI/Common/ArchiveName.cpp
+++ b/CPP/7zip/UI/Common/ArchiveName.cpp
@@ -29,7 +29,7 @@ UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepName)
{
- FString resultName = FTEXT("Archive");
+ FString resultName ("Archive");
if (fromPrev)
{
FString dirPrefix;
diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp
index ecbacbc9..70d4ffd6 100644
--- a/CPP/7zip/UI/Common/Bench.cpp
+++ b/CPP/7zip/UI/Common/Bench.cpp
@@ -32,8 +32,6 @@
#include "../../../../C/Alloc.h"
#include "../../../../C/CpuArch.h"
-#include "../../../Windows/System.h"
-
#ifndef _7ZIP_ST
#include "../../../Windows/Synchronization.h"
#include "../../../Windows/Thread.h"
@@ -1200,10 +1198,9 @@ static HRESULT MethodBench(
if (oldLzmaBenchMode && methodId == k_LZMA)
{
- bool fixedNumber;
- UInt32 numLzmaThreads = method.Get_Lzma_NumThreads(fixedNumber);
- if (!fixedNumber && numThreads == 1)
+ if (numThreads == 1 && method.Get_NumThreads() < 0)
method.AddProp_NumThreads(1);
+ const UInt32 numLzmaThreads = method.Get_Lzma_NumThreads();
if (numThreads > 1 && numLzmaThreads > 1)
{
numEncoderThreads = numThreads / 2;
@@ -1858,6 +1855,37 @@ static void PrintTotals(IBenchPrintCallback &f, bool showFreq, UInt64 cpuFreq, c
PrintResults(f, res.Usage / numIterations2, res.RPU / numIterations2, res.Rating / numIterations2, showFreq, cpuFreq);
}
+
+static void PrintHex(AString &s, UInt64 v)
+{
+ char temp[32];
+ ConvertUInt64ToHex(v, temp);
+ s += temp;
+}
+
+AString GetProcessThreadsInfo(const NSystem::CProcessAffinity &ti)
+{
+ AString s;
+ // s.Add_UInt32(ti.numProcessThreads);
+ if (ti.processAffinityMask != ti.systemAffinityMask)
+ {
+ // if (ti.numProcessThreads != ti.numSysThreads)
+ {
+ s += " / ";
+ s.Add_UInt32(ti.GetNumSystemThreads());
+ }
+ s += " : ";
+ PrintHex(s, ti.processAffinityMask);
+ s += " / ";
+ PrintHex(s, ti.systemAffinityMask);
+ }
+ return s;
+}
+
+
+extern bool g_LargePagesMode;
+
+
static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads)
{
@@ -1867,12 +1895,16 @@ static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
PrintNumber(f, (size >> 20), 6);
else
f.Print(" ?");
- f.Print(" MB, # ");
+ f.Print(" MB");
+ if (g_LargePagesMode)
+ f.Print(" LP");
+ f.Print(", # ");
f.Print(threadsString);
PrintNumber(f, numThreads, 3);
- f.NewLine();
}
+
+
struct CBenchCallbackToPrint: public IBenchCallback
{
CBenchProps BenchProps;
@@ -1930,7 +1962,7 @@ HRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool fina
return S_OK;
}
-static const char *kSep = " | ";
+static const char * const kSep = " | ";
HRESULT CBenchCallbackToPrint::SetDecodeResult(const CBenchInfo &info, bool final)
{
@@ -2147,7 +2179,7 @@ static HRESULT CrcBench(
numThreads = 1;
#endif
- AString methodName = method.MethodName;
+ const AString &methodName = method.MethodName;
// methodName.RemoveChar(L'-');
CMethodId hashID;
if (!FindHashMethod(
@@ -2410,6 +2442,240 @@ static void x86cpuid_to_String(const Cx86cpuid &c, AString &s)
#endif
+
+static const char * const k_PROCESSOR_ARCHITECTURE[] =
+{
+ "x86" // "INTEL"
+ , "MIPS"
+ , "ALPHA"
+ , "PPC"
+ , "SHX"
+ , "ARM"
+ , "IA64"
+ , "ALPHA64"
+ , "MSIL"
+ , "x64" // "AMD64"
+ , "IA32_ON_WIN64"
+ , "NEUTRAL"
+ , "ARM64"
+ , "ARM32_ON_WIN64"
+};
+
+#define MY__PROCESSOR_ARCHITECTURE_INTEL 0
+#define MY__PROCESSOR_ARCHITECTURE_AMD64 9
+
+
+#define MY__PROCESSOR_INTEL_PENTIUM 586
+#define MY__PROCESSOR_AMD_X8664 8664
+
+/*
+static const CUInt32PCharPair k_PROCESSOR[] =
+{
+ { 2200, "IA64" },
+ { 8664, "x64" }
+};
+
+#define PROCESSOR_INTEL_386 386
+#define PROCESSOR_INTEL_486 486
+#define PROCESSOR_INTEL_PENTIUM 586
+#define PROCESSOR_INTEL_860 860
+#define PROCESSOR_INTEL_IA64 2200
+#define PROCESSOR_AMD_X8664 8664
+#define PROCESSOR_MIPS_R2000 2000
+#define PROCESSOR_MIPS_R3000 3000
+#define PROCESSOR_MIPS_R4000 4000
+#define PROCESSOR_ALPHA_21064 21064
+#define PROCESSOR_PPC_601 601
+#define PROCESSOR_PPC_603 603
+#define PROCESSOR_PPC_604 604
+#define PROCESSOR_PPC_620 620
+#define PROCESSOR_HITACHI_SH3 10003
+#define PROCESSOR_HITACHI_SH3E 10004
+#define PROCESSOR_HITACHI_SH4 10005
+#define PROCESSOR_MOTOROLA_821 821
+#define PROCESSOR_SHx_SH3 103
+#define PROCESSOR_SHx_SH4 104
+#define PROCESSOR_STRONGARM 2577 // 0xA11
+#define PROCESSOR_ARM720 1824 // 0x720
+#define PROCESSOR_ARM820 2080 // 0x820
+#define PROCESSOR_ARM920 2336 // 0x920
+#define PROCESSOR_ARM_7TDMI 70001
+#define PROCESSOR_OPTIL 18767 // 0x494f
+*/
+
+#ifdef _WIN32
+
+static const char * const k_PF[] =
+{
+ "FP_ERRATA"
+ , "FP_EMU"
+ , "CMPXCHG"
+ , "MMX"
+ , "PPC_MOVEMEM_64BIT"
+ , "ALPHA_BYTE"
+ , "SSE"
+ , "3DNOW"
+ , "RDTSC"
+ , "PAE"
+ , "SSE2"
+ , "SSE_DAZ"
+ , "NX"
+ , "SSE3"
+ , "CMPXCHG16B"
+ , "CMP8XCHG16"
+ , "CHANNELS"
+ , "XSAVE"
+ , "ARM_VFP_32"
+ , "ARM_NEON"
+ , "L2AT"
+ , "VIRT_FIRMWARE"
+ , "RDWRFSGSBASE"
+ , "FASTFAIL"
+ , "ARM_DIVIDE"
+ , "ARM_64BIT_LOADSTORE_ATOMIC"
+ , "ARM_EXTERNAL_CACHE"
+ , "ARM_FMAC"
+ , "RDRAND"
+ , "ARM_V8"
+ , "ARM_V8_CRYPTO"
+ , "ARM_V8_CRC32"
+ , "RDTSCP"
+};
+
+#endif
+
+
+static void PrintSize(AString &s, UInt64 ptr)
+{
+ UInt64 v = ptr;
+ UInt64 t = v >> 40;
+ UInt64 g = v >> 30;
+ UInt64 m = v >> 20;
+ UInt64 k = v >> 10;
+ UInt32 d = (UInt32)v;
+ char c = 0;
+ if (t >= 1000) { d = (UInt32)t; c = 'T'; }
+ else if (g >= 1000) { d = (UInt32)g; c = 'G'; }
+ else if (m >= 1000) { d = (UInt32)m; c = 'M'; }
+ else if (k >= 10) { d = (UInt32)k; c = 'K'; }
+
+ s.Add_UInt32(d);
+ // s += ' ';
+ if (c)
+ s += c;
+
+
+ // PrintHex(s, (DWORD_PTR)v);
+}
+
+
+static void PrintPage(AString &s, UInt32 v)
+{
+ if ((v & 0x3FF) == 0)
+ {
+ s.Add_UInt32(v >> 10);
+ s += "K";
+ }
+ else
+ s.Add_UInt32(v >> 10);
+}
+
+static AString TypeToString2(const char * const table[], unsigned num, UInt32 value)
+{
+ char sz[16];
+ const char *p = NULL;
+ if (value < num)
+ p = table[value];
+ if (!p)
+ {
+ ConvertUInt32ToString(value, sz);
+ p = sz;
+ }
+ return (AString)p;
+}
+
+#ifdef _WIN32
+
+static void SysInfo_To_String(AString &s, const SYSTEM_INFO &si)
+{
+ s += TypeToString2(k_PROCESSOR_ARCHITECTURE, ARRAY_SIZE(k_PROCESSOR_ARCHITECTURE), si.wProcessorArchitecture);
+
+ if (!( si.wProcessorArchitecture == MY__PROCESSOR_ARCHITECTURE_INTEL && si.dwProcessorType == MY__PROCESSOR_INTEL_PENTIUM
+ || si.wProcessorArchitecture == MY__PROCESSOR_ARCHITECTURE_AMD64 && si.dwProcessorType == MY__PROCESSOR_AMD_X8664))
+ {
+ s += " ";
+ // s += TypePairToString(k_PROCESSOR, ARRAY_SIZE(k_PROCESSOR), si.dwProcessorType);
+ s.Add_UInt32(si.dwProcessorType);
+ }
+ s += " ";
+ PrintHex(s, si.wProcessorLevel);
+ s += ".";
+ PrintHex(s, si.wProcessorRevision);
+ if (si.dwActiveProcessorMask + 1 != ((UInt64)1 << si.dwNumberOfProcessors))
+ {
+ s += " act:";
+ PrintHex(s, si.dwActiveProcessorMask);
+ }
+ s += " cpus:";
+ s.Add_UInt32(si.dwNumberOfProcessors);
+ if (si.dwPageSize != 1 << 12)
+ {
+ s += " page:";
+ PrintPage(s, si.dwPageSize);
+ }
+ if (si.dwAllocationGranularity != 1 << 16)
+ {
+ s += " gran:";
+ PrintPage(s, si.dwAllocationGranularity);
+ }
+ s += " ";
+
+ DWORD_PTR minAdd = (DWORD_PTR)si.lpMinimumApplicationAddress;
+ if (minAdd != (1 << 16))
+ {
+ PrintSize(s, minAdd);
+ s += "-";
+ }
+ PrintSize(s, (UInt64)(DWORD_PTR)si.lpMaximumApplicationAddress + 1);
+}
+
+#ifndef _WIN64
+typedef VOID (WINAPI *Func_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo);
+#endif
+
+#endif
+
+void GetSysInfo(AString &s1, AString &s2)
+{
+ s1.Empty();
+ s2.Empty();
+
+ #ifdef _WIN32
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ {
+ SysInfo_To_String(s1, si);
+ // s += " : ";
+ }
+
+ #if !defined(_WIN64) && !defined(UNDER_CE)
+ Func_GetNativeSystemInfo fn_GetNativeSystemInfo = (Func_GetNativeSystemInfo)GetProcAddress(
+ GetModuleHandleA("kernel32.dll"), "GetNativeSystemInfo");
+ if (fn_GetNativeSystemInfo)
+ {
+ SYSTEM_INFO si2;
+ fn_GetNativeSystemInfo(&si2);
+ // if (memcmp(&si, &si2, sizeof(si)) != 0)
+ {
+ // s += " - ";
+ SysInfo_To_String(s2, si2);
+ }
+ }
+ #endif
+ #endif
+}
+
+
void GetCpuName(AString &s)
{
s.Empty();
@@ -2419,31 +2685,53 @@ void GetCpuName(AString &s)
Cx86cpuid cpuid;
if (x86cpuid_CheckAndRead(&cpuid))
{
- x86cpuid_to_String(cpuid, s);
+ AString s2;
+ x86cpuid_to_String(cpuid, s2);
+ s += s2;
return;
}
#ifdef MY_CPU_AMD64
- s = "x64";
+ s += "x64";
#else
- s = "x86";
+ s += "x86";
#endif
}
#else
#ifdef MY_CPU_LE
- s = "LE";
+ s += "LE";
#elif defined(MY_CPU_BE)
- s = "BE";
+ s += "BE";
#endif
#endif
}
+void GetCpuFeatures(AString &s)
+{
+ s.Empty();
+
+ #ifdef _WIN32
+ const unsigned kNumFeatures_Extra = 32; // we check also for unknown features
+ const unsigned kNumFeatures = ARRAY_SIZE(k_PF) + kNumFeatures_Extra;
+ for (unsigned i = 0; i < kNumFeatures; i++)
+ {
+ if (IsProcessorFeaturePresent(i))
+ {
+ s.Add_Space_if_NotEmpty();
+ s += TypeToString2(k_PF, ARRAY_SIZE(k_PF), i);
+ }
+ }
+ #endif
+}
+
+
HRESULT Bench(
DECL_EXTERNAL_CODECS_LOC_VARS
IBenchPrintCallback *printCallback,
IBenchCallback *benchCallback,
+ // IBenchFreqCallback *freqCallback,
const CObjectVector<CProperty> &props,
UInt32 numIterations,
bool multiDict)
@@ -2454,8 +2742,16 @@ HRESULT Bench(
UInt32 numCPUs = 1;
UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29;
+ NSystem::CProcessAffinity threadsInfo;
+ threadsInfo.InitST();
+
#ifndef _7ZIP_ST
- numCPUs = NSystem::GetNumberOfProcessors();
+
+ if (threadsInfo.Get() && threadsInfo.processAffinityMask != 0)
+ numCPUs = threadsInfo.GetNumProcessThreads();
+ else
+ numCPUs = NSystem::GetNumberOfProcessors();
+
#endif
bool ramSize_Defined = NSystem::GetRamSize(ramSize);
@@ -2477,7 +2773,7 @@ HRESULT Bench(
for (i = 0; i < props.Size(); i++)
{
const CProperty &property = props[i];
- UString name = property.Name;
+ UString name (property.Name);
name.MakeLower_Ascii();
if (name.IsEqualTo("file"))
@@ -2504,7 +2800,6 @@ HRESULT Bench(
if (printCallback)
{
printCallback->Print("file size =");
- // printCallback->Print(GetOemString(property.Value));
PrintNumber(*printCallback, len, 0);
printCallback->NewLine();
}
@@ -2523,14 +2818,14 @@ HRESULT Bench(
if (name.IsEqualTo("time"))
{
- RINOK(ParsePropToUInt32(L"", propVariant, testTime));
+ RINOK(ParsePropToUInt32(UString(), propVariant, testTime));
continue;
}
if (name.IsEqualTo("freq"))
{
UInt32 freq32 = 0;
- RINOK(ParsePropToUInt32(L"", propVariant, freq32));
+ RINOK(ParsePropToUInt32(UString(), propVariant, freq32));
if (freq32 == 0)
return E_INVALIDARG;
specifiedFreq = (UInt64)freq32 * 1000000;
@@ -2548,19 +2843,12 @@ HRESULT Bench(
if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
UString s = name.Ptr(2);
- if (s == L"*")
+ if (s.IsEqualTo("*")
+ || s.IsEmpty() && propVariant.vt == VT_BSTR && StringsAreEqual_Ascii(propVariant.bstrVal, "*"))
{
multiThreadTests = true;
continue;
}
- if (s.IsEmpty() && propVariant.vt == VT_BSTR)
- {
- if (wcscmp(propVariant.bstrVal, L"*") == 0)
- {
- multiThreadTests = true;
- continue;
- }
- }
#ifndef _7ZIP_ST
RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified));
#endif
@@ -2573,10 +2861,38 @@ HRESULT Bench(
if (printCallback)
{
- AString s;
- GetCpuName(s);
- printCallback->Print(s);
- printCallback->NewLine();
+ {
+ AString s1, s2;
+ GetSysInfo(s1, s2);
+ if (!s1.IsEmpty() || !s2.IsEmpty())
+ {
+ printCallback->Print(s1);
+ if (s1 != s2 && !s2.IsEmpty())
+ {
+ printCallback->Print(" - ");
+ printCallback->Print(s2);
+ }
+ printCallback->NewLine();
+ }
+ }
+ {
+ AString s;
+ GetCpuFeatures(s);
+ if (!s.IsEmpty())
+ {
+ printCallback->Print(s);
+ printCallback->NewLine();
+ }
+ }
+ {
+ AString s;
+ GetCpuName(s);
+ if (!s.IsEmpty())
+ {
+ printCallback->Print(s);
+ printCallback->NewLine();
+ }
+ }
}
if (printCallback)
@@ -2586,7 +2902,7 @@ HRESULT Bench(
UInt64 complexInCommands = kComplexInCommands;
- if (printCallback /* || benchCallback */)
+ if (printCallback /* || freqCallback */)
{
UInt64 numMilCommands = 1 << 6;
if (specifiedFreq != 0)
@@ -2623,8 +2939,8 @@ HRESULT Bench(
}
}
/*
- if (benchCallback)
- benchCallback->AddCpuFreq(mipsVal);
+ if (freqCallback)
+ freqCallback->AddCpuFreq(mipsVal);
*/
if (jj >= 3)
@@ -2643,6 +2959,8 @@ HRESULT Bench(
printCallback->NewLine();
printCallback->NewLine();
PrintRequirements(*printCallback, "size: ", ramSize_Defined, ramSize, "CPU hardware threads:", numCPUs);
+ printCallback->Print(GetProcessThreadsInfo(threadsInfo));
+ printCallback->NewLine();
}
if (numThreadsSpecified < 1 || numThreadsSpecified > kNumThreadsMax)
@@ -2669,7 +2987,7 @@ HRESULT Bench(
kOldLzmaDictBits, printCallback, benchCallback, &benchProps);
}
- AString methodName = method.MethodName;
+ AString methodName (method.MethodName);
if (methodName.IsEqualTo_Ascii_NoCase("CRC"))
methodName = "crc32";
method.MethodName = methodName;
@@ -2691,7 +3009,7 @@ HRESULT Bench(
for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++)
{
const CBenchHash &h = g_Hash[i];
- AString s = h.Name;
+ AString s (h.Name);
AString hProp;
int propPos = s.Find(':');
if (propPos >= 0)
@@ -2852,6 +3170,7 @@ HRESULT Bench(
}
PrintRequirements(f, "usage:", true, GetBenchMemoryUsage(numThreads, dict, totalBenchMode), "Benchmark threads: ", numThreads);
+ f.NewLine();
f.NewLine();
@@ -3000,7 +3319,6 @@ HRESULT Bench(
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;
@@ -3040,7 +3358,7 @@ HRESULT Bench(
// method2 can have two different dictionary size properties.
// And last property is main.
NCOM::CPropVariant propVariant = (UInt32)pow;
- RINOK(method2.ParseMethodFromPROPVARIANT(L"d", propVariant));
+ RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant));
}
size_t uncompressedDataSize;
diff --git a/CPP/7zip/UI/Common/Bench.h b/CPP/7zip/UI/Common/Bench.h
index 841250ef..ec51faee 100644
--- a/CPP/7zip/UI/Common/Bench.h
+++ b/CPP/7zip/UI/Common/Bench.h
@@ -3,6 +3,8 @@
#ifndef __7ZIP_BENCH_H
#define __7ZIP_BENCH_H
+#include "../../../Windows/System.h"
+
#include "../../Common/CreateCoder.h"
#include "../../UI/Common/Property.h"
@@ -43,13 +45,28 @@ struct IBenchPrintCallback
virtual HRESULT CheckBreak() = 0;
};
+/*
+struct IBenchFreqCallback
+{
+ virtual void AddCpuFreq(UInt64 freq) = 0;
+};
+*/
+
HRESULT Bench(
DECL_EXTERNAL_CODECS_LOC_VARS
IBenchPrintCallback *printCallback,
IBenchCallback *benchCallback,
+ // IBenchFreqCallback *freqCallback,
const CObjectVector<CProperty> &props,
UInt32 numIterations,
bool multiDict
);
+AString GetProcessThreadsInfo(const NWindows::NSystem::CProcessAffinity &ti);
+
+void GetSysInfo(AString &s1, AString &s2);
+void GetCpuName(AString &s);
+void GetCpuFeatures(AString &s);
+
+
#endif
diff --git a/CPP/7zip/UI/Common/CompressCall.cpp b/CPP/7zip/UI/Common/CompressCall.cpp
index 37da9d1a..6439dfb9 100644
--- a/CPP/7zip/UI/Common/CompressCall.cpp
+++ b/CPP/7zip/UI/Common/CompressCall.cpp
@@ -30,24 +30,24 @@ using namespace NWindows;
#define MY_TRY_FINISH_VOID } \
catch(...) { ErrorMessageHRESULT(E_FAIL); }
-static const char *k7zGui = "7zG.exe";
+#define k7zGui "7zG.exe"
-static const char *kShowDialogSwitch = " -ad";
-static const char *kEmailSwitch = " -seml.";
-static const char *kIncludeSwitch = " -i";
-static const char *kArchiveTypeSwitch = " -t";
-static const char *kArcIncludeSwitches = " -an -ai";
-static const char *kHashIncludeSwitches = " -i";
-static const char *kStopSwitchParsing = " --";
-static const char *kLargePagesDisable = " -slp-";
+#define kShowDialogSwitch " -ad"
+#define kEmailSwitch " -seml."
+#define kIncludeSwitch " -i"
+#define kArchiveTypeSwitch " -t"
+#define kArcIncludeSwitches " -an -ai"
+#define kHashIncludeSwitches " -i"
+#define kStopSwitchParsing " --"
+#define kLargePagesDisable " -slp-"
extern HWND g_HWND;
UString GetQuotedString(const UString &s)
{
- UString s2 = L'\"';
+ UString s2 ('\"');
s2 += s;
- s2 += L'\"';
+ s2 += '\"';
return s2;
}
@@ -73,7 +73,7 @@ static HRESULT Call7zGui(const UString &params,
NSynchronization::CBaseEvent *event)
{
UString imageName = fs2us(NWindows::NDLL::GetModuleDirPrefix());
- imageName.AddAscii(k7zGui);
+ imageName += k7zGui;
CProcess process;
WRes res = process.Create(imageName, params, NULL); // curDir);
@@ -95,7 +95,7 @@ static HRESULT Call7zGui(const UString &params,
static void AddLagePagesSwitch(UString &params)
{
if (!ReadLockMemoryEnable())
- params.AddAscii(kLargePagesDisable);
+ params += kLargePagesDisable;
}
class CRandNameGenerator
@@ -105,10 +105,8 @@ public:
CRandNameGenerator() { _random.Init(); }
void GenerateName(UString &s, const char *prefix)
{
- s.AddAscii(prefix);
- char temp[16];
- ConvertUInt32ToString((UInt32)(unsigned)_random.Generate(), temp);
- s.AddAscii(temp);
+ s += prefix;
+ s.Add_UInt32((UInt32)(unsigned)_random.Generate());
}
};
@@ -150,14 +148,14 @@ static HRESULT CreateMap(const UStringVector &names,
event.Close();
}
- params += L'#';
+ params += '#';
params += mappingName;
- params += L':';
+ params += ':';
char temp[32];
ConvertUInt64ToString(totalSize, temp);
- params.AddAscii(temp);
+ params += temp;
- params += L':';
+ params += ':';
params += eventName;
LPVOID data = fileMapping.Map(FILE_MAP_WRITE, 0, totalSize);
@@ -187,36 +185,36 @@ HRESULT CompressFiles(
bool email, bool showDialog, bool waitFinish)
{
MY_TRY_BEGIN
- UString params = L'a';
+ UString params ('a');
CFileMapping fileMapping;
NSynchronization::CManualResetEvent event;
- params.AddAscii(kIncludeSwitch);
+ params += kIncludeSwitch;
RINOK(CreateMap(names, fileMapping, event, params));
if (!arcType.IsEmpty())
{
- params.AddAscii(kArchiveTypeSwitch);
+ params += kArchiveTypeSwitch;
params += arcType;
}
if (email)
- params.AddAscii(kEmailSwitch);
+ params += kEmailSwitch;
if (showDialog)
- params.AddAscii(kShowDialogSwitch);
+ params += kShowDialogSwitch;
AddLagePagesSwitch(params);
if (arcName.IsEmpty())
- params.AddAscii(" -an");
+ params += " -an";
if (addExtension)
- params.AddAscii(" -saa");
+ params += " -saa";
else
- params.AddAscii(" -sae");
+ params += " -sae";
- params.AddAscii(kStopSwitchParsing);
+ params += kStopSwitchParsing;
params.Add_Space();
if (!arcName.IsEmpty())
@@ -237,7 +235,7 @@ HRESULT CompressFiles(
static void ExtractGroupCommand(const UStringVector &arcPaths, UString &params, bool isHash)
{
AddLagePagesSwitch(params);
- params.AddAscii(isHash ? kHashIncludeSwitches : kArcIncludeSwitches);
+ params += (isHash ? kHashIncludeSwitches : kArcIncludeSwitches);
CFileMapping fileMapping;
NSynchronization::CManualResetEvent event;
HRESULT result = CreateMap(arcPaths, fileMapping, event, params);
@@ -250,16 +248,16 @@ static void ExtractGroupCommand(const UStringVector &arcPaths, UString &params,
void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup)
{
MY_TRY_BEGIN
- UString params = L'x';
+ UString params ('x');
if (!outFolder.IsEmpty())
{
- params.AddAscii(" -o");
+ params += " -o";
params += GetQuotedString(outFolder);
}
if (elimDup)
- params.AddAscii(" -spe");
+ params += " -spe";
if (showDialog)
- params.AddAscii(kShowDialogSwitch);
+ params += kShowDialogSwitch;
ExtractGroupCommand(arcPaths, params, false);
MY_TRY_FINISH_VOID
}
@@ -267,7 +265,7 @@ void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bo
void TestArchives(const UStringVector &arcPaths)
{
MY_TRY_BEGIN
- UString params = L't';
+ UString params ('t');
ExtractGroupCommand(arcPaths, params, false);
MY_TRY_FINISH_VOID
}
@@ -275,10 +273,10 @@ void TestArchives(const UStringVector &arcPaths)
void CalcChecksum(const UStringVector &paths, const UString &methodName)
{
MY_TRY_BEGIN
- UString params = L'h';
+ UString params ('h');
if (!methodName.IsEmpty())
{
- params.AddAscii(" -scrc");
+ params += " -scrc";
params += methodName;
}
ExtractGroupCommand(paths, params, true);
@@ -288,7 +286,10 @@ void CalcChecksum(const UStringVector &paths, const UString &methodName)
void Benchmark(bool totalMode)
{
MY_TRY_BEGIN
- HRESULT result = Call7zGui(totalMode ? L"b -mm=*" : L"b", false, NULL);
+ UString params ('b');
+ if (totalMode)
+ params += " -mm=*";
+ HRESULT result = Call7zGui(params, false, NULL);
if (result != S_OK)
ErrorMessageHRESULT(result);
MY_TRY_FINISH_VOID
diff --git a/CPP/7zip/UI/Common/CompressCall2.cpp b/CPP/7zip/UI/Common/CompressCall2.cpp
index b3421e5a..fb67ed12 100644
--- a/CPP/7zip/UI/Common/CompressCall2.cpp
+++ b/CPP/7zip/UI/Common/CompressCall2.cpp
@@ -59,9 +59,9 @@ static void ThrowException_if_Error(HRESULT res)
UString GetQuotedString(const UString &s)
{
- UString s2 = L'\"';
+ UString s2 ('\"');
s2 += s;
- s2 += L'\"';
+ s2 += '\"';
return s2;
}
@@ -145,6 +145,7 @@ HRESULT CompressFiles(
return S_OK;
}
+
static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
bool showDialog, const UString &outFolder, bool testMode, bool elimDup = false)
{
@@ -192,10 +193,14 @@ static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
censor.AddPathsToCensor(NWildcard::k_RelatPath);
bool messageWasDisplayed = false;
+
+ ecs->MultiArcMode = (arcPathsSorted.Size() > 1);
+
result = ExtractGUI(codecs,
formatIndices, CIntVector(),
arcPathsSorted, arcFullPathsSorted,
censor.Pairs.Front().Head, eo, NULL, showDialog, messageWasDisplayed, ecs, g_HWND);
+
if (result != S_OK)
{
if (result != E_ABORT && messageWasDisplayed)
@@ -260,8 +265,8 @@ void Benchmark(bool totalMode)
if (totalMode)
{
CProperty prop;
- prop.Name = L"m";
- prop.Value = L"*";
+ prop.Name = "m";
+ prop.Value = "*";
props.Add(prop);
}
result = Benchmark(EXTERNAL_CODECS_VARS_L props, g_HWND);
diff --git a/CPP/7zip/UI/Common/DirItem.h b/CPP/7zip/UI/Common/DirItem.h
index 4286b4e8..67e492d8 100644
--- a/CPP/7zip/UI/Common/DirItem.h
+++ b/CPP/7zip/UI/Common/DirItem.h
@@ -20,9 +20,18 @@ struct CDirItemsStat
UInt64 AltStreamsSize;
UInt64 NumErrors;
- // UInt64 GetTotalItems() const { return NumDirs + NumFiles + NumAltStreams; }
+ UInt64 Get_NumItems() const { return NumDirs + NumFiles + NumAltStreams; }
+ UInt64 Get_NumDataItems() const { return NumFiles + NumAltStreams; }
UInt64 GetTotalBytes() const { return FilesSize + AltStreamsSize; }
+
+ bool IsEmpty() const { return
+ 0 == NumDirs
+ && 0 == NumFiles
+ && 0 == NumAltStreams
+ && 0 == FilesSize
+ && 0 == AltStreamsSize
+ && 0 == NumErrors; }
CDirItemsStat():
NumDirs(0),
diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp
index 3ebf25aa..28887614 100644
--- a/CPP/7zip/UI/Common/EnumDirItems.cpp
+++ b/CPP/7zip/UI/Common/EnumDirItems.cpp
@@ -213,7 +213,8 @@ HRESULT CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phy
{
RINOK(ScanProgress(phyPrefix));
- NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
+ NFind::CEnumerator enumerator;
+ enumerator.SetDirPrefix(phyPrefix);
for (unsigned ttt = 0; ; ttt++)
{
NFind::CFileInfo fi;
@@ -570,7 +571,7 @@ static HRESULT EnumerateDirItems(
#endif
*/
- fullPath = FCHAR_PATH_SEPARATOR;
+ fullPath = CHAR_PATH_SEPARATOR;
}
#if defined(_WIN32) && !defined(UNDER_CE)
else if (item.IsDriveItem())
@@ -682,7 +683,7 @@ static HRESULT EnumerateDirItems(
{
{
if (nextNode.Name.IsEmpty())
- fullPath = FCHAR_PATH_SEPARATOR;
+ fullPath = CHAR_PATH_SEPARATOR;
#ifdef _WIN32
else if (NWildcard::IsDriveColonName(nextNode.Name))
fullPath.Add_PathSepar();
@@ -773,7 +774,9 @@ static HRESULT EnumerateDirItems(
#endif
#endif
- NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
+ NFind::CEnumerator enumerator;
+ enumerator.SetDirPrefix(phyPrefix);
+
for (unsigned ttt = 0; ; ttt++)
{
NFind::CFileInfo fi;
diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp
index 3da0aadb..e92c988e 100644
--- a/CPP/7zip/UI/Common/Extract.cpp
+++ b/CPP/7zip/UI/Common/Extract.cpp
@@ -51,7 +51,7 @@ static HRESULT DecompressArchive(
replaceName = arc0.DefaultName;
}
- outDir.Replace(FSTRING_ANY_MASK, us2fs(Get_Correct_FsFile_Name(replaceName)));
+ outDir.Replace(FString("*"), us2fs(Get_Correct_FsFile_Name(replaceName)));
bool elimIsPossible = false;
UString elimPrefix; // only pure name without dir delimiter
@@ -156,7 +156,7 @@ static HRESULT DecompressArchive(
#endif
if (outDir.IsEmpty())
- outDir = FTEXT(".") FSTRING_PATH_SEPARATOR;
+ outDir = "." STRING_PATH_SEPARATOR;
/*
#ifdef _WIN32
else if (NName::IsAltPathPrefix(outDir)) {}
@@ -167,7 +167,7 @@ static HRESULT DecompressArchive(
HRESULT res = ::GetLastError();
if (res == S_OK)
res = E_FAIL;
- errorMessage.SetFromAscii("Can not create output directory: ");
+ errorMessage = "Can not create output directory: ";
errorMessage += fs2us(outDir);
return res;
}
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
index 39e67b7f..e92badec 100644
--- a/CPP/7zip/UI/Common/ExtractingFilePath.cpp
+++ b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
@@ -8,6 +8,15 @@
#include "ExtractingFilePath.h"
+bool g_PathTrailReplaceMode =
+ #ifdef _WIN32
+ true
+ #else
+ false
+ #endif
+ ;
+
+
static void ReplaceIncorrectChars(UString &s)
{
{
@@ -26,17 +35,42 @@ static void ReplaceIncorrectChars(UString &s)
}
}
- #ifdef _WIN32
+ if (g_PathTrailReplaceMode)
{
- for (unsigned i = s.Len(); i != 0;)
+ /*
+ // if (g_PathTrailReplaceMode == 1)
{
- wchar_t c = s[--i];
- if (c != '.' && c != ' ')
- break;
- s.ReplaceOneCharAtPos(i, '_');
+ if (!s.IsEmpty())
+ {
+ wchar_t c = s.Back();
+ if (c == '.' || c == ' ')
+ {
+ // s += (wchar_t)(0x9c); // STRING TERMINATOR
+ s += (wchar_t)'_';
+ }
+ }
+ }
+ else
+ */
+ {
+ unsigned i;
+ for (i = s.Len(); i != 0;)
+ {
+ wchar_t c = s[i - 1];
+ if (c != '.' && c != ' ')
+ break;
+ i--;
+ s.ReplaceOneCharAtPos(i, '_');
+ // s.ReplaceOneCharAtPos(i, (c == ' ' ? (wchar_t)(0x2423) : (wchar_t)0x00B7));
+ }
+ /*
+ if (g_PathTrailReplaceMode > 1 && i != s.Len())
+ {
+ s.DeleteFrom(i);
+ }
+ */
}
}
- #endif
}
#ifdef _WIN32
@@ -61,7 +95,7 @@ void Correct_AltStream_Name(UString &s)
s.ReplaceOneCharAtPos(i, '_');
}
if (s.IsEmpty())
- s = L'_';
+ s = '_';
}
static const unsigned g_ReservedWithNum_Index = 4;
@@ -120,8 +154,8 @@ static void Correct_PathPart(UString &s)
#endif
}
-// static const wchar_t *k_EmptyReplaceName = L"[]";
-static const wchar_t k_EmptyReplaceName = L'_';
+// static const char * const k_EmptyReplaceName = "[]";
+static const char k_EmptyReplaceName = '_';
UString Get_Correct_FsFile_Name(const UString &name)
{
@@ -176,11 +210,11 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir)
if (isDrive)
{
// we convert "c:name" to "c:\name", if absIsAllowed path.
- const UString &ds = parts[i - 1];
- if (ds.Len() != 2)
+ UString &ds = parts[i - 1];
+ if (ds.Len() > 2)
{
- UString s = ds.Ptr(2);
- parts.Insert(i, s);
+ parts.Insert(i, ds.Ptr(2));
+ ds.DeleteFrom(2);
}
}
#endif
@@ -214,7 +248,7 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir)
if (!isDir)
{
if (parts.IsEmpty())
- parts.Add(k_EmptyReplaceName);
+ parts.Add((UString)k_EmptyReplaceName);
else
{
UString &s = parts.Back();
diff --git a/CPP/7zip/UI/Common/HashCalc.cpp b/CPP/7zip/UI/Common/HashCalc.cpp
index 60a747d5..46a69de1 100644
--- a/CPP/7zip/UI/Common/HashCalc.cpp
+++ b/CPP/7zip/UI/Common/HashCalc.cpp
@@ -30,17 +30,13 @@ public:
~CHashMidBuf() { ::MidFree(_data); }
};
-static const char *k_DefaultHashMethod = "CRC32";
+static const char * const k_DefaultHashMethod = "CRC32";
HRESULT CHashBundle::SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &hashMethods)
{
UStringVector names = hashMethods;
if (names.IsEmpty())
- {
- UString s;
- s.SetFromAscii(k_DefaultHashMethod);
- names.Add(s);
- }
+ names.Add(UString(k_DefaultHashMethod));
CRecordVector<CMethodId> ids;
CObjectVector<COneMethodInfo> methods;
diff --git a/CPP/7zip/UI/Common/LoadCodecs.cpp b/CPP/7zip/UI/Common/LoadCodecs.cpp
index 5435499b..f1334613 100644
--- a/CPP/7zip/UI/Common/LoadCodecs.cpp
+++ b/CPP/7zip/UI/Common/LoadCodecs.cpp
@@ -81,7 +81,7 @@ using namespace NFile;
#define kFormatsFolderName FTEXT("Formats")
-static CFSTR kMainDll =
+static CFSTR const kMainDll =
// #ifdef _WIN32
FTEXT("7z.dll");
// #else
@@ -91,9 +91,9 @@ static CFSTR kMainDll =
#ifdef _WIN32
-static LPCTSTR kRegistryPath = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-zip");
-static LPCWSTR kProgramPathValue = L"Path";
-static LPCWSTR kProgramPath2Value = L"Path"
+static LPCTSTR const kRegistryPath = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-zip");
+static LPCWSTR const kProgramPathValue = L"Path";
+static LPCWSTR const kProgramPath2Value = L"Path"
#ifdef _WIN64
L"64";
#else
@@ -516,12 +516,11 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded
}
lib.CreateObject = (Func_CreateObject)lib.Lib.GetProc("CreateObject");
- if (lib.CreateObject)
{
unsigned startSize = Codecs.Size() + Hashers.Size();
res = LoadCodecs();
used = (startSize != Codecs.Size() + Hashers.Size());
- if (res == S_OK)
+ if (res == S_OK && lib.CreateObject)
{
startSize = Formats.Size();
res = LoadFormats();
@@ -539,7 +538,8 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded
HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPrefix)
{
- NFile::NFind::CEnumerator enumerator(folderPrefix + FCHAR_ANY_MASK);
+ NFile::NFind::CEnumerator enumerator;
+ enumerator.SetDirPrefix(folderPrefix);
NFile::NFind::CFileInfo fi;
while (enumerator.Next(fi))
{
@@ -595,7 +595,7 @@ HRESULT CCodecs::Load()
const CArcInfo &arc = *g_Arcs[i];
CArcInfoEx item;
- item.Name.SetFromAscii(arc.Name);
+ item.Name = arc.Name;
item.CreateInArchive = arc.CreateInArchive;
item.IsArcFunc = arc.IsArc;
item.Flags = arc.Flags;
@@ -603,9 +603,9 @@ HRESULT CCodecs::Load()
{
UString e, ae;
if (arc.Ext)
- e.SetFromAscii(arc.Ext);
+ e = arc.Ext;
if (arc.AddExt)
- ae.SetFromAscii(arc.AddExt);
+ ae = arc.AddExt;
item.AddExts(e, ae);
}
@@ -866,7 +866,8 @@ STDMETHODIMP CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder)
const CCodecLib &lib = Libs[ci.LibIndex];
if (lib.CreateDecoder)
return lib.CreateDecoder(ci.CodecIndex, iid, (void **)coder);
- return lib.CreateObject(&ci.Decoder, iid, (void **)coder);
+ if (lib.CreateObject)
+ return lib.CreateObject(&ci.Decoder, iid, (void **)coder);
}
return S_OK;
#else
@@ -888,7 +889,8 @@ STDMETHODIMP CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder)
const CCodecLib &lib = Libs[ci.LibIndex];
if (lib.CreateEncoder)
return lib.CreateEncoder(ci.CodecIndex, iid, (void **)coder);
- return lib.CreateObject(&ci.Encoder, iid, (void **)coder);
+ if (lib.CreateObject)
+ return lib.CreateObject(&ci.Encoder, iid, (void **)coder);
}
return S_OK;
#else
diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp
index bf3b982e..69817179 100644
--- a/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -330,17 +330,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath:
{
- wchar_t sz[32];
+ char sz[32];
ConvertUInt32ToString(index + 1, sz);
- UString s = sz;
+ UString s(sz);
if (!item.Name.IsEmpty())
{
- s += L'.';
+ s += '.';
s += item.Name;
}
if (!item.Extension.IsEmpty())
{
- s += L'.';
+ s += '.';
s += item.Extension;
}
prop = s; break;
@@ -583,7 +583,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
{
{
UString &s2 = parts[parts.Size() - 2];
- s2 += L':';
+ s2 += ':';
s2 += parts.Back();
}
parts.DeleteBack();
@@ -733,7 +733,7 @@ HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const
RINOK(Archive->GetProperty(index, kpidExtension, &prop));
if (prop.vt == VT_BSTR)
{
- result += L'.';
+ result += '.';
result += prop.bstrVal;
}
else if (prop.vt != VT_EMPTY)
@@ -1020,10 +1020,11 @@ static void MakeCheckOrder(CCodecs *codecs,
#ifdef UNDER_CE
static const unsigned kNumHashBytes = 1;
- #define HASH_VAL(buf, pos) ((buf)[pos])
+ #define HASH_VAL(buf) ((buf)[0])
#else
static const unsigned kNumHashBytes = 2;
- #define HASH_VAL(buf, pos) ((buf)[pos] | ((UInt32)(buf)[pos + 1] << 8))
+ // #define HASH_VAL(buf) ((buf)[0] | ((UInt32)(buf)[1] << 8))
+ #define HASH_VAL(buf) GetUi16(buf)
#endif
@@ -2317,7 +2318,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
continue;
}
thereAreHandlersForSearch = true;
- UInt32 v = HASH_VAL(sig, 0);
+ UInt32 v = HASH_VAL(sig);
unsigned sigIndex = arc2sig[(unsigned)index] + k;
prevs[sigIndex] = hash[v];
hash[v] = (Byte)sigIndex;
@@ -2440,6 +2441,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
}
+ if (bytesInBuf <= (size_t)posInBuf)
+ break;
+
bool useOffsetCallback = false;
if (openCallback_Offset)
{
@@ -2489,17 +2493,19 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
scanSize++;
const Byte *buf = byteBuffer + (size_t)posInBuf;
+ const Byte *bufLimit = buf + scanSize;
size_t ppp = 0;
if (!needCheckStartOpen)
{
- for (; ppp < scanSize && hash[HASH_VAL(buf, ppp)] == 0xFF; ppp++);
+ for (; buf < bufLimit && hash[HASH_VAL(buf)] == 0xFF; buf++);
+ ppp = buf - (byteBuffer + (size_t)posInBuf);
pos += ppp;
- if (ppp == scanSize)
+ if (buf == bufLimit)
continue;
}
- UInt32 v = HASH_VAL(buf, ppp);
+ UInt32 v = HASH_VAL(buf);
bool nextNeedCheckStartOpen = true;
unsigned i = hash[v];
unsigned indexOfDifficult = 0;
@@ -2539,7 +2545,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
const CByteBuffer &sig = ai.Signatures[sigIndex];
if (ppp + sig.Size() > availSize
- || !TestSignature(buf + ppp, sig, sig.Size()))
+ || !TestSignature(buf, sig, sig.Size()))
continue;
// printf("\nSignature OK: %10S %8x %5d", (const wchar_t *)ai.Name, (int)pos, (int)(pos - prevPos));
// prevPos = pos;
@@ -2946,10 +2952,10 @@ HRESULT CArc::OpenStream(const COpenOptions &op)
#ifdef _SFX
#ifdef _WIN32
- static const char *k_ExeExt = ".exe";
+ #define k_ExeExt ".exe"
static const unsigned k_ExeExt_Len = 4;
#else
- static const char *k_ExeExt = "";
+ #define k_ExeExt ""
static const unsigned k_ExeExt_Len = 0;
#endif
@@ -3012,10 +3018,10 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
if (ai.IsSplit())
continue;
UString path3 = path2;
- path3 += L'.';
+ path3 += '.';
path3 += ai.GetMainExt(); // "7z" for SFX.
Path = path3;
- Path.AddAscii(".001");
+ Path += ".001";
bool isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path));
if (!isOk)
{
diff --git a/CPP/7zip/UI/Common/PropIDUtils.cpp b/CPP/7zip/UI/Common/PropIDUtils.cpp
index dccc08b1..4d0e98db 100644
--- a/CPP/7zip/UI/Common/PropIDUtils.cpp
+++ b/CPP/7zip/UI/Common/PropIDUtils.cpp
@@ -83,18 +83,17 @@ void ConvertWinAttribToString(char *s, UInt32 wa) throw()
}
}
-void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID propID, bool full) throw()
+void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &prop, PROPID propID, int level) throw()
{
*dest = 0;
if (prop.vt == VT_FILETIME)
{
- FILETIME localFileTime;
- if ((prop.filetime.dwHighDateTime == 0 &&
- prop.filetime.dwLowDateTime == 0) ||
- !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
+ const FILETIME &ft = prop.filetime;
+ if ((ft.dwHighDateTime == 0 &&
+ ft.dwLowDateTime == 0))
return;
- ConvertFileTimeToString(localFileTime, dest, true, full);
+ ConvertUtcFileTimeToString(prop.filetime, dest, level);
return;
}
@@ -158,7 +157,7 @@ void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID pr
ConvertPropVariantToShortString(prop, dest);
}
-void ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID propID, bool full)
+void ConvertPropertyToString2(UString &dest, const PROPVARIANT &prop, PROPID propID, int level)
{
if (prop.vt == VT_BSTR)
{
@@ -166,8 +165,8 @@ void ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID prop
return;
}
char temp[64];
- ConvertPropertyToShortString(temp, prop, propID, full);
- dest.SetFromAscii(temp);
+ ConvertPropertyToShortString2(temp, prop, propID, level);
+ dest = temp;
}
static inline unsigned GetHex(unsigned v)
@@ -349,13 +348,9 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
}
}
- char sz[16];
s += "S-1-";
if (p[2] == 0 && p[3] == 0)
- {
- ConvertUInt32ToString(authority, sz);
- s += sz;
- }
+ s.Add_UInt32(authority);
else
{
s += "0x";
@@ -365,8 +360,7 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
for (UInt32 i = 0; i < num; i++)
{
s += '-';
- ConvertUInt32ToString(Get32(p + 8 + i * 4), sz);
- s += sz;
+ s.Add_UInt32(Get32(p + 8 + i * 4));
}
}
@@ -536,11 +530,11 @@ bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
if (attr.Parse(data, size))
{
if (!attr.IsSymLink())
- s.AddAscii("Junction: ");
+ s += "Junction: ";
s += attr.GetPath();
if (!attr.IsOkNamePair())
{
- s.AddAscii(" : ");
+ s += " : ";
s += attr.PrintName;
}
return true;
@@ -557,7 +551,7 @@ bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
char hex[16];
ConvertUInt32ToHex8Digits(tag, hex);
- s.AddAscii(hex);
+ s += hex;
s.Add_Space();
data += 8;
@@ -565,8 +559,8 @@ bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
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);
+ s += (char)GetHex((b >> 4) & 0xF);
+ s += (char)GetHex(b & 0xF);
}
return true;
}
diff --git a/CPP/7zip/UI/Common/PropIDUtils.h b/CPP/7zip/UI/Common/PropIDUtils.h
index 1dea321e..915bfc28 100644
--- a/CPP/7zip/UI/Common/PropIDUtils.h
+++ b/CPP/7zip/UI/Common/PropIDUtils.h
@@ -6,8 +6,8 @@
#include "../../../Common/MyString.h"
// provide at least 64 bytes for buffer including zero-end
-void ConvertPropertyToShortString(char *dest, const PROPVARIANT &propVariant, PROPID propID, bool full = true) throw();
-void ConvertPropertyToString(UString &dest, const PROPVARIANT &propVariant, PROPID propID, bool full = true);
+void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &propVariant, PROPID propID, int level = 0) throw();
+void ConvertPropertyToString2(UString &dest, const PROPVARIANT &propVariant, PROPID propID, int level = 0);
bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s);
void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s);
diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp
index 0db4a87f..78f68f35 100644
--- a/CPP/7zip/UI/Common/Update.cpp
+++ b/CPP/7zip/UI/Common/Update.cpp
@@ -4,7 +4,6 @@
#include "Update.h"
-#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/DLL.h"
@@ -30,16 +29,19 @@
#include "TempFiles.h"
#include "UpdateCallback.h"
-static const char *kUpdateIsNotSupoorted =
+static const char * const kUpdateIsNotSupoorted =
"update operations are not supported for this archive";
+static const char * const kUpdateIsNotSupoorted_MultiVol =
+ "Updating for multivolume archives is not implemented";
+
using namespace NWindows;
using namespace NCOM;
using namespace NFile;
using namespace NDir;
using namespace NName;
-static CFSTR kTempFolderPrefix = FTEXT("7zE");
+static CFSTR const kTempFolderPrefix = FTEXT("7zE");
void CUpdateErrorInfo::SetFromLastError(const char *message)
@@ -60,7 +62,8 @@ static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path)
NFind::CFileInfo fileInfo;
FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
{
- NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK);
+ NFind::CEnumerator enumerator;
+ enumerator.SetDirPrefix(pathPrefix);
while (enumerator.Next(fileInfo))
{
if (fileInfo.IsDir())
@@ -156,7 +159,7 @@ bool COutMultiVolStream::SetMTime(const FILETIME *mTime)
STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
while (size > 0)
{
@@ -164,9 +167,8 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
{
CAltStreamInfo altStream;
- FChar temp[16];
- ConvertUInt32ToString(_streamIndex + 1, temp);
- FString name = temp;
+ FString name;
+ name.Add_UInt32(_streamIndex + 1);
while (name.Len() < 3)
name.InsertAtFront(FTEXT('0'));
name.Insert(0, Prefix);
@@ -218,7 +220,7 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
_length = _absPos;
if (_offsetPos > altStream.RealSize)
altStream.RealSize = _offsetPos;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize += realProcessed;
if (altStream.Pos == volSize)
{
@@ -243,7 +245,7 @@ STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *n
case STREAM_SEEK_END: _absPos = _length + offset; break;
}
_offsetPos = _absPos;
- if (newPosition != NULL)
+ if (newPosition)
*newPosition = _absPos;
_streamIndex = 0;
return S_OK;
@@ -316,7 +318,7 @@ UString CArchivePath::GetFinalPath() const
UString path = GetPathWithoutExt();
if (!BaseExtension.IsEmpty())
{
- path += L'.';
+ path += '.';
path += BaseExtension;
}
return path;
@@ -327,7 +329,7 @@ UString CArchivePath::GetFinalVolPath() const
UString path = GetPathWithoutExt();
if (!BaseExtension.IsEmpty())
{
- path += L'.';
+ path += '.';
path += VolExtension;
}
return path;
@@ -339,17 +341,17 @@ FString CArchivePath::GetTempPath() const
path += us2fs(Name);
if (!BaseExtension.IsEmpty())
{
- path += FTEXT('.');
+ path += '.';
path += us2fs(BaseExtension);
}
- path.AddAscii(".tmp");
+ path += ".tmp";
path += TempPostfix;
return path;
}
-static const wchar_t *kDefaultArcType = L"7z";
-static const wchar_t *kDefaultArcExt = L"7z";
-static const char *kSFXExtension =
+static const char * const kDefaultArcType = "7z";
+static const char * const kDefaultArcExt = "7z";
+static const char * const kSFXExtension =
#ifdef _WIN32
"exe";
#else
@@ -398,7 +400,7 @@ bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath)
}
UString ext = typeExt;
if (SfxMode)
- ext.SetFromAscii(kSFXExtension);
+ ext = kSFXExtension;
ArchivePath.BaseExtension = ext;
ArchivePath.VolExtension = typeExt;
ArchivePath.ParseFromPath(arcPath, ArcNameMode);
@@ -412,19 +414,43 @@ bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath)
return true;
}
+
struct CUpdateProduceCallbackImp: public IUpdateProduceCallback
{
const CObjectVector<CArcItem> *_arcItems;
IUpdateCallbackUI *_callback;
+ CDirItemsStat *_stat;
+
+ CUpdateProduceCallbackImp(
+ const CObjectVector<CArcItem> *a,
+ CDirItemsStat *stat,
+ IUpdateCallbackUI *callback):
+ _arcItems(a),
+ _stat(stat),
+ _callback(callback) {}
- CUpdateProduceCallbackImp(const CObjectVector<CArcItem> *a,
- IUpdateCallbackUI *callback): _arcItems(a), _callback(callback) {}
virtual HRESULT ShowDeleteFile(unsigned arcIndex);
};
+
HRESULT CUpdateProduceCallbackImp::ShowDeleteFile(unsigned arcIndex)
{
const CArcItem &ai = (*_arcItems)[arcIndex];
+ {
+ CDirItemsStat &stat = *_stat;
+ if (ai.IsDir)
+ stat.NumDirs++;
+ else if (ai.IsAltStream)
+ {
+ stat.NumAltStreams++;
+ stat.AltStreamsSize += ai.Size;
+ }
+ else
+ {
+ stat.NumFiles++;
+ stat.FilesSize += ai.Size;
+ }
+ }
return _callback->ShowDeleteFile(ai.Name, ai.IsDir);
}
@@ -562,6 +588,8 @@ static HRESULT Compress(
UStringVector newNames;
+ CArcToDoStat stat2;
+
if (options.RenamePairs.Size() != 0)
{
FOR_VECTOR (i, arcItems)
@@ -595,7 +623,7 @@ static HRESULT Compress(
if (rp.GetNewPath(false, mainName, dest))
{
needRename = true;
- dest += L':';
+ dest += ':';
dest += ai.Name.Ptr(colonPos + 1);
break;
}
@@ -620,17 +648,51 @@ static HRESULT Compress(
{
CRecordVector<CUpdatePair> updatePairs;
GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!!
- CUpdateProduceCallbackImp upCallback(&arcItems, callback);
+ CUpdateProduceCallbackImp upCallback(&arcItems, &stat2.DeleteData, callback);
UpdateProduce(updatePairs, actionSet, updatePairs2, isUpdatingItself ? &upCallback : NULL);
}
{
- UInt32 numItems = 0;
FOR_VECTOR (i, updatePairs2)
- if (updatePairs2[i].NewData)
- numItems++;
- RINOK(callback->SetNumItems(numItems));
+ {
+ const CUpdatePair2 &up = updatePairs2[i];
+ if (up.NewData)
+ {
+ CDirItemsStat &stat = stat2.NewData;
+ const CDirItem &di = dirItems.Items[up.DirIndex];
+ if (di.IsDir())
+ stat.NumDirs++;
+ else if (di.IsAltStream)
+ {
+ stat.NumAltStreams++;
+ stat.AltStreamsSize += di.Size;
+ }
+ else
+ {
+ stat.NumFiles++;
+ stat.FilesSize += di.Size;
+ }
+ }
+ else if (up.ArcIndex >= 0)
+ {
+ CDirItemsStat &stat = stat2.OldData;
+ const CArcItem &ai = arcItems[up.ArcIndex];
+ if (ai.IsDir)
+ stat.NumDirs++;
+ else if (ai.IsAltStream)
+ {
+ stat.NumAltStreams++;
+ stat.AltStreamsSize += ai.Size;
+ }
+ else
+ {
+ stat.NumFiles++;
+ stat.FilesSize += ai.Size;
+ }
+ }
+ }
+ RINOK(callback->SetNumItems(stat2));
}
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
@@ -698,9 +760,8 @@ static HRESULT Compress(
{
if (i > 0)
{
- FChar s[16];
- ConvertUInt32ToString(i, s);
- archivePath.TempPostfix = s;
+ archivePath.TempPostfix.Empty();
+ archivePath.TempPostfix.Add_UInt32(i);
}
realPath = archivePath.GetTempPath();
}
@@ -734,7 +795,7 @@ static HRESULT Compress(
outStream = outSeekStream;
volStreamSpec->Sizes = options.VolumesSizes;
volStreamSpec->Prefix = us2fs(archivePath.GetFinalVolPath());
- volStreamSpec->Prefix += FTEXT('.');
+ volStreamSpec->Prefix += '.';
volStreamSpec->TempFiles = &tempFiles;
volStreamSpec->Init();
@@ -742,7 +803,7 @@ static HRESULT Compress(
updateCallbackSpec->VolumesSizes = volumesSizes;
updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name;
if (!archivePath.VolExtension.IsEmpty())
- updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension;
+ updateCallbackSpec->VolExt = UString('.') + archivePath.VolExtension;
*/
}
@@ -1025,7 +1086,7 @@ HRESULT UpdateArchive(
if (options.SfxMode)
{
CProperty property;
- property.Name.SetFromAscii("rsfx");
+ property.Name = "rsfx";
options.MethodMode.Properties.Add(property);
if (options.SfxModule.IsEmpty())
{
@@ -1058,7 +1119,15 @@ HRESULT UpdateArchive(
!options.SetArcPath(codecs, cmdArcPath2))
return E_NOTIMPL;
}
- const UString arcPath = options.ArchivePath.GetFinalPath();
+
+ UString arcPath = options.ArchivePath.GetFinalPath();
+
+ if (!options.VolumesSizes.IsEmpty())
+ {
+ arcPath = options.ArchivePath.GetFinalVolPath();
+ arcPath += '.';
+ arcPath += "001";
+ }
if (cmdArcPath2.IsEmpty())
{
@@ -1085,7 +1154,12 @@ HRESULT UpdateArchive(
if (fi.IsDevice)
return E_NOTIMPL;
if (options.VolumesSizes.Size() > 0)
+ {
+ errorInfo.FileNames.Add(us2fs(arcPath));
+ errorInfo.SystemError = (DWORD)E_NOTIMPL;
+ errorInfo.Message = kUpdateIsNotSupoorted_MultiVol;
return E_NOTIMPL;
+ }
CObjectVector<COpenType> types2;
// change it.
if (options.MethodMode.Type_Defined)
@@ -1122,7 +1196,7 @@ HRESULT UpdateArchive(
if (arcLink.VolumePaths.Size() > 1)
{
errorInfo.SystemError = (DWORD)E_NOTIMPL;
- errorInfo.Message = "Updating for multivolume archives is not implemented";
+ errorInfo.Message = kUpdateIsNotSupoorted_MultiVol;
return E_NOTIMPL;
}
@@ -1147,7 +1221,7 @@ HRESULT UpdateArchive(
if (options.MethodMode.Type.FormatIndex < 0)
{
- options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArcType);
+ options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType((UString)kDefaultArcType);
if (options.MethodMode.Type.FormatIndex < 0)
return E_NOTIMPL;
}
@@ -1218,7 +1292,7 @@ HRESULT UpdateArchive(
{
NFind::CFileInfo fi;
FString prefix = us2fs(censor.Pairs[0].Prefix);
- prefix += FTEXT('.');
+ prefix += '.';
// UString prefix = censor.Pairs[0].Prefix;
/*
if (prefix.Back() == WCHAR_PATH_SEPARATOR)
@@ -1353,7 +1427,7 @@ HRESULT UpdateArchive(
if (options.StdOutMode)
{
- name.SetFromAscii("stdout");
+ name = "stdout";
isUpdating = thereIsInArchive;
}
else
@@ -1461,10 +1535,10 @@ HRESULT UpdateArchive(
for (i = 0; i < fullPaths.Size(); i++)
{
- UString arcPath2 = fs2us(fullPaths[i]);
- UString fileName = ExtractFileNameFromPath(arcPath2);
- AString path = GetAnsiString(arcPath2);
- AString name = GetAnsiString(fileName);
+ const UString arcPath2 = fs2us(fullPaths[i]);
+ const UString fileName = ExtractFileNameFromPath(arcPath2);
+ const AString path (GetAnsiString(arcPath2));
+ const AString name (GetAnsiString(fileName));
// Warning!!! MAPISendDocuments function changes Current directory
// fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
@@ -1479,7 +1553,7 @@ HRESULT UpdateArchive(
m.nFileCount = 1;
m.lpFiles = &f;
- const AString addr = GetAnsiString(options.EMailAddress);
+ const AString addr (GetAnsiString(options.EMailAddress));
MapiRecipDesc rec;
if (!addr.IsEmpty())
{
diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp
index 5499f2a1..ae3c4831 100644
--- a/CPP/7zip/UI/Common/UpdateCallback.cpp
+++ b/CPP/7zip/UI/Common/UpdateCallback.cpp
@@ -51,6 +51,8 @@ CArchiveUpdateCallback::CArchiveUpdateCallback():
ArcItems(NULL),
UpdatePairs(NULL),
NewNames(NULL),
+ CommentIndex(-1),
+ Comment(NULL),
ShareForWrite(false),
StdInMode(false),
@@ -300,7 +302,7 @@ static UString GetRelativePath(const UString &to, const UString &from)
unsigned k;
for (k = i + 1; k < partsFrom.Size(); k++)
- s += L".." WSTRING_PATH_SEPARATOR;
+ s += ".." STRING_PATH_SEPARATOR;
for (k = i; k < partsTo.Size(); k++)
{
@@ -396,6 +398,11 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
}
else if (propID == kpidPath && up.NewNameIndex >= 0)
prop = (*NewNames)[up.NewNameIndex];
+ else if (propID == kpidComment
+ && CommentIndex >= 0
+ && (unsigned)CommentIndex == index
+ && Comment)
+ prop = *Comment;
else if (propID == kpidShortName && up.NewNameIndex >= 0 && up.IsMainRenameItem)
{
// we can generate new ShortName here;
@@ -690,13 +697,13 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
{
COM_TRY_BEGIN
- FChar temp[16];
+ char temp[16];
ConvertUInt32ToString(index + 1, temp);
- FString res = temp;
+ FString res (temp);
while (res.Len() < 2)
res.InsertAtFront(FTEXT('0'));
FString fileName = VolName;
- fileName += FTEXT('.');
+ fileName += '.';
fileName += res;
fileName += VolExt;
COutFileStream *streamSpec = new COutFileStream;
diff --git a/CPP/7zip/UI/Common/UpdateCallback.h b/CPP/7zip/UI/Common/UpdateCallback.h
index 4ff4a7eb..87a114b1 100644
--- a/CPP/7zip/UI/Common/UpdateCallback.h
+++ b/CPP/7zip/UI/Common/UpdateCallback.h
@@ -15,6 +15,18 @@
#include "OpenArchive.h"
+struct CArcToDoStat
+{
+ CDirItemsStat NewData;
+ CDirItemsStat OldData;
+ CDirItemsStat DeleteData;
+
+ UInt64 Get_NumDataItems_Total() const
+ {
+ return NewData.Get_NumDataItems() + OldData.Get_NumDataItems();
+ }
+};
+
#define INTERFACE_IUpdateCallbackUI(x) \
virtual HRESULT WriteSfx(const wchar_t *name, UInt64 size) x; \
virtual HRESULT SetTotal(UInt64 size) x; \
@@ -22,7 +34,7 @@
virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) x; \
virtual HRESULT CheckBreak() x; \
/* virtual HRESULT Finalize() x; */ \
- virtual HRESULT SetNumItems(UInt64 numItems) x; \
+ virtual HRESULT SetNumItems(const CArcToDoStat &stat) x; \
virtual HRESULT GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode) x; \
virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x; \
virtual HRESULT ReadingFileError(const FString &path, DWORD systemError) x; \
@@ -120,6 +132,8 @@ public:
const CObjectVector<CArcItem> *ArcItems;
const CRecordVector<CUpdatePair2> *UpdatePairs;
const UStringVector *NewNames;
+ int CommentIndex;
+ const UString *Comment;
bool ShareForWrite;
bool StdInMode;
diff --git a/CPP/7zip/UI/Common/UpdatePair.cpp b/CPP/7zip/UI/Common/UpdatePair.cpp
index e2115197..82876c1d 100644
--- a/CPP/7zip/UI/Common/UpdatePair.cpp
+++ b/CPP/7zip/UI/Common/UpdatePair.cpp
@@ -38,14 +38,13 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time
throw 4191618;
}
-static const char *k_Duplicate_inArc_Message = "Duplicate filename in archive:";
-static const char *k_Duplicate_inDir_Message = "Duplicate filename on disk:";
-static const char *k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):";
+static const char * const k_Duplicate_inArc_Message = "Duplicate filename in archive:";
+static const char * const k_Duplicate_inDir_Message = "Duplicate filename on disk:";
+static const char * const k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):";
static void ThrowError(const char *message, const UString &s1, const UString &s2)
{
- UString m;
- m.SetFromAscii(message);
+ UString m (message);
m.Add_LF(); m += s1;
m.Add_LF(); m += s2;
throw m;
diff --git a/CPP/7zip/UI/Common/UpdateProduce.cpp b/CPP/7zip/UI/Common/UpdateProduce.cpp
index e6eabcf1..d5052f13 100644
--- a/CPP/7zip/UI/Common/UpdateProduce.cpp
+++ b/CPP/7zip/UI/Common/UpdateProduce.cpp
@@ -6,7 +6,7 @@
using namespace NUpdateArchive;
-static const char *kUpdateActionSetCollision = "Internal collision in update action set";
+static const char * const kUpdateActionSetCollision = "Internal collision in update action set";
void UpdateProduce(
const CRecordVector<CUpdatePair> &updatePairs,
diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp
index a0e692d0..558a159c 100644
--- a/CPP/7zip/UI/Common/ZipRegistry.cpp
+++ b/CPP/7zip/UI/Common/ZipRegistry.cpp
@@ -16,9 +16,9 @@ using namespace NRegistry;
static NSynchronization::CCriticalSection g_CS;
#define CS_LOCK NSynchronization::CCriticalSectionLock lock(g_CS);
-static const TCHAR *kCuPrefix = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR);
+static LPCTSTR const kCuPrefix = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR);
-static CSysString GetKeyPath(const CSysString &path) { return kCuPrefix + path; }
+static CSysString GetKeyPath(LPCTSTR path) { return kCuPrefix + (CSysString)path; }
static LONG OpenMainKey(CKey &key, LPCTSTR keyName)
{
@@ -51,16 +51,16 @@ static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b)
namespace NExtract
{
-static const TCHAR *kKeyName = TEXT("Extraction");
+static LPCTSTR const kKeyName = TEXT("Extraction");
-static const TCHAR *kExtractMode = TEXT("ExtractMode");
-static const TCHAR *kOverwriteMode = TEXT("OverwriteMode");
-static const TCHAR *kShowPassword = TEXT("ShowPassword");
-static const TCHAR *kPathHistory = TEXT("PathHistory");
-static const TCHAR *kSplitDest = TEXT("SplitDest");
-static const TCHAR *kElimDup = TEXT("ElimDup");
-// static const TCHAR *kAltStreams = TEXT("AltStreams");
-static const TCHAR *kNtSecur = TEXT("Security");
+static LPCTSTR const kExtractMode = TEXT("ExtractMode");
+static LPCTSTR const kOverwriteMode = TEXT("OverwriteMode");
+static LPCTSTR const kShowPassword = TEXT("ShowPassword");
+static LPCTSTR const kPathHistory = TEXT("PathHistory");
+static LPCTSTR const kSplitDest = TEXT("SplitDest");
+static LPCTSTR const kElimDup = TEXT("ElimDup");
+// static LPCTSTR const kAltStreams = TEXT("AltStreams");
+static LPCTSTR const kNtSecur = TEXT("Security");
void CInfo::Save() const
{
@@ -144,30 +144,30 @@ bool Read_ShowPassword()
namespace NCompression
{
-static const TCHAR *kKeyName = TEXT("Compression");
+static LPCTSTR const kKeyName = TEXT("Compression");
-static const TCHAR *kArcHistory = TEXT("ArcHistory");
-static const WCHAR *kArchiver = L"Archiver";
-static const TCHAR *kShowPassword = TEXT("ShowPassword");
-static const TCHAR *kEncryptHeaders = TEXT("EncryptHeaders");
+static LPCTSTR const kArcHistory = TEXT("ArcHistory");
+static LPCWSTR const kArchiver = L"Archiver";
+static LPCTSTR const kShowPassword = TEXT("ShowPassword");
+static LPCTSTR const kEncryptHeaders = TEXT("EncryptHeaders");
-static const TCHAR *kOptionsKeyName = TEXT("Options");
+static LPCTSTR const kOptionsKeyName = TEXT("Options");
-static const TCHAR *kLevel = TEXT("Level");
-static const TCHAR *kDictionary = TEXT("Dictionary");
-static const TCHAR *kOrder = TEXT("Order");
-static const TCHAR *kBlockSize = TEXT("BlockSize");
-static const TCHAR *kNumThreads = TEXT("NumThreads");
-static const WCHAR *kMethod = L"Method";
-static const WCHAR *kOptions = L"Options";
-static const WCHAR *kEncryptionMethod = L"EncryptionMethod";
+static LPCTSTR const kLevel = TEXT("Level");
+static LPCTSTR const kDictionary = TEXT("Dictionary");
+static LPCTSTR const kOrder = TEXT("Order");
+static LPCTSTR const kBlockSize = TEXT("BlockSize");
+static LPCTSTR const kNumThreads = TEXT("NumThreads");
+static LPCWSTR const kMethod = L"Method";
+static LPCWSTR const kOptions = L"Options";
+static LPCWSTR const kEncryptionMethod = L"EncryptionMethod";
-static const TCHAR *kNtSecur = TEXT("Security");
-static const TCHAR *kAltStreams = TEXT("AltStreams");
-static const TCHAR *kHardLinks = TEXT("HardLinks");
-static const TCHAR *kSymLinks = TEXT("SymLinks");
+static LPCTSTR const kNtSecur = TEXT("Security");
+static LPCTSTR const kAltStreams = TEXT("AltStreams");
+static LPCTSTR const kHardLinks = TEXT("HardLinks");
+static LPCTSTR const kSymLinks = TEXT("SymLinks");
-static void SetRegString(CKey &key, const WCHAR *name, const UString &value)
+static void SetRegString(CKey &key, LPCWSTR name, const UString &value)
{
if (value.IsEmpty())
key.DeleteValue(name);
@@ -175,7 +175,7 @@ static void SetRegString(CKey &key, const WCHAR *name, const UString &value)
key.SetValue(name, value);
}
-static void SetRegUInt32(CKey &key, const TCHAR *name, UInt32 value)
+static void SetRegUInt32(CKey &key, LPCTSTR name, UInt32 value)
{
if (value == (UInt32)(Int32)-1)
key.DeleteValue(name);
@@ -183,13 +183,13 @@ static void SetRegUInt32(CKey &key, const TCHAR *name, UInt32 value)
key.SetValue(name, value);
}
-static void GetRegString(CKey &key, const WCHAR *name, UString &value)
+static void GetRegString(CKey &key, LPCWSTR name, UString &value)
{
if (key.QueryValue(name, value) != ERROR_SUCCESS)
value.Empty();
}
-static void GetRegUInt32(CKey &key, const TCHAR *name, UInt32 &value)
+static void GetRegUInt32(CKey &key, LPCTSTR name, UInt32 &value)
{
if (key.QueryValue(name, value) != ERROR_SUCCESS)
value = (UInt32)(Int32)-1;
@@ -300,13 +300,13 @@ void CInfo::Load()
}
-static const TCHAR *kOptionsInfoKeyName = TEXT("Options");
+static LPCTSTR const kOptionsInfoKeyName = TEXT("Options");
namespace NWorkDir
{
-static const TCHAR *kWorkDirType = TEXT("WorkDirType");
-static const WCHAR *kWorkDirPath = L"WorkDirPath";
-static const TCHAR *kTempRemovableOnly = TEXT("TempRemovableOnly");
+static LPCTSTR const kWorkDirType = TEXT("WorkDirType");
+static LPCWSTR const kWorkDirPath = L"WorkDirPath";
+static LPCTSTR const kTempRemovableOnly = TEXT("TempRemovableOnly");
void CInfo::Save()const
@@ -352,10 +352,10 @@ void CInfo::Load()
}
-static const TCHAR *kCascadedMenu = TEXT("CascadedMenu");
-static const TCHAR *kContextMenu = TEXT("ContextMenu");
-static const TCHAR *kMenuIcons = TEXT("MenuIcons");
-static const TCHAR *kElimDup = TEXT("ElimDupExtract");
+static LPCTSTR const kCascadedMenu = TEXT("CascadedMenu");
+static LPCTSTR const kContextMenu = TEXT("ContextMenu");
+static LPCTSTR const kMenuIcons = TEXT("MenuIcons");
+static LPCTSTR const kElimDup = TEXT("ElimDupExtract");
void CContextMenuInfo::Save() const
{
diff --git a/CPP/7zip/UI/Console/Console.dsp b/CPP/7zip/UI/Console/Console.dsp
index 84ee4a6f..4145d726 100644
--- a/CPP/7zip/UI/Console/Console.dsp
+++ b/CPP/7zip/UI/Console/Console.dsp
@@ -44,7 +44,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAs /Yu"StdAfx.h" /FD /GF /c
+# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /GF /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
index 8dac7fbc..68a7a85f 100644
--- a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
@@ -32,7 +32,7 @@ static HRESULT CheckBreak2()
return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK;
}
-static const char *kError = "ERROR: ";
+static const char * const kError = "ERROR: ";
void CExtractScanConsole::StartScanning()
@@ -138,33 +138,33 @@ static NSynchronization::CCriticalSection g_CriticalSection;
#endif
-static const char *kTestString = "T";
-static const char *kExtractString = "-";
-static const char *kSkipString = ".";
+static const char * const kTestString = "T";
+static const char * const kExtractString = "-";
+static const char * const kSkipString = ".";
-// static const char *kCantAutoRename = "can not create file with auto name\n";
-// static const char *kCantRenameFile = "can not rename existing file\n";
-// static const char *kCantDeleteOutputFile = "can not delete output file ";
+// static const char * const kCantAutoRename = "can not create file with auto name\n";
+// static const char * const kCantRenameFile = "can not rename existing file\n";
+// static const char * const kCantDeleteOutputFile = "can not delete output file ";
-static const char *kMemoryExceptionMessage = "Can't allocate required memory!";
+static const char * const kMemoryExceptionMessage = "Can't allocate required memory!";
-static const char *kExtracting = "Extracting archive: ";
-static const char *kTesting = "Testing archive: ";
+static const char * const kExtracting = "Extracting archive: ";
+static const char * const kTesting = "Testing archive: ";
-static const char *kEverythingIsOk = "Everything is Ok";
-static const char *kNoFiles = "No files to process";
+static const char * const kEverythingIsOk = "Everything is Ok";
+static const char * const kNoFiles = "No files to process";
-static const char *kUnsupportedMethod = "Unsupported Method";
-static const char *kCrcFailed = "CRC Failed";
-static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?";
-static const char *kDataError = "Data Error";
-static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?";
-static const char *kUnavailableData = "Unavailable data";
-static const char *kUnexpectedEnd = "Unexpected end of data";
-static const char *kDataAfterEnd = "There are some data after the end of the payload data";
-static const char *kIsNotArc = "Is not archive";
-static const char *kHeadersError = "Headers Error";
-static const char *kWrongPassword = "Wrong password";
+static const char * const kUnsupportedMethod = "Unsupported Method";
+static const char * const kCrcFailed = "CRC Failed";
+static const char * const kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?";
+static const char * const kDataError = "Data Error";
+static const char * const kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?";
+static const char * const kUnavailableData = "Unavailable data";
+static const char * const kUnexpectedEnd = "Unexpected end of data";
+static const char * const kDataAfterEnd = "There are some data after the end of the payload data";
+static const char * const kIsNotArc = "Is not archive";
+static const char * const kHeadersError = "Headers Error";
+static const char * const kWrongPassword = "Wrong password";
static const char * const k_ErrorFlagsMessages[] =
{
@@ -206,7 +206,7 @@ STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue)
return CheckBreak2();
}
-static const char *kTab = " ";
+static const char * const kTab = " ";
static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size)
{
@@ -220,10 +220,8 @@ static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIM
if (ft)
{
char temp[64];
- FILETIME locTime;
- if (FileTimeToLocalFileTime(ft, &locTime))
- if (ConvertFileTimeToString(locTime, temp, true, true))
- *_so << kTab << "Modified: " << temp << endl;
+ if (ConvertUtcFileTimeToString(*ft, temp, kTimestampPrintLevel_SEC))
+ *_so << kTab << "Modified: " << temp << endl;
}
}
@@ -256,6 +254,8 @@ STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
case NUserAnswerMode::kYesAll: *answer = NOverwriteAnswer::kYesToAll; break;
case NUserAnswerMode::kYes: *answer = NOverwriteAnswer::kYes; break;
case NUserAnswerMode::kAutoRenameAll: *answer = NOverwriteAnswer::kAutoRename; break;
+ case NUserAnswerMode::kEof: return E_ABORT;
+ case NUserAnswerMode::kError: return E_FAIL;
default: return E_FAIL;
}
@@ -388,10 +388,8 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest)
dest += s;
else
{
- char temp[16];
- ConvertUInt32ToString(opRes, temp);
dest += "Error #";
- dest += temp;
+ dest.Add_UInt32(opRes);
}
}
@@ -524,22 +522,22 @@ void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags)
void Add_Messsage_Pre_ArcType(UString &s, const char *pre, const wchar_t *arcType)
{
s.Add_LF();
- s.AddAscii(pre);
- s.AddAscii(" as [");
+ s += pre;
+ s += " as [";
s += arcType;
- s.AddAscii("] archive");
+ s += "] archive";
}
void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc)
{
const CArcErrorInfo &er = arc.ErrorInfo;
- UString s = L"WARNING:\n";
+ UString s ("WARNING:\n");
s += arc.Path;
if (arc.FormatIndex == er.ErrorFormatIndex)
{
s.Add_LF();
- s.AddAscii("The archive is open with offset");
+ s += "The archive is open with offset";
}
else
{
diff --git a/CPP/7zip/UI/Console/HashCon.cpp b/CPP/7zip/UI/Console/HashCon.cpp
index 6a82daf2..8ff90753 100644
--- a/CPP/7zip/UI/Console/HashCon.cpp
+++ b/CPP/7zip/UI/Console/HashCon.cpp
@@ -7,9 +7,9 @@
#include "ConsoleClose.h"
#include "HashCon.h"
-static const wchar_t *kEmptyFileAlias = L"[Content]";
+static const char * const kEmptyFileAlias = "[Content]";
-static const char *kScanningMessage = "Scanning";
+static const char * const kScanningMessage = "Scanning";
static HRESULT CheckBreak2()
{
@@ -168,7 +168,7 @@ HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb)
if (PrintSize)
{
_s.Add_Space();
- const AString s2 = "Size";
+ const AString s2 ("Size");
AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len());
_s += s2;
}
diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp
index 62e813b2..57d1d1bc 100644
--- a/CPP/7zip/UI/Console/List.cpp
+++ b/CPP/7zip/UI/Console/List.cpp
@@ -128,14 +128,14 @@ static const char * const kPropIdToName[] =
static const char kEmptyAttribChar = '.';
-static const char *kListing = "Listing archive: ";
+static const char * const kListing = "Listing archive: ";
-static const char *kString_Files = "files";
-static const char *kString_Dirs = "folders";
-static const char *kString_AltStreams = "alternate streams";
-static const char *kString_Streams = "streams";
+static const char * const kString_Files = "files";
+static const char * const kString_Dirs = "folders";
+static const char * const kString_AltStreams = "alternate streams";
+static const char * const kString_Streams = "streams";
-static const char *kError = "ERROR: ";
+static const char * const kError = "ERROR: ";
static void GetAttribString(UInt32 wa, bool isDir, bool allAttribs, char *s)
{
@@ -417,9 +417,8 @@ static void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UStr
nameU = name;
else
{
- char s[16];
- ConvertUInt32ToString(propID, s);
- nameA = s;
+ nameA.Empty();
+ nameA.Add_UInt32(propID);
}
}
@@ -429,7 +428,7 @@ void CFieldPrinter::AddProp(const wchar_t *name, PROPID propID, bool isRawProp)
f.PropID = propID;
f.IsRawProp = isRawProp;
GetPropName(propID, name, f.NameA, f.NameU);
- f.NameU.AddAscii(" = ");
+ f.NameU += " = ";
if (!f.NameA.IsEmpty())
f.NameA += " = ";
else
@@ -499,10 +498,7 @@ static void PrintTime(char *dest, const FILETIME *ft)
*dest = 0;
if (ft->dwLowDateTime == 0 && ft->dwHighDateTime == 0)
return;
- FILETIME locTime;
- if (!FileTimeToLocalFileTime(ft, &locTime))
- throw 20121211;
- ConvertFileTimeToString(locTime, dest, true, true);
+ ConvertUtcFileTimeToString(*ft, dest, kTimestampPrintLevel_SEC);
}
#ifndef _SFX
@@ -686,7 +682,7 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st)
else
{
char s[64];
- ConvertPropertyToShortString(s, prop, f.PropID);
+ ConvertPropertyToShortString2(s, prop, f.PropID);
if (techMode)
g_StdOut << s;
else
@@ -828,7 +824,7 @@ static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *va
static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *name, const CPropVariant &prop)
{
UString s;
- ConvertPropertyToString(s, prop, propID);
+ ConvertPropertyToString2(s, prop, propID);
if (!s.IsEmpty())
{
AString nameA;
diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp
index 50652555..8a077d47 100644
--- a/CPP/7zip/UI/Console/Main.cpp
+++ b/CPP/7zip/UI/Console/Main.cpp
@@ -64,6 +64,8 @@ using namespace NCommandLineParser;
HINSTANCE g_hInstance = 0;
#endif
+bool g_LargePagesMode = false;
+
extern CStdOutStream *g_StdStream;
extern CStdOutStream *g_ErrStream;
@@ -73,24 +75,19 @@ extern const CCodecInfo *g_Codecs[];
extern unsigned g_NumHashers;
extern const CHasherInfo *g_Hashers[];
-static const char *kCopyrightString = "\n7-Zip"
-#ifndef EXTERNAL_CODECS
-#ifdef PROG_VARIANT_R
-" (r)"
-#else
-" (a)"
-#endif
-#endif
-
-#ifdef MY_CPU_64BIT
-" [64]"
-#elif defined MY_CPU_32BIT
-" [32]"
-#endif
+static const char * const kCopyrightString = "\n7-Zip"
+ #ifndef EXTERNAL_CODECS
+ #ifdef PROG_VARIANT_R
+ " (r)"
+ #else
+ " (a)"
+ #endif
+ #endif
-" " MY_VERSION_COPYRIGHT_DATE "\n\n";
+ " " MY_VERSION_CPU
+ " : " MY_COPYRIGHT_DATE "\n\n";
-static const char *kHelpString =
+static const char * const kHelpString =
"Usage: 7z"
#ifndef EXTERNAL_CODECS
#ifdef PROG_VARIANT_R
@@ -128,6 +125,7 @@ static const char *kHelpString =
" -i[r[-|0]]{@listfile|!wildcard} : Include filenames\n"
" -m{Parameters} : set compression Method\n"
" -mmt[N] : set number of CPU threads\n"
+ " -mx[N] : set compression level: -mx1 (fastest) ... -mx9 (ultra)\n"
" -o{Directory} : set Output directory\n"
#ifndef _NO_CRYPTO
" -p{Password} : set Password\n"
@@ -166,13 +164,13 @@ static const char *kHelpString =
// ---------------------------
// exception messages
-static const char *kEverythingIsOk = "Everything is Ok";
-static const char *kUserErrorMessage = "Incorrect command line";
-static const char *kNoFormats = "7-Zip cannot find the code that works with archives.";
-static const char *kUnsupportedArcTypeMessage = "Unsupported archive type";
-// static const char *kUnsupportedUpdateArcType = "Can't create archive for that type";
+static const char * const kEverythingIsOk = "Everything is Ok";
+static const char * const kUserErrorMessage = "Incorrect command line";
+static const char * const kNoFormats = "7-Zip cannot find the code that works with archives.";
+static const char * const kUnsupportedArcTypeMessage = "Unsupported archive type";
+// static const char * const kUnsupportedUpdateArcType = "Can't create archive for that type";
-static CFSTR kDefaultSfxModule = FTEXT("7zCon.sfx");
+#define kDefaultSfxModule "7zCon.sfx"
static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code)
{
@@ -204,9 +202,9 @@ static void ShowCopyrightAndHelp(CStdOutStream *so, bool needHelp)
}
-static void PrintStringRight(CStdOutStream &so, const AString &s, unsigned size)
+static void PrintStringRight(CStdOutStream &so, const char *s, unsigned size)
{
- unsigned len = s.Len();
+ unsigned len = MyStringLen(s);
for (unsigned i = len; i < size; i++)
so << ' ';
so << s;
@@ -279,7 +277,7 @@ static int WarningsCheck(HRESULT result, const CCallbackConsoleBase &callback,
UString message;
if (!errorInfo.Message.IsEmpty())
{
- message.AddAscii(errorInfo.Message);
+ message += errorInfo.Message.Ptr();
message.Add_LF();
}
{
@@ -389,6 +387,7 @@ static void PrintMemUsage(const char *s, UInt64 val)
EXTERN_C_BEGIN
typedef BOOL (WINAPI *Func_GetProcessMemoryInfo)(HANDLE Process,
PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb);
+typedef BOOL (WINAPI *Func_QueryProcessCycleTime)(HANDLE Process, PULONG64 CycleTime);
EXTERN_C_END
#endif
@@ -415,6 +414,8 @@ static void PrintStat()
PROCESS_MEMORY_COUNTERS m;
memset(&m, 0, sizeof(m));
BOOL memDefined = FALSE;
+ BOOL cycleDefined = FALSE;
+ ULONG64 cycleTime = 0;
{
/* NT 4.0: GetProcessMemoryInfo() in Psapi.dll
Win7: new function K32GetProcessMemoryInfo() in kernel32.dll
@@ -425,8 +426,9 @@ static void PrintStat()
// memDefined = GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m));
*/
+ HMODULE kern = ::GetModuleHandleW(L"kernel32.dll");
Func_GetProcessMemoryInfo my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)
- ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "K32GetProcessMemoryInfo");
+ ::GetProcAddress(kern, "K32GetProcessMemoryInfo");
if (!my_GetProcessMemoryInfo)
{
HMODULE lib = LoadLibraryW(L"Psapi.dll");
@@ -436,6 +438,11 @@ static void PrintStat()
if (my_GetProcessMemoryInfo)
memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m));
// FreeLibrary(lib);
+
+ Func_QueryProcessCycleTime my_QueryProcessCycleTime = (Func_QueryProcessCycleTime)
+ ::GetProcAddress(kern, "QueryProcessCycleTime");
+ if (my_QueryProcessCycleTime)
+ cycleDefined = my_QueryProcessCycleTime(GetCurrentProcess(), &cycleTime);
}
#endif
@@ -448,6 +455,16 @@ static void PrintStat()
UInt64 totalTime = curTime - creationTime;
PrintTime("Kernel ", kernelTime, totalTime);
+
+ #ifndef UNDER_CE
+ if (cycleDefined)
+ {
+ *g_StdStream << " ";
+ PrintNum(cycleTime / 1000000, 22);
+ *g_StdStream << " MCycles";
+ }
+ #endif
+
PrintTime("User ", userTime, totalTime);
PrintTime("Process", kernelTime + userTime, totalTime);
@@ -470,6 +487,7 @@ static void PrintHexId(CStdOutStream &so, UInt64 id)
PrintStringRight(so, s, 8);
}
+
int Main2(
#ifndef _WIN32
int numArgs, char *args[]
@@ -488,14 +506,17 @@ int Main2(
GetArguments(numArgs, args, commandStrings);
#endif
- if (commandStrings.Size() == 1)
+ #ifndef UNDER_CE
+ if (commandStrings.Size() > 0)
+ commandStrings.Delete(0);
+ #endif
+
+ if (commandStrings.Size() == 0)
{
ShowCopyrightAndHelp(g_StdStream, true);
return 0;
}
- commandStrings.Delete(0);
-
CArcCmdLineOptions options;
CArcCmdLineParser parser;
@@ -527,8 +548,11 @@ int Main2(
if (options.LargePages)
{
SetLargePageSize();
+ g_LargePagesMode =
#if defined(_WIN32) && !defined(UNDER_CE)
- NSecurity::EnablePrivilege_LockMemory();
+ NSecurity::EnablePrivilege_LockMemory();
+ #else
+ true;
#endif
}
#endif
@@ -579,7 +603,7 @@ int Main2(
#ifdef EXTERNAL_CODECS
if (!codecs->MainDll_ErrorPath.IsEmpty())
{
- UString s = L"Can't load module ";
+ UString s ("Can't load module: ");
s += fs2us(codecs->MainDll_ErrorPath);
throw s;
}
@@ -639,7 +663,7 @@ int Main2(
so << endl << "Formats:" << endl;
- const char *kArcFlags = "KSNFMGOPBELH";
+ const char * const kArcFlags = "KSNFMGOPBELH";
const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags);
for (i = 0; i < codecs->Formats.Size(); i++)
@@ -673,9 +697,9 @@ int Main2(
s += ext.Ext;
if (!ext.AddExt.IsEmpty())
{
- s += L" (";
+ s += " (";
s += ext.AddExt;
- s += L')';
+ s += ')';
}
}
diff --git a/CPP/7zip/UI/Console/MainAr.cpp b/CPP/7zip/UI/Console/MainAr.cpp
index d30a96e4..68e5fe97 100644
--- a/CPP/7zip/UI/Console/MainAr.cpp
+++ b/CPP/7zip/UI/Console/MainAr.cpp
@@ -24,12 +24,12 @@ extern int Main2(
#endif
);
-static const char *kException_CmdLine_Error_Message = "Command Line Error:";
-static const char *kExceptionErrorMessage = "ERROR:";
-static const char *kUserBreakMessage = "Break signaled";
-static const char *kMemoryExceptionMessage = "ERROR: Can't allocate required memory!";
-static const char *kUnknownExceptionMessage = "Unknown Error";
-static const char *kInternalExceptionMessage = "\n\nInternal Error #";
+static const char * const kException_CmdLine_Error_Message = "Command Line Error:";
+static const char * const kExceptionErrorMessage = "ERROR:";
+static const char * const kUserBreakMessage = "Break signaled";
+static const char * const kMemoryExceptionMessage = "ERROR: Can't allocate required memory!";
+static const char * const kUnknownExceptionMessage = "Unknown Error";
+static const char * const kInternalExceptionMessage = "\n\nInternal Error #";
static void FlushStreams()
{
diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
index 9d25a729..a074fa1f 100644
--- a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
@@ -32,13 +32,17 @@ HRESULT COpenCallbackConsole::Open_SetTotal(const UInt64 *files, const UInt64 *b
if (bytes)
{
- _totalBytesDefined = true;
- // _totalBytes = *bytes;
+ // _totalBytesDefined = true;
+ _totalBytes = *bytes;
if (!files)
_percent.Total = *bytes;
}
else
- _totalBytesDefined = false;
+ {
+ // _totalBytesDefined = false;
+ if (!files)
+ _percent.Total = _totalBytes;
+ }
}
return CheckBreak2();
@@ -83,7 +87,7 @@ HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password)
if (!PasswordIsDefined)
{
ClosePercents();
- Password = GetPassword(_so);
+ RINOK(GetPassword_HRESULT(_so, Password));
PasswordIsDefined = true;
}
return StringToBstr(Password, password);
diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.h b/CPP/7zip/UI/Console/OpenCallbackConsole.h
index 0dd4e1d1..64c1dad3 100644
--- a/CPP/7zip/UI/Console/OpenCallbackConsole.h
+++ b/CPP/7zip/UI/Console/OpenCallbackConsole.h
@@ -18,9 +18,9 @@ protected:
CStdOutStream *_se;
bool _totalFilesDefined;
- bool _totalBytesDefined;
+ // bool _totalBytesDefined;
// UInt64 _totalFiles;
- // UInt64 _totalBytes;
+ UInt64 _totalBytes;
bool NeedPercents() const { return _percent._so != NULL; }
@@ -36,7 +36,8 @@ public:
COpenCallbackConsole():
_totalFilesDefined(false),
- _totalBytesDefined(false),
+ // _totalBytesDefined(false),
+ _totalBytes(0),
MultiArcMode(false)
#ifndef _NO_CRYPTO
diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
index f4f2d102..efac98e3 100644
--- a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
@@ -23,15 +23,15 @@ static NSynchronization::CCriticalSection g_CriticalSection;
#define MT_LOCK
#endif
-static const wchar_t *kEmptyFileAlias = L"[Content]";
+static const wchar_t * const kEmptyFileAlias = L"[Content]";
-static const char *kOpenArchiveMessage = "Open archive: ";
-static const char *kCreatingArchiveMessage = "Creating archive: ";
-static const char *kUpdatingArchiveMessage = "Updating archive: ";
-static const char *kScanningMessage = "Scanning the drive:";
+static const char * const kOpenArchiveMessage = "Open archive: ";
+static const char * const kCreatingArchiveMessage = "Creating archive: ";
+static const char * const kUpdatingArchiveMessage = "Updating archive: ";
+static const char * const kScanningMessage = "Scanning the drive:";
-static const char *kError = "ERROR: ";
-static const char *kWarning = "WARNING: ";
+static const char * const kError = "ERROR: ";
+static const char * const kWarning = "WARNING: ";
static HRESULT CheckBreak2()
{
@@ -259,7 +259,7 @@ HRESULT CUpdateCallbackConsole::FinishScanning(const CDirItemsStat &st)
return S_OK;
}
-static const char *k_StdOut_ArcName = "StdOut";
+static const char * const k_StdOut_ArcName = "StdOut";
HRESULT CUpdateCallbackConsole::StartOpenArchive(const wchar_t *name)
{
@@ -316,7 +316,7 @@ HRESULT CUpdateCallbackConsole::WriteSfx(const wchar_t *name, UInt64 size)
{
*_so << "Write SFX: ";
*_so << name;
- AString s = " : ";
+ AString s (" : ");
PrintSize_bytes_Smart(s, size);
*_so << s << endl;
}
@@ -398,14 +398,31 @@ HRESULT CUpdateCallbackConsole::Finalize()
}
*/
-HRESULT CUpdateCallbackConsole::SetNumItems(UInt64 numItems)
+
+void static PrintToDoStat(CStdOutStream *_so, const CDirItemsStat &stat, const char *name)
+{
+ AString s;
+ Print_DirItemsStat(s, stat);
+ *_so << name << ": " << s << endl;
+}
+
+HRESULT CUpdateCallbackConsole::SetNumItems(const CArcToDoStat &stat)
{
if (_so)
{
ClosePercents_for_so();
- AString s;
- PrintPropPair(s, "Items to compress", numItems);
- *_so << s << endl << endl;
+ if (!stat.DeleteData.IsEmpty())
+ {
+ *_so << endl;
+ PrintToDoStat(_so, stat.DeleteData, "Delete data from archive");
+ }
+ if (!stat.OldData.IsEmpty())
+ PrintToDoStat(_so, stat.OldData, "Keep old data in archive");
+ // if (!stat.NewData.IsEmpty())
+ {
+ PrintToDoStat(_so, stat.NewData, "Add new data to archive");
+ }
+ *_so << endl;
}
return S_OK;
}
@@ -622,7 +639,7 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined,
{
if (AskPassword)
{
- Password = GetPassword(_so);
+ RINOK(GetPassword_HRESULT(_so, Password));
PasswordIsDefined = true;
}
}
@@ -649,7 +666,7 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password)
if (!PasswordIsDefined)
{
{
- Password = GetPassword(_so);
+ RINOK(GetPassword_HRESULT(_so, Password))
PasswordIsDefined = true;
}
}
diff --git a/CPP/7zip/UI/Console/UserInputUtils.cpp b/CPP/7zip/UI/Console/UserInputUtils.cpp
index c7f830ff..0e2d7ac1 100644
--- a/CPP/7zip/UI/Console/UserInputUtils.cpp
+++ b/CPP/7zip/UI/Console/UserInputUtils.cpp
@@ -14,8 +14,8 @@ static const char kNoAll = 's';
static const char kAutoRenameAll = 'u';
static const char kQuit = 'q';
-static const char *kFirstQuestionMessage = "? ";
-static const char *kHelpQuestionMessage =
+static const char * const kFirstQuestionMessage = "? ";
+static const char * const kHelpQuestionMessage =
"(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? ";
// return true if pressed Quite;
@@ -31,9 +31,16 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
*outStream << kHelpQuestionMessage;
outStream->Flush();
}
- AString scannedString = g_StdIn.ScanStringUntilNewLine();
+ AString scannedString;
+ if (!g_StdIn.ScanAStringUntilNewLine(scannedString))
+ return NUserAnswerMode::kError;
+ if (g_StdIn.Error())
+ return NUserAnswerMode::kError;
scannedString.Trim();
- if (!scannedString.IsEmpty())
+ if (scannedString.IsEmpty() && g_StdIn.Eof())
+ return NUserAnswerMode::kEof;
+
+ if (scannedString.Len() == 1)
switch (::MyCharLower_Ascii(scannedString[0]))
{
case kYes: return NUserAnswerMode::kYes;
@@ -52,7 +59,7 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
#endif
#endif
-UString GetPassword(CStdOutStream *outStream)
+static bool GetPassword(CStdOutStream *outStream, UString &psw)
{
if (outStream)
{
@@ -72,19 +79,32 @@ UString GetPassword(CStdOutStream *outStream)
if (console != INVALID_HANDLE_VALUE && console != 0)
if (GetConsoleMode(console, &mode))
wasChanged = (SetConsoleMode(console, mode & ~ENABLE_ECHO_INPUT) != 0);
- UString res = g_StdIn.ScanUStringUntilNewLine();
+ bool res = g_StdIn.ScanUStringUntilNewLine(psw);
if (wasChanged)
SetConsoleMode(console, mode);
+
+ #else
+
+ bool res = g_StdIn.ScanUStringUntilNewLine(psw);
+
+ #endif
+
if (outStream)
{
*outStream << endl;
outStream->Flush();
}
+
return res;
-
- #else
-
- return g_StdIn.ScanUStringUntilNewLine();
-
- #endif
+}
+
+HRESULT GetPassword_HRESULT(CStdOutStream *outStream, UString &psw)
+{
+ if (!GetPassword(outStream, psw))
+ return E_INVALIDARG;
+ if (g_StdIn.Error())
+ return E_FAIL;
+ if (g_StdIn.Eof() && psw.IsEmpty())
+ return E_ABORT;
+ return S_OK;
}
diff --git a/CPP/7zip/UI/Console/UserInputUtils.h b/CPP/7zip/UI/Console/UserInputUtils.h
index 16f04580..256feafe 100644
--- a/CPP/7zip/UI/Console/UserInputUtils.h
+++ b/CPP/7zip/UI/Console/UserInputUtils.h
@@ -14,11 +14,14 @@ enum EEnum
kYesAll,
kNoAll,
kAutoRenameAll,
- kQuit
+ kQuit,
+ kEof,
+ kError
};
}
NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream);
-UString GetPassword(CStdOutStream *outStream);
+// bool GetPassword(CStdOutStream *outStream, UString &psw);
+HRESULT GetPassword_HRESULT(CStdOutStream *outStream, UString &psw);
#endif
diff --git a/CPP/7zip/UI/Console/resource.rc b/CPP/7zip/UI/Console/resource.rc
index 6e09bb96..2f7ef073 100644
--- a/CPP/7zip/UI/Console/resource.rc
+++ b/CPP/7zip/UI/Console/resource.rc
@@ -1,3 +1,3 @@
#include "../../MyVersionInfo.rc"
-MY_VERSION_INFO_APP("7-Zip Console", "7z")
+MY_VERSION_INFO_APP("7-Zip Console" , "7z")
diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp
index 62ad0aa9..21de12a5 100644
--- a/CPP/7zip/UI/Explorer/ContextMenu.cpp
+++ b/CPP/7zip/UI/Explorer/ContextMenu.cpp
@@ -129,27 +129,16 @@ HRESULT CZipContextMenu::InitContextMenu(const wchar_t * /* folder */, const wch
/////////////////////////////
// IContextMenu
-static LPCWSTR kMainVerb = L"SevenZip";
-static LPCWSTR kOpenCascadedVerb = L"SevenZip.OpenWithType.";
-static LPCWSTR kCheckSumCascadedVerb = L"SevenZip.Checksum";
+static LPCSTR const kMainVerb = "SevenZip";
+static LPCSTR const kOpenCascadedVerb = "SevenZip.OpenWithType.";
+static LPCSTR const kCheckSumCascadedVerb = "SevenZip.Checksum";
-/*
-static LPCTSTR kOpenVerb = TEXT("SevenOpen");
-static LPCTSTR kExtractVerb = TEXT("SevenExtract");
-static LPCTSTR kExtractHereVerb = TEXT("SevenExtractHere");
-static LPCTSTR kExtractToVerb = TEXT("SevenExtractTo");
-static LPCTSTR kTestVerb = TEXT("SevenTest");
-static LPCTSTR kCompressVerb = TEXT("SevenCompress");
-static LPCTSTR kCompressToVerb = TEXT("SevenCompressTo");
-static LPCTSTR kCompressEmailVerb = TEXT("SevenCompressEmail");
-static LPCTSTR kCompressToEmailVerb = TEXT("SevenCompressToEmail");
-*/
struct CContextMenuCommand
{
UInt32 flag;
CZipContextMenu::ECommandInternalID CommandInternalID;
- LPCWSTR Verb;
+ LPCSTR Verb;
UINT ResourceID;
};
@@ -158,67 +147,67 @@ static const CContextMenuCommand g_Commands[] =
{
NContextMenuFlags::kOpen,
CZipContextMenu::kOpen,
- L"Open",
+ "Open",
IDS_CONTEXT_OPEN
},
{
NContextMenuFlags::kExtract,
CZipContextMenu::kExtract,
- L"Extract",
+ "Extract",
IDS_CONTEXT_EXTRACT
},
{
NContextMenuFlags::kExtractHere,
CZipContextMenu::kExtractHere,
- L"ExtractHere",
+ "ExtractHere",
IDS_CONTEXT_EXTRACT_HERE
},
{
NContextMenuFlags::kExtractTo,
CZipContextMenu::kExtractTo,
- L"ExtractTo",
+ "ExtractTo",
IDS_CONTEXT_EXTRACT_TO
},
{
NContextMenuFlags::kTest,
CZipContextMenu::kTest,
- L"Test",
+ "Test",
IDS_CONTEXT_TEST
},
{
NContextMenuFlags::kCompress,
CZipContextMenu::kCompress,
- L"Compress",
+ "Compress",
IDS_CONTEXT_COMPRESS
},
{
NContextMenuFlags::kCompressEmail,
CZipContextMenu::kCompressEmail,
- L"CompressEmail",
+ "CompressEmail",
IDS_CONTEXT_COMPRESS_EMAIL
},
{
NContextMenuFlags::kCompressTo7z,
CZipContextMenu::kCompressTo7z,
- L"CompressTo7z",
+ "CompressTo7z",
IDS_CONTEXT_COMPRESS_TO
},
{
NContextMenuFlags::kCompressTo7zEmail,
CZipContextMenu::kCompressTo7zEmail,
- L"CompressTo7zEmail",
+ "CompressTo7zEmail",
IDS_CONTEXT_COMPRESS_TO_EMAIL
},
{
NContextMenuFlags::kCompressToZip,
CZipContextMenu::kCompressToZip,
- L"CompressToZip",
+ "CompressToZip",
IDS_CONTEXT_COMPRESS_TO
},
{
NContextMenuFlags::kCompressToZipEmail,
CZipContextMenu::kCompressToZipEmail,
- L"CompressToZipEmail",
+ "CompressToZipEmail",
IDS_CONTEXT_COMPRESS_TO_EMAIL
}
};
@@ -226,17 +215,17 @@ static const CContextMenuCommand g_Commands[] =
struct CHashCommand
{
CZipContextMenu::ECommandInternalID CommandInternalID;
- LPCWSTR UserName;
- LPCWSTR MethodName;
+ LPCSTR UserName;
+ LPCSTR MethodName;
};
static const CHashCommand g_HashCommands[] =
{
- { CZipContextMenu::kHash_CRC32, L"CRC-32", L"CRC32" },
- { CZipContextMenu::kHash_CRC64, L"CRC-64", L"CRC64" },
- { CZipContextMenu::kHash_SHA1, L"SHA-1", L"SHA1" },
- { CZipContextMenu::kHash_SHA256, L"SHA-256", L"SHA256" },
- { CZipContextMenu::kHash_All, L"*", L"*" }
+ { CZipContextMenu::kHash_CRC32, "CRC-32", "CRC32" },
+ { CZipContextMenu::kHash_CRC64, "CRC-64", "CRC64" },
+ { CZipContextMenu::kHash_SHA1, "SHA-1", "SHA1" },
+ { CZipContextMenu::kHash_SHA256, "SHA-256", "SHA256" },
+ { CZipContextMenu::kHash_All, "*", "*" }
};
static int FindCommand(CZipContextMenu::ECommandInternalID &id)
@@ -255,7 +244,8 @@ bool CZipContextMenu::FillCommand(ECommandInternalID id, UString &mainString, CC
return false;
const CContextMenuCommand &command = g_Commands[i];
commandMapItem.CommandInternalID = command.CommandInternalID;
- commandMapItem.Verb = (UString)kMainVerb + (UString)command.Verb;
+ commandMapItem.Verb = kMainVerb;
+ commandMapItem.Verb += command.Verb;
// LangString(command.ResourceHelpID, command.LangID + 1, commandMapItem.HelpString);
LangString(command.ResourceID, mainString);
return true;
@@ -341,7 +331,7 @@ static void MyFormatNew_ReducedName(UString &s, const UString &name)
s = MyFormatNew(s, GetQuotedReducedString(name));
}
-static const char *kExtractExludeExtensions =
+static const char * const kExtractExludeExtensions =
" 3gp"
" aac ans ape asc asm asp aspx avi awk"
" bas bat bmp"
@@ -353,7 +343,7 @@ static const char *kExtractExludeExtensions =
" h hpp hta htm html hxx"
" ico idl inc ini inl"
" java jpeg jpg js"
- " la log"
+ " la lnk log"
" mak manifest wmv mov mp3 mp4 mpe mpeg mpg m4a"
" ofr ogg"
" pac pas pdf php php3 php4 php5 phptml pl pm png ps py pyo"
@@ -366,7 +356,7 @@ static const char *kExtractExludeExtensions =
" ";
/*
-static const char *kNoOpenAsExtensions =
+static const char * const kNoOpenAsExtensions =
" 7z arj bz2 cab chm cpio flv gz lha lzh lzma rar swm tar tbz2 tgz wim xar xz z zip ";
*/
@@ -419,7 +409,7 @@ static bool DoNeedExtract(const FString &name)
}
// we must use diferent Verbs for Popup subMenu.
-void CZipContextMenu::AddMapItem_ForSubMenu(const wchar_t *verb)
+void CZipContextMenu::AddMapItem_ForSubMenu(const char *verb)
{
CCommandMapItem commandMapItem;
commandMapItem.CommandInternalID = kCommandNULL;
@@ -498,9 +488,9 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
fi0.Name = us2fs(fileName.Ptr(NName::kDevicePathPrefixSize)); // change it 4 - must be constant
folderPrefix =
#ifdef UNDER_CE
- FTEXT("\\");
+ "\\";
#else
- FTEXT("C:\\");
+ "C:\\";
#endif
}
else
@@ -555,9 +545,11 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
FillCommand(kOpen, mainString, commandMapItem);
else
{
- mainString.SetFromAscii(kOpenTypes[i]);
+ mainString = kOpenTypes[i];
commandMapItem.CommandInternalID = kOpen;
- commandMapItem.Verb = (UString)kMainVerb + L".Open." + mainString;
+ commandMapItem.Verb = kMainVerb;
+ commandMapItem.Verb += ".Open.";
+ commandMapItem.Verb += mainString;
commandMapItem.HelpString = mainString;
commandMapItem.ArcType = mainString;
}
@@ -599,7 +591,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (_dropMode)
baseFolder = _dropPath;
- UString specFolder = L'*';
+ UString specFolder ('*');
if (_fileNames.Size() == 1)
specFolder = GetSubFolderNameForExtract(fs2us(fi0.Name));
specFolder.Add_PathSepar();
@@ -653,8 +645,10 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
else
arcName = CreateArchiveName(fileName, _fileNames.Size() > 1, false);
- UString arcName7z = arcName + L".7z";
- UString arcNameZip = arcName + L".zip";
+ UString arcName7z = arcName;
+ arcName7z += ".7z";
+ UString arcNameZip = arcName;
+ arcNameZip += ".zip";
// Compress
if ((contextMenuFlags & NContextMenuFlags::kCompress) != 0)
@@ -694,7 +688,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
else
commandMapItem.Folder = fs2us(folderPrefix);
commandMapItem.ArcName = arcName7z;
- commandMapItem.ArcType.SetFromAscii("7z");
+ commandMapItem.ArcType = "7z";
MyFormatNew_ReducedName(s, arcName7z);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
_commandMap.Add(commandMapItem);
@@ -708,7 +702,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UString s;
FillCommand(kCompressTo7zEmail, s, commandMapItem);
commandMapItem.ArcName = arcName7z;
- commandMapItem.ArcType.SetFromAscii("7z");
+ commandMapItem.ArcType = "7z";
MyFormatNew_ReducedName(s, arcName7z);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
_commandMap.Add(commandMapItem);
@@ -727,7 +721,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
else
commandMapItem.Folder = fs2us(folderPrefix);
commandMapItem.ArcName = arcNameZip;
- commandMapItem.ArcType.SetFromAscii("zip");
+ commandMapItem.ArcType = "zip";
MyFormatNew_ReducedName(s, arcNameZip);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
_commandMap.Add(commandMapItem);
@@ -741,7 +735,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UString s;
FillCommand(kCompressToZipEmail, s, commandMapItem);
commandMapItem.ArcName = arcNameZip;
- commandMapItem.ArcType.SetFromAscii("zip");
+ commandMapItem.ArcType = "zip";
MyFormatNew_ReducedName(s, arcNameZip);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
_commandMap.Add(commandMapItem);
@@ -763,7 +757,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
mi.fMask |= MIIM_CHECKMARKS;
mi.wID = currentCommandID++;
mi.hSubMenu = popupMenu.Detach();
- mi.StringValue.SetFromAscii("7-Zip"); // LangString(IDS_CONTEXT_POPUP_CAPTION);
+ mi.StringValue = "7-Zip"; // LangString(IDS_CONTEXT_POPUP_CAPTION);
mi.hbmpUnchecked = bitmap;
CMenu menu;
@@ -799,7 +793,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
mi.fMask |= MIIM_CHECKMARKS;
mi.wID = currentCommandID++;
mi.hSubMenu = subMenu;
- mi.StringValue.SetFromAscii("CRC SHA");
+ mi.StringValue = "CRC SHA";
mi.hbmpUnchecked = bitmap;
CMenu menu;
@@ -814,9 +808,10 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
const CHashCommand &hc = g_HashCommands[i];
CCommandMapItem commandMapItem;
commandMapItem.CommandInternalID = hc.CommandInternalID;
- commandMapItem.Verb = (UString)kCheckSumCascadedVerb + (UString)hc.MethodName;
+ commandMapItem.Verb = kCheckSumCascadedVerb;
+ commandMapItem.Verb += hc.MethodName;
// commandMapItem.HelpString = hc.Name;
- MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, hc.UserName, bitmap);
+ MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, (UString)hc.UserName, bitmap);
_commandMap.Add(commandMapItem);
}
@@ -881,7 +876,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
params = GetQuotedString(_fileNames[0]);
if (!commandMapItem.ArcType.IsEmpty())
{
- params += L" -t";
+ params += " -t";
params += commandMapItem.ArcType;
}
MyCreateProcess(Get7zFmPath(), params);
@@ -935,7 +930,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
const CHashCommand &hc = g_HashCommands[i];
if (hc.CommandInternalID == cmdID)
{
- CalcChecksum(_fileNames, hc.MethodName);
+ CalcChecksum(_fileNames, (UString)hc.MethodName);
break;
}
}
diff --git a/CPP/7zip/UI/Explorer/ContextMenu.h b/CPP/7zip/UI/Explorer/ContextMenu.h
index 53bf18de..3a0eacc8 100644
--- a/CPP/7zip/UI/Explorer/ContextMenu.h
+++ b/CPP/7zip/UI/Explorer/ContextMenu.h
@@ -79,7 +79,7 @@ private:
HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames);
int FindVerb(const UString &verb);
bool FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &commandMapItem);
- void AddMapItem_ForSubMenu(const wchar_t *ver);
+ void AddMapItem_ForSubMenu(const char *ver);
};
#endif
diff --git a/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp b/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
index d02af9ef..c38d7257 100644
--- a/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
+++ b/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
@@ -25,11 +25,11 @@
#include "ContextMenu.h"
-static LPCTSTR k_ShellExtName = TEXT("7-Zip Shell Extension");
-static LPCTSTR k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
+static LPCTSTR const k_ShellExtName = TEXT("7-Zip Shell Extension");
+static LPCTSTR const k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
// {23170F69-40C1-278A-1000-000100020000}
-static LPCTSTR k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}");
+static LPCTSTR const k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}");
DEFINE_GUID(CLSID_CZipContextMenu,
k_7zip_GUID_Data1,
@@ -155,9 +155,8 @@ static BOOL RegisterServer()
return FALSE;
const UString modulePathU = fs2us(modulePath);
- CSysString clsidString = k_Clsid;
- CSysString s = TEXT("CLSID\\");
- s += clsidString;
+ CSysString s ("CLSID\\");
+ s += k_Clsid;
{
NRegistry::CKey key;
@@ -177,7 +176,7 @@ static BOOL RegisterServer()
{
NRegistry::CKey key;
if (key.Create(HKEY_LOCAL_MACHINE, k_Approved, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR)
- key.SetValue(clsidString, k_ShellExtName);
+ key.SetValue(k_Clsid, k_ShellExtName);
}
return TRUE;
@@ -190,13 +189,10 @@ STDAPI DllRegisterServer(void)
static BOOL UnregisterServer()
{
- const CSysString clsidString = k_Clsid;
- CSysString s = TEXT("CLSID\\");
- s += clsidString;
- CSysString s2 = s;
- s2.AddAscii("\\InprocServer32");
+ CSysString s ("CLSID\\");
+ s += k_Clsid;
- RegDeleteKey(HKEY_CLASSES_ROOT, s2);
+ RegDeleteKey(HKEY_CLASSES_ROOT, s + TEXT("\\InprocServer32"));
RegDeleteKey(HKEY_CLASSES_ROOT, s);
#if !defined(_WIN64) && !defined(UNDER_CE)
@@ -206,7 +202,7 @@ static BOOL UnregisterServer()
HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, k_Approved, 0, KEY_SET_VALUE, &hKey) == NOERROR)
{
- RegDeleteValue(hKey, clsidString);
+ RegDeleteValue(hKey, k_Clsid);
RegCloseKey(hKey);
}
}
diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp
index d83aa76e..c9d7910f 100644
--- a/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp
+++ b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp
@@ -17,21 +17,23 @@ using namespace NRegistry;
// CLISID (and Approved ?) items are separated for 32-bit and 64-bit code.
// shellex items shared by 32-bit and 64-bit code?
-static LPCTSTR k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}");
-static LPCTSTR k_ShellExtName = TEXT("7-Zip Shell Extension");
+#define k_Clsid_A "{23170F69-40C1-278A-1000-000100020000}"
-static LPCTSTR k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
-static LPCTSTR k_Inproc = TEXT("InprocServer32");
+static LPCTSTR const k_Clsid = TEXT(k_Clsid_A);
+static LPCTSTR const k_ShellExtName = TEXT("7-Zip Shell Extension");
-static LPCTSTR k_KeyPostfix_ContextMenu = TEXT("\\shellex\\ContextMenuHandlers\\7-Zip");
-static LPCTSTR k_KeyPostfix_DragDrop = TEXT("\\shellex\\DragDropHandlers\\7-Zip");
+static LPCTSTR const k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
+static LPCTSTR const k_Inproc = TEXT("InprocServer32");
-static LPCTSTR k_KeyName_File = TEXT("*");
-static LPCTSTR k_KeyName_Folder = TEXT("Folder");
-static LPCTSTR k_KeyName_Directory = TEXT("Directory");
-static LPCTSTR k_KeyName_Drive = TEXT("Drive");
+static LPCSTR const k_KeyPostfix_ContextMenu = "\\shellex\\ContextMenuHandlers\\7-Zip";
+static LPCSTR const k_KeyPostfix_DragDrop = "\\shellex\\DragDropHandlers\\7-Zip";
-static LPCTSTR const k_shellex_Prefixes[] =
+static LPCSTR const k_KeyName_File = "*";
+static LPCSTR const k_KeyName_Folder = "Folder";
+static LPCSTR const k_KeyName_Directory = "Directory";
+static LPCSTR const k_KeyName_Drive = "Drive";
+
+static LPCSTR const k_shellex_Prefixes[] =
{
k_KeyName_File,
k_KeyName_Folder,
@@ -95,32 +97,32 @@ static LONG MyRegistry_DeleteKey_HKCR(LPCTSTR name, UInt32 wow)
// static NSynchronization::CCriticalSection g_CS;
-static CSysString Get_ContextMenuHandler_KeyName(const CSysString &keyName)
- { return (keyName + k_KeyPostfix_ContextMenu); }
+static AString Get_ContextMenuHandler_KeyName(LPCSTR keyName)
+ { return (AString)keyName + k_KeyPostfix_ContextMenu; }
/*
-static CSysString Get_DragDropHandler_KeyName(const CSysString &keyName)
- { return (keyName + k_KeyPostfix_DragDrop); }
+static CSysString Get_DragDropHandler_KeyName(LPCTSTR keyName)
+ { return (AString)keyName + k_KeyPostfix_DragDrop); }
*/
-static bool CheckHandlerCommon(const CSysString &keyName, UInt32 wow)
+static bool CheckHandlerCommon(const AString &keyName, UInt32 wow)
{
CKey key;
- if (key.Open(HKEY_CLASSES_ROOT, keyName, KEY_READ | wow) != ERROR_SUCCESS)
+ if (key.Open(HKEY_CLASSES_ROOT, (CSysString)keyName, KEY_READ | wow) != ERROR_SUCCESS)
return false;
CSysString value;
if (key.QueryValue(NULL, value) != ERROR_SUCCESS)
return false;
- return StringsAreEqualNoCase_Ascii(value, k_Clsid);
+ return StringsAreEqualNoCase_Ascii(value, k_Clsid_A);
}
bool CheckContextMenuHandler(const UString &path, UInt32 wow)
{
// NSynchronization::CCriticalSectionLock lock(g_CS);
- CSysString s = TEXT("CLSID\\");
- s += k_Clsid;
- s.AddAscii("\\InprocServer32");
+ CSysString s ("CLSID\\");
+ s += k_Clsid_A;
+ s += "\\InprocServer32";
{
NRegistry::CKey key;
@@ -160,8 +162,8 @@ LONG SetContextMenuHandler(bool setMode, const UString &path, UInt32 wow)
LONG res;
{
- CSysString s = TEXT("CLSID\\");
- s += k_Clsid;
+ CSysString s ("CLSID\\");
+ s += k_Clsid_A;
if (setMode)
{
@@ -189,8 +191,8 @@ LONG SetContextMenuHandler(bool setMode, const UString &path, UInt32 wow)
}
else
{
- CSysString s2 = s;
- s2.AddAscii("\\InprocServer32");
+ CSysString s2 (s);
+ s2 += "\\InprocServer32";
MyRegistry_DeleteKey_HKCR(s2, wow);
res = MyRegistry_DeleteKey_HKCR(s, wow);
@@ -203,7 +205,7 @@ LONG SetContextMenuHandler(bool setMode, const UString &path, UInt32 wow)
{
for (unsigned k = 0; k < ARRAY_SIZE(k_shellex_Prefixes); k++)
{
- CSysString s = k_shellex_Prefixes[k];
+ CSysString s (k_shellex_Prefixes[k]);
s += (i == 0 ? k_KeyPostfix_ContextMenu : k_KeyPostfix_DragDrop);
if (k_shellex_Statuses[i][k])
{
diff --git a/CPP/7zip/UI/Far/ExtractEngine.cpp b/CPP/7zip/UI/Far/ExtractEngine.cpp
index c21655fd..04bad724 100644
--- a/CPP/7zip/UI/Far/ExtractEngine.cpp
+++ b/CPP/7zip/UI/Far/ExtractEngine.cpp
@@ -6,7 +6,6 @@
#include "../../../Windows/Synchronization.h"
#endif
-#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "ExtractEngine.h"
@@ -128,9 +127,9 @@ STDMETHODIMP CExtractCallbackImp::AskOverwrite(
return CheckBreak2();
}
-static const char *kTestString = "Testing";
-static const char *kExtractString = "Extracting";
-static const char *kSkipString = "Skipping";
+static const char * const kTestString = "Testing";
+static const char * const kExtractString = "Extracting";
+static const char * const kSkipString = "Skipping";
STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 /* isFolder */, Int32 askExtractMode, const UInt64 * /* position */)
{
@@ -161,7 +160,7 @@ STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *message)
{
MT_LOCK
- AString s = UnicodeStringToMultiByte(message, CP_OEMCP);
+ AString s (UnicodeStringToMultiByte(message, CP_OEMCP));
if (g_StartupInfo.ShowErrorMessage((const char *)s) == -1)
return E_ABORT;
@@ -198,7 +197,7 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s)
if (messageID != 0)
{
s = g_StartupInfo.GetMsgString(messageID);
- s.Replace(" '%s'", "");
+ s.Replace((AString)" '%s'", AString());
}
else if (opRes == NArchive::NExtract::NOperationResult::kUnavailable)
s = "Unavailable data";
@@ -212,10 +211,8 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s)
s = "kHeaders Error";
else
{
- char temp[16];
- ConvertUInt32ToString(opRes, temp);
s = "Error #";
- s += temp;
+ s.Add_UInt32(opRes);
}
}
}
diff --git a/CPP/7zip/UI/Far/Far.cpp b/CPP/7zip/UI/Far/Far.cpp
index 7c0876dd..cec4af52 100644
--- a/CPP/7zip/UI/Far/Far.cpp
+++ b/CPP/7zip/UI/Far/Far.cpp
@@ -25,10 +25,10 @@ using namespace NFar;
static const DWORD kShowProgressTime_ms = 100;
-static const char *kCommandPrefix = "7-zip";
-static const TCHAR *kRegisrtryMainKeyName = TEXT("");
-static const TCHAR *kRegisrtryValueNameEnabled = TEXT("UsedByDefault3");
-static const char *kHelpTopicConfig = "Config";
+static const char * const kCommandPrefix = "7-zip";
+static const char * const kRegisrtryMainKeyName = NULL; // ""
+static LPCTSTR const kRegisrtryValueNameEnabled = TEXT("UsedByDefault3");
+static const char * const kHelpTopicConfig = "Config";
static bool kPluginEnabledDefault = true;
HINSTANCE g_hInstance;
@@ -67,7 +67,7 @@ static struct COptions
bool Enabled;
} g_Options;
-static const TCHAR *kPliginNameForRegestry = TEXT("7-ZIP");
+static const char * const kPliginNameForRegistry = "7-ZIP";
EXTERN_C void WINAPI ExitFAR()
{
@@ -84,7 +84,7 @@ EXTERN_C void WINAPI ExitFAR()
EXTERN_C void WINAPI SetStartupInfo(const PluginStartupInfo *info)
{
MY_TRY_BEGIN;
- g_StartupInfo.Init(*info, kPliginNameForRegestry);
+ g_StartupInfo.Init(*info, kPliginNameForRegistry);
g_Options.Enabled = g_StartupInfo.QueryRegKeyValue(
HKEY_CURRENT_USER, kRegisrtryMainKeyName,
kRegisrtryValueNameEnabled, kPluginEnabledDefault);
@@ -299,8 +299,7 @@ HRESULT GetPassword(UString &password)
if (g_StartupInfo.ShowDialog(76, 6, NULL, dialogItems, kNumItems) < 0)
return E_ABORT;
- AString oemPassword = dialogItems[2].Data;
- password = MultiByteToUnicodeString(oemPassword, CP_OEMCP);
+ password = MultiByteToUnicodeString(dialogItems[2].Data, CP_OEMCP);
return S_OK;
}
@@ -449,7 +448,7 @@ EXTERN_C HANDLE WINAPI OpenPlugin(int openFrom, INT_PTR item)
if (openFrom == OPEN_COMMANDLINE)
{
- AString fileName = (const char *)item;
+ AString fileName ((const char *)item);
if (fileName.IsEmpty())
return INVALID_HANDLE_VALUE;
if (fileName.Len() >= 2
@@ -522,9 +521,9 @@ EXTERN_C int WINAPI GetFindData(HANDLE plugin, struct PluginPanelItem **panelIte
EXTERN_C void WINAPI FreeFindData(HANDLE plugin, struct PluginPanelItem *panelItems, int itemsNumber)
{
- MY_TRY_BEGIN;
+ // MY_TRY_BEGIN;
((CPlugin *)plugin)->FreeFindData(panelItems, itemsNumber);
- MY_TRY_END1("FreeFindData");
+ // MY_TRY_END1("FreeFindData");
}
EXTERN_C int WINAPI GetFiles(HANDLE plugin, struct PluginPanelItem *panelItems,
diff --git a/CPP/7zip/UI/Far/FarUtils.cpp b/CPP/7zip/UI/Far/FarUtils.cpp
index cc058ef9..ddca3cab 100644
--- a/CPP/7zip/UI/Far/FarUtils.cpp
+++ b/CPP/7zip/UI/Far/FarUtils.cpp
@@ -2,7 +2,7 @@
#include "StdAfx.h"
-#include "../../../Common/IntToString.h"
+// #include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#ifndef UNDER_CE
@@ -19,13 +19,15 @@ namespace NFar {
CStartupInfo g_StartupInfo;
+const char kRegistryKeyDelimiter = '\\';
+
void CStartupInfo::Init(const PluginStartupInfo &pluginStartupInfo,
- const CSysString &pluginNameForRegestry)
+ const char *pluginNameForRegistry)
{
m_Data = pluginStartupInfo;
- m_RegistryPath = GetSystemString(pluginStartupInfo.RootKey);
- m_RegistryPath += TEXT('\\');
- m_RegistryPath += pluginNameForRegestry;
+ m_RegistryPath = pluginStartupInfo.RootKey;
+ m_RegistryPath += kRegistryKeyDelimiter;
+ m_RegistryPath += pluginNameForRegistry;
}
const char *CStartupInfo::GetMsgString(int messageId)
@@ -114,7 +116,7 @@ static void SplitString(const AString &src, AStringVector &destStrings)
int CStartupInfo::ShowErrorMessage(const char *message)
{
AStringVector strings;
- SplitString(message, strings);
+ SplitString((AString)message, strings);
const unsigned kNumStringsMax = 20;
const char *items[kNumStringsMax + 1];
unsigned pos = 0;
@@ -209,28 +211,31 @@ void CStartupInfo::RestoreScreen(HANDLE handle)
m_Data.RestoreScreen(handle);
}
-const TCHAR kRegestryKeyDelimiter = TEXT('\'');
-
-CSysString CStartupInfo::GetFullKeyName(const CSysString &keyName) const
+CSysString CStartupInfo::GetFullKeyName(const char *keyName) const
{
- return (keyName.IsEmpty()) ? m_RegistryPath:
- (m_RegistryPath + kRegestryKeyDelimiter + keyName);
+ AString s = m_RegistryPath;
+ if (keyName && *keyName)
+ {
+ s += kRegistryKeyDelimiter;
+ s += keyName;
+ }
+ return (CSysString)s;
}
LONG CStartupInfo::CreateRegKey(HKEY parentKey,
- const CSysString &keyName, NRegistry::CKey &destKey) const
+ const char *keyName, NRegistry::CKey &destKey) const
{
return destKey.Create(parentKey, GetFullKeyName(keyName));
}
LONG CStartupInfo::OpenRegKey(HKEY parentKey,
- const CSysString &keyName, NRegistry::CKey &destKey) const
+ const char *keyName, NRegistry::CKey &destKey) const
{
return destKey.Open(parentKey, GetFullKeyName(keyName));
}
-void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName,
+void CStartupInfo::SetRegKeyValue(HKEY parentKey, const char *keyName,
LPCTSTR valueName, LPCTSTR value) const
{
NRegistry::CKey regKey;
@@ -238,7 +243,7 @@ void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName,
regKey.SetValue(valueName, value);
}
-void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName,
+void CStartupInfo::SetRegKeyValue(HKEY parentKey, const char *keyName,
LPCTSTR valueName, UInt32 value) const
{
NRegistry::CKey regKey;
@@ -246,7 +251,7 @@ void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName,
regKey.SetValue(valueName, value);
}
-void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName,
+void CStartupInfo::SetRegKeyValue(HKEY parentKey, const char *keyName,
LPCTSTR valueName, bool value) const
{
NRegistry::CKey regKey;
@@ -254,7 +259,7 @@ void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName,
regKey.SetValue(valueName, value);
}
-CSysString CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
+CSysString CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName,
LPCTSTR valueName, const CSysString &valueDefault) const
{
NRegistry::CKey regKey;
@@ -268,7 +273,7 @@ CSysString CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyN
return value;
}
-UInt32 CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
+UInt32 CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName,
LPCTSTR valueName, UInt32 valueDefault) const
{
NRegistry::CKey regKey;
@@ -282,7 +287,7 @@ UInt32 CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
return value;
}
-bool CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
+bool CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName,
LPCTSTR valueName, bool valueDefault) const
{
NRegistry::CKey regKey;
@@ -390,7 +395,7 @@ int CStartupInfo::Menu(
unsigned int flags,
const char *title,
const char *helpTopic,
- const CSysStringVector &items,
+ const AStringVector &items,
int selectedItem)
{
CRecordVector<FarMenuItem> farMenuItems;
@@ -400,8 +405,8 @@ int CStartupInfo::Menu(
item.Checked = 0;
item.Separator = 0;
item.Selected = ((int)i == selectedItem);
- CSysString reducedString = items[i].Left(ARRAY_SIZE(item.Text) - 1);
- MyStringCopy(item.Text, (const char *)GetOemString(reducedString));
+ const AString reducedString (items[i].Left(ARRAY_SIZE(item.Text) - 1));
+ MyStringCopy(item.Text, reducedString);
farMenuItems.Add(item);
}
return Menu(flags, title, helpTopic, &farMenuItems.Front(), farMenuItems.Size());
@@ -434,11 +439,9 @@ void CScreenRestorer::Restore()
int PrintErrorMessage(const char *message, unsigned code)
{
- AString s = message;
+ AString s (message);
s += " #";
- char temp[16];
- ConvertUInt32ToString((UInt32)code, temp);
- s += temp;
+ s.Add_UInt32((UInt32)code);
return g_StartupInfo.ShowErrorMessage(s);
}
@@ -479,10 +482,10 @@ int ShowLastErrorMessage()
int ShowSysErrorMessage(DWORD errorCode, const wchar_t *name)
{
- UString s = NError::MyFormatMessage(errorCode);
- AString s1 = UnicodeStringToMultiByte(s, CP_OEMCP);
- AString s2 = UnicodeStringToMultiByte(name, CP_OEMCP);
- return g_StartupInfo.ShowErrorMessage2(s1, s2);
+ const UString s = NError::MyFormatMessage(errorCode);
+ return g_StartupInfo.ShowErrorMessage2(
+ UnicodeStringToMultiByte(s, CP_OEMCP),
+ UnicodeStringToMultiByte(name, CP_OEMCP));
}
diff --git a/CPP/7zip/UI/Far/FarUtils.h b/CPP/7zip/UI/Far/FarUtils.h
index 5617c6c8..38f64f98 100644
--- a/CPP/7zip/UI/Far/FarUtils.h
+++ b/CPP/7zip/UI/Far/FarUtils.h
@@ -47,17 +47,17 @@ struct CInitDialogItem
class CStartupInfo
{
PluginStartupInfo m_Data;
- CSysString m_RegistryPath;
+ AString m_RegistryPath;
- CSysString GetFullKeyName(const CSysString &keyName) const;
+ CSysString GetFullKeyName(const char *keyName) const;
LONG CreateRegKey(HKEY parentKey,
- const CSysString &keyName, NWindows::NRegistry::CKey &destKey) const;
+ const char *keyName, NWindows::NRegistry::CKey &destKey) const;
LONG OpenRegKey(HKEY parentKey,
- const CSysString &keyName, NWindows::NRegistry::CKey &destKey) const;
+ const char *keyName, NWindows::NRegistry::CKey &destKey) const;
public:
void Init(const PluginStartupInfo &pluginStartupInfo,
- const CSysString &pluginNameForRegestry);
+ const char *pluginNameForRegistry);
const char *GetMsgString(int messageId);
int ShowMessage(unsigned int flags, const char *helpTopic,
@@ -82,20 +82,20 @@ public:
HANDLE SaveScreen();
void RestoreScreen(HANDLE handle);
- void SetRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ void SetRegKeyValue(HKEY parentKey, const char *keyName,
const LPCTSTR valueName, LPCTSTR value) const;
- void SetRegKeyValue(HKEY hRoot, const CSysString &keyName,
+ void SetRegKeyValue(HKEY hRoot, const char *keyName,
const LPCTSTR valueName, UInt32 value) const;
- void SetRegKeyValue(HKEY hRoot, const CSysString &keyName,
+ void SetRegKeyValue(HKEY hRoot, const char *keyName,
const LPCTSTR valueName, bool value) const;
- CSysString QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ CSysString QueryRegKeyValue(HKEY parentKey, const char *keyName,
LPCTSTR valueName, const CSysString &valueDefault) const;
- UInt32 QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ UInt32 QueryRegKeyValue(HKEY parentKey, const char *keyName,
LPCTSTR valueName, UInt32 valueDefault) const;
- bool QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ bool QueryRegKeyValue(HKEY parentKey, const char *keyName,
LPCTSTR valueName, bool valueDefault) const;
bool Control(HANDLE plugin, int command, void *param);
@@ -131,7 +131,7 @@ public:
unsigned int flags,
const char *title,
const char *helpTopic,
- const CSysStringVector &items,
+ const AStringVector &items,
int selectedItem);
int Editor(const char *fileName, const char *title,
diff --git a/CPP/7zip/UI/Far/OverwriteDialogFar.cpp b/CPP/7zip/UI/Far/OverwriteDialogFar.cpp
index e950f695..1171453e 100644
--- a/CPP/7zip/UI/Far/OverwriteDialogFar.cpp
+++ b/CPP/7zip/UI/Far/OverwriteDialogFar.cpp
@@ -43,23 +43,31 @@ void SetFileInfoStrings(const CFileInfo &fileInfo,
fileInfoStrings.Size = "";
}
- FILETIME localFileTime;
fileInfoStrings.Time.Empty();
if (fileInfo.TimeIsDefined)
{
- if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime))
- throw 4190402;
char timeString[32];
- ConvertFileTimeToString(localFileTime, timeString);
+ ConvertUtcFileTimeToString(fileInfo.Time, timeString);
fileInfoStrings.Time = g_StartupInfo.GetMsgString(NMessageID::kOverwriteModifiedOn);
fileInfoStrings.Time += ' ';
fileInfoStrings.Time += timeString;
}
}
+static void ReduceString2(UString &s, unsigned size)
+{
+ if (!s.IsEmpty() && s.Back() == ' ')
+ {
+ // s += (wchar_t)(0x2423);
+ s.InsertAtFront(L'\"');
+ s += L'\"';
+ }
+ ReduceString(s, size);
+}
+
NResult::EEnum Execute(const CFileInfo &oldFileInfo, const CFileInfo &newFileInfo)
{
- const int kYSize = 20;
+ const int kYSize = 22;
const int kXSize = 76;
CFileInfoStrings oldFileInfoStrings;
@@ -68,17 +76,30 @@ NResult::EEnum Execute(const CFileInfo &oldFileInfo, const CFileInfo &newFileInf
SetFileInfoStrings(oldFileInfo, oldFileInfoStrings);
SetFileInfoStrings(newFileInfo, newFileInfoStrings);
- UString oldName2 = oldFileInfo.Name;
- UString newName2 = newFileInfo.Name;
+ const UString &oldName2 = oldFileInfo.Name;
+ const UString &newName2 = newFileInfo.Name;
+
+ int slashPos = oldName2.ReverseFind_PathSepar();
+ UString pref1 = oldName2.Left(slashPos + 1);
+ UString name1 = oldName2.Ptr(slashPos + 1);
+
+ slashPos = newName2.ReverseFind_PathSepar();
+ UString pref2 = newName2.Left(slashPos + 1);
+ UString name2 = newName2.Ptr(slashPos + 1);
+ const unsigned kNameOffset = 2;
{
const unsigned maxNameLen = kXSize - 9 - 2;
- ReduceString(oldName2, maxNameLen);
- ReduceString(newName2, maxNameLen);
+ ReduceString(pref1, maxNameLen);
+ ReduceString(pref2, maxNameLen);
+ ReduceString2(name1, maxNameLen - kNameOffset);
+ ReduceString2(name2, maxNameLen - kNameOffset);
}
- AString oldName = UnicodeStringToMultiByte(oldName2);
- AString newName = UnicodeStringToMultiByte(newName2);
+ AString pref1A (UnicodeStringToMultiByte(pref1, CP_OEMCP));
+ AString pref2A (UnicodeStringToMultiByte(pref2, CP_OEMCP));
+ AString name1A (UnicodeStringToMultiByte(name1, CP_OEMCP));
+ AString name2A (UnicodeStringToMultiByte(name2, CP_OEMCP));
struct CInitDialogItem initItems[]={
{ DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kOverwriteTitle, NULL, NULL },
@@ -88,15 +109,17 @@ NResult::EEnum Execute(const CFileInfo &oldFileInfo, const CFileInfo &newFileInf
{ DI_TEXT, 5, 4, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessageWouldYouLike, NULL, NULL },
- { DI_TEXT, 7, 6, 0, 0, false, false, 0, false, -1, oldName, NULL },
- { DI_TEXT, 7, 7, 0, 0, false, false, 0, false, -1, oldFileInfoStrings.Size, NULL },
- { DI_TEXT, 7, 8, 0, 0, false, false, 0, false, -1, oldFileInfoStrings.Time, NULL },
+ { DI_TEXT, 7, 6, 0, 0, false, false, 0, false, -1, pref1A, NULL },
+ { DI_TEXT, 7 + kNameOffset, 7, 0, 0, false, false, 0, false, -1, name1A, NULL },
+ { DI_TEXT, 7, 8, 0, 0, false, false, 0, false, -1, oldFileInfoStrings.Size, NULL },
+ { DI_TEXT, 7, 9, 0, 0, false, false, 0, false, -1, oldFileInfoStrings.Time, NULL },
- { DI_TEXT, 5, 10, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessageWithtTisOne, NULL, NULL },
+ { DI_TEXT, 5, 11, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessageWithtTisOne, NULL, NULL },
- { DI_TEXT, 7, 12, 0, 0, false, false, 0, false, -1, newName, NULL },
- { DI_TEXT, 7, 13, 0, 0, false, false, 0, false, -1, newFileInfoStrings.Size, NULL },
- { DI_TEXT, 7, 14, 0, 0, false, false, 0, false, -1, newFileInfoStrings.Time, NULL },
+ { DI_TEXT, 7, 13, 0, 0, false, false, 0, false, -1, pref2A, NULL },
+ { DI_TEXT, 7 + kNameOffset, 14, 0, 0, false, false, 0, false, -1, name2A, NULL },
+ { DI_TEXT, 7, 15, 0, 0, false, false, 0, false, -1, newFileInfoStrings.Size, NULL },
+ { DI_TEXT, 7, 16, 0, 0, false, false, 0, false, -1, newFileInfoStrings.Time, NULL },
{ DI_TEXT, 3, kYSize - 5, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL },
diff --git a/CPP/7zip/UI/Far/Plugin.cpp b/CPP/7zip/UI/Far/Plugin.cpp
index 607cdfe3..72f81ac9 100644
--- a/CPP/7zip/UI/Far/Plugin.cpp
+++ b/CPP/7zip/UI/Far/Plugin.cpp
@@ -30,7 +30,8 @@ int CompareFileNames_ForFolderList(const wchar_t *s1, const wchar_t *s2)
CPlugin::CPlugin(const FString &fileName, CAgent *agent, UString archiveTypeName):
_agent(agent),
m_FileName(fileName),
- _archiveTypeName(archiveTypeName)
+ _archiveTypeName(archiveTypeName),
+ PasswordIsDefined(false)
{
m_ArchiveHandler = agent;
if (!m_FileInfo.Find(m_FileName))
@@ -82,7 +83,7 @@ void CPlugin::ReadPluginPanelItem(PluginPanelItem &panelItem, UInt32 itemIndex)
if (prop.vt != VT_BSTR)
throw 272340;
- AString oemString = UnicodeStringToMultiByte(prop.bstrVal, CP_OEMCP);
+ AString oemString (UnicodeStringToMultiByte(prop.bstrVal, CP_OEMCP));
if (oemString == "..")
oemString = kDotsReplaceString;
@@ -193,7 +194,7 @@ void CPlugin::EnterToDirectory(const UString &dirName)
CMyComPtr<IFolderFolder> newFolder;
UString s = dirName;
if (dirName == kDotsReplaceStringU)
- s = L"..";
+ s = "..";
_folder->BindToFolder(s, &newFolder);
if (!newFolder)
if (dirName.IsEmpty())
@@ -281,7 +282,7 @@ void CPlugin::SetCurrentDirVar()
}
}
-static const char *kPluginFormatName = "7-ZIP";
+static const char * const kPluginFormatName = "7-ZIP";
static int FindPropNameID(PROPID propID)
@@ -371,17 +372,17 @@ static AString GetNameOfProp(PROPID propID, const wchar_t *name)
{
int farID = FindPropNameID(propID);
if (farID >= 0)
- return g_StartupInfo.GetMsgString(farID);
+ return (AString)g_StartupInfo.GetMsgString(farID);
if (name)
- return UnicodeStringToMultiByte((const wchar_t *)name, CP_OEMCP);
+ return UnicodeStringToMultiByte(name, CP_OEMCP);
char s[16];
ConvertUInt32ToString(propID, s);
- return s;
+ return (AString)s;
}
static AString GetNameOfProp2(PROPID propID, const wchar_t *name)
{
- AString s = GetNameOfProp(propID, name);
+ AString s (GetNameOfProp(propID, name));
if (s.Len() > (kInfoPanelLineSize - 1))
s.DeleteFrom(kInfoPanelLineSize - 1);
return s;
@@ -403,14 +404,14 @@ static AString ConvertSizeToString(UInt64 value)
}
while (i > 0)
s[--pos] = s[--i];
- return s + pos;
+ return (AString)(s + pos);
}
static AString PropToString(const NCOM::CPropVariant &prop, PROPID propID)
{
if (prop.vt == VT_BSTR)
{
- AString s = UnicodeStringToMultiByte(prop.bstrVal, CP_OEMCP);
+ AString s (UnicodeStringToMultiByte(prop.bstrVal, CP_OEMCP));
s.Replace((char)0xA, ' ');
s.Replace((char)0xD, ' ');
return s;
@@ -419,7 +420,7 @@ static AString PropToString(const NCOM::CPropVariant &prop, PROPID propID)
{
int messageID = VARIANT_BOOLToBool(prop.boolVal) ?
NMessageID::kYes : NMessageID::kNo;
- return g_StartupInfo.GetMsgString(messageID);
+ return (AString)g_StartupInfo.GetMsgString(messageID);
}
if (prop.vt != VT_EMPTY)
{
@@ -441,8 +442,8 @@ static AString PropToString(const NCOM::CPropVariant &prop, PROPID propID)
}
{
char sz[64];
- ConvertPropertyToShortString(sz, prop, propID);
- return sz;
+ ConvertPropertyToShortString2(sz, prop, propID);
+ return (AString)sz;
}
}
return AString();
@@ -450,7 +451,7 @@ static AString PropToString(const NCOM::CPropVariant &prop, PROPID propID)
static AString PropToString2(const NCOM::CPropVariant &prop, PROPID propID)
{
- AString s = PropToString(prop, propID);
+ AString s (PropToString(prop, propID));
if (s.Len() > (kInfoPanelLineSize - 1))
s.DeleteFrom(kInfoPanelLineSize - 1);
return s;
@@ -461,7 +462,7 @@ static void AddPropertyString(InfoPanelLine *lines, int &numItems, PROPID propID
{
if (prop.vt != VT_EMPTY)
{
- AString val = PropToString2(prop, propID);
+ AString val (PropToString2(prop, propID));
if (!val.IsEmpty())
{
InfoPanelLine &item = lines[numItems++];
@@ -504,9 +505,9 @@ void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info)
name = fs2us(fileName);
}
- m_PannelTitle = L' ';
+ m_PannelTitle = ' ';
m_PannelTitle += _archiveTypeName;
- m_PannelTitle += L':';
+ m_PannelTitle += ':';
m_PannelTitle += name;
m_PannelTitle.Add_Space();
if (!m_CurrentDir.IsEmpty())
@@ -748,8 +749,7 @@ HRESULT CPlugin::ShowAttributesWindow()
NCOM::CPropVariant prop;
RINOK(_folder->GetProperty(itemIndex, property.ID, &prop));
- AString s = PropToString(prop, property.ID);
- values.Add(s);
+ values.Add(PropToString(prop, property.ID));
{
const CInitDialogItem idi =
@@ -803,10 +803,8 @@ HRESULT CPlugin::ShowAttributesWindow()
const UInt32 kMaxDataSize = 64;
if (dataSize > kMaxDataSize)
{
- char temp[64];
s += "data:";
- ConvertUInt32ToString(dataSize, temp);
- s += temp;
+ s.Add_UInt32(dataSize);
}
else
{
diff --git a/CPP/7zip/UI/Far/PluginDelete.cpp b/CPP/7zip/UI/Far/PluginDelete.cpp
index e1a103ac..95584341 100644
--- a/CPP/7zip/UI/Far/PluginDelete.cpp
+++ b/CPP/7zip/UI/Far/PluginDelete.cpp
@@ -84,6 +84,8 @@ int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems, int opMode)
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec);
updateCallbackSpec->Init(/* m_ArchiveHandler, */ progressBoxPointer);
+ updateCallbackSpec->PasswordIsDefined = PasswordIsDefined;
+ updateCallbackSpec->Password = Password;
/*
outArchive->SetFolder(_folder);
diff --git a/CPP/7zip/UI/Far/PluginRead.cpp b/CPP/7zip/UI/Far/PluginRead.cpp
index 433e8140..9df4a09f 100644
--- a/CPP/7zip/UI/Far/PluginRead.cpp
+++ b/CPP/7zip/UI/Far/PluginRead.cpp
@@ -21,11 +21,11 @@ using namespace NFile;
using namespace NDir;
using namespace NFar;
-static const char *kHelpTopicExtrFromSevenZip = "Extract";
+static const char * const kHelpTopicExtrFromSevenZip = "Extract";
-static const char kDirDelimiter = '\\';
+static const char kDirDelimiter = CHAR_PATH_SEPARATOR;
-static const char *kExractPathHistoryName = "7-ZipExtractPath";
+static const char * const kExractPathHistoryName = "7-ZipExtractPath";
HRESULT CPlugin::ExtractFiles(
bool decompressAllItems,
@@ -95,7 +95,7 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa
return NFileOperationReturnCode::kError;
}
- AString destPath = destPathLoc;
+ AString destPath (destPathLoc);
UString destPathU = GetUnicodeString(destPath, CP_OEMCP);
NName::NormalizeDirPathPrefix(destPathU);
destPath = UnicodeStringToMultiByte(destPathU, CP_OEMCP);
@@ -127,7 +127,7 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa
const int kXMid = kXSize / 2;
- AString oemPassword = UnicodeStringToMultiByte(password, CP_OEMCP);
+ AString oemPassword (UnicodeStringToMultiByte(password, CP_OEMCP));
struct CInitDialogItem initItems[]={
{ DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kExtractTitle, NULL, NULL },
@@ -196,7 +196,7 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa
if (destPathU.IsEmpty())
{
#ifdef UNDER_CE
- destPathU = L"\\";
+ destPathU = "\\";
#else
FString destPathF = us2fs(destPathU);
if (!GetCurrentDir(destPathF))
diff --git a/CPP/7zip/UI/Far/PluginWrite.cpp b/CPP/7zip/UI/Far/PluginWrite.cpp
index b22577af..ec0f119b 100644
--- a/CPP/7zip/UI/Far/PluginWrite.cpp
+++ b/CPP/7zip/UI/Far/PluginWrite.cpp
@@ -27,9 +27,9 @@ using namespace NFar;
using namespace NUpdateArchive;
-static const char *kHelpTopic = "Update";
+static const char * const kHelpTopic = "Update";
-static const char *kArchiveHistoryKeyName = "7-ZipArcName";
+static const char * const kArchiveHistoryKeyName = "7-ZipArcName";
static const UInt32 g_MethodMap[] = { 0, 1, 3, 5, 7, 9 };
@@ -38,13 +38,18 @@ static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UInt32 method)
CMyComPtr<ISetProperties> setProperties;
if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
{
+ /*
UStringVector realNames;
- realNames.Add(UString(L"x"));
+ realNames.Add(UString("x"));
NCOM::CPropVariant value = (UInt32)method;
CRecordVector<const wchar_t *> names;
FOR_VECTOR (i, realNames)
names.Add(realNames[i]);
RINOK(setProperties->SetProperties(&names.Front(), &value, names.Size()));
+ */
+ NCOM::CPropVariant value = (UInt32)method;
+ const wchar_t *name = L"x";
+ RINOK(setProperties->SetProperties(&name, &value, 1));
}
return S_OK;
}
@@ -219,6 +224,8 @@ NFileOperationReturnCode::EEnum CPlugin::PutFiles(
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec );
updateCallbackSpec->Init(/* m_ArchiveHandler, */ progressBoxPointer);
+ updateCallbackSpec->PasswordIsDefined = PasswordIsDefined;
+ updateCallbackSpec->Password = Password;
if (SetOutProperties(outArchive, compressionInfo.Level) != S_OK)
return NFileOperationReturnCode::kError;
@@ -287,7 +294,7 @@ struct CParsedPath
UString MergePath() const;
};
-static const wchar_t kDirDelimiter = WCHAR_PATH_SEPARATOR;
+static const char kDirDelimiter = CHAR_PATH_SEPARATOR;
static const wchar_t kDiskDelimiter = L':';
namespace NPathType
@@ -322,7 +329,7 @@ void CParsedPath::ParsePath(const UString &path)
case NPathType::kUNC:
{
// the bug was fixed:
- curPos = path.Find(kDirDelimiter, 2);
+ curPos = path.Find((wchar_t)kDirDelimiter, 2);
if (curPos < 0)
curPos = path.Len();
else
@@ -355,7 +362,7 @@ static void SetArcName(UString &arcName, const CArcInfoEx &arcInfo)
if (dotPos > slashPos + 1)
arcName.DeleteFrom(dotPos);
}
- arcName += L'.';
+ arcName += '.';
arcName += arcInfo.GetMainExt();
}
@@ -444,7 +451,7 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
for (;;)
{
- AString archiveNameA = UnicodeStringToMultiByte(arcName, CP_OEMCP);
+ AString archiveNameA (UnicodeStringToMultiByte(arcName, CP_OEMCP));
const int kYSize = 16;
const int kXMid = 38;
@@ -456,7 +463,7 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
char updateAddToArchiveString[512];
{
const CArcInfoEx &arcInfo = codecs->Formats[archiverIndex];
- const AString s = UnicodeStringToMultiByte(arcInfo.Name, CP_OEMCP);
+ const AString s (UnicodeStringToMultiByte(arcInfo.Name, CP_OEMCP));
sprintf(updateAddToArchiveString,
g_StartupInfo.GetMsgString(NMessageID::kUpdateAddToArchive), (const char *)s);
}
@@ -530,14 +537,14 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
if (askCode == kSelectarchiverButtonIndex)
{
CIntVector indices;
- CSysStringVector archiverNames;
+ AStringVector archiverNames;
FOR_VECTOR (k, codecs->Formats)
{
const CArcInfoEx &arc = codecs->Formats[k];
if (arc.UpdateEnabled)
{
indices.Add(k);
- archiverNames.Add(GetSystemString(arc.Name, CP_OEMCP));
+ archiverNames.Add(GetOemString(arc.Name));
}
}
@@ -704,7 +711,7 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
}
-static const char *k_CreateFolder_History = "NewFolder"; // we use default FAR folder name
+static const char * const k_CreateFolder_History = "NewFolder"; // we use default FAR folder name
HRESULT CPlugin::CreateFolder()
{
@@ -720,7 +727,7 @@ HRESULT CPlugin::CreateFolder()
const int kYSize = 8;
const int kPathIndex = 2;
- AString destPath = "New Folder";
+ AString destPath ("New Folder");
const struct CInitDialogItem initItems[]={
{ DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false,
@@ -773,6 +780,8 @@ HRESULT CPlugin::CreateFolder()
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec);
updateCallbackSpec->Init(/* m_ArchiveHandler, */ progressBoxPointer);
+ updateCallbackSpec->PasswordIsDefined = PasswordIsDefined;
+ updateCallbackSpec->Password = Password;
HRESULT result;
{
@@ -797,7 +806,7 @@ HRESULT CPlugin::CreateFolder()
if (g_StartupInfo.ControlGetActivePanelInfo(panelInfo))
{
- AString destPath = GetOemString(destPathU);
+ const AString destPath (GetOemString(destPathU));
for (int i = 0; i < panelInfo.ItemsNumber; i++)
{
diff --git a/CPP/7zip/UI/Far/ProgressBox.cpp b/CPP/7zip/UI/Far/ProgressBox.cpp
index 75467864..6efb132a 100644
--- a/CPP/7zip/UI/Far/ProgressBox.cpp
+++ b/CPP/7zip/UI/Far/ProgressBox.cpp
@@ -18,7 +18,7 @@ void CPercentPrinterState::ClearCurState()
FileName.Empty();
}
-void CProgressBox::Init(const AString &title)
+void CProgressBox::Init(const char *title)
{
_title = title;
_wasPrinted = false;
@@ -218,14 +218,13 @@ void CProgressBox::Print()
unsigned filled = 0;
if (total != (UInt64)(Int64)-1 && total != 0)
filled = (unsigned)(cur * numChars / total);
+ if (filled > numChars)
+ filled = numChars;
unsigned i = 0;
- if (filled < numChars)
- {
- for (i = 0; i < filled; i++)
- _perc += '=';
- }
+ for (i = 0; i < filled; i++)
+ _perc += (char)(Byte)0xDB; // '=';
for (; i < numChars; i++)
- _perc += '.';
+ _perc += (char)(Byte)0xB0; // '.';
}
_perc.Add_Space();
diff --git a/CPP/7zip/UI/Far/ProgressBox.h b/CPP/7zip/UI/Far/ProgressBox.h
index 83731b38..54bdb4f1 100644
--- a/CPP/7zip/UI/Far/ProgressBox.h
+++ b/CPP/7zip/UI/Far/ProgressBox.h
@@ -76,7 +76,7 @@ public:
MaxLen(60)
{}
- void Init(const AString &title);
+ void Init(const char *title);
void Print();
};
diff --git a/CPP/7zip/UI/Far/UpdateCallbackFar.cpp b/CPP/7zip/UI/Far/UpdateCallbackFar.cpp
index 18d1a2c9..3f0f206b 100644
--- a/CPP/7zip/UI/Far/UpdateCallbackFar.cpp
+++ b/CPP/7zip/UI/Far/UpdateCallbackFar.cpp
@@ -62,6 +62,20 @@ STDMETHODIMP CUpdateCallback100Imp::SetNumFiles(UInt64 numFiles)
return CheckBreak2();
}
+
+STDMETHODIMP CUpdateCallback100Imp::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)
+{
+ MT_LOCK
+ return CheckBreak2();
+}
+
+
+
STDMETHODIMP CUpdateCallback100Imp::SetTotal(UInt64 size)
{
MT_LOCK
@@ -203,10 +217,21 @@ STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password)
MT_LOCK
*password = NULL;
- if (!m_PasswordIsDefined)
+ if (!PasswordIsDefined)
{
- RINOK(GetPassword(m_Password));
- m_PasswordIsDefined = true;
+ RINOK(GetPassword(Password));
+ PasswordIsDefined = true;
}
- return StringToBstr(m_Password, password);
+ return StringToBstr(Password, password);
+}
+
+STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
+{
+ MT_LOCK
+
+ *password = NULL;
+ *passwordIsDefined = BoolToInt(PasswordIsDefined);
+ if (!PasswordIsDefined)
+ return S_OK;
+ return StringToBstr(Password, password);
}
diff --git a/CPP/7zip/UI/Far/UpdateCallbackFar.h b/CPP/7zip/UI/Far/UpdateCallbackFar.h
index a2328669..d2c2c8ed 100644
--- a/CPP/7zip/UI/Far/UpdateCallbackFar.h
+++ b/CPP/7zip/UI/Far/UpdateCallbackFar.h
@@ -15,35 +15,45 @@ class CUpdateCallback100Imp:
public IFolderArchiveUpdateCallback,
public IFolderArchiveUpdateCallback2,
public IFolderScanProgress,
+ public ICryptoGetTextPassword2,
public ICryptoGetTextPassword,
+ public IArchiveOpenCallback,
public CMyUnknownImp
{
// CMyComPtr<IInFolderArchive> _archiveHandler;
CProgressBox *_percent;
UInt64 _total;
- bool m_PasswordIsDefined;
- UString m_Password;
public:
- MY_UNKNOWN_IMP4(
+
+ bool PasswordIsDefined;
+ UString Password;
+
+ MY_UNKNOWN_IMP6(
IFolderArchiveUpdateCallback,
IFolderArchiveUpdateCallback2,
IFolderScanProgress,
- ICryptoGetTextPassword)
+ ICryptoGetTextPassword2,
+ ICryptoGetTextPassword,
+ IArchiveOpenCallback
+ )
INTERFACE_IProgress(;)
INTERFACE_IFolderArchiveUpdateCallback(;)
INTERFACE_IFolderArchiveUpdateCallback2(;)
INTERFACE_IFolderScanProgress(;)
+ INTERFACE_IArchiveOpenCallback(;)
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+ STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
CUpdateCallback100Imp(): _total(0) {}
void Init(/* IInFolderArchive *archiveHandler, */ CProgressBox *progressBox)
{
// _archiveHandler = archiveHandler;
_percent = progressBox;
- m_PasswordIsDefined = false;
+ PasswordIsDefined = false;
+ Password.Empty();
}
};
diff --git a/CPP/7zip/UI/FileManager/AboutDialog.cpp b/CPP/7zip/UI/FileManager/AboutDialog.cpp
index 35e67753..a644474b 100644
--- a/CPP/7zip/UI/FileManager/AboutDialog.cpp
+++ b/CPP/7zip/UI/FileManager/AboutDialog.cpp
@@ -17,8 +17,8 @@ static const UInt32 kLangIDs[] =
IDT_ABOUT_INFO
};
-static LPCTSTR kHomePageURL = TEXT("http://www.7-zip.org/");
-static LPCWSTR kHelpTopic = L"start.htm";
+#define kHomePageURL TEXT("http://www.7-zip.org/")
+#define kHelpTopic "start.htm"
#define LLL_(quote) L##quote
#define LLL(quote) LLL_(quote)
@@ -26,14 +26,7 @@ static LPCWSTR kHelpTopic = L"start.htm";
bool CAboutDialog::OnInit()
{
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
- UString s = L"7-Zip " LLL(MY_VERSION);
- #ifdef MY_CPU_64BIT
- s += L" [";
- AddLangString(s, IDS_PROP_BIT64);
- s += L']';
- #endif
-
- SetItemText(IDT_ABOUT_VERSION, s);
+ SetItemText(IDT_ABOUT_VERSION, UString("7-Zip " MY_VERSION_CPU));
SetItemText(IDT_ABOUT_DATE, LLL(MY_DATE));
LangSetWindowText(*this, IDD_ABOUT);
@@ -43,7 +36,7 @@ bool CAboutDialog::OnInit()
void CAboutDialog::OnHelp()
{
- ShowHelpWindow(NULL, kHelpTopic);
+ ShowHelpWindow(kHelpTopic);
}
bool CAboutDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
diff --git a/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp b/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp
index c209bf35..b7fbb235 100644
--- a/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp
+++ b/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp
@@ -274,7 +274,7 @@ STDMETHODIMP CAltStreamsFolder::BindToFolder(const wchar_t * /* name */, IFolder
return E_INVALIDARG;
}
-static const CFSTR kSuperPrefix = FTEXT("\\\\?\\");
+// static CFSTR const kSuperPrefix = FTEXT("\\\\?\\");
STDMETHODIMP CAltStreamsFolder::BindToParentFolder(IFolderFolder **resultFolder)
{
@@ -408,7 +408,7 @@ static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
const wchar_t *message, const FString &fileName)
{
UString s = message;
- s += L" : ";
+ s += " : ";
s += fs2us(fileName);
return callback->ShowMessage(s);
}
@@ -417,7 +417,7 @@ static HRESULT SendMessageError(IFolderArchiveUpdateCallback *callback,
const wchar_t *message, const FString &fileName)
{
UString s = message;
- s += L" : ";
+ s += " : ";
s += fs2us(fileName);
return callback->UpdateErrorMessage(s);
}
@@ -629,7 +629,7 @@ static HRESULT CopyStream(
if (IntToBool(writeAskResult))
{
RINOK(callback->SetCurrentFilePath(fs2us(srcPath)));
- FString destPathNew = us2fs((LPCOLESTR)destPathResult);
+ FString destPathNew (us2fs((LPCOLESTR)destPathResult));
RINOK(state.MyCopyFile(srcPath, destPathNew));
if (state.ErrorFileIndex >= 0)
{
@@ -712,7 +712,7 @@ STDMETHODIMP CAltStreamsFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UI
}
*/
- FString destPath = us2fs(path);
+ FString destPath (us2fs(path));
if (destPath.IsEmpty() /* && !ExtractToStreamCallback */)
return E_INVALIDARG;
diff --git a/CPP/7zip/UI/FileManager/App.cpp b/CPP/7zip/UI/FileManager/App.cpp
index 6d5662de..dfc75b69 100644
--- a/CPP/7zip/UI/FileManager/App.cpp
+++ b/CPP/7zip/UI/FileManager/App.cpp
@@ -23,6 +23,7 @@
#include "FormatUtils.h"
#include "IFolder.h"
#include "LangUtils.h"
+#include "MyLoadMenu.h"
#include "RegistryUtils.h"
#include "ViewSettings.h"
@@ -37,7 +38,7 @@ using namespace NName;
extern DWORD g_ComCtl32Version;
extern HINSTANCE g_hInstance;
-static CFSTR kTempDirPrefix = FTEXT("7zE");
+#define kTempDirPrefix FTEXT("7zE")
void CPanelCallbackImp::OnTab()
{
@@ -281,9 +282,6 @@ void CApp::SaveToolbarChanges()
}
-void MyLoadMenu();
-
-
HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, bool &archiveIsOpened, bool &encrypted)
{
_window.Attach(hwnd);
@@ -460,7 +458,7 @@ static void AddSizeValue(UString &s, UInt64 size)
static void AddValuePair1(UString &s, UINT resourceID, UInt64 size)
{
AddLangString(s, resourceID);
- s += L": ";
+ s += ": ";
AddSizeValue(s, size);
s.Add_LF();
}
@@ -470,14 +468,14 @@ void AddValuePair2(UString &s, UINT resourceID, UInt64 num, UInt64 size)
if (num == 0)
return;
AddLangString(s, resourceID);
- s += L": ";
+ s += ": ";
s += ConvertSizeToString(num);
if (size != (UInt64)(Int64)-1)
{
- s += L" ( ";
+ s += " ( ";
AddSizeValue(s, size);
- s += L" )";
+ s += " )";
}
s.Add_LF();
}
@@ -529,14 +527,18 @@ UString CPanel::GetItemsInfoString(const CRecordVector<UInt32> &indices)
for (i = 0; i < indices.Size() && (int)i < (int)kCopyDialog_NumInfoLines - 6; i++)
{
- info += L"\n ";
+ info.Add_LF();
+ info += " ";
int index = indices[i];
info += GetItemRelPath(index);
if (IsItem_Folder(index))
info.Add_PathSepar();
}
if (i != indices.Size())
- info += L"\n ...";
+ {
+ info.Add_LF();
+ info += " ...";
+ }
return info;
}
@@ -697,7 +699,7 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
else
{
if (indices.Size() == 1 &&
- !destPath.IsEmpty() && destPath.Back() != WCHAR_PATH_SEPARATOR)
+ !destPath.IsEmpty() && !IS_PATH_SEPAR(destPath.Back()))
{
int pos = destPath.ReverseFind_PathSepar();
if (pos < 0)
@@ -810,7 +812,7 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
// srcPanel.InvalidateList(NULL, true);
if (result != E_ABORT)
- srcPanel.MessageBoxError(result, L"Error");
+ srcPanel.MessageBoxError(result);
// return;
}
@@ -862,12 +864,24 @@ void CApp::OnSetSubFolder(int srcPanelIndex)
{
if (srcPanel._folder->BindToParentFolder(&newFolder) != S_OK)
return;
+ if (!newFolder)
+ {
+ const UString parentPrefix = srcPanel.GetParentDirPrefix();
+ bool archiveIsOpened, encrypted;
+ destPanel.BindToPath(parentPrefix, UString(), archiveIsOpened, encrypted);
+ destPanel.RefreshListCtrl();
+ return;
+ }
}
else
{
if (srcPanel._folder->BindToFolder(realIndex, &newFolder) != S_OK)
return;
}
+
+ if (!newFolder)
+ return;
+
destPanel.CloseOpenFolders();
destPanel.SetNewFolder(newFolder);
destPanel.RefreshListCtrl();
@@ -927,7 +941,7 @@ void CApp::RefreshTitle(bool always)
{
UString path = GetFocusedPanel()._currentFolderPrefix;
if (path.IsEmpty())
- path = L"7-Zip"; // LangString(IDS_APP_TITLE);
+ path = "7-Zip"; // LangString(IDS_APP_TITLE);
if (!always && path == PrevTitle)
return;
PrevTitle = path;
diff --git a/CPP/7zip/UI/FileManager/App.h b/CPP/7zip/UI/FileManager/App.h
index 9cc1066b..fa8eeaa7 100644
--- a/CPP/7zip/UI/FileManager/App.h
+++ b/CPP/7zip/UI/FileManager/App.h
@@ -195,7 +195,7 @@ public:
void MoveTo() { OnCopy(true, false, GetFocusedPanelIndex()); }
void Delete(bool toRecycleBin) { GetFocusedPanel().DeleteItems(toRecycleBin); }
HRESULT CalculateCrc2(const UString &methodName);
- void CalculateCrc(const UString &methodName);
+ void CalculateCrc(const char *methodName);
void DiffFiles();
void Split();
void Combine();
@@ -259,7 +259,23 @@ public:
void SetListSettings();
HRESULT SwitchOnOffOnePanel();
+ CIntVector _timestampLevels;
+
bool GetFlatMode() { return Panels[LastFocusedPanel].GetFlatMode(); }
+
+ int GetTimestampLevel() const { return Panels[LastFocusedPanel]._timestampLevel; }
+ void SetTimestampLevel(int level)
+ {
+ unsigned i;
+ for (i = 0; i < kNumPanelsMax; i++)
+ {
+ CPanel &panel = Panels[i];
+ panel._timestampLevel = level;
+ if (panel.PanelCreated)
+ panel.RedrawListItems();
+ }
+ }
+
// bool Get_ShowNtfsStrems_Mode() { return Panels[LastFocusedPanel].Get_ShowNtfsStrems_Mode(); }
void ChangeFlatMode() { Panels[LastFocusedPanel].ChangeFlatMode(); }
diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/CPP/7zip/UI/FileManager/BrowseDialog.cpp
index 066ac219..d8f9ebe8 100644
--- a/CPP/7zip/UI/FileManager/BrowseDialog.cpp
+++ b/CPP/7zip/UI/FileManager/BrowseDialog.cpp
@@ -209,7 +209,7 @@ bool CBrowseDialog::OnInit()
if (!FilterDescription.IsEmpty())
s = FilterDescription;
else if (ShowAllFiles)
- s = L"*.*";
+ s = "*.*";
else
{
FOR_VECTOR (i, Filters)
@@ -468,11 +468,11 @@ bool CBrowseDialog::GetParentPath(const UString &path, UString &parentPrefix, US
if (_topDirPrefix == path)
return false;
UString s = path;
- if (s.Back() == WCHAR_PATH_SEPARATOR)
+ if (IS_PATH_SEPAR(s.Back()))
s.DeleteBack();
if (s.IsEmpty())
return false;
- if (s.Back() == WCHAR_PATH_SEPARATOR)
+ if (IS_PATH_SEPAR(s.Back()))
return false;
int pos = s.ReverseFind_PathSepar();
parentPrefix.SetFrom(s, pos + 1);
@@ -531,7 +531,7 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
#ifndef UNDER_CE
bool isDrive = false;
- if (pathPrefix.IsEmpty() || pathPrefix == kSuperPathPrefix)
+ if (pathPrefix.IsEmpty() || pathPrefix.IsEqualTo(kSuperPathPrefix))
{
isDrive = true;
FStringVector drives;
@@ -551,7 +551,8 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
else
#endif
{
- CEnumerator enumerator(us2fs(pathPrefix + L'*'));
+ CEnumerator enumerator;
+ enumerator.SetDirPrefix(us2fs(pathPrefix));
for (;;)
{
bool found;
@@ -596,7 +597,7 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
if (_showDots && _topDirPrefix != DirPrefix)
{
item.iItem = index;
- const UString itemName = L"..";
+ const UString itemName ("..");
if (selectedName.IsEmpty())
cursorIndex = index;
item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
@@ -642,16 +643,14 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
_list.InsertItem(&item);
wchar_t s[32];
{
- FILETIME ft;
s[0] = 0;
- if (FileTimeToLocalFileTime(&fi.MTime, &ft))
- ConvertFileTimeToString(ft, s,
+ ConvertUtcFileTimeToString(fi.MTime, s,
#ifndef UNDER_CE
- true
+ kTimestampPrintLevel_MIN
#else
- false
+ kTimestampPrintLevel_DAY
#endif
- , false);
+ );
_list.SetSubItem(index, subItem++, s);
}
{
@@ -780,8 +779,10 @@ void CBrowseDialog::OnItemEnter()
*/
return;
}
- UString s = DirPrefix + fs2us(file.Name) + WCHAR_PATH_SEPARATOR;
- HRESULT res = Reload(s, L"");
+ UString s = DirPrefix;
+ s += fs2us(file.Name);
+ s.Add_PathSepar();
+ HRESULT res = Reload(s, UString());
if (res != S_OK)
MessageBox_HResError(*this, res, s);
SetPathEditText();
@@ -853,17 +854,17 @@ bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path,
#else
// maybe we must use GetLastError in WinCE.
DWORD errorCode = CommDlgExtendedError();
- const wchar_t *errorMessage = NULL;
+ const char *errorMessage = NULL;
switch (errorCode)
{
case 0: return false; // cancel or close obn dialog
- case FNERR_INVALIDFILENAME: errorMessage = L"Invalid File Name"; break;
- default: errorMessage = L"Open Dialog Error";
+ case FNERR_INVALIDFILENAME: errorMessage = "Invalid File Name"; break;
+ default: errorMessage = "Open Dialog Error";
}
if (!errorMessage)
return false;
{
- UString s = errorMessage;
+ UString s (errorMessage);
s.Add_LF();
s += path;
MessageBox_Error_Global(owner, s);
diff --git a/CPP/7zip/UI/FileManager/EditPage.cpp b/CPP/7zip/UI/FileManager/EditPage.cpp
index b88c0f68..0108904d 100644
--- a/CPP/7zip/UI/FileManager/EditPage.cpp
+++ b/CPP/7zip/UI/FileManager/EditPage.cpp
@@ -23,7 +23,7 @@ static const UInt32 kLangIDs_Colon[] =
IDT_EDIT_VIEWER
};
-static LPCWSTR kEditTopic = L"FM/options.htm#editor";
+#define kEditTopic "FM/options.htm#editor"
bool CEditPage::OnInit()
{
@@ -76,17 +76,38 @@ LONG CEditPage::OnApply()
void CEditPage::OnNotifyHelp()
{
- ShowHelpWindow(NULL, kEditTopic);
+ ShowHelpWindow(kEditTopic);
}
+void SplitCmdLineSmart(const UString &cmd, UString &prg, UString &params);
+
static void Edit_BrowseForFile(NWindows::NControl::CEdit &edit, HWND hwnd)
{
- UString path;
- edit.GetText(path);
+ UString cmd;
+ edit.GetText(cmd);
+
+ UString param;
+ UString prg;
+
+ SplitCmdLineSmart(cmd, prg, param);
+
UString resPath;
- if (MyBrowseForFile(hwnd, 0, path, NULL, L"*.exe", resPath))
+
+ if (MyBrowseForFile(hwnd, 0, prg, NULL, L"*.exe", resPath))
{
- edit.SetText(resPath);
+ resPath.Trim();
+ cmd = resPath;
+ /*
+ if (!param.IsEmpty() && !resPath.IsEmpty())
+ {
+ cmd.InsertAtFront(L'\"');
+ cmd += L'\"';
+ cmd.Add_Space();
+ cmd += param;
+ }
+ */
+
+ edit.SetText(cmd);
// Changed();
}
}
diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.cpp b/CPP/7zip/UI/FileManager/ExtractCallback.cpp
index 7d61d14d..343bb0f8 100644
--- a/CPP/7zip/UI/FileManager/ExtractCallback.cpp
+++ b/CPP/7zip/UI/FileManager/ExtractCallback.cpp
@@ -335,20 +335,18 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileNam
s += msg;
else
{
- char temp[16];
- ConvertUInt32ToString(opRes, temp);
- s.AddAscii("Error #");
- s.AddAscii(temp);
+ s += "Error #";
+ s.Add_UInt32(opRes);
}
if (encrypted && opRes != NArchive::NExtract::NOperationResult::kWrongPassword)
{
- // s.AddAscii(" : ");
+ // s += " : ";
// AddLangString(s, IDS_EXTRACT_MSG_ENCRYPTED);
- s.AddAscii(" : ");
+ s += " : ";
AddLangString(s, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
}
- s.AddAscii(" : ");
+ s += " : ";
s += fileName;
}
}
@@ -466,7 +464,7 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags)
continue;
if (f == kpv_ErrorFlags_EncryptedHeadersError)
{
- m.AddAscii(" : ");
+ m += " : ";
AddLangString(m, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
}
if (!s.IsEmpty())
@@ -483,7 +481,7 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags)
ConvertUInt32ToHex(errorFlags, sz + 2);
if (!s.IsEmpty())
s.Add_LF();
- s.AddAscii(sz);
+ s += sz;
}
return s;
@@ -503,7 +501,7 @@ static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
if (warningFlags != 0)
{
s += GetNameOfProperty(kpidWarningFlags, L"Warnings");
- s.AddAscii(":");
+ s += ":";
s.Add_LF();
AddNewLineString(s, GetOpenArcErrorMessage(warningFlags));
}
@@ -511,7 +509,7 @@ static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
if (!er.WarningMessage.IsEmpty())
{
s += GetNameOfProperty(kpidWarning, L"Warning");
- s.AddAscii(": ");
+ s += ": ";
s += er.WarningMessage;
s.Add_LF();
}
@@ -519,9 +517,9 @@ static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
static UString GetBracedType(const wchar_t *type)
{
- UString s = L'[';
+ UString s ('[');
s += type;
- s += L']';
+ s += ']';
return s;
}
@@ -1009,7 +1007,7 @@ HRESULT CVirtFileSystem::FlushToDisk(bool closeLast)
{
_outFileStream.Release();
return E_FAIL;
- // MessageBoxMyError(UString(L"Can't create file ") + fs2us(tempFilePath));
+ // MessageBoxMyError(UString("Can't create file ") + fs2us(tempFilePath));
}
_fileIsOpen = true;
RINOK(WriteStream(_outFileStream, file.Data, (size_t)file.Size));
diff --git a/CPP/7zip/UI/FileManager/FM.cpp b/CPP/7zip/UI/FileManager/FM.cpp
index ce39011e..fe5ae671 100644
--- a/CPP/7zip/UI/FileManager/FM.cpp
+++ b/CPP/7zip/UI/FileManager/FM.cpp
@@ -8,7 +8,6 @@
#include "../../../../C/Alloc.h"
-#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
@@ -43,16 +42,21 @@ using namespace NFind;
#define MENU_HEIGHT 26
bool g_RAM_Size_Defined;
+bool g_LargePagesMode = false;
+bool g_OpenArchive = false;
+
+static bool g_Maximized = false;
+
UInt64 g_RAM_Size;
#ifdef _WIN32
HINSTANCE g_hInstance;
#endif
+
HWND g_HWND;
-bool g_OpenArchive = false;
+
static UString g_MainPath;
static UString g_ArcFormat;
-static bool g_Maximized = false;
// HRESULT LoadGlobalCodecs();
void FreeGlobalCodecs();
@@ -166,7 +170,7 @@ CApp g_App;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
-const wchar_t *kWindowClass = L"FM";
+static const wchar_t * const kWindowClass = L"FM";
#ifdef UNDER_CE
#define WS_OVERLAPPEDWINDOW ( \
@@ -185,7 +189,7 @@ static BOOL InitInstance(int nCmdShow)
// LoadString(hInstance, IDS_CLASS, windowClass, MAX_LOADSTRING);
- UString title = L"7-Zip"; // LangString(IDS_APP_TITLE, 0x03000000);
+ UString title ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000);
/*
//If it is already running, then focus on the window
@@ -379,7 +383,7 @@ static void SetMemoryLock()
NSecurity::AddLockMemoryPrivilege();
if (ReadLockMemoryEnable())
- NSecurity::EnablePrivilege_LockMemory();
+ g_LargePagesMode = NSecurity::EnablePrivilege_LockMemory();
}
bool g_SymLink_Supported = false;
@@ -426,8 +430,13 @@ static void ErrorMessage(const wchar_t *s)
MessageBoxW(0, s, L"7-Zip", MB_ICONERROR);
}
+static void ErrorMessage(const char *s)
+{
+ ErrorMessage(GetUnicodeString(s));
+}
+
-#define NT_CHECK_FAIL_ACTION ErrorMessage(L"Unsupported Windows version"); return 1;
+#define NT_CHECK_FAIL_ACTION ErrorMessage("Unsupported Windows version"); return 1;
static int WINAPI WinMain2(int nCmdShow)
{
@@ -667,7 +676,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
}
catch(const AString &s)
{
- ErrorMessage(GetUnicodeString(s));
+ ErrorMessage(s.Ptr());
return 1;
}
catch(const wchar_t *s)
@@ -677,19 +686,19 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
}
catch(const char *s)
{
- ErrorMessage(GetUnicodeString(s));
+ ErrorMessage(s);
return 1;
}
catch(int v)
{
- wchar_t s[32];
- ConvertUInt32ToString(v, s);
- ErrorMessage(UString(L"Error: ") + s);
+ AString e ("Error: ");
+ e.Add_UInt32(v);
+ ErrorMessage(e);
return 1;
}
catch(...)
{
- ErrorMessage(L"Unknown error");
+ ErrorMessage("Unknown error");
return 1;
}
}
@@ -844,7 +853,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
if (needOpenFile && !archiveIsOpened || res != S_OK)
{
- UString m = L"Error";
+ UString m ("Error");
if (res == S_FALSE || res == S_OK)
{
m = MyFormatNew(encrypted ?
diff --git a/CPP/7zip/UI/FileManager/FM.dsp b/CPP/7zip/UI/FileManager/FM.dsp
index f18e5441..3b2fb2e3 100644
--- a/CPP/7zip/UI/FileManager/FM.dsp
+++ b/CPP/7zip/UI/FileManager/FM.dsp
@@ -45,7 +45,7 @@ RSC=rc.exe
# 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 "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /D "NEW_FOLDER_INTERFACE" /D "EXTERNAL_CODECS" /D "SUPPORT_DEVICE_FILE" /FAs /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /D "NEW_FOLDER_INTERFACE" /D "EXTERNAL_CODECS" /D "SUPPORT_DEVICE_FILE" /FAcs /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"
diff --git a/CPP/7zip/UI/FileManager/FSDrives.cpp b/CPP/7zip/UI/FileManager/FSDrives.cpp
index dd4ba724..208cea4e 100644
--- a/CPP/7zip/UI/FileManager/FSDrives.cpp
+++ b/CPP/7zip/UI/FileManager/FSDrives.cpp
@@ -28,12 +28,14 @@ using namespace NWindows;
using namespace NFile;
using namespace NFind;
-static const CFSTR kVolPrefix = FTEXT("\\\\.\\");
-static const CFSTR kSuperPrefix = FTEXT("\\\\?\\");
+static const char * const kVolPrefix = "\\\\.\\";
+static const char * const kSuperPrefix = "\\\\?\\";
FString CDriveInfo::GetDeviceFileIoName() const
{
- return kVolPrefix + Name;
+ FString f (kVolPrefix);
+ f += Name;
+ return f;
}
struct CPhysTempBuffer
@@ -179,11 +181,10 @@ STDMETHODIMP CFSDrives::LoadItems()
// we must use IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
for (unsigned n = 0; n < 16; n++) // why 16 ?
{
- FChar temp[16];
- ConvertUInt32ToString(n, temp);
- FString name = FTEXT("PhysicalDrive");
- name += temp;
- FString fullPath = kVolPrefix;
+ FString name ("PhysicalDrive");
+ name.Add_UInt32(n);
+
+ FString fullPath (kVolPrefix);
fullPath += name;
CFileInfo fi;
@@ -336,7 +337,7 @@ STDMETHODIMP CFSDrives::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)
void CFSDrives::AddExt(FString &s, unsigned index) const
{
- s += FTEXT('.');
+ s += '.';
const CDriveInfo &di = _drives[index];
const char *ext;
if (di.DriveType == DRIVE_CDROM)
@@ -347,7 +348,7 @@ void CFSDrives::AddExt(FString &s, unsigned index) const
ext = "fat";
else
ext = "img";
- s.AddAscii(ext);
+ s += ext;
}
HRESULT CFSDrives::GetFileSize(unsigned index, UInt64 &fileSize) const
diff --git a/CPP/7zip/UI/FileManager/FSFolder.cpp b/CPP/7zip/UI/FileManager/FSFolder.cpp
index e46afb9e..94cd04cb 100644
--- a/CPP/7zip/UI/FileManager/FSFolder.cpp
+++ b/CPP/7zip/UI/FileManager/FSFolder.cpp
@@ -73,6 +73,8 @@ HRESULT CFSFolder::Init(const FString &path /* , IFolderFolder *parentFolder */)
// _parentFolder = parentFolder;
_path = path;
+ #ifdef _WIN32
+
_findChangeNotification.FindFirst(_path, false,
FILE_NOTIFY_CHANGE_FILE_NAME
| FILE_NOTIFY_CHANGE_DIR_NAME
@@ -85,17 +87,24 @@ HRESULT CFSFolder::Init(const FString &path /* , IFolderFolder *parentFolder */)
| FILE_NOTIFY_CHANGE_SECURITY
*/
);
+
if (!_findChangeNotification.IsHandleAllocated())
{
DWORD lastError = GetLastError();
CFindFile findFile;
CFileInfo fi;
- if (!findFile.FindFirst(_path + FCHAR_ANY_MASK, fi))
+ FString path2 = _path;
+ path2 += '*'; // CHAR_ANY_MASK;
+ if (!findFile.FindFirst(path2, fi))
return lastError;
}
+
+ #endif
+
return S_OK;
}
+
HRESULT CFsFolderStat::Enumerate()
{
if (Progress)
@@ -103,9 +112,9 @@ HRESULT CFsFolderStat::Enumerate()
RINOK(Progress->SetCompleted(NULL));
}
Path.Add_PathSepar();
- unsigned len = Path.Len();
- Path += FCHAR_ANY_MASK;
- CEnumerator enumerator(Path);
+ const unsigned len = Path.Len();
+ CEnumerator enumerator;
+ enumerator.SetDirPrefix(Path);
CFileInfo fi;
while (enumerator.Next(fi))
{
@@ -164,7 +173,8 @@ HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix)
{
unsigned startIndex = Folders.Size();
{
- CEnumerator enumerator(_path + relPrefix + FCHAR_ANY_MASK);
+ CEnumerator enumerator;
+ enumerator.SetDirPrefix(_path + relPrefix);
CDirItem fi;
fi.FolderStat_Defined = false;
fi.NumFolders = 0;
@@ -267,7 +277,7 @@ STDMETHODIMP CFSFolder::LoadItems()
return S_OK;
}
-static CFSTR kDescriptionFileName = FTEXT("descript.ion");
+static CFSTR const kDescriptionFileName = FTEXT("descript.ion");
bool CFSFolder::LoadComments()
{
@@ -389,6 +399,7 @@ bool CFSFolder::ReadFileInfo(CDirItem &di)
{
di.FileInfo_WasRequested = true;
BY_HANDLE_FILE_INFORMATION info;
+ memset(&info, 0, sizeof(info)); // for vc6-O2
if (!NIO::CFileBase::GetFileInformation(_path + GetRelPath(di), &info))
return false;
di.NumLinks = info.nNumberOfLinks;
@@ -744,8 +755,6 @@ STDMETHODIMP CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **result
return BindToFolderSpec(us2fs(name), resultFolder);
}
-static const CFSTR kSuperPrefix = FTEXT("\\\\?\\");
-
STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
{
*resultFolder = 0;
@@ -759,43 +768,39 @@ STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
*/
if (_path.IsEmpty())
return E_INVALIDARG;
- int pos = _path.ReverseFind_PathSepar();
- if (pos < 0 || pos != (int)_path.Len() - 1)
- return E_FAIL;
- FString parentPath = _path.Left(pos);
- pos = parentPath.ReverseFind_PathSepar();
- if (pos < 0)
+
+ #ifndef UNDER_CE
+
+ if (IsDriveRootPath_SuperAllowed(_path))
{
- #ifdef UNDER_CE
- *resultFolder = 0;
- #else
CFSDrives *drivesFolderSpec = new CFSDrives;
CMyComPtr<IFolderFolder> drivesFolder = drivesFolderSpec;
- drivesFolderSpec->Init();
+ drivesFolderSpec->Init(false, IsSuperPath(_path));
*resultFolder = drivesFolder.Detach();
- #endif
return S_OK;
}
- /*
+ int pos = _path.ReverseFind_PathSepar();
+ if (pos < 0 || pos != (int)_path.Len() - 1)
+ return E_FAIL;
+ FString parentPath = _path.Left(pos);
+ pos = parentPath.ReverseFind_PathSepar();
parentPath.DeleteFrom(pos + 1);
-
- if (parentPath == kSuperPrefix)
+
+ if (NName::IsDrivePath_SuperAllowed(parentPath))
{
- #ifdef UNDER_CE
- *resultFolder = 0;
- #else
- CFSDrives *drivesFolderSpec = new CFSDrives;
- CMyComPtr<IFolderFolder> drivesFolder = drivesFolderSpec;
- drivesFolderSpec->Init(false, true);
- *resultFolder = drivesFolder.Detach();
- #endif
- return S_OK;
+ CFSFolder *parentFolderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
+ if (parentFolderSpec->Init(parentPath) == S_OK)
+ {
+ *resultFolder = parentFolder.Detach();
+ return S_OK;
+ }
}
-
+
+ /*
FString parentPathReduced = parentPath.Left(pos);
- #ifndef UNDER_CE
pos = parentPathReduced.ReverseFind_PathSepar();
if (pos == 1)
{
@@ -807,13 +812,10 @@ STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
*resultFolder = netFolder.Detach();
return S_OK;
}
- #endif
-
- CFSFolder *parentFolderSpec = new CFSFolder;
- CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
- RINOK(parentFolderSpec->Init(parentPath, 0));
- *resultFolder = parentFolder.Detach();
*/
+
+ #endif
+
return S_OK;
}
@@ -844,24 +846,22 @@ STDMETHODIMP CFSFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
STDMETHODIMP CFSFolder::WasChanged(Int32 *wasChanged)
{
bool wasChangedMain = false;
+
+ #ifdef _WIN32
+
for (;;)
{
if (!_findChangeNotification.IsHandleAllocated())
- {
- *wasChanged = BoolToInt(false);
- return S_OK;
- }
-
+ break;
DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0);
- bool wasChangedLoc = (waitResult == WAIT_OBJECT_0);
- if (wasChangedLoc)
- {
- _findChangeNotification.FindNext();
- wasChangedMain = true;
- }
- else
+ if (waitResult != WAIT_OBJECT_0)
break;
+ _findChangeNotification.FindNext();
+ wasChangedMain = true;
}
+
+ #endif
+
*wasChanged = BoolToInt(wasChangedMain);
return S_OK;
}
diff --git a/CPP/7zip/UI/FileManager/FSFolder.h b/CPP/7zip/UI/FileManager/FSFolder.h
index 057ba14c..4cbace52 100644
--- a/CPP/7zip/UI/FileManager/FSFolder.h
+++ b/CPP/7zip/UI/FileManager/FSFolder.h
@@ -142,7 +142,9 @@ private:
// bool _scanAltStreams;
bool _flatMode;
+ #ifdef _WIN32
NWindows::NFile::NFind::CFindChangeNotification _findChangeNotification;
+ #endif
HRESULT GetItemsFullSize(const UInt32 *indices, UInt32 numItems, CFsFolderStat &stat);
@@ -161,7 +163,7 @@ private:
public:
HRESULT Init(const FString &path /* , IFolderFolder *parentFolder */);
#if !defined(_WIN32) || defined(UNDER_CE)
- HRESULT InitToRoot() { return Init(FSTRING_PATH_SEPARATOR /* , NULL */); }
+ HRESULT InitToRoot() { return Init((FString) FSTRING_PATH_SEPARATOR /* , NULL */); }
#endif
CFSFolder() : _flatMode(false)
diff --git a/CPP/7zip/UI/FileManager/FSFolderCopy.cpp b/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
index c91deb07..fa728b47 100644
--- a/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
+++ b/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
@@ -75,7 +75,7 @@ HRESULT CCopyStateIO::MyCopyFile(CFSTR inPath, CFSTR outPath)
}
if (written != num)
{
- ErrorMessage = L"Write error";
+ ErrorMessage = "Write error";
return S_OK;
}
CurrentSize += num;
@@ -357,7 +357,7 @@ static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
const wchar_t *message, const FString &fileName)
{
UString s = message;
- s += L" : ";
+ s += " : ";
s += fs2us(fileName);
return callback->ShowMessage(s);
}
@@ -514,7 +514,8 @@ static HRESULT CopyFolder(
return E_ABORT;
}
- CEnumerator enumerator(CombinePath(srcPath, FSTRING_ANY_MASK));
+ CEnumerator enumerator;
+ enumerator.SetDirPrefix(CombinePath(srcPath, FString()));
for (;;)
{
diff --git a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
index dc46ff5b..4e964628 100644
--- a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
+++ b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
@@ -68,7 +68,7 @@ static void SplitNameToPureNameAndExtension(const FString &fullName,
else
{
pureName.SetFrom(fullName, index);
- extensionDelimiter = FTEXT('.');
+ extensionDelimiter = '.';
extension = fullName.Ptr(index + 1);
}
}
@@ -151,7 +151,7 @@ HRESULT OpenFileFolderPlugin(
UString progressTitle = LangString(IDS_OPENNING);
t.OpenCallbackSpec->ProgressDialog.MainWindow = parentWindow;
- t.OpenCallbackSpec->ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE);
+ t.OpenCallbackSpec->ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
t.OpenCallbackSpec->ProgressDialog.MainAddTitle = progressTitle + L' ';
t.OpenCallbackSpec->ProgressDialog.WaitMode = true;
diff --git a/CPP/7zip/UI/FileManager/FoldersPage.cpp b/CPP/7zip/UI/FileManager/FoldersPage.cpp
index 42662153..d019bab8 100644
--- a/CPP/7zip/UI/FileManager/FoldersPage.cpp
+++ b/CPP/7zip/UI/FileManager/FoldersPage.cpp
@@ -27,6 +27,8 @@ static const int kWorkModeButtons[] =
IDR_FOLDERS_WORK_SPECIFIED
};
+#define kFoldersTopic "fm/options.htm#folders"
+
static const unsigned kNumWorkModeButtons = ARRAY_SIZE(kWorkModeButtons);
bool CFoldersPage::OnInit()
@@ -158,9 +160,7 @@ LONG CFoldersPage::OnApply()
return PSNRET_NOERROR;
}
-static LPCWSTR kFoldersTopic = L"fm/options.htm#folders";
-
void CFoldersPage::OnNotifyHelp()
{
- ShowHelpWindow(NULL, kFoldersTopic);
+ ShowHelpWindow(kFoldersTopic);
}
diff --git a/CPP/7zip/UI/FileManager/HelpUtils.cpp b/CPP/7zip/UI/FileManager/HelpUtils.cpp
index bae2365e..c0f57990 100644
--- a/CPP/7zip/UI/FileManager/HelpUtils.cpp
+++ b/CPP/7zip/UI/FileManager/HelpUtils.cpp
@@ -6,7 +6,7 @@
#if defined(UNDER_CE) || !defined(_WIN32)
-void ShowHelpWindow(HWND, LPCWSTR)
+void ShowHelpWindow(LPCSTR)
{
}
@@ -18,12 +18,15 @@ void ShowHelpWindow(HWND, LPCWSTR)
#include "../../../Windows/DLL.h"
-static LPCWSTR kHelpFileName = L"7-zip.chm::/";
+#define kHelpFileName "7-zip.chm::/"
-void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile)
+void ShowHelpWindow(LPCSTR topicFile)
{
FString path = NWindows::NDLL::GetModuleDirPrefix();
- HtmlHelp(hwnd, GetSystemString(fs2us(path) + kHelpFileName + topicFile), HH_DISPLAY_TOPIC, 0);
+ path += kHelpFileName;
+ path += topicFile;
+ // HWND hwnd = NULL;
+ HtmlHelp(NULL, GetSystemString(fs2us(path)), HH_DISPLAY_TOPIC, 0);
}
#endif
diff --git a/CPP/7zip/UI/FileManager/HelpUtils.h b/CPP/7zip/UI/FileManager/HelpUtils.h
index 52b1418a..90c5f7d1 100644
--- a/CPP/7zip/UI/FileManager/HelpUtils.h
+++ b/CPP/7zip/UI/FileManager/HelpUtils.h
@@ -5,6 +5,6 @@
#include "../../../Common/MyString.h"
-void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile);
+void ShowHelpWindow(LPCSTR topicFile);
#endif
diff --git a/CPP/7zip/UI/FileManager/LangPage.cpp b/CPP/7zip/UI/FileManager/LangPage.cpp
index cb1bbaab..47e7894c 100644
--- a/CPP/7zip/UI/FileManager/LangPage.cpp
+++ b/CPP/7zip/UI/FileManager/LangPage.cpp
@@ -20,13 +20,13 @@ static const UInt32 kLangIDs[] =
IDT_LANG_LANG
};
-static LPCWSTR kLangTopic = L"fm/options.htm#language";
+#define kLangTopic "fm/options.htm#language"
static void NativeLangString(UString &dest, const wchar_t *s)
{
- dest += L" (";
+ dest += " (";
dest += s;
- dest += L')';
+ dest += ')';
}
bool LangOpen(CLang &lang, CFSTR fileName);
@@ -45,7 +45,8 @@ bool CLangPage::OnInit()
_langCombo.SetCurSel(0);
const FString dirPrefix = GetLangDirPrefix();
- NFile::NFind::CEnumerator enumerator(dirPrefix + FTEXT("*.txt"));
+ NFile::NFind::CEnumerator enumerator;
+ enumerator.SetDirPrefix(dirPrefix);
NFile::NFind::CFileInfo fi;
CLang lang;
UString error;
@@ -54,12 +55,15 @@ bool CLangPage::OnInit()
{
if (fi.IsDir())
continue;
- const int kExtSize = 4;
+ const unsigned kExtSize = 4;
if (fi.Name.Len() < kExtSize)
continue;
- unsigned pos = fi.Name.Len() - kExtSize;
+ const unsigned pos = fi.Name.Len() - kExtSize;
if (!StringsAreEqualNoCase_Ascii(fi.Name.Ptr(pos), ".txt"))
+ {
+ // if (!StringsAreEqualNoCase_Ascii(fi.Name.Ptr(pos), ".ttt"))
continue;
+ }
if (!LangOpen(lang, dirPrefix + fi.Name))
{
@@ -101,7 +105,7 @@ LONG CLangPage::OnApply()
void CLangPage::OnNotifyHelp()
{
- ShowHelpWindow(NULL, kLangTopic);
+ ShowHelpWindow(kLangTopic);
}
bool CLangPage::OnCommand(int code, int itemID, LPARAM param)
diff --git a/CPP/7zip/UI/FileManager/LangUtils.cpp b/CPP/7zip/UI/FileManager/LangUtils.cpp
index 761319b5..94e9ecba 100644
--- a/CPP/7zip/UI/FileManager/LangUtils.cpp
+++ b/CPP/7zip/UI/FileManager/LangUtils.cpp
@@ -25,7 +25,7 @@ static NSynchronization::CCriticalSection g_CriticalSection;
bool LangOpen(CLang &lang, CFSTR fileName)
{
- return lang.Open(fileName, L"7-Zip");
+ return lang.Open(fileName, "7-Zip");
}
FString GetLangDirPrefix()
@@ -94,7 +94,7 @@ void LangSetDlgItems_Colon(HWND dialog, const UInt32 *ids, unsigned numItems)
{
CWindow window(GetDlgItem(dialog, id));
UString s2 = s;
- s2 += L':';
+ s2 += ':';
window.SetText(s2);
}
}
@@ -139,7 +139,7 @@ void LangString_OnlyFromLangFile(UInt32 langID, UString &dest)
dest = s;
}
-static const char *kLangs =
+static const char * const kLangs =
"ar.bg.ca.zh.-tw.-cn.cs.da.de.el.en.es.fi.fr.he.hu.is."
"it.ja.ko.nl.no.=nb.=nn.pl.pt.-br.rm.ro.ru.sr.=hr.-spl.-spc.sk.sq.sv.th.tr."
"ur.id.uk.be.sl.et.lv.lt.tg.fa.vi.hy.az.eu.hsb.mk."
@@ -153,7 +153,7 @@ static const char *kLangs =
// ".gd."
;
-static void FindShortNames(UInt32 primeLang, UStringVector &names)
+static void FindShortNames(UInt32 primeLang, AStringVector &names)
{
UInt32 index = 0;
for (const char *p = kLangs; *p != 0;)
@@ -167,7 +167,7 @@ static void FindShortNames(UInt32 primeLang, UStringVector &names)
{
if (index > primeLang)
break;
- UString s;
+ AString s;
if (isSub)
{
if (p[0] == '-')
@@ -176,7 +176,7 @@ static void FindShortNames(UInt32 primeLang, UStringVector &names)
p++;
}
while (p != p2)
- s += (wchar_t)(Byte)*p++;
+ s += (char)(Byte)*p++;
names.Add(s);
}
p = p2 + 1;
@@ -195,7 +195,7 @@ static struct CC1Lang
UString s;
char ttt[32];
ConvertUInt32ToHex(i, ttt);
- s.AddAscii(ttt);
+ s += ttt;
UStringVector names;
FindShortNames(i, names);
@@ -238,18 +238,21 @@ static void OpenDefaultLang()
WORD primLang = (WORD)(PRIMARYLANGID(langID));
WORD subLang = (WORD)(SUBLANGID(langID));
{
- UStringVector names;
+ AStringVector names;
FindShortNames(primLang, names);
- const FString dirPrefix = GetLangDirPrefix();
+ const FString dirPrefix (GetLangDirPrefix());
for (unsigned i = 0; i < 2; i++)
{
unsigned index = (i == 0 ? subLang : 0);
if (index < names.Size())
{
- const UString &name = names[index];
+ const AString &name = names[index];
if (!name.IsEmpty())
{
- if (LangOpen(g_Lang, dirPrefix + us2fs(name) + FTEXT(".txt")))
+ FString path (dirPrefix);
+ path += name;
+ path += ".txt";
+ if (LangOpen(g_Lang, path))
{
g_LangID = name;
return;
@@ -280,7 +283,7 @@ void ReloadLang()
if (s.Find(FCHAR_PATH_SEPARATOR) < 0)
{
if (s.Find(FTEXT('.')) < 0)
- s += FTEXT(".txt");
+ s += ".txt";
s.Insert(0, GetLangDirPrefix());
}
LangOpen(g_Lang, s);
diff --git a/CPP/7zip/UI/FileManager/LinkDialog.cpp b/CPP/7zip/UI/FileManager/LinkDialog.cpp
index 2ef2da5b..ba21c0c7 100644
--- a/CPP/7zip/UI/FileManager/LinkDialog.cpp
+++ b/CPP/7zip/UI/FileManager/LinkDialog.cpp
@@ -108,11 +108,11 @@ bool CLinkDialog::OnInit()
UString s = attr.PrintName;
if (!attr.IsOkNamePair())
{
- s += L" : ";
+ s += " : ";
s += attr.SubsName;
}
if (!res)
- s = L"ERROR: " + s;
+ s.Insert(0, L"ERROR: ");
SetItemText(IDT_LINK_PATH_TO_CUR, s);
@@ -214,7 +214,7 @@ void CLinkDialog::OnButton_SetPath(bool to)
_pathToCombo :
_pathFromCombo;
combo.GetText(currentPath);
- // UString title = L"Specify a location for output folder";
+ // UString title = "Specify a location for output folder";
UString title = LangString(IDS_SET_FOLDER);
UString resultPath;
diff --git a/CPP/7zip/UI/FileManager/MenuPage.cpp b/CPP/7zip/UI/FileManager/MenuPage.cpp
index 8852ce35..4067ad75 100644
--- a/CPP/7zip/UI/FileManager/MenuPage.cpp
+++ b/CPP/7zip/UI/FileManager/MenuPage.cpp
@@ -35,7 +35,7 @@ static const UInt32 kLangIDs[] =
IDT_SYSTEM_CONTEXT_MENU_ITEMS
};
-static LPCWSTR kSystemTopic = L"fm/options.htm#sevenZip";
+#define kMenuTopic "fm/options.htm#sevenZip"
struct CContextMenuItem
{
@@ -71,6 +71,13 @@ static const CContextMenuItem kMenuItems[] =
extern bool g_Is_Wow64;
#endif
+#ifndef KEY_WOW64_64KEY
+ #define KEY_WOW64_64KEY (0x0100)
+#endif
+
+#ifndef KEY_WOW64_32KEY
+ #define KEY_WOW64_32KEY (0x0200)
+#endif
bool CMenuPage::OnInit()
{
@@ -95,14 +102,14 @@ bool CMenuPage::OnInit()
}
UString bit64 = LangString(IDS_PROP_BIT64);
if (bit64.IsEmpty())
- bit64.SetFromAscii("64-bit");
+ bit64 = "64-bit";
#ifdef _WIN64
bit64.Replace(L"64", L"32");
#endif
s.Add_Space();
- s += L'(';
+ s += '(';
s += bit64;
- s += L')';
+ s += ')';
SetItemText(IDX_SYSTEM_INTEGRATE_TO_MENU_2, s);
}
@@ -136,7 +143,7 @@ bool CMenuPage::OnInit()
FString &path = dll.Path;
path = prefix;
- path.AddAscii(d == 0 ? "7-zip.dll" :
+ path += (d == 0 ? "7-zip.dll" :
#ifdef _WIN64
"7-zip32.dll"
#else
@@ -180,10 +187,10 @@ bool CMenuPage::OnInit()
UString s = LangString(menuItem.ControlID);
if (menuItem.Flag == kCRC)
- s.SetFromAscii("CRC SHA");
+ s = "CRC SHA";
if (menuItem.Flag == kOpenAs ||
menuItem.Flag == kCRC)
- s.AddAscii(" >");
+ s += " >";
switch (menuItem.ControlID)
{
@@ -200,11 +207,11 @@ bool CMenuPage::OnInit()
{
case kCompressTo7z:
case kCompressTo7zEmail:
- s2.AddAscii(".7z");
+ s2 += (".7z");
break;
case kCompressToZip:
case kCompressToZipEmail:
- s2.AddAscii(".zip");
+ s2 += (".zip");
break;
}
s = MyFormatNew(s, s2);
@@ -286,7 +293,7 @@ LONG CMenuPage::OnApply()
void CMenuPage::OnNotifyHelp()
{
- ShowHelpWindow(NULL, kSystemTopic);
+ ShowHelpWindow(kMenuTopic);
}
bool CMenuPage::OnButtonClicked(int buttonID, HWND buttonHWND)
diff --git a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
index d3031f5a..50104950 100644
--- a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
+++ b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
@@ -3,6 +3,7 @@
#include "StdAfx.h"
#include "../../../Windows/Menu.h"
+#include "../../../Windows/TimeUtils.h"
#include "../../../Windows/Control/Dialog.h"
#include "../../PropID.h"
@@ -22,10 +23,12 @@ using namespace NWindows;
static const UINT kOpenBookmarkMenuID = 830;
static const UINT kSetBookmarkMenuID = 810;
+static const UINT kMenuID_Time_Parent = 760;
+static const UINT kMenuID_Time = 761;
extern HINSTANCE g_hInstance;
-static LPCWSTR kFMHelpTopic = L"FM/index.htm";
+#define kFMHelpTopic "FM/index.htm"
extern void OptionsDialog(HWND hwndOwner, HINSTANCE hInstance);
@@ -115,10 +118,12 @@ static UINT Get_fMask_for_FType_and_String()
static inline UINT Get_fMask_for_String() { return MIIM_TYPE; }
static inline UINT Get_fMask_for_FType_and_String() { return MIIM_TYPE; }
+
static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex)
{
CMenu menu;
menu.Attach(menuLoc);
+
for (int i = 0;; i++)
{
CMenuItem item;
@@ -137,7 +142,12 @@ static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex)
{
MyChangeMenu(item.hSubMenu, level + 1, i);
if (level == 1 && menuIndex == kMenuIndex_View)
- langID = kToolbarsLangID;
+ {
+ if (item.wID == kMenuID_Time_Parent || item.StringValue.IsPrefixedBy_Ascii_NoCase("20"))
+ continue;
+ else
+ langID = kToolbarsLangID;
+ }
else if (level == 0 && i < ARRAY_SIZE(kTopMenuLangIDs))
langID = kTopMenuLangIDs[i];
else
@@ -168,7 +178,18 @@ static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex)
int tabPos = newString.Find(L"\t");
if (tabPos >= 0)
newString.DeleteFrom(tabPos);
- newString += (langID == IDM_OPEN_INSIDE_ONE ? L" *" : L" #");
+ newString += (langID == IDM_OPEN_INSIDE_ONE ? " *" : " #");
+ }
+ else if (langID == IDM_BENCHMARK2)
+ {
+ LangString_OnlyFromLangFile(IDM_BENCHMARK, newString);
+ if (newString.IsEmpty())
+ continue;
+ newString.Replace(L"&", L"");
+ int tabPos = newString.Find(L"\t");
+ if (tabPos >= 0)
+ newString.DeleteFrom(tabPos);
+ newString += " 2";
}
else
LangString_OnlyFromLangFile(langID, newString);
@@ -245,6 +266,8 @@ void MyLoadMenu()
::DestroyMenu(oldMenu);
/* BOOL b = */ g_App._commandBar.InsertMenubar(g_hInstance, IDM_MENU, 0);
baseMenu = g_App._commandBar.GetMenu(0);
+ // if (startInit)
+ // SetIdsForSubMenes(baseMenu, 0, 0);
if (!g_LangID.IsEmpty())
MyChangeMenu(baseMenu, 0, 0);
g_App._commandBar.DrawMenuBar(0);
@@ -256,6 +279,8 @@ void MyLoadMenu()
::SetMenu(hWnd, ::LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_MENU)));
::DestroyMenu(oldMenu);
baseMenu = ::GetMenu(hWnd);
+ // if (startInit)
+ // SetIdsForSubMenes(baseMenu, 0, 0);
if (!g_LangID.IsEmpty())
MyChangeMenu(baseMenu, 0, 0);
::DrawMenuBar(hWnd);
@@ -277,8 +302,10 @@ void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
::GetMenu(g_HWND)
#endif
;
+
if (::GetSubMenu(mainMenu, position) != hMenu)
return;
+
if (position == kMenuIndex_File)
{
CMenu menu;
@@ -316,6 +343,72 @@ void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
menu.CheckItemByID(IDM_VIEW_AUTO_REFRESH, g_App.Get_AutoRefresh_Mode());
// menu.CheckItemByID(IDM_VIEW_SHOW_STREAMS, g_App.Get_ShowNtfsStrems_Mode());
// menu.CheckItemByID(IDM_VIEW_SHOW_DELETED, g_App.ShowDeletedFiles);
+
+ for (int i = 0;; i++)
+ {
+ CMenuItem item;
+ item.fMask = Get_fMask_for_String() | MIIM_SUBMENU | MIIM_ID;
+ item.fType = MFT_STRING;
+ if (!menu.GetItem(i, true, item))
+ break;
+ if (item.hSubMenu && (item.wID == kMenuID_Time_Parent
+ || item.StringValue.IsPrefixedBy_Ascii_NoCase("20")
+ ))
+ {
+ FILETIME ft;
+ NTime::GetCurUtcFileTime(ft);
+
+ {
+ wchar_t s[64];
+ s[0] = 0;
+ if (ConvertUtcFileTimeToString(ft, s, kTimestampPrintLevel_DAY))
+ item.StringValue = s;
+ }
+
+ item.fMask = Get_fMask_for_String() | MIIM_ID;
+ item.fType = MFT_STRING;
+ item.wID = kMenuID_Time_Parent;
+ menu.SetItem(i, true, item);
+
+ CMenu subMenu;
+ subMenu.Attach(menu.GetSubMenu(i));
+ subMenu.RemoveAllItems();
+
+ const int k_TimeLevels[] =
+ {
+ kTimestampPrintLevel_DAY,
+ kTimestampPrintLevel_MIN,
+ kTimestampPrintLevel_SEC,
+ // 1,2,3,4,5,6,
+ kTimestampPrintLevel_NTFS
+ };
+
+ unsigned last = kMenuID_Time;
+ unsigned selectedCommand = 0;
+ g_App._timestampLevels.Clear();
+ unsigned id = kMenuID_Time;
+
+ for (unsigned k = 0; k < ARRAY_SIZE(k_TimeLevels); k++)
+ {
+ wchar_t s[64];
+ s[0] = 0;
+ int timestampLevel = k_TimeLevels[k];
+ if (ConvertUtcFileTimeToString(ft, s, timestampLevel))
+ {
+ if (subMenu.AppendItem(MF_STRING, id, s))
+ {
+ last = id;
+ g_App._timestampLevels.Add(timestampLevel);
+ if (g_App.GetTimestampLevel() == timestampLevel)
+ selectedCommand = id;
+ id++;
+ }
+ }
+ }
+ if (selectedCommand != 0)
+ menu.CheckRadioItem(kMenuID_Time, last, selectedCommand, MF_BYCOMMAND);
+ }
+ }
}
else if (position == kMenuIndex_Bookmarks)
{
@@ -331,9 +424,9 @@ void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
{
UString s = LangString(IDS_BOOKMARK);
s.Add_Space();
- wchar_t c = (wchar_t)(L'0' + i);
+ char c = (char)(L'0' + i);
s += c;
- s.AddAscii("\tAlt+Shift+");
+ s += "\tAlt+Shift+";
s += c;
subMenu.AppendItem(MF_STRING, kSetBookmarkMenuID + i, s);
}
@@ -351,9 +444,9 @@ void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
s.Insert(kFirstPartSize, L" ... ");
}
if (s.IsEmpty())
- s = L'-';
- s.AddAscii("\tAlt+");
- s += (wchar_t)(L'0' + i);
+ s = '-';
+ s += "\tAlt+";
+ s += (char)('0' + i);
menu.AppendItem(MF_STRING, kOpenBookmarkMenuID + i, s);
}
}
@@ -398,6 +491,15 @@ void CFileMenu::Load(HMENU hMenu, unsigned startPos)
if (item.wID == IDM_OPEN_INSIDE_ONE || item.wID == IDM_OPEN_INSIDE_PARSER)
{
// We use diff as "super mode" marker for additional commands.
+ /*
+ if (diffPath.IsEmpty())
+ continue;
+ */
+ }
+
+ if (item.wID == IDM_BENCHMARK2)
+ {
+ // We use diff as "super mode" marker for additional commands.
if (diffPath.IsEmpty())
continue;
}
@@ -473,11 +575,11 @@ bool ExecuteFileCommand(int id)
case IDM_MOVE_TO: g_App.MoveTo(); break;
case IDM_DELETE: g_App.Delete(!IsKeyDown(VK_SHIFT)); break;
- case IDM_HASH_ALL: g_App.CalculateCrc(L"*"); break;
- case IDM_CRC32: g_App.CalculateCrc(L"CRC32"); break;
- case IDM_CRC64: g_App.CalculateCrc(L"CRC64"); break;
- case IDM_SHA1: g_App.CalculateCrc(L"SHA1"); break;
- case IDM_SHA256: g_App.CalculateCrc(L"SHA256"); break;
+ case IDM_HASH_ALL: g_App.CalculateCrc("*"); break;
+ case IDM_CRC32: g_App.CalculateCrc("CRC32"); break;
+ case IDM_CRC64: g_App.CalculateCrc("CRC64"); break;
+ case IDM_SHA1: g_App.CalculateCrc("SHA1"); break;
+ case IDM_SHA256: g_App.CalculateCrc("SHA256"); break;
case IDM_DIFF: g_App.DiffFiles(); break;
case IDM_SPLIT: g_App.Split(); break;
@@ -614,7 +716,7 @@ bool OnMenuCommand(HWND hWnd, int id)
// Help
case IDM_HELP_CONTENTS:
- ShowHelpWindow(NULL, kFMHelpTopic);
+ ShowHelpWindow(kFMHelpTopic);
break;
case IDM_ABOUT:
{
@@ -634,6 +736,12 @@ bool OnMenuCommand(HWND hWnd, int id)
g_App.SetBookmark(id - kSetBookmarkMenuID);
return true;
}
+ else if (id >= kMenuID_Time && (unsigned)id <= kMenuID_Time + g_App._timestampLevels.Size())
+ {
+ unsigned index = id - kMenuID_Time;
+ g_App.SetTimestampLevel(g_App._timestampLevels[index]);
+ return true;
+ }
return false;
}
}
diff --git a/CPP/7zip/UI/FileManager/NetFolder.cpp b/CPP/7zip/UI/FileManager/NetFolder.cpp
index 112f8c06..a941e73d 100644
--- a/CPP/7zip/UI/FileManager/NetFolder.cpp
+++ b/CPP/7zip/UI/FileManager/NetFolder.cpp
@@ -232,7 +232,7 @@ STDMETHODIMP CNetFolder::BindToParentFolder(IFolderFolder **resultFolder)
CNetFolder *netFolder = new CNetFolder;
CMyComPtr<IFolderFolder> subFolder = netFolder;
- netFolder->Init(&resourceParent, 0, WCHAR_PATH_SEPARATOR);
+ netFolder->Init(&resourceParent, 0, WSTRING_PATH_SEPARATOR);
*resultFolder = subFolder.Detach();
}
return S_OK;
diff --git a/CPP/7zip/UI/FileManager/OpenCallback.cpp b/CPP/7zip/UI/FileManager/OpenCallback.cpp
index 331b171b..bf7abfb7 100644
--- a/CPP/7zip/UI/FileManager/OpenCallback.cpp
+++ b/CPP/7zip/UI/FileManager/OpenCallback.cpp
@@ -22,10 +22,10 @@ STDMETHODIMP COpenArchiveCallback::SetTotal(const UInt64 *numFiles, const UInt64
RINOK(ProgressDialog.Sync.CheckStop());
{
// NSynchronization::CCriticalSectionLock lock(_criticalSection);
- if (numFiles)
+ ProgressDialog.Sync.Set_NumFilesTotal(numFiles ? *numFiles : (UInt64)(Int64)-1);
+ // if (numFiles)
{
- ProgressDialog.Sync.Set_NumFilesTotal(*numFiles);
- ProgressDialog.Sync.Set_BytesProgressMode(false);
+ ProgressDialog.Sync.Set_BytesProgressMode(numFiles == NULL);
}
if (numBytes)
ProgressDialog.Sync.Set_NumBytesTotal(*numBytes);
diff --git a/CPP/7zip/UI/FileManager/OverwriteDialog.cpp b/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
index c6feb902..1c029132 100644
--- a/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
+++ b/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
@@ -40,6 +40,12 @@ void COverwriteDialog::ReduceString(UString &s)
s.Delete(size / 2, s.Len() - size);
s.Insert(size / 2, L" ... ");
}
+ if (!s.IsEmpty() && s.Back() == ' ')
+ {
+ // s += (wchar_t)(0x2423);
+ s.InsertAtFront(L'\"');
+ s += L'\"';
+ }
}
void COverwriteDialog::SetFileInfoControl(int textID, int iconID,
@@ -66,13 +72,10 @@ void COverwriteDialog::SetFileInfoControl(int textID, int iconID,
if (fileInfo.TimeIsDefined)
{
- FILETIME localFileTime;
- if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime))
- throw 4190402;
AddLangString(s, IDS_PROP_MTIME);
- s += L": ";
- wchar_t t[32];
- ConvertFileTimeToString(localFileTime, t);
+ s += ": ";
+ char t[32];
+ ConvertUtcFileTimeToString(fileInfo.Time, t);
s += t;
}
diff --git a/CPP/7zip/UI/FileManager/Panel.cpp b/CPP/7zip/UI/FileManager/Panel.cpp
index 5e3ec8ef..6a067acb 100644
--- a/CPP/7zip/UI/FileManager/Panel.cpp
+++ b/CPP/7zip/UI/FileManager/Panel.cpp
@@ -68,7 +68,7 @@ HWND CPanel::GetParent()
return (h == 0) ? _mainWindow : h;
}
-static LPCWSTR kClassName = L"7-Zip::Panel";
+#define kClassName L"7-Zip::Panel"
HRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
@@ -933,7 +933,7 @@ void CPanel::ExtractArchives()
if (indices.Size() == 1)
outFolder += GetSubFolderNameForExtract2(GetItemRelPath(indices[0]));
else
- outFolder += L'*';
+ outFolder += '*';
outFolder.Add_PathSepar();
::ExtractArchives(paths, outFolder
@@ -947,9 +947,9 @@ static void AddValuePair(UINT resourceID, UInt64 value, UString &s)
{
AddLangString(s, resourceID);
char sz[32];
- s += L": ";
+ s += ": ";
ConvertUInt64ToString(value, sz);
- s.AddAsciiStr(sz);
+ s += sz;
s.Add_LF();
}
*/
@@ -999,11 +999,11 @@ static void AddSizePair(UInt32 langID, UInt64 value, UString &s)
AddLangString(s, langID);
s += L' ';
ConvertUInt64ToString(value, sz);
- s.AddAsciiStr(sz);
+ s += sz;
ConvertUInt64ToString(value >> 20, sz);
- s.AddAsciiStr(" (");
- s.AddAsciiStr(sz);
- s.AddAsciiStr(" MB)");
+ s += " (";
+ s += sz;
+ s += " MB)";
s.Add_LF();
}
*/
@@ -1051,11 +1051,10 @@ void CPanel::TestArchives()
extracter.Indices = indices;
UString title = LangString(IDS_PROGRESS_TESTING);
- UString progressWindowTitle = L"7-Zip"; // LangString(IDS_APP_TITLE);
extracter.ProgressDialog.CompressingMode = false;
extracter.ProgressDialog.MainWindow = GetParent();
- extracter.ProgressDialog.MainTitle = progressWindowTitle;
+ extracter.ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
extracter.ProgressDialog.MainAddTitle = title + L' ';
extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
diff --git a/CPP/7zip/UI/FileManager/Panel.h b/CPP/7zip/UI/FileManager/Panel.h
index 0110ee9d..6402ec2c 100644
--- a/CPP/7zip/UI/FileManager/Panel.h
+++ b/CPP/7zip/UI/FileManager/Panel.h
@@ -17,6 +17,7 @@
#include "../../../Windows/FileFind.h"
#include "../../../Windows/FileName.h"
#include "../../../Windows/Handle.h"
+#include "../../../Windows/PropVariantConv.h"
#include "../../../Windows/Synchronization.h"
#include "../../../Windows/Control/ComboBox.h"
@@ -373,6 +374,16 @@ public:
// CUIntVector _realIndices;
bool _enableItemChangeNotify;
bool _mySelectMode;
+
+ int _timestampLevel;
+
+
+ void RedrawListItems()
+ {
+ _listView.RedrawAllItems();
+ }
+
+
CBoolVector _selectedStatusVector;
CSelectedState _selectedState;
@@ -466,6 +477,7 @@ public:
UString GetItemRelPath(int itemIndex) const;
UString GetItemRelPath2(int itemIndex) const;
UString GetItemFullPath(int itemIndex) const;
+ UInt64 GetItem_UInt64Prop(int itemIndex, PROPID propID) const;
UInt64 GetItemSize(int itemIndex) const;
////////////////////////
@@ -487,6 +499,7 @@ public:
void CloseOpenFolders();
void OpenRootFolder();
+ UString GetParentDirPrefix() const;
HRESULT Create(HWND mainWindow, HWND parentWindow,
UINT id,
@@ -526,7 +539,9 @@ public:
_thereAreDeletedItems(false),
_markDeletedItems(true),
_enableItemChangeNotify(true),
- _dontShowMode(false)
+ _dontShowMode(false),
+
+ _timestampLevel(kTimestampPrintLevel_MIN)
{}
void SetExtendedStyle()
diff --git a/CPP/7zip/UI/FileManager/PanelCopy.cpp b/CPP/7zip/UI/FileManager/PanelCopy.cpp
index fb418963..a64b4a90 100644
--- a/CPP/7zip/UI/FileManager/PanelCopy.cpp
+++ b/CPP/7zip/UI/FileManager/PanelCopy.cpp
@@ -183,7 +183,7 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
title = LangString(titleID);
}
- UString progressWindowTitle = L"7-Zip"; // LangString(IDS_APP_TITLE);
+ UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE);
extracter.ProgressDialog.MainWindow = GetParent();
extracter.ProgressDialog.MainTitle = progressWindowTitle;
@@ -248,9 +248,12 @@ struct CThreadUpdate
}
};
+
HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStringVector &filePaths,
bool showErrorMessages, UStringVector *messages)
{
+ // CDisableNotify disableNotify(*this);
+
HRESULT res;
if (!_folderOperations)
res = E_NOINTERFACE;
@@ -265,7 +268,7 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri
updater.UpdateCallbackSpec->ProgressDialog = &updater.ProgressDialog;
UString title = LangString(IDS_COPYING);
- UString progressWindowTitle = L"7-Zip"; // LangString(IDS_APP_TITLE);
+ UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE);
updater.ProgressDialog.MainWindow = GetParent();
updater.ProgressDialog.MainTitle = progressWindowTitle;
@@ -321,10 +324,10 @@ void CPanel::CopyFromNoAsk(const UStringVector &filePaths)
CSelectedState srcSelState;
SaveSelectedState(srcSelState);
- HRESULT result = CopyFrom(false, L"", filePaths, true, 0);
-
CDisableNotify disableNotify(*this);
+ HRESULT result = CopyFrom(false, L"", filePaths, true, 0);
+
if (result != S_OK)
{
disableNotify.Restore();
@@ -345,9 +348,9 @@ void CPanel::CopyFromAsk(const UStringVector &filePaths)
{
UString title = LangString(IDS_CONFIRM_FILE_COPY);
UString message = LangString(IDS_WANT_TO_COPY_FILES);
- message += L"\n\'";
+ message += "\n\'";
message += _currentFolderPrefix;
- message += L"\' ?";
+ message += "\' ?";
int res = ::MessageBoxW(*(this), message, title, MB_YESNOCANCEL | MB_ICONQUESTION);
if (res != IDYES)
return;
diff --git a/CPP/7zip/UI/FileManager/PanelCrc.cpp b/CPP/7zip/UI/FileManager/PanelCrc.cpp
index c9697e8b..8500a9a5 100644
--- a/CPP/7zip/UI/FileManager/PanelCrc.cpp
+++ b/CPP/7zip/UI/FileManager/PanelCrc.cpp
@@ -128,14 +128,15 @@ DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &r
FString s = resPath;
s.Add_PathSepar();
Prefixes.Add(s);
- s += FCHAR_ANY_MASK;
- Enumerators.Add(NFind::CEnumerator(BasePrefix + s));
+ Enumerators.AddNew().SetDirPrefix(BasePrefix + s);
}
filled = true;
return S_OK;
}
+
+
class CThreadCrc: public CProgressThreadVirt
{
HRESULT ProcessVirt();
@@ -364,7 +365,7 @@ HRESULT CApp::CalculateCrc2(const UString &methodName)
UString title = LangString(IDS_CHECKSUM_CALCULATING);
t.ProgressDialog.MainWindow = _window;
- t.ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE);
+ t.ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
t.ProgressDialog.MainAddTitle = title;
t.ProgressDialog.MainAddTitle.Add_Space();
@@ -374,9 +375,9 @@ HRESULT CApp::CalculateCrc2(const UString &methodName)
return S_OK;
}
-void CApp::CalculateCrc(const UString &methodName)
+void CApp::CalculateCrc(const char *methodName)
{
- HRESULT res = CalculateCrc2(methodName);
+ HRESULT res = CalculateCrc2(UString(methodName));
if (res != S_OK && res != E_ABORT)
{
unsigned srcPanelIndex = GetFocusedPanelIndex();
diff --git a/CPP/7zip/UI/FileManager/PanelDrag.cpp b/CPP/7zip/UI/FileManager/PanelDrag.cpp
index ff16f24e..bdfccbb3 100644
--- a/CPP/7zip/UI/FileManager/PanelDrag.cpp
+++ b/CPP/7zip/UI/FileManager/PanelDrag.cpp
@@ -31,8 +31,9 @@ using namespace NDir;
extern bool g_IsNT;
#endif
-static CFSTR kTempDirPrefix = FTEXT("7zE");
-static LPCTSTR kSvenZipSetFolderFormat = TEXT("7-Zip::SetTargetFolder");
+#define kTempDirPrefix FTEXT("7zE")
+
+static LPCTSTR const kSvenZipSetFolderFormat = TEXT("7-Zip::SetTargetFolder");
////////////////////////////////////////////////////////
@@ -619,7 +620,10 @@ bool CDropTarget::IsItSameDrive() const
return false;
}
else if (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0)
- drive = m_SubFolderName + WCHAR_PATH_SEPARATOR;
+ {
+ drive = m_SubFolderName;
+ drive.Add_PathSepar();
+ }
else
return false;
diff --git a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
index 5a59d056..fad29cf1 100644
--- a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
+++ b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
@@ -67,6 +67,12 @@ void CPanel::SetToRootFolder()
rootFolderSpec->Init();
}
+
+static bool DoesNameContainWildcard_SkipRoot(const UString &path)
+{
+ return DoesNameContainWildcard(path.Ptr(NName::GetRootPrefixSize(path)));
+}
+
HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted)
{
UString path = fullPath;
@@ -178,11 +184,11 @@ HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, bo
else if (fileInfo.IsDir())
{
#ifdef _WIN32
- if (DoesNameContainWildcard(sysPath))
+ if (DoesNameContainWildcard_SkipRoot(sysPath))
{
FString dirPrefix, fileName;
NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName);
- if (DoesNameContainWildcard(dirPrefix))
+ if (DoesNameContainWildcard_SkipRoot(fs2us(dirPrefix)))
return E_INVALIDARG;
sysPath = fs2us(dirPrefix + fileInfo.Name);
}
@@ -200,10 +206,10 @@ HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, bo
HRESULT res = S_OK;
#ifdef _WIN32
- if (DoesNameContainWildcard(dirPrefix))
+ if (DoesNameContainWildcard_SkipRoot(fs2us(dirPrefix)))
return E_INVALIDARG;
- if (DoesNameContainWildcard(fileName))
+ if (DoesNameContainWildcard(fs2us(fileName)))
res = S_FALSE;
else
#endif
@@ -281,7 +287,17 @@ HRESULT CPanel::BindToPathAndRefresh(const UString &path)
CDisableTimerProcessing disableTimerProcessing(*this);
CDisableNotify disableNotify(*this);
bool archiveIsOpened, encrypted;
- HRESULT res = BindToPath(path, UString(), archiveIsOpened, encrypted);
+ UString s = path;
+
+ #ifdef _WIN32
+ if (!s.IsEmpty() && s[0] == '\"' && s.Back() == '\"')
+ {
+ s.DeleteBack();
+ s.Delete(0);
+ }
+ #endif
+
+ HRESULT res = BindToPath(s, UString(), archiveIsOpened, encrypted);
RefreshListCtrl(UString(), -1, true, UStringVector());
return res;
}
@@ -349,14 +365,14 @@ void CPanel::LoadFullPathAndShow()
#else
1
#endif
- && path.Back() == WCHAR_PATH_SEPARATOR)
+ && IS_PATH_SEPAR(path.Back()))
path.DeleteBack();
DWORD attrib = FILE_ATTRIBUTE_DIRECTORY;
// GetRealIconIndex is slow for direct DVD/UDF path. So we use dummy path
if (path.IsPrefixedBy(L"\\\\.\\"))
- path = L"_TestFolder_";
+ path = "_TestFolder_";
else
{
CFileInfo fi;
@@ -456,7 +472,7 @@ void CPanel::AddComboBoxItem(const UString &name, int iconIndex, int indent, boo
UString s;
iconIndex = iconIndex;
for (int i = 0; i < indent; i++)
- s += L" ";
+ s += " ";
_headerComboBox.AddString(s + name);
#else
@@ -631,6 +647,30 @@ void CPanel::FoldersHistory()
BindToPathAndRefresh(selectString);
}
+
+UString CPanel::GetParentDirPrefix() const
+{
+ UString s;
+ if (!_currentFolderPrefix.IsEmpty())
+ {
+ wchar_t c = _currentFolderPrefix.Back();
+ if (IS_PATH_SEPAR(c) || c == ':')
+ {
+ s = _currentFolderPrefix;
+ s.DeleteBack();
+ if (s != L"\\\\." &&
+ s != L"\\\\?")
+ {
+ int pos = s.ReverseFind_PathSepar();
+ if (pos >= 0)
+ s.DeleteFrom(pos + 1);
+ }
+ }
+ }
+ return s;
+}
+
+
void CPanel::OpenParentFolder()
{
LoadFullPath(); // Maybe we don't need it ??
@@ -641,12 +681,12 @@ void CPanel::OpenParentFolder()
if (!_currentFolderPrefix.IsEmpty())
{
wchar_t c = _currentFolderPrefix.Back();
- if (c == WCHAR_PATH_SEPARATOR || c == ':')
+ if (IS_PATH_SEPAR(c) || c == ':')
{
focusedName = _currentFolderPrefix;
focusedName.DeleteBack();
/*
- if (c == ':' && !focusedName.IsEmpty() && focusedName.Back() == WCHAR_PATH_SEPARATOR)
+ if (c == ':' && !focusedName.IsEmpty() && IS_PATH_SEPAR(focusedName.Back()))
{
focusedName.DeleteBack();
}
@@ -825,7 +865,7 @@ void CPanel::OpenAltStreams()
path.DeleteBack();
}
- path += L':';
+ path += ':';
BindToPathAndRefresh(path);
#endif
}
diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
index cfbc5770..795e74b7 100644
--- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
+++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
@@ -46,7 +46,7 @@ extern UInt64 g_RAM_Size;
extern bool g_IsNT;
#endif
-static CFSTR kTempDirPrefix = FTEXT("7zO");
+#define kTempDirPrefix FTEXT("7zO")
// #define SHOW_DEBUG_INFO
@@ -534,23 +534,23 @@ HRESULT CPanel::OpenAsArc(IInStream *inStream,
UString s2;
if (!values[3].IsEmpty())
{
- s2 = L"Can not open the file as [" + values[3] + L"] archive";
+ s2 = "Can not open the file as [" + values[3] + "] archive";
if (level2 != 0)
- s2 += L"\nThe file is open as [" + values[2] + L"] archive";
+ s2 += "\nThe file is open as [" + values[2] + "] archive";
}
if (!values[0].IsEmpty())
{
if (!s2.IsEmpty())
s2.Add_LF();
- s2 += L"[";
+ s2 += "[";
s2 += values[2];
- s2 += L"] Error: ";
+ s2 += "] Error: ";
s2 += values[0];
}
if (!s2.IsEmpty())
{
if (!s.IsEmpty())
- s += L"--------------------\n";
+ s += "--------------------\n";
s += values[1];
s.Add_LF();
s += s2;
@@ -587,7 +587,7 @@ HRESULT CPanel::OpenAsArc_Msg(IInStream *inStream,
if (showErrorMessage && encrypted)
{
- UString message = L"Error";
+ UString message("Error");
if (res == S_FALSE)
{
message = MyFormatNew(
@@ -663,11 +663,15 @@ HRESULT CPanel::OpenParentArchiveFolder()
}
-static const char *kStartExtensions =
+static const char * const kExeExtensions =
+ " exe bat ps1 com"
+ " ";
+
+static const char * const kStartExtensions =
#ifdef UNDER_CE
" cab"
#endif
- " exe bat com"
+ " exe bat ps1 com"
" chm"
" msi doc xls ppt pps wps wpt wks xlr wdb vsd pub"
@@ -718,6 +722,51 @@ static bool DoItemAlwaysStart(const UString &name)
UString GetQuotedString(const UString &s);
+
+void SplitCmdLineSmart(const UString &cmd, UString &prg, UString &params)
+{
+ params.Empty();
+ prg = cmd;
+ prg.Trim();
+ if (prg.Len() >= 2 && prg[0] == L'"')
+ {
+ int pos = prg.Find(L'"', 1);
+ if (pos >= 0)
+ {
+ if ((unsigned)pos + 1 == prg.Len() || prg[pos + 1] == ' ')
+ {
+ params = prg.Ptr(pos + 1);
+ params.Trim();
+ prg.DeleteFrom(pos);
+ prg.DeleteFrontal(1);
+ }
+ }
+ }
+}
+
+
+static WRes StartAppWithParams(const UString &cmd, const UStringVector &paramVector, CProcess &process)
+{
+ UString param;
+ UString prg;
+
+ SplitCmdLineSmart(cmd, prg, param);
+
+ param.Trim();
+
+ // int pos = params.Find(L"%1");
+
+ FOR_VECTOR (i, paramVector)
+ {
+ if (!param.IsEmpty() && param.Back() != ' ')
+ param.Add_Space();
+ param += GetQuotedString(paramVector[i]);
+ }
+
+ return process.Create(prg, param, NULL);
+}
+
+
static HRESULT StartEditApplication(const UString &path, bool useEditor, HWND window, CProcess &process)
{
UString command;
@@ -725,7 +774,7 @@ static HRESULT StartEditApplication(const UString &path, bool useEditor, HWND wi
if (command.IsEmpty())
{
#ifdef UNDER_CE
- command = L"\\Windows\\";
+ command = "\\Windows\\";
#else
FString winDir;
if (!GetWindowsDir(winDir))
@@ -733,15 +782,19 @@ static HRESULT StartEditApplication(const UString &path, bool useEditor, HWND wi
NName::NormalizeDirPathPrefix(winDir);
command = fs2us(winDir);
#endif
- command += L"notepad.exe";
+ command += "notepad.exe";
}
- HRESULT res = process.Create(command, GetQuotedString(path), NULL);
+ UStringVector params;
+ params.Add(path);
+
+ HRESULT res = StartAppWithParams(command, params, process);
if (res != SZ_OK)
::MessageBoxW(window, LangString(IDS_CANNOT_START_EDITOR), L"7-Zip", MB_OK | MB_ICONSTOP);
return res;
}
+
void CApp::DiffFiles()
{
const CPanel &panel = GetFocusedPanel();
@@ -779,16 +832,21 @@ void CApp::DiffFiles()
if (command.IsEmpty())
return;
- UString param = GetQuotedString(path1);
- param.Add_Space();
- param += GetQuotedString(path2);
+ UStringVector params;
+ params.Add(path1);
+ params.Add(path2);
- HRESULT res = MyCreateProcess(command, param);
+ HRESULT res;
+ {
+ CProcess process;
+ res = StartAppWithParams(command, params, process);
+ }
if (res == SZ_OK)
return;
::MessageBoxW(_window, LangString(IDS_CANNOT_START_EDITOR), L"7-Zip", MB_OK | MB_ICONSTOP);
}
+
#ifndef _UNICODE
typedef BOOL (WINAPI * ShellExecuteExWP)(LPSHELLEXECUTEINFOW lpExecInfo);
#endif
@@ -802,7 +860,7 @@ static HRESULT StartApplication(const UString &dir, const UString &path, HWND wi
int dot = path2.ReverseFind_Dot();
int separ = path2.ReverseFind_PathSepar();
if (dot < 0 || dot < separ)
- path2 += L'.';
+ path2 += '.';
}
#endif
@@ -841,8 +899,8 @@ static HRESULT StartApplication(const UString &dir, const UString &path, HWND wi
;
execInfo.hwnd = NULL;
execInfo.lpVerb = NULL;
- const CSysString sysPath = GetSystemString(path2);
- const CSysString sysDir = GetSystemString(dir);
+ const CSysString sysPath (GetSystemString(path2));
+ const CSysString sysDir (GetSystemString(dir));
execInfo.lpFile = sysPath;
execInfo.lpParameters = NULL;
execInfo.lpDirectory =
@@ -896,27 +954,36 @@ void CPanel::EditItem(int index, bool useEditor)
StartEditApplication(GetItemFullPath(index), useEditor, (HWND)*this, process);
}
+
void CPanel::OpenFolderExternal(int index)
{
- UString fsPrefix = GetFsPath();
- UString name;
+ UString prefix = GetFsPath();
+ UString path = prefix;
+
if (index == kParentIndex)
{
- int pos = fsPrefix.ReverseFind_PathSepar();
- if (pos >= 0 && pos == (int)fsPrefix.Len() - 1)
- {
- UString s = fsPrefix.Left(pos);
- pos = s.ReverseFind_PathSepar();
- if (pos >= 0)
- fsPrefix.SetFrom(s, pos + 1);
- }
- name = fsPrefix;
+ if (prefix.IsEmpty())
+ return;
+ const wchar_t c = prefix.Back();
+ if (!IS_PATH_SEPAR(c) && c != ':')
+ return;
+ prefix.DeleteBack();
+ int pos = prefix.ReverseFind_PathSepar();
+ if (pos < 0)
+ return;
+ prefix.DeleteFrom(pos + 1);
+ path = prefix;
}
else
- name = fsPrefix + GetItemRelPath(index) + WCHAR_PATH_SEPARATOR;
- StartApplicationDontWait(fsPrefix, name, (HWND)*this);
+ {
+ path += GetItemRelPath(index);
+ path.Add_PathSepar();
+ }
+
+ StartApplicationDontWait(prefix, path, (HWND)*this);
}
+
bool CPanel::IsVirus_Message(const UString &name)
{
UString name2;
@@ -928,12 +995,12 @@ bool CPanel::IsVirus_Message(const UString &name)
if (name2.Find(cRLO) >= 0)
{
- UString badString = cRLO;
+ const UString badString(cRLO);
name2.Replace(badString, L"[RLO]");
isVirus = true;
}
{
- const wchar_t *kVirusSpaces = L" ";
+ const wchar_t * const kVirusSpaces = L" ";
// const unsigned kNumSpaces = strlen(kVirusSpaces);
for (;;)
{
@@ -945,6 +1012,27 @@ bool CPanel::IsVirus_Message(const UString &name)
name2.Replace(kVirusSpaces, L" ");
}
}
+
+ #ifdef _WIN32
+ {
+ unsigned i;
+ for (i = name2.Len(); i != 0;)
+ {
+ wchar_t c = name2[i - 1];
+ if (c != '.' && c != ' ')
+ break;
+ i--;
+ name2.ReplaceOneCharAtPos(i, '_');
+ }
+ if (i != name2.Len())
+ {
+ UString name3 = name2;
+ name3.DeleteFrom(i);
+ if (FindExt(kExeExtensions, name3))
+ isVirus = true;
+ }
+ }
+ #endif
if (!isVirus)
return false;
@@ -983,8 +1071,9 @@ void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal, const wchar
CDisableTimerProcessing disableTimerProcessing(*this);
UString name = GetItemRelPath2(index);
- if (IsVirus_Message(name))
- return;
+ if (tryExternal)
+ if (IsVirus_Message(name))
+ return;
if (!_parentFolders.IsEmpty())
{
@@ -1330,7 +1419,7 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
#if defined(_WIN32) && !defined(UNDER_CE)
-static const FChar *k_ZoneId_StreamName = FTEXT(":Zone.Identifier");
+static const FChar * const k_ZoneId_StreamName = FTEXT(":Zone.Identifier");
#endif
@@ -1443,7 +1532,7 @@ HRESULT CBufSeqOutStream_WithFile::FlushToFile()
{
outFileStream.Release();
return E_FAIL;
- // MessageBoxMyError(UString(L"Can't create file ") + fs2us(tempFilePath));
+ // MessageBoxMyError(UString("Can't create file ") + fs2us(tempFilePath));
}
}
while (_fileWritePos != _pos)
@@ -1494,8 +1583,9 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
const UString name = GetItemName(index);
const UString relPath = GetItemRelPath(index);
- if (IsVirus_Message(name))
- return;
+ if (tryExternal)
+ if (IsVirus_Message(name))
+ return;
if (!_folderOperations)
{
diff --git a/CPP/7zip/UI/FileManager/PanelItems.cpp b/CPP/7zip/UI/FileManager/PanelItems.cpp
index 55981d6d..2f32a143 100644
--- a/CPP/7zip/UI/FileManager/PanelItems.cpp
+++ b/CPP/7zip/UI/FileManager/PanelItems.cpp
@@ -532,7 +532,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
if (showDots)
{
- UString itemName = L"..";
+ UString itemName ("..");
item.iItem = listViewItemCount;
if (itemName == focusedName)
cursorIndex = item.iItem;
@@ -587,7 +587,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
unsigned prefixLen = 0;
_folderGetItemName->GetItemPrefix(i, &prefix, &prefixLen);
if (prefix)
- relPath += prefix;
+ relPath = prefix;
}
if (!prefix)
{
@@ -595,7 +595,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
if (_folder->GetProperty(i, kpidPrefix, &prop) != S_OK)
throw 2723400;
if (prop.vt == VT_BSTR)
- relPath += prop.bstrVal;
+ relPath.SetFromBstr(prop.bstrVal);
}
}
relPath += name;
@@ -637,7 +637,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
if (j < finish)
{
correctedName.Empty();
- correctedName = L"virus";
+ correctedName = "virus";
int pos = 0;
for (;;)
{
@@ -648,7 +648,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
break;
}
correctedName += itemName.Mid(pos, posNew - pos);
- correctedName += L" ... ";
+ correctedName += " ... ";
pos = posNew;
while (itemName[++pos] == ' ');
}
@@ -664,19 +664,6 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
LPSTR_TEXTCALLBACKW can be 2-3 times faster for loading in this loop. */
}
- UInt32 attrib = 0;
- // for (int yyy = 0; yyy < 6000000; yyy++) {
- NCOM::CPropVariant prop;
- RINOK(_folder->GetProperty(i, kpidAttrib, &prop));
- if (prop.vt == VT_UI4)
- {
- // char s[256]; sprintf(s, "attrib = %7x", attrib); OutputDebugStringA(s);
- attrib = prop.ulVal;
- }
- else if (IsItem_Folder(i))
- attrib |= FILE_ATTRIBUTE_DIRECTORY;
- // }
-
bool defined = false;
if (folderGetSystemIconIndex)
@@ -684,8 +671,19 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
folderGetSystemIconIndex->GetSystemIconIndex(i, &item.iImage);
defined = (item.iImage > 0);
}
+
if (!defined)
{
+ UInt32 attrib = 0;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(_folder->GetProperty(i, kpidAttrib, &prop));
+ if (prop.vt == VT_UI4)
+ attrib = prop.ulVal;
+ }
+ if (IsItem_Folder(i))
+ attrib |= FILE_ATTRIBUTE_DIRECTORY;
+
if (_currentFolderPrefix.IsEmpty())
{
int iconIndexTemp;
@@ -993,7 +991,7 @@ void CPanel::GetItemName(int itemIndex, UString &s) const
{
if (itemIndex == kParentIndex)
{
- s = L"..";
+ s = "..";
return;
}
NCOM::CPropVariant prop;
@@ -1073,14 +1071,12 @@ bool CPanel::IsItem_AltStream(int itemIndex) const
return GetItem_BoolProp(itemIndex, kpidIsAltStream);
}
-UInt64 CPanel::GetItemSize(int itemIndex) const
+UInt64 CPanel::GetItem_UInt64Prop(int itemIndex, PROPID propID) const
{
if (itemIndex == kParentIndex)
return 0;
- if (_folderGetItemName)
- return _folderGetItemName->GetItemSize(itemIndex);
NCOM::CPropVariant prop;
- if (_folder->GetProperty(itemIndex, kpidSize, &prop) != S_OK)
+ if (_folder->GetProperty(itemIndex, propID, &prop) != S_OK)
throw 2723400;
UInt64 val = 0;
if (ConvertPropVariantToUInt64(prop, val))
@@ -1088,6 +1084,14 @@ UInt64 CPanel::GetItemSize(int itemIndex) const
return 0;
}
+UInt64 CPanel::GetItemSize(int itemIndex) const
+{
+ if (itemIndex == kParentIndex)
+ return 0;
+ if (_folderGetItemName)
+ return _folderGetItemName->GetItemSize(itemIndex);
+ return GetItem_UInt64Prop(itemIndex, kpidSize);
+}
void CPanel::SaveListViewInfo()
{
diff --git a/CPP/7zip/UI/FileManager/PanelKey.cpp b/CPP/7zip/UI/FileManager/PanelKey.cpp
index 26aa0b2f..5603251f 100644
--- a/CPP/7zip/UI/FileManager/PanelKey.cpp
+++ b/CPP/7zip/UI/FileManager/PanelKey.cpp
@@ -10,7 +10,7 @@
using namespace NWindows;
-// static LPCWSTR kHelpTopic = L"FM/index.htm";
+// #define kHelpTopic "FM/index.htm"
struct CVKeyPropIDPair
{
diff --git a/CPP/7zip/UI/FileManager/PanelListNotify.cpp b/CPP/7zip/UI/FileManager/PanelListNotify.cpp
index cc84f712..d7785d12 100644
--- a/CPP/7zip/UI/FileManager/PanelListNotify.cpp
+++ b/CPP/7zip/UI/FileManager/PanelListNotify.cpp
@@ -19,6 +19,18 @@
using namespace NWindows;
+/* Unicode characters for space:
+0x009C STRING TERMINATOR
+0x00B7 Middle dot
+0x237D Shouldered open box
+0x2420 Symbol for space
+0x2422 Blank symbol
+0x2423 Open box
+*/
+
+#define SPACE_REPLACE_CHAR (wchar_t)(0x2423)
+#define SPACE_TERMINATOR_CHAR (wchar_t)(0x9C)
+
#define INT_TO_STR_SPEC(v) \
while (v >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(v % 10)); v /= 10; } \
*s++ = (unsigned char)('0' + (unsigned)v);
@@ -42,7 +54,7 @@ static void ConvertSizeToString(UInt64 val, wchar_t *s) throw()
{
if (i != 0)
{
- *s++ = temp[i - 1];
+ *s++ = temp[(size_t)i - 1];
if (i == 2)
*s++ = temp[0];
}
@@ -62,9 +74,9 @@ static void ConvertSizeToString(UInt64 val, wchar_t *s) throw()
do
{
s[0] = ' ';
- s[1] = temp[i - 1];
- s[2] = temp[i - 2];
- s[3] = temp[i - 3];
+ s[1] = temp[(size_t)i - 1];
+ s[2] = temp[(size_t)i - 2];
+ s[3] = temp[(size_t)i - 3];
s += 4;
}
while (i -= 3);
@@ -337,17 +349,17 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
{
if (c != 0x202E) // RLO
continue;
- text[dest - 1] = '_';
+ text[(size_t)dest - 1] = '_';
continue;
}
- if (name[i + 1] != ' ')
+ if (name[i] != ' ')
continue;
- unsigned t = 2;
+ unsigned t = 1;
for (; name[i + t] == ' '; t++);
-
- if (t >= 4 && dest + 4 <= limit)
+
+ if (t >= 4 && dest + 4 < limit)
{
text[dest++] = '.';
text[dest++] = '.';
@@ -356,6 +368,20 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
i += t;
}
}
+
+ if (dest == 0)
+ text[dest++]= '_';
+
+ #ifdef _WIN32
+ else if (text[(size_t)dest - 1] == ' ')
+ {
+ if (dest < limit)
+ text[dest++] = SPACE_TERMINATOR_CHAR;
+ else
+ text[dest - 1] = SPACE_REPLACE_CHAR;
+ }
+ #endif
+
text[dest] = 0;
// OutputDebugStringW(text);
return 0;
@@ -392,7 +418,7 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
if (res != S_OK)
{
MyStringCopy(text, L"Error: ");
- // s = UString(L"Error: ") + HResultToMessage(res);
+ // s = UString("Error: ") + HResultToMessage(res);
}
else if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && IsSizeProp(propID))
{
@@ -418,7 +444,7 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
else
{
char temp[64];
- ConvertPropertyToShortString(temp, prop, propID, false);
+ ConvertPropertyToShortString2(temp, prop, propID, _timestampLevel);
unsigned i;
unsigned limit = item.cchTextMax - 1;
for (i = 0; i < limit; i++)
@@ -712,7 +738,7 @@ void CPanel::Refresh_StatusBar()
{
char dateString2[32];
dateString2[0] = 0;
- ConvertPropertyToShortString(dateString2, prop, kpidMTime, false);
+ ConvertPropertyToShortString2(dateString2, prop, kpidMTime);
for (unsigned i = 0;; i++)
{
char c = dateString2[i];
diff --git a/CPP/7zip/UI/FileManager/PanelMenu.cpp b/CPP/7zip/UI/FileManager/PanelMenu.cpp
index c5b07825..b3f3a6b6 100644
--- a/CPP/7zip/UI/FileManager/PanelMenu.cpp
+++ b/CPP/7zip/UI/FileManager/PanelMenu.cpp
@@ -14,6 +14,7 @@
#include "../Explorer/ContextMenu.h"
#include "App.h"
+#include "FormatUtils.h"
#include "LangUtils.h"
#include "MyLoadMenu.h"
#include "PropertyName.h"
@@ -49,9 +50,9 @@ void CPanel::InvokeSystemCommand(const char *command)
contextMenu->InvokeCommand(&ci);
}
-static const char *kSeparator = "----------------------------\n";
-static const char *kSeparatorSmall = "----\n";
-static const char *kPropValueSeparator = ": ";
+static const char * const kSeparator = "----------------------------\n";
+static const char * const kSeparatorSmall = "----\n";
+static const char * const kPropValueSeparator = ": ";
extern UString ConvertSizeToString(UInt64 value) throw();
bool IsSizeProp(UINT propID) throw();
@@ -82,12 +83,12 @@ static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
val = ConvertSizeToString(v);
}
else
- ConvertPropertyToString(val, prop, propID);
+ ConvertPropertyToString2(val, prop, propID);
if (!val.IsEmpty())
{
s += GetNameOfProperty(propID, nameBSTR);
- s.AddAscii(kPropValueSeparator);
+ s += kPropValueSeparator;
/*
if (propID == kpidComment)
s.Add_LF();
@@ -98,6 +99,14 @@ static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
}
}
+
+static void AddPropertyString(PROPID propID, UInt64 val, UString &s)
+{
+ NCOM::CPropVariant prop = val;
+ AddPropertyString(propID, NULL, prop, s);
+}
+
+
static inline char GetHex(Byte value)
{
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
@@ -132,10 +141,11 @@ void CPanel::Properties()
CRecordVector<UInt32> operatedIndices;
GetOperatedItemIndices(operatedIndices);
+
if (operatedIndices.Size() == 1)
{
UInt32 index = operatedIndices[0];
- // message += L"Item:\n";
+ // message += "Item:\n");
UInt32 numProps;
if (_folder->GetNumberOfProperties(&numProps) == S_OK)
{
@@ -182,10 +192,8 @@ void CPanel::Properties()
const UInt32 kMaxDataSize = 64;
if (dataSize > kMaxDataSize)
{
- char temp[64];
s += "data:";
- ConvertUInt32ToString(dataSize, temp);
- s += temp;
+ s.Add_UInt32(dataSize);
}
else
{
@@ -198,15 +206,53 @@ void CPanel::Properties()
}
}
message += GetNameOfProperty(propID, name);
- message.AddAscii(kPropValueSeparator);
- message.AddAscii(s);
+ message += kPropValueSeparator;
+ message += s.Ptr();
message.Add_LF();
}
}
}
- message.AddAscii(kSeparator);
+ message += kSeparator;
+ }
+ else if (operatedIndices.Size() >= 1)
+ {
+ UInt64 packSize = 0;
+ UInt64 unpackSize = 0;
+ UInt64 numFiles = 0;
+ UInt64 numDirs = 0;
+
+ FOR_VECTOR (i, operatedIndices)
+ {
+ const UInt32 index = operatedIndices[i];
+ unpackSize += GetItemSize(index);
+ packSize += GetItem_UInt64Prop(index, kpidPackSize);
+ if (IsItem_Folder(index))
+ {
+ numDirs++;
+ numDirs += GetItem_UInt64Prop(index, kpidNumSubDirs);
+ numFiles += GetItem_UInt64Prop(index, kpidNumSubFiles);;
+ }
+ else
+ numFiles++;
+ }
+ {
+ wchar_t temp[32];
+ ConvertUInt32ToString(operatedIndices.Size(), temp);
+ message += MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, temp);
+ message.Add_LF();
+ }
+
+ if (numDirs != 0)
+ AddPropertyString(kpidNumSubDirs, numDirs, message);
+ if (numFiles != 0)
+ AddPropertyString(kpidNumSubFiles, numFiles, message);
+ AddPropertyString(kpidSize, unpackSize, message);
+ AddPropertyString(kpidPackSize, packSize, message);
+
+ message += kSeparator;
}
+
/*
AddLangString(message, IDS_PROP_FILE_TYPE);
@@ -263,7 +309,7 @@ void CPanel::Properties()
{
const int kNumSpecProps = ARRAY_SIZE(kSpecProps);
- message.AddAscii(kSeparator);
+ message += kSeparator;
for (Int32 i = -(int)kNumSpecProps; i < (Int32)numProps; i++)
{
@@ -288,7 +334,7 @@ void CPanel::Properties()
UInt32 numProps;
if (getProps->GetArcNumProps2(level, &numProps) == S_OK)
{
- message.AddAscii(kSeparatorSmall);
+ message += kSeparatorSmall;
for (Int32 i = 0; i < (Int32)numProps; i++)
{
CMyComBSTR name;
@@ -331,8 +377,8 @@ void CPanel::EditCopy()
GetSelectedItemsIndices(indices);
FOR_VECTOR (i, indices)
{
- if (i > 0)
- s += L"\xD\n";
+ if (i != 0)
+ s += "\xD\n";
s += GetItemName(indices[i]);
}
ClipboardSetText(_mainWindow, s);
@@ -755,7 +801,7 @@ bool CPanel::InvokePluginCommand(int id,
commandInfo.hwnd = GetParent();
commandInfo.lpVerb = (LPCSTR)(MAKEINTRESOURCE(offset));
commandInfo.lpParameters = NULL;
- CSysString currentFolderSys = GetSystemString(_currentFolderPrefix);
+ const CSysString currentFolderSys (GetSystemString(_currentFolderPrefix));
commandInfo.lpDirectory = (LPCSTR)(LPCTSTR)(currentFolderSys);
commandInfo.nShow = SW_SHOW;
diff --git a/CPP/7zip/UI/FileManager/PanelOperations.cpp b/CPP/7zip/UI/FileManager/PanelOperations.cpp
index 3331a4cf..3d852cdc 100644
--- a/CPP/7zip/UI/FileManager/PanelOperations.cpp
+++ b/CPP/7zip/UI/FileManager/PanelOperations.cpp
@@ -96,7 +96,7 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr
ProgressDialog.MainWindow = panel._mainWindow; // panel.GetParent()
- ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE);
+ ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
ProgressDialog.MainAddTitle = progressTitle + L' ';
RINOK(Create(progressTitle, ProgressDialog.MainWindow));
@@ -138,7 +138,7 @@ void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin))
CDynamicBuffer<CHAR> buffer;
FOR_VECTOR (i, indices)
{
- const AString path = GetSystemString(GetItemFullPath(indices[i]));
+ const AString path (GetSystemString(GetItemFullPath(indices[i])));
buffer.AddData(path, path.Len() + 1);
}
*buffer.GetCurPtrAndGrow(1) = 0;
@@ -502,7 +502,7 @@ void CPanel::ChangeComment()
UString name = GetItemRelPath2(realIndex);
CComboDialog dlg;
dlg.Title = name;
- dlg.Title += L" : ";
+ dlg.Title += " : ";
AddLangString(dlg.Title, IDS_COMMENT);
dlg.Value = comment;
LangString(IDS_COMMENT2, dlg.Static);
diff --git a/CPP/7zip/UI/FileManager/PanelSelect.cpp b/CPP/7zip/UI/FileManager/PanelSelect.cpp
index 72cb4838..268b64af 100644
--- a/CPP/7zip/UI/FileManager/PanelSelect.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSelect.cpp
@@ -156,7 +156,7 @@ void CPanel::SelectSpec(bool selectMode)
CComboDialog dlg;
LangString(selectMode ? IDS_SELECT : IDS_DESELECT, dlg.Title );
LangString(IDS_SELECT_MASK, dlg.Static);
- dlg.Value = L'*';
+ dlg.Value = '*';
if (dlg.Create(GetParent()) != IDOK)
return;
const UString &mask = dlg.Value;
@@ -192,7 +192,7 @@ void CPanel::SelectByType(bool selectMode)
}
else
{
- UString mask = L'*';
+ UString mask ('*');
mask += name.Ptr(pos);
FOR_VECTOR (i, _selectedStatusVector)
if (IsItem_Folder(i) == isItemFolder && DoesWildcardMatchName(mask, GetItemName(i)))
diff --git a/CPP/7zip/UI/FileManager/PanelSort.cpp b/CPP/7zip/UI/FileManager/PanelSort.cpp
index 59b785b8..4adfc39f 100644
--- a/CPP/7zip/UI/FileManager/PanelSort.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSort.cpp
@@ -176,17 +176,13 @@ int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
panel->_folder->GetProperty((UInt32)lParam1, propID, &prop1);
panel->_folder->GetProperty((UInt32)lParam2, propID, &prop2);
if (prop1.vt != prop2.vt)
- {
return MyCompare(prop1.vt, prop2.vt);
- }
if (prop1.vt == VT_BSTR)
- {
- return _wcsicmp(prop1.bstrVal, prop2.bstrVal);
- }
+ return MyStringCompareNoCase(prop1.bstrVal, prop2.bstrVal);
return prop1.Compare(prop2);
- // return 0;
}
+
int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
{
if (lpData == 0) return 0;
diff --git a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
index 7aaa97b1..604448e8 100644
--- a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
@@ -24,21 +24,21 @@ using namespace NWindows;
using namespace NFile;
using namespace NDir;
-static const wchar_t *g_Message_FileWriteError = L"File write error";
+static const char * const g_Message_FileWriteError = "File write error";
struct CVolSeqName
{
UString UnchangedPart;
UString ChangedPart;
- CVolSeqName(): ChangedPart(L"000") {};
+ CVolSeqName(): ChangedPart("000") {};
void SetNumDigits(UInt64 numVolumes)
{
- ChangedPart = L"000";
+ ChangedPart = "000";
while (numVolumes > 999)
{
numVolumes /= 10;
- ChangedPart += L'0';
+ ChangedPart += '0';
}
}
@@ -131,7 +131,7 @@ HRESULT CThreadSplit::ProcessVirt()
if (curVolSize == 0)
{
FString name = VolBasePath;
- name += FTEXT('.');
+ name += '.';
name += us2fs(seqName.GetNextName());
sync.Set_FilePath(fs2us(name));
sync.Set_NumFilesCur(numFiles++);
@@ -236,7 +236,7 @@ void CApp::Split()
CProgressDialog &progressDialog = spliter.ProgressDialog;
- UString progressWindowTitle = L"7-Zip"; // LangString(IDS_APP_TITLE, 0x03000000);
+ UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000);
UString title = LangString(IDS_SPLITTING);
progressDialog.ShowCompressionInfo = false;
@@ -340,7 +340,7 @@ extern void AddValuePair2(UString &s, UINT resourceID, UInt64 num, UInt64 size);
static void AddInfoFileName(UString &dest, const UString &name)
{
- dest += L"\n ";
+ dest += "\n ";
dest += name;
}
@@ -450,7 +450,7 @@ void CApp::Combine()
outName.DeleteBack();
}
if (outName.IsEmpty())
- outName = L"file";
+ outName = "file";
NFind::CFileInfo fileInfo;
UString destFilePath = path + outName;
@@ -464,7 +464,7 @@ void CApp::Combine()
CProgressDialog &progressDialog = combiner.ProgressDialog;
progressDialog.ShowCompressionInfo = false;
- UString progressWindowTitle = L"7-Zip"; // LangString(IDS_APP_TITLE, 0x03000000);
+ UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000);
UString title = LangString(IDS_COMBINING);
progressDialog.MainWindow = _window;
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.cpp b/CPP/7zip/UI/FileManager/ProgressDialog.cpp
index 65201a9e..1bf115ad 100644
--- a/CPP/7zip/UI/FileManager/ProgressDialog.cpp
+++ b/CPP/7zip/UI/FileManager/ProgressDialog.cpp
@@ -120,7 +120,7 @@ bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
wchar_t s[64];
ConvertUInt64ToString(percentValue, s);
UString title = s;
- title += L"% ";
+ title += "% ";
SetText(title + _title);
#ifndef _SFX
AddToTitle(title + MainAddTitle);
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
index 8c38b81a..762f2492 100644
--- a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
@@ -217,7 +217,7 @@ void CProgressSync::AddError_Message_Name(const wchar_t *message, const wchar_t
UString s;
if (name && *name != 0)
s += name;
- if (message && *message != 0 )
+ if (message && *message != 0)
{
if (!s.IsEmpty())
s.Add_LF();
@@ -232,7 +232,7 @@ void CProgressSync::AddError_Code_Name(DWORD systemError, const wchar_t *name)
{
UString s = NError::MyFormatMessage(systemError);
if (systemError == 0)
- s = L"Error";
+ s = "Error";
AddError_Message_Name(s, name);
}
@@ -828,8 +828,8 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
ConvertUInt64ToString(completedFiles, s);
if (IS_DEFINED_VAL(totalFiles))
{
- wcscat(s, L" / ");
- ConvertUInt64ToString(totalFiles, s + wcslen(s));
+ MyStringCat(s, L" / ");
+ ConvertUInt64ToString(totalFiles, s + MyStringLen(s));
}
if (_filesStr_Prev != s)
{
@@ -862,7 +862,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
{
_ratio_Prev = ratio;
ConvertUInt64ToString(ratio, s);
- wcscat(s, L"%");
+ MyStringCat(s, L"%");
SetItemText(IDT_PROGRESS_RATIO_VAL, s);
}
}
@@ -986,7 +986,7 @@ bool CProgressDialog::OnExternalCloseMessage()
{
MessagesDisplayed = true;
if (fm.ErrorMessage.Title.IsEmpty())
- fm.ErrorMessage.Title = L"7-Zip";
+ fm.ErrorMessage.Title = "7-Zip";
MessageBoxW(*this, fm.ErrorMessage.Message, fm.ErrorMessage.Title, MB_ICONERROR);
}
else if (!thereAreMessages)
@@ -995,7 +995,7 @@ bool CProgressDialog::OnExternalCloseMessage()
if (!fm.OkMessage.Message.IsEmpty())
{
if (fm.OkMessage.Title.IsEmpty())
- fm.OkMessage.Title = L"7-Zip";
+ fm.OkMessage.Title = "7-Zip";
MessageBoxW(*this, fm.OkMessage.Message, fm.OkMessage.Title, MB_OK);
}
}
@@ -1050,8 +1050,8 @@ void CProgressDialog::SetTitleText()
{
char temp[32];
ConvertUInt64ToString(_prevPercentValue, temp);
- s.AddAscii(temp);
- s += L'%';
+ s += temp;
+ s += '%';
}
if (!_foreground)
{
@@ -1273,12 +1273,10 @@ void CProgressThreadVirt::Process()
catch(const char *s) { m = GetUnicodeString(s); }
catch(int v)
{
- wchar_t s[16];
- ConvertUInt32ToString(v, s);
- m = L"Error #";
- m += s;
+ m = "Error #";
+ m.Add_UInt32(v);
}
- catch(...) { m = L"Error"; }
+ catch(...) { m = "Error"; }
if (Result != E_ABORT)
{
if (m.IsEmpty() && Result != S_OK)
diff --git a/CPP/7zip/UI/FileManager/RegistryAssociations.cpp b/CPP/7zip/UI/FileManager/RegistryAssociations.cpp
index 93ba40c2..e48dbb44 100644
--- a/CPP/7zip/UI/FileManager/RegistryAssociations.cpp
+++ b/CPP/7zip/UI/FileManager/RegistryAssociations.cpp
@@ -17,14 +17,14 @@ namespace NRegistryAssoc {
// static NSynchronization::CCriticalSection g_CriticalSection;
-static const TCHAR *kClasses = TEXT("Software\\Classes\\");
-// static const TCHAR *kShellNewKeyName = TEXT("ShellNew");
-// static const TCHAR *kShellNewDataValueName = TEXT("Data");
-static const TCHAR *kDefaultIconKeyName = TEXT("DefaultIcon");
-static const TCHAR *kShellKeyName = TEXT("shell");
-static const TCHAR *kOpenKeyName = TEXT("open");
-static const TCHAR *kCommandKeyName = TEXT("command");
-static const TCHAR *k7zipPrefix = TEXT("7-Zip.");
+static const TCHAR * const kClasses = TEXT("Software\\Classes\\");
+// static const TCHAR * const kShellNewKeyName = TEXT("ShellNew");
+// static const TCHAR * const kShellNewDataValueName = TEXT("Data");
+static const TCHAR * const kDefaultIconKeyName = TEXT("DefaultIcon");
+static const TCHAR * const kShellKeyName = TEXT("shell");
+static const TCHAR * const kOpenKeyName = TEXT("open");
+static const TCHAR * const kCommandKeyName = TEXT("command");
+static const char * const k7zipPrefix = "7-Zip.";
static CSysString GetExtProgramKeyName(const CSysString &ext)
{
@@ -59,7 +59,8 @@ bool CShellExtInfo::ReadFromRegistry(HKEY hkey, const CSysString &ext)
}
{
CKey iconKey;
- if (iconKey.Open(hkey, GetFullKeyPath(hkey, ProgramKey + CSysString(TEXT(CHAR_PATH_SEPARATOR)) + kDefaultIconKeyName), KEY_READ) == ERROR_SUCCESS)
+
+ if (iconKey.Open(hkey, GetFullKeyPath(hkey, ProgramKey + CSysString(CHAR_PATH_SEPARATOR) + kDefaultIconKeyName), KEY_READ) == ERROR_SUCCESS)
{
UString value;
if (iconKey.QueryValue(NULL, value) == ERROR_SUCCESS)
@@ -86,7 +87,7 @@ bool CShellExtInfo::ReadFromRegistry(HKEY hkey, const CSysString &ext)
bool CShellExtInfo::IsIt7Zip() const
{
- return IsString1PrefixedByString2_NoCase(GetUnicodeString(ProgramKey), GetUnicodeString(k7zipPrefix));
+ return ProgramKey.IsPrefixedBy_Ascii_NoCase(k7zipPrefix);
}
LONG DeleteShellExtensionInfo(HKEY hkey, const CSysString &ext)
@@ -114,9 +115,9 @@ LONG AddShellExtensionInfo(HKEY hkey,
// NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
CSysString programKeyName;
{
- CSysString ext2 = ext;
+ CSysString ext2 (ext);
if (iconIndex < 0)
- ext2 = TEXT("*");
+ ext2 = "*";
programKeyName = GetExtProgramKeyName(ext2);
}
{
@@ -142,10 +143,8 @@ LONG AddShellExtensionInfo(HKEY hkey,
iconIndex = 0;
// if (iconIndex >= 0)
{
- iconPathFull += L',';
- wchar_t s[16];
- ConvertUInt32ToString((UInt32)iconIndex, s);
- iconPathFull += s;
+ iconPathFull += ',';
+ iconPathFull.Add_UInt32((UInt32)iconIndex);
}
iconKey.Create(programKey, kDefaultIconKeyName);
iconKey.SetValue(NULL, iconPathFull);
diff --git a/CPP/7zip/UI/FileManager/RegistryPlugins.cpp b/CPP/7zip/UI/FileManager/RegistryPlugins.cpp
index ad70db80..a0753ca6 100644
--- a/CPP/7zip/UI/FileManager/RegistryPlugins.cpp
+++ b/CPP/7zip/UI/FileManager/RegistryPlugins.cpp
@@ -13,12 +13,12 @@ using namespace NWindows;
using namespace NFile;
/*
-static const TCHAR *kLMBasePath = TEXT("Software\\7-Zip\\FM");
+static LPCTSTR const kLMBasePath = TEXT("Software\\7-Zip\\FM");
-static const TCHAR *kPluginsKeyName = TEXT("Plugins");
-static const TCHAR *kPluginsOpenClassIDValue = TEXT("CLSID");
-static const TCHAR *kPluginsOptionsClassIDValue = TEXT("Options");
-static const TCHAR *kPluginsTypeValue = TEXT("Type");
+static LPCTSTR const kPluginsKeyName = TEXT("Plugins");
+static LPCTSTR const kPluginsOpenClassIDValue = TEXT("CLSID");
+static LPCTSTR const kPluginsOptionsClassIDValue = TEXT("Options");
+static LPCTSTR const kPluginsTypeValue = TEXT("Type");
static CSysString GetFileFolderPluginsKeyName()
{
@@ -101,8 +101,10 @@ void ReadPluginInfoList(CObjectVector<CPluginInfo> &plugins)
if (::ReadPluginInfo(pluginInfo, false))
plugins.Add(pluginInfo);
}
- FString folderPath = baseFolderPrefix + FTEXT("Plugins") FSTRING_PATH_SEPARATOR;
- NFind::CEnumerator enumerator(folderPath + FCHAR_ANY_MASK);
+ FString folderPath = baseFolderPrefix;
+ folderPath += "Plugins" STRING_PATH_SEPARATOR;
+ NFind::CEnumerator enumerator;
+ enumerator.SetDirPrefix(folderPath);
NFind::CFileInfo fileInfo;
while (enumerator.Next(fileInfo))
{
@@ -127,7 +129,7 @@ void ReadFileFolderPluginInfoList(CObjectVector<CPluginInfo> &plugins)
CPluginInfo p;
// p.FilePath.Empty();
p.Type = kPluginTypeFF;
- p.Name = L"7-Zip";
+ p.Name = "7-Zip";
// p.ClassID = CLSID_CAgentArchiveHandler;
p.ClassIDDefined = true;
// p.OptionsClassID;
diff --git a/CPP/7zip/UI/FileManager/RegistryUtils.cpp b/CPP/7zip/UI/FileManager/RegistryUtils.cpp
index 9cc76c36..91b69a21 100644
--- a/CPP/7zip/UI/FileManager/RegistryUtils.cpp
+++ b/CPP/7zip/UI/FileManager/RegistryUtils.cpp
@@ -13,31 +13,31 @@ using namespace NRegistry;
#define REG_PATH_7Z TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip")
-static const TCHAR *kCUBasePath = REG_PATH_7Z;
-static const TCHAR *kCU_FMPath = REG_PATH_7Z TEXT(STRING_PATH_SEPARATOR) TEXT("FM");
-// static const TCHAR *kLM_Path = REG_PATH_7Z TEXT(STRING_PATH_SEPARATOR) TEXT("FM");
+static LPCTSTR const kCUBasePath = REG_PATH_7Z;
+static LPCTSTR const kCU_FMPath = REG_PATH_7Z TEXT(STRING_PATH_SEPARATOR) TEXT("FM");
+// static LPCTSTR const kLM_Path = REG_PATH_7Z TEXT(STRING_PATH_SEPARATOR) TEXT("FM");
-static const WCHAR *kLangValueName = L"Lang";
+static LPCWSTR const kLangValueName = L"Lang";
-static const WCHAR *kViewer = L"Viewer";
-static const WCHAR *kEditor = L"Editor";
-static const WCHAR *kDiff = L"Diff";
+static LPCWSTR const kViewer = L"Viewer";
+static LPCWSTR const kEditor = L"Editor";
+static LPCWSTR const kDiff = L"Diff";
-static const TCHAR *kShowDots = TEXT("ShowDots");
-static const TCHAR *kShowRealFileIcons = TEXT("ShowRealFileIcons");
-static const TCHAR *kFullRow = TEXT("FullRow");
-static const TCHAR *kShowGrid = TEXT("ShowGrid");
-static const TCHAR *kSingleClick = TEXT("SingleClick");
-static const TCHAR *kAlternativeSelection = TEXT("AlternativeSelection");
-// static const TCHAR *kUnderline = TEXT("Underline");
+static LPCTSTR const kShowDots = TEXT("ShowDots");
+static LPCTSTR const kShowRealFileIcons = TEXT("ShowRealFileIcons");
+static LPCTSTR const kFullRow = TEXT("FullRow");
+static LPCTSTR const kShowGrid = TEXT("ShowGrid");
+static LPCTSTR const kSingleClick = TEXT("SingleClick");
+static LPCTSTR const kAlternativeSelection = TEXT("AlternativeSelection");
+// static LPCTSTR const kUnderline = TEXT("Underline");
-static const TCHAR *kShowSystemMenu = TEXT("ShowSystemMenu");
+static LPCTSTR const kShowSystemMenu = TEXT("ShowSystemMenu");
-// static const TCHAR *kLockMemoryAdd = TEXT("LockMemoryAdd");
-static const TCHAR *kLargePages = TEXT("LargePages");
+// static LPCTSTR const kLockMemoryAdd = TEXT("LockMemoryAdd");
+static LPCTSTR const kLargePages = TEXT("LargePages");
-static const TCHAR *kFlatViewName = TEXT("FlatViewArc");
-// static const TCHAR *kShowDeletedFiles = TEXT("ShowDeleted");
+static LPCTSTR const kFlatViewName = TEXT("FlatViewArc");
+// static LPCTSTR const kShowDeletedFiles = TEXT("ShowDeleted");
static void SaveCuString(LPCTSTR keyPath, LPCWSTR valuePath, LPCWSTR value)
{
@@ -63,21 +63,21 @@ void ReadRegEditor(bool useEditor, UString &path) { ReadCuString(kCU_FMPath, use
void SaveRegDiff(const UString &path) { SaveCuString(kCU_FMPath, kDiff, path); }
void ReadRegDiff(UString &path) { ReadCuString(kCU_FMPath, kDiff, path); }
-static void Save7ZipOption(const TCHAR *value, bool enabled)
+static void Save7ZipOption(LPCTSTR value, bool enabled)
{
CKey key;
key.Create(HKEY_CURRENT_USER, kCUBasePath);
key.SetValue(value, enabled);
}
-static void SaveOption(const TCHAR *value, bool enabled)
+static void SaveOption(LPCTSTR value, bool enabled)
{
CKey key;
key.Create(HKEY_CURRENT_USER, kCU_FMPath);
key.SetValue(value, enabled);
}
-static bool Read7ZipOption(const TCHAR *value, bool defaultValue)
+static bool Read7ZipOption(LPCTSTR value, bool defaultValue)
{
CKey key;
if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS)
@@ -89,7 +89,7 @@ static bool Read7ZipOption(const TCHAR *value, bool defaultValue)
return defaultValue;
}
-static void ReadOption(CKey &key, const TCHAR *value, bool &dest)
+static void ReadOption(CKey &key, LPCTSTR value, bool &dest)
{
bool enabled = false;
if (key.QueryValue(value, enabled) == ERROR_SUCCESS)
@@ -97,14 +97,14 @@ static void ReadOption(CKey &key, const TCHAR *value, bool &dest)
}
/*
-static void SaveLmOption(const TCHAR *value, bool enabled)
+static void SaveLmOption(LPCTSTR value, bool enabled)
{
CKey key;
key.Create(HKEY_LOCAL_MACHINE, kLM_Path);
key.SetValue(value, enabled);
}
-static bool ReadLmOption(const TCHAR *value, bool defaultValue)
+static bool ReadLmOption(LPCTSTR value, bool defaultValue)
{
CKey key;
if (key.Open(HKEY_LOCAL_MACHINE, kLM_Path, KEY_READ) == ERROR_SUCCESS)
diff --git a/CPP/7zip/UI/FileManager/RootFolder.cpp b/CPP/7zip/UI/FileManager/RootFolder.cpp
index b9629263..643f1066 100644
--- a/CPP/7zip/UI/FileManager/RootFolder.cpp
+++ b/CPP/7zip/UI/FileManager/RootFolder.cpp
@@ -79,7 +79,7 @@ enum
};
#ifdef USE_WIN_PATHS
-static const wchar_t *kVolPrefix = L"\\\\.";
+static const char * const kVolPrefix = "\\\\.";
#endif
void CRootFolder::Init()
@@ -194,7 +194,7 @@ static bool AreEqualNames(const UString &path, const wchar_t *name)
unsigned len = MyStringLen(name);
if (len > path.Len() || len + 1 < path.Len())
return false;
- if (len + 1 == path.Len() && path[len] != WCHAR_PATH_SEPARATOR)
+ if (len + 1 == path.Len() && !IS_PATH_SEPAR(path[len]))
return false;
return path.IsPrefixedBy(name);
}
@@ -244,13 +244,13 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
CMyComPtr<IFolderFolder> subFolder;
#ifdef USE_WIN_PATHS
- if (name2.IsPrefixedBy(kVolPrefix))
+ if (name2.IsPrefixedBy_Ascii_NoCase(kVolPrefix))
{
CFSDrives *folderSpec = new CFSDrives;
subFolder = folderSpec;
folderSpec->Init(true);
}
- else if (name2 == NFile::NName::kSuperPathPrefix)
+ else if (name2.IsEqualTo(NFile::NName::kSuperPathPrefix))
{
CFSDrives *folderSpec = new CFSDrives;
subFolder = folderSpec;
@@ -272,7 +272,7 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
if (fsFolderSpec->Init(us2fs(name2)) != S_OK)
{
#ifdef USE_WIN_PATHS
- if (name2[0] == WCHAR_PATH_SEPARATOR)
+ if (IS_PATH_SEPAR(name2[0]))
{
CNetFolder *netFolderSpec = new CNetFolder;
subFolder = netFolderSpec;
diff --git a/CPP/7zip/UI/FileManager/SettingsPage.cpp b/CPP/7zip/UI/FileManager/SettingsPage.cpp
index 07121b28..bdd62f71 100644
--- a/CPP/7zip/UI/FileManager/SettingsPage.cpp
+++ b/CPP/7zip/UI/FileManager/SettingsPage.cpp
@@ -29,7 +29,7 @@ static const UInt32 kLangIDs[] =
IDX_SETTINGS_LARGE_PAGES
};
-static LPCWSTR kEditTopic = L"FM/options.htm#settings";
+#define kSettingsTopic "FM/options.htm#settings"
extern bool IsLargePageSupported();
@@ -108,7 +108,7 @@ LONG CSettingsPage::OnApply()
void CSettingsPage::OnNotifyHelp()
{
- ShowHelpWindow(NULL, kEditTopic); // change it
+ ShowHelpWindow(kSettingsTopic);
}
bool CSettingsPage::OnButtonClicked(int buttonID, HWND buttonHWND)
diff --git a/CPP/7zip/UI/FileManager/SplitDialog.cpp b/CPP/7zip/UI/FileManager/SplitDialog.cpp
index 455874ef..0c9fdd17 100644
--- a/CPP/7zip/UI/FileManager/SplitDialog.cpp
+++ b/CPP/7zip/UI/FileManager/SplitDialog.cpp
@@ -90,7 +90,7 @@ void CSplitDialog::OnButtonSetPath()
{
UString currentPath;
_pathCombo.GetText(currentPath);
- // UString title = L"Specify a location for output folder";
+ // UString title = "Specify a location for output folder";
UString title = LangString(IDS_SET_FOLDER);
UString resultPath;
diff --git a/CPP/7zip/UI/FileManager/SplitUtils.cpp b/CPP/7zip/UI/FileManager/SplitUtils.cpp
index b0172a9f..4b6235b3 100644
--- a/CPP/7zip/UI/FileManager/SplitUtils.cpp
+++ b/CPP/7zip/UI/FileManager/SplitUtils.cpp
@@ -57,16 +57,25 @@ bool ParseVolumeSizes(const UString &s, CRecordVector<UInt64> &values)
return true;
}
+
+static const char * const k_Sizes[] =
+{
+ "10M"
+ , "100M"
+ , "1000M"
+ , "650M - CD"
+ , "700M - CD"
+ , "4092M - FAT"
+ , "4480M - DVD" // 4489 MiB limit
+ , "8128M - DVD DL" // 8147 MiB limit
+ , "23040M - BD" // 23866 MiB limit
+ // , "1457664 - 3.5\" floppy"
+};
+
void AddVolumeItems(NWindows::NControl::CComboBox &combo)
{
- combo.AddString(TEXT("10M"));
- combo.AddString(TEXT("650M - CD"));
- combo.AddString(TEXT("700M - CD"));
- combo.AddString(TEXT("4092M - FAT"));
- combo.AddString(TEXT("4480M - DVD")); // 4489 MiB limit
- combo.AddString(TEXT("8128M - DVD DL")); // 8147 MiB limit
- combo.AddString(TEXT("23040M - BD")); // 23866 MiB limit
- combo.AddString(TEXT("1457664 - 3.5\" floppy"));
+ for (unsigned i = 0; i < ARRAY_SIZE(k_Sizes); i++)
+ combo.AddString(CSysString(k_Sizes[i]));
}
UInt64 GetNumberOfVolumes(UInt64 size, const CRecordVector<UInt64> &volSizes)
diff --git a/CPP/7zip/UI/FileManager/StringUtils.cpp b/CPP/7zip/UI/FileManager/StringUtils.cpp
index 7c814f7f..04783992 100644
--- a/CPP/7zip/UI/FileManager/StringUtils.cpp
+++ b/CPP/7zip/UI/FileManager/StringUtils.cpp
@@ -12,9 +12,9 @@ void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2)
for (unsigned i = 0; i < src.Len(); i++)
{
const wchar_t c = src[i];
- if (c == L'\"')
+ if (c == '\"')
quoteMode = !quoteMode;
- else if (c == L' ' && !quoteMode)
+ else if (c == ' ' && !quoteMode)
{
dest2 = src.Ptr(i + 1);
return;
@@ -34,7 +34,7 @@ void SplitString(const UString &srcString, UStringVector &destStrings)
for (unsigned i = 0; i < len; i++)
{
wchar_t c = srcString[i];
- if (c == L' ')
+ if (c == ' ')
{
if (!s.IsEmpty())
{
diff --git a/CPP/7zip/UI/FileManager/SystemPage.cpp b/CPP/7zip/UI/FileManager/SystemPage.cpp
index 5214a55c..819443ee 100644
--- a/CPP/7zip/UI/FileManager/SystemPage.cpp
+++ b/CPP/7zip/UI/FileManager/SystemPage.cpp
@@ -30,7 +30,7 @@ static const UInt32 kLangIDs[] =
IDT_SYSTEM_ASSOCIATE
};
-static LPCWSTR kSystemTopic = L"FM/options.htm#system";
+#define kSystemTopic "FM/options.htm#system"
CSysString CModifiedExtInfo::GetString() const
{
@@ -165,7 +165,7 @@ bool CSystemPage::OnInit()
UString s;
#if NUM_EXT_GROUPS == 1
- s.SetFromAscii("Program");
+ s = "Program";
#else
#ifndef UNDER_CE
const unsigned kSize = 256;
@@ -190,7 +190,7 @@ bool CSystemPage::OnInit()
if (!res)
#endif
- s.SetFromAscii("Current User");
+ s = "Current User";
#endif
LV_COLUMNW ci;
@@ -257,9 +257,9 @@ bool CSystemPage::OnInit()
static UString GetProgramCommand()
{
- UString s = L"\"";
+ UString s ('\"');
s += fs2us(NDLL::GetModuleDirPrefix());
- s.AddAscii("7zFM.exe\" \"%1\"");
+ s += "7zFM.exe\" \"%1\"";
return s;
}
@@ -291,7 +291,7 @@ LONG CSystemPage::OnApply()
if (mi.State == kExtState_7Zip)
{
UString title = extInfo.Ext;
- title.AddAscii(" Archive");
+ title += " Archive";
const CPluginToIcon &plug = extInfo.Plugins[0];
res2 = NRegistryAssoc::AddShellExtensionInfo(key, GetSystemString(extInfo.Ext),
title, command, plug.IconPath, plug.IconIndex);
@@ -327,7 +327,7 @@ LONG CSystemPage::OnApply()
void CSystemPage::OnNotifyHelp()
{
- ShowHelpWindow(NULL, kSystemTopic);
+ ShowHelpWindow(kSystemTopic);
}
diff --git a/CPP/7zip/UI/FileManager/TextPairs.cpp b/CPP/7zip/UI/FileManager/TextPairs.cpp
index 0fac2506..d4002b45 100644
--- a/CPP/7zip/UI/FileManager/TextPairs.cpp
+++ b/CPP/7zip/UI/FileManager/TextPairs.cpp
@@ -178,13 +178,13 @@ void CPairsStorage::SaveToString(UString &text) const
const CTextPair &pair = Pairs[i];
bool multiWord = (pair.ID.Find(L' ') >= 0);
if (multiWord)
- text += L'\"';
+ text += '\"';
text += pair.ID;
if (multiWord)
- text += L'\"';
- text += L' ';
+ text += '\"';
+ text += ' ';
text += pair.Value;
- text += L'\x0D';
+ text += '\x0D';
text.Add_LF();
}
}
diff --git a/CPP/7zip/UI/FileManager/ViewSettings.cpp b/CPP/7zip/UI/FileManager/ViewSettings.cpp
index 9292d120..af61efcd 100644
--- a/CPP/7zip/UI/FileManager/ViewSettings.cpp
+++ b/CPP/7zip/UI/FileManager/ViewSettings.cpp
@@ -17,18 +17,19 @@ using namespace NRegistry;
#define REG_PATH_FM TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR) TEXT("FM")
-static const TCHAR *kCUBasePath = REG_PATH_FM;
-static const TCHAR *kCulumnsKeyName = REG_PATH_FM TEXT(STRING_PATH_SEPARATOR) TEXT("Columns");
+static LPCTSTR const kCUBasePath = REG_PATH_FM;
+static LPCTSTR const kCulumnsKeyName = REG_PATH_FM TEXT(STRING_PATH_SEPARATOR) TEXT("Columns");
-static const TCHAR *kPositionValueName = TEXT("Position");
-static const TCHAR *kPanelsInfoValueName = TEXT("Panels");
-static const TCHAR *kToolbars = TEXT("Toolbars");
+static LPCTSTR const kPositionValueName = TEXT("Position");
+static LPCTSTR const kPanelsInfoValueName = TEXT("Panels");
+static LPCTSTR const kToolbars = TEXT("Toolbars");
-static const WCHAR *kPanelPathValueName = L"PanelPath";
-static const TCHAR *kListMode = TEXT("ListMode");
-static const TCHAR *kFolderHistoryValueName = TEXT("FolderHistory");
-static const TCHAR *kFastFoldersValueName = TEXT("FolderShortcuts");
-static const TCHAR *kCopyHistoryValueName = TEXT("CopyHistory");
+static LPCWSTR const kPanelPathValueName = L"PanelPath";
+
+static LPCTSTR const kListMode = TEXT("ListMode");
+static LPCTSTR const kFolderHistoryValueName = TEXT("FolderHistory");
+static LPCTSTR const kFastFoldersValueName = TEXT("FolderShortcuts");
+static LPCTSTR const kCopyHistoryValueName = TEXT("CopyHistory");
static NSynchronization::CCriticalSection g_CS;
@@ -246,9 +247,9 @@ void CListMode::Read()
static UString GetPanelPathName(UInt32 panelIndex)
{
- WCHAR s[16];
- ConvertUInt32ToString(panelIndex, s);
- return (UString)kPanelPathValueName + s;
+ UString s (kPanelPathValueName);
+ s.Add_UInt32(panelIndex);
+ return s;
}
void SavePanelPath(UInt32 panel, const UString &path)
diff --git a/CPP/7zip/UI/FileManager/resource.h b/CPP/7zip/UI/FileManager/resource.h
index b7ca17f1..bb0d7752 100644
--- a/CPP/7zip/UI/FileManager/resource.h
+++ b/CPP/7zip/UI/FileManager/resource.h
@@ -85,6 +85,8 @@
#define IDM_VIEW_TOOLBARS_LARGE_BUTTONS 752
#define IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT 753
+#define IDM_VIEW_TIME 761
+
#define IDS_BOOKMARK 801
#define IDM_OPTIONS 900
diff --git a/CPP/7zip/UI/FileManager/resource.rc b/CPP/7zip/UI/FileManager/resource.rc
index 7db5d3a1..a166129b 100644
--- a/CPP/7zip/UI/FileManager/resource.rc
+++ b/CPP/7zip/UI/FileManager/resource.rc
@@ -83,6 +83,12 @@ BEGIN
MENUITEM SEPARATOR
MENUITEM "Flat View", IDM_VIEW_FLAT_VIEW
MENUITEM "&2 Panels\tF9", IDM_VIEW_TWO_PANELS
+
+ POPUP "2017"
+ BEGIN
+ MENUITEM "Time", IDM_VIEW_TIME
+ END
+
POPUP "Toolbars"
BEGIN
MENUITEM "Archive Toolbar", IDM_VIEW_ARCHIVE_TOOLBAR
@@ -112,9 +118,10 @@ BEGIN
POPUP "&Tools"
BEGIN
MENUITEM "&Options...", IDM_OPTIONS
+ MENUITEM SEPARATOR
MENUITEM "&Benchmark", IDM_BENCHMARK
#ifdef UNDER_CE
- MENUITEM "&Benchmark2", IDM_BENCHMARK2
+ MENUITEM "Benchmark 2", IDM_BENCHMARK2
#endif
#ifndef UNDER_CE
END
diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp
index 4fba3dc3..59dc78b3 100644
--- a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp
+++ b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp
@@ -23,9 +23,7 @@
using namespace NWindows;
-void GetCpuName(AString &s);
-
-static LPCWSTR kHelpTopic = L"fm/benchmark.htm";
+#define kHelpTopic "fm/benchmark.htm"
static const UINT_PTR kTimerID = 4;
static const UINT kTimerElapse = 1000;
@@ -66,10 +64,10 @@ static const UInt32 kLangIDs_Colon[] =
#endif
-static const LPCTSTR kProcessingString = TEXT("...");
-static const LPCTSTR kMB = TEXT(" MB");
-static const LPCTSTR kMIPS = TEXT(" MIPS");
-static const LPCTSTR kKBs = TEXT(" KB/s");
+static LPCTSTR const kProcessingString = TEXT("...");
+static LPCTSTR const kMB = TEXT(" MB");
+static LPCTSTR const kMIPS = TEXT(" MIPS");
+static LPCTSTR const kKBs = TEXT(" KB/s");
static const unsigned kMinDicLogSize =
#ifdef UNDER_CE
@@ -119,35 +117,67 @@ bool CBenchmarkDialog::OnInit()
_consoleEdit.SendMsg(WM_SETFONT, (WPARAM)_font._font, TRUE);
}
+ UInt32 numCPUs = 1;
+
{
- TCHAR s[40];
- s[0] = '/';
- s[1] = ' ';
- ConvertUInt32ToString(NSystem::GetNumberOfProcessors(), s + 2);
+ UString s ("/ ");
+
+ NSystem::CProcessAffinity threadsInfo;
+ threadsInfo.InitST();
+
+ #ifndef _7ZIP_ST
+
+ if (threadsInfo.Get() && threadsInfo.processAffinityMask != 0)
+ numCPUs = threadsInfo.GetNumProcessThreads();
+ else
+ numCPUs = NSystem::GetNumberOfProcessors();
+
+ #endif
+
+ s.Add_UInt32(numCPUs);
+ s += GetProcessThreadsInfo(threadsInfo);
SetItemText(IDT_BENCH_HARDWARE_THREADS, s);
}
{
UString s;
{
- AString cpuName;
- GetCpuName(cpuName);
- s.SetFromAscii(cpuName);
+ AString s1, s2;
+ GetSysInfo(s1, s2);
+ s = s1;
+ SetItemText(IDT_BENCH_SYS1, s);
+ if (s1 != s2 && !s2.IsEmpty())
+ {
+ s = s2;
+ SetItemText(IDT_BENCH_SYS2, s);
+ }
+ }
+ /*
+ {
+ GetVersionString(s);
+ SetItemText(IDT_BENCH_SYSTEM, s);
+ }
+ */
+ {
+ AString s2;
+ GetCpuName(s2);
+ s = s2;
SetItemText(IDT_BENCH_CPU, s);
}
+ /*
+ {
+ AString s2;
+ GetCpuFeatures(s2);
+ s = s2;
+ SetItemText(IDT_BENCH_CPU_FEATURE, s);
+ }
+ */
- s.SetFromAscii("7-Zip " MY_VERSION " ["
- #ifdef MY_CPU_64BIT
- "64-bit"
- #elif defined MY_CPU_32BIT
- "32-bit"
- #endif
- "]");
+ s = "7-Zip " MY_VERSION_CPU;
SetItemText(IDT_BENCH_VER, s);
}
- UInt32 numCPUs = NSystem::GetNumberOfProcessors();
if (numCPUs < 1)
numCPUs = 1;
numCPUs = MyMin(numCPUs, (UInt32)(1 << 8));
@@ -178,8 +208,8 @@ bool CBenchmarkDialog::OnInit()
m_Dictionary.Attach(GetItem(IDC_BENCH_DICTIONARY));
cur = 0;
- UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29;
- bool ramSize_Defined = NSystem::GetRamSize(ramSize);
+ ramSize = (UInt64)(sizeof(size_t)) << 29;
+ ramSize_Defined = NSystem::GetRamSize(ramSize);
#ifdef UNDER_CE
const UInt32 kNormalizedCeSize = (16 << 20);
@@ -208,10 +238,10 @@ bool CBenchmarkDialog::OnInit()
for (unsigned i = kMinDicLogSize; i <= 30; i++)
for (unsigned j = 0; j < 2; j++)
{
- UInt32 dict = (1 << i) + (j << (i - 1));
+ UInt32 dict = ((UInt32)1 << i) + ((UInt32)j << (i - 1));
if (dict > kMaxDicSize)
continue;
- TCHAR s[16];
+ TCHAR s[32];
ConvertUInt32ToString((dict >> 20), s);
lstrcat(s, kMB);
int index = (int)m_Dictionary.AddString(s);
@@ -276,15 +306,43 @@ UInt32 CBenchmarkDialog::GetNumberOfThreads()
return (UInt32)m_NumThreads.GetItemData_of_CurSel();
}
+
+void CBenchmarkDialog::SetItemText_Number(int itemID, UInt64 val, LPCTSTR post)
+{
+ TCHAR s[64];
+ ConvertUInt64ToString(val, s);
+ if (post)
+ lstrcat(s, post);
+ SetItemText(itemID, s);
+}
+
+static void PrintSize_MB(UString &s, UInt64 size)
+{
+ char temp[32];
+ ConvertUInt64ToString((size + (1 << 20) - 1) >> 20, temp);
+ s += temp;
+ s += kMB;
+}
+
+extern bool g_LargePagesMode;
+
UInt32 CBenchmarkDialog::OnChangeDictionary()
{
- UInt32 dict = (UInt32)m_Dictionary.GetItemData_of_CurSel();
- UInt64 memUsage = GetBenchMemoryUsage(GetNumberOfThreads(), dict);
- memUsage = (memUsage + (1 << 20) - 1) >> 20;
- TCHAR s[40];
- ConvertUInt64ToString(memUsage, s);
- lstrcat(s, kMB);
+ const UInt32 dict = (UInt32)m_Dictionary.GetItemData_of_CurSel();
+ const UInt64 memUsage = GetBenchMemoryUsage(GetNumberOfThreads(), dict);
+
+ UString s;
+ PrintSize_MB(s, memUsage);
+ if (ramSize_Defined)
+ {
+ s += " / ";
+ PrintSize_MB(s, ramSize);
+ }
+ if (g_LargePagesMode)
+ s += " LP";
+
SetItemText(IDT_BENCH_MEMORY_VAL, s);
+
return dict;
}
@@ -311,6 +369,9 @@ static const UInt32 g_IDs[] =
IDT_BENCH_TOTAL_USAGE_VAL,
IDT_BENCH_TOTAL_RATING_VAL,
IDT_BENCH_TOTAL_RPU_VAL
+
+ // IDT_BENCH_FREQ_CUR,
+ // IDT_BENCH_FREQ_RES
};
void CBenchmarkDialog::OnChangeSettings()
@@ -342,7 +403,7 @@ void CBenchmarkDialog::OnStopButton()
void CBenchmarkDialog::OnHelp()
{
- ShowHelpWindow(NULL, kHelpTopic);
+ ShowHelpWindow(kHelpTopic);
}
void CBenchmarkDialog::OnCancel()
@@ -368,18 +429,12 @@ void CBenchmarkDialog::PrintTime()
void CBenchmarkDialog::PrintRating(UInt64 rating, UINT controlID)
{
- TCHAR s[40];
- ConvertUInt64ToString(rating / 1000000, s);
- lstrcat(s, kMIPS);
- SetItemText(controlID, s);
+ SetItemText_Number(controlID, rating / 1000000, kMIPS);
}
void CBenchmarkDialog::PrintUsage(UInt64 usage, UINT controlID)
{
- TCHAR s[40];
- ConvertUInt64ToString((usage + 5000) / 10000, s);
- lstrcat(s, TEXT("%"));
- SetItemText(controlID, s);
+ SetItemText_Number(controlID, (usage + 5000) / 10000, TEXT("%"));
}
void CBenchmarkDialog::PrintResults(
@@ -391,12 +446,9 @@ void CBenchmarkDialog::PrintResults(
if (info.GlobalTime == 0)
return;
- TCHAR s[40];
{
- UInt64 speed = info.UnpackSize * info.NumIterations * info.GlobalFreq / info.GlobalTime;
- ConvertUInt64ToString(speed / 1024, s);
- lstrcat(s, kKBs);
- SetItemText(speedID, s);
+ const UInt64 speed = info.UnpackSize * info.NumIterations * info.GlobalFreq / info.GlobalTime;
+ SetItemText_Number(speedID, speed >> 10, kKBs);
}
UInt64 rating;
if (decompressMode)
@@ -419,25 +471,36 @@ bool CBenchmarkDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
}
if (printTime)
PrintTime();
- NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS);
if (TotalMode)
{
- if (Sync.TextWasChanged)
+ bool wasChanged = false;
{
- _consoleEdit.SetText(GetSystemString(Sync.Text));
- Sync.TextWasChanged = false;
+ NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS);
+
+ if (Sync.TextWasChanged)
+ {
+ wasChanged = true;
+ Bench2Text += Sync.Text;
+ Sync.Text.Empty();
+ Sync.TextWasChanged = false;
+ }
}
+ if (wasChanged)
+ _consoleEdit.SetText(Bench2Text);
return true;
}
- TCHAR s[40];
- ConvertUInt64ToString((Sync.ProcessedSize >> 20), s);
- lstrcat(s, kMB);
- SetItemText(IDT_BENCH_SIZE_VAL, s);
+ SetItemText_Number(IDT_BENCH_SIZE_VAL, (Sync.ProcessedSize >> 20), kMB);
- ConvertUInt64ToString(Sync.NumPasses, s);
- SetItemText(IDT_BENCH_PASSES_VAL, s);
+ SetItemText_Number(IDT_BENCH_PASSES_VAL, Sync.NumPasses);
+
+ /*
+ if (Sync.FirstPath)
+ SetItemText_Number(IDT_BENCH_FREQ_CUR, Sync.Freq, TEXT(" MHz"));
+ else
+ SetItemText_Number(IDT_BENCH_FREQ_RES, Sync.Freq, TEXT(" MHz"));
+ */
/*
if (Sync.FreqWasChanged)
@@ -549,7 +612,7 @@ struct CThreadBenchmark
struct CBenchCallback: public IBenchCallback
{
UInt32 dictionarySize;
- CProgressSyncInfo *Sync;
+ CBenchProgressSync *Sync;
// void AddCpuFreq(UInt64 cpuFreq);
HRESULT SetFreq(bool showFreq, UInt64 cpuFreq);
@@ -613,7 +676,8 @@ HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final)
struct CBenchCallback2: public IBenchPrintCallback
{
- CProgressSyncInfo *Sync;
+ CBenchProgressSync *Sync;
+ bool TotalMode;
void Print(const char *s);
void NewLine();
@@ -622,9 +686,12 @@ struct CBenchCallback2: public IBenchPrintCallback
void CBenchCallback2::Print(const char *s)
{
- NSynchronization::CCriticalSectionLock lock(Sync->CS);
- Sync->Text += s;
- Sync->TextWasChanged = true;
+ if (TotalMode)
+ {
+ NSynchronization::CCriticalSectionLock lock(Sync->CS);
+ Sync->Text += s;
+ Sync->TextWasChanged = true;
+ }
}
void CBenchCallback2::NewLine()
@@ -640,9 +707,27 @@ HRESULT CBenchCallback2::CheckBreak()
}
+
+/*
+struct CFreqCallback: public IBenchFreqCallback
+{
+ CBenchProgressSync *Sync;
+
+ virtual void AddCpuFreq(UInt64 freq);
+};
+
+void CFreqCallback::AddCpuFreq(UInt64 freq)
+{
+ NSynchronization::CCriticalSectionLock lock(Sync->CS);
+ Sync->Freq = freq;
+}
+*/
+
+
+
HRESULT CThreadBenchmark::Process()
{
- CProgressSyncInfo &sync = BenchmarkDialog->Sync;
+ CBenchProgressSync &sync = BenchmarkDialog->Sync;
sync.WaitCreating();
try
{
@@ -665,13 +750,20 @@ HRESULT CThreadBenchmark::Process()
sync.Init();
dictionarySize = sync.DictionarySize;
numThreads = sync.NumThreads;
+ /*
+ if (sync.CompressingInfo.GlobalTime != 0)
+ sync.FirstPath = false;
+ */
}
CBenchCallback callback;
callback.dictionarySize = dictionarySize;
callback.Sync = &sync;
CBenchCallback2 callback2;
+ callback2.TotalMode = BenchmarkDialog->TotalMode;
callback2.Sync = &sync;
+ // CFreqCallback freqCallback;
+ // freqCallback.Sync = &sync;
HRESULT result;
try
@@ -685,26 +777,25 @@ HRESULT CThreadBenchmark::Process()
{
{
CProperty prop;
- prop.Name = L"mt";
- wchar_t s[16];
- ConvertUInt32ToString(numThreads, s);
- prop.Value = s;
+ prop.Name = "mt";
+ prop.Value.Add_UInt32(numThreads);
props.Add(prop);
}
{
CProperty prop;
- prop.Name = L'd';
- wchar_t s[16];
- ConvertUInt32ToString(dictionarySize, s);
- prop.Name += s;
- prop.Name += L'b';
+ prop.Name = 'd';
+ prop.Name.Add_UInt32(dictionarySize);
+ prop.Name += 'b';
props.Add(prop);
}
}
+
result = Bench(EXTERNAL_CODECS_LOC_VARS
BenchmarkDialog->TotalMode ? &callback2 : NULL,
BenchmarkDialog->TotalMode ? NULL : &callback,
+ // &freqCallback,
props, 1, false);
+
if (BenchmarkDialog->TotalMode)
{
sync.Stop();
@@ -725,9 +816,9 @@ HRESULT CThreadBenchmark::Process()
}
UString message;
if (result == S_FALSE)
- message = L"Decoding error";
+ message = "Decoding error";
else if (result == CLASS_E_CLASSNOTAVAILABLE)
- message = L"Can't find 7z.dll";
+ message = "Can't find 7z.dll";
else
message = HResultToMessage(result);
BenchmarkDialog->MessageBoxError(message);
@@ -820,7 +911,13 @@ HRESULT Benchmark(
RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant));
}
- // bool totalBenchMode = (method.MethodName == L"*");
+ if (bd.TotalMode)
+ {
+ // bd.Bench2Text.Empty();
+ bd.Bench2Text = "7-Zip " MY_VERSION_CPU;
+ bd.Bench2Text += (char)0xD;
+ bd.Bench2Text.Add_LF();
+ }
{
UInt32 dict;
diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.h b/CPP/7zip/UI/GUI/BenchmarkDialog.h
index 0d88d217..1bad8ea9 100644
--- a/CPP/7zip/UI/GUI/BenchmarkDialog.h
+++ b/CPP/7zip/UI/GUI/BenchmarkDialog.h
@@ -29,7 +29,7 @@ struct CBenchInfo2 : public CBenchInfo
}
};
-class CProgressSyncInfo
+class CBenchProgressSync
{
public:
bool Stopped;
@@ -51,10 +51,12 @@ public:
AString Text;
bool TextWasChanged;
+ // bool FirstPath;
+ // UInt64 Freq;
// UString Freq;
// bool FreqWasChanged;
- CProgressSyncInfo()
+ CBenchProgressSync()
{
if (_startEvent.Create() != S_OK)
throw 3986437;
@@ -74,6 +76,8 @@ public:
NumPasses = 0;
+ // FirstPath = true;
+ // Freq = 0;
// Freq.SetFromAscii("MHz: ");
// FreqWasChanged = true;
@@ -135,6 +139,9 @@ class CBenchmarkDialog:
UInt32 _startTime;
CMyFont _font;
+ UInt64 ramSize;
+ bool ramSize_Defined;
+
bool OnSize(WPARAM /* wParam */, int xSize, int ySize);
bool OnTimer(WPARAM timerID, LPARAM callback);
virtual bool OnInit();
@@ -156,11 +163,16 @@ class CBenchmarkDialog:
UInt32 GetNumberOfThreads();
UInt32 OnChangeDictionary();
void OnChangeSettings();
+
+ void SetItemText_Number(int itemID, UInt64 val, LPCTSTR post = NULL);
+
public:
- CProgressSyncInfo Sync;
+ CBenchProgressSync Sync;
bool TotalMode;
CObjectVector<CProperty> Props;
+ CSysString Bench2Text;
+
CBenchmarkDialog(): _timer(0), TotalMode(false) {}
INT_PTR Create(HWND wndParent = 0)
{
diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.rc b/CPP/7zip/UI/GUI/BenchmarkDialog.rc
index cae9097b..f1d37cab 100644
--- a/CPP/7zip/UI/GUI/BenchmarkDialog.rc
+++ b/CPP/7zip/UI/GUI/BenchmarkDialog.rc
@@ -16,7 +16,7 @@
#define gSpace 24
#define g0xs 90
-#define g1xs 44
+#define g1xs 48
#define g1x (m + g0xs)
#define gc2x (g1x + g1xs + m)
#define gc2xs 80
@@ -27,12 +27,15 @@
#define sSpeed 60
#define sUsage 60
#define sRpu 60
+#define sFreq 34
#define xRating (xs - m - m - sRating)
#define xRpu (xRating - sRpu)
#define xUsage (xRpu - sUsage)
#define xSpeed (xUsage - sSpeed)
+#define xFreq (xUsage - sFreq)
+
#define sLabel (xUsage - g4x)
#define sTotalRating (sUsage + sRpu + sRating + m + m)
#define xTotalRating (xs - m - sTotalRating)
@@ -51,6 +54,8 @@
#define GROUP_Y2_SIZE 32
#endif
+#define g7xs bx1 - m - g0xs - g1xs - m
+
IDD_BENCH DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX
CAPTION "Benchmark"
MY_FONT
@@ -64,12 +69,12 @@ BEGIN
LTEXT "&Dictionary size:", IDT_BENCH_DICTIONARY, m, m + 1, g0xs, 8
COMBOBOX IDC_BENCH_DICTIONARY, g1x, m, g1xs, 140, MY_COMBO
- LTEXT "Memory usage:", IDT_BENCH_MEMORY, gc2x, m + 1, gc2xs, 8
- LTEXT "", IDT_BENCH_MEMORY_VAL, gc2x + gc2xs, m + 1, 40, 8
+ LTEXT "Memory usage:", IDT_BENCH_MEMORY, gc2x, m - 2, g7xs, 8
+ LTEXT "", IDT_BENCH_MEMORY_VAL, gc2x, m + 8, g7xs, 8
- LTEXT "&Number of CPU threads:", IDT_BENCH_NUM_THREADS, m, 28, g0xs, 8
- COMBOBOX IDC_BENCH_NUM_THREADS, g1x, 27, g1xs, 140, MY_COMBO
- LTEXT "", IDT_BENCH_HARDWARE_THREADS, gc2x, 28, 40, 8
+ LTEXT "&Number of CPU threads:", IDT_BENCH_NUM_THREADS, m, 30, g0xs, 8
+ COMBOBOX IDC_BENCH_NUM_THREADS, g1x, 29, g1xs, 140, MY_COMBO
+ LTEXT "", IDT_BENCH_HARDWARE_THREADS, gc2x, 32, g7xs, 8
RTEXT "CPU Usage", IDT_BENCH_USAGE_LABEL, xUsage, 54, sUsage, 8
RTEXT "Speed", IDT_BENCH_SPEED, xSpeed, 54, sSpeed, 8
@@ -111,7 +116,17 @@ BEGIN
RTEXT "", IDT_BENCH_TOTAL_RATING_VAL, xRating, 176, sRating, 8
RTEXT "", IDT_BENCH_CPU, m, 202, xc, 8
- RTEXT "", IDT_BENCH_VER, m, 216, xc, 8
+
+ RTEXT "", IDT_BENCH_VER, m + xc - 80, 216, 80, 8
+
+ LTEXT "", IDT_BENCH_CPU_FEATURE, m, 212, xc - 80, 26
+ LTEXT "", IDT_BENCH_SYS1, m, 238, xc - 140, 8
+ LTEXT "", IDT_BENCH_SYS2, m, 248, xc - 140, 8
+
+ // LTEXT "", IDT_BENCH_SYSTEM, m, 232, xc - 80, 8
+ // LTEXT "", IDT_BENCH_FREQ_RES, m, 242, 80, 8
+
+
LTEXT "Elapsed time:", IDT_BENCH_ELAPSED, m, 163, g2xs, 8
LTEXT "Size:", IDT_BENCH_SIZE, m, 176, g2xs, 8
diff --git a/CPP/7zip/UI/GUI/BenchmarkDialogRes.h b/CPP/7zip/UI/GUI/BenchmarkDialogRes.h
index a632d764..8ee4f681 100644
--- a/CPP/7zip/UI/GUI/BenchmarkDialogRes.h
+++ b/CPP/7zip/UI/GUI/BenchmarkDialogRes.h
@@ -11,6 +11,9 @@
#define IDT_BENCH_VER 105
#define IDT_BENCH_CPU 106
+#define IDT_BENCH_SYS1 107
+#define IDT_BENCH_SYS2 108
+#define IDT_BENCH_CPU_FEATURE 109
#define IDT_BENCH_COMPRESS_SPEED1 110
#define IDT_BENCH_COMPRESS_SPEED2 111
@@ -39,6 +42,9 @@
#define IDT_BENCH_PASSES_VAL 142
+// #define IDT_BENCH_FREQ_CUR 150
+// #define IDT_BENCH_FREQ_RES 151
+
#define IDB_STOP 442
#define IDB_RESTART 443
diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp
index 14a9d31c..57f7c30a 100644
--- a/CPP/7zip/UI/GUI/CompressDialog.cpp
+++ b/CPP/7zip/UI/GUI/CompressDialog.cpp
@@ -80,8 +80,9 @@ using namespace NDir;
static const unsigned kHistorySize = 20;
-static LPCWSTR kExeExt = L".exe";
-static LPCWSTR k7zFormat = L"7z";
+static LPCSTR const kExeExt = ".exe";
+
+#define k7zFormat "7z"
static const UInt32 g_Levels[] =
{
@@ -109,16 +110,16 @@ enum EMethodID
kPPMdZip
};
-static const LPCWSTR kMethodsNames[] =
+static LPCSTR const kMethodsNames[] =
{
- L"Copy",
- L"LZMA",
- L"LZMA2",
- L"PPMd",
- L"BZip2",
- L"Deflate",
- L"Deflate64",
- L"PPMd"
+ "Copy"
+ , "LZMA"
+ , "LZMA2"
+ , "PPMd"
+ , "BZip2"
+ , "Deflate"
+ , "Deflate64"
+ , "PPMd"
};
static const EMethodID g_7zMethods[] =
@@ -169,10 +170,10 @@ static const EMethodID g_SwfcMethods[] =
struct CFormatInfo
{
- LPCWSTR Name;
+ LPCSTR Name;
UInt32 LevelsMask;
- const EMethodID *MathodIDs;
unsigned NumMethods;
+ const EMethodID *MathodIDs;
bool Filter;
bool Solid;
bool MultiThread;
@@ -182,12 +183,12 @@ struct CFormatInfo
bool EncryptFileNames;
};
-#define METHODS_PAIR(x) x, ARRAY_SIZE(x)
+#define METHODS_PAIR(x) ARRAY_SIZE(x), x
static const CFormatInfo g_Formats[] =
{
{
- L"",
+ "",
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
0, 0,
false, false, false, false, false, false
@@ -199,43 +200,43 @@ static const CFormatInfo g_Formats[] =
true, true, true, true, true, true
},
{
- L"Zip",
+ "Zip",
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
METHODS_PAIR(g_ZipMethods),
false, false, true, false, true, false
},
{
- L"GZip",
+ "GZip",
(1 << 1) | (1 << 5) | (1 << 7) | (1 << 9),
METHODS_PAIR(g_GZipMethods),
false, false, false, false, false, false
},
{
- L"BZip2",
+ "BZip2",
(1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
METHODS_PAIR(g_BZip2Methods),
false, false, true, false, false, false
},
{
- L"xz",
+ "xz",
(1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
METHODS_PAIR(g_XzMethods),
false, false, true, false, false, false
},
{
- L"Swfc",
+ "Swfc",
(1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
METHODS_PAIR(g_SwfcMethods),
false, false, true, false, false, false
},
{
- L"Tar",
+ "Tar",
(1 << 0),
0, 0,
false, false, false, false, false, false
},
{
- L"wim",
+ "wim",
(1 << 0),
0, 0,
false, false, false, false, false, false
@@ -383,6 +384,8 @@ bool CCompressDialog::OnInit()
}
}
+ CheckButton(IDX_COMPRESS_SFX, Info.SFXMode);
+
{
UString fileName;
SetArcPathFields(Info.ArcPath, fileName, true);
@@ -408,7 +411,6 @@ bool CCompressDialog::OnInit()
ConvertUInt32ToString(NSystem::GetNumberOfProcessors(), s + 2);
SetItemText(IDT_COMPRESS_HARDWARE_THREADS, s);
- CheckButton(IDX_COMPRESS_SFX, Info.SFXMode);
CheckButton(IDX_COMPRESS_SHARED, Info.OpenShareForWrite);
CheckButton(IDX_COMPRESS_DEL, Info.DeleteAfterCompressing);
@@ -580,7 +582,7 @@ void CCompressDialog::OnButtonSFX()
if (dotPos >= 0)
{
UString ext = fileName.Ptr(dotPos);
- if (ext.IsEqualTo_NoCase(kExeExt))
+ if (ext.IsEqualTo_Ascii_NoCase(kExeExt))
{
fileName.DeleteFrom(dotPos);
m_ArchivePath.SetText(fileName);
@@ -639,7 +641,7 @@ bool CCompressDialog::SetArcPathFields(const UString &path, UString &name, bool
return res;
}
-static const wchar_t *k_IncorrectPathMessage = L"Incorrect archive path";
+static const wchar_t * const k_IncorrectPathMessage = L"Incorrect archive path";
void CCompressDialog::OnButtonSetArchive()
{
@@ -652,7 +654,7 @@ void CCompressDialog::OnButtonSetArchive()
UString title = LangString(IDS_COMPRESS_SET_ARCHIVE_BROWSE);
UString filterDescription = LangString(IDS_OPEN_TYPE_ALL_FILES);
- filterDescription += L" (*.*)";
+ filterDescription += " (*.*)";
UString resPath;
CurrentDirWasChanged = true;
if (!MyBrowseForFile(*this, title,
@@ -812,11 +814,11 @@ void CCompressDialog::OnOK()
CModalDialog::OnOK();
}
-static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/add.htm";
+#define kHelpTopic "fm/plugins/7-zip/add.htm"
void CCompressDialog::OnHelp()
{
- ShowHelpWindow(NULL, kHelpTopic);
+ ShowHelpWindow(kHelpTopic);
}
bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam)
@@ -917,7 +919,10 @@ void CCompressDialog::SetArchiveName2(bool prevWasSFX)
if (prevWasSFX)
prevExtension = kExeExt;
else
- prevExtension = UString(L'.') + prevArchiverInfo.GetMainExt();
+ {
+ prevExtension += '.';
+ prevExtension += prevArchiverInfo.GetMainExt();
+ }
const unsigned prevExtensionLen = prevExtension.Len();
if (fileName.Len() >= prevExtensionLen)
if (StringsAreEqualNoCase(fileName.RightPtr(prevExtensionLen), prevExtension))
@@ -954,7 +959,7 @@ void CCompressDialog::SetArchiveName(const UString &name)
fileName += kExeExt;
else
{
- fileName += L'.';
+ fileName += '.';
fileName += ai.GetMainExt();
}
m_ArchivePath.SetText(fileName);
@@ -987,7 +992,7 @@ int CCompressDialog::GetStaticFormatIndex()
{
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
for (unsigned i = 0; i < ARRAY_SIZE(g_Formats); i++)
- if (ai.Name.IsEqualTo_NoCase(g_Formats[i].Name))
+ if (ai.Name.IsEqualTo_Ascii_NoCase(g_Formats[i].Name))
return i;
return 0; // -1;
}
@@ -1035,6 +1040,13 @@ void CCompressDialog::SetLevel()
SetMethod();
}
+
+static LRESULT ComboBox_AddStringAscii(NControl::CComboBox &cb, const char *s)
+{
+ return cb.AddString((CSysString)s);
+}
+
+
void CCompressDialog::SetMethod(int keepMethodId)
{
m_Method.ResetContent();
@@ -1063,8 +1075,8 @@ void CCompressDialog::SetMethod(int keepMethodId)
if (isSfx)
if (!IsMethodSupportedBySfx(methodID))
continue;
- const LPCWSTR method = kMethodsNames[methodID];
- int itemIndex = (int)m_Method.AddString(GetSystemString(method));
+ const char *method = kMethodsNames[methodID];
+ int itemIndex = (int)ComboBox_AddStringAscii(m_Method, method);
m_Method.SetItemData(itemIndex, methodID);
if (keepMethodId == methodID)
{
@@ -1072,7 +1084,7 @@ void CCompressDialog::SetMethod(int keepMethodId)
weUseSameMethod = true;
continue;
}
- if ((defaultMethod.IsEqualTo_NoCase(method) || m == 0) && !weUseSameMethod)
+ if ((defaultMethod.IsEqualTo_Ascii_NoCase(method) || m == 0) && !weUseSameMethod)
m_Method.SetCurSel(itemIndex);
}
@@ -1095,7 +1107,7 @@ void CCompressDialog::SetEncryptionMethod()
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
if (ai.Name.IsEqualTo_Ascii_NoCase("7z"))
{
- _encryptionMethod.AddString(TEXT("AES-256"));
+ ComboBox_AddStringAscii(_encryptionMethod, "AES-256");
_encryptionMethod.SetCurSel(0);
}
else if (ai.Name.IsEqualTo_Ascii_NoCase("zip"))
@@ -1107,8 +1119,8 @@ void CCompressDialog::SetEncryptionMethod()
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
encryptionMethod = fo.EncryptionMethod;
}
- _encryptionMethod.AddString(TEXT("ZipCrypto"));
- _encryptionMethod.AddString(TEXT("AES-256"));
+ ComboBox_AddStringAscii(_encryptionMethod, "ZipCrypto");
+ ComboBox_AddStringAscii(_encryptionMethod, "AES-256");
_encryptionMethod.SetCurSel(encryptionMethod.IsPrefixedBy_Ascii_NoCase("aes") ? 1 : 0);
}
}
@@ -1122,21 +1134,22 @@ int CCompressDialog::GetMethodID()
UString CCompressDialog::GetMethodSpec()
{
- if (m_Method.GetCount() <= 1)
- return UString();
- return kMethodsNames[GetMethodID()];
+ UString s;
+ if (m_Method.GetCount() > 1)
+ s = kMethodsNames[GetMethodID()];
+ return s;
}
UString CCompressDialog::GetEncryptionMethodSpec()
{
- if (_encryptionMethod.GetCount() <= 1)
- return UString();
- if (_encryptionMethod.GetCurSel() <= 0)
- return UString();
- UString result;
- _encryptionMethod.GetText(result);
- result.RemoveChar(L'-');
- return result;
+ UString s;
+ if (_encryptionMethod.GetCount() > 1
+ && _encryptionMethod.GetCurSel() > 0)
+ {
+ _encryptionMethod.GetText(s);
+ s.RemoveChar(L'-');
+ }
+ return s;
}
void CCompressDialog::AddDictionarySize(UInt32 size)
diff --git a/CPP/7zip/UI/GUI/ExtractDialog.cpp b/CPP/7zip/UI/GUI/ExtractDialog.cpp
index af47fc2d..b36a4943 100644
--- a/CPP/7zip/UI/GUI/ExtractDialog.cpp
+++ b/CPP/7zip/UI/GUI/ExtractDialog.cpp
@@ -143,7 +143,7 @@ bool CExtractDialog::OnInit()
GetText(s);
if (!ArcPath.IsEmpty())
{
- s.AddAscii(" : ");
+ s += " : ";
s += ArcPath;
}
SetText(s);
@@ -409,10 +409,10 @@ void CExtractDialog::OnOK()
}
#ifndef NO_REGISTRY
-static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/extract.htm";
+#define kHelpTopic "fm/plugins/7-zip/extract.htm"
void CExtractDialog::OnHelp()
{
- ShowHelpWindow(NULL, kHelpTopic);
+ ShowHelpWindow(kHelpTopic);
CModalDialog::OnHelp();
}
#endif
diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp
index 7fb843a1..5071d1f0 100644
--- a/CPP/7zip/UI/GUI/ExtractGUI.cpp
+++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp
@@ -34,7 +34,7 @@ using namespace NWindows;
using namespace NFile;
using namespace NDir;
-static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path";
+static const wchar_t * const kIncorrectOutDir = L"Incorrect output directory path";
#ifndef _SFX
@@ -42,28 +42,31 @@ static void AddValuePair(UString &s, UINT resourceID, UInt64 value, bool addColo
{
AddLangString(s, resourceID);
if (addColon)
- s += L':';
+ s += ':';
s.Add_Space();
char sz[32];
ConvertUInt64ToString(value, sz);
- s.AddAscii(sz);
+ s += sz;
s.Add_LF();
}
static void AddSizePair(UString &s, UINT resourceID, UInt64 value)
{
- wchar_t sz[32];
- AddLangString(s, resourceID);
- s += L": ";
- ConvertUInt64ToString(value, sz);
- s += MyFormatNew(IDS_FILE_SIZE, sz);
+ {
+ wchar_t sz[32];
+ AddLangString(s, resourceID);
+ s += ": ";
+ ConvertUInt64ToString(value, sz);
+ s += MyFormatNew(IDS_FILE_SIZE, sz);
+ }
// s += sz;
if (value >= (1 << 20))
{
+ char sz[32];
ConvertUInt64ToString(value >> 20, sz);
- s += L" (";
+ s += " (";
s += sz;
- s += L" MB)";
+ s += " MB)";
}
s.Add_LF();
}
diff --git a/CPP/7zip/UI/GUI/GUI.cpp b/CPP/7zip/UI/GUI/GUI.cpp
index 489fc721..2a2ef883 100644
--- a/CPP/7zip/UI/GUI/GUI.cpp
+++ b/CPP/7zip/UI/GUI/GUI.cpp
@@ -11,7 +11,6 @@
#include "../../../Common/MyInitGuid.h"
#include "../../../Common/CommandLineParser.h"
-#include "../../../Common/IntToString.h"
#include "../../../Common/MyException.h"
#include "../../../Common/StringConvert.h"
@@ -37,8 +36,8 @@
using namespace NWindows;
HINSTANCE g_hInstance;
-#ifndef _UNICODE
-#endif
+
+bool g_LargePagesMode = false;
#ifndef UNDER_CE
@@ -74,12 +73,17 @@ static void ErrorMessage(LPCWSTR message)
MessageBoxW(NULL, message, L"7-Zip", MB_ICONERROR | MB_OK);
}
+static void ErrorMessage(const char *s)
+{
+ ErrorMessage(GetUnicodeString(s));
+}
+
static void ErrorLangMessage(UINT resourceID)
{
ErrorMessage(LangString(resourceID));
}
-static const char *kNoFormats = "7-Zip cannot find the code that works with archives.";
+static const char * const kNoFormats = "7-Zip cannot find the code that works with archives.";
static int ShowMemErrorMessage()
{
@@ -126,7 +130,10 @@ static int Main2()
NSecurity::EnablePrivilege_SymLink();
#ifdef _7ZIP_LARGE_PAGES
if (options.LargePages)
- NSecurity::EnablePrivilege_LockMemory();
+ {
+ SetLargePageSize();
+ g_LargePagesMode = NSecurity::EnablePrivilege_LockMemory();
+ }
#endif
#endif
@@ -146,7 +153,7 @@ static int Main2()
#ifdef EXTERNAL_CODECS
if (!codecs->MainDll_ErrorPath.IsEmpty())
{
- UString s = L"7-Zip cannot load module ";
+ UString s ("7-Zip cannot load module: ");
s += fs2us(codecs->MainDll_ErrorPath);
throw s;
}
@@ -350,7 +357,7 @@ static int Main2()
return 0;
}
-#define NT_CHECK_FAIL_ACTION ErrorMessage(L"Unsupported Windows version"); return NExitCode::kFatalError;
+#define NT_CHECK_FAIL_ACTION ErrorMessage("Unsupported Windows version"); return NExitCode::kFatalError;
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
#ifdef UNDER_CE
@@ -361,9 +368,9 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
/* lpCmdLine */, int /* nCmdShow */)
{
g_hInstance = hInstance;
+
#ifdef _WIN32
NT_CHECK
- SetLargePageSize();
#endif
InitCommonControls();
@@ -407,7 +414,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
}
catch(const AString &s)
{
- ErrorMessage(GetUnicodeString(s));
+ ErrorMessage(s);
return NExitCode::kFatalError;
}
catch(const wchar_t *s)
@@ -417,19 +424,19 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
}
catch(const char *s)
{
- ErrorMessage(GetUnicodeString(s));
+ ErrorMessage(s);
return NExitCode::kFatalError;
}
catch(int v)
{
- wchar_t s[32];
- ConvertUInt32ToString(v, s);
- ErrorMessage(UString(L"Error: ") + s);
+ AString e ("Error: ");
+ e.Add_UInt32(v);
+ ErrorMessage(e);
return NExitCode::kFatalError;
}
catch(...)
{
- ErrorMessage(L"Unknown error");
+ ErrorMessage("Unknown error");
return NExitCode::kFatalError;
}
}
diff --git a/CPP/7zip/UI/GUI/GUI.dsp b/CPP/7zip/UI/GUI/GUI.dsp
index 63cdb2fd..9a171d93 100644
--- a/CPP/7zip/UI/GUI/GUI.dsp
+++ b/CPP/7zip/UI/GUI/GUI.dsp
@@ -45,7 +45,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
-# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "SUPPORT_DEVICE_FILE" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "SUPPORT_DEVICE_FILE" /FAcs /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"
@@ -835,10 +835,6 @@ SOURCE=..\..\..\..\C\Threads.h
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\..\..\Common\Buffer.h
-# End Source File
-# Begin Source File
-
SOURCE=..\..\..\Common\CommandLineParser.cpp
# End Source File
# Begin Source File
@@ -875,6 +871,10 @@ SOURCE=..\..\..\Common\ListFileUtils.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Common\MyBuffer.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Common\MyString.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/UI/GUI/HashGUI.cpp b/CPP/7zip/UI/GUI/HashGUI.cpp
index 03d65156..cc93f07e 100644
--- a/CPP/7zip/UI/GUI/HashGUI.cpp
+++ b/CPP/7zip/UI/GUI/HashGUI.cpp
@@ -47,25 +47,30 @@ public:
static void AddValuePair(UString &s, UINT resourceID, UInt64 value)
{
AddLangString(s, resourceID);
- s.AddAscii(": ");
+ s += ": ";
char sz[32];
ConvertUInt64ToString(value, sz);
- s.AddAscii(sz);
+ s += sz;
s.Add_LF();
}
static void AddSizeValuePair(UString &s, UINT resourceID, UInt64 value)
{
AddLangString(s, resourceID);
- s.AddAscii(": ");
- wchar_t sz[32];
- ConvertUInt64ToString(value, sz);
- s += MyFormatNew(IDS_FILE_SIZE, sz);
- ConvertUInt64ToString(value >> 20, sz);
- s.AddAscii(" (");
- s += sz;
- s.AddAscii(" MB)");
- s.Add_LF();
+ s += ": ";
+ {
+ wchar_t sz[32];
+ ConvertUInt64ToString(value, sz);
+ s += MyFormatNew(IDS_FILE_SIZE, sz);
+ }
+ {
+ char sz[32];
+ ConvertUInt64ToString(value >> 20, sz);
+ s += " (";
+ s += sz;
+ s += " MB)";
+ s.Add_LF();
+ }
}
HRESULT CHashCallbackGUI::StartScanning()
@@ -155,15 +160,14 @@ static void AddHashString(UString &s, const CHasherState &h, unsigned digestInde
s.Add_Space();
char temp[k_HashCalc_DigestSize_Max * 2 + 4];
AddHashHexToString(temp, h.Digests[digestIndex], h.DigestSize);
- s.AddAscii(temp);
+ s += temp;
s.Add_LF();
}
static void AddHashResString(UString &s, const CHasherState &h, unsigned digestIndex, UInt32 resID)
{
UString s2 = LangString(resID);
- UString name;
- name.SetFromAscii(h.Name);
+ UString name (h.Name);
s2.Replace(L"CRC", name);
AddHashString(s, h, digestIndex, s2);
}
@@ -179,7 +183,7 @@ void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFil
if (hb.NumFiles == 1 && hb.NumDirs == 0 && !firstFileName.IsEmpty())
{
AddLangString(s, IDS_PROP_NAME);
- s.AddAscii(": ");
+ s += ": ";
s += firstFileName;
s.Add_LF();
}
@@ -210,7 +214,7 @@ void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFil
const CHasherState &h = hb.Hashers[i];
if (hb.NumFiles == 1 && hb.NumDirs == 0)
{
- s.AddAscii(h.Name);
+ s += h.Name;
AddHashString(s, h, k_HashCalc_Index_DataSum, L":");
}
else
@@ -268,7 +272,7 @@ HRESULT HashCalcGUI(
const UString title = LangString(IDS_CHECKSUM_CALCULATING);
- t.ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE);
+ t.ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
t.ProgressDialog.MainAddTitle = title;
t.ProgressDialog.MainAddTitle.Add_Space();
diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp
index 0723b223..33852e3b 100644
--- a/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp
+++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp
@@ -97,9 +97,9 @@ HRESULT CUpdateCallbackGUI::Finalize()
}
*/
-HRESULT CUpdateCallbackGUI::SetNumItems(UInt64 numItems)
+HRESULT CUpdateCallbackGUI::SetNumItems(const CArcToDoStat &stat)
{
- ProgressDialog->Sync.Set_NumFilesTotal(numItems);
+ ProgressDialog->Sync.Set_NumFilesTotal(stat.Get_NumDataItems_Total());
return S_OK;
}
diff --git a/CPP/7zip/UI/GUI/UpdateGUI.cpp b/CPP/7zip/UI/GUI/UpdateGUI.cpp
index 53864f72..261b1e2b 100644
--- a/CPP/7zip/UI/GUI/UpdateGUI.cpp
+++ b/CPP/7zip/UI/GUI/UpdateGUI.cpp
@@ -28,8 +28,8 @@ using namespace NWindows;
using namespace NFile;
using namespace NDir;
-static CFSTR kDefaultSfxModule = FTEXT("7z.sfx");
-static const wchar_t *kSFXExtension = L"exe";
+static const char * const kDefaultSfxModule = "7z.sfx";
+static const char * const kSFXExtension = "exe";
extern void AddMessageToString(UString &dest, const UString &src);
@@ -54,14 +54,14 @@ HRESULT CThreadUpdating::ProcessVirt()
HRESULT res = UpdateArchive(codecs, *formatIndices, *cmdArcPath,
*WildcardCensor, *Options,
ei, UpdateCallbackGUI, UpdateCallbackGUI, needSetPath);
- FinalMessage.ErrorMessage.Message.SetFromAscii(ei.Message);
+ FinalMessage.ErrorMessage.Message = ei.Message.Ptr();
ErrorPaths = ei.FileNames;
if (ei.SystemError != S_OK && ei.SystemError != E_FAIL && ei.SystemError != E_ABORT)
return ei.SystemError;
return res;
}
-static void AddProp(CObjectVector<CProperty> &properties, const UString &name, const UString &value)
+static void AddProp(CObjectVector<CProperty> &properties, const char *name, const UString &value)
{
CProperty prop;
prop.Name = name;
@@ -69,16 +69,16 @@ static void AddProp(CObjectVector<CProperty> &properties, const UString &name, c
properties.Add(prop);
}
-static void AddProp(CObjectVector<CProperty> &properties, const UString &name, UInt32 value)
+static void AddProp(CObjectVector<CProperty> &properties, const char *name, UInt32 value)
{
- wchar_t tmp[32];
+ char tmp[32];
ConvertUInt64ToString(value, tmp);
- AddProp(properties, name, tmp);
+ AddProp(properties, name, UString(tmp));
}
-static void AddProp(CObjectVector<CProperty> &properties, const UString &name, bool value)
+static void AddProp(CObjectVector<CProperty> &properties, const char *name, bool value)
{
- AddProp(properties, name, value ? UString(L"on"): UString(L"off"));
+ AddProp(properties, name, UString(value ? "on": "off"));
}
static bool IsThereMethodOverride(bool is7z, const UString &propertiesString)
@@ -128,12 +128,12 @@ static void ParseAndAddPropertires(CObjectVector<CProperty> &properties,
static UString GetNumInBytesString(UInt64 v)
{
- wchar_t s[32];
+ char s[32];
ConvertUInt64ToString(v, s);
- size_t len = wcslen(s);
- s[len++] = L'B';
- s[len] = L'\0';
- return s;
+ size_t len = MyStringLen(s);
+ s[len++] = 'B';
+ s[len] = '\0';
+ return UString(s);
}
static void SetOutProperties(
@@ -152,44 +152,38 @@ static void SetOutProperties(
bool /* sfxMode */)
{
if (level != (UInt32)(Int32)-1)
- AddProp(properties, L"x", (UInt32)level);
+ AddProp(properties, "x", (UInt32)level);
if (setMethod)
{
if (!method.IsEmpty())
- AddProp(properties, is7z ? L"0": L"m", method);
+ AddProp(properties, is7z ? "0": "m", method);
if (dictionary != (UInt32)(Int32)-1)
{
- UString name;
+ AString name;
if (is7z)
- name = L"0";
- if (orderMode)
- name += L"mem";
- else
- name += L"d";
+ name = "0";
+ name += (orderMode ? "mem" : "d");
AddProp(properties, name, GetNumInBytesString(dictionary));
}
if (order != (UInt32)(Int32)-1)
{
- UString name;
+ AString name;
if (is7z)
- name = L"0";
- if (orderMode)
- name += L"o";
- else
- name += L"fb";
+ name = "0";
+ name += (orderMode ? "o" : "fb");
AddProp(properties, name, (UInt32)order);
}
}
if (!encryptionMethod.IsEmpty())
- AddProp(properties, L"em", encryptionMethod);
+ AddProp(properties, "em", encryptionMethod);
if (encryptHeadersIsAllowed)
- AddProp(properties, L"he", encryptHeaders);
+ AddProp(properties, "he", encryptHeaders);
if (solidIsSpecified)
- AddProp(properties, L"s", GetNumInBytesString(solidBlockSize));
+ AddProp(properties, "s", GetNumInBytesString(solidBlockSize));
if (multiThreadIsAllowed)
- AddProp(properties, L"mt", numThreads);
+ AddProp(properties, "mt", numThreads);
}
struct C_UpdateMode_ToAction_Pair
@@ -453,8 +447,8 @@ HRESULT UpdateGUI(
}
if (options.SfxMode && options.SfxModule.IsEmpty())
{
- FString folder = NWindows::NDLL::GetModuleDirPrefix();
- options.SfxModule = folder + kDefaultSfxModule;
+ options.SfxModule = NWindows::NDLL::GetModuleDirPrefix();
+ options.SfxModule += kDefaultSfxModule;
}
CThreadUpdating tu;
diff --git a/CPP/Build.mak b/CPP/Build.mak
index ef0ed0c4..39ebe0aa 100644
--- a/CPP/Build.mak
+++ b/CPP/Build.mak
@@ -53,15 +53,22 @@ CFLAGS = $(CFLAGS) -MD
!ENDIF
!IFDEF NEW_COMPILER
-CFLAGS = $(CFLAGS) -GS- -Zc:forScope
+CFLAGS = $(CFLAGS) -GS- -Zc:forScope -Zc:wchar_t
!IFNDEF UNDER_CE
CFLAGS = $(CFLAGS) -MP2
+!IFNDEF CPU
+# CFLAGS = $(CFLAGS) -arch:IA32
+!ENDIF
!ENDIF
!ELSE
CFLAGS = $(CFLAGS)
!ENDIF
+!IF "$(CPU)" == "AMD64"
+CFLAGS_O1 = $(CFLAGS) -O1
+!ELSE
CFLAGS_O1 = $(CFLAGS) -O1
+!ENDIF
CFLAGS_O2 = $(CFLAGS) -O2
LFLAGS = $(LFLAGS) -nologo -OPT:REF -OPT:ICF
@@ -72,15 +79,27 @@ LFLAGS = $(LFLAGS) /LARGEADDRESSAWARE
!IFDEF DEF_FILE
LFLAGS = $(LFLAGS) -DLL -DEF:$(DEF_FILE)
+!ELSE
+LFLAGS = $(LFLAGS) /FIXED
+# /BASE:0x400000
!ENDIF
-MY_SUB_SYS_VER=6.0
+
+# !IF "$(CPU)" == "AMD64"
+
+!IFDEF SUB_SYS_VER
+
+MY_SUB_SYS_VER=5.02
+
!IFDEF MY_CONSOLE
-# LFLAGS = $(LFLAGS) /SUBSYSTEM:console,$(MY_SUB_SYS_VER)
+LFLAGS = $(LFLAGS) /SUBSYSTEM:console,$(MY_SUB_SYS_VER)
!ELSE
-# LFLAGS = $(LFLAGS) /SUBSYSTEM:windows,$(MY_SUB_SYS_VER)
+LFLAGS = $(LFLAGS) /SUBSYSTEM:windows,$(MY_SUB_SYS_VER)
!ENDIF
+!ENDIF
+
+
PROGPATH = $O\$(PROG)
COMPL_O1 = $(CC) $(CFLAGS_O1) $**
diff --git a/CPP/Common/ComTry.h b/CPP/Common/ComTry.h
index fb4ef045..297c407b 100644
--- a/CPP/Common/ComTry.h
+++ b/CPP/Common/ComTry.h
@@ -10,7 +10,11 @@
#define COM_TRY_BEGIN try {
#define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; }
- // catch(const CNewException &) { return E_OUTOFMEMORY; }
+/*
+#define COM_TRY_END } \
+ catch(const CNewException &) { return E_OUTOFMEMORY; } \
+ catch(...) { return HRESULT_FROM_WIN32(ERROR_NOACCESS); } \
+*/
// catch(const CSystemException &e) { return e.ErrorCode; }
// catch(...) { return E_FAIL; }
diff --git a/CPP/Common/CommandLineParser.cpp b/CPP/Common/CommandLineParser.cpp
index 1c7f2654..145f3435 100644
--- a/CPP/Common/CommandLineParser.cpp
+++ b/CPP/Common/CommandLineParser.cpp
@@ -4,20 +4,6 @@
#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)
@@ -44,7 +30,7 @@ bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
void SplitCommandLine(const UString &s, UStringVector &parts)
{
- UString sTemp = s;
+ UString sTemp (s);
sTemp.Trim();
parts.Clear();
for (;;)
@@ -59,18 +45,17 @@ void SplitCommandLine(const UString &s, UStringVector &parts)
}
-static const char *kStopSwitchParsing = "--";
+static const char * const kStopSwitchParsing = "--";
static bool inline IsItSwitchChar(wchar_t c)
{
return (c == '-');
}
-CParser::CParser(unsigned numSwitches):
- _numSwitches(numSwitches),
- _switches(0)
+CParser::CParser():
+ _switches(NULL),
+ StopSwitchIndex(-1)
{
- _switches = new CSwitchResult[numSwitches];
}
CParser::~CParser()
@@ -81,7 +66,7 @@ CParser::~CParser()
// 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)
+bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches)
{
if (s.IsEmpty() || !IsItSwitchChar(s[0]))
return false;
@@ -90,13 +75,13 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
unsigned switchIndex = 0;
int maxLen = -1;
- for (unsigned i = 0; i < _numSwitches; i++)
+ for (unsigned i = 0; i < numSwitches; i++)
{
- const char *key = switchForms[i].Key;
+ const char * const 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))
+ if (IsString1PrefixedByString2_NoCase_Ascii((const wchar_t *)s + pos, key))
{
switchIndex = i;
maxLen = switchLen;
@@ -161,8 +146,10 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
break;
case NSwitchType::kString:
- sw.PostStrings.Add((const wchar_t *)s + pos);
+ {
+ sw.PostStrings.Add(s.Ptr(pos));
return true;
+ }
}
if (pos != s.Len())
@@ -173,23 +160,30 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
return true;
}
-bool CParser::ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings)
+
+bool CParser::ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings)
{
+ StopSwitchIndex = -1;
+ ErrorMessage.Empty();
ErrorLine.Empty();
- bool stopSwitch = false;
+ NonSwitchStrings.Clear();
+ delete []_switches;
+ _switches = NULL;
+ _switches = new CSwitchResult[numSwitches];
+
FOR_VECTOR (i, commandStrings)
{
const UString &s = commandStrings[i];
- if (!stopSwitch)
+ if (StopSwitchIndex < 0)
{
if (s.IsEqualTo(kStopSwitchParsing))
{
- stopSwitch = true;
+ StopSwitchIndex = NonSwitchStrings.Size();
continue;
}
if (!s.IsEmpty() && IsItSwitchChar(s[0]))
{
- if (ParseString(s, switchForms))
+ if (ParseString(s, switchForms, numSwitches))
continue;
ErrorLine = s;
return false;
diff --git a/CPP/Common/CommandLineParser.h b/CPP/Common/CommandLineParser.h
index c9fd2956..1dbdd4ea 100644
--- a/CPP/Common/CommandLineParser.h
+++ b/CPP/Common/CommandLineParser.h
@@ -43,19 +43,19 @@ struct CSwitchResult
class CParser
{
- unsigned _numSwitches;
CSwitchResult *_switches;
- bool ParseString(const UString &s, const CSwitchForm *switchForms);
+ bool ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches);
public:
UStringVector NonSwitchStrings;
+ int StopSwitchIndex; // NonSwitchStrings[StopSwitchIndex+] are after "--"
AString ErrorMessage;
UString ErrorLine;
- CParser(unsigned numSwitches);
+ CParser();
~CParser();
- bool ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings);
- const CSwitchResult& operator[](size_t index) const { return _switches[index]; }
+ bool ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings);
+ const CSwitchResult& operator[](unsigned index) const { return _switches[index]; }
};
}
diff --git a/CPP/Common/Common.h b/CPP/Common/Common.h
index 9dd30f4b..5430a92d 100644
--- a/CPP/Common/Common.h
+++ b/CPP/Common/Common.h
@@ -3,11 +3,41 @@
#ifndef __COMMON_COMMON_H
#define __COMMON_COMMON_H
+/*
+This file is included to all cpp files in 7-Zip.
+Each folder contains StdAfx.h file that includes "Common.h".
+So 7-Zip includes "Common.h" in both modes:
+ with precompiled StdAfx.h
+and
+ without precompiled StdAfx.h
+
+If you use 7-Zip code, you must include "Common.h" before other h files of 7-zip.
+If you don't need some things that are used in 7-Zip,
+you can change this h file or h files included in this file.
+*/
+
+// compiler pragmas to disable some warnings
#include "../../C/Compiler.h"
+// it's <windows.h> or code that defines windows things, if it's not _WIN32
#include "MyWindows.h"
+
+// NewHandler.h and NewHandler.cpp redefine operator new() to throw exceptions, if compiled with old MSVC compilers
#include "NewHandler.h"
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[1]))
+
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+
+/* There is BUG in MSVC 6.0 compiler for operator new[]:
+ It doesn't check overflow, when it calculates size in bytes for allocated array.
+ So we can use MY_ARRAY_NEW macro instead of new[] operator. */
+
+#if defined(_MSC_VER) && (_MSC_VER == 1200) && !defined(_WIN64)
+ #define MY_ARRAY_NEW(p, T, size) p = new T[(size > (unsigned)0xFFFFFFFF / sizeof(T)) ? (unsigned)0xFFFFFFFF / sizeof(T) : size];
+#else
+ #define MY_ARRAY_NEW(p, T, size) p = new T[size];
+#endif
#endif
diff --git a/CPP/Common/DynLimBuf.h b/CPP/Common/DynLimBuf.h
index 93aa144f..e80a7e7c 100644
--- a/CPP/Common/DynLimBuf.h
+++ b/CPP/Common/DynLimBuf.h
@@ -27,6 +27,7 @@ public:
~CDynLimBuf() { MyFree(_chars); }
size_t Len() const { return _pos; }
+ bool IsError() const { return _error; }
void Empty() { _pos = 0; _error = false; }
operator const Byte *() const { return _chars; }
diff --git a/CPP/Common/IntToString.cpp b/CPP/Common/IntToString.cpp
index ed217c72..05b1c148 100644
--- a/CPP/Common/IntToString.cpp
+++ b/CPP/Common/IntToString.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../../C/CpuArch.h"
+
#include "IntToString.h"
#define CONVERT_INT_TO_STR(charType, tempSize) \
@@ -46,6 +48,12 @@ void ConvertUInt64ToOct(UInt64 val, char *s) throw()
while (i);
}
+
+#define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))))
+
+static inline char GetHexChar(unsigned t) { return GET_HEX_CHAR(t); }
+
+
void ConvertUInt32ToHex(UInt32 val, char *s) throw()
{
UInt32 v = val;
@@ -59,13 +67,14 @@ void ConvertUInt32ToHex(UInt32 val, char *s) throw()
s[i] = 0;
do
{
- unsigned t = (unsigned)((val & 0xF));
+ unsigned t = (unsigned)(val & 0xF);
val >>= 4;
- s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ s[--i] = GET_HEX_CHAR(t);
}
while (i);
}
+
void ConvertUInt64ToHex(UInt64 val, char *s) throw()
{
UInt64 v = val;
@@ -79,9 +88,9 @@ void ConvertUInt64ToHex(UInt64 val, char *s) throw()
s[i] = 0;
do
{
- unsigned t = (unsigned)((val & 0xF));
+ unsigned t = (unsigned)(val & 0xF);
val >>= 4;
- s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ s[--i] = GET_HEX_CHAR(t);
}
while (i);
}
@@ -93,7 +102,7 @@ void ConvertUInt32ToHex8Digits(UInt32 val, char *s) throw()
{
unsigned t = val & 0xF;
val >>= 4;
- s[i] = (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10))));
+ s[i] = GET_HEX_CHAR(t);;
}
}
@@ -144,3 +153,41 @@ void ConvertInt64ToString(Int64 val, wchar_t *s) throw()
}
ConvertUInt64ToString(val, s);
}
+
+
+static void ConvertByteToHex2Digits(unsigned v, char *s) throw()
+{
+ s[0] = GetHexChar(v >> 4);
+ s[1] = GetHexChar(v & 0xF);
+}
+
+static void ConvertUInt16ToHex4Digits(UInt32 val, char *s) throw()
+{
+ ConvertByteToHex2Digits(val >> 8, s);
+ ConvertByteToHex2Digits(val & 0xFF, s + 2);
+}
+
+char *RawLeGuidToString(const Byte *g, char *s) throw()
+{
+ ConvertUInt32ToHex8Digits(GetUi32(g ), s); s += 8; *s++ = '-';
+ ConvertUInt16ToHex4Digits(GetUi16(g + 4), s); s += 4; *s++ = '-';
+ ConvertUInt16ToHex4Digits(GetUi16(g + 6), s); s += 4; *s++ = '-';
+ for (unsigned i = 0; i < 8; i++)
+ {
+ if (i == 2)
+ *s++ = '-';
+ ConvertByteToHex2Digits(g[8 + i], s);
+ s += 2;
+ }
+ *s = 0;
+ return s;
+}
+
+char *RawLeGuidToString_Braced(const Byte *g, char *s) throw()
+{
+ *s++ = '{';
+ s = RawLeGuidToString(g, s);
+ *s++ = '}';
+ *s = 0;
+ return s;
+}
diff --git a/CPP/Common/IntToString.h b/CPP/Common/IntToString.h
index 69605ab7..d4110d1d 100644
--- a/CPP/Common/IntToString.h
+++ b/CPP/Common/IntToString.h
@@ -21,4 +21,8 @@ void ConvertUInt32ToHex8Digits(UInt32 value, char *s) throw();
void ConvertInt64ToString(Int64 value, char *s) throw();
void ConvertInt64ToString(Int64 value, wchar_t *s) throw();
+// use RawLeGuid only for RAW bytes that contain stored GUID as Little-endian.
+char *RawLeGuidToString(const Byte *guid, char *s) throw();
+char *RawLeGuidToString_Braced(const Byte *guid, char *s) throw();
+
#endif
diff --git a/CPP/Common/Lang.cpp b/CPP/Common/Lang.cpp
index 8c525cf7..e959ba48 100644
--- a/CPP/Common/Lang.cpp
+++ b/CPP/Common/Lang.cpp
@@ -10,13 +10,13 @@
void CLang::Clear() throw()
{
- delete []_text;
- _text = 0;
_ids.Clear();
_offsets.Clear();
+ delete []_text;
+ _text = 0;
}
-static const wchar_t *kLangSignature = L";!@Lang2@!UTF-8!";
+static const char * const kLangSignature = ";!@Lang2@!UTF-8!";
bool CLang::OpenFromString(const AString &s2)
{
@@ -29,9 +29,9 @@ bool CLang::OpenFromString(const AString &s2)
if (s[0] == 0xFEFF)
i++;
- for (const wchar_t *p = kLangSignature;; i++)
+ for (const char *p = kLangSignature;; i++)
{
- wchar_t c = *p++;
+ Byte c = *p++;
if (c == 0)
break;
if (s[i] != c)
@@ -109,7 +109,7 @@ bool CLang::OpenFromString(const AString &s2)
return true;
}
-bool CLang::Open(CFSTR fileName, const wchar_t *id)
+bool CLang::Open(CFSTR fileName, const char *id)
{
Clear();
NWindows::NFile::NIO::CInFile file;
@@ -146,7 +146,7 @@ bool CLang::Open(CFSTR fileName, const wchar_t *id)
if (OpenFromString(s))
{
const wchar_t *name = Get(0);
- if (name && wcscmp(name, id) == 0)
+ if (name && StringsAreEqual_Ascii(name, id))
return true;
}
diff --git a/CPP/Common/Lang.h b/CPP/Common/Lang.h
index 22e42574..cc66677d 100644
--- a/CPP/Common/Lang.h
+++ b/CPP/Common/Lang.h
@@ -15,7 +15,7 @@ class CLang
public:
CLang(): _text(0) {}
~CLang() { Clear(); }
- bool Open(CFSTR fileName, const wchar_t *id);
+ bool Open(CFSTR fileName, const char *id);
void Clear() throw();
const wchar_t *Get(UInt32 id) const throw();
};
diff --git a/CPP/Common/ListFileUtils.cpp b/CPP/Common/ListFileUtils.cpp
index 3bf4ec29..9112003b 100644
--- a/CPP/Common/ListFileUtils.cpp
+++ b/CPP/Common/ListFileUtils.cpp
@@ -52,7 +52,7 @@ bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage
if (codePage == MY__CP_UTF16)
for (unsigned i = 0; i < num; i++)
{
- wchar_t c = GetUi16(buf + i * 2);
+ wchar_t c = GetUi16(buf + (size_t)i * 2);
if (c == 0)
return false;
p[i] = c;
@@ -60,7 +60,7 @@ bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage
else
for (unsigned i = 0; i < num; i++)
{
- wchar_t c = (wchar_t)GetBe16(buf + i * 2);
+ wchar_t c = (wchar_t)GetBe16(buf + (size_t)i * 2);
if (c == 0)
return false;
p[i] = c;
@@ -104,7 +104,7 @@ bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage
wchar_t c = u[i];
if (c == kGoodBOM || c == kBadBOM)
return false;
- if (c == L'\n' || c == 0xD)
+ if (c == '\n' || c == 0xD)
{
AddName(strings, s);
s.Empty();
diff --git a/CPP/Common/MyBuffer.h b/CPP/Common/MyBuffer.h
index d0378057..5d4e3475 100644
--- a/CPP/Common/MyBuffer.h
+++ b/CPP/Common/MyBuffer.h
@@ -5,6 +5,9 @@
#include "Defs.h"
+/* 7-Zip now uses CBuffer only as CByteBuffer.
+ So there is no need to use MY_ARRAY_NEW macro in CBuffer code. */
+
template <class T> class CBuffer
{
T *_items;
@@ -119,7 +122,7 @@ bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
}
-typedef CBuffer<char> CCharBuffer;
+// typedef CBuffer<char> CCharBuffer;
// typedef CBuffer<wchar_t> CWCharBuffer;
typedef CBuffer<unsigned char> CByteBuffer;
@@ -129,7 +132,7 @@ template <class T> class CObjArray
protected:
T *_items;
private:
- // we disable constructors
+ // we disable copy
CObjArray(const CObjArray &buffer);
void operator=(const CObjArray &buffer);
public:
@@ -138,7 +141,14 @@ public:
delete []_items;
_items = 0;
}
- CObjArray(size_t size): _items(0) { if (size != 0) _items = new T[size]; }
+ CObjArray(size_t size): _items(0)
+ {
+ if (size != 0)
+ {
+ MY_ARRAY_NEW(_items, T, size)
+ // _items = new T[size];
+ }
+ }
CObjArray(): _items(0) {};
~CObjArray() { delete []_items; }
@@ -149,7 +159,8 @@ public:
{
delete []_items;
_items = 0;
- _items = new T[newSize];
+ MY_ARRAY_NEW(_items, T, newSize)
+ // _items = new T[newSize];
}
};
@@ -164,6 +175,7 @@ template <class T> class CObjArray2
T *_items;
unsigned _size;
+ // we disable copy
CObjArray2(const CObjArray2 &buffer);
void operator=(const CObjArray2 &buffer);
public:
@@ -216,7 +228,10 @@ public:
return;
T *newBuffer = NULL;
if (size != 0)
- newBuffer = new T[size];
+ {
+ MY_ARRAY_NEW(newBuffer, T, size)
+ // newBuffer = new T[size];
+ }
delete []_items;
_items = newBuffer;
_size = size;
diff --git a/CPP/Common/MyBuffer2.h b/CPP/Common/MyBuffer2.h
new file mode 100644
index 00000000..ba98d137
--- /dev/null
+++ b/CPP/Common/MyBuffer2.h
@@ -0,0 +1,45 @@
+// Common/MyBuffer2.h
+
+#ifndef __COMMON_MY_BUFFER2_H
+#define __COMMON_MY_BUFFER2_H
+
+#include "../../C/Alloc.h"
+
+#include "Defs.h"
+
+class CMidBuffer
+{
+ Byte *_data;
+ size_t _size;
+
+ CLASS_NO_COPY(CMidBuffer)
+
+public:
+ CMidBuffer(): _data(NULL), _size(0) {};
+ ~CMidBuffer() { ::MidFree(_data); }
+
+ void Free() { ::MidFree(_data); _data = NULL; _size = 0; }
+
+ bool IsAllocated() const { return _data != NULL; }
+ operator Byte *() { return _data; }
+ operator const Byte *() const { return _data; }
+ size_t Size() const { return _size; }
+
+ void AllocAtLeast(size_t size)
+ {
+ if (!_data || size > _size)
+ {
+ const size_t kMinSize = (size_t)1 << 16;
+ if (size < kMinSize)
+ size = kMinSize;
+ ::MidFree(_data);
+ _size = 0;
+ _data = 0;
+ _data = (Byte *)::MidAlloc(size);
+ if (_data)
+ _size = size;
+ }
+ }
+};
+
+#endif
diff --git a/CPP/Common/MyCom.h b/CPP/Common/MyCom.h
index 7c725c91..031921d3 100644
--- a/CPP/Common/MyCom.h
+++ b/CPP/Common/MyCom.h
@@ -4,7 +4,6 @@
#define __MY_COM_H
#include "MyWindows.h"
-#include "NewHandler.h"
#ifndef RINOK
#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; }
@@ -158,7 +157,20 @@ private:
}
};
-//////////////////////////////////////////////////////////
+
+
+/*
+ If CMyUnknownImp doesn't use virtual destructor, the code size is smaller.
+ But if some class_1 derived from CMyUnknownImp
+ uses MY_ADDREF_RELEASE and IUnknown::Release()
+ and some another class_2 is derived from class_1,
+ then class_1 must use virtual destructor:
+ virtual ~class_1();
+ In that case, class_1::Release() calls correct destructor of class_2.
+
+ Also you can use virtual ~CMyUnknownImp(), if you want to disable warning
+ "class has virtual functions, but destructor is not virtual".
+*/
class CMyUnknownImp
{
@@ -166,9 +178,12 @@ public:
ULONG __m_RefCount;
CMyUnknownImp(): __m_RefCount(0) {}
- // virtual ~CMyUnknownImp() {};
+ // virtual
+ ~CMyUnknownImp() {}
};
+
+
#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
(REFGUID iid, void **outObject) throw() { *outObject = NULL;
diff --git a/CPP/Common/MyString.cpp b/CPP/Common/MyString.cpp
index a2d4cc4e..e2ec8a68 100644
--- a/CPP/Common/MyString.cpp
+++ b/CPP/Common/MyString.cpp
@@ -8,6 +8,8 @@
#include <ctype.h>
#endif
+#include "IntToString.h"
+
#if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING)
#include "StringConvert.h"
#endif
@@ -28,6 +30,10 @@ inline const char* MyStringGetNextCharPointer(const char *p) throw()
}
*/
+#define MY_STRING_NEW_char(_size_) MY_STRING_NEW(char, _size_)
+#define MY_STRING_NEW_wchar_t(_size_) MY_STRING_NEW(wchar_t, _size_)
+
+
int FindCharPosInString(const char *s, char c) throw()
{
for (const char *p = s;; p++)
@@ -52,7 +58,18 @@ int FindCharPosInString(const wchar_t *s, wchar_t c) throw()
}
/*
-void MyStringUpper_Ascii(wchar_t *s)
+void MyStringUpper_Ascii(char *s) throw()
+{
+ for (;;)
+ {
+ char c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharUpper_Ascii(c);
+ }
+}
+
+void MyStringUpper_Ascii(wchar_t *s) throw()
{
for (;;)
{
@@ -282,6 +299,26 @@ bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw()
}
}
+bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw()
+{
+ for (;;)
+ {
+ unsigned char c2 = (unsigned char)(*s2++); if (c2 == 0) return true;
+ wchar_t c1 = *s1++; if (c1 != c2) return false;
+ }
+}
+
+bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *s1, const char *s2) throw()
+{
+ for (;;)
+ {
+ char c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++;
+ if (c1 != (unsigned char)c2 && MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))
+ return false;
+ }
+}
+
bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
@@ -345,8 +382,8 @@ 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)); \
+ char *newBuf = MY_STRING_NEW_char(newLimit + 1);
+ memcpy(newBuf, _chars, (size_t)(_len + 1));
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = newLimit;
@@ -356,7 +393,7 @@ 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);
+ char *newBuf = MY_STRING_NEW_char(newLimit + 1);
newBuf[0] = 0;
MY_STRING_DELETE(_chars);
_chars = newBuf;
@@ -366,7 +403,7 @@ void AString::ReAlloc2(unsigned newLimit)
void AString::SetStartLen(unsigned len)
{
_chars = 0;
- _chars = MY_STRING_NEW(char, len + 1);
+ _chars = MY_STRING_NEW_char(len + 1);
_len = len;
_limit = len;
}
@@ -393,7 +430,6 @@ void AString::Grow(unsigned n)
ReAlloc(next - 1);
}
-/*
AString::AString(unsigned num, const char *s)
{
unsigned len = MyStringLen(s);
@@ -403,7 +439,6 @@ AString::AString(unsigned num, const char *s)
memcpy(_chars, s, num);
_chars[num] = 0;
}
-*/
AString::AString(unsigned num, const AString &s)
{
@@ -421,7 +456,7 @@ AString::AString(const AString &s, char c)
unsigned len = s.Len();
memcpy(chars, s, len);
chars[len] = c;
- chars[len + 1] = 0;
+ chars[(size_t)len + 1] = 0;
}
AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2)
@@ -436,20 +471,23 @@ AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.
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()); }
+static const unsigned kStartStringCapacity = 4;
+
AString::AString()
{
_chars = 0;
- _chars = MY_STRING_NEW(char, 4);
+ _chars = MY_STRING_NEW_char(kStartStringCapacity);
_len = 0;
- _limit = 4 - 1;
+ _limit = kStartStringCapacity - 1;
_chars[0] = 0;
}
AString::AString(char c)
{
SetStartLen(1);
- _chars[0] = c;
- _chars[1] = 0;
+ char *chars = _chars;
+ chars[0] = c;
+ chars[1] = 0;
}
AString::AString(const char *s)
@@ -468,14 +506,15 @@ AString &AString::operator=(char c)
{
if (1 > _limit)
{
- char *newBuf = MY_STRING_NEW(char, 1 + 1);
+ char *newBuf = MY_STRING_NEW_char(1 + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = 1;
}
_len = 1;
- _chars[0] = c;
- _chars[1] = 0;
+ char *chars = _chars;
+ chars[0] = c;
+ chars[1] = 0;
return *this;
}
@@ -484,7 +523,7 @@ AString &AString::operator=(const char *s)
unsigned len = MyStringLen(s);
if (len > _limit)
{
- char *newBuf = MY_STRING_NEW(char, len + 1);
+ char *newBuf = MY_STRING_NEW_char(len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -501,7 +540,7 @@ AString &AString::operator=(const AString &s)
unsigned len = s._len;
if (len > _limit)
{
- char *newBuf = MY_STRING_NEW(char, len + 1);
+ char *newBuf = MY_STRING_NEW_char(len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -526,7 +565,7 @@ void AString::SetFromWStr_if_Ascii(const wchar_t *s)
}
if (len > _limit)
{
- char *newBuf = MY_STRING_NEW(char, len + 1);
+ char *newBuf = MY_STRING_NEW_char(len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -550,7 +589,7 @@ void AString::SetFromBstr_if_Ascii(BSTR s)
}
if (len > _limit)
{
- char *newBuf = MY_STRING_NEW(char, len + 1);
+ char *newBuf = MY_STRING_NEW_char(len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -577,6 +616,12 @@ AString &AString::operator+=(const char *s)
return *this;
}
+void AString::Add_OptSpaced(const char *s)
+{
+ Add_Space_if_NotEmpty();
+ (*this) += s;
+}
+
AString &AString::operator+=(const AString &s)
{
Grow(s._len);
@@ -585,11 +630,18 @@ AString &AString::operator+=(const AString &s)
return *this;
}
+void AString::Add_UInt32(UInt32 v)
+{
+ char sz[16];
+ ConvertUInt32ToString(v, sz);
+ (*this) += sz;
+}
+
void AString::SetFrom(const char *s, unsigned len) // no check
{
if (len > _limit)
{
- char *newBuf = MY_STRING_NEW(char, len + 1);
+ char *newBuf = MY_STRING_NEW_char(len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -694,7 +746,7 @@ void AString::TrimRight() throw()
unsigned i;
for (i = _len; i != 0; i--)
{
- char c = p[i - 1];
+ char c = p[(size_t)i - 1];
if (c != ' ' && c != '\n' && c != '\t')
break;
}
@@ -780,12 +832,13 @@ void AString::Replace(char oldChar, char newChar) throw()
return; // 0;
// unsigned number = 0;
int pos = 0;
+ char *chars = _chars;
while ((unsigned)pos < _len)
{
pos = Find(oldChar, pos);
if (pos < 0)
break;
- _chars[(unsigned)pos] = newChar;
+ chars[(unsigned)pos] = newChar;
pos++;
// number++;
}
@@ -895,7 +948,7 @@ 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);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(newLimit + 1);
wmemcpy(newBuf, _chars, _len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
@@ -906,7 +959,7 @@ 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);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(newLimit + 1);
newBuf[0] = 0;
MY_STRING_DELETE(_chars);
_chars = newBuf;
@@ -916,7 +969,7 @@ void UString::ReAlloc2(unsigned newLimit)
void UString::SetStartLen(unsigned len)
{
_chars = 0;
- _chars = MY_STRING_NEW(wchar_t, len + 1);
+ _chars = MY_STRING_NEW_wchar_t(len + 1);
_len = len;
_limit = len;
}
@@ -971,7 +1024,7 @@ UString::UString(const UString &s, wchar_t c)
unsigned len = s.Len();
wmemcpy(chars, s, len);
chars[len] = c;
- chars[len + 1] = 0;
+ chars[(size_t)len + 1] = 0;
}
UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2)
@@ -989,17 +1042,26 @@ UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyS
UString::UString()
{
_chars = 0;
- _chars = MY_STRING_NEW(wchar_t, 4);
+ _chars = MY_STRING_NEW_wchar_t(kStartStringCapacity);
_len = 0;
- _limit = 4 - 1;
+ _limit = kStartStringCapacity - 1;
_chars[0] = 0;
}
UString::UString(wchar_t c)
{
SetStartLen(1);
- _chars[0] = c;
- _chars[1] = 0;
+ wchar_t *chars = _chars;
+ chars[0] = c;
+ chars[1] = 0;
+}
+
+UString::UString(char c)
+{
+ SetStartLen(1);
+ wchar_t *chars = _chars;
+ chars[0] = (unsigned char)c;
+ chars[1] = 0;
}
UString::UString(const wchar_t *s)
@@ -1009,6 +1071,16 @@ UString::UString(const wchar_t *s)
wmemcpy(_chars, s, len + 1);
}
+UString::UString(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ SetStartLen(len);
+ wchar_t *chars = _chars;
+ for (unsigned i = 0; i < len; i++)
+ chars[i] = (unsigned char)s[i];
+ chars[len] = 0;
+}
+
UString::UString(const UString &s)
{
SetStartLen(s._len);
@@ -1019,14 +1091,15 @@ UString &UString::operator=(wchar_t c)
{
if (1 > _limit)
{
- wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1);
+ 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;
+ wchar_t *chars = _chars;
+ chars[0] = c;
+ chars[1] = 0;
return *this;
}
@@ -1035,7 +1108,7 @@ UString &UString::operator=(const wchar_t *s)
unsigned len = MyStringLen(s);
if (len > _limit)
{
- wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -1052,7 +1125,7 @@ UString &UString::operator=(const UString &s)
unsigned len = s._len;
if (len > _limit)
{
- wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -1062,12 +1135,27 @@ UString &UString::operator=(const UString &s)
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::SetFromBstr(BSTR s)
{
unsigned len = ::SysStringLen(s);
if (len > _limit)
{
- wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -1077,6 +1165,24 @@ void UString::SetFromBstr(BSTR s)
wmemcpy(_chars, s, len + 1);
}
+UString &UString::operator=(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;
+ return *this;
+}
+
void UString::Add_Space() { operator+=(L' '); }
void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
@@ -1108,39 +1214,7 @@ UString &UString::operator+=(const UString &s)
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)
+UString &UString::operator+=(const char *s)
{
unsigned len = MyStringLen(s);
Grow(len);
@@ -1149,9 +1223,17 @@ void UString::AddAscii(const char *s)
chars[i] = (unsigned char)s[i];
chars[len] = 0;
_len += len;
+ return *this;
}
+void UString::Add_UInt32(UInt32 v)
+{
+ char sz[16];
+ ConvertUInt32ToString(v, sz);
+ (*this) += sz;
+}
+
int UString::Find(const wchar_t *s, unsigned startIndex) const throw()
{
@@ -1238,7 +1320,7 @@ void UString::TrimRight() throw()
unsigned i;
for (i = _len; i != 0; i--)
{
- wchar_t c = p[i - 1];
+ wchar_t c = p[(size_t)i - 1];
if (c != ' ' && c != '\n' && c != '\t')
break;
}
@@ -1324,12 +1406,13 @@ void UString::Replace(wchar_t oldChar, wchar_t newChar) throw()
return; // 0;
// unsigned number = 0;
int pos = 0;
+ wchar_t *chars = _chars;
while ((unsigned)pos < _len)
{
pos = Find(oldChar, pos);
if (pos < 0)
break;
- _chars[(unsigned)pos] = newChar;
+ chars[(unsigned)pos] = newChar;
pos++;
// number++;
}
@@ -1392,13 +1475,13 @@ 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);
+ _chars = MY_STRING_NEW_wchar_t(newLimit + 1);
}
void UString2::SetStartLen(unsigned len)
{
_chars = 0;
- _chars = MY_STRING_NEW(wchar_t, len + 1);
+ _chars = MY_STRING_NEW_wchar_t(len + 1);
_len = len;
}
@@ -1407,8 +1490,9 @@ void UString2::SetStartLen(unsigned len)
UString2::UString2(wchar_t c)
{
SetStartLen(1);
- _chars[0] = c;
- _chars[1] = 0;
+ wchar_t *chars = _chars;
+ chars[0] = c;
+ chars[1] = 0;
}
*/
@@ -1433,14 +1517,15 @@ UString2 &UString2::operator=(wchar_t c)
{
if (1 > _len)
{
- wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1);
+ 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;
+ wchar_t *chars = _chars;
+ chars[0] = c;
+ chars[1] = 0;
return *this;
}
*/
@@ -1450,7 +1535,7 @@ UString2 &UString2::operator=(const wchar_t *s)
unsigned len = MyStringLen(s);
if (len > _len)
{
- wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
if (_chars)
MY_STRING_DELETE(_chars);
_chars = newBuf;
@@ -1465,7 +1550,7 @@ void UString2::SetFromAscii(const char *s)
unsigned len = MyStringLen(s);
if (len > _len)
{
- wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
if (_chars)
MY_STRING_DELETE(_chars);
_chars = newBuf;
@@ -1484,7 +1569,7 @@ UString2 &UString2::operator=(const UString2 &s)
unsigned len = s._len;
if (len > _len)
{
- wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
if (_chars)
MY_STRING_DELETE(_chars);
_chars = newBuf;
@@ -1542,6 +1627,11 @@ AString fs2fas(CFSTR s)
return UnicodeStringToMultiByte(s, GetCurrentCodePage());
}
+FString fas2fs(const char *s)
+{
+ return MultiByteToUnicodeString(s, GetCurrentCodePage());
+}
+
FString fas2fs(const AString &s)
{
return MultiByteToUnicodeString(s, GetCurrentCodePage());
@@ -1551,9 +1641,14 @@ FString fas2fs(const AString &s)
#else
+UString fs2us(const FChar *s)
+{
+ return MultiByteToUnicodeString(s, GetCurrentCodePage());
+}
+
UString fs2us(const FString &s)
{
- return MultiByteToUnicodeString((AString)s, GetCurrentCodePage());
+ return MultiByteToUnicodeString(s, GetCurrentCodePage());
}
FString us2fs(const wchar_t *s)
diff --git a/CPP/Common/MyString.h b/CPP/Common/MyString.h
index 02308555..1c7357e4 100644
--- a/CPP/Common/MyString.h
+++ b/CPP/Common/MyString.h
@@ -14,6 +14,26 @@
#include "MyTypes.h"
#include "MyVector.h"
+
+#ifdef _MSC_VER
+ #ifdef _NATIVE_WCHAR_T_DEFINED
+ #define MY_NATIVE_WCHAR_T_DEFINED
+ #endif
+#else
+ #define MY_NATIVE_WCHAR_T_DEFINED
+#endif
+
+/*
+ native support for wchar_t:
+ _MSC_VER == 1600 : /Zc:wchar_t is not supported
+ _MSC_VER == 1310 (VS2003)
+ ? _MSC_VER == 1400 (VS2005) : wchar_t <- unsigned short
+ /Zc:wchar_t : wchar_t <- __wchar_t, _WCHAR_T_DEFINED and _NATIVE_WCHAR_T_DEFINED
+ _MSC_VER > 1400 (VS2008+)
+ /Zc:wchar_t[-]
+ /Zc:wchar_t is on by default
+*/
+
#ifdef _WIN32
#define IS_PATH_SEPAR(c) ((c) == '\\' || (c) == '/')
#else
@@ -60,6 +80,12 @@ inline void MyStringCopy(wchar_t *dest, const wchar_t *src)
while ((*dest++ = *src++) != 0);
}
+inline void MyStringCat(wchar_t *dest, const wchar_t *src)
+{
+ MyStringCopy(dest + MyStringLen(dest), src);
+}
+
+
/*
inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src)
{
@@ -88,13 +114,15 @@ int FindCharPosInString(const wchar_t *s, wchar_t c) throw();
#define STRING_UNICODE_THROW throw()
#endif
-/*
+
inline char MyCharUpper_Ascii(char c)
{
if (c >= 'a' && c <= 'z')
- return (char)(c - 0x20);
+ return (char)((unsigned char)c - 0x20);
return c;
}
+
+/*
inline wchar_t MyCharUpper_Ascii(wchar_t c)
{
if (c >= 'a' && c <= 'z')
@@ -158,6 +186,7 @@ inline wchar_t MyCharLower(wchar_t c) throw()
// char *MyStringUpper(char *s) throw();
// char *MyStringLower(char *s) throw();
+// void MyStringUpper_Ascii(char *s) throw();
// void MyStringUpper_Ascii(wchar_t *s) throw();
void MyStringLower_Ascii(char *s) throw();
void MyStringLower_Ascii(wchar_t *s) throw();
@@ -168,8 +197,11 @@ bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw();
bool IsString1PrefixedByString2(const char *s1, const char *s2) throw();
bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw();
+bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw();
+bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *u, const char *a) throw();
bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw();
+#define MyStringCompare(s1, s2) wcscmp(s1, s2)
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();
@@ -183,6 +215,33 @@ 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_);
+
+#define FORBID_STRING_OPS_2(cls, t) \
+ void Find(t) const; \
+ void Find(t, unsigned startIndex) const; \
+ void ReverseFind(t) const; \
+ void InsertAtFront(t); \
+ void RemoveChar(t); \
+ void Replace(t, t); \
+
+#define FORBID_STRING_OPS(cls, t) \
+ explicit cls(t); \
+ explicit cls(const t *); \
+ cls &operator=(t); \
+ cls &operator=(const t *); \
+ cls &operator+=(t); \
+ cls &operator+=(const t *); \
+ FORBID_STRING_OPS_2(cls, t); \
+
+/*
+ cls &operator+(t); \
+ cls &operator+(const t *); \
+*/
+
+#define FORBID_STRING_OPS_AString(t) FORBID_STRING_OPS(AString, t)
+#define FORBID_STRING_OPS_UString(t) FORBID_STRING_OPS(UString, t)
+#define FORBID_STRING_OPS_UString2(t) FORBID_STRING_OPS(UString2, t)
+
class AString
{
char *_chars;
@@ -202,7 +261,7 @@ class AString
void Grow_1();
void Grow(unsigned n);
- // AString(unsigned num, const char *s);
+ 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);
@@ -215,20 +274,24 @@ class AString
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);
+
+ #ifdef MY_NATIVE_WCHAR_T_DEFINED
+ FORBID_STRING_OPS_AString(wchar_t)
+ #endif
+
+ FORBID_STRING_OPS_AString(signed char)
+ FORBID_STRING_OPS_AString(unsigned char)
+ FORBID_STRING_OPS_AString(short)
+ FORBID_STRING_OPS_AString(unsigned short)
+ FORBID_STRING_OPS_AString(int)
+ FORBID_STRING_OPS_AString(unsigned)
+ FORBID_STRING_OPS_AString(long)
+ FORBID_STRING_OPS_AString(unsigned long)
public:
- AString();
- AString(char c);
- AString(const char *s);
+ explicit AString();
+ explicit AString(char c);
+ explicit AString(const char *s);
AString(const AString &s);
~AString() { MY_STRING_DELETE(_chars); }
@@ -240,7 +303,7 @@ public:
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]; }
+ char Back() const { return _chars[(size_t)_len - 1]; }
void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; }
@@ -292,16 +355,17 @@ public:
void Add_Space();
void Add_Space_if_NotEmpty();
+ void Add_OptSpaced(const char *s);
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 Add_UInt32(UInt32 v);
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); }
@@ -444,28 +508,27 @@ class UString
// ---------- 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);
+ FORBID_STRING_OPS_UString(signed char)
+ FORBID_STRING_OPS_UString(unsigned char)
+ FORBID_STRING_OPS_UString(short)
+
+ #ifdef MY_NATIVE_WCHAR_T_DEFINED
+ FORBID_STRING_OPS_UString(unsigned short)
+ #endif
+
+ FORBID_STRING_OPS_UString(int)
+ FORBID_STRING_OPS_UString(unsigned)
+ FORBID_STRING_OPS_UString(long)
+ FORBID_STRING_OPS_UString(unsigned long)
+
+ FORBID_STRING_OPS_2(UString, char)
public:
UString();
- UString(wchar_t c);
+ explicit UString(wchar_t c);
+ explicit UString(char c);
+ explicit UString(const char *s);
+ // UString(const AString &s);
UString(const wchar_t *s);
UString(const UString &s);
~UString() { MY_STRING_DELETE(_chars); }
@@ -478,7 +541,7 @@ public:
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]; }
+ wchar_t Back() const { return _chars[(size_t)_len - 1]; }
void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
@@ -508,9 +571,13 @@ public:
}
UString &operator=(wchar_t c);
+ UString &operator=(char c) { return (*this)=((wchar_t)c); }
UString &operator=(const wchar_t *s);
UString &operator=(const UString &s);
+ void SetFrom(const wchar_t *s, unsigned len); // no check
void SetFromBstr(BSTR s);
+ UString &operator=(const char *s);
+ UString &operator=(const AString &s) { return operator=(s.Ptr()); }
UString &operator+=(wchar_t c)
{
@@ -524,6 +591,8 @@ public:
return *this;
}
+ UString &operator+=(char c) { return (*this)+=((wchar_t)(unsigned char)c); }
+
void Add_Space();
void Add_Space_if_NotEmpty();
void Add_LF();
@@ -531,11 +600,10 @@ public:
UString &operator+=(const wchar_t *s);
UString &operator+=(const UString &s);
+ UString &operator+=(const char *s);
+ UString &operator+=(const AString &s) { return operator+=(s.Ptr()); }
- void SetFrom(const wchar_t *s, unsigned len); // no check
-
- void SetFromAscii(const char *s);
- void AddAscii(const char *s);
+ void Add_UInt32(UInt32 v);
UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); }
UString Left(unsigned count) const { return UString(count, *this); }
@@ -630,6 +698,12 @@ 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 AString &s1, const UString &s2);
+void operator+(const UString &s1, const AString &s2);
+
+void operator+(const UString &s1, const char *s2);
+void operator+(const char *s1, const UString &s2);
+
void operator+(const UString &s, char c);
void operator+(const UString &s, unsigned char c);
void operator+(char c, const UString &s);
@@ -662,15 +736,16 @@ class UString2
// ---------- forbidden functions ----------
- UString2 &operator=(char c);
- UString2 &operator=(unsigned char c);
+ FORBID_STRING_OPS_UString2(char)
+ FORBID_STRING_OPS_UString2(signed char)
+ FORBID_STRING_OPS_UString2(unsigned char)
+ FORBID_STRING_OPS_UString2(short)
+
UString2 &operator=(wchar_t c);
- UString2(char c);
- UString2(unsigned char c);
+ UString2(wchar_t 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); }
@@ -682,6 +757,8 @@ public:
// operator const wchar_t *() const { return _chars; }
const wchar_t *GetRawPtr() const { return _chars; }
+ int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
+
wchar_t *GetBuf(unsigned minLen)
{
if (!_chars || minLen > _len)
@@ -754,6 +831,7 @@ typedef CObjectVector<CSysString> CSysStringVector;
#define fs2us(_x_) (_x_)
#define us2fs(_x_) (_x_)
+ FString fas2fs(const char *s);
FString fas2fs(const AString &s);
AString fs2fas(const FChar *s);
@@ -764,6 +842,7 @@ typedef CObjectVector<CSysString> CSysStringVector;
typedef char FChar;
typedef AString FString;
+ UString fs2us(const FChar *s);
UString fs2us(const FString &s);
FString us2fs(const wchar_t *s);
#define fas2fs(_x_) (_x_)
@@ -775,8 +854,10 @@ typedef CObjectVector<CSysString> CSysStringVector;
#define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR)
#define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR)
-#define FCHAR_ANY_MASK FTEXT('*')
-#define FSTRING_ANY_MASK FTEXT("*")
+
+// #define FCHAR_ANY_MASK FTEXT('*')
+// #define FSTRING_ANY_MASK FTEXT("*")
+
typedef const FChar *CFSTR;
typedef CObjectVector<FString> FStringVector;
diff --git a/CPP/Common/MyVector.h b/CPP/Common/MyVector.h
index 14f7b11a..61dabbd1 100644
--- a/CPP/Common/MyVector.h
+++ b/CPP/Common/MyVector.h
@@ -22,7 +22,9 @@ class CRecordVector
if (_size == _capacity)
{
unsigned newCapacity = _capacity + (_capacity >> 2) + 1;
- T *p = new T[newCapacity];
+ T *p;
+ MY_ARRAY_NEW(p, T, newCapacity);
+ // p = new T[newCapacity];
if (_size != 0)
memcpy(p, _items, (size_t)_size * sizeof(T));
delete []_items;
@@ -54,7 +56,8 @@ public:
{
if (size != 0)
{
- _items = new T[size];
+ MY_ARRAY_NEW(_items, T, size)
+ // _items = new T[size];
_capacity = size;
}
}
@@ -63,7 +66,9 @@ public:
{
if (newCapacity > _capacity)
{
- T *p = new T[newCapacity];
+ T *p;
+ MY_ARRAY_NEW(p, T, newCapacity);
+ // p = new T[newCapacity];
if (_size != 0)
memcpy(p, _items, (size_t)_size * sizeof(T));
delete []_items;
@@ -80,7 +85,8 @@ public:
delete []_items;
_items = NULL;
_capacity = 0;
- _items = new T[newCapacity];
+ MY_ARRAY_NEW(_items, T, newCapacity)
+ // _items = new T[newCapacity];
_capacity = newCapacity;
}
}
@@ -95,7 +101,9 @@ public:
{
if (newSize > _capacity)
{
- T *p = new T[newSize];
+ T *p;
+ MY_ARRAY_NEW(p, T, newSize)
+ // p = new T[newSize];
if (_size != 0)
memcpy(p, _items, (size_t)_size * sizeof(T));
delete []_items;
@@ -230,8 +238,8 @@ public:
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]; }
+ const T& Back() const { return _items[(size_t)_size - 1]; }
+ T& Back() { return _items[(size_t)_size - 1]; }
/*
void Swap(unsigned i, unsigned j)
@@ -370,7 +378,7 @@ public:
unsigned s = (k << 1);
if (s > size)
break;
- if (s < size && p[s + 1].Compare(p[s]) > 0)
+ if (s < size && p[(size_t)s + 1].Compare(p[s]) > 0)
s++;
if (temp.Compare(p[s]) >= 0)
break;
@@ -453,8 +461,8 @@ public:
T& operator[](unsigned index) { return *((T *)_v[index]); }
const T& Front() const { return operator[](0); }
T& Front() { return operator[](0); }
- const T& Back() const { return operator[](_v.Size() - 1); }
- T& Back() { return operator[](_v.Size() - 1); }
+ const T& Back() const { return *(T *)_v.Back(); }
+ T& Back() { return *(T *)_v.Back(); }
void MoveToFront(unsigned index) { _v.MoveToFront(index); }
@@ -521,7 +529,7 @@ public:
void DeleteBack()
{
- delete (T *)_v[_v.Size() - 1];
+ delete (T *)_v.Back();
_v.DeleteBack();
}
diff --git a/CPP/Common/MyWindows.h b/CPP/Common/MyWindows.h
index 139a4e8b..a8db9e65 100644
--- a/CPP/Common/MyWindows.h
+++ b/CPP/Common/MyWindows.h
@@ -44,6 +44,16 @@ typedef UINT32 ULONG;
#undef DWORD
typedef UINT32 DWORD;
+typedef long BOOL;
+
+#ifndef FALSE
+ #define FALSE 0
+ #define TRUE 1
+#endif
+
+// typedef size_t ULONG_PTR;
+typedef size_t DWORD_PTR;
+
typedef Int64 LONGLONG;
typedef UInt64 ULONGLONG;
diff --git a/CPP/Common/MyXml.cpp b/CPP/Common/MyXml.cpp
index a177e4a2..f34a745e 100644
--- a/CPP/Common/MyXml.cpp
+++ b/CPP/Common/MyXml.cpp
@@ -20,7 +20,7 @@ static bool IsSpaceChar(char c)
#define SKIP_SPACES(s) while (IsSpaceChar(*s)) s++;
-int CXmlItem::FindProp(const AString &propName) const throw()
+int CXmlItem::FindProp(const char *propName) const throw()
{
FOR_VECTOR (i, Props)
if (Props[i].Name == propName)
@@ -28,7 +28,7 @@ int CXmlItem::FindProp(const AString &propName) const throw()
return -1;
}
-AString CXmlItem::GetPropVal(const AString &propName) const
+AString CXmlItem::GetPropVal(const char *propName) const
{
int index = FindProp(propName);
if (index >= 0)
@@ -36,12 +36,12 @@ AString CXmlItem::GetPropVal(const AString &propName) const
return AString();
}
-bool CXmlItem::IsTagged(const AString &tag) const throw()
+bool CXmlItem::IsTagged(const char *tag) const throw()
{
return (IsTag && Name == tag);
}
-int CXmlItem::FindSubTag(const AString &tag) const throw()
+int CXmlItem::FindSubTag(const char *tag) const throw()
{
FOR_VECTOR (i, SubItems)
if (SubItems[i].IsTagged(tag))
@@ -71,7 +71,7 @@ const AString * CXmlItem::GetSubStringPtr() const throw()
return NULL;
}
-AString CXmlItem::GetSubStringForTag(const AString &tag) const
+AString CXmlItem::GetSubStringForTag(const char *tag) const
{
int index = FindSubTag(tag);
if (index >= 0)
diff --git a/CPP/Common/MyXml.h b/CPP/Common/MyXml.h
index 0e4b21d4..00b7113a 100644
--- a/CPP/Common/MyXml.h
+++ b/CPP/Common/MyXml.h
@@ -21,13 +21,13 @@ public:
const char * ParseItem(const char *s, int numAllowedLevels);
- bool IsTagged(const AString &tag) const throw();
- int FindProp(const AString &propName) const throw();
- AString GetPropVal(const AString &propName) const;
+ bool IsTagged(const char *tag) const throw();
+ int FindProp(const char *propName) const throw();
+ AString GetPropVal(const char *propName) const;
AString GetSubString() const;
const AString * GetSubStringPtr() const throw();
- int FindSubTag(const AString &tag) const throw();
- AString GetSubStringForTag(const AString &tag) const;
+ int FindSubTag(const char *tag) const throw();
+ AString GetSubStringForTag(const char *tag) const;
void AppendTo(AString &s) const;
};
diff --git a/CPP/Common/NewHandler.cpp b/CPP/Common/NewHandler.cpp
index 522c2a75..7e5b1d45 100644
--- a/CPP/Common/NewHandler.cpp
+++ b/CPP/Common/NewHandler.cpp
@@ -10,7 +10,7 @@
#ifndef DEBUG_MEMORY_LEAK
-#ifdef _WIN32
+#ifdef _7ZIP_REDEFINE_OPERATOR_NEW
/*
void * my_new(size_t size)
diff --git a/CPP/Common/NewHandler.h b/CPP/Common/NewHandler.h
index dcad5688..aedeca64 100644
--- a/CPP/Common/NewHandler.h
+++ b/CPP/Common/NewHandler.h
@@ -4,28 +4,29 @@
#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.
+NewHandler.h and NewHandler.cpp allows to solve problem with compilers that
+don't throw exception in operator new().
-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.
+This file must be included before any code that uses operators new() or delete()
+and you must compile and link "NewHandler.cpp", if you use some old MSVC compiler.
-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.
+The operator new() in some MSVC versions doesn't throw exception std::bad_alloc.
+MSVC 6.0 (_MSC_VER == 1200) doesn't throw exception.
+The code produced by some another MSVC compilers also can be linked
+to library that doesn't throw exception.
+We suppose that code compiled with VS2015+ (_MSC_VER >= 1900) throws exception std::bad_alloc.
+For older _MSC_VER versions we redefine operator new() and operator delete().
+Our version of operator new() throws CNewException() exception on failure.
-Also we declare delete(void *p) throw() that creates smaller code.
+It's still allowed to use redefined version of operator new() from "NewHandler.cpp"
+with any compiler. 7-Zip's code can work with std::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() is not problem for your code.
*/
#include <stddef.h>
-class CNewException {};
-
-#ifdef WIN32
+#ifdef _WIN32
// We can compile my_new and my_delete with _fastcall
/*
void * my_new(size_t size);
@@ -34,7 +35,19 @@ void my_delete(void *p) throw();
*/
#endif
-#ifdef _WIN32
+
+#if defined(_MSC_VER) && (_MSC_VER < 1900)
+ // If you want to use default operator new(), you can disable the following line
+ #define _7ZIP_REDEFINE_OPERATOR_NEW
+#endif
+
+
+#ifdef _7ZIP_REDEFINE_OPERATOR_NEW
+
+// std::bad_alloc can require additional DLL dependency.
+// So we don't define CNewException as std::bad_alloc here.
+
+class CNewException {};
void *
#ifdef _MSC_VER
@@ -48,6 +61,12 @@ __cdecl
#endif
operator delete(void *p) throw();
+#else
+
+#include <new>
+
+#define CNewException std::bad_alloc
+
#endif
/*
diff --git a/CPP/Common/StdInStream.cpp b/CPP/Common/StdInStream.cpp
index c35747bb..422a96e5 100644
--- a/CPP/Common/StdInStream.cpp
+++ b/CPP/Common/StdInStream.cpp
@@ -8,13 +8,11 @@
#include "StringConvert.h"
#include "UTFConvert.h"
-static const char kNewLineChar = '\n';
+// #define kEOFMessage "Unexpected end of input stream"
+// #define kReadErrorMessage "Error reading input stream"
+// #define kIllegalCharMessage "Illegal zero character in input stream"
-static const char *kEOFMessage = "Unexpected end of input stream";
-static const char *kReadErrorMessage ="Error reading input stream";
-static const char *kIllegalCharMessage = "Illegal character in input stream";
-
-static LPCTSTR kFileOpenMode = TEXT("r");
+#define kFileOpenMode TEXT("r")
extern int g_CodePage;
@@ -36,59 +34,56 @@ bool CStdInStream::Close() throw()
return !_streamIsOpen;
}
-AString CStdInStream::ScanStringUntilNewLine(bool allowEOF)
+bool CStdInStream::ScanAStringUntilNewLine(AString &s)
{
- AString s;
+ s.Empty();
for (;;)
{
int intChar = GetChar();
if (intChar == EOF)
- {
- if (allowEOF)
- break;
- throw kEOFMessage;
- }
+ return true;
char c = (char)intChar;
if (c == 0)
- throw kIllegalCharMessage;
- if (c == kNewLineChar)
- break;
+ return false;
+ if (c == '\n')
+ return true;
s += c;
}
- return s;
}
-UString CStdInStream::ScanUStringUntilNewLine()
+bool CStdInStream::ScanUStringUntilNewLine(UString &dest)
{
- AString s = ScanStringUntilNewLine(true);
+ dest.Empty();
+ AString s;
+ bool res = ScanAStringUntilNewLine(s);
int codePage = g_CodePage;
if (codePage == -1)
codePage = CP_OEMCP;
- UString dest;
if (codePage == CP_UTF8)
ConvertUTF8ToUnicode(s, dest);
else
- dest = MultiByteToUnicodeString(s, (UINT)codePage);
- return dest;
+ MultiByteToUnicodeString2(dest, s, (UINT)codePage);
+ return res;
}
-void CStdInStream::ReadToString(AString &resultString)
+/*
+bool CStdInStream::ReadToString(AString &resultString)
{
resultString.Empty();
- int c;
- while ((c = GetChar()) != EOF)
- resultString += (char)c;
-}
-
-bool CStdInStream::Eof() throw()
-{
- return (feof(_stream) != 0);
+ for (;;)
+ {
+ int intChar = GetChar();
+ if (intChar == EOF)
+ return !Error();
+ char c = (char)intChar;
+ if (c == 0)
+ return false;
+ resultString += c;
+ }
}
+*/
int CStdInStream::GetChar()
{
- int c = fgetc(_stream); // getc() doesn't work in BeOS?
- if (c == EOF && !Eof())
- throw kReadErrorMessage;
- return c;
+ return fgetc(_stream); // getc() doesn't work in BeOS?
}
diff --git a/CPP/Common/StdInStream.h b/CPP/Common/StdInStream.h
index 6d9ed670..698ebec1 100644
--- a/CPP/Common/StdInStream.h
+++ b/CPP/Common/StdInStream.h
@@ -20,11 +20,16 @@ public:
bool Open(LPCTSTR fileName) throw();
bool Close() throw();
- AString ScanStringUntilNewLine(bool allowEOF = false);
- void ReadToString(AString &resultString);
- UString ScanUStringUntilNewLine();
+ // returns:
+ // false, if ZERO character in stream
+ // true, if EOF or '\n'
+ bool ScanAStringUntilNewLine(AString &s);
+ bool ScanUStringUntilNewLine(UString &s);
+ // bool ReadToString(AString &resultString);
+
+ bool Eof() const throw() { return (feof(_stream) != 0); }
+ bool Error() const throw() { return (ferror(_stream) != 0); }
- bool Eof() throw();
int GetChar();
};
diff --git a/CPP/Common/StdOutStream.cpp b/CPP/Common/StdOutStream.cpp
index 6aed31a3..19e0329f 100644
--- a/CPP/Common/StdOutStream.cpp
+++ b/CPP/Common/StdOutStream.cpp
@@ -9,9 +9,7 @@
#include "StringConvert.h"
#include "UTFConvert.h"
-static const char kNewLineChar = '\n';
-
-static const char *kFileOpenMode = "wt";
+#define kFileOpenMode "wt"
extern int g_CodePage;
@@ -44,7 +42,7 @@ bool CStdOutStream::Flush() throw()
CStdOutStream & endl(CStdOutStream & outStream) throw()
{
- return outStream << kNewLineChar;
+ return outStream << '\n';
}
CStdOutStream & CStdOutStream::operator<<(const wchar_t *s)
diff --git a/CPP/Common/StringConvert.cpp b/CPP/Common/StringConvert.cpp
index 30d95aa7..2a73d688 100644
--- a/CPP/Common/StringConvert.cpp
+++ b/CPP/Common/StringConvert.cpp
@@ -291,6 +291,12 @@ UString MultiByteToUnicodeString(const AString &src, UINT codePage)
return dest;
}
+UString MultiByteToUnicodeString(const char *src, UINT codePage)
+{
+ return MultiByteToUnicodeString(AString(src), codePage);
+}
+
+
void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage)
{
bool defaultCharWasUsed;
diff --git a/CPP/Common/StringConvert.h b/CPP/Common/StringConvert.h
index 92401245..25fe503f 100644
--- a/CPP/Common/StringConvert.h
+++ b/CPP/Common/StringConvert.h
@@ -6,72 +6,83 @@
#include "MyString.h"
#include "MyWindows.h"
-UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP);
+UString MultiByteToUnicodeString(const AString &src, UINT codePage = CP_ACP);
+UString MultiByteToUnicodeString(const char *src, UINT codePage = CP_ACP);
// optimized versions that work faster for ASCII strings
-void MultiByteToUnicodeString2(UString &dest, const AString &srcString, UINT codePage = CP_ACP);
+void MultiByteToUnicodeString2(UString &dest, const AString &src, 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)
- { return unicodeString; }
-inline UString GetUnicodeString(const AString &ansiString)
- { return MultiByteToUnicodeString(ansiString); }
-inline UString GetUnicodeString(const AString &multiByteString, UINT codePage)
- { return MultiByteToUnicodeString(multiByteString, codePage); }
-inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT)
- { return unicodeString; }
-inline const UString& GetUnicodeString(const UString &unicodeString, UINT)
- { return unicodeString; }
-
-inline const char* GetAnsiString(const char* ansiString)
- { return ansiString; }
-inline const AString& GetAnsiString(const AString &ansiString)
- { return ansiString; }
-inline AString GetAnsiString(const UString &unicodeString)
- { return UnicodeStringToMultiByte(unicodeString); }
-
-inline const char* GetOemString(const char* oemString)
- { return oemString; }
-inline const AString& GetOemString(const AString &oemString)
- { return oemString; }
-inline AString GetOemString(const UString &unicodeString)
- { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); }
+void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage);
+AString UnicodeStringToMultiByte(const UString &src, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
+AString UnicodeStringToMultiByte(const UString &src, UINT codePage = CP_ACP);
+
+inline const wchar_t* GetUnicodeString(const wchar_t *u) { return u; }
+inline const UString& GetUnicodeString(const UString &u) { return u; }
+
+inline UString GetUnicodeString(const AString &a) { return MultiByteToUnicodeString(a); }
+inline UString GetUnicodeString(const char *a) { return MultiByteToUnicodeString(a); }
+
+inline UString GetUnicodeString(const AString &a, UINT codePage)
+ { return MultiByteToUnicodeString(a, codePage); }
+inline UString GetUnicodeString(const char *a, UINT codePage)
+ { return MultiByteToUnicodeString(a, codePage); }
+
+inline const wchar_t* GetUnicodeString(const wchar_t *u, UINT) { return u; }
+inline const UString& GetUnicodeString(const UString &u, UINT) { return u; }
+
+inline const char* GetAnsiString(const char *a) { return a; }
+inline const AString& GetAnsiString(const AString &a) { return a; }
+
+inline AString GetAnsiString(const wchar_t *u) { return UnicodeStringToMultiByte(UString(u)); }
+inline AString GetAnsiString(const UString &u) { return UnicodeStringToMultiByte(u); }
+
+/*
+inline const char* GetOemString(const char* oem)
+ { return oem; }
+inline const AString& GetOemString(const AString &oem)
+ { return oem; }
+*/
+const char* GetOemString(const char* oem);
+const AString& GetOemString(const AString &oem);
+inline AString GetOemString(const UString &u)
+ { return UnicodeStringToMultiByte(u, CP_OEMCP); }
#ifdef _UNICODE
- inline const wchar_t* GetSystemString(const wchar_t* unicodeString)
- { return unicodeString;}
- inline const UString& GetSystemString(const UString &unicodeString)
- { return unicodeString;}
- inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT /* codePage */)
- { return unicodeString;}
- inline const UString& GetSystemString(const UString &unicodeString, UINT /* codePage */)
- { return unicodeString;}
- inline UString GetSystemString(const AString &multiByteString, UINT codePage)
- { return MultiByteToUnicodeString(multiByteString, codePage);}
- inline UString GetSystemString(const AString &multiByteString)
- { return MultiByteToUnicodeString(multiByteString);}
+ inline const wchar_t* GetSystemString(const wchar_t *u) { return u;}
+ inline const UString& GetSystemString(const UString &u) { return u;}
+ inline const wchar_t* GetSystemString(const wchar_t *u, UINT /* codePage */) { return u;}
+ inline const UString& GetSystemString(const UString &u, UINT /* codePage */) { return u;}
+
+ inline UString GetSystemString(const AString &a, UINT codePage) { return MultiByteToUnicodeString(a, codePage); }
+ inline UString GetSystemString(const char *a, UINT codePage) { return MultiByteToUnicodeString(a, codePage); }
+ inline UString GetSystemString(const AString &a) { return MultiByteToUnicodeString(a); }
+ inline UString GetSystemString(const char *a) { return MultiByteToUnicodeString(a); }
#else
- inline const char* GetSystemString(const char *ansiString)
- { return ansiString; }
- inline const AString& GetSystemString(const AString &multiByteString, UINT)
- { return multiByteString; }
- inline const char * GetSystemString(const char *multiByteString, UINT)
- { return multiByteString; }
- inline AString GetSystemString(const UString &unicodeString)
- { return UnicodeStringToMultiByte(unicodeString); }
- inline AString GetSystemString(const UString &unicodeString, UINT codePage)
- { return UnicodeStringToMultiByte(unicodeString, codePage); }
+ inline const char* GetSystemString(const char *a) { return a; }
+ inline const AString& GetSystemString(const AString &a) { return a; }
+ inline const char* GetSystemString(const char *a, UINT) { return a; }
+ inline const AString& GetSystemString(const AString &a, UINT) { return a; }
+
+ inline AString GetSystemString(const wchar_t *u) { return UnicodeStringToMultiByte(UString(u)); }
+ inline AString GetSystemString(const UString &u) { return UnicodeStringToMultiByte(u); }
+ inline AString GetSystemString(const UString &u, UINT codePage) { return UnicodeStringToMultiByte(u, codePage); }
+
+
+
+ /*
+ inline AString GetSystemString(const wchar_t *u)
+ {
+ UString s;
+ s = u;
+ return UnicodeStringToMultiByte(s);
+ }
+ */
+
#endif
#ifndef UNDER_CE
-AString SystemStringToOemString(const CSysString &srcString);
+AString SystemStringToOemString(const CSysString &src);
#endif
#endif
diff --git a/CPP/Common/TextConfig.cpp b/CPP/Common/TextConfig.cpp
index 9ae4074b..1428aab5 100644
--- a/CPP/Common/TextConfig.cpp
+++ b/CPP/Common/TextConfig.cpp
@@ -61,7 +61,7 @@ bool GetTextConfig(const AString &s, CObjectVector<CTextConfigPair> &pairs)
break;
CTextConfigPair pair;
unsigned finishPos;
- AString temp = GetIDString(((const char *)s) + pos, finishPos);
+ const AString temp (GetIDString(((const char *)s) + pos, finishPos));
if (!ConvertUTF8ToUnicode(temp, pair.ID))
return false;
if (finishPos == 0)
@@ -107,15 +107,15 @@ bool GetTextConfig(const AString &s, CObjectVector<CTextConfigPair> &pairs)
return true;
}
-int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id) throw()
+int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const char *id) throw()
{
FOR_VECTOR (i, pairs)
- if (pairs[i].ID == id)
+ if (pairs[i].ID.IsEqualTo(id))
return i;
return -1;
}
-UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id)
+UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const char *id)
{
int index = FindTextConfigItem(pairs, id);
if (index < 0)
diff --git a/CPP/Common/TextConfig.h b/CPP/Common/TextConfig.h
index 0129ad96..cc7ce412 100644
--- a/CPP/Common/TextConfig.h
+++ b/CPP/Common/TextConfig.h
@@ -13,7 +13,7 @@ struct CTextConfigPair
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);
+int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const char *id) throw();
+UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const char *id);
#endif
diff --git a/CPP/Common/Wildcard.cpp b/CPP/Common/Wildcard.cpp
index 5e6ddfc6..a7199170 100644
--- a/CPP/Common/Wildcard.cpp
+++ b/CPP/Common/Wildcard.cpp
@@ -22,16 +22,18 @@ bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2)
int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW
{
if (g_CaseSensitive)
- return wcscmp(s1, s2);
+ return MyStringCompare(s1, s2);
return MyStringCompareNoCase(s1, s2);
}
#ifndef USE_UNICODE_FSTRING
int CompareFileNames(const char *s1, const char *s2)
{
+ const UString u1 = fs2us(s1);
+ const UString u2 = fs2us(s2);
if (g_CaseSensitive)
- return wcscmp(fs2us(s1), fs2us(s2));
- return MyStringCompareNoCase(fs2us(s1), fs2us(s2));
+ return MyStringCompare(u1, u2);
+ return MyStringCompareNoCase(u1, u2);
}
#endif
@@ -120,24 +122,16 @@ void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &na
name = p;
}
+/*
UString ExtractDirPrefixFromPath(const UString &path)
{
- const wchar_t *start = path;
- const wchar_t *p = start + path.Len();
- for (; p != start; p--)
- if (IsPathSepar(*(p - 1)))
- break;
- return path.Left((unsigned)(p - start));
+ return path.Left(path.ReverseFind_PathSepar() + 1));
}
+*/
UString ExtractFileNameFromPath(const UString &path)
{
- const wchar_t *start = path;
- const wchar_t *p = start + path.Len();
- for (; p != start; p--)
- if (IsPathSepar(*(p - 1)))
- break;
- return p;
+ return UString(path.Ptr(path.ReverseFind_PathSepar() + 1));
}
@@ -425,7 +419,7 @@ void CCensorNode::AddItem2(bool include, const UString &path, bool recursive, bo
return;
bool forFile = true;
bool forFolder = true;
- UString path2 = path;
+ UString path2 (path);
if (IsPathSepar(path.Back()))
{
path2.DeleteBack();
@@ -612,7 +606,7 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat
{
// we create universal item, if we skip all parts as prefix (like \ or L:\ )
pathParts.Clear();
- pathParts.Add(L"*");
+ pathParts.Add(UString("*"));
forFile = true;
wildcardMatching = true;
recursive = false;
diff --git a/CPP/Common/Wildcard.h b/CPP/Common/Wildcard.h
index 512687d1..93f53c0f 100644
--- a/CPP/Common/Wildcard.h
+++ b/CPP/Common/Wildcard.h
@@ -139,7 +139,7 @@ public:
}
void AddPreItem_Wildcard()
{
- AddPreItem(true, L"*", false, true);
+ AddPreItem(true, UString("*"), false, true);
}
};
diff --git a/CPP/Common/XzCrc64Init.cpp b/CPP/Common/XzCrc64Init.cpp
new file mode 100644
index 00000000..5cb8e674
--- /dev/null
+++ b/CPP/Common/XzCrc64Init.cpp
@@ -0,0 +1,7 @@
+// XzCrc64Init.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/XzCrc64.h"
+
+static struct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit;
diff --git a/CPP/Windows/Clipboard.cpp b/CPP/Windows/Clipboard.cpp
index e0996930..bc7e201d 100644
--- a/CPP/Windows/Clipboard.cpp
+++ b/CPP/Windows/Clipboard.cpp
@@ -117,7 +117,7 @@ bool ClipboardSetText(HWND owner, const UString &s)
bool res;
res = ClipboardSetData(CF_UNICODETEXT, (const wchar_t *)s, (s.Len() + 1) * sizeof(wchar_t));
#ifndef _UNICODE
- AString a = UnicodeStringToMultiByte(s, CP_ACP);
+ AString a (UnicodeStringToMultiByte(s, CP_ACP));
if (ClipboardSetData(CF_TEXT, (const char *)a, (a.Len() + 1) * sizeof(char)))
res = true;
a = UnicodeStringToMultiByte(s, CP_OEMCP);
diff --git a/CPP/Windows/Control/PropertyPage.cpp b/CPP/Windows/Control/PropertyPage.cpp
index bbac74ad..ce8696d4 100644
--- a/CPP/Windows/Control/PropertyPage.cpp
+++ b/CPP/Windows/Control/PropertyPage.cpp
@@ -115,7 +115,7 @@ INT_PTR MyPropertySheet(const CObjectVector<CPageInfo> &pagesInfo, HWND hwndPare
sheet.dwFlags = PSH_PROPSHEETPAGE;
sheet.hwndParent = hwndParent;
sheet.hInstance = g_hInstance;
- AString titleA = GetSystemString(title);
+ AString titleA (GetSystemString(title));
sheet.pszCaption = titleA;
sheet.nPages = pagesInfo.Size();
sheet.nStartPage = 0;
diff --git a/CPP/Windows/DLL.cpp b/CPP/Windows/DLL.cpp
index a71a8017..d7f38375 100644
--- a/CPP/Windows/DLL.cpp
+++ b/CPP/Windows/DLL.cpp
@@ -97,12 +97,11 @@ FString GetModuleDirPrefix()
{
int pos = s.ReverseFind_PathSepar();
if (pos >= 0)
- {
s.DeleteFrom(pos + 1);
- return s;
- }
}
- return FTEXT(".") FSTRING_PATH_SEPARATOR;
+ if (s.IsEmpty())
+ s = "." STRING_PATH_SEPARATOR;
+ return s;
}
#endif
diff --git a/CPP/Windows/ErrorMsg.cpp b/CPP/Windows/ErrorMsg.cpp
index c9de4a6c..b86c0b39 100644
--- a/CPP/Windows/ErrorMsg.cpp
+++ b/CPP/Windows/ErrorMsg.cpp
@@ -53,8 +53,8 @@ UString MyFormatMessage(DWORD errorCode)
s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
s[8] = 0;
- m.AddAscii("Error #");
- m.AddAscii(s);
+ m += "Error #";
+ m += s;
}
else if (m.Len() >= 2
&& m[m.Len() - 1] == 0x0A
diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp
index da71b710..a7164b6b 100644
--- a/CPP/Windows/FileDir.cpp
+++ b/CPP/Windows/FileDir.cpp
@@ -345,7 +345,7 @@ bool CreateComplexDir(CFSTR _path)
#endif
- FString path = _path;
+ FString path (_path);
int pos = path.ReverseFind_PathSepar();
if (pos >= 0 && (unsigned)pos == path.Len() - 1)
@@ -355,7 +355,7 @@ bool CreateComplexDir(CFSTR _path)
path.DeleteBack();
}
- const FString path2 = path;
+ const FString path2 (path);
pos = path.Len();
for (;;)
@@ -452,11 +452,11 @@ bool RemoveDirWithSubItems(const FString &path)
if (needRemoveSubItems)
{
- FString s = path;
+ FString s (path);
s.Add_PathSepar();
- unsigned prefixSize = s.Len();
- s += FCHAR_ANY_MASK;
- NFind::CEnumerator enumerator(s);
+ const unsigned prefixSize = s.Len();
+ NFind::CEnumerator enumerator;
+ enumerator.SetDirPrefix(s);
NFind::CFileInfo fi;
while (enumerator.Next(fi))
{
@@ -580,18 +580,18 @@ static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COu
path = prefix;
if (addRandom)
{
- FChar s[16];
- UInt32 value = d;
+ char s[16];
+ UInt32 val = d;
unsigned k;
for (k = 0; k < 8; k++)
{
- unsigned t = value & 0xF;
- value >>= 4;
- s[k] = (FChar)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ unsigned t = val & 0xF;
+ val >>= 4;
+ s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
s[k] = '\0';
if (outFile)
- path += FChar('.');
+ path += '.';
path += s;
UInt32 step = GetTickCount() + 2;
if (step == 0)
@@ -600,7 +600,7 @@ static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COu
}
addRandom = true;
if (outFile)
- path += FTEXT(".tmp");
+ path += ".tmp";
if (NFind::DoesFileOrDirExist(path))
{
SetLastError(ERROR_ALREADY_EXISTS);
diff --git a/CPP/Windows/FileFind.cpp b/CPP/Windows/FileFind.cpp
index 05196f92..b9692b81 100644
--- a/CPP/Windows/FileFind.cpp
+++ b/CPP/Windows/FileFind.cpp
@@ -227,7 +227,7 @@ bool CStreamInfo::IsMainStream() const throw()
UString CStreamInfo::GetReducedName() const
{
// remove ":$DATA" postfix, but keep postfix, if Name is "::$DATA"
- UString s = Name;
+ UString s (Name);
if (s.Len() > 6 + 1 && StringsAreEqualNoCase_Ascii(s.RightPtr(6), ":$DATA"))
s.DeleteFrom(s.Len() - 6);
return s;
@@ -453,7 +453,7 @@ bool CFileInfo::Find(CFSTR path)
if (colonPos >= 0 && path[(unsigned)colonPos + 1] != 0)
{
UString streamName = fs2us(path + (unsigned)colonPos);
- FString filePath = path;
+ FString filePath (path);
filePath.DeleteFrom(colonPos);
/* we allow both cases:
name:stream
@@ -462,7 +462,7 @@ bool CFileInfo::Find(CFSTR path)
const unsigned kPostfixSize = 6;
if (streamName.Len() <= kPostfixSize
|| !StringsAreEqualNoCase_Ascii(streamName.RightPtr(kPostfixSize), ":$DATA"))
- streamName += L":$DATA";
+ streamName += ":$DATA";
bool isOk = true;
@@ -559,9 +559,9 @@ bool CFileInfo::Find(CFSTR path)
{
if (NName::FindSepar(path + prefixSize) < 0)
{
- FString s = path;
+ FString s (path);
s.Add_PathSepar();
- s += FCHAR_ANY_MASK;
+ s += '*'; // CHAR_ANY_MASK
bool isOK = false;
if (finder.FindFirst(s, *this))
@@ -618,6 +618,12 @@ bool DoesFileOrDirExist(CFSTR name)
}
+void CEnumerator::SetDirPrefix(const FString &dirPrefix)
+{
+ _wildcard = dirPrefix;
+ _wildcard += '*';
+}
+
bool CEnumerator::NextAny(CFileInfo &fi)
{
if (_findFile.IsHandleAllocated())
diff --git a/CPP/Windows/FileFind.h b/CPP/Windows/FileFind.h
index 615c2dfe..bfb29206 100644
--- a/CPP/Windows/FileFind.h
+++ b/CPP/Windows/FileFind.h
@@ -134,7 +134,7 @@ class CEnumerator
bool NextAny(CFileInfo &fileInfo);
public:
- CEnumerator(const FString &wildcard): _wildcard(wildcard) {}
+ void SetDirPrefix(const FString &dirPrefix);
bool Next(CFileInfo &fileInfo);
bool Next(CFileInfo &fileInfo, bool &found);
};
diff --git a/CPP/Windows/FileLink.cpp b/CPP/Windows/FileLink.cpp
index 25d49ac3..9e706ead 100644
--- a/CPP/Windows/FileLink.cpp
+++ b/CPP/Windows/FileLink.cpp
@@ -74,7 +74,7 @@ static const UInt32 kReparseFlags_Microsoft = ((UInt32)1 << 31);
#define Set16(p, v) SetUi16(p, v)
#define Set32(p, v) SetUi32(p, v)
-static const wchar_t *k_LinkPrefix = L"\\??\\";
+static const wchar_t * const k_LinkPrefix = L"\\??\\";
static const unsigned k_LinkPrefix_Size = 4;
static const bool IsLinkPrefix(const wchar_t *s)
@@ -83,7 +83,7 @@ static const bool IsLinkPrefix(const wchar_t *s)
}
/*
-static const wchar_t *k_VolumePrefix = L"Volume{";
+static const wchar_t * const k_VolumePrefix = L"Volume{";
static const bool IsVolumeName(const wchar_t *s)
{
return IsString1PrefixedByString2(s, k_VolumePrefix);
@@ -332,7 +332,7 @@ bool CReparseAttr::IsVolume() const
UString CReparseAttr::GetPath() const
{
- UString s = SubsName;
+ UString s (SubsName);
if (IsLinkPrefix(s))
{
s.ReplaceOneCharAtPos(1, '\\');
@@ -376,7 +376,7 @@ bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMA
static bool CreatePrefixDirOfFile(CFSTR path)
{
- FString path2 = path;
+ FString path2 (path);
int pos = path2.ReverseFind_PathSepar();
if (pos < 0)
return true;
diff --git a/CPP/Windows/FileName.cpp b/CPP/Windows/FileName.cpp
index 908ed53f..2d0b50d5 100644
--- a/CPP/Windows/FileName.cpp
+++ b/CPP/Windows/FileName.cpp
@@ -87,8 +87,8 @@ bool IsAltPathPrefix(CFSTR s) throw()
#if defined(_WIN32) && !defined(UNDER_CE)
-const wchar_t *kSuperPathPrefix = L"\\\\?\\";
-static const wchar_t *kSuperUncPrefix = L"\\\\?\\UNC\\";
+const char * const kSuperPathPrefix = "\\\\?\\";
+static const char * const kSuperUncPrefix = "\\\\?\\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]))
@@ -109,7 +109,7 @@ bool IsDevicePath(CFSTR s) throw()
/*
// 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)
+ if (len < 5 || len > 5 || !IsString1PrefixedByString2(s, "DSK"))
return false;
if (s[4] != ':')
return false;
@@ -123,7 +123,7 @@ bool IsDevicePath(CFSTR s) throw()
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)
+ if (len < 18 || len > 22 || !IsString1PrefixedByString2(s + kDevicePathPrefixSize, "PhysicalDrive"))
return false;
for (unsigned i = 17; i < len; i++)
if (s[i] < '0' || s[i] > '9')
@@ -191,14 +191,12 @@ 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)
+bool IsDrivePath_SuperAllowed(CFSTR s) throw()
{
if (IsSuperPath(s))
s += kSuperPathPrefixSize;
return IsDrivePath(s);
}
-*/
bool IsDriveRootPath_SuperAllowed(CFSTR s) throw()
{
@@ -212,7 +210,7 @@ bool IsAbsolutePath(const wchar_t *s) throw()
return IS_SEPAR(s[0]) || IsDrivePath2(s);
}
-int FindAltStreamColon(CFSTR path)
+int FindAltStreamColon(CFSTR path) throw()
{
unsigned i = 0;
if (IsDrivePath2(path))
@@ -274,7 +272,7 @@ static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s)
return kSuperPathPrefixSize + pos + 1;
}
-unsigned GetRootPrefixSize(CFSTR s)
+unsigned GetRootPrefixSize(CFSTR s) throw()
{
if (IS_DEVICE_PATH(s))
return kDevicePathPrefixSize;
@@ -285,7 +283,7 @@ unsigned GetRootPrefixSize(CFSTR s)
#endif // USE_UNICODE_FSTRING
-static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s)
+static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s) throw()
{
// Network path: we look "server\path\" as root prefix
int pos = FindSepar(s);
@@ -297,7 +295,7 @@ static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s)
return pos + pos2 + 2;
}
-static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s)
+static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s) throw()
{
if (IsDrivePath(s))
return kDrivePrefixSize;
@@ -309,7 +307,7 @@ static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s)
return (size == 0) ? 0 : 2 + size;
}
-static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s)
+static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s) throw()
{
if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
{
@@ -628,7 +626,7 @@ static bool GetSuperPathBase(CFSTR s, UString &res)
unsigned fixedSizeStart = 0;
unsigned fixedSize = 0;
- const wchar_t *superMarker = NULL;
+ const char *superMarker = NULL;
if (IsSuperPath(curDir))
{
fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
diff --git a/CPP/Windows/FileName.h b/CPP/Windows/FileName.h
index 6f9b6e03..2c9c56db 100644
--- a/CPP/Windows/FileName.h
+++ b/CPP/Windows/FileName.h
@@ -23,7 +23,7 @@ bool IsAltPathPrefix(CFSTR s) throw(); /* name: */
#if defined(_WIN32) && !defined(UNDER_CE)
-extern const wchar_t *kSuperPathPrefix; /* \\?\ */
+extern const char * const kSuperPathPrefix; /* \\?\ */
const unsigned kDevicePathPrefixSize = 4;
const unsigned kSuperPathPrefixSize = 4;
const unsigned kSuperUncPathPrefixSize = kSuperPathPrefixSize + 4;
@@ -42,7 +42,7 @@ 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 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:"
@@ -71,7 +71,7 @@ unsigned GetRootPrefixSize(CFSTR s) throw();
#endif
-int FindAltStreamColon(CFSTR path);
+int FindAltStreamColon(CFSTR path) throw();
#endif // _WIN32
diff --git a/CPP/Windows/Net.cpp b/CPP/Windows/Net.cpp
index 47079f37..14d06d6e 100644
--- a/CPP/Windows/Net.cpp
+++ b/CPP/Windows/Net.cpp
@@ -364,8 +364,8 @@ DWORD AddConnection2(const CResourceW &resource, LPCWSTR password, LPCWSTR userN
}
CResource resourceA;
ConvertResourceWToResource(resource, resourceA);
- CSysString passwordA = GetSystemString(password);
- CSysString userNameA = GetSystemString(userName);
+ const CSysString passwordA (GetSystemString(password));
+ const CSysString userNameA (GetSystemString(userName));
return AddConnection2(resourceA,
password ? (LPCTSTR)passwordA: 0,
userName ? (LPCTSTR)userNameA: 0,
diff --git a/CPP/Windows/ProcessUtils.cpp b/CPP/Windows/ProcessUtils.cpp
index 9b833e54..f7878d51 100644
--- a/CPP/Windows/ProcessUtils.cpp
+++ b/CPP/Windows/ProcessUtils.cpp
@@ -15,9 +15,9 @@ namespace NWindows {
#ifndef UNDER_CE
static UString GetQuotedString(const UString &s)
{
- UString s2 = L'\"';
+ UString s2 ('\"');
s2 += s;
- s2 += L'\"';
+ s2 += '\"';
return s2;
}
#endif
diff --git a/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp
index e95cbd2b..c4ad3acb 100644
--- a/CPP/Windows/PropVariant.cpp
+++ b/CPP/Windows/PropVariant.cpp
@@ -91,7 +91,7 @@ CPropVariant& CPropVariant::operator=(BSTR bstrSrc)
return *this;
}
-static const char *kMemException = "out of memory";
+static const char * const kMemException = "out of memory";
CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
{
diff --git a/CPP/Windows/PropVariant.h b/CPP/Windows/PropVariant.h
index 3610d6a8..58e8a0c6 100644
--- a/CPP/Windows/PropVariant.h
+++ b/CPP/Windows/PropVariant.h
@@ -80,6 +80,8 @@ public:
CPropVariant& operator=(const UString &s);
CPropVariant& operator=(const UString2 &s);
CPropVariant& operator=(const char *s);
+ CPropVariant& operator=(const AString &s)
+ { return (*this)=(const char *)s; }
CPropVariant& operator=(bool bSrc) throw();
CPropVariant& operator=(Byte value) throw();
diff --git a/CPP/Windows/PropVariantConv.cpp b/CPP/Windows/PropVariantConv.cpp
index fe86f936..65aa9f7e 100644
--- a/CPP/Windows/PropVariantConv.cpp
+++ b/CPP/Windows/PropVariantConv.cpp
@@ -9,21 +9,24 @@
#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()
+bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
{
+ *s = 0;
+ FILETIME ft;
+ if (!FileTimeToLocalFileTime(&utc, &ft))
+ return false;
+
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;
- }
+
{
+ 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);
@@ -32,40 +35,66 @@ bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool
}
UINT_TO_STR_2('-', st.wMonth);
UINT_TO_STR_2('-', st.wDay);
- if (includeTime)
+
+ if (level > kTimestampPrintLevel_DAY)
{
UINT_TO_STR_2(' ', st.wHour);
UINT_TO_STR_2(':', st.wMinute);
- if (includeSeconds)
+
+ if (level >= kTimestampPrintLevel_SEC)
{
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;
- */
+
+ if (level > kTimestampPrintLevel_SEC)
+ {
+ *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++ = ' ';
+ */
+
+ {
+ unsigned numDigits = 7;
+ UInt32 val = (UInt32)((((UInt64)ft.dwHighDateTime << 32) + ft.dwLowDateTime) % 10000000);
+ for (unsigned i = numDigits; i != 0;)
+ {
+ i--;
+ s[i] = (char)('0' + val % 10); val /= 10;
+ }
+ if (numDigits > (unsigned)level)
+ numDigits = (unsigned)level;
+ s += numDigits;
+ }
+ }
}
}
+
*s = 0;
return true;
}
-void ConvertFileTimeToString(const FILETIME &ft, wchar_t *dest, bool includeTime, bool includeSeconds) throw()
+
+bool ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *dest, int level) throw()
{
char s[32];
- ConvertFileTimeToString(ft, s, includeTime, includeSeconds);
+ bool res = ConvertUtcFileTimeToString(ft, s, level);
for (unsigned i = 0;; i++)
{
unsigned char c = s[i];
dest[i] = c;
if (c == 0)
- return;
+ break;
}
+ return res;
}
+
void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw()
{
*dest = 0;
@@ -77,7 +106,7 @@ void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw(
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_FILETIME: ConvertUtcFileTimeToString(prop.filetime, dest); 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;
@@ -98,7 +127,7 @@ void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) thr
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_FILETIME: ConvertUtcFileTimeToString(prop.filetime, dest); 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;
diff --git a/CPP/Windows/PropVariantConv.h b/CPP/Windows/PropVariantConv.h
index 5d26357f..390e0b89 100644
--- a/CPP/Windows/PropVariantConv.h
+++ b/CPP/Windows/PropVariantConv.h
@@ -6,8 +6,15 @@
#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();
+
+#define kTimestampPrintLevel_DAY -3
+// #define kTimestampPrintLevel_HOUR -2
+#define kTimestampPrintLevel_MIN -1
+#define kTimestampPrintLevel_SEC 0
+#define kTimestampPrintLevel_NTFS 7
+
+bool ConvertUtcFileTimeToString(const FILETIME &ft, char *s, int level = kTimestampPrintLevel_SEC) throw();
+bool ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *s, int level = kTimestampPrintLevel_SEC) throw();
// provide at least 32 bytes for buffer including zero-end
// don't send VT_BSTR to these functions
diff --git a/CPP/Windows/PropVariantUtils.cpp b/CPP/Windows/PropVariantUtils.cpp
index 7149616b..fab556a5 100644
--- a/CPP/Windows/PropVariantUtils.cpp
+++ b/CPP/Windows/PropVariantUtils.cpp
@@ -8,27 +8,32 @@
using namespace NWindows;
-static AString GetHex(UInt32 v)
+static void AddHex(AString &s, UInt32 v)
{
char sz[16];
sz[0] = '0';
sz[1] = 'x';
ConvertUInt32ToHex(v, sz + 2);
- return sz;
+ s += sz;
}
+
AString TypePairToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 value)
{
- AString s;
+ char sz[16];
+ const char *p = NULL;
for (unsigned i = 0; i < num; i++)
{
- const CUInt32PCharPair &p = pairs[i];
- if (p.Value == value)
- s = p.Name;
+ const CUInt32PCharPair &pair = pairs[i];
+ if (pair.Value == value)
+ p = pair.Name;
}
- if (s.IsEmpty())
- s = GetHex(value);
- return s;
+ if (!p)
+ {
+ ConvertUInt32ToString(value, sz);
+ p = sz;
+ }
+ return (AString)p;
}
void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NCOM::CPropVariant &prop)
@@ -39,14 +44,30 @@ void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NCOM:
AString TypeToString(const char * const table[], unsigned num, UInt32 value)
{
+ char sz[16];
+ const char *p = NULL;
if (value < num)
- return table[value];
- return GetHex(value);
+ p = table[value];
+ if (!p)
+ {
+ ConvertUInt32ToString(value, sz);
+ p = sz;
+ }
+ return (AString)p;
}
-void TypeToProp(const char * const table[], unsigned num, UInt32 value, NCOM::CPropVariant &prop)
+void TypeToProp(const char * const table[], unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop)
{
- prop = TypeToString(table, num, value);
+ char sz[16];
+ const char *p = NULL;
+ if (value < num)
+ p = table[value];
+ if (!p)
+ {
+ ConvertUInt32ToString(value, sz);
+ p = sz;
+ }
+ prop = p;
}
@@ -59,20 +80,17 @@ AString FlagsToString(const char * const *names, unsigned num, UInt32 flags)
if ((flags & flag) != 0)
{
const char *name = names[i];
- if (name != 0 && name[0] != 0)
+ if (name && name[0] != 0)
{
- if (!s.IsEmpty())
- s += ' ';
- s += name;
+ s.Add_OptSpaced(name);
flags &= ~flag;
}
}
}
if (flags != 0)
{
- if (!s.IsEmpty())
- s += ' ';
- s += GetHex(flags);
+ s.Add_Space_if_NotEmpty();
+ AddHex(s, flags);
}
return s;
}
@@ -87,23 +105,23 @@ AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags)
if ((flags & flag) != 0)
{
if (p.Name[0] != 0)
- {
- if (!s.IsEmpty())
- s += ' ';
- s += p.Name;
- }
+ s.Add_OptSpaced(p.Name);
}
flags &= ~flag;
}
if (flags != 0)
{
- if (!s.IsEmpty())
- s += ' ';
- s += GetHex(flags);
+ s.Add_Space_if_NotEmpty();
+ AddHex(s, flags);
}
return s;
}
+void FlagsToProp(const char * const *names, unsigned num, UInt32 flags, NCOM::CPropVariant &prop)
+{
+ prop = FlagsToString(names, num, flags);
+}
+
void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NCOM::CPropVariant &prop)
{
prop = FlagsToString(pairs, num, flags);
@@ -120,24 +138,18 @@ AString Flags64ToString(const CUInt32PCharPair *pairs, unsigned num, UInt64 flag
if ((flags & flag) != 0)
{
if (p.Name[0] != 0)
- {
- if (!s.IsEmpty())
- s += ' ';
- s += p.Name;
- }
+ s.Add_OptSpaced(p.Name);
}
flags &= ~flag;
}
if (flags != 0)
{
- if (!s.IsEmpty())
- s += ' ';
{
char sz[32];
sz[0] = '0';
sz[1] = 'x';
ConvertUInt64ToHex(flags, sz + 2);
- s += sz;
+ s.Add_OptSpaced(sz);
}
}
return s;
diff --git a/CPP/Windows/PropVariantUtils.h b/CPP/Windows/PropVariantUtils.h
index 64dfd5a1..3dd8295f 100644
--- a/CPP/Windows/PropVariantUtils.h
+++ b/CPP/Windows/PropVariantUtils.h
@@ -18,6 +18,7 @@ void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NWind
AString FlagsToString(const char * const *names, unsigned num, UInt32 flags);
AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags);
+void FlagsToProp(const char * const *names, unsigned num, UInt32 flags, NWindows::NCOM::CPropVariant &prop);
void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NWindows::NCOM::CPropVariant &prop);
AString TypeToString(const char * const table[], unsigned num, UInt32 value);
diff --git a/CPP/Windows/Shell.cpp b/CPP/Windows/Shell.cpp
index 8e82c14a..382d774f 100644
--- a/CPP/Windows/Shell.cpp
+++ b/CPP/Windows/Shell.cpp
@@ -153,8 +153,8 @@ bool BrowseForFolder(HWND /* owner */, LPCTSTR /* title */,
MessageBoxW(0, L"yes", L"", 0);
*/
/*
- UString s = L"all files";
- s += L" (*.*)";
+ UString s = "all files";
+ s += " (*.*)";
return MyGetOpenFileName(owner, title, initialFolder, s, resultPath, true);
*/
return false;
diff --git a/CPP/Windows/System.cpp b/CPP/Windows/System.cpp
index 59cb7c0b..cc33169a 100644
--- a/CPP/Windows/System.cpp
+++ b/CPP/Windows/System.cpp
@@ -11,12 +11,42 @@
namespace NWindows {
namespace NSystem {
+UInt32 CountAffinity(DWORD_PTR mask)
+{
+ UInt32 num = 0;
+ for (unsigned i = 0; i < sizeof(mask) * 8; i++)
+ num += (UInt32)((mask >> i) & 1);
+ return num;
+}
+
#ifdef _WIN32
+BOOL CProcessAffinity::Get()
+{
+ #ifndef UNDER_CE
+ return GetProcessAffinityMask(GetCurrentProcess(), &processAffinityMask, &systemAffinityMask);
+ #else
+ return FALSE;
+ #endif
+}
+
+
UInt32 GetNumberOfProcessors()
{
+ // We need to know how many threads we can use.
+ // By default the process is assigned to one group.
+ // So we get the number of logical processors (threads)
+ // assigned to current process in the current group.
+ // Group size can be smaller than total number logical processors, for exammple, 2x36
+
+ CProcessAffinity pa;
+
+ if (pa.Get() && pa.processAffinityMask != 0)
+ return pa.GetNumProcessThreads();
+
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo);
+ // the number of logical processors in the current group
return (UInt32)systemInfo.dwNumberOfProcessors;
}
diff --git a/CPP/Windows/System.h b/CPP/Windows/System.h
index 910bc7fd..519e0444 100644
--- a/CPP/Windows/System.h
+++ b/CPP/Windows/System.h
@@ -8,6 +8,29 @@
namespace NWindows {
namespace NSystem {
+UInt32 CountAffinity(DWORD_PTR mask);
+
+struct CProcessAffinity
+{
+ // UInt32 numProcessThreads;
+ // UInt32 numSysThreads;
+ DWORD_PTR processAffinityMask;
+ DWORD_PTR systemAffinityMask;
+
+ void InitST()
+ {
+ // numProcessThreads = 1;
+ // numSysThreads = 1;
+ processAffinityMask = 1;
+ systemAffinityMask = 1;
+ }
+
+ UInt32 GetNumProcessThreads() const { return CountAffinity(processAffinityMask); }
+ UInt32 GetNumSystemThreads() const { return CountAffinity(systemAffinityMask); }
+
+ BOOL Get();
+};
+
UInt32 GetNumberOfProcessors();
bool GetRamSize(UInt64 &size); // returns false, if unknown ram size
diff --git a/CPP/Windows/TimeUtils.cpp b/CPP/Windows/TimeUtils.cpp
index 7ef44d9c..d288f121 100644
--- a/CPP/Windows/TimeUtils.cpp
+++ b/CPP/Windows/TimeUtils.cpp
@@ -115,16 +115,26 @@ bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw()
return true;
}
+UInt64 UnixTimeToFileTime64(UInt32 unixTime) throw()
+{
+ return (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond;
+}
+
void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft) throw()
{
- UInt64 v = (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond;
+ UInt64 v = UnixTimeToFileTime64(unixTime);
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
}
+UInt64 UnixTime64ToFileTime64(Int64 unixTime) throw()
+{
+ return (UInt64)(kUnixTimeOffset + unixTime) * kNumTimeQuantumsInSecond;
+}
+
bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft) throw()
{
- if (unixTime > kNumSecondsInFileTime - kUnixTimeOffset)
+ if (unixTime > (Int64)(kNumSecondsInFileTime - kUnixTimeOffset))
{
ft.dwLowDateTime = ft.dwHighDateTime = (UInt32)(Int32)-1;
return false;
@@ -144,7 +154,7 @@ bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft) throw()
Int64 FileTimeToUnixTime64(const FILETIME &ft) throw()
{
UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
- return (Int64)(winTime / kNumTimeQuantumsInSecond) - kUnixTimeOffset;
+ return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset;
}
bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw()
diff --git a/CPP/Windows/TimeUtils.h b/CPP/Windows/TimeUtils.h
index d3033ede..d1d8c150 100644
--- a/CPP/Windows/TimeUtils.h
+++ b/CPP/Windows/TimeUtils.h
@@ -11,10 +11,18 @@ namespace NTime {
bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime) throw();
bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime) throw();
+
+// UInt32 Unix Time : for dates 1970-2106
+UInt64 UnixTimeToFileTime64(UInt32 unixTime) throw();
void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime) throw();
+
+// Int64 Unix Time : negative values for dates before 1970
+UInt64 UnixTime64ToFileTime64(Int64 unixTime) 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();
diff --git a/DOC/7zip.inf b/DOC/7zip.inf
index b8aa402e..0789dbd5 100644
--- a/DOC/7zip.inf
+++ b/DOC/7zip.inf
@@ -10,8 +10,8 @@ AppName = "7-Zip"
InstallDir = %CE1%\%AppName%
[Strings]
-AppVer = "16.04"
-AppDate = "2016-10-04"
+AppVer = "17.00"
+AppDate = "2017-04-29"
[CEDevice]
; ProcessorType = 2577 ; ARM
diff --git a/DOC/7zip.nsi b/DOC/7zip.nsi
index abaa4c2e..da6e3d4e 100644
--- a/DOC/7zip.nsi
+++ b/DOC/7zip.nsi
@@ -1,9 +1,9 @@
;--------------------------------
;Defines
-!define VERSION_MAJOR 16
-!define VERSION_MINOR 04
-!define VERSION_POSTFIX_FULL ""
+!define VERSION_MAJOR 17
+!define VERSION_MINOR 00
+!define VERSION_POSTFIX_FULL " beta"
!ifdef WIN64
!ifdef IA64
!define VERSION_SYS_POSTFIX_FULL " for Windows IA-64"
diff --git a/DOC/7zip.wxs b/DOC/7zip.wxs
index d26e2a85..3b52739f 100644
--- a/DOC/7zip.wxs
+++ b/DOC/7zip.wxs
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
-<?define VerMajor = "16" ?>
-<?define VerMinor = "04" ?>
+<?define VerMajor = "17" ?>
+<?define VerMinor = "00" ?>
<?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "$(var.VerMajor)$(var.VerMinor)" ?>
diff --git a/DOC/License.txt b/DOC/License.txt
index 2c6b3074..c4f905d3 100644
--- a/DOC/License.txt
+++ b/DOC/License.txt
@@ -3,7 +3,7 @@
License for use and distribution
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 7-Zip Copyright (C) 1999-2016 Igor Pavlov.
+ 7-Zip Copyright (C) 1999-2017 Igor Pavlov.
Licenses for files are:
diff --git a/DOC/Methods.txt b/DOC/Methods.txt
index f6cda7d5..54ff61cd 100644
--- a/DOC/Methods.txt
+++ b/DOC/Methods.txt
@@ -1,8 +1,8 @@
7-Zip method IDs for 7z and xz archives
---------------------------------------
-Version: 16.03
-Date: 2016-09-27
+Version: 17.00
+Date: 2017-01-01
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).
@@ -122,9 +122,15 @@ List of defined IDs
F7 - External codecs (that are not included to 7-Zip)
0x xx - reserved
+
10 xx - reserved (LZHAM)
- 11 xx - reserved (Zstd)
+ 01 - LZHAM
+ 11 xx - reserved (Tino Reichardt)
+ 01 - ZSTD
+ 04 - LZ4
+ 05 - LZ5
+
06.. - Crypto
diff --git a/DOC/readme.txt b/DOC/readme.txt
index 3d7b8d1d..1da3094e 100644
--- a/DOC/readme.txt
+++ b/DOC/readme.txt
@@ -1,9 +1,9 @@
-7-Zip 16.04 Sources
--------------------
+7-Zip 17.00 beta Sources
+------------------------
7-Zip is a file archiver for Windows.
-7-Zip Copyright (C) 1999-2016 Igor Pavlov.
+7-Zip Copyright (C) 1999-2017 Igor Pavlov.
License Info
diff --git a/DOC/src-history.txt b/DOC/src-history.txt
index 6b48c80f..6f637d01 100644
--- a/DOC/src-history.txt
+++ b/DOC/src-history.txt
@@ -1,6 +1,15 @@
HISTORY of the 7-Zip source code
--------------------------------
+17.00 beta 2017-04-29
+-------------------------
+- NewHandler.h / NewHandler.cpp:
+ now it redefines operator new() only for old MSVC compilers (_MSC_VER < 1900).
+- C/7zTypes.h : the names of variables in interface structures were changed (vt).
+- Some bugs were fixed. 7-Zip could crash in some cases.
+- Some internal changes in code.
+
+
16.02 2016-05-21
-------------------------
- The BUG in 16.00 - 16.01 was fixed: