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
path: root/CPP
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 /CPP
parent603abd5528c97346e9448c0ff47949f818fe558c (diff)
17.0017.00
Diffstat (limited to 'CPP')
-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
368 files changed, 13720 insertions, 7244 deletions
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();