summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/unix
diff options
context:
space:
mode:
authorKarsten Heimrich <karsten.heimrich@theqtcompany.com>2015-06-09 16:04:24 +0200
committerKarsten Heimrich <karsten.heimrich@theqtcompany.com>2015-06-10 08:15:38 +0000
commit4677d362982a38c6e2aabb667e33aaa7f921f018 (patch)
treefe3b676288f05a87cdbb53a170e815427e3d9380 /src/libs/7zip/unix
parent22ec6aa53e44069c03c7baf94881949c7a4facff (diff)
Update source tree with version 9.38.beta of LZMA SDK.
- Remove unused files. - Split in .pri files. - Add HEADERS section. - Adjust lib7z_facade. Change-Id: I31e7bafbfe1a9346364bd58c391601955f98ad3a Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
Diffstat (limited to 'src/libs/7zip/unix')
-rw-r--r--src/libs/7zip/unix/7zC.txt194
-rw-r--r--src/libs/7zip/unix/7zFormat.txt471
-rw-r--r--src/libs/7zip/unix/C/7zBuf.h39
-rw-r--r--src/libs/7zip/unix/C/7zBuf2.c45
-rw-r--r--src/libs/7zip/unix/C/7zCrc.c73
-rw-r--r--src/libs/7zip/unix/C/7zCrc.h4
-rw-r--r--src/libs/7zip/unix/C/7zCrcOpt.c40
-rw-r--r--src/libs/7zip/unix/C/7zStream.c6
-rw-r--r--src/libs/7zip/unix/C/7zTypes.h (renamed from src/libs/7zip/unix/C/Types.h)14
-rw-r--r--src/libs/7zip/unix/C/7zVersion.h14
-rw-r--r--src/libs/7zip/unix/C/Alloc.c57
-rw-r--r--src/libs/7zip/unix/C/Bra.c12
-rw-r--r--src/libs/7zip/unix/C/Bra.h20
-rw-r--r--src/libs/7zip/unix/C/Bra86.c99
-rw-r--r--src/libs/7zip/unix/C/BraIA64.c14
-rw-r--r--src/libs/7zip/unix/C/C.pri47
-rw-r--r--src/libs/7zip/unix/C/Compiler.h28
-rw-r--r--src/libs/7zip/unix/C/CpuArch.c176
-rw-r--r--src/libs/7zip/unix/C/CpuArch.h20
-rw-r--r--src/libs/7zip/unix/C/Delta.c2
-rw-r--r--src/libs/7zip/unix/C/Delta.h12
-rw-r--r--src/libs/7zip/unix/C/LzFind.c6
-rw-r--r--src/libs/7zip/unix/C/LzFind.h12
-rw-r--r--src/libs/7zip/unix/C/LzFindMt.c33
-rw-r--r--src/libs/7zip/unix/C/LzFindMt.h14
-rw-r--r--src/libs/7zip/unix/C/Lzma2Dec.c42
-rw-r--r--src/libs/7zip/unix/C/Lzma2Dec.h10
-rw-r--r--src/libs/7zip/unix/C/Lzma2Enc.c40
-rw-r--r--src/libs/7zip/unix/C/Lzma2Enc.h10
-rw-r--r--src/libs/7zip/unix/C/Lzma86Dec.c61
-rw-r--r--src/libs/7zip/unix/C/Lzma86Enc.c113
-rw-r--r--src/libs/7zip/unix/C/LzmaDec.c78
-rw-r--r--src/libs/7zip/unix/C/LzmaDec.h16
-rw-r--r--src/libs/7zip/unix/C/LzmaEnc.c80
-rw-r--r--src/libs/7zip/unix/C/LzmaEnc.h14
-rw-r--r--src/libs/7zip/unix/C/MtCoder.c6
-rw-r--r--src/libs/7zip/unix/C/MtCoder.h4
-rw-r--r--src/libs/7zip/unix/C/Precomp.h10
-rw-r--r--src/libs/7zip/unix/C/RotateDefs.h8
-rw-r--r--src/libs/7zip/unix/C/Sha256.c4
-rw-r--r--src/libs/7zip/unix/C/Sha256.h4
-rw-r--r--src/libs/7zip/unix/C/Threads.c44
-rw-r--r--src/libs/7zip/unix/C/Threads.h2
-rw-r--r--src/libs/7zip/unix/C/Xz.c2
-rw-r--r--src/libs/7zip/unix/C/Xz.h47
-rw-r--r--src/libs/7zip/unix/C/XzCrc64.c89
-rw-r--r--src/libs/7zip/unix/C/XzCrc64.h4
-rw-r--r--src/libs/7zip/unix/C/XzCrc64Opt.c69
-rw-r--r--src/libs/7zip/unix/C/XzDec.c108
-rw-r--r--src/libs/7zip/unix/C/XzEnc.c309
-rw-r--r--src/libs/7zip/unix/C/XzEnc.h32
-rw-r--r--src/libs/7zip/unix/C/XzIn.c55
-rw-r--r--src/libs/7zip/unix/CPP/7zip/7zip.pri6
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7z.pri29
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zCompressionMode.cpp3
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zCompressionMode.h9
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.cpp153
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.h13
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zEncode.cpp136
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zEncode.h2
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zExtract.cpp58
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderInStream.cpp4
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderInStream.h2
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.cpp2
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.h6
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandler.cpp717
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandler.h84
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandlerOut.cpp708
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHeader.cpp5
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHeader.h14
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zIn.cpp1459
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zIn.h359
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zItem.h214
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.cpp481
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.h211
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zProperties.cpp56
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zRegister.cpp23
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zSpecStream.cpp10
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zUpdate.cpp712
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/7z/7zUpdate.h44
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Archive.pri5
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/ArchiveExports.cpp135
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2.cpp74
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2.h19
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2MT.cpp60
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2MT.h15
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/Common.pri18
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/CrossThreadProgress.cpp15
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/CrossThreadProgress.h37
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/DummyOutStream.cpp19
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/DummyOutStream.h7
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/HandlerOut.cpp618
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/HandlerOut.h80
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/InStreamWithCRC.cpp32
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/ItemNameUtils.cpp41
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/ItemNameUtils.h7
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/MultiStream.cpp57
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/MultiStream.h13
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/OutStreamWithCRC.h1
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/ParseProperties.cpp177
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/Common/ParseProperties.h16
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/DllExports2.cpp76
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/IArchive.h325
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/LzmaHandler.cpp348
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/SplitHandler.cpp267
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Archive/XzHandler.cpp752
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/CWrappers.cpp44
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/CWrappers.h37
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/Common.pri39
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp218
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.h41
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp28
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h10
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/FileStreams.cpp318
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/FileStreams.h80
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.cpp24
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.h22
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/InBuffer.cpp122
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/InBuffer.h101
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp15
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h4
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp255
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.h142
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/MethodId.cpp27
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/MethodId.h2
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/MethodProps.cpp484
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/MethodProps.h178
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.cpp35
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.h25
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.cpp57
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.h37
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp2
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/PropId.cpp99
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h67
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h48
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.cpp153
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.h43
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.cpp75
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.h31
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.cpp8
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.h12
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.cpp56
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.h30
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/VirtThread.cpp14
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Common/VirtThread.h11
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/Bcj2Coder.cpp176
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/Bcj2Coder.h55
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/BranchMisc.cpp42
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/CodecExports.cpp160
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/Compress.pri29
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/CopyCoder.cpp21
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/CopyCoder.h1
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/DeltaFilter.cpp17
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Decoder.cpp4
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Encoder.cpp2
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Encoder.h2
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/LzmaDecoder.cpp18
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/LzmaDecoder.h8
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/LzmaEncoder.cpp34
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/LzmaEncoder.h4
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/RangeCoder.h30
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/RangeCoderBit.h16
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Guid.txt38
-rw-r--r--src/libs/7zip/unix/CPP/7zip/ICoder.h29
-rw-r--r--src/libs/7zip/unix/CPP/7zip/IPassword.h3
-rw-r--r--src/libs/7zip/unix/CPP/7zip/IProgress.h2
-rw-r--r--src/libs/7zip/unix/CPP/7zip/IStream.h89
-rw-r--r--src/libs/7zip/unix/CPP/7zip/MyVersion.h11
-rw-r--r--src/libs/7zip/unix/CPP/7zip/PropID.h66
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveCommandLine.cpp1216
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveCommandLine.h79
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp999
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveExtractCallback.h208
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveName.cpp54
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveName.h10
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp46
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveOpenCallback.h38
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/Bench.cpp1028
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/Bench.h42
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/Common.pri43
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/DefaultName.cpp6
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/DefaultName.h6
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/DirItem.h91
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/EnumDirItems.cpp678
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/EnumDirItems.h18
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ExitCode.h27
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.cpp370
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.h54
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractMode.h42
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.cpp114
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.h12
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/HashCalc.cpp361
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/HashCalc.h107
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/IFileExtractCallback.h32
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/LoadCodecs.cpp796
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/LoadCodecs.h190
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/OpenArchive.cpp3170
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/OpenArchive.h351
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/PropIDUtils.cpp549
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/PropIDUtils.h13
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/Property.h6
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/SetProperties.cpp31
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/SortUtils.cpp17
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/SortUtils.h8
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/TempFiles.cpp9
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/TempFiles.h8
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/Update.cpp1124
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/Update.h145
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateAction.cpp10
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateAction.h29
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateCallback.cpp455
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateCallback.h64
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/UpdatePair.cpp214
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/UpdatePair.h4
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateProduce.cpp27
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateProduce.h26
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/WorkDir.cpp59
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/WorkDir.h10
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Common/ZipRegistry.h105
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/BenchCon.cpp297
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/BenchCon.h16
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/Console.pri2
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/ConsoleClose.cpp49
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/ConsoleClose.h26
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp228
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/ExtractCallbackConsole.h73
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/List.cpp654
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/List.h20
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/Main.cpp628
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/MainAr.cpp127
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/OpenCallbackConsole.cpp58
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/OpenCallbackConsole.h24
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/PercentPrinter.cpp40
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/PercentPrinter.h11
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp261
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/UpdateCallbackConsole.h62
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/UserInputUtils.cpp96
-rw-r--r--src/libs/7zip/unix/CPP/7zip/UI/Console/UserInputUtils.h24
-rw-r--r--src/libs/7zip/unix/CPP/Common/AutoPtr.h35
-rw-r--r--src/libs/7zip/unix/CPP/Common/Buffer.h77
-rw-r--r--src/libs/7zip/unix/CPP/Common/CRC.cpp7
-rw-r--r--src/libs/7zip/unix/CPP/Common/C_FileIO.cpp88
-rw-r--r--src/libs/7zip/unix/CPP/Common/C_FileIO.h47
-rw-r--r--src/libs/7zip/unix/CPP/Common/ComTry.h2
-rw-r--r--src/libs/7zip/unix/CPP/Common/CommandLineParser.cpp265
-rw-r--r--src/libs/7zip/unix/CPP/Common/CommandLineParser.h51
-rw-r--r--src/libs/7zip/unix/CPP/Common/Common.h13
-rw-r--r--src/libs/7zip/unix/CPP/Common/Common.pri34
-rw-r--r--src/libs/7zip/unix/CPP/Common/DynamicBuffer.h50
-rw-r--r--src/libs/7zip/unix/CPP/Common/IntToString.cpp149
-rw-r--r--src/libs/7zip/unix/CPP/Common/IntToString.h23
-rw-r--r--src/libs/7zip/unix/CPP/Common/ListFileUtils.cpp122
-rw-r--r--src/libs/7zip/unix/CPP/Common/ListFileUtils.h11
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyBuffer.h237
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyCom.h63
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyGuidDef.h2
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyInitGuid.h23
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyString.cpp1239
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyString.h922
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyTypes.h32
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyUnknown.h2
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyVector.cpp87
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyVector.h577
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyWindows.cpp23
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyWindows.h8
-rw-r--r--src/libs/7zip/unix/CPP/Common/NewHandler.cpp32
-rw-r--r--src/libs/7zip/unix/CPP/Common/NewHandler.h56
-rw-r--r--src/libs/7zip/unix/CPP/Common/StdInStream.cpp100
-rw-r--r--src/libs/7zip/unix/CPP/Common/StdInStream.h32
-rw-r--r--src/libs/7zip/unix/CPP/Common/StdOutStream.cpp83
-rw-r--r--src/libs/7zip/unix/CPP/Common/StdOutStream.h61
-rw-r--r--src/libs/7zip/unix/CPP/Common/StringConvert.cpp68
-rw-r--r--src/libs/7zip/unix/CPP/Common/StringConvert.h10
-rw-r--r--src/libs/7zip/unix/CPP/Common/StringToInt.cpp144
-rw-r--r--src/libs/7zip/unix/CPP/Common/StringToInt.h23
-rw-r--r--src/libs/7zip/unix/CPP/Common/Types.h11
-rw-r--r--src/libs/7zip/unix/CPP/Common/UTFConvert.cpp61
-rw-r--r--src/libs/7zip/unix/CPP/Common/UTFConvert.h5
-rw-r--r--src/libs/7zip/unix/CPP/Common/Wildcard.cpp391
-rw-r--r--src/libs/7zip/unix/CPP/Common/Wildcard.h101
-rw-r--r--src/libs/7zip/unix/CPP/Windows/DLL.cpp44
-rw-r--r--src/libs/7zip/unix/CPP/Windows/DLL.h24
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Defs.h1
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Error.cpp58
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Error.h33
-rw-r--r--src/libs/7zip/unix/CPP/Windows/FileDir.cpp898
-rw-r--r--src/libs/7zip/unix/CPP/Windows/FileDir.h134
-rw-r--r--src/libs/7zip/unix/CPP/Windows/FileFind.cpp467
-rw-r--r--src/libs/7zip/unix/CPP/Windows/FileFind.h115
-rw-r--r--src/libs/7zip/unix/CPP/Windows/FileIO.cpp41
-rw-r--r--src/libs/7zip/unix/CPP/Windows/FileIO.h7
-rw-r--r--src/libs/7zip/unix/CPP/Windows/FileName.cpp37
-rw-r--r--src/libs/7zip/unix/CPP/Windows/FileName.h8
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Handle.h37
-rw-r--r--src/libs/7zip/unix/CPP/Windows/NtCheck.h44
-rw-r--r--src/libs/7zip/unix/CPP/Windows/PropVariant.cpp105
-rw-r--r--src/libs/7zip/unix/CPP/Windows/PropVariant.h97
-rw-r--r--src/libs/7zip/unix/CPP/Windows/PropVariantConv.cpp99
-rw-r--r--src/libs/7zip/unix/CPP/Windows/PropVariantConv.h30
-rw-r--r--src/libs/7zip/unix/CPP/Windows/PropVariantConversions.cpp139
-rw-r--r--src/libs/7zip/unix/CPP/Windows/PropVariantConversions.h14
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Registry.cpp313
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Registry.h113
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Synchronization.cpp2
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Synchronization.h14
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Synchronization2.h12
-rw-r--r--src/libs/7zip/unix/CPP/Windows/System.cpp2
-rw-r--r--src/libs/7zip/unix/CPP/Windows/System.h2
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Thread.h2
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Time.cpp68
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Time.h21
-rw-r--r--src/libs/7zip/unix/CPP/Windows/TimeUtils.cpp203
-rw-r--r--src/libs/7zip/unix/CPP/Windows/TimeUtils.h23
-rw-r--r--src/libs/7zip/unix/CPP/Windows/Windows.pri24
-rw-r--r--src/libs/7zip/unix/CPP/include_windows/basetyps.h10
-rw-r--r--src/libs/7zip/unix/CPP/include_windows/include_windows.pri3
-rw-r--r--src/libs/7zip/unix/CPP/include_windows/tchar.h2
-rw-r--r--src/libs/7zip/unix/CPP/include_windows/windows.h28
-rw-r--r--src/libs/7zip/unix/CPP/myWindows/StdAfx.h89
-rw-r--r--src/libs/7zip/unix/CPP/myWindows/config.h7
-rw-r--r--src/libs/7zip/unix/CPP/myWindows/myCommandLineParser.cpp51
-rw-r--r--src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp42
-rw-r--r--src/libs/7zip/unix/CPP/myWindows/myWindows.pri7
-rw-r--r--src/libs/7zip/unix/Methods.txt152
-rw-r--r--src/libs/7zip/unix/history.txt271
-rw-r--r--src/libs/7zip/unix/lzma.txt598
-rw-r--r--src/libs/7zip/unix/unix.pri144
327 files changed, 23411 insertions, 17686 deletions
diff --git a/src/libs/7zip/unix/7zC.txt b/src/libs/7zip/unix/7zC.txt
deleted file mode 100644
index 5d5d06d7b..000000000
--- a/src/libs/7zip/unix/7zC.txt
+++ /dev/null
@@ -1,194 +0,0 @@
-7z ANSI-C Decoder 4.62
-----------------------
-
-7z ANSI-C provides 7z/LZMA decoding.
-7z ANSI-C version is simplified version ported from C++ code.
-
-LZMA is default and general compression method of 7z format
-in 7-Zip compression program (www.7-zip.org). LZMA provides high
-compression ratio and very fast decompression.
-
-
-LICENSE
--------
-
-7z ANSI-C Decoder is part of the LZMA SDK.
-LZMA SDK is written and placed in the public domain by Igor Pavlov.
-
-Files
----------------------
-
-7zDecode.* - Low level 7z decoding
-7zExtract.* - High level 7z decoding
-7zHeader.* - .7z format constants
-7zIn.* - .7z archive opening
-7zItem.* - .7z structures
-7zMain.c - Test application
-
-
-How To Use
-----------
-
-You must download 7-Zip program from www.7-zip.org.
-
-You can create .7z archive with 7z.exe or 7za.exe:
-
- 7za.exe a archive.7z *.htm -r -mx -m0fb=255
-
-If you have big number of files in archive, and you need fast extracting,
-you can use partly-solid archives:
-
- 7za.exe a archive.7z *.htm -ms=512K -r -mx -m0fb=255 -m0d=512K
-
-In that example 7-Zip will use 512KB solid blocks. So it needs to decompress only
-512KB for extracting one file from such archive.
-
-
-Limitations of current version of 7z ANSI-C Decoder
----------------------------------------------------
-
- - It reads only "FileName", "Size", "LastWriteTime" and "CRC" information for each file in archive.
- - It supports only LZMA and Copy (no compression) methods with BCJ or BCJ2 filters.
- - It converts original UTF-16 Unicode file names to UTF-8 Unicode file names.
-
-These limitations will be fixed in future versions.
-
-
-Using 7z ANSI-C Decoder Test application:
------------------------------------------
-
-Usage: 7zDec <command> <archive_name>
-
-<Command>:
- e: Extract files from archive
- l: List contents of archive
- t: Test integrity of archive
-
-Example:
-
- 7zDec l archive.7z
-
-lists contents of archive.7z
-
- 7zDec e archive.7z
-
-extracts files from archive.7z to current folder.
-
-
-How to use .7z Decoder
-----------------------
-
-Memory allocation
-~~~~~~~~~~~~~~~~~
-
-7z Decoder uses two memory pools:
-1) Temporary pool
-2) Main pool
-Such scheme can allow you to avoid fragmentation of allocated blocks.
-
-
-Steps for using 7z decoder
---------------------------
-
-Use code at 7zMain.c as example.
-
-1) Declare variables:
- inStream /* implements ILookInStream interface */
- CSzArEx db; /* 7z archive database structure */
- ISzAlloc allocImp; /* memory functions for main pool */
- ISzAlloc allocTempImp; /* memory functions for temporary pool */
-
-2) call CrcGenerateTable(); function to initialize CRC structures.
-
-3) call SzArEx_Init(&db); function to initialize db structures.
-
-4) call SzArEx_Open(&db, inStream, &allocMain, &allocTemp) to open archive
-
-This function opens archive "inStream" and reads headers to "db".
-All items in "db" will be allocated with "allocMain" functions.
-SzArEx_Open function allocates and frees temporary structures by "allocTemp" functions.
-
-5) List items or Extract items
-
- Listing code:
- ~~~~~~~~~~~~~
- {
- UInt32 i;
- for (i = 0; i < db.db.NumFiles; i++)
- {
- CFileItem *f = db.db.Files + i;
- printf("%10d %s\n", (int)f->Size, f->Name);
- }
- }
-
- Extracting code:
- ~~~~~~~~~~~~~~~~
-
- SZ_RESULT SzAr_Extract(
- CArchiveDatabaseEx *db,
- ILookInStream *inStream,
- UInt32 fileIndex, /* index of file */
- UInt32 *blockIndex, /* index of solid block */
- Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
- size_t *outBufferSize, /* buffer size for output buffer */
- size_t *offset, /* offset of stream for required file in *outBuffer */
- size_t *outSizeProcessed, /* size of file in *outBuffer */
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp);
-
- If you need to decompress more than one file, you can send these values from previous call:
- blockIndex,
- outBuffer,
- outBufferSize,
- You can consider "outBuffer" as cache of solid block. If your archive is solid,
- it will increase decompression speed.
-
- After decompressing you must free "outBuffer":
- allocImp.Free(outBuffer);
-
-6) call SzArEx_Free(&db, allocImp.Free) to free allocated items in "db".
-
-
-
-
-Memory requirements for .7z decoding
-------------------------------------
-
-Memory usage for Archive opening:
- - Temporary pool:
- - Memory for uncompressed .7z headers
- - some other temporary blocks
- - Main pool:
- - Memory for database:
- Estimated size of one file structures in solid archive:
- - Size (4 or 8 Bytes)
- - CRC32 (4 bytes)
- - LastWriteTime (8 bytes)
- - Some file information (4 bytes)
- - File Name (variable length) + pointer + allocation structures
-
-Memory usage for archive Decompressing:
- - Temporary pool:
- - Memory for LZMA decompressing structures
- - Main pool:
- - Memory for decompressed solid block
- - Memory for temprorary buffers, if BCJ2 fileter is used. Usually these
- temprorary buffers can be about 15% of solid block size.
-
-
-7z Decoder doesn't allocate memory for compressed blocks.
-Instead of this, you must allocate buffer with desired
-size before calling 7z Decoder. Use 7zMain.c as example.
-
-
-Defines
--------
-
-_SZ_ALLOC_DEBUG - define it if you want to debug alloc/free operations to stderr.
-
-
----
-
-http://www.7-zip.org
-http://www.7-zip.org/sdk.html
-http://www.7-zip.org/support.html
diff --git a/src/libs/7zip/unix/7zFormat.txt b/src/libs/7zip/unix/7zFormat.txt
deleted file mode 100644
index e1cf7380d..000000000
--- a/src/libs/7zip/unix/7zFormat.txt
+++ /dev/null
@@ -1,471 +0,0 @@
-7z Format description (2.30 Beta 25)
------------------------------------
-
-This file contains description of 7z archive format.
-7z archive can contain files compressed with any method.
-See "Methods.txt" for description for defined compressing methods.
-
-
-Format structure Overview
--------------------------
-
-Some fields can be optional.
-
-Archive structure
-~~~~~~~~~~~~~~~~~
-SignatureHeader
-[PackedStreams]
-[PackedStreamsForHeaders]
-[
- Header
- or
- {
- Packed Header
- HeaderInfo
- }
-]
-
-
-
-Header structure
-~~~~~~~~~~~~~~~~
-{
- ArchiveProperties
- AdditionalStreams
- {
- PackInfo
- {
- PackPos
- NumPackStreams
- Sizes[NumPackStreams]
- CRCs[NumPackStreams]
- }
- CodersInfo
- {
- NumFolders
- Folders[NumFolders]
- {
- NumCoders
- CodersInfo[NumCoders]
- {
- ID
- NumInStreams;
- NumOutStreams;
- PropertiesSize
- Properties[PropertiesSize]
- }
- NumBindPairs
- BindPairsInfo[NumBindPairs]
- {
- InIndex;
- OutIndex;
- }
- PackedIndices
- }
- UnPackSize[Folders][Folders.NumOutstreams]
- CRCs[NumFolders]
- }
- SubStreamsInfo
- {
- NumUnPackStreamsInFolders[NumFolders];
- UnPackSizes[]
- CRCs[]
- }
- }
- MainStreamsInfo
- {
- (Same as in AdditionalStreams)
- }
- FilesInfo
- {
- NumFiles
- Properties[]
- {
- ID
- Size
- Data
- }
- }
-}
-
-HeaderInfo structure
-~~~~~~~~~~~~~~~~~~~~
-{
- (Same as in AdditionalStreams)
-}
-
-
-
-Notes about Notation and encoding
----------------------------------
-
-7z uses little endian encoding.
-
-7z archive format has optional headers that are marked as
-[]
-Header
-[]
-
-REAL_UINT64 means real UINT64.
-
-UINT64 means real UINT64 encoded with the following scheme:
-
- Size of encoding sequence depends from first byte:
- First_Byte Extra_Bytes Value
- (binary)
- 0xxxxxxx : ( xxxxxxx )
- 10xxxxxx BYTE y[1] : ( xxxxxx << (8 * 1)) + y
- 110xxxxx BYTE y[2] : ( xxxxx << (8 * 2)) + y
- ...
- 1111110x BYTE y[6] : ( x << (8 * 6)) + y
- 11111110 BYTE y[7] : y
- 11111111 BYTE y[8] : y
-
-
-
-Property IDs
-------------
-
-0x00 = kEnd,
-
-0x01 = kHeader,
-
-0x02 = kArchiveProperties,
-
-0x03 = kAdditionalStreamsInfo,
-0x04 = kMainStreamsInfo,
-0x05 = kFilesInfo,
-
-0x06 = kPackInfo,
-0x07 = kUnPackInfo,
-0x08 = kSubStreamsInfo,
-
-0x09 = kSize,
-0x0A = kCRC,
-
-0x0B = kFolder,
-
-0x0C = kCodersUnPackSize,
-0x0D = kNumUnPackStream,
-
-0x0E = kEmptyStream,
-0x0F = kEmptyFile,
-0x10 = kAnti,
-
-0x11 = kName,
-0x12 = kCreationTime,
-0x13 = kLastAccessTime,
-0x14 = kLastWriteTime,
-0x15 = kWinAttributes,
-0x16 = kComment,
-
-0x17 = kEncodedHeader,
-
-
-7z format headers
------------------
-
-SignatureHeader
-~~~~~~~~~~~~~~~
- BYTE kSignature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
-
- ArchiveVersion
- {
- BYTE Major; // now = 0
- BYTE Minor; // now = 2
- };
-
- UINT32 StartHeaderCRC;
-
- StartHeader
- {
- REAL_UINT64 NextHeaderOffset
- REAL_UINT64 NextHeaderSize
- UINT32 NextHeaderCRC
- }
-
-
-...........................
-
-
-ArchiveProperties
-~~~~~~~~~~~~~~~~~
-BYTE NID::kArchiveProperties (0x02)
-for (;;)
-{
- BYTE PropertyType;
- if (aType == 0)
- break;
- UINT64 PropertySize;
- BYTE PropertyData[PropertySize];
-}
-
-
-Digests (NumStreams)
-~~~~~~~~~~~~~~~~~~~~~
- BYTE AllAreDefined
- if (AllAreDefined == 0)
- {
- for(NumStreams)
- BIT Defined
- }
- UINT32 CRCs[NumDefined]
-
-
-PackInfo
-~~~~~~~~~~~~
- BYTE NID::kPackInfo (0x06)
- UINT64 PackPos
- UINT64 NumPackStreams
-
- []
- BYTE NID::kSize (0x09)
- UINT64 PackSizes[NumPackStreams]
- []
-
- []
- BYTE NID::kCRC (0x0A)
- PackStreamDigests[NumPackStreams]
- []
-
- BYTE NID::kEnd
-
-
-Folder
-~~~~~~
- UINT64 NumCoders;
- for (NumCoders)
- {
- BYTE
- {
- 0:3 DecompressionMethod.IDSize
- 4:
- 0 - IsSimple
- 1 - Is not simple
- 5:
- 0 - No Attributes
- 1 - There Are Attributes
- 7:
- 0 - Last Method in Alternative_Method_List
- 1 - There are more alternative methods
- }
- BYTE DecompressionMethod.ID[DecompressionMethod.IDSize]
- if (!IsSimple)
- {
- UINT64 NumInStreams;
- UINT64 NumOutStreams;
- }
- if (DecompressionMethod[0] != 0)
- {
- UINT64 PropertiesSize
- BYTE Properties[PropertiesSize]
- }
- }
-
- NumBindPairs = NumOutStreamsTotal - 1;
-
- for (NumBindPairs)
- {
- UINT64 InIndex;
- UINT64 OutIndex;
- }
-
- NumPackedStreams = NumInStreamsTotal - NumBindPairs;
- if (NumPackedStreams > 1)
- for(NumPackedStreams)
- {
- UINT64 Index;
- };
-
-
-
-
-Coders Info
-~~~~~~~~~~~
-
- BYTE NID::kUnPackInfo (0x07)
-
-
- BYTE NID::kFolder (0x0B)
- UINT64 NumFolders
- BYTE External
- switch(External)
- {
- case 0:
- Folders[NumFolders]
- case 1:
- UINT64 DataStreamIndex
- }
-
-
- BYTE ID::kCodersUnPackSize (0x0C)
- for(Folders)
- for(Folder.NumOutStreams)
- UINT64 UnPackSize;
-
-
- []
- BYTE NID::kCRC (0x0A)
- UnPackDigests[NumFolders]
- []
-
-
-
- BYTE NID::kEnd
-
-
-
-SubStreams Info
-~~~~~~~~~~~~~~
- BYTE NID::kSubStreamsInfo; (0x08)
-
- []
- BYTE NID::kNumUnPackStream; (0x0D)
- UINT64 NumUnPackStreamsInFolders[NumFolders];
- []
-
-
- []
- BYTE NID::kSize (0x09)
- UINT64 UnPackSizes[]
- []
-
-
- []
- BYTE NID::kCRC (0x0A)
- Digests[Number of streams with unknown CRC]
- []
-
-
- BYTE NID::kEnd
-
-
-Streams Info
-~~~~~~~~~~~~
-
- []
- PackInfo
- []
-
-
- []
- CodersInfo
- []
-
-
- []
- SubStreamsInfo
- []
-
- BYTE NID::kEnd
-
-
-FilesInfo
-~~~~~~~~~
- BYTE NID::kFilesInfo; (0x05)
- UINT64 NumFiles
-
- for (;;)
- {
- BYTE PropertyType;
- if (aType == 0)
- break;
-
- UINT64 Size;
-
- switch(PropertyType)
- {
- kEmptyStream: (0x0E)
- for(NumFiles)
- BIT IsEmptyStream
-
- kEmptyFile: (0x0F)
- for(EmptyStreams)
- BIT IsEmptyFile
-
- kAnti: (0x10)
- for(EmptyStreams)
- BIT IsAntiFile
-
- case kCreationTime: (0x12)
- case kLastAccessTime: (0x13)
- case kLastWriteTime: (0x14)
- BYTE AllAreDefined
- if (AllAreDefined == 0)
- {
- for(NumFiles)
- BIT TimeDefined
- }
- BYTE External;
- if(External != 0)
- UINT64 DataIndex
- []
- for(Definded Items)
- UINT32 Time
- []
-
- kNames: (0x11)
- BYTE External;
- if(External != 0)
- UINT64 DataIndex
- []
- for(Files)
- {
- wchar_t Names[NameSize];
- wchar_t 0;
- }
- []
-
- kAttributes: (0x15)
- BYTE AllAreDefined
- if (AllAreDefined == 0)
- {
- for(NumFiles)
- BIT AttributesAreDefined
- }
- BYTE External;
- if(External != 0)
- UINT64 DataIndex
- []
- for(Definded Attributes)
- UINT32 Attributes
- []
- }
- }
-
-
-Header
-~~~~~~
- BYTE NID::kHeader (0x01)
-
- []
- ArchiveProperties
- []
-
- []
- BYTE NID::kAdditionalStreamsInfo; (0x03)
- StreamsInfo
- []
-
- []
- BYTE NID::kMainStreamsInfo; (0x04)
- StreamsInfo
- []
-
- []
- FilesInfo
- []
-
- BYTE NID::kEnd
-
-
-HeaderInfo
-~~~~~~~~~~
- []
- BYTE NID::kEncodedHeader; (0x17)
- StreamsInfo for Encoded Header
- []
-
-
----
-End of document
diff --git a/src/libs/7zip/unix/C/7zBuf.h b/src/libs/7zip/unix/C/7zBuf.h
deleted file mode 100644
index e9f2f316d..000000000
--- a/src/libs/7zip/unix/C/7zBuf.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* 7zBuf.h -- Byte Buffer
-2009-02-07 : Igor Pavlov : Public domain */
-
-#ifndef __7Z_BUF_H
-#define __7Z_BUF_H
-
-#include "Types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct
-{
- Byte *data;
- size_t size;
-} CBuf;
-
-void Buf_Init(CBuf *p);
-int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
-void Buf_Free(CBuf *p, ISzAlloc *alloc);
-
-typedef struct
-{
- Byte *data;
- size_t size;
- size_t pos;
-} CDynBuf;
-
-void DynBuf_Construct(CDynBuf *p);
-void DynBuf_SeekToBeg(CDynBuf *p);
-int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
-void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/libs/7zip/unix/C/7zBuf2.c b/src/libs/7zip/unix/C/7zBuf2.c
deleted file mode 100644
index 8d17e0dcf..000000000
--- a/src/libs/7zip/unix/C/7zBuf2.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* 7zBuf2.c -- Byte Buffer
-2008-10-04 : Igor Pavlov : Public domain */
-
-#include <string.h>
-#include "7zBuf.h"
-
-void DynBuf_Construct(CDynBuf *p)
-{
- p->data = 0;
- p->size = 0;
- p->pos = 0;
-}
-
-void DynBuf_SeekToBeg(CDynBuf *p)
-{
- p->pos = 0;
-}
-
-int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)
-{
- if (size > p->size - p->pos)
- {
- size_t newSize = p->pos + size;
- Byte *data;
- newSize += newSize / 4;
- data = (Byte *)alloc->Alloc(alloc, newSize);
- if (data == 0)
- return 0;
- p->size = newSize;
- memcpy(data, p->data, p->pos);
- alloc->Free(alloc, p->data);
- p->data = data;
- }
- memcpy(p->data + p->pos, buf, size);
- p->pos += size;
- return 1;
-}
-
-void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc)
-{
- alloc->Free(alloc, p->data);
- p->data = 0;
- p->size = 0;
- p->pos = 0;
-}
diff --git a/src/libs/7zip/unix/C/7zCrc.c b/src/libs/7zip/unix/C/7zCrc.c
index 404090ef3..ac33358f6 100644
--- a/src/libs/7zip/unix/C/7zCrc.c
+++ b/src/libs/7zip/unix/C/7zCrc.c
@@ -1,41 +1,33 @@
-/* 7zCrc.c -- CRC32 calculation
-2009-11-23 : Igor Pavlov : Public domain */
+/* 7zCrc.c -- CRC32 init
+2013-11-12 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "7zCrc.h"
#include "CpuArch.h"
#define kCrcPoly 0xEDB88320
-#ifdef MY_CPU_LE
-#define CRC_NUM_TABLES 8
+#ifdef MY_CPU_X86_OR_AMD64
+ #define CRC_NUM_TABLES 8
+ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
+#elif defined(MY_CPU_LE)
+ #define CRC_NUM_TABLES 4
#else
-#define CRC_NUM_TABLES 1
+ #define CRC_NUM_TABLES 5
+ #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
+ UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
+#endif
+
+#ifndef MY_CPU_BE
+ UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
-static CRC_FUNC g_CrcUpdate;
+CRC_FUNC g_CrcUpdate;
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
-#if CRC_NUM_TABLES == 1
-
-#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
-
-static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
-{
- const Byte *p = (const Byte *)data;
- for (; size > 0; size--, p++)
- v = CRC_UPDATE_BYTE_2(v, *p);
- return v;
-}
-
-#else
-
-UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
-UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
-
-#endif
-
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
{
return g_CrcUpdate(v, data, size, g_CrcTable);
@@ -57,20 +49,39 @@ void MY_FAST_CALL CrcGenerateTable()
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
g_CrcTable[i] = r;
}
- #if CRC_NUM_TABLES == 1
- g_CrcUpdate = CrcUpdateT1;
- #else
for (; i < 256 * CRC_NUM_TABLES; i++)
{
UInt32 r = g_CrcTable[i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
+
+ #ifdef MY_CPU_LE
+
g_CrcUpdate = CrcUpdateT4;
-/* FIXME
- #ifdef MY_CPU_X86_OR_AMD64
+
+ #if CRC_NUM_TABLES == 8
+ #ifdef P7ZIP_USE_ASM
if (!CPU_Is_InOrder())
g_CrcUpdate = CrcUpdateT8;
#endif
-*/
+ #endif
+
+ #else
+ {
+ #ifndef MY_CPU_BE
+ UInt32 k = 1;
+ if (*(const Byte *)&k == 1)
+ g_CrcUpdate = CrcUpdateT4;
+ else
+ #endif
+ {
+ for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
+ {
+ UInt32 x = g_CrcTable[i - 256];
+ g_CrcTable[i] = CRC_UINT32_SWAP(x);
+ }
+ g_CrcUpdate = CrcUpdateT1_BeT4;
+ }
+ }
#endif
}
diff --git a/src/libs/7zip/unix/C/7zCrc.h b/src/libs/7zip/unix/C/7zCrc.h
index 38e3e5fbc..8fd579587 100644
--- a/src/libs/7zip/unix/C/7zCrc.h
+++ b/src/libs/7zip/unix/C/7zCrc.h
@@ -1,10 +1,10 @@
/* 7zCrc.h -- CRC32 calculation
-2009-11-21 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __7Z_CRC_H
#define __7Z_CRC_H
-#include "Types.h"
+#include "7zTypes.h"
EXTERN_C_BEGIN
diff --git a/src/libs/7zip/unix/C/7zCrcOpt.c b/src/libs/7zip/unix/C/7zCrcOpt.c
index 6c766a209..ce132b5d4 100644
--- a/src/libs/7zip/unix/C/7zCrcOpt.c
+++ b/src/libs/7zip/unix/C/7zCrcOpt.c
@@ -1,12 +1,14 @@
-/* 7zCrcOpt.c -- CRC32 calculation : optimized version
-2009-11-23 : Igor Pavlov : Public domain */
+/* 7zCrcOpt.c -- CRC32 calculation
+2013-11-12 : Igor Pavlov : Public domain */
-#include "CpuArch.h"
+#include "Precomp.h"
-#ifdef MY_CPU_LE
+#include "CpuArch.h"
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+#ifndef MY_CPU_BE
+
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
@@ -32,3 +34,33 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U
}
#endif
+
+
+#ifndef MY_CPU_LE
+
+#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
+
+UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
+{
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ v = CRC_UINT32_SWAP(v);
+ table += 0x100;
+ for (; size >= 4; size -= 4, p += 4)
+ {
+ v ^= *(const UInt32 *)p;
+ v =
+ table[0x000 + (v & 0xFF)] ^
+ table[0x100 + ((v >> 8) & 0xFF)] ^
+ table[0x200 + ((v >> 16) & 0xFF)] ^
+ table[0x300 + ((v >> 24))];
+ }
+ table -= 0x100;
+ v = CRC_UINT32_SWAP(v);
+ for (; size > 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ return v;
+}
+
+#endif
diff --git a/src/libs/7zip/unix/C/7zStream.c b/src/libs/7zip/unix/C/7zStream.c
index 0ebb7b5f9..88f9c42b1 100644
--- a/src/libs/7zip/unix/C/7zStream.c
+++ b/src/libs/7zip/unix/C/7zStream.c
@@ -1,9 +1,11 @@
/* 7zStream.c -- 7z Stream functions
-2010-03-11 : Igor Pavlov : Public domain */
+2013-11-12 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <string.h>
-#include "Types.h"
+#include "7zTypes.h"
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
{
diff --git a/src/libs/7zip/unix/C/Types.h b/src/libs/7zip/unix/C/7zTypes.h
index 7732c240c..778413ef4 100644
--- a/src/libs/7zip/unix/C/Types.h
+++ b/src/libs/7zip/unix/C/7zTypes.h
@@ -1,15 +1,15 @@
-/* Types.h -- Basic types
-2010-10-09 : Igor Pavlov : Public domain */
+/* 7zTypes.h -- Basic types
+2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
-#include <stddef.h>
-
#ifdef _WIN32
-#include <windows.h>
+/* #include <windows.h> */
#endif
+#include <stddef.h>
+
#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
@@ -43,7 +43,8 @@ EXTERN_C_BEGIN
typedef int SRes;
#ifdef _WIN32
-typedef DWORD WRes;
+/* typedef DWORD WRes; */
+typedef unsigned WRes;
#else
typedef int WRes;
#endif
@@ -116,6 +117,7 @@ typedef int Bool;
#else
+#define MY_NO_INLINE
#define MY_CDECL
#define MY_FAST_CALL
diff --git a/src/libs/7zip/unix/C/7zVersion.h b/src/libs/7zip/unix/C/7zVersion.h
index 9d99c5dff..518513534 100644
--- a/src/libs/7zip/unix/C/7zVersion.h
+++ b/src/libs/7zip/unix/C/7zVersion.h
@@ -1,7 +1,13 @@
#define MY_VER_MAJOR 9
-#define MY_VER_MINOR 20
-#define MY_VER_BUILD 0
-#define MY_VERSION "9.20"
-#define MY_DATE "2010-11-18"
+#define MY_VER_MINOR 38
+#define MY_VER_BUILD 00
+#define MY_VERSION "9.38 beta"
+// #define MY_7ZIP_VERSION "9.38"
+#define MY_DATE "2015-01-03"
+#undef MY_COPYRIGHT
+#undef MY_VERSION_COPYRIGHT_DATE
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
+
+#define P7ZIP_VERSION "9.38.1"
+
diff --git a/src/libs/7zip/unix/C/Alloc.c b/src/libs/7zip/unix/C/Alloc.c
index be02a9299..9c5fe00ca 100644
--- a/src/libs/7zip/unix/C/Alloc.c
+++ b/src/libs/7zip/unix/C/Alloc.c
@@ -34,18 +34,52 @@ int g_allocCountMid = 0;
int g_allocCountBig = 0;
#endif
+#ifdef P7ZIP_USE_ASM
+// #include <emmintrin.h>
+extern int posix_memalign (void **, size_t, size_t);
+void *align_alloc(size_t size)
+{
+ // return _mm_malloc(size,16);
+ void * ptr = 0;
+
+ if (posix_memalign (&ptr, 16, size) == 0)
+ return ptr;
+ else
+ return NULL;
+}
+
+void align_free(void * ptr)
+{
+ // _mm_free(ptr);
+ free(ptr);
+}
+
+
+#else
+void *align_alloc(size_t size)
+{
+ return malloc(size);
+}
+
+void align_free(void * ptr)
+{
+ free(ptr);
+}
+
+#endif
+
void *MyAlloc(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
{
- void *p = malloc(size);
+ void *p = align_alloc(size);
fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
return p;
}
#else
- return malloc(size);
+ return align_alloc(size);
#endif
}
@@ -55,7 +89,7 @@ void MyFree(void *address)
if (address != 0)
fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
#endif
- free(address);
+ align_free(address);
}
#ifndef _WIN32
@@ -71,9 +105,9 @@ static char *g_HugetlbPath;
#endif
+#ifdef _7ZIP_LARGE_PAGES
static void *VirtualAlloc(size_t size, int memLargePages)
{
- #ifdef _7ZIP_LARGE_PAGES
if (memLargePages)
{
#ifdef __linux__
@@ -122,9 +156,14 @@ static void *VirtualAlloc(size_t size, int memLargePages)
return address;
#endif
}
- #endif
- return malloc(size);
+ return align_alloc(size);
}
+#else
+static void *VirtualAlloc(size_t size, int memLargePages )
+{
+ return align_alloc(size);
+}
+#endif
static int VirtualFree(void *address)
{
@@ -143,7 +182,7 @@ static int VirtualFree(void *address)
}
#endif
#endif
- free(address);
+ align_free(address);
return 1;
}
@@ -255,7 +294,7 @@ void *BigAlloc(size_t size)
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
#endif
-
+
#ifdef _7ZIP_LARGE_PAGES
if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
{
@@ -273,7 +312,7 @@ void BigFree(void *address)
if (address != 0)
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
#endif
-
+
if (address == 0)
return;
VirtualFree(address);
diff --git a/src/libs/7zip/unix/C/Bra.c b/src/libs/7zip/unix/C/Bra.c
index 2e47b1413..33f7a391c 100644
--- a/src/libs/7zip/unix/C/Bra.c
+++ b/src/libs/7zip/unix/C/Bra.c
@@ -1,6 +1,8 @@
/* Bra.c -- Converters for RISC code
2010-04-16 : Igor Pavlov : Public domain */
+#include "Precomp.h"
+
#include "Bra.h"
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
@@ -48,14 +50,14 @@ SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
((UInt32)data[i + 0] << 11) |
(((UInt32)data[i + 3] & 0x7) << 8) |
(data[i + 2]);
-
+
src <<= 1;
if (encoding)
dest = ip + (UInt32)i + src;
else
dest = src - (ip + (UInt32)i);
dest >>= 1;
-
+
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
data[i + 0] = (Byte)(dest >> 11);
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
@@ -80,7 +82,7 @@ SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
((UInt32)data[i + 1] << 16) |
((UInt32)data[i + 2] << 8) |
((UInt32)data[i + 3] & (~3));
-
+
UInt32 dest;
if (encoding)
dest = ip + (UInt32)i + src;
@@ -113,14 +115,14 @@ SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
((UInt32)data[i + 2] << 8) |
((UInt32)data[i + 3]);
UInt32 dest;
-
+
src <<= 2;
if (encoding)
dest = ip + i + src;
else
dest = src - (ip + i);
dest >>= 2;
-
+
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
data[i + 0] = (Byte)(dest >> 24);
diff --git a/src/libs/7zip/unix/C/Bra.h b/src/libs/7zip/unix/C/Bra.h
index 5748c1c05..184c291a7 100644
--- a/src/libs/7zip/unix/C/Bra.h
+++ b/src/libs/7zip/unix/C/Bra.h
@@ -1,35 +1,33 @@
/* Bra.h -- Branch converters for executables
-2009-02-07 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __BRA_H
#define __BRA_H
-#include "Types.h"
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
/*
These functions convert relative addresses to absolute addresses
in CALL instructions to increase the compression ratio.
-
+
In:
data - data buffer
size - size of data
ip - current virtual Instruction Pinter (IP) value
state - state variable for x86 converter
encoding - 0 (for decoding), 1 (for encoding)
-
+
Out:
state - state variable for x86 converter
Returns:
The number of processed bytes. If you call these functions with multiple calls,
you must start next call with first byte after block of processed bytes.
-
+
Type Endian Alignment LookAhead
-
+
x86 little 1 4
ARMT little 2 2
ARM little 4 0
@@ -61,8 +59,6 @@ SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/src/libs/7zip/unix/C/Bra86.c b/src/libs/7zip/unix/C/Bra86.c
index 1ee0e709b..6db15e7ec 100644
--- a/src/libs/7zip/unix/C/Bra86.c
+++ b/src/libs/7zip/unix/C/Bra86.c
@@ -1,85 +1,82 @@
/* Bra86.c -- Converter for x86 code (BCJ)
-2008-10-04 : Igor Pavlov : Public domain */
+2013-11-12 : Igor Pavlov : Public domain */
-#include "Bra.h"
+#include "Precomp.h"
-#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+#include "Bra.h"
-const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
-const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
{
- SizeT bufferPos = 0, prevPosT;
- UInt32 prevMask = *state & 0x7;
+ SizeT pos = 0;
+ UInt32 mask = *state & 7;
if (size < 5)
return 0;
+ size -= 4;
ip += 5;
- prevPosT = (SizeT)0 - 1;
for (;;)
{
- Byte *p = data + bufferPos;
- Byte *limit = data + size - 4;
+ Byte *p = data + pos;
+ const Byte *limit = data + size;
for (; p < limit; p++)
if ((*p & 0xFE) == 0xE8)
break;
- bufferPos = (SizeT)(p - data);
- if (p >= limit)
- break;
- prevPosT = bufferPos - prevPosT;
- if (prevPosT > 3)
- prevMask = 0;
- else
+
{
- prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
- if (prevMask != 0)
+ SizeT d = (SizeT)(p - data - pos);
+ pos = (SizeT)(p - data);
+ if (p >= limit)
{
- Byte b = p[4 - kMaskToBitNumber[prevMask]];
- if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
+ *state = (d > 2 ? 0 : mask >> (unsigned)d);
+ return pos;
+ }
+ if (d > 2)
+ mask = 0;
+ else
+ {
+ mask >>= (unsigned)d;
+ if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1])))
{
- prevPosT = bufferPos;
- prevMask = ((prevMask << 1) & 0x7) | 1;
- bufferPos++;
+ mask = (mask >> 1) | 4;
+ pos++;
continue;
}
}
}
- prevPosT = bufferPos;
if (Test86MSByte(p[4]))
{
- UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
- UInt32 dest;
- for (;;)
+ UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
+ UInt32 cur = ip + (UInt32)pos;
+ pos += 5;
+ if (encoding)
+ v += cur;
+ else
+ v -= cur;
+ if (mask != 0)
{
- Byte b;
- int index;
- if (encoding)
- dest = (ip + (UInt32)bufferPos) + src;
- else
- dest = src - (ip + (UInt32)bufferPos);
- if (prevMask == 0)
- break;
- index = kMaskToBitNumber[prevMask] * 8;
- b = (Byte)(dest >> (24 - index));
- if (!Test86MSByte(b))
- break;
- src = dest ^ ((1 << (32 - index)) - 1);
+ unsigned sh = (mask & 6) << 2;
+ if (Test86MSByte((Byte)(v >> sh)))
+ {
+ v ^= (((UInt32)0x100 << sh) - 1);
+ if (encoding)
+ v += cur;
+ else
+ v -= cur;
+ }
+ mask = 0;
}
- p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
- p[3] = (Byte)(dest >> 16);
- p[2] = (Byte)(dest >> 8);
- p[1] = (Byte)dest;
- bufferPos += 5;
+ p[1] = (Byte)v;
+ p[2] = (Byte)(v >> 8);
+ p[3] = (Byte)(v >> 16);
+ p[4] = (Byte)(0 - ((v >> 24) & 1));
}
else
{
- prevMask = ((prevMask << 1) & 0x7) | 1;
- bufferPos++;
+ mask = (mask >> 1) | 4;
+ pos++;
}
}
- prevPosT = bufferPos - prevPosT;
- *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
- return bufferPos;
}
diff --git a/src/libs/7zip/unix/C/BraIA64.c b/src/libs/7zip/unix/C/BraIA64.c
index 0b4ee85bc..aa1a44e1e 100644
--- a/src/libs/7zip/unix/C/BraIA64.c
+++ b/src/libs/7zip/unix/C/BraIA64.c
@@ -1,5 +1,7 @@
/* BraIA64.c -- Converter for IA-64 code
-2008-10-04 : Igor Pavlov : Public domain */
+2013-11-12 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "Bra.h"
@@ -42,20 +44,20 @@ SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
UInt32 dest;
src |= ((UInt32)(instNorm >> 36) & 1) << 20;
-
+
src <<= 4;
-
+
if (encoding)
dest = ip + (UInt32)i + src;
else
dest = src - (ip + (UInt32)i);
-
+
dest >>= 4;
-
+
instNorm &= ~((UInt64)(0x8FFFFF) << 13);
instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
-
+
instruction &= (1 << bitRes) - 1;
instruction |= (instNorm << bitRes);
for (j = 0; j < 6; j++)
diff --git a/src/libs/7zip/unix/C/C.pri b/src/libs/7zip/unix/C/C.pri
new file mode 100644
index 000000000..6f0abb674
--- /dev/null
+++ b/src/libs/7zip/unix/C/C.pri
@@ -0,0 +1,47 @@
+HEADERS += $$7ZIP_BASE/C/7zCrc.h \
+ $$7ZIP_BASE/C/7zTypes.h \
+ $$7ZIP_BASE/C/7zVersion.h \
+ $$7ZIP_BASE/C/Alloc.h \
+ $$7ZIP_BASE/C/Bra.h \
+ $$7ZIP_BASE/C/Compiler.h \
+ $$7ZIP_BASE/C/CpuArch.h \
+ $$7ZIP_BASE/C/Delta.h \
+ $$7ZIP_BASE/C/LzFind.h \
+ $$7ZIP_BASE/C/LzFindMt.h \
+ $$7ZIP_BASE/C/LzHash.h \
+ $$7ZIP_BASE/C/Lzma2Dec.h \
+ $$7ZIP_BASE/C/Lzma2Enc.h \
+ $$7ZIP_BASE/C/LzmaDec.h \
+ $$7ZIP_BASE/C/LzmaEnc.h \
+ $$7ZIP_BASE/C/MtCoder.h \
+ $$7ZIP_BASE/C/Precomp.h \
+ $$7ZIP_BASE/C/RotateDefs.h \
+ $$7ZIP_BASE/C/Sha256.h \
+ $$7ZIP_BASE/C/Threads.h \
+ $$7ZIP_BASE/C/Xz.h \
+ $$7ZIP_BASE/C/XzCrc64.h \
+ $$7ZIP_BASE/C/XzEnc.h
+
+SOURCES += $$7ZIP_BASE/C/7zCrc.c \
+ $$7ZIP_BASE/C/7zCrcOpt.c \
+ $$7ZIP_BASE/C/7zStream.c \
+ $$7ZIP_BASE/C/Alloc.c \
+ $$7ZIP_BASE/C/Bra.c \
+ $$7ZIP_BASE/C/Bra86.c \
+ $$7ZIP_BASE/C/BraIA64.c \
+ $$7ZIP_BASE/C/Delta.c \
+ $$7ZIP_BASE/C/LzFind.c \
+ $$7ZIP_BASE/C/LzFindMt.c \
+ $$7ZIP_BASE/C/Lzma2Dec.c \
+ $$7ZIP_BASE/C/Lzma2Enc.c \
+ $$7ZIP_BASE/C/LzmaDec.c \
+ $$7ZIP_BASE/C/LzmaEnc.c \
+ $$7ZIP_BASE/C/MtCoder.c \
+ $$7ZIP_BASE/C/Sha256.c \
+ $$7ZIP_BASE/C/Threads.c \
+ $$7ZIP_BASE/C/Xz.c \
+ $$7ZIP_BASE/C/XzCrc64.c \
+ $$7ZIP_BASE/C/XzCrc64Opt.c \
+ $$7ZIP_BASE/C/XzDec.c \
+ $$7ZIP_BASE/C/XzEnc.c \
+ $$7ZIP_BASE/C/XzIn.c
diff --git a/src/libs/7zip/unix/C/Compiler.h b/src/libs/7zip/unix/C/Compiler.h
new file mode 100644
index 000000000..6e964897e
--- /dev/null
+++ b/src/libs/7zip/unix/C/Compiler.h
@@ -0,0 +1,28 @@
+/* Compiler.h -- Compiler ypes
+2013-11-12 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_COMPILER_H
+#define __7Z_COMPILER_H
+
+#ifdef _MSC_VER
+
+ #ifdef UNDER_CE
+ #define RPC_NO_WINDOWS_H
+ /* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */
+ #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
+ #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
+ #endif
+
+ #if _MSC_VER >= 1300
+ #pragma warning(disable : 4996) // This function or variable may be unsafe
+ #else
+ #pragma warning(disable : 4511) // copy constructor could not be generated
+ #pragma warning(disable : 4512) // assignment operator could not be generated
+ #pragma warning(disable : 4702) // unreachable code
+ #pragma warning(disable : 4710) // not inlined
+ #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
+ #endif
+
+#endif
+
+#endif
diff --git a/src/libs/7zip/unix/C/CpuArch.c b/src/libs/7zip/unix/C/CpuArch.c
deleted file mode 100644
index dffa5bd65..000000000
--- a/src/libs/7zip/unix/C/CpuArch.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* CpuArch.c -- CPU specific code
-2010-10-26: Igor Pavlov : Public domain */
-
-#include "CpuArch.h"
-
-#ifdef MY_CPU_X86_OR_AMD64
-
-#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
-#define USE_ASM
-#endif
-
-#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
-static UInt32 CheckFlag(UInt32 flag)
-{
- #ifdef _MSC_VER
- __asm pushfd;
- __asm pop EAX;
- __asm mov EDX, EAX;
- __asm xor EAX, flag;
- __asm push EAX;
- __asm popfd;
- __asm pushfd;
- __asm pop EAX;
- __asm xor EAX, EDX;
- __asm push EDX;
- __asm popfd;
- __asm and flag, EAX;
- #else
- __asm__ __volatile__ (
- "pushf\n\t"
- "pop %%EAX\n\t"
- "movl %%EAX,%%EDX\n\t"
- "xorl %0,%%EAX\n\t"
- "push %%EAX\n\t"
- "popf\n\t"
- "pushf\n\t"
- "pop %%EAX\n\t"
- "xorl %%EDX,%%EAX\n\t"
- "push %%EDX\n\t"
- "popf\n\t"
- "andl %%EAX, %0\n\t":
- "=c" (flag) : "c" (flag));
- #endif
- return flag;
-}
-#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
-#else
-#define CHECK_CPUID_IS_SUPPORTED
-#endif
-
-static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
-{
- #ifdef USE_ASM
-
- #ifdef _MSC_VER
-
- UInt32 a2, b2, c2, d2;
- __asm xor EBX, EBX;
- __asm xor ECX, ECX;
- __asm xor EDX, EDX;
- __asm mov EAX, function;
- __asm cpuid;
- __asm mov a2, EAX;
- __asm mov b2, EBX;
- __asm mov c2, ECX;
- __asm mov d2, EDX;
-
- *a = a2;
- *b = b2;
- *c = c2;
- *d = d2;
-
- #else
-
- __asm__ __volatile__ (
- #if defined(MY_CPU_X86) && defined(__PIC__)
- "mov %%ebx, %%edi;"
- "cpuid;"
- "xchgl %%ebx, %%edi;"
- : "=a" (*a) ,
- "=D" (*b) , /* edi */
- #else
- "cpuid"
- : "=a" (*a) ,
- "=b" (*b) ,
- #endif
- "=c" (*c) ,
- "=d" (*d)
- : "0" (function)) ;
-
- #endif
-
- #else
-
- int CPUInfo[4];
- __cpuid(CPUInfo, function);
- *a = CPUInfo[0];
- *b = CPUInfo[1];
- *c = CPUInfo[2];
- *d = CPUInfo[3];
-
- #endif
-}
-
-Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
-{
- CHECK_CPUID_IS_SUPPORTED
- MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
- MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
- return True;
-}
-
-static UInt32 kVendors[][3] =
-{
- { 0x756E6547, 0x49656E69, 0x6C65746E},
- { 0x68747541, 0x69746E65, 0x444D4163},
- { 0x746E6543, 0x48727561, 0x736C7561}
-};
-
-int x86cpuid_GetFirm(const Cx86cpuid *p)
-{
- unsigned i;
- for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
- {
- const UInt32 *v = kVendors[i];
- if (v[0] == p->vendor[0] &&
- v[1] == p->vendor[1] &&
- v[2] == p->vendor[2])
- return (int)i;
- }
- return -1;
-}
-
-Bool CPU_Is_InOrder()
-{
- Cx86cpuid p;
- int firm;
- UInt32 family, model;
- if (!x86cpuid_CheckAndRead(&p))
- return True;
- family = x86cpuid_GetFamily(&p);
- model = x86cpuid_GetModel(&p);
- firm = x86cpuid_GetFirm(&p);
- switch (firm)
- {
- case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
- case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
- case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
- }
- return True;
-}
-
-#if !defined(MY_CPU_AMD64) && defined(_WIN32)
-static Bool CPU_Sys_Is_SSE_Supported()
-{
- OSVERSIONINFO vi;
- vi.dwOSVersionInfoSize = sizeof(vi);
- if (!GetVersionEx(&vi))
- return False;
- return (vi.dwMajorVersion >= 5);
-}
-#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
-#else
-#define CHECK_SYS_SSE_SUPPORT
-#endif
-
-Bool CPU_Is_Aes_Supported()
-{
- Cx86cpuid p;
- CHECK_SYS_SSE_SUPPORT
- if (!x86cpuid_CheckAndRead(&p))
- return False;
- return (p.c >> 25) & 1;
-}
-
-#endif
diff --git a/src/libs/7zip/unix/C/CpuArch.h b/src/libs/7zip/unix/C/CpuArch.h
index 01930c7e6..e3e5d8c99 100644
--- a/src/libs/7zip/unix/C/CpuArch.h
+++ b/src/libs/7zip/unix/C/CpuArch.h
@@ -1,10 +1,10 @@
/* CpuArch.h -- CPU specific code
-2010-10-26: Igor Pavlov : Public domain */
+2013-11-12: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
-#include "Types.h"
+#include "7zTypes.h"
EXTERN_C_BEGIN
@@ -16,7 +16,7 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
*/
-#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
+#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__AMD64__) || defined(__amd64__)
#define MY_CPU_AMD64
#endif
@@ -52,7 +52,7 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_LE
#endif
-#if defined(__BIG_ENDIAN__)
+#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__)
#define MY_CPU_BE
#endif
@@ -62,9 +62,9 @@ Stop_Compiling_Bad_Endian
#ifdef MY_CPU_LE_UNALIGN
-#define GetUi16(p) (*(const UInt16 *)(p))
-#define GetUi32(p) (*(const UInt32 *)(p))
-#define GetUi64(p) (*(const UInt64 *)(p))
+#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
+#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
+#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
@@ -99,6 +99,8 @@ Stop_Compiling_Bad_Endian
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
+#include <stdlib.h>
+
#pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64)
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
@@ -116,10 +118,11 @@ Stop_Compiling_Bad_Endian
#endif
-#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
+#define GetBe16(p) ((UInt16)(((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]))
#ifdef MY_CPU_X86_OR_AMD64
+#ifdef P7ZIP_USE_ASM
typedef struct
{
@@ -149,6 +152,7 @@ Bool CPU_Is_InOrder();
Bool CPU_Is_Aes_Supported();
#endif
+#endif
EXTERN_C_END
diff --git a/src/libs/7zip/unix/C/Delta.c b/src/libs/7zip/unix/C/Delta.c
index 2b327f15f..e3edd21ed 100644
--- a/src/libs/7zip/unix/C/Delta.c
+++ b/src/libs/7zip/unix/C/Delta.c
@@ -1,6 +1,8 @@
/* Delta.c -- Delta converter
2009-05-26 : Igor Pavlov : Public domain */
+#include "Precomp.h"
+
#include "Delta.h"
void Delta_Init(Byte *state)
diff --git a/src/libs/7zip/unix/C/Delta.h b/src/libs/7zip/unix/C/Delta.h
index 0d4cd6274..2fa54ad67 100644
--- a/src/libs/7zip/unix/C/Delta.h
+++ b/src/libs/7zip/unix/C/Delta.h
@@ -1,14 +1,12 @@
/* Delta.h -- Delta converter
-2009-04-15 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __DELTA_H
#define __DELTA_H
-#include "Types.h"
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
#define DELTA_STATE_SIZE 256
@@ -16,8 +14,6 @@ void Delta_Init(Byte *state);
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size);
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/src/libs/7zip/unix/C/LzFind.c b/src/libs/7zip/unix/C/LzFind.c
index e3ecb0542..9a4d25b80 100644
--- a/src/libs/7zip/unix/C/LzFind.c
+++ b/src/libs/7zip/unix/C/LzFind.c
@@ -1,6 +1,8 @@
/* LzFind.c -- Match finder for LZ algorithms
2009-04-22 : Igor Pavlov : Public domain */
+#include "Precomp.h"
+
#include <string.h>
#include "LzFind.h"
@@ -512,7 +514,7 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
delta2 = p->pos - p->hash[hash2Value];
curMatch = p->hash[kFix3HashSize + hashValue];
-
+
p->hash[hash2Value] =
p->hash[kFix3HashSize + hashValue] = p->pos;
@@ -546,7 +548,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
delta2 = p->pos - p->hash[ hash2Value];
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
curMatch = p->hash[kFix4HashSize + hashValue];
-
+
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] =
p->hash[kFix4HashSize + hashValue] = p->pos;
diff --git a/src/libs/7zip/unix/C/LzFind.h b/src/libs/7zip/unix/C/LzFind.h
index 010c4b92b..706143d25 100644
--- a/src/libs/7zip/unix/C/LzFind.h
+++ b/src/libs/7zip/unix/C/LzFind.h
@@ -1,14 +1,12 @@
/* LzFind.h -- Match finder for LZ algorithms
-2009-04-22 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H
#define __LZ_FIND_H
-#include "Types.h"
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
typedef UInt32 CLzRef;
@@ -108,8 +106,6 @@ UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/src/libs/7zip/unix/C/LzFindMt.c b/src/libs/7zip/unix/C/LzFindMt.c
index aa41ed98a..8be0adaaf 100644
--- a/src/libs/7zip/unix/C/LzFindMt.c
+++ b/src/libs/7zip/unix/C/LzFindMt.c
@@ -1,5 +1,7 @@
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
-2009-09-20 : Igor Pavlov : Public domain */
+2014-12-29 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "LzHash.h"
@@ -58,7 +60,7 @@ void MtSync_StopWriting(CMtSync *p)
p->csWasEntered = False;
}
Semaphore_Release1(&p->freeSemaphore);
-
+
Event_Wait(&p->wasStopped);
while (myNumBlocks++ != p->numProcessedBlocks)
@@ -97,7 +99,7 @@ void MtSync_Destruct(CMtSync *p)
#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
-static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
+static SRes MtSync_Create2(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks)
{
if (p->wasCreated)
return SZ_OK;
@@ -108,18 +110,18 @@ static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart));
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted));
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped));
-
+
RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks));
RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks));
p->needStart = True;
-
+
RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj));
p->wasCreated = True;
return SZ_OK;
}
-static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
+static SRes MtSync_Create(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks)
{
SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
if (res != SZ_OK)
@@ -385,7 +387,7 @@ void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
CriticalSection_Enter(&sync->cs);
sync->csWasEntered = True;
}
-
+
BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize);
if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
@@ -451,13 +453,12 @@ void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
-static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
-static unsigned MY_STD_CALL BtThreadFunc2(void *p)
+static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
+static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
{
Byte allocaDummy[0x180];
- int i = 0;
- for (i = 0; i < 16; i++)
- allocaDummy[i] = (Byte)i;
+ allocaDummy[0] = 0;
+ allocaDummy[1] = allocaDummy[0];
BtThreadFunc((CMatchFinderMt *)p);
return 0;
}
@@ -561,7 +562,7 @@ UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos;
MT_HASH2_CALC
-
+
curMatch2 = hash[hash2Value];
hash[hash2Value] = lzPos;
@@ -584,7 +585,7 @@ UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
curMatch2 = hash[ hash2Value];
curMatch3 = hash[kFix3HashSize + hash3Value];
-
+
hash[ hash2Value] =
hash[kFix3HashSize + hash3Value] =
lzPos;
@@ -616,11 +617,11 @@ UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos;
MT_HASH4_CALC
-
+
curMatch2 = hash[ hash2Value];
curMatch3 = hash[kFix3HashSize + hash3Value];
curMatch4 = hash[kFix4HashSize + hash4Value];
-
+
hash[ hash2Value] =
hash[kFix3HashSize + hash3Value] =
hash[kFix4HashSize + hash4Value] =
diff --git a/src/libs/7zip/unix/C/LzFindMt.h b/src/libs/7zip/unix/C/LzFindMt.h
index b985af5fe..65cc12783 100644
--- a/src/libs/7zip/unix/C/LzFindMt.h
+++ b/src/libs/7zip/unix/C/LzFindMt.h
@@ -1,5 +1,5 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
-2009-02-07 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_MT_H
#define __LZ_FIND_MT_H
@@ -7,9 +7,7 @@
#include "LzFind.h"
#include "Threads.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
#define kMtHashBlockSize (1 << 13)
#define kMtHashNumBlocks (1 << 3)
@@ -62,7 +60,7 @@ typedef struct _CMatchFinderMt
const UInt32 *crc;
Mf_Mix_Matches MixMatchesFunc;
-
+
/* LZ + BT */
CMtSync btSync;
Byte btDummy[kMtCacheLineDummy];
@@ -85,7 +83,7 @@ typedef struct _CMatchFinderMt
/* BT + Hash */
CMtSync hashSync;
/* Byte hashDummy[kMtCacheLineDummy]; */
-
+
/* Hash */
Mf_GetHeads GetHeadsFunc;
CMatchFinder *MatchFinder;
@@ -98,8 +96,6 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/src/libs/7zip/unix/C/Lzma2Dec.c b/src/libs/7zip/unix/C/Lzma2Dec.c
index 7ea1cc953..e7dcc2725 100644
--- a/src/libs/7zip/unix/C/Lzma2Dec.c
+++ b/src/libs/7zip/unix/C/Lzma2Dec.c
@@ -1,8 +1,10 @@
/* Lzma2Dec.c -- LZMA2 Decoder
-2009-05-03 : Igor Pavlov : Public domain */
+2010-12-15 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
+#include "Precomp.h"
+
#ifdef SHOW_DEBUG_INFO
#include <stdio.h>
#endif
@@ -114,17 +116,17 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
else
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
return LZMA2_STATE_UNPACK0;
-
+
case LZMA2_STATE_UNPACK0:
p->unpackSize |= (UInt32)b << 8;
return LZMA2_STATE_UNPACK1;
-
+
case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b;
p->unpackSize++;
PRF(printf(" %8d", p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
-
+
case LZMA2_STATE_PACK0:
p->packSize = (UInt32)b << 8;
return LZMA2_STATE_PACK1;
@@ -199,7 +201,7 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
SizeT destSizeCur = dicLimit - dicPos;
SizeT srcSizeCur = inSize - *srcLen;
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
-
+
if (p->unpackSize <= destSizeCur)
{
destSizeCur = (SizeT)p->unpackSize;
@@ -250,7 +252,7 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
Bool initState = (mode > 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
return SZ_ERROR_DATA;
-
+
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->needInitDic = False;
p->needInitState = False;
@@ -258,9 +260,9 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
}
if (srcSizeCur > p->packSize)
srcSizeCur = (SizeT)p->packSize;
-
+
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
-
+
src += srcSizeCur;
*srcLen += srcSizeCur;
p->packSize -= (UInt32)srcSizeCur;
@@ -330,27 +332,21 @@ SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
{
- CLzma2Dec decoder;
+ CLzma2Dec p;
SRes res;
SizeT outSize = *destLen, inSize = *srcLen;
- Byte props[LZMA_PROPS_SIZE];
-
- Lzma2Dec_Construct(&decoder);
-
*destLen = *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
- decoder.decoder.dic = dest;
- decoder.decoder.dicBufSize = outSize;
-
- RINOK(Lzma2Dec_GetOldProps(prop, props));
- RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));
-
+ Lzma2Dec_Construct(&p);
+ RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
+ p.decoder.dic = dest;
+ p.decoder.dicBufSize = outSize;
+ Lzma2Dec_Init(&p);
*srcLen = inSize;
- res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
- *destLen = decoder.decoder.dicPos;
+ res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
+ *destLen = p.decoder.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF;
-
- LzmaDec_FreeProbs(&decoder.decoder, alloc);
+ Lzma2Dec_FreeProbs(&p, alloc);
return res;
}
diff --git a/src/libs/7zip/unix/C/Lzma2Dec.h b/src/libs/7zip/unix/C/Lzma2Dec.h
index 6bc07bbc1..367daf6b3 100644
--- a/src/libs/7zip/unix/C/Lzma2Dec.h
+++ b/src/libs/7zip/unix/C/Lzma2Dec.h
@@ -1,14 +1,12 @@
/* Lzma2Dec.h -- LZMA2 Decoder
-2009-05-03 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H
#include "LzmaDec.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
/* ---------- State Interface ---------- */
@@ -77,8 +75,6 @@ Returns:
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/src/libs/7zip/unix/C/Lzma2Enc.c b/src/libs/7zip/unix/C/Lzma2Enc.c
index e97597f63..5d67cc344 100644
--- a/src/libs/7zip/unix/C/Lzma2Enc.c
+++ b/src/libs/7zip/unix/C/Lzma2Enc.c
@@ -1,5 +1,7 @@
/* Lzma2Enc.c -- LZMA2 Encoder
-2010-09-24 : Igor Pavlov : Public domain */
+2012-06-19 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
/* #include <stdio.h> */
#include <string.h>
@@ -83,11 +85,11 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
if (packSize < lzHeaderSize)
return SZ_ERROR_OUTPUT_EOF;
packSize -= lzHeaderSize;
-
+
LzmaEnc_SaveState(p->enc);
res = LzmaEnc_CodeOneMemBlock(p->enc, p->needInitState,
outBuf + lzHeaderSize, &packSize, LZMA2_PACK_SIZE_MAX, &unpackSize);
-
+
PRF(printf("\npackSize = %7d unpackSize = %7d ", packSize, unpackSize));
if (unpackSize == 0)
@@ -146,10 +148,10 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
outBuf[destPos++] = (Byte)u;
outBuf[destPos++] = (Byte)(pm >> 8);
outBuf[destPos++] = (Byte)pm;
-
+
if (p->needInitProp)
outBuf[destPos++] = p->props;
-
+
p->needInitProp = False;
p->needInitState = False;
destPos += packSize;
@@ -216,8 +218,7 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
t3 = t1n * t2;
p->lzmaProps.numThreads = t1;
- p->numBlockThreads = t2;
- p->numTotalThreads = t3;
+
LzmaEncProps_Normalize(&p->lzmaProps);
if (p->blockSize == 0)
@@ -231,6 +232,21 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
if (blockSize < dictSize) blockSize = dictSize;
p->blockSize = (size_t)blockSize;
}
+ if (t2 > 1)
+ {
+ UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1;
+ if (temp > p->lzmaProps.reduceSize)
+ {
+ UInt64 numBlocks = temp / p->blockSize;
+ if (numBlocks < t2)
+ {
+ t2 = (UInt32)numBlocks;
+ t3 = t1 * t2;
+ }
+ }
+ }
+ p->numBlockThreads = t2;
+ p->numTotalThreads = t3;
}
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
@@ -244,7 +260,7 @@ typedef struct
{
Byte propEncoded;
CLzma2EncProps props;
-
+
Byte *outBuf;
ISzAlloc *alloc;
@@ -322,10 +338,10 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des
if (srcSize != 0)
{
RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
-
+
RINOK(LzmaEnc_MemPrepare(p->enc, src, srcSize, LZMA2_KEEP_WINDOW_SIZE,
mainEncoder->alloc, mainEncoder->allocBig));
-
+
while (p->srcPos < srcSize)
{
size_t packSize = destLim - *destSize;
@@ -460,7 +476,7 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
mtCallback.funcTable.Code = MtCallbackImp_Code;
mtCallback.lzma2Enc = p;
-
+
p->mtCoder.progress = progress;
p->mtCoder.inStream = inStream;
p->mtCoder.outStream = outStream;
@@ -470,7 +486,7 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
p->mtCoder.blockSize = p->props.blockSize;
p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16;
p->mtCoder.numThreads = p->props.numBlockThreads;
-
+
return MtCoder_Code(&p->mtCoder);
}
#endif
diff --git a/src/libs/7zip/unix/C/Lzma2Enc.h b/src/libs/7zip/unix/C/Lzma2Enc.h
index 283525581..f409f184c 100644
--- a/src/libs/7zip/unix/C/Lzma2Enc.h
+++ b/src/libs/7zip/unix/C/Lzma2Enc.h
@@ -1,14 +1,12 @@
/* Lzma2Enc.h -- LZMA2 Encoder
-2009-02-07 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA2_ENC_H
#define __LZMA2_ENC_H
#include "LzmaEnc.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
typedef struct
{
@@ -59,8 +57,6 @@ SRes Lzma2Encode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
*/
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/src/libs/7zip/unix/C/Lzma86Dec.c b/src/libs/7zip/unix/C/Lzma86Dec.c
deleted file mode 100644
index b801dd1ca..000000000
--- a/src/libs/7zip/unix/C/Lzma86Dec.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
-2008-04-07
-Igor Pavlov
-Public domain */
-
-#include "Lzma86Dec.h"
-
-#include "../Alloc.h"
-#include "../Bra.h"
-#include "../LzmaDec.h"
-
-#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
-#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
-
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
-SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
-{
- unsigned i;
- if (srcLen < LZMA86_HEADER_SIZE)
- return SZ_ERROR_INPUT_EOF;
- *unpackSize = 0;
- for (i = 0; i < sizeof(UInt64); i++)
- *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i);
- return SZ_OK;
-}
-
-SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)
-{
- SRes res;
- int useFilter;
- SizeT inSizePure;
- ELzmaStatus status;
-
- if (*srcLen < LZMA86_HEADER_SIZE)
- return SZ_ERROR_INPUT_EOF;
-
- useFilter = src[0];
-
- if (useFilter > 1)
- {
- *destLen = 0;
- return SZ_ERROR_UNSUPPORTED;
- }
-
- inSizePure = *srcLen - LZMA86_HEADER_SIZE;
- res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure,
- src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc);
- *srcLen = inSizePure + LZMA86_HEADER_SIZE;
- if (res != SZ_OK)
- return res;
- if (useFilter == 1)
- {
- UInt32 x86State;
- x86_Convert_Init(x86State);
- x86_Convert(dest, *destLen, 0, &x86State, 0);
- }
- return SZ_OK;
-}
diff --git a/src/libs/7zip/unix/C/Lzma86Enc.c b/src/libs/7zip/unix/C/Lzma86Enc.c
deleted file mode 100644
index efc81ea35..000000000
--- a/src/libs/7zip/unix/C/Lzma86Enc.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
-2008-08-05
-Igor Pavlov
-Public domain */
-
-#include <string.h>
-
-#include "Lzma86Enc.h"
-
-#include "../Alloc.h"
-#include "../Bra.h"
-#include "../LzmaEnc.h"
-
-#define SZE_OUT_OVERFLOW SZE_DATA_ERROR
-
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
-#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
-#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
-
-int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
- int level, UInt32 dictSize, int filterMode)
-{
- size_t outSize2 = *destLen;
- Byte *filteredStream;
- Bool useFilter;
- int mainResult = SZ_ERROR_OUTPUT_EOF;
- CLzmaEncProps props;
- LzmaEncProps_Init(&props);
- props.level = level;
- props.dictSize = dictSize;
-
- *destLen = 0;
- if (outSize2 < LZMA86_HEADER_SIZE)
- return SZ_ERROR_OUTPUT_EOF;
-
- {
- int i;
- UInt64 t = srcLen;
- for (i = 0; i < 8; i++, t >>= 8)
- dest[LZMA86_SIZE_OFFSET + i] = (Byte)t;
- }
-
- filteredStream = 0;
- useFilter = (filterMode != SZ_FILTER_NO);
- if (useFilter)
- {
- if (srcLen != 0)
- {
- filteredStream = (Byte *)MyAlloc(srcLen);
- if (filteredStream == 0)
- return SZ_ERROR_MEM;
- memcpy(filteredStream, src, srcLen);
- }
- {
- UInt32 x86State;
- x86_Convert_Init(x86State);
- x86_Convert(filteredStream, srcLen, 0, &x86State, 1);
- }
- }
-
- {
- size_t minSize = 0;
- Bool bestIsFiltered = False;
-
- /* passes for SZ_FILTER_AUTO:
- 0 - BCJ + LZMA
- 1 - LZMA
- 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
- */
- int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
-
- int i;
- for (i = 0; i < numPasses; i++)
- {
- size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;
- size_t outPropsSize = 5;
- SRes curRes;
- Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);
- if (curModeIsFiltered && !bestIsFiltered)
- break;
- if (useFilter && i == 0)
- curModeIsFiltered = True;
-
- curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
- curModeIsFiltered ? filteredStream : src, srcLen,
- &props, dest + 1, &outPropsSize, 0,
- NULL, &g_Alloc, &g_Alloc);
-
- if (curRes != SZ_ERROR_OUTPUT_EOF)
- {
- if (curRes != SZ_OK)
- {
- mainResult = curRes;
- break;
- }
- if (outSizeProcessed <= minSize || mainResult != SZ_OK)
- {
- minSize = outSizeProcessed;
- bestIsFiltered = curModeIsFiltered;
- mainResult = SZ_OK;
- }
- }
- }
- dest[0] = (bestIsFiltered ? 1 : 0);
- *destLen = LZMA86_HEADER_SIZE + minSize;
- }
- if (useFilter)
- MyFree(filteredStream);
- return mainResult;
-}
diff --git a/src/libs/7zip/unix/C/LzmaDec.c b/src/libs/7zip/unix/C/LzmaDec.c
index 2036761bf..b1a2ad150 100644
--- a/src/libs/7zip/unix/C/LzmaDec.c
+++ b/src/libs/7zip/unix/C/LzmaDec.c
@@ -1,5 +1,7 @@
/* LzmaDec.c -- LZMA Decoder
-2009-09-20 : Igor Pavlov : Public domain */
+2015-01-01 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "LzmaDec.h"
@@ -44,6 +46,13 @@
i -= 0x40; }
#endif
+#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol)
+#define MATCHED_LITER_DEC \
+ matchByte <<= 1; \
+ bit = (matchByte & offs); \
+ probLit = prob + offs + bit + symbol; \
+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
+
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
@@ -141,7 +150,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
Byte *dic = p->dic;
SizeT dicBufSize = p->dicBufSize;
SizeT dicPos = p->dicPos;
-
+
UInt32 processedPos = p->processedPos;
UInt32 checkDicSize = p->checkDicSize;
unsigned len = 0;
@@ -171,24 +180,47 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
{
state -= (state < 4) ? state : 3;
symbol = 1;
- do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
+ #ifdef _LZMA_SIZE_OPT
+ do { NORMAL_LITER_DEC } while (symbol < 0x100);
+ #else
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ #endif
}
else
{
- unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ unsigned matchByte = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
unsigned offs = 0x100;
state -= (state < 10) ? 3 : 6;
symbol = 1;
+ #ifdef _LZMA_SIZE_OPT
do
{
unsigned bit;
CLzmaProb *probLit;
- matchByte <<= 1;
- bit = (matchByte & offs);
- probLit = prob + offs + bit + symbol;
- GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
+ MATCHED_LITER_DEC
}
while (symbol < 0x100);
+ #else
+ {
+ unsigned bit;
+ CLzmaProb *probLit;
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ }
+ #endif
}
dic[dicPos++] = (Byte)symbol;
processedPos++;
@@ -324,7 +356,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
{
NORMALIZE
range >>= 1;
-
+
{
UInt32 t;
code -= range;
@@ -442,8 +474,9 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
p->processedPos += len;
p->remainLen -= len;
- while (len-- != 0)
+ while (len != 0)
{
+ len--;
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
dicPos++;
}
@@ -722,7 +755,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
SizeT inSize = *srcLen;
(*srcLen) = 0;
LzmaDec_WriteRem(p, dicLimit);
-
+
*status = LZMA_STATUS_NOT_SPECIFIED;
while (p->remainLen != kMatchSpecLenStart)
@@ -768,7 +801,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
if (p->needInitState)
LzmaDec_InitStateReal(p);
-
+
if (p->tempBufSize == 0)
{
SizeT processed;
@@ -899,12 +932,12 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
{
UInt32 dicSize;
Byte d;
-
+
if (size < LZMA_PROPS_SIZE)
return SZ_ERROR_UNSUPPORTED;
else
dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
-
+
if (dicSize < LZMA_DIC_MIN)
dicSize = LZMA_DIC_MIN;
p->dicSize = dicSize;
@@ -972,28 +1005,21 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
{
CLzmaDec p;
SRes res;
- SizeT inSize = *srcLen;
- SizeT outSize = *destLen;
- *srcLen = *destLen = 0;
+ SizeT outSize = *destLen, inSize = *srcLen;
+ *destLen = *srcLen = 0;
+ *status = LZMA_STATUS_NOT_SPECIFIED;
if (inSize < RC_INIT_SIZE)
return SZ_ERROR_INPUT_EOF;
-
LzmaDec_Construct(&p);
- res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
- if (res != 0)
- return res;
+ RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc));
p.dic = dest;
p.dicBufSize = outSize;
-
LzmaDec_Init(&p);
-
*srcLen = inSize;
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
-
+ *destLen = p.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF;
-
- (*destLen) = p.dicPos;
LzmaDec_FreeProbs(&p, alloc);
return res;
}
diff --git a/src/libs/7zip/unix/C/LzmaDec.h b/src/libs/7zip/unix/C/LzmaDec.h
index bf7f084ba..63efc351f 100644
--- a/src/libs/7zip/unix/C/LzmaDec.h
+++ b/src/libs/7zip/unix/C/LzmaDec.h
@@ -1,14 +1,12 @@
/* LzmaDec.h -- LZMA Decoder
-2009-02-07 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H
#define __LZMA_DEC_H
-#include "Types.h"
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
/* #define _LZMA_PROB32 */
/* _LZMA_PROB32 can increase the speed on some CPUs,
@@ -130,7 +128,7 @@ LzmaDec_Allocate* can return:
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
-
+
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
@@ -159,7 +157,7 @@ void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
*/
/* LzmaDec_DecodeToDic
-
+
The decoding to internal dictionary buffer (CLzmaDec::dic).
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
@@ -224,8 +222,6 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/src/libs/7zip/unix/C/LzmaEnc.c b/src/libs/7zip/unix/C/LzmaEnc.c
index cf131388a..bf3cc2ddb 100644
--- a/src/libs/7zip/unix/C/LzmaEnc.c
+++ b/src/libs/7zip/unix/C/LzmaEnc.c
@@ -1,5 +1,7 @@
/* LzmaEnc.c -- LZMA Encoder
-2010-04-16 : Igor Pavlov : Public domain */
+2014-12-29 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <string.h>
@@ -18,7 +20,7 @@
#endif
#ifdef SHOW_STAT
-static int ttt = 0;
+static unsigned g_STAT_OFFSET = 0;
#endif
#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
@@ -46,6 +48,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p)
{
p->level = 5;
p->dictSize = p->mc = 0;
+ p->reduceSize = (UInt64)(Int64)-1;
p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
p->writeEndMark = 0;
}
@@ -56,6 +59,15 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
if (level < 0) level = 5;
p->level = level;
if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
+ if (p->dictSize > p->reduceSize)
+ {
+ unsigned i;
+ for (i = 11; i <= 30; i++)
+ {
+ if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
+ if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
+ }
+ }
if (p->lc < 0) p->lc = 3;
if (p->lp < 0) p->lp = 0;
if (p->pb < 0) p->pb = 2;
@@ -109,7 +121,7 @@ void LzmaEnc_FastPosInit(Byte *g_FastPos)
int c = 2, slotFast;
g_FastPos[0] = 0;
g_FastPos[1] = 1;
-
+
for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
{
UInt32 k = (1 << ((slotFast >> 1) - 1));
@@ -246,7 +258,7 @@ typedef struct
CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
CLzmaProb posAlignEncoder[1 << kNumAlignBits];
-
+
CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc;
@@ -269,7 +281,7 @@ typedef struct
#ifndef _7ZIP_ST
Byte pad[128];
#endif
-
+
UInt32 optimumEndIndex;
UInt32 optimumCurrentIndex;
@@ -277,7 +289,7 @@ typedef struct
UInt32 numPairs;
UInt32 numAvail;
COptimal opt[kNumOpts];
-
+
#ifndef LZMA_LOG_BSR
Byte g_FastPos[1 << kNumLogBits];
#endif
@@ -311,14 +323,14 @@ typedef struct
CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
CLzmaProb posAlignEncoder[1 << kNumAlignBits];
-
+
CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc;
unsigned lclp;
Bool fastMode;
-
+
CRangeEnc rc;
Bool writeEndMark;
@@ -329,7 +341,6 @@ typedef struct
SRes result;
UInt32 dictSize;
- UInt32 matchFinderCycles;
int needInit;
@@ -398,7 +409,6 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30))
return SZ_ERROR_PARAM;
p->dictSize = props.dictSize;
- p->matchFinderCycles = props.mc;
{
unsigned fb = props.fb;
if (fb < 5)
@@ -508,7 +518,7 @@ static void RangeEnc_FlushStream(CRangeEnc *p)
static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
{
- if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
+ if ((UInt32)p->low < (UInt32)0xFF000000 || (unsigned)(p->low >> 32) != 0)
{
Byte temp = p->cache;
do
@@ -534,7 +544,7 @@ static void RangeEnc_FlushData(CRangeEnc *p)
RangeEnc_ShiftLow(p);
}
-static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, unsigned numBits)
{
do
{
@@ -803,9 +813,10 @@ static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32
static void MovePos(CLzmaEnc *p, UInt32 num)
{
#ifdef SHOW_STAT
- ttt += num;
+ g_STAT_OFFSET += num;
printf("\n MovePos %d", num);
#endif
+
if (num != 0)
{
p->additionalOffset += num;
@@ -818,15 +829,17 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
UInt32 lenRes = 0, numPairs;
p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
+
#ifdef SHOW_STAT
- printf("\n i = %d numPairs = %d ", ttt, numPairs / 2);
- ttt++;
+ printf("\n i = %d numPairs = %d ", g_STAT_OFFSET, numPairs / 2);
+ g_STAT_OFFSET++;
{
UInt32 i;
for (i = 0; i < numPairs; i += 2)
printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
}
#endif
+
if (numPairs > 0)
{
lenRes = p->matches[numPairs - 2];
@@ -909,10 +922,10 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
{
UInt32 posPrev = posMem;
UInt32 backCur = backMem;
-
+
backMem = p->opt[posPrev].backPrev;
posMem = p->opt[posPrev].posPrev;
-
+
p->opt[posPrev].backPrev = backCur;
p->opt[posPrev].posPrev = cur;
cur = posPrev;
@@ -943,7 +956,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
return lenRes;
}
p->optimumCurrentIndex = p->optimumEndIndex = 0;
-
+
if (p->additionalOffset == 0)
mainLen = ReadMatchDistances(p, &numPairs);
else
@@ -1241,7 +1254,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
-
+
if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
{
UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
@@ -1303,7 +1316,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
}
}
}
-
+
startLen = 2; /* speed optimization */
{
UInt32 repIndex;
@@ -1334,10 +1347,10 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
}
while (--lenTest >= 2);
lenTest = lenTestTemp;
-
+
if (repIndex == 0)
startLen = lenTest + 1;
-
+
/* if (_maxMode) */
{
UInt32 lenTest2 = lenTest + 1;
@@ -1361,7 +1374,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
nextRepMatchPrice = curAndLenCharPrice +
GET_PRICE_1(p->isMatch[state2][posStateNext]) +
GET_PRICE_1(p->isRep[state2]);
-
+
/* for (; lenTest2 >= 2; lenTest2--) */
{
UInt32 curAndLenPrice;
@@ -1416,7 +1429,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
else
curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
-
+
opt = &p->opt[cur + lenTest];
if (curAndLenPrice < opt->price)
{
@@ -1450,7 +1463,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
nextRepMatchPrice = curAndLenCharPrice +
GET_PRICE_1(p->isMatch[state2][posStateNext]) +
GET_PRICE_1(p->isRep[state2]);
-
+
/* for (; lenTest2 >= 2; lenTest2--) */
{
UInt32 offset = cur + lenTest + 1 + lenTest2;
@@ -1562,7 +1575,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
MovePos(p, repLen - 1);
return repLen;
}
-
+
if (mainLen < 2 || numAvail <= 2)
return 1;
@@ -1576,7 +1589,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
(p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
return 1;
}
-
+
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
for (i = 0; i < LZMA_NUM_REPS; i++)
{
@@ -1837,7 +1850,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
pos -= LZMA_NUM_REPS;
GetPosSlot(pos, posSlot);
RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
-
+
if (posSlot >= kStartPosModelIndex)
{
UInt32 footerBits = ((posSlot >> 1) - 1);
@@ -1897,12 +1910,10 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
{
UInt32 beforeSize = kNumOpts;
- Bool btMode;
if (!RangeEnc_Alloc(&p->rc, alloc))
return SZ_ERROR_MEM;
- btMode = (p->matchFinderBase.btMode != 0);
#ifndef _7ZIP_ST
- p->mtMode = (p->multiThread && !p->fastMode && btMode);
+ p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0));
#endif
{
@@ -2142,7 +2153,7 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
p->rc.outStream = &outStream.funcTable;
res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
-
+
*unpackSize = (UInt32)(p->nowPos64 - nowPos64);
*destLen -= outStream.rem;
if (outStream.overflow)
@@ -2157,9 +2168,8 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
#ifndef _7ZIP_ST
Byte allocaDummy[0x300];
- int i = 0;
- for (i = 0; i < 16; i++)
- allocaDummy[i] = (Byte)i;
+ allocaDummy[0] = 0;
+ allocaDummy[1] = allocaDummy[0];
#endif
for (;;)
diff --git a/src/libs/7zip/unix/C/LzmaEnc.h b/src/libs/7zip/unix/C/LzmaEnc.h
index 200d60eb8..cffe220bb 100644
--- a/src/libs/7zip/unix/C/LzmaEnc.h
+++ b/src/libs/7zip/unix/C/LzmaEnc.h
@@ -1,14 +1,12 @@
/* LzmaEnc.h -- LZMA Encoder
-2009-02-07 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA_ENC_H
#define __LZMA_ENC_H
-#include "Types.h"
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
#define LZMA_PROPS_SIZE 5
@@ -18,6 +16,8 @@ typedef struct _CLzmaEncProps
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
default = (1 << 24) */
+ UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF.
+ Encoder uses this value to reduce dictionary size */
int lc; /* 0 <= lc <= 8, default = 3 */
int lp; /* 0 <= lp <= 4, default = 0 */
int pb; /* 0 <= pb <= 4, default = 2 */
@@ -73,8 +73,6 @@ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/src/libs/7zip/unix/C/MtCoder.c b/src/libs/7zip/unix/C/MtCoder.c
index 946fbbc70..3d4dd2d14 100644
--- a/src/libs/7zip/unix/C/MtCoder.c
+++ b/src/libs/7zip/unix/C/MtCoder.c
@@ -1,6 +1,8 @@
/* MtCoder.c -- Multi-thread Coder
2010-09-24 : Igor Pavlov : Public domain */
+#include "Precomp.h"
+
#include <stdio.h>
#include "MtCoder.h"
@@ -190,9 +192,9 @@ static SRes MtThread_Process(CMtThread *p, Bool *stop)
*stop = True;
if (Event_Wait(&p->canRead) != 0)
return SZ_ERROR_THREAD;
-
+
next = GET_NEXT_THREAD(p);
-
+
if (p->stopReading)
{
next->stopReading = True;
diff --git a/src/libs/7zip/unix/C/MtCoder.h b/src/libs/7zip/unix/C/MtCoder.h
index f0f06da28..e2cbdc3ab 100644
--- a/src/libs/7zip/unix/C/MtCoder.h
+++ b/src/libs/7zip/unix/C/MtCoder.h
@@ -14,7 +14,7 @@ typedef struct
CAutoResetEvent startEvent;
CAutoResetEvent finishedEvent;
int stop;
-
+
THREAD_FUNC_TYPE func;
LPVOID param;
THREAD_FUNC_RET_TYPE res;
@@ -75,7 +75,7 @@ typedef struct _CMtCoder
size_t blockSize;
size_t destBlockSize;
unsigned numThreads;
-
+
ISeqInStream *inStream;
ISeqOutStream *outStream;
ICompressProgress *progress;
diff --git a/src/libs/7zip/unix/C/Precomp.h b/src/libs/7zip/unix/C/Precomp.h
new file mode 100644
index 000000000..e8ff8b40e
--- /dev/null
+++ b/src/libs/7zip/unix/C/Precomp.h
@@ -0,0 +1,10 @@
+/* Precomp.h -- StdAfx
+2013-11-12 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_PRECOMP_H
+#define __7Z_PRECOMP_H
+
+#include "Compiler.h"
+/* #include "7zTypes.h" */
+
+#endif
diff --git a/src/libs/7zip/unix/C/RotateDefs.h b/src/libs/7zip/unix/C/RotateDefs.h
index c3a1385ce..1b83e5ea1 100644
--- a/src/libs/7zip/unix/C/RotateDefs.h
+++ b/src/libs/7zip/unix/C/RotateDefs.h
@@ -1,5 +1,5 @@
/* RotateDefs.h -- Rotate functions
-2009-02-07 : Igor Pavlov : Public domain */
+2013-11-12 : Igor Pavlov : Public domain */
#ifndef __ROTATE_DEFS_H
#define __ROTATE_DEFS_H
@@ -7,6 +7,12 @@
#ifdef _MSC_VER
#include <stdlib.h>
+
+// #if (_MSC_VER >= 1200)
+#pragma intrinsic(_rotl)
+#pragma intrinsic(_rotr)
+// #endif
+
#define rotlFixed(x, n) _rotl((x), (n))
#define rotrFixed(x, n) _rotr((x), (n))
diff --git a/src/libs/7zip/unix/C/Sha256.c b/src/libs/7zip/unix/C/Sha256.c
index eb4fc61fc..10df0874f 100644
--- a/src/libs/7zip/unix/C/Sha256.c
+++ b/src/libs/7zip/unix/C/Sha256.c
@@ -2,6 +2,8 @@
2010-06-11 : Igor Pavlov : Public domain
This code is based on public domain code from Wei Dai's Crypto++ library. */
+#include "Precomp.h"
+
#include "RotateDefs.h"
#include "Sha256.h"
@@ -133,7 +135,7 @@ static void Sha256_Transform(UInt32 *state, const UInt32 *data)
for (j = 0; j < 8; j++)
state[j] += T[j];
#endif
-
+
/* Wipe variables */
/* memset(W, 0, sizeof(W)); */
/* memset(T, 0, sizeof(T)); */
diff --git a/src/libs/7zip/unix/C/Sha256.h b/src/libs/7zip/unix/C/Sha256.h
index 530f513ec..3f455dbc0 100644
--- a/src/libs/7zip/unix/C/Sha256.h
+++ b/src/libs/7zip/unix/C/Sha256.h
@@ -1,10 +1,10 @@
/* Sha256.h -- SHA-256 Hash
-2010-06-11 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __CRYPTO_SHA256_H
#define __CRYPTO_SHA256_H
-#include "Types.h"
+#include "7zTypes.h"
EXTERN_C_BEGIN
diff --git a/src/libs/7zip/unix/C/Threads.c b/src/libs/7zip/unix/C/Threads.c
index 1b8203f68..f3fdb24e1 100644
--- a/src/libs/7zip/unix/C/Threads.c
+++ b/src/libs/7zip/unix/C/Threads.c
@@ -11,16 +11,16 @@
#include <errno.h>
-#if defined(__linux__)
+#if defined(__linux__)
#define PTHREAD_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK_NP
#endif
#ifdef ENV_BEOS
-/* TODO : optimize the code and verify the returned values */
+/* TODO : optimize the code and verify the returned values */
WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
-{
+{
thread->_tid = spawn_thread((int32 (*)(void *))startAddress, "CThread", B_LOW_PRIORITY, parameter);
if (thread->_tid >= B_OK) {
resume_thread(thread->_tid);
@@ -38,7 +38,7 @@ WRes Thread_Wait(CThread *thread)
if (thread->_created == 0)
return EINVAL;
- if (thread->_tid >= B_OK)
+ if (thread->_tid >= B_OK)
{
status_t exit_value;
wait_for_thread(thread->_tid, &exit_value);
@@ -46,16 +46,16 @@ WRes Thread_Wait(CThread *thread)
} else {
return EINVAL;
}
-
+
thread->_created = 0;
-
+
return 0;
}
WRes Thread_Close(CThread *thread)
{
if (!thread->_created) return SZ_OK;
-
+
thread->_tid = B_BAD_THREAD_ID;
thread->_created = 0;
return SZ_OK;
@@ -91,12 +91,12 @@ WRes Event_Reset(CEvent *p) {
release_sem(p->_sem);
return 0;
}
-
+
WRes Event_Wait(CEvent *p) {
acquire_sem(p->_sem);
while (p->_state == FALSE)
{
- thread_id sender;
+ thread_id sender;
p->_waiting[p->_index_waiting++] = find_thread(NULL);
release_sem(p->_sem);
/* int msg = */ receive_data(&sender, NULL, 0);
@@ -110,7 +110,7 @@ WRes Event_Wait(CEvent *p) {
return 0;
}
-WRes Event_Close(CEvent *p) {
+WRes Event_Close(CEvent *p) {
if (p->_created)
{
p->_created = 0;
@@ -133,7 +133,7 @@ WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
{
UInt32 newCount;
int index;
-
+
if (releaseCount < 1) return EINVAL;
acquire_sem(p->_sem);
@@ -157,14 +157,14 @@ WRes Semaphore_Wait(CSemaphore *p) {
acquire_sem(p->_sem);
while (p->_count < 1)
{
- thread_id sender;
+ thread_id sender;
p->_waiting[p->_index_waiting++] = find_thread(NULL);
release_sem(p->_sem);
/* int msg = */ receive_data(&sender, NULL, 0);
acquire_sem(p->_sem);
}
p->_count--;
- release_sem(p->_sem);
+ release_sem(p->_sem);
return 0;
}
@@ -186,7 +186,7 @@ WRes CriticalSection_Init(CCriticalSection * lpCriticalSection)
#else /* !ENV_BEOS */
WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
-{
+{
pthread_attr_t attr;
int ret;
@@ -219,14 +219,14 @@ WRes Thread_Wait(CThread *thread)
ret = pthread_join(thread->_tid,&thread_return);
thread->_created = 0;
-
+
return ret;
}
WRes Thread_Close(CThread *thread)
{
if (!thread->_created) return SZ_OK;
-
+
pthread_detach(thread->_tid);
thread->_tid = 0;
thread->_created = 0;
@@ -293,7 +293,7 @@ WRes Event_Reset(CEvent *p) {
}
return ret;
}
-
+
WRes Event_Wait(CEvent *p) {
int ret = pthread_mutex_lock(&p->_mutex);
if (ret != 0) dump_error(__LINE__,ret,"EW::pthread_mutex_lock",&p->_mutex);
@@ -317,7 +317,7 @@ WRes Event_Wait(CEvent *p) {
return ret;
}
-WRes Event_Close(CEvent *p) {
+WRes Event_Close(CEvent *p) {
if (p->_created)
{
int ret;
@@ -484,7 +484,7 @@ WRes Event_Reset(CEvent *p) {
pthread_mutex_unlock(&p->_mutex);
return 0;
}
-
+
WRes Event_Wait(CEvent *p) {
pthread_mutex_lock(&p->_mutex);
while (p->_state == FALSE)
@@ -499,7 +499,7 @@ WRes Event_Wait(CEvent *p) {
return 0;
}
-WRes Event_Close(CEvent *p) {
+WRes Event_Close(CEvent *p) {
if (p->_created)
{
p->_created = 0;
@@ -572,11 +572,11 @@ WRes CriticalSection_Init(CCriticalSection * lpCriticalSection)
WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
{ return Event_Create(p, TRUE, initialSignaled); }
-WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
+WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
{ return ManualResetEvent_Create(p, 0); }
WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
{ return Event_Create(p, FALSE, initialSignaled); }
-WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
+WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
{ return AutoResetEvent_Create(p, 0); }
diff --git a/src/libs/7zip/unix/C/Threads.h b/src/libs/7zip/unix/C/Threads.h
index 07b05be0c..a285bc901 100644
--- a/src/libs/7zip/unix/C/Threads.h
+++ b/src/libs/7zip/unix/C/Threads.h
@@ -4,7 +4,7 @@
#ifndef __7Z_THRESDS_H
#define __7Z_THRESDS_H
-#include "Types.h"
+#include "7zTypes.h"
#include "windows.h"
#ifdef ENV_BEOS
diff --git a/src/libs/7zip/unix/C/Xz.c b/src/libs/7zip/unix/C/Xz.c
index 18caba2c1..fbc732a8a 100644
--- a/src/libs/7zip/unix/C/Xz.c
+++ b/src/libs/7zip/unix/C/Xz.c
@@ -1,6 +1,8 @@
/* Xz.c - Xz
2009-04-15 : Igor Pavlov : Public domain */
+#include "Precomp.h"
+
#include "7zCrc.h"
#include "CpuArch.h"
#include "Xz.h"
diff --git a/src/libs/7zip/unix/C/Xz.h b/src/libs/7zip/unix/C/Xz.h
index 2cfa1b789..9268d5bc6 100644
--- a/src/libs/7zip/unix/C/Xz.h
+++ b/src/libs/7zip/unix/C/Xz.h
@@ -1,5 +1,5 @@
/* Xz.h - Xz interface
-2010-09-17 : Igor Pavlov : Public domain */
+2014-12-30 : Igor Pavlov : Public domain */
#ifndef __XZ_H
#define __XZ_H
@@ -199,7 +199,7 @@ typedef struct
unsigned indexPreSize;
CXzStreamFlags streamFlags;
-
+
UInt32 blockHeaderSize;
UInt64 packSize;
UInt64 unpackSize;
@@ -209,7 +209,9 @@ typedef struct
UInt64 indexPos;
UInt64 padSize;
- UInt64 numStreams;
+ UInt64 numStartedStreams;
+ UInt64 numFinishedStreams;
+ UInt64 numTotalBlocks;
UInt32 crc;
CMixCoder decoder;
@@ -220,33 +222,54 @@ typedef struct
Byte buf[XZ_BLOCK_HEADER_SIZE_MAX];
} CXzUnpacker;
-SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc);
+void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc);
+void XzUnpacker_Init(CXzUnpacker *p);
void XzUnpacker_Free(CXzUnpacker *p);
/*
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
- LZMA_FINISH_ANY - use smallest number of input bytes
- LZMA_FINISH_END - read EndOfStream marker after decoding
+ CODER_FINISH_ANY - use smallest number of input bytes
+ CODER_FINISH_END - read EndOfStream marker after decoding
Returns:
SZ_OK
status:
- LZMA_STATUS_FINISHED_WITH_MARK
- LZMA_STATUS_NOT_FINISHED
- SZ_ERROR_DATA - Data error
+ CODER_STATUS_NOT_FINISHED,
+ CODER_STATUS_NEEDS_MORE_INPUT - maybe there are more xz streams,
+ call XzUnpacker_IsStreamWasFinished to check that current stream was finished
SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_UNSUPPORTED - Unsupported properties
- SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+ SZ_ERROR_DATA - Data error
+ SZ_ERROR_UNSUPPORTED - Unsupported method or method properties
+ SZ_ERROR_CRC - CRC error
+ // SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+
+ SZ_ERROR_NO_ARCHIVE - the error with xz Stream Header with one of the following reasons:
+ - xz Stream Signature failure
+ - CRC32 of xz Stream Header is failed
+ - The size of Stream padding is not multiple of four bytes.
+ It's possible to get that error, if xz stream was finished and the stream
+ contains some another data. In that case you can call XzUnpacker_GetExtraSize()
+ function to get real size of xz stream.
*/
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
- const Byte *src, SizeT *srcLen, /* int srcWasFinished, */ int finishMode,
+ const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode,
ECoderStatus *status);
Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p);
+/*
+Call XzUnpacker_GetExtraSize after XzUnpacker_Code function to detect real size of
+xz stream in two cases:
+XzUnpacker_Code() returns:
+ res == SZ_OK && status == CODER_STATUS_NEEDS_MORE_INPUT
+ res == SZ_ERROR_NO_ARCHIVE
+*/
+
+UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p);
+
EXTERN_C_END
#endif
diff --git a/src/libs/7zip/unix/C/XzCrc64.c b/src/libs/7zip/unix/C/XzCrc64.c
index 0369554b7..2c04c0af4 100644
--- a/src/libs/7zip/unix/C/XzCrc64.c
+++ b/src/libs/7zip/unix/C/XzCrc64.c
@@ -1,33 +1,90 @@
/* XzCrc64.c -- CRC64 calculation
-2010-04-16 : Igor Pavlov : Public domain */
+2011-06-28 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "XzCrc64.h"
+#include "CpuArch.h"
#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42)
-UInt64 g_Crc64Table[256];
-void MY_FAST_CALL Crc64GenerateTable(void)
+#ifdef MY_CPU_LE
+ #define CRC_NUM_TABLES 4
+#else
+ #define CRC_NUM_TABLES 5
+ #define CRC_UINT64_SWAP(v) \
+ ((v >> 56) | \
+ ((v >> 40) & ((UInt64)0xFF << 8)) | \
+ ((v >> 24) & ((UInt64)0xFF << 16)) | \
+ ((v >> 8) & ((UInt64)0xFF << 24)) | \
+ ((v << 8) & ((UInt64)0xFF << 32)) | \
+ ((v << 24) & ((UInt64)0xFF << 40)) | \
+ ((v << 40) & ((UInt64)0xFF << 48)) | \
+ (v << 56))
+ UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
+#endif
+
+#ifndef MY_CPU_BE
+ UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
+#endif
+
+typedef UInt64 (MY_FAST_CALL *CRC_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table);
+
+static CRC_FUNC g_Crc64Update;
+UInt64 g_Crc64Table[256 * CRC_NUM_TABLES];
+
+UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size)
+{
+ return g_Crc64Update(v, data, size, g_Crc64Table);
+}
+
+UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size)
+{
+ return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL;
+}
+
+void MY_FAST_CALL Crc64GenerateTable()
{
UInt32 i;
for (i = 0; i < 256; i++)
{
UInt64 r = i;
- int j;
+ unsigned j;
for (j = 0; j < 8; j++)
- r = (r >> 1) ^ ((UInt64)kCrc64Poly & ~((r & 1) - 1));
+ r = (r >> 1) ^ (kCrc64Poly & ~((r & 1) - 1));
g_Crc64Table[i] = r;
}
-}
+ for (; i < 256 * CRC_NUM_TABLES; i++)
+ {
+ UInt64 r = g_Crc64Table[i - 256];
+ g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8);
+ }
-UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size)
-{
- const Byte *p = (const Byte *)data;
- for (; size > 0 ; size--, p++)
- v = CRC64_UPDATE_BYTE(v, *p);
- return v;
-}
+ #ifdef MY_CPU_LE
-UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size)
-{
- return CRC64_GET_DIGEST(Crc64Update(CRC64_INIT_VAL, data, size));
+ g_Crc64Update = XzCrc64UpdateT4;
+
+
+
+
+
+
+ #else
+ {
+ #ifndef MY_CPU_BE
+ UInt32 k = 1;
+ if (*(const Byte *)&k == 1)
+ g_Crc64Update = XzCrc64UpdateT4;
+ else
+ #endif
+ {
+ for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
+ {
+ UInt64 x = g_Crc64Table[i - 256];
+ g_Crc64Table[i] = CRC_UINT64_SWAP(x);
+ }
+ g_Crc64Update = XzCrc64UpdateT1_BeT4;
+ }
+ }
+ #endif
}
diff --git a/src/libs/7zip/unix/C/XzCrc64.h b/src/libs/7zip/unix/C/XzCrc64.h
index 0e8efd7ea..08dbc330c 100644
--- a/src/libs/7zip/unix/C/XzCrc64.h
+++ b/src/libs/7zip/unix/C/XzCrc64.h
@@ -1,12 +1,12 @@
/* XzCrc64.h -- CRC64 calculation
-2010-04-16 : Igor Pavlov : Public domain */
+2013-01-18 : Igor Pavlov : Public domain */
#ifndef __XZ_CRC64_H
#define __XZ_CRC64_H
#include <stddef.h>
-#include "Types.h"
+#include "7zTypes.h"
EXTERN_C_BEGIN
diff --git a/src/libs/7zip/unix/C/XzCrc64Opt.c b/src/libs/7zip/unix/C/XzCrc64Opt.c
new file mode 100644
index 000000000..dccae1c19
--- /dev/null
+++ b/src/libs/7zip/unix/C/XzCrc64Opt.c
@@ -0,0 +1,69 @@
+/* XzCrc64Opt.c -- CRC64 calculation
+2011-06-28 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "CpuArch.h"
+
+#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+
+#ifndef MY_CPU_BE
+
+UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
+{
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ for (; size >= 4; size -= 4, p += 4)
+ {
+ UInt32 d = (UInt32)v ^ *(const UInt32 *)p;
+ v = (v >> 32) ^
+ table[0x300 + ((d ) & 0xFF)] ^
+ table[0x200 + ((d >> 8) & 0xFF)] ^
+ table[0x100 + ((d >> 16) & 0xFF)] ^
+ table[0x000 + ((d >> 24))];
+ }
+ for (; size > 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ return v;
+}
+
+#endif
+
+
+#ifndef MY_CPU_LE
+
+#define CRC_UINT64_SWAP(v) \
+ ((v >> 56) | \
+ ((v >> 40) & ((UInt64)0xFF << 8)) | \
+ ((v >> 24) & ((UInt64)0xFF << 16)) | \
+ ((v >> 8) & ((UInt64)0xFF << 24)) | \
+ ((v << 8) & ((UInt64)0xFF << 32)) | \
+ ((v << 24) & ((UInt64)0xFF << 40)) | \
+ ((v << 40) & ((UInt64)0xFF << 48)) | \
+ (v << 56))
+
+UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
+{
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ v = CRC_UINT64_SWAP(v);
+ table += 0x100;
+ for (; size >= 4; size -= 4, p += 4)
+ {
+ UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)p;
+ v = (v << 32) ^
+ table[0x000 + ((d ) & 0xFF)] ^
+ table[0x100 + ((d >> 8) & 0xFF)] ^
+ table[0x200 + ((d >> 16) & 0xFF)] ^
+ table[0x300 + ((d >> 24))];
+ }
+ table -= 0x100;
+ v = CRC_UINT64_SWAP(v);
+ for (; size > 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ return v;
+}
+
+#endif
diff --git a/src/libs/7zip/unix/C/XzDec.c b/src/libs/7zip/unix/C/XzDec.c
index 40f1a2a45..6eef587d3 100644
--- a/src/libs/7zip/unix/C/XzDec.c
+++ b/src/libs/7zip/unix/C/XzDec.c
@@ -1,5 +1,7 @@
/* XzDec.c -- Xz Decode
-2010-04-16 : Igor Pavlov : Public domain */
+2014-12-30 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
/* #define XZ_DUMP */
@@ -18,7 +20,8 @@
#include "Lzma2Dec.h"
#ifdef USE_SUBBLOCK
-#include "SbDec.h"
+#include "Bcj3Dec.c"
+#include "SbDec.c"
#endif
#include "Xz.h"
@@ -72,7 +75,6 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a
{
CBraState *p = ((CBraState *)pp);
alloc = alloc;
- p->encodeMode = 0;
p->ip = 0;
if (p->methodId == XZ_ID_Delta)
{
@@ -195,7 +197,7 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
return SZ_OK;
}
-SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
+SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc)
{
CBraState *decoder;
if (id != XZ_ID_Delta &&
@@ -207,10 +209,11 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
id != XZ_ID_SPARC)
return SZ_ERROR_UNSUPPORTED;
p->p = 0;
- decoder = alloc->Alloc(alloc, sizeof(CBraState));
+ decoder = (CBraState *)alloc->Alloc(alloc, sizeof(CBraState));
if (decoder == 0)
return SZ_ERROR_MEM;
decoder->methodId = (UInt32)id;
+ decoder->encodeMode = encodeMode;
p->p = decoder;
p->Free = BraState_Free;
p->SetProps = BraState_SetProps;
@@ -225,8 +228,8 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
static void SbState_Free(void *pp, ISzAlloc *alloc)
{
- CSubblockDec *p = (CSubblockDec *)pp;
- SubblockDec_Free(p, alloc);
+ CSbDec *p = (CSbDec *)pp;
+ SbDec_Free(p);
alloc->Free(alloc, pp);
}
@@ -240,24 +243,32 @@ static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAl
static void SbState_Init(void *pp)
{
- SubblockDec_Init((CSubblockDec *)pp);
+ SbDec_Init((CSbDec *)pp);
}
static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
{
- ECoderStatus status;
- SRes res = SubblockDec_Decode((CSubblockDec *)pp, dest, destLen, src, srcLen, finishMode, &status);
+ CSbDec *p = (CSbDec *)pp;
+ SRes res;
srcWasFinished = srcWasFinished;
- *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
+ p->dest = dest;
+ p->destLen = *destLen;
+ p->src = src;
+ p->srcLen = *srcLen;
+ p->finish = finishMode; /* change it */
+ res = SbDec_Decode((CSbDec *)pp);
+ *destLen -= p->destLen;
+ *srcLen -= p->srcLen;
+ *wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */
return res;
}
SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
{
- CSubblockDec *decoder;
+ CSbDec *decoder;
p->p = 0;
- decoder = alloc->Alloc(alloc, sizeof(CSubblockDec));
+ decoder = alloc->Alloc(alloc, sizeof(CSbDec));
if (decoder == 0)
return SZ_ERROR_MEM;
p->p = decoder;
@@ -265,7 +276,8 @@ SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
p->SetProps = SbState_SetProps;
p->Init = SbState_Init;
p->Code = SbState_Code;
- SubblockDec_Construct(decoder);
+ SbDec_Construct(decoder);
+ SbDec_SetAlloc(decoder, alloc);
return SZ_OK;
}
#endif
@@ -295,7 +307,7 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr
{
ELzmaStatus status;
/* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */
- SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, finishMode, &status);
+ SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status);
srcWasFinished = srcWasFinished;
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
return res;
@@ -303,7 +315,7 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr
static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
{
- CLzma2Dec *decoder = alloc->Alloc(alloc, sizeof(CLzma2Dec));
+ CLzma2Dec *decoder = (CLzma2Dec *)alloc->Alloc(alloc, sizeof(CLzma2Dec));
p->p = decoder;
if (decoder == 0)
return SZ_ERROR_MEM;
@@ -337,7 +349,10 @@ void MixCoder_Free(CMixCoder *p)
}
p->numCoders = 0;
if (p->buf)
+ {
p->alloc->Free(p->alloc, p->buf);
+ p->buf = 0; /* 9.31: the BUG was fixed */
+ }
}
void MixCoder_Init(CMixCoder *p)
@@ -369,7 +384,7 @@ SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)
}
if (coderIndex == 0)
return SZ_ERROR_UNSUPPORTED;
- return BraState_SetFromMethod(sc, methodId, p->alloc);
+ return BraState_SetFromMethod(sc, methodId, 0, p->alloc);
}
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
@@ -385,7 +400,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
if (p->buf == 0)
{
- p->buf = p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
+ p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
if (p->buf == 0)
return SZ_ERROR_MEM;
}
@@ -411,7 +426,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
const Byte *srcCur;
int srcFinishedCur;
int encodingWasFinished;
-
+
if (i == 0)
{
srcCur = src;
@@ -424,7 +439,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
srcLenCur = p->size[i - 1] - p->pos[i - 1];
srcFinishedCur = p->finished[i - 1];
}
-
+
if (i == p->numCoders - 1)
{
destCur = dest;
@@ -437,7 +452,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
destCur = p->buf + (CODER_BUF_SIZE * i);
destLenCur = CODER_BUF_SIZE;
}
-
+
res = coder->Code(coder->p, destCur, &destLenCur, srcCur, &srcLenCur, srcFinishedCur, finishMode, &encodingWasFinished);
if (!encodingWasFinished)
@@ -464,7 +479,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
p->pos[i] = 0;
p->finished[i] = encodingWasFinished;
}
-
+
if (res != SZ_OK)
return res;
@@ -587,13 +602,20 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
return SZ_OK;
}
-SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc)
+void XzUnpacker_Init(CXzUnpacker *p)
{
- MixCoder_Construct(&p->decoder, alloc);
p->state = XZ_STATE_STREAM_HEADER;
p->pos = 0;
- p->numStreams = 0;
- return SZ_OK;
+ p->numStartedStreams = 0;
+ p->numFinishedStreams = 0;
+ p->numTotalBlocks = 0;
+ p->padSize = 0;
+}
+
+void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc)
+{
+ MixCoder_Construct(&p->decoder, alloc);
+ XzUnpacker_Init(p);
}
void XzUnpacker_Free(CXzUnpacker *p)
@@ -602,7 +624,7 @@ void XzUnpacker_Free(CXzUnpacker *p)
}
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
- const Byte *src, SizeT *srcLen, int finishMode, ECoderStatus *status)
+ const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, ECoderStatus *status)
{
SizeT destLenOrig = *destLen;
SizeT srcLenOrig = *srcLen;
@@ -623,20 +645,20 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
*status = CODER_STATUS_NOT_FINISHED;
return SZ_OK;
}
-
+
res = MixCoder_Code(&p->decoder, dest, &destLen2, src, &srcLen2, False, finishMode, status);
XzCheck_Update(&p->check, dest, destLen2);
-
+
(*srcLen) += srcLen2;
src += srcLen2;
p->packSize += srcLen2;
-
+
(*destLen) += destLen2;
dest += destLen2;
p->unpackSize += destLen2;
-
+
RINOK(res);
-
+
if (*status == CODER_STATUS_FINISHED_WITH_MARK)
{
Byte temp[32];
@@ -645,14 +667,14 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
Sha256_Update(&p->sha, temp, num);
p->indexSize += num;
p->numBlocks++;
-
+
p->state = XZ_STATE_BLOCK_FOOTER;
p->pos = 0;
p->alignPos = 0;
}
else if (srcLen2 == 0 && destLen2 == 0)
return SZ_OK;
-
+
continue;
}
@@ -662,7 +684,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
return SZ_OK;
}
- switch(p->state)
+ switch (p->state)
{
case XZ_STATE_STREAM_HEADER:
{
@@ -676,6 +698,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
else
{
RINOK(Xz_ParseHeader(&p->streamFlags, p->buf));
+ p->numStartedStreams++;
p->state = XZ_STATE_BLOCK_HEADER;
Sha256_Init(&p->sha);
p->indexSize = 0;
@@ -716,6 +739,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
else
{
RINOK(XzBlock_Parse(&p->block, p->buf));
+ p->numTotalBlocks++;
p->state = XZ_STATE_BLOCK;
p->packSize = 0;
p->unpackSize = 0;
@@ -833,7 +857,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
if (p->pos == XZ_STREAM_FOOTER_SIZE)
{
p->state = XZ_STATE_STREAM_PADDING;
- p->numStreams++;
+ p->numFinishedStreams++;
p->padSize = 0;
if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf))
return SZ_ERROR_CRC;
@@ -858,7 +882,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
}
break;
}
-
+
case XZ_STATE_BLOCK: break; /* to disable GCC warning */
}
}
@@ -873,3 +897,13 @@ Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p)
{
return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0);
}
+
+UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p)
+{
+ UInt64 num = 0;
+ if (p->state == XZ_STATE_STREAM_PADDING)
+ num += p->padSize;
+ else if (p->state == XZ_STATE_STREAM_HEADER)
+ num += p->padSize + p->pos;
+ return num;
+}
diff --git a/src/libs/7zip/unix/C/XzEnc.c b/src/libs/7zip/unix/C/XzEnc.c
index 721b4e765..56680fcd8 100644
--- a/src/libs/7zip/unix/C/XzEnc.c
+++ b/src/libs/7zip/unix/C/XzEnc.c
@@ -1,5 +1,7 @@
/* XzEnc.c -- Xz Encode
-2009-06-04 : Igor Pavlov : Public domain */
+2014-12-30 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <stdlib.h>
#include <string.h>
@@ -9,7 +11,9 @@
#include "Bra.h"
#include "CpuArch.h"
#ifdef USE_SUBBLOCK
-#include "SbEnc.h"
+#include "Bcj3Enc.c"
+#include "SbFind.c"
+#include "SbEnc.c"
#endif
#include "XzEnc.h"
@@ -130,7 +134,7 @@ SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAll
CXzBlockSizes *blocks;
if (newSize / sizeof(CXzBlockSizes) != num)
return SZ_ERROR_MEM;
- blocks = alloc->Alloc(alloc, newSize);
+ blocks = (CXzBlockSizes *)alloc->Alloc(alloc, newSize);
if (blocks == 0)
return SZ_ERROR_MEM;
if (p->numBlocks != 0)
@@ -198,158 +202,147 @@ static size_t MyWrite(void *pp, const void *data, size_t size)
/* ---------- CSeqInFilter ---------- */
-/*
-typedef struct _IFilter
-{
- void *p;
- void (*Free)(void *p, ISzAlloc *alloc);
- SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc);
- void (*Init)(void *p);
- size_t (*Filter)(void *p, Byte *data, SizeT destLen);
-} IFilter;
-
-#define FILT_BUF_SIZE (1 << 19)
+#define FILTER_BUF_SIZE (1 << 20)
typedef struct
{
ISeqInStream p;
ISeqInStream *realStream;
- UInt32 x86State;
- UInt32 ip;
- UInt64 processed;
- CXzCheck check;
- Byte buf[FILT_BUF_SIZE];
- UInt32 bufferPos;
- UInt32 convertedPosBegin;
- UInt32 convertedPosEnd;
- IFilter *filter;
+ IStateCoder StateCoder;
+ Byte *buf;
+ size_t curPos;
+ size_t endPos;
+ int srcWasFinished;
} CSeqInFilter;
static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)
{
CSeqInFilter *p = (CSeqInFilter *)pp;
- size_t remSize = *size;
+ size_t sizeOriginal = *size;
+ if (sizeOriginal == 0)
+ return SZ_OK;
*size = 0;
-
- while (remSize > 0)
+ for (;;)
{
- int i;
- if (p->convertedPosBegin != p->convertedPosEnd)
+ if (!p->srcWasFinished && p->curPos == p->endPos)
{
- UInt32 sizeTemp = p->convertedPosEnd - p->convertedPosBegin;
- if (remSize < sizeTemp)
- sizeTemp = (UInt32)remSize;
- memmove(data, p->buf + p->convertedPosBegin, sizeTemp);
- p->convertedPosBegin += sizeTemp;
- data = (void *)((Byte *)data + sizeTemp);
- remSize -= sizeTemp;
- *size += sizeTemp;
- break;
+ p->curPos = 0;
+ p->endPos = FILTER_BUF_SIZE;
+ RINOK(p->realStream->Read(p->realStream, p->buf, &p->endPos));
+ if (p->endPos == 0)
+ p->srcWasFinished = 1;
}
- for (i = 0; p->convertedPosEnd + i < p->bufferPos; i++)
- p->buf[i] = p->buf[i + p->convertedPosEnd];
- p->bufferPos = i;
- p->convertedPosBegin = p->convertedPosEnd = 0;
{
- size_t processedSizeTemp = FILT_BUF_SIZE - p->bufferPos;
- RINOK(p->realStream->Read(p->realStream, p->buf + p->bufferPos, &processedSizeTemp));
- p->bufferPos = p->bufferPos + (UInt32)processedSizeTemp;
- }
- p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos);
- if (p->convertedPosEnd == 0)
- {
- if (p->bufferPos == 0)
- break;
- else
- {
- p->convertedPosEnd = p->bufferPos;
- continue;
- }
- }
- if (p->convertedPosEnd > p->bufferPos)
- {
- for (; p->bufferPos < p->convertedPosEnd; p->bufferPos++)
- p->buf[p->bufferPos] = 0;
- p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos);
+ SizeT srcLen = p->endPos - p->curPos;
+ int wasFinished;
+ SRes res;
+ *size = sizeOriginal;
+ res = p->StateCoder.Code(p->StateCoder.p, data, size, p->buf + p->curPos, &srcLen,
+ p->srcWasFinished, CODER_FINISH_ANY, &wasFinished);
+ p->curPos += srcLen;
+ if (*size != 0 || srcLen == 0 || res != 0)
+ return res;
}
}
+}
+
+static void SeqInFilter_Construct(CSeqInFilter *p)
+{
+ p->buf = NULL;
+ p->p.Read = SeqInFilter_Read;
+}
+
+static void SeqInFilter_Free(CSeqInFilter *p)
+{
+ if (p->buf)
+ {
+ g_Alloc.Free(&g_Alloc, p->buf);
+ p->buf = NULL;
+ }
+}
+
+SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc);
+
+static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props)
+{
+ if (!p->buf)
+ {
+ p->buf = g_Alloc.Alloc(&g_Alloc, FILTER_BUF_SIZE);
+ if (!p->buf)
+ return SZ_ERROR_MEM;
+ }
+ p->curPos = p->endPos = 0;
+ p->srcWasFinished = 0;
+ RINOK(BraState_SetFromMethod(&p->StateCoder, props->id, 1, &g_Alloc));
+ RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, &g_Alloc));
+ p->StateCoder.Init(p->StateCoder.p);
return SZ_OK;
}
-*/
-/*
+/* ---------- CSbEncInStream ---------- */
+
+#ifdef USE_SUBBLOCK
+
typedef struct
{
ISeqInStream p;
- ISeqInStream *realStream;
- CMixCoder mixCoder;
- Byte buf[FILT_BUF_SIZE];
- UInt32 bufPos;
- UInt32 bufSize;
-} CMixCoderSeqInStream;
+ ISeqInStream *inStream;
+ CSbEnc enc;
+} CSbEncInStream;
-static SRes CMixCoderSeqInStream_Read(void *pp, void *data, size_t *size)
+static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
{
- CMixCoderSeqInStream *p = (CMixCoderSeqInStream *)pp;
- SRes res = SZ_OK;
- size_t remSize = *size;
- *size = 0;
- while (remSize > 0)
+ CSbEncInStream *p = (CSbEncInStream *)pp;
+ size_t sizeOriginal = *size;
+ if (sizeOriginal == 0)
+ return S_OK;
+ for (;;)
{
- if (p->bufPos == p->bufSize)
- {
- size_t curSize;
- p->bufPos = p->bufSize = 0;
- if (*size != 0)
- break;
- curSize = FILT_BUF_SIZE;
- RINOK(p->realStream->Read(p->realStream, p->buf, &curSize));
- p->bufSize = (UInt32)curSize;
- }
+ if (p->enc.needRead && !p->enc.readWasFinished)
{
- SizeT destLen = remSize;
- SizeT srcLen = p->bufSize - p->bufPos;
- res = MixCoder_Code(&p->mixCoder, data, &destLen, p->buf + p->bufPos, &srcLen, 0);
- data = (void *)((Byte *)data + destLen);
- remSize -= destLen;
- *size += destLen;
- p->bufPos += srcLen;
+ size_t processed = p->enc.needReadSizeMax;
+ RINOK(p->inStream->Read(p->inStream, p->enc.buf + p->enc.readPos, &processed));
+ p->enc.readPos += processed;
+ if (processed == 0)
+ {
+ p->enc.readWasFinished = True;
+ p->enc.isFinalFinished = True;
+ }
+ p->enc.needRead = False;
}
+ *size = sizeOriginal;
+ RINOK(SbEnc_Read(&p->enc, data, size));
+ if (*size != 0 || !p->enc.needRead)
+ return S_OK;
}
- return res;
}
-*/
-#ifdef USE_SUBBLOCK
-typedef struct
+void SbEncInStream_Construct(CSbEncInStream *p, ISzAlloc *alloc)
{
- ISeqInStream p;
- CSubblockEnc sb;
- UInt64 processed;
-} CSbEncInStream;
+ SbEnc_Construct(&p->enc, alloc);
+ p->p.Read = SbEncInStream_Read;
+}
-void SbEncInStream_Init(CSbEncInStream *p)
+SRes SbEncInStream_Init(CSbEncInStream *p)
{
- p->processed = 0;
- SubblockEnc_Init(&p->sb);
+ return SbEnc_Init(&p->enc);
}
-static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
+void SbEncInStream_Free(CSbEncInStream *p)
{
- CSbEncInStream *p = (CSbEncInStream *)pp;
- SRes res = SubblockEnc_Read(&p->sb, data, size);
- p->processed += *size;
- return res;
+ SbEnc_Free(&p->enc);
}
+
#endif
+
typedef struct
{
- /* CMixCoderSeqInStream inStream; */
CLzma2EncHandle lzma2;
#ifdef USE_SUBBLOCK
CSbEncInStream sb;
#endif
+ CSeqInFilter filter;
ISzAlloc *alloc;
ISzAlloc *bigAlloc;
} CLzma2WithFilters;
@@ -361,9 +354,9 @@ static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, IS
p->bigAlloc = bigAlloc;
p->lzma2 = NULL;
#ifdef USE_SUBBLOCK
- p->sb.p.Read = SbEncInStream_Read;
- SubblockEnc_Construct(&p->sb.sb, p->alloc);
+ SbEncInStream_Construct(&p->sb, alloc);
#endif
+ SeqInFilter_Construct(&p->filter);
}
static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
@@ -376,8 +369,9 @@ static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
{
+ SeqInFilter_Free(&p->filter);
#ifdef USE_SUBBLOCK
- SubblockEnc_Free(&p->sb.sb);
+ SbEncInStream_Free(&p->sb);
#endif
if (p->lzma2)
{
@@ -386,17 +380,28 @@ static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
}
}
-static SRes Xz_Compress(CXzStream *xz,
- CLzma2WithFilters *lzmaf,
- ISeqOutStream *outStream,
- ISeqInStream *inStream,
- const CLzma2EncProps *lzma2Props,
- Bool useSubblock,
- ICompressProgress *progress)
+void XzProps_Init(CXzProps *p)
+{
+ p->lzma2Props = 0;
+ p->filterProps = 0;
+ p->checkId = XZ_CHECK_CRC32;
+}
+
+void XzFilterProps_Init(CXzFilterProps *p)
{
- xz->flags = XZ_CHECK_CRC32;
+ p->id = 0;
+ p->delta = 0;
+ p->ip= 0;
+ p->ipDefined = False;
+}
+
+static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
+ ISeqOutStream *outStream, ISeqInStream *inStream,
+ const CXzProps *props, ICompressProgress *progress)
+{
+ xz->flags = (Byte)props->checkId;
- RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, lzma2Props));
+ RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, props->lzma2Props));
RINOK(Xz_WriteHeader(xz->flags, outStream));
{
@@ -404,15 +409,27 @@ static SRes Xz_Compress(CXzStream *xz,
CSeqSizeOutStream seqSizeOutStream;
CXzBlock block;
int filterIndex = 0;
-
+ CXzFilter *filter = NULL;
+ const CXzFilterProps *fp = props->filterProps;
+
XzBlock_ClearFlags(&block);
- XzBlock_SetNumFilters(&block, 1 + (useSubblock ? 1 : 0));
-
- if (useSubblock)
+ XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0));
+
+ if (fp)
{
- CXzFilter *f = &block.filters[filterIndex++];
- f->id = XZ_ID_Subblock;
- f->propsSize = 0;
+ filter = &block.filters[filterIndex++];
+ filter->id = fp->id;
+ filter->propsSize = 0;
+ if (fp->id == XZ_ID_Delta)
+ {
+ filter->props[0] = (Byte)(fp->delta - 1);
+ filter->propsSize = 1;
+ }
+ else if (fp->ipDefined)
+ {
+ SetUi32(filter->props, fp->ip);
+ filter->propsSize = 4;
+ }
}
{
@@ -425,27 +442,37 @@ static SRes Xz_Compress(CXzStream *xz,
seqSizeOutStream.p.Write = MyWrite;
seqSizeOutStream.realStream = outStream;
seqSizeOutStream.processed = 0;
-
+
RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p));
-
+
checkInStream.p.Read = SeqCheckInStream_Read;
checkInStream.realStream = inStream;
SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags));
-
- #ifdef USE_SUBBLOCK
- if (useSubblock)
+
+ if (fp)
{
- lzmaf->sb.sb.inStream = &checkInStream.p;
- SubblockEnc_Init(&lzmaf->sb.sb);
+ #ifdef USE_SUBBLOCK
+ if (fp->id == XZ_ID_Subblock)
+ {
+ lzmaf->sb.inStream = &checkInStream.p;
+ RINOK(SbEncInStream_Init(&lzmaf->sb));
+ }
+ else
+ #endif
+ {
+ lzmaf->filter.realStream = &checkInStream.p;
+ RINOK(SeqInFilter_Init(&lzmaf->filter, filter));
+ }
}
- #endif
-
+
{
UInt64 packPos = seqSizeOutStream.processed;
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
+ fp ?
#ifdef USE_SUBBLOCK
- useSubblock ? &lzmaf->sb.p:
+ (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
#endif
+ &lzmaf->filter.p:
&checkInStream.p,
progress);
RINOK(res);
@@ -467,8 +494,7 @@ static SRes Xz_Compress(CXzStream *xz,
}
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
- const CLzma2EncProps *lzma2Props, Bool useSubblock,
- ICompressProgress *progress)
+ const CXzProps *props, ICompressProgress *progress)
{
SRes res;
CXzStream xz;
@@ -477,8 +503,7 @@ SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
Lzma2WithFilters_Construct(&lzmaf, &g_Alloc, &g_BigAlloc);
res = Lzma2WithFilters_Create(&lzmaf);
if (res == SZ_OK)
- res = Xz_Compress(&xz, &lzmaf, outStream, inStream,
- lzma2Props, useSubblock, progress);
+ res = Xz_Compress(&xz, &lzmaf, outStream, inStream, props, progress);
Lzma2WithFilters_Free(&lzmaf);
Xz_Free(&xz, &g_Alloc);
return res;
diff --git a/src/libs/7zip/unix/C/XzEnc.h b/src/libs/7zip/unix/C/XzEnc.h
index 13390df8b..c3c19eca0 100644
--- a/src/libs/7zip/unix/C/XzEnc.h
+++ b/src/libs/7zip/unix/C/XzEnc.h
@@ -1,5 +1,5 @@
/* XzEnc.h -- Xz Encode
-2009-04-15 : Igor Pavlov : Public domain */
+2011-02-07 : Igor Pavlov : Public domain */
#ifndef __XZ_ENC_H
#define __XZ_ENC_H
@@ -8,18 +8,32 @@
#include "Xz.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
+
+typedef struct
+{
+ UInt32 id;
+ UInt32 delta;
+ UInt32 ip;
+ int ipDefined;
+} CXzFilterProps;
+
+void XzFilterProps_Init(CXzFilterProps *p);
+
+typedef struct
+{
+ const CLzma2EncProps *lzma2Props;
+ const CXzFilterProps *filterProps;
+ unsigned checkId;
+} CXzProps;
+
+void XzProps_Init(CXzProps *p);
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
- const CLzma2EncProps *lzma2Props, Bool useSubblock,
- ICompressProgress *progress);
+ const CXzProps *props, ICompressProgress *progress);
SRes Xz_EncodeEmpty(ISeqOutStream *outStream);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/src/libs/7zip/unix/C/XzIn.c b/src/libs/7zip/unix/C/XzIn.c
index f8ea86315..ed9eac31a 100644
--- a/src/libs/7zip/unix/C/XzIn.c
+++ b/src/libs/7zip/unix/C/XzIn.c
@@ -1,5 +1,7 @@
/* XzIn.c - Xz input
-2009-06-19 : Igor Pavlov : Public domain */
+2014-12-30 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <string.h>
@@ -70,7 +72,7 @@ SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream)
static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc)
{
- size_t i, numBlocks, crcStartPos, pos = 1;
+ size_t i, numBlocks, pos = 1;
UInt32 crc;
if (size < 5 || buf[0] != 0)
@@ -88,8 +90,7 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *
if (numBlocks != numBlocks64 || numBlocks * 2 > size)
return SZ_ERROR_ARCHIVE;
}
-
- crcStartPos = pos;
+
Xz_Free(p, alloc);
if (numBlocks != 0)
{
@@ -149,44 +150,43 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
RINOK(SeekFromCur(stream, startOffset));
RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
-
+
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
{
- Int64 i = 0;
+ UInt32 total = 0;
*startOffset += XZ_STREAM_FOOTER_SIZE;
for (;;)
{
- int j;
- size_t processedSize;
+ size_t i;
#define TEMP_BUF_SIZE (1 << 10)
Byte tempBuf[TEMP_BUF_SIZE];
- if (*startOffset < XZ_STREAM_FOOTER_SIZE || i > (1 << 16))
+ if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
return SZ_ERROR_NO_ARCHIVE;
- processedSize = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
- i += processedSize;
- *startOffset = -(Int64)processedSize;
+ i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
+ total += (UInt32)i;
+ *startOffset = -(Int64)i;
RINOK(SeekFromCur(stream, startOffset));
- RINOK(LookInStream_Read2(stream, tempBuf, processedSize, SZ_ERROR_NO_ARCHIVE));
- for (j = (int)processedSize; j >= 1; j--) // FIXED j >= 0 => j >= 1
- if (tempBuf[j -1] != 0)
+ RINOK(LookInStream_Read2(stream, tempBuf, i, SZ_ERROR_NO_ARCHIVE));
+ for (; i != 0; i--)
+ if (tempBuf[i - 1] != 0)
break;
- if (j != 0)
+ if (i != 0)
{
- if ((j & 3) != 0)
- return SZ_ERROR_NO_ARCHIVE;
- *startOffset += j;
- if (*startOffset < XZ_STREAM_FOOTER_SIZE)
- return SZ_ERROR_NO_ARCHIVE;
- *startOffset -= XZ_STREAM_FOOTER_SIZE;
- RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
- RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
- if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
+ if ((i & 3) != 0)
return SZ_ERROR_NO_ARCHIVE;
+ *startOffset += i;
break;
}
}
+ if (*startOffset < XZ_STREAM_FOOTER_SIZE)
+ return SZ_ERROR_NO_ARCHIVE;
+ *startOffset -= XZ_STREAM_FOOTER_SIZE;
+ RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
+ RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
+ if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
+ return SZ_ERROR_NO_ARCHIVE;
}
-
+
p->flags = (CXzStreamFlags)GetBe16(buf + 8);
if (!XzFlags_IsSupported(p->flags))
@@ -291,7 +291,8 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompr
if (data == 0)
return SZ_ERROR_MEM;
p->numAllocated = newNum;
- memcpy(data, p->streams, p->num * sizeof(CXzStream));
+ if (p->num != 0)
+ memcpy(data, p->streams, p->num * sizeof(CXzStream));
alloc->Free(alloc, p->streams);
p->streams = (CXzStream *)data;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/7zip.pri b/src/libs/7zip/unix/CPP/7zip/7zip.pri
new file mode 100644
index 000000000..a2b70a1f2
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/7zip.pri
@@ -0,0 +1,6 @@
+HEADERS += $$7ZIP_BASE/CPP/7zip/ICoder.h \
+ $$7ZIP_BASE/CPP/7zip/IDecl.h \
+ $$7ZIP_BASE/CPP/7zip/IPassword.h \
+ $$7ZIP_BASE/CPP/7zip/IProgress.h \
+ $$7ZIP_BASE/CPP/7zip/IStream.h \
+ $$7ZIP_BASE/CPP/7zip/PropID.h
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7z.pri b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7z.pri
new file mode 100644
index 000000000..60211faae
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7z.pri
@@ -0,0 +1,29 @@
+HEADERS += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zCompressionMode.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zDecode.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zEncode.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zFolderInStream.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zFolderOutStream.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHandler.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHeader.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zIn.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zItem.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zOut.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zProperties.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zSpecStream.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zUpdate.h
+
+SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zDecode.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zEncode.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zExtract.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zFolderInStream.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zFolderOutStream.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHandler.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHandlerOut.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHeader.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zIn.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zOut.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zProperties.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zRegister.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zSpecStream.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/7zUpdate.cpp
+
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zCompressionMode.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zCompressionMode.cpp
deleted file mode 100644
index 6774fc482..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zCompressionMode.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-// CompressionMethod.cpp
-
-#include "StdAfx.h"
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zCompressionMode.h b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zCompressionMode.h
index 55bbc68ee..5cde97c38 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zCompressionMode.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zCompressionMode.h
@@ -3,19 +3,18 @@
#ifndef __7Z_COMPRESSION_MODE_H
#define __7Z_COMPRESSION_MODE_H
-#include "../../../Common/MyString.h"
-
-#include "../../../Windows/PropVariant.h"
-
+#include "../../Common/MethodId.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
namespace N7z {
-struct CMethodFull: public CMethod
+struct CMethodFull: public CProps
{
+ CMethodId Id;
UInt32 NumInStreams;
UInt32 NumOutStreams;
+
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
};
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.cpp
index 425a34157..973966bd3 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.cpp
@@ -16,29 +16,33 @@ static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
CBindInfoEx &bindInfo)
{
bindInfo.Clear();
- int i;
+ bindInfo.BindPairs.ClearAndSetSize(folder.BindPairs.Size());
+ unsigned i;
for (i = 0; i < folder.BindPairs.Size(); i++)
{
- NCoderMixer::CBindPair bindPair;
+ NCoderMixer::CBindPair &bindPair = bindInfo.BindPairs[i];
bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;
bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;
- bindInfo.BindPairs.Add(bindPair);
}
+
+ bindInfo.Coders.ClearAndSetSize(folder.Coders.Size());
+ bindInfo.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size());
+
UInt32 outStreamIndex = 0;
for (i = 0; i < folder.Coders.Size(); i++)
{
- NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
+ NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
const CCoderInfo &coderInfo = folder.Coders[i];
coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams;
coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams;
- bindInfo.Coders.Add(coderStreamsInfo);
- bindInfo.CoderMethodIDs.Add(coderInfo.MethodID);
+ bindInfo.CoderMethodIDs[i] = coderInfo.MethodID;
for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)
if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
bindInfo.OutStreams.Add(outStreamIndex);
}
+ bindInfo.InStreams.ClearAndSetSize(folder.PackStreams.Size());
for (i = 0; i < folder.PackStreams.Size(); i++)
- bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);
+ bindInfo.InStreams[i] = (UInt32)folder.PackStreams[i];
}
static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1,
@@ -58,7 +62,7 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
{
if (a1.Coders.Size() != a2.Coders.Size())
return false;
- int i;
+ unsigned i;
for (i = 0; i < a1.Coders.Size(); i++)
if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))
return false;
@@ -90,46 +94,50 @@ HRESULT CDecoder::Decode(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
UInt64 startPos,
- const UInt64 *packSizes,
- const CFolder &folderInfo,
+ const CFolders &folders, int folderIndex,
ISequentialOutStream *outStream,
ICompressProgressInfo *compressProgress
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS_DECL
#if !defined(_7ZIP_ST) && !defined(_SFX)
, bool mtMode, UInt32 numThreads
#endif
)
{
- if (!folderInfo.CheckStructure())
+ const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]];
+ CFolder folderInfo;
+ folders.ParseFolderInfo(folderIndex, folderInfo);
+
+ if (!folderInfo.CheckStructure(folders.GetNumFolderUnpackSizes(folderIndex)))
return E_NOTIMPL;
+
+ /*
+ We don't need to init isEncrypted and passwordIsDefined
+ We must upgrade them only
#ifndef _NO_CRYPTO
+ isEncrypted = false;
passwordIsDefined = false;
#endif
+ */
+
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
-
+
CLockedInStream lockedInStream;
lockedInStream.Init(inStream);
-
- for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
+
+ for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++)
{
- CLockedSequentialInStreamImp *lockedStreamImpSpec = new
- CLockedSequentialInStreamImp;
+ CLockedSequentialInStreamImp *lockedStreamImpSpec = new CLockedSequentialInStreamImp;
CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
- lockedStreamImpSpec->Init(&lockedInStream, startPos);
- startPos += packSizes[j];
-
- CLimitedSequentialInStream *streamSpec = new
- CLimitedSequentialInStream;
+ lockedStreamImpSpec->Init(&lockedInStream, startPos + packPositions[j]);
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream = streamSpec;
streamSpec->SetStream(lockedStreamImp);
- streamSpec->Init(packSizes[j]);
+ streamSpec->Init(packPositions[j + 1] - packPositions[j]);
inStreams.Add(inStream);
}
-
- int numCoders = folderInfo.Coders.Size();
-
+
+ unsigned numCoders = folderInfo.Coders.Size();
+
CBindInfoEx bindInfo;
ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
bool createNewCoders;
@@ -139,10 +147,10 @@ HRESULT CDecoder::Decode(
createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
if (createNewCoders)
{
- int i;
+ unsigned i;
_decoders.Clear();
// _decoders2.Clear();
-
+
_mixerCoder.Release();
if (_multiThread)
@@ -160,12 +168,12 @@ HRESULT CDecoder::Decode(
#endif
}
RINOK(_mixerCoderCommon->SetBindInfo(bindInfo));
-
+
for (i = 0; i < numCoders; i++)
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
-
+
CMyComPtr<ICompressCoder> decoder;
CMyComPtr<ICompressCoder2> decoder2;
RINOK(CreateCoder(
@@ -178,7 +186,7 @@ HRESULT CDecoder::Decode(
return E_NOTIMPL;
decoderUnknown = (IUnknown *)decoder;
-
+
if (_multiThread)
_mixerCoderMTSpec->AddCoder(decoder);
#ifdef _ST_MODE
@@ -204,32 +212,34 @@ HRESULT CDecoder::Decode(
decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
if (setCompressCodecsInfo)
{
- RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
}
#endif
}
_bindInfoExPrev = bindInfo;
_bindInfoExPrevIsDefined = true;
}
- int i;
+ unsigned i;
_mixerCoderCommon->ReInit();
-
- UInt32 packStreamIndex = 0, unpackStreamIndex = 0;
+
+ UInt32 packStreamIndex = 0;
+ UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex];
+ UInt32 unpackStreamIndex = unpackStreamIndexStart;
UInt32 coderIndex = 0;
// UInt32 coder2Index = 0;
-
+
for (i = 0; i < numCoders; i++)
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
-
+
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
if (setDecoderProperties)
{
const CByteBuffer &props = coderInfo.Props;
- size_t size = props.GetCapacity();
+ size_t size = props.Size();
if (size > 0xFFFFFFFF)
return E_NOTIMPL;
// if (size > 0)
@@ -257,56 +267,55 @@ HRESULT CDecoder::Decode(
decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
if (cryptoSetPassword)
{
- if (getTextPassword == 0)
- return E_FAIL;
+ isEncrypted = true;
+ if (!getTextPassword)
+ return E_NOTIMPL;
CMyComBSTR passwordBSTR;
RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
- CByteBuffer buffer;
passwordIsDefined = true;
- const UString password(passwordBSTR);
- const UInt32 sizeInBytes = password.Length() * 2;
- buffer.SetCapacity(sizeInBytes);
- for (int i = 0; i < password.Length(); i++)
+ size_t len = 0;
+ if (passwordBSTR)
+ len = MyStringLen((BSTR)passwordBSTR);
+ CByteBuffer buffer(len * 2);
+ for (size_t i = 0; i < len; i++)
{
- wchar_t c = password[i];
+ wchar_t c = passwordBSTR[i];
((Byte *)buffer)[i * 2] = (Byte)c;
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
}
- RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
+ RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size()));
}
}
#endif
coderIndex++;
-
+
UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
- CRecordVector<const UInt64 *> packSizesPointers;
- CRecordVector<const UInt64 *> unpackSizesPointers;
- packSizesPointers.Reserve(numInStreams);
- unpackSizesPointers.Reserve(numOutStreams);
+ CObjArray<UInt64> packSizes(numInStreams);
+ CObjArray<const UInt64 *> packSizesPointers(numInStreams);
+ CObjArray<const UInt64 *> unpackSizesPointers(numOutStreams);
UInt32 j;
+
for (j = 0; j < numOutStreams; j++, unpackStreamIndex++)
- unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]);
-
+ unpackSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndex];
+
for (j = 0; j < numInStreams; j++, packStreamIndex++)
{
int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
if (bindPairIndex >= 0)
- packSizesPointers.Add(
- &folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
+ packSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndexStart + (UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex];
else
{
int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
if (index < 0)
- return E_FAIL;
- packSizesPointers.Add(&packSizes[index]);
+ return S_FALSE; // check it
+ packSizes[j] = packPositions[index + 1] - packPositions[index];
+ packSizesPointers[j] = &packSizes[j];
}
}
-
- _mixerCoderCommon->SetCoderInfo(i,
- &packSizesPointers.Front(),
- &unpackSizesPointers.Front());
+
+ _mixerCoderCommon->SetCoderInfo(i, packSizesPointers, unpackSizesPointers);
}
UInt32 mainCoder, temp;
bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
@@ -317,16 +326,18 @@ HRESULT CDecoder::Decode(
else
_mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
*/
-
+
if (numCoders == 0)
return 0;
- CRecordVector<ISequentialInStream *> inStreamPointers;
- inStreamPointers.Reserve(inStreams.Size());
- for (i = 0; i < inStreams.Size(); i++)
- inStreamPointers.Add(inStreams[i]);
+ unsigned num = inStreams.Size();
+ CObjArray<ISequentialInStream *> inStreamPointers(num);
+ for (i = 0; i < num; i++)
+ inStreamPointers[i] = inStreams[i];
ISequentialOutStream *outStreamPointer = outStream;
- return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
- inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
+ return _mixerCoder->Code(
+ inStreamPointers, NULL, num,
+ &outStreamPointer, NULL, 1,
+ compressProgress);
}
}}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.h b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.h
index d8a424a36..54e9d2b52 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.h
@@ -14,7 +14,7 @@
#include "../../Common/CreateCoder.h"
-#include "7zItem.h"
+#include "7zIn.h"
namespace NArchive {
namespace N7z {
@@ -33,14 +33,14 @@ class CDecoder
{
bool _bindInfoExPrevIsDefined;
CBindInfoEx _bindInfoExPrev;
-
+
bool _multiThread;
#ifdef _ST_MODE
NCoderMixer::CCoderMixer2ST *_mixerCoderSTSpec;
#endif
NCoderMixer::CCoderMixer2MT *_mixerCoderMTSpec;
NCoderMixer::CCoderMixer2 *_mixerCoderCommon;
-
+
CMyComPtr<ICompressCoder2> _mixerCoder;
CObjectVector<CMyComPtr<IUnknown> > _decoders;
// CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
@@ -50,13 +50,10 @@ public:
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
UInt64 startPos,
- const UInt64 *packSizes,
- const CFolder &folder,
+ const CFolders &folders, int folderIndex,
ISequentialOutStream *outStream,
ICompressProgressInfo *compressProgress
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPasswordSpec, bool &passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS_DECL
#if !defined(_7ZIP_ST) && !defined(_SFX)
, bool mtMode, UInt32 numThreads
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zEncode.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zEncode.cpp
index 87996bc0e..5f1436fc7 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zEncode.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zEncode.cpp
@@ -23,30 +23,39 @@ static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindIn
const CRecordVector<CMethodId> decompressionMethods,
CFolder &folder)
{
- folder.Coders.Clear();
// bindInfo.CoderMethodIDs.Clear();
// folder.OutStreams.Clear();
- folder.PackStreams.Clear();
- folder.BindPairs.Clear();
- int i;
+ folder.BindPairs.SetSize(bindInfo.BindPairs.Size());
+ unsigned i;
for (i = 0; i < bindInfo.BindPairs.Size(); i++)
{
- CBindPair bindPair;
- bindPair.InIndex = bindInfo.BindPairs[i].InIndex;
- bindPair.OutIndex = bindInfo.BindPairs[i].OutIndex;
- folder.BindPairs.Add(bindPair);
+ CBindPair &bp = folder.BindPairs[i];
+ const NCoderMixer::CBindPair &mixerBp = bindInfo.BindPairs[i];
+ bp.InIndex = mixerBp.InIndex;
+ bp.OutIndex = mixerBp.OutIndex;
}
+ folder.Coders.SetSize(bindInfo.Coders.Size());
for (i = 0; i < bindInfo.Coders.Size(); i++)
{
- CCoderInfo coderInfo;
+ CCoderInfo &coderInfo = folder.Coders[i];
const NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;
coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;
coderInfo.MethodID = decompressionMethods[i];
- folder.Coders.Add(coderInfo);
+ // coderInfo.Props can be nonFree;
}
+ folder.PackStreams.SetSize(bindInfo.InStreams.Size());
for (i = 0; i < bindInfo.InStreams.Size(); i++)
- folder.PackStreams.Add(bindInfo.InStreams[i]);
+ folder.PackStreams[i] = bindInfo.InStreams[i];
+}
+
+static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder)
+{
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
+ if (setCoderProperties)
+ return props.SetCoderProps(setCoderProperties, dataSizeReduce);
+ return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK;
}
HRESULT CEncoder::CreateMixerCoder(
@@ -56,15 +65,14 @@ HRESULT CEncoder::CreateMixerCoder(
_mixerCoderSpec = new NCoderMixer::CCoderMixer2MT;
_mixerCoder = _mixerCoderSpec;
RINOK(_mixerCoderSpec->SetBindInfo(_bindInfo));
- for (int i = 0; i < _options.Methods.Size(); i++)
+ FOR_VECTOR (i, _options.Methods)
{
const CMethodFull &methodFull = _options.Methods[i];
- _codersInfo.Add(CCoderInfo());
- CCoderInfo &encodingInfo = _codersInfo.Back();
+ CCoderInfo &encodingInfo = _codersInfo.AddNew();
encodingInfo.MethodID = methodFull.Id;
CMyComPtr<ICompressCoder> encoder;
CMyComPtr<ICompressCoder2> encoder2;
-
+
RINOK(CreateCoder(
EXTERNAL_CODECS_LOC_VARS
@@ -74,7 +82,7 @@ HRESULT CEncoder::CreateMixerCoder(
return E_FAIL;
CMyComPtr<IUnknown> encoderCommon = encoder ? (IUnknown *)encoder : (IUnknown *)encoder2;
-
+
#ifndef _7ZIP_ST
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
@@ -85,14 +93,13 @@ HRESULT CEncoder::CreateMixerCoder(
}
}
#endif
-
- RINOK(SetMethodProperties(methodFull, inSizeForReduce, encoderCommon));
+ RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon));
/*
CMyComPtr<ICryptoResetSalt> resetSalt;
encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt);
- if (resetSalt != NULL)
+ if (resetSalt)
{
resetSalt->ResetSalt();
}
@@ -103,19 +110,18 @@ HRESULT CEncoder::CreateMixerCoder(
encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
if (setCompressCodecsInfo)
{
- RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
}
#endif
-
+
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
if (cryptoSetPassword)
{
- CByteBuffer buffer;
- const UInt32 sizeInBytes = _options.Password.Length() * 2;
- buffer.SetCapacity(sizeInBytes);
- for (int i = 0; i < _options.Password.Length(); i++)
+ const UInt32 sizeInBytes = _options.Password.Len() * 2;
+ CByteBuffer buffer(sizeInBytes);
+ for (unsigned i = 0; i < _options.Password.Len(); i++)
{
wchar_t c = _options.Password[i];
((Byte *)buffer)[i * 2] = (Byte)c;
@@ -137,13 +143,15 @@ HRESULT CEncoder::Encode(
ISequentialInStream *inStream,
const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
CFolder &folderItem,
+ CRecordVector<UInt64> &coderUnpackSizes,
+ UInt64 &unpackSize,
ISequentialOutStream *outStream,
CRecordVector<UInt64> &packSizes,
ICompressProgressInfo *compressProgress)
{
RINOK(EncoderConstr());
- if (_mixerCoderSpec == NULL)
+ if (!_mixerCoderSpec)
{
RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
}
@@ -153,13 +161,13 @@ HRESULT CEncoder::Encode(
CObjectVector<CInOutTempBuffer> inOutTempBuffers;
CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
- int numMethods = _bindInfo.Coders.Size();
- int i;
+ unsigned numMethods = _bindInfo.Coders.Size();
+ unsigned i;
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
{
- inOutTempBuffers.Add(CInOutTempBuffer());
- inOutTempBuffers.Back().Create();
- inOutTempBuffers.Back().InitWriting();
+ CInOutTempBuffer &iotb = inOutTempBuffers.AddNew();
+ iotb.Create();
+ iotb.InitWriting();
}
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
{
@@ -177,8 +185,8 @@ HRESULT CEncoder::Encode(
return E_FAIL;
UInt32 mainCoderIndex, mainStreamIndex;
_bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
-
- if (inStreamSize != NULL)
+
+ if (inStreamSize)
{
CRecordVector<const UInt64 *> sizePointers;
for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
@@ -189,40 +197,47 @@ HRESULT CEncoder::Encode(
_mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
}
-
+
// UInt64 outStreamStartPos;
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
-
+
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
- CSequentialOutStreamSizeCount *outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
- CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
+ CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL;
+ CMyComPtr<ISequentialOutStream> outStreamSizeCount;
inStreamSizeCountSpec->Init(inStream);
- outStreamSizeCountSpec->SetStream(outStream);
- outStreamSizeCountSpec->Init();
CRecordVector<ISequentialInStream *> inStreamPointers;
CRecordVector<ISequentialOutStream *> outStreamPointers;
inStreamPointers.Add(inStreamSizeCount);
- outStreamPointers.Add(outStreamSizeCount);
+
+ if (_bindInfo.OutStreams.Size() != 0)
+ {
+ outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
+ outStreamSizeCount = outStreamSizeCountSpec;
+ outStreamSizeCountSpec->SetStream(outStream);
+ outStreamSizeCountSpec->Init();
+ outStreamPointers.Add(outStreamSizeCount);
+ }
+
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
outStreamPointers.Add(tempBuffers[i - 1]);
for (i = 0; i < _codersInfo.Size(); i++)
{
CCoderInfo &encodingInfo = _codersInfo[i];
-
+
CMyComPtr<ICryptoResetInitVector> resetInitVector;
_mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
- if (resetInitVector != NULL)
+ if (resetInitVector)
{
resetInitVector->ResetInitVector();
}
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
_mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
- if (writeCoderProperties != NULL)
+ if (writeCoderProperties)
{
CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
@@ -242,33 +257,38 @@ HRESULT CEncoder::Encode(
}
_mixerCoderSpec->SetProgressCoderIndex(progressIndex);
-
+
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
-
+
ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem);
-
- packSizes.Add(outStreamSizeCountSpec->GetSize());
-
+
+ if (_bindInfo.OutStreams.Size() != 0)
+ packSizes.Add(outStreamSizeCountSpec->GetSize());
+
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
{
CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
RINOK(inOutTempBuffer.WriteToStream(outStream));
packSizes.Add(inOutTempBuffer.GetDataSize());
}
-
+
+ unpackSize = 0;
for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
{
int binder = _bindInfo.FindBinderForInStream(
_bindReverseConverter->DestOutToSrcInMap[i]);
UInt64 streamSize;
if (binder < 0)
+ {
streamSize = inStreamSizeCountSpec->GetSize();
+ unpackSize = streamSize;
+ }
else
streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
- folderItem.UnpackSizes.Add(streamSize);
+ coderUnpackSizes.Add(streamSize);
}
- for (i = numMethods - 1; i >= 0; i--)
+ for (i = 0; i < numMethods; i++)
folderItem.Coders[numMethods - 1 - i].Props = _codersInfo[i].Props;
return S_OK;
}
@@ -298,16 +318,16 @@ HRESULT CEncoder::EncoderConstr()
throw 1;
NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
CMethodFull method;
-
+
method.NumInStreams = 1;
method.NumOutStreams = 1;
coderStreamsInfo.NumInStreams = 1;
coderStreamsInfo.NumOutStreams = 1;
method.Id = k_AES;
-
+
_options.Methods.Add(method);
_bindInfo.Coders.Add(coderStreamsInfo);
-
+
_bindInfo.InStreams.Add(0);
_bindInfo.OutStreams.Add(0);
}
@@ -315,7 +335,7 @@ HRESULT CEncoder::EncoderConstr()
{
UInt32 numInStreams = 0, numOutStreams = 0;
- int i;
+ unsigned i;
for (i = 0; i < _options.Methods.Size(); i++)
{
const CMethodFull &methodFull = _options.Methods[i];
@@ -331,12 +351,12 @@ HRESULT CEncoder::EncoderConstr()
bindPair.OutIndex = numOutStreams;
_bindInfo.BindPairs.Add(bindPair);
}
- else
+ else if (coderStreamsInfo.NumOutStreams != 0)
_bindInfo.OutStreams.Insert(0, numOutStreams);
for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
_bindInfo.OutStreams.Add(numOutStreams + j);
}
-
+
numInStreams += coderStreamsInfo.NumInStreams;
numOutStreams += coderStreamsInfo.NumOutStreams;
@@ -390,7 +410,7 @@ HRESULT CEncoder::EncoderConstr()
if (_options.PasswordIsDefined)
{
- int numCryptoStreams = _bindInfo.OutStreams.Size();
+ unsigned numCryptoStreams = _bindInfo.OutStreams.Size();
for (i = 0; i < numCryptoStreams; i++)
{
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zEncode.h b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zEncode.h
index 4909a6e89..8e20bdb5f 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zEncode.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zEncode.h
@@ -45,6 +45,8 @@ public:
ISequentialInStream *inStream,
const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
CFolder &folderItem,
+ CRecordVector<UInt64> &coderUnpackSizes,
+ UInt64 &unpackSize,
ISequentialOutStream *outStream,
CRecordVector<UInt64> &packSizes,
ICompressProgressInfo *compressProgress);
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zExtract.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zExtract.cpp
index d55f38e13..bb350455c 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zExtract.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zExtract.cpp
@@ -37,8 +37,8 @@ struct CExtractFolderInfo
{
if (fileIndex != kNumNoIndex)
{
- ExtractStatuses.Reserve(1);
- ExtractStatuses.Add(true);
+ ExtractStatuses.ClearAndSetSize(1);
+ ExtractStatuses[0] = true;
}
};
};
@@ -51,7 +51,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
UInt64 importantTotalUnpacked = 0;
- bool allFilesMode = (numItems == (UInt32)-1);
+ bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems =
#ifdef _7Z_VOL
@@ -60,17 +60,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
_db.Files.Size();
#endif
- if(numItems == 0)
+ if (numItems == 0)
return S_OK;
/*
- if(_volumes.Size() != 1)
+ if (_volumes.Size() != 1)
return E_FAIL;
const CVolume &volume = _volumes.Front();
- const CArchiveDatabaseEx &_db = volume.Database;
+ const CDbEx &_db = volume.Database;
IInStream *_inStream = volume.Stream;
*/
-
+
CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
for (UInt32 ii = 0; ii < numItems; ii++)
{
@@ -86,10 +86,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
int volumeIndex = ref.VolumeIndex;
const CVolume &volume = _volumes[volumeIndex];
- const CArchiveDatabaseEx &db = volume.Database;
+ const CDbEx &db = volume.Database;
UInt32 fileIndex = ref.ItemIndex;
#else
- const CArchiveDatabaseEx &db = _db;
+ const CDbEx &db = _db;
UInt32 fileIndex = ref2Index;
#endif
@@ -115,14 +115,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
volumeIndex,
#endif
kNumNoIndex, folderIndex));
- const CFolder &folderInfo = db.Folders[folderIndex];
- UInt64 unpackSize = folderInfo.GetUnpackSize();
+ UInt64 unpackSize = db.GetFolderUnpackSize(folderIndex);
importantTotalUnpacked += unpackSize;
extractFolderInfoVector.Back().UnpackSize = unpackSize;
}
-
+
CExtractFolderInfo &efi = extractFolderInfoVector.Back();
-
+
// const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
CNum startIndex = db.FolderStartFileIndex[folderIndex];
for (CNum index = efi.ExtractStatuses.Size();
@@ -156,7 +155,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
- for (int i = 0;; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)
+ for (unsigned i = 0;; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)
{
lps->OutSize = totalUnpacked;
lps->InSize = totalPacked;
@@ -164,7 +163,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (i >= extractFolderInfoVector.Size())
break;
-
+
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
curUnpacked = efi.UnpackSize;
curPacked = 0;
@@ -174,9 +173,9 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
#ifdef _7Z_VOL
const CVolume &volume = _volumes[efi.VolumeIndex];
- const CArchiveDatabaseEx &db = volume.Database;
+ const CDbEx &db = volume.Database;
#else
- const CArchiveDatabaseEx &db = _db;
+ const CDbEx &db = _db;
#endif
CNum startIndex;
@@ -200,13 +199,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
continue;
CNum folderIndex = efi.FolderIndex;
- const CFolder &folderInfo = db.Folders[folderIndex];
-
curPacked = _db.GetFolderFullPackSize(folderIndex);
- CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex];
- UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0);
-
#ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (extractCallback)
@@ -216,26 +210,24 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
try
{
#ifndef _NO_CRYPTO
- bool passwordIsDefined;
+ bool isEncrypted = false;
+ bool passwordIsDefined = false;
#endif
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_VARS
#ifdef _7Z_VOL
- volume.Stream,
+ volume.Stream,
#else
- _inStream,
+ _inStream,
#endif
- folderStartPackPos,
- &db.PackSizes[packStreamIndex],
- folderInfo,
+ db.ArcInfo.DataStartPosition,
+ db, folderIndex,
outStream,
progress
- #ifndef _NO_CRYPTO
- , getTextPassword, passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) && !defined(_SFX)
- , true, _numThreads
+ , true, _numThreads
#endif
);
@@ -246,7 +238,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
if (result == E_NOTIMPL)
{
- RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kUnSupportedMethod));
+ RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kUnsupportedMethod));
continue;
}
if (result != S_OK)
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderInStream.cpp
index edd276bc1..3f420a513 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderInStream.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderInStream.cpp
@@ -106,8 +106,8 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
*value = 0;
- int index2 = (int)subStream;
- if (index2 < 0 || subStream > Sizes.Size())
+ unsigned index2 = (unsigned)subStream;
+ if (subStream > Sizes.Size())
return E_FAIL;
if (index2 < Sizes.Size())
{
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderInStream.h b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderInStream.h
index 6df3672a1..4ed4b2dd2 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderInStream.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderInStream.h
@@ -47,7 +47,7 @@ public:
UInt64 GetFullSize() const
{
UInt64 size = 0;
- for (int i = 0; i < Sizes.Size(); i++)
+ FOR_VECTOR (i, Sizes)
size += Sizes[i];
return size;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
index 22c4600ec..847f65bf2 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
@@ -14,7 +14,7 @@ CFolderOutStream::CFolderOutStream()
}
HRESULT CFolderOutStream::Init(
- const CArchiveDatabaseEx *db,
+ const CDbEx *db,
UInt32 ref2Offset, UInt32 startIndex,
const CBoolVector *extractStatuses,
IArchiveExtractCallback *extractCallback,
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.h b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.h
index f9bb1af42..cc2d77343 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.h
@@ -19,12 +19,12 @@ class CFolderOutStream:
{
COutStreamWithCRC *_crcStreamSpec;
CMyComPtr<ISequentialOutStream> _crcStream;
- const CArchiveDatabaseEx *_db;
+ const CDbEx *_db;
const CBoolVector *_extractStatuses;
CMyComPtr<IArchiveExtractCallback> _extractCallback;
UInt32 _ref2Offset;
UInt32 _startIndex;
- int _currentIndex;
+ unsigned _currentIndex;
bool _testMode;
bool _checkCrc;
bool _fileIsOpen;
@@ -43,7 +43,7 @@ public:
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
HRESULT Init(
- const CArchiveDatabaseEx *db,
+ const CDbEx *db,
UInt32 ref2Offset, UInt32 startIndex,
const CBoolVector *extractStatuses,
IArchiveExtractCallback *extractCallback,
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandler.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandler.cpp
index 4ab7afa87..ed65dc20c 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandler.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandler.cpp
@@ -23,26 +23,23 @@
#endif
using namespace NWindows;
-
-extern UString ConvertMethodIdToString(UInt64 id);
+using namespace NCOM;
namespace NArchive {
namespace N7z {
CHandler::CHandler()
{
- _crcSize = 4;
-
#ifndef _NO_CRYPTO
+ _isEncrypted = false;
_passwordIsDefined = false;
#endif
#ifdef EXTRACT_ONLY
+ _crcSize = 4;
#ifdef __7Z_SET_PROPERTIES
_numThreads = NSystem::GetNumberOfProcessors();
#endif
- #else
- Init();
#endif
}
@@ -54,11 +51,12 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
#ifdef _SFX
-IMP_IInArchive_ArcProps_NO
+IMP_IInArchive_ArcProps_NO_Table
-STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
{
- return E_NOTIMPL;
+ *numProps = 0;
+ return S_OK;
}
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
@@ -67,162 +65,502 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
return E_NOTIMPL;
}
-
#else
-STATPROPSTG kArcProps[] =
+static const Byte kArcProps[] =
{
- { NULL, kpidMethod, VT_BSTR},
- { NULL, kpidSolid, VT_BOOL},
- { NULL, kpidNumBlocks, VT_UI4},
- { NULL, kpidPhySize, VT_UI8},
- { NULL, kpidHeadersSize, VT_UI8},
- { NULL, kpidOffset, VT_UI8}
+ kpidHeadersSize,
+ kpidMethod,
+ kpidSolid,
+ kpidNumBlocks
+ // , kpidIsTree
};
+IMP_IInArchive_ArcProps
+
+static inline char GetHex(unsigned value)
+{
+ return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+}
+
+static unsigned ConvertMethodIdToString_Back(char *s, UInt64 id)
+{
+ int len = 0;
+ do
+ {
+ s[--len] = GetHex((unsigned)id & 0xF); id >>= 4;
+ s[--len] = GetHex((unsigned)id & 0xF); id >>= 4;
+ }
+ while (id != 0);
+ return (unsigned)-len;
+}
+
+static void ConvertMethodIdToString(AString &res, UInt64 id)
+{
+ const unsigned kLen = 32;
+ char s[kLen];
+ unsigned len = kLen - 1;
+ s[len] = 0;
+ res += s + len - ConvertMethodIdToString_Back(s + len, id);
+}
+
+static unsigned GetStringForSizeValue(char *s, UInt32 val)
+{
+ unsigned i;
+ for (i = 0; i <= 31; i++)
+ if (((UInt32)1 << i) == val)
+ {
+ if (i < 10)
+ {
+ s[0] = (char)('0' + i);
+ s[1] = 0;
+ return 1;
+ }
+ if (i < 20) { s[0] = '1'; s[1] = (char)('0' + i - 10); }
+ else if (i < 30) { s[0] = '2'; s[1] = (char)('0' + i - 20); }
+ else { s[0] = '3'; s[1] = (char)('0' + i - 30); }
+ s[2] = 0;
+ return 2;
+ }
+ char c = 'b';
+ if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
+ else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
+ ::ConvertUInt32ToString(val, s);
+ unsigned pos = MyStringLen(s);
+ s[pos++] = c;
+ s[pos] = 0;
+ return pos;
+}
+
+/*
+static inline void AddHexToString(UString &res, Byte value)
+{
+ res += GetHex((Byte)(value >> 4));
+ res += GetHex((Byte)(value & 0xF));
+}
+*/
+
+static char *AddProp32(char *s, const char *name, UInt32 v)
+{
+ *s++ = ':';
+ s = MyStpCpy(s, name);
+ ::ConvertUInt32ToString(v, s);
+ return s + MyStringLen(s);
+}
+
+void CHandler::AddMethodName(AString &s, UInt64 id)
+{
+ UString methodName;
+ FindMethod(EXTERNAL_CODECS_VARS id, methodName);
+ if (methodName.IsEmpty())
+ {
+ for (unsigned i = 0; i < methodName.Len(); i++)
+ if (methodName[i] >= 0x80)
+ {
+ methodName.Empty();
+ break;
+ }
+ }
+ if (methodName.IsEmpty())
+ ConvertMethodIdToString(s, id);
+ else
+ for (unsigned i = 0; i < methodName.Len(); i++)
+ s += (char)methodName[i];
+}
+
+#endif
+
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
+ #ifndef _SFX
COM_TRY_BEGIN
+ #endif
NCOM::CPropVariant prop;
- switch(propID)
+ switch (propID)
{
+ #ifndef _SFX
case kpidMethod:
{
- UString resString;
- CRecordVector<UInt64> ids;
- int i;
- for (i = 0; i < _db.Folders.Size(); i++)
- {
- const CFolder &f = _db.Folders[i];
- for (int j = f.Coders.Size() - 1; j >= 0; j--)
- ids.AddToUniqueSorted(f.Coders[j].MethodID);
- }
-
- for (i = 0; i < ids.Size(); i++)
+ AString s;
+ const CParsedMethods &pm = _db.ParsedMethods;
+ FOR_VECTOR (i, pm.IDs)
{
- UInt64 id = ids[i];
- UString methodName;
- /* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName);
- if (methodName.IsEmpty())
- methodName = ConvertMethodIdToString(id);
- if (!resString.IsEmpty())
- resString += L' ';
- resString += methodName;
+ UInt64 id = pm.IDs[i];
+ if (!s.IsEmpty())
+ s += ' ';
+ char temp[16];
+ if (id == k_LZMA2)
+ {
+ s += "LZMA2:";
+ if ((pm.Lzma2Prop & 1) == 0)
+ ConvertUInt32ToString((pm.Lzma2Prop >> 1) + 12, temp);
+ else
+ GetStringForSizeValue(temp, 3 << ((pm.Lzma2Prop >> 1) + 11));
+ s += temp;
+ }
+ else if (id == k_LZMA)
+ {
+ s += "LZMA:";
+ GetStringForSizeValue(temp, pm.LzmaDic);
+ s += temp;
+ }
+ else
+ AddMethodName(s, id);
}
- prop = resString;
+ prop = s;
break;
}
case kpidSolid: prop = _db.IsSolid(); break;
- case kpidNumBlocks: prop = (UInt32)_db.Folders.Size(); break;
+ case kpidNumBlocks: prop = (UInt32)_db.NumFolders; break;
case kpidHeadersSize: prop = _db.HeadersSize; break;
case kpidPhySize: prop = _db.PhySize; break;
- case kpidOffset: if (_db.ArchiveInfo.StartPosition != 0) prop = _db.ArchiveInfo.StartPosition; break;
+ case kpidOffset: if (_db.ArcInfo.StartPosition != 0) prop = _db.ArcInfo.StartPosition; break;
+ /*
+ case kpidIsTree: if (_db.IsTree) prop = true; break;
+ case kpidIsAltStream: if (_db.ThereAreAltStreams) prop = true; break;
+ case kpidIsAux: if (_db.IsTree) prop = true; break;
+ */
+ // case kpidError: if (_db.ThereIsHeaderError) prop = "Header error"; break;
+ #endif
+
+ case kpidWarningFlags:
+ {
+ UInt32 v = 0;
+ if (_db.StartHeaderWasRecovered) v |= kpv_ErrorFlags_HeadersError;
+ if (_db.UnsupportedFeatureWarning) v |= kpv_ErrorFlags_UnsupportedFeature;
+ if (v != 0)
+ prop = v;
+ break;
+ }
+
+ case kpidErrorFlags:
+ {
+ UInt32 v = 0;
+ if (!_db.IsArc) v |= kpv_ErrorFlags_IsNotArc;
+ if (_db.ThereIsHeaderError) v |= kpv_ErrorFlags_HeadersError;
+ if (_db.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
+ // if (_db.UnsupportedVersion) v |= kpv_ErrorFlags_Unsupported;
+ if (_db.UnsupportedFeatureError) v |= kpv_ErrorFlags_UnsupportedFeature;
+ prop = v;
+ break;
+ }
}
prop.Detach(value);
return S_OK;
+ #ifndef _SFX
COM_TRY_END
+ #endif
}
-IMP_IInArchive_ArcProps
-
-#endif
-
-static void SetPropFromUInt64Def(CUInt64DefVector &v, int index, NCOM::CPropVariant &prop)
+static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, int index)
{
UInt64 value;
if (v.GetItem(index, value))
+ PropVarEm_Set_FileTime64(prop, value);
+}
+
+bool CHandler::IsFolderEncrypted(CNum folderIndex) const
+{
+ if (folderIndex == kNumNoIndex)
+ return false;
+ size_t startPos = _db.FoCodersDataOffset[folderIndex];
+ const Byte *p = _db.CodersData + startPos;
+ size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos;
+ CInByte2 inByte;
+ inByte.Init(p, size);
+
+ CNum numCoders = inByte.ReadNum();
+ for (; numCoders != 0; numCoders--)
{
- FILETIME ft;
- ft.dwLowDateTime = (DWORD)value;
- ft.dwHighDateTime = (DWORD)(value >> 32);
- prop = ft;
+ Byte mainByte = inByte.ReadByte();
+ unsigned idSize = (mainByte & 0xF);
+ const Byte *longID = inByte.GetPtr();
+ UInt64 id64 = 0;
+ for (unsigned j = 0; j < idSize; j++)
+ id64 = ((id64 << 8) | longID[j]);
+ inByte.SkipDataNoCheck(idSize);
+ if (id64 == k_AES)
+ return true;
+ if ((mainByte & 0x20) != 0)
+ inByte.SkipDataNoCheck(inByte.ReadNum());
}
+ return false;
}
-#ifndef _SFX
+STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps)
+{
+ *numProps = 0;
+ return S_OK;
+}
-static UString ConvertUInt32ToString(UInt32 value)
+STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)
{
- wchar_t buffer[32];
- ConvertUInt64ToString(value, buffer);
- return buffer;
+ *name = NULL;
+ *propID = kpidNtSecure;
+ return S_OK;
}
-static UString GetStringForSizeValue(UInt32 value)
+STDMETHODIMP CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)
{
- for (int i = 31; i >= 0; i--)
- if ((UInt32(1) << i) == value)
- return ConvertUInt32ToString(i);
- UString result;
- if (value % (1 << 20) == 0)
- {
- result += ConvertUInt32ToString(value >> 20);
- result += L"m";
- }
- else if (value % (1 << 10) == 0)
+ /*
+ const CFileItem &file = _db.Files[index];
+ *parentType = (file.IsAltStream ? NParentType::kAltStream : NParentType::kDir);
+ *parent = (UInt32)(Int32)file.Parent;
+ */
+ *parentType = NParentType::kDir;
+ *parent = (UInt32)(Int32)-1;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
+{
+ *data = NULL;
+ *dataSize = 0;
+ *propType = 0;
+
+ if (/* _db.IsTree && propID == kpidName ||
+ !_db.IsTree && */ propID == kpidPath)
{
- result += ConvertUInt32ToString(value >> 10);
- result += L"k";
+ if (_db.NameOffsets && _db.NamesBuf)
+ {
+ size_t offset = _db.NameOffsets[index];
+ size_t size = (_db.NameOffsets[index + 1] - offset) * 2;
+ if (size < ((UInt32)1 << 31))
+ {
+ *data = (const void *)(_db.NamesBuf + offset * 2);
+ *dataSize = (UInt32)size;
+ *propType = NPropDataType::kUtf16z;
+ }
+ }
+ return S_OK;
}
- else
+ /*
+ if (propID == kpidNtSecure)
{
- result += ConvertUInt32ToString(value);
- result += L"b";
+ if (index < (UInt32)_db.SecureIDs.Size())
+ {
+ int id = _db.SecureIDs[index];
+ size_t offs = _db.SecureOffsets[id];
+ size_t size = _db.SecureOffsets[id + 1] - offs;
+ if (size >= 0)
+ {
+ *data = _db.SecureBuf + offs;
+ *dataSize = (UInt32)size;
+ *propType = NPropDataType::kRaw;
+ }
+ }
}
- return result;
+ */
+ return S_OK;
}
-static const UInt64 k_Copy = 0x0;
-static const UInt64 k_Delta = 3;
-static const UInt64 k_LZMA2 = 0x21;
-static const UInt64 k_LZMA = 0x030101;
-static const UInt64 k_PPMD = 0x030401;
+#ifndef _SFX
-static wchar_t GetHex(Byte value)
-{
- return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10)));
-}
-static inline void AddHexToString(UString &res, Byte value)
+HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
{
- res += GetHex((Byte)(value >> 4));
- res += GetHex((Byte)(value & 0xF));
+ PropVariant_Clear(prop);
+ if (folderIndex == kNumNoIndex)
+ return S_OK;
+ // for (int ttt = 0; ttt < 1; ttt++) {
+ const unsigned kTempSize = 256;
+ char temp[kTempSize];
+ unsigned pos = kTempSize;
+ temp[--pos] = 0;
+
+ size_t startPos = _db.FoCodersDataOffset[folderIndex];
+ const Byte *p = _db.CodersData + startPos;
+ size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos;
+ CInByte2 inByte;
+ inByte.Init(p, size);
+
+ // numCoders == 0 ???
+ CNum numCoders = inByte.ReadNum();
+ bool needSpace = false;
+ for (; numCoders != 0; numCoders--, needSpace = true)
+ {
+ if (pos < 32) // max size of property
+ break;
+ Byte mainByte = inByte.ReadByte();
+ unsigned idSize = (mainByte & 0xF);
+ const Byte *longID = inByte.GetPtr();
+ UInt64 id64 = 0;
+ for (unsigned j = 0; j < idSize; j++)
+ id64 = ((id64 << 8) | longID[j]);
+ inByte.SkipDataNoCheck(idSize);
+
+ if ((mainByte & 0x10) != 0)
+ {
+ inByte.ReadNum(); // NumInStreams
+ inByte.ReadNum(); // NumOutStreams
+ }
+
+ CNum propsSize = 0;
+ const Byte *props = NULL;
+ if ((mainByte & 0x20) != 0)
+ {
+ propsSize = inByte.ReadNum();
+ props = inByte.GetPtr();
+ inByte.SkipDataNoCheck(propsSize);
+ }
+
+ const char *name = NULL;
+ char s[32];
+ s[0] = 0;
+
+ if (id64 <= (UInt32)0xFFFFFFFF)
+ {
+ UInt32 id = (UInt32)id64;
+ if (id == k_LZMA)
+ {
+ name = "LZMA";
+ if (propsSize == 5)
+ {
+ UInt32 dicSize = GetUi32((const Byte *)props + 1);
+ char *dest = s + GetStringForSizeValue(s, dicSize);
+ UInt32 d = props[0];
+ if (d != 0x5D)
+ {
+ UInt32 lc = d % 9;
+ d /= 9;
+ UInt32 pb = d / 5;
+ UInt32 lp = d % 5;
+ if (lc != 3) dest = AddProp32(dest, "lc", lc);
+ if (lp != 0) dest = AddProp32(dest, "lp", lp);
+ if (pb != 2) dest = AddProp32(dest, "pb", pb);
+ }
+ }
+ }
+ else if (id == k_LZMA2)
+ {
+ name = "LZMA2";
+ if (propsSize == 1)
+ {
+ Byte p = props[0];
+ if ((p & 1) == 0)
+ ConvertUInt32ToString((UInt32)((p >> 1) + 12), s);
+ else
+ GetStringForSizeValue(s, 3 << ((p >> 1) + 11));
+ }
+ }
+ else if (id == k_PPMD)
+ {
+ name = "PPMD";
+ if (propsSize == 5)
+ {
+ Byte order = *props;
+ char *dest = s;
+ *dest++ = 'o';
+ ConvertUInt32ToString(order, dest);
+ dest += MyStringLen(dest);
+ dest = MyStpCpy(dest, ":mem");
+ GetStringForSizeValue(dest, GetUi32(props + 1));
+ }
+ }
+ else if (id == k_Delta)
+ {
+ name = "Delta";
+ if (propsSize == 1)
+ ConvertUInt32ToString((UInt32)props[0] + 1, s);
+ }
+ else if (id == k_BCJ2) name = "BCJ2";
+ else if (id == k_BCJ) name = "BCJ";
+ else if (id == k_AES)
+ {
+ name = "7zAES";
+ if (propsSize >= 1)
+ {
+ Byte firstByte = props[0];
+ UInt32 numCyclesPower = firstByte & 0x3F;
+ ConvertUInt32ToString(numCyclesPower, s);
+ }
+ }
+ }
+
+ if (name)
+ {
+ unsigned nameLen = MyStringLen(name);
+ unsigned propsLen = MyStringLen(s);
+ unsigned totalLen = nameLen + propsLen;
+ if (propsLen != 0)
+ totalLen++;
+ if (needSpace)
+ totalLen++;
+ if (totalLen + 5 >= pos)
+ break;
+ pos -= totalLen;
+ MyStringCopy(temp + pos, name);
+ if (propsLen != 0)
+ {
+ char *dest = temp + pos + nameLen;
+ *dest++ = ':';
+ MyStringCopy(dest, s);
+ }
+ if (needSpace)
+ temp[pos + totalLen - 1] = ' ';
+ }
+ else
+ {
+ UString methodName;
+ FindMethod(EXTERNAL_CODECS_VARS id64, methodName);
+ if (methodName.IsEmpty())
+ {
+ for (unsigned j = 0; j < methodName.Len(); j++)
+ if (methodName[j] >= 0x80)
+ {
+ methodName.Empty();
+ break;
+ }
+ }
+ if (needSpace)
+ temp[--pos] = ' ';
+ if (methodName.IsEmpty())
+ pos -= ConvertMethodIdToString_Back(temp + pos, id64);
+ else
+ {
+ unsigned len = methodName.Len();
+ if (len + 5 > pos)
+ break;
+ pos -= len;
+ for (unsigned i = 0; i < len; i++)
+ temp[pos + i] = (char)methodName[i];
+ }
+ }
+ }
+ if (numCoders != 0 && pos >= 4)
+ {
+ temp[--pos] = ' ';
+ temp[--pos] = '.';
+ temp[--pos] = '.';
+ temp[--pos] = '.';
+ }
+ return PropVarEm_Set_Str(prop, temp + pos);
+ // }
}
#endif
-bool CHandler::IsEncrypted(UInt32 index2) const
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
- CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
- if (folderIndex != kNumNoIndex)
- return _db.Folders[folderIndex].IsEncrypted();
- return false;
-}
+ PropVariant_Clear(value);
+ // COM_TRY_BEGIN
+ // NCOM::CPropVariant prop;
-STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
-{
- COM_TRY_BEGIN
- NCOM::CPropVariant prop;
-
/*
const CRef2 &ref2 = _refs[index];
if (ref2.Refs.IsEmpty())
return E_FAIL;
const CRef &ref = ref2.Refs.Front();
*/
-
+
const CFileItem &item = _db.Files[index];
UInt32 index2 = index;
switch(propID)
{
- case kpidPath:
- if (!item.Name.IsEmpty())
- prop = NItemName::GetOSName(item.Name);
- break;
- case kpidIsDir: prop = item.IsDir; break;
+ case kpidIsDir: PropVarEm_Set_Bool(value, item.IsDir); break;
case kpidSize:
{
- prop = item.Size;
+ PropVarEm_Set_UInt64(value, item.Size);
// prop = ref2.Size;
break;
}
@@ -234,122 +572,49 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
if (folderIndex != kNumNoIndex)
{
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2)
- prop = _db.GetFolderFullPackSize(folderIndex);
+ PropVarEm_Set_UInt64(value, _db.GetFolderFullPackSize(folderIndex));
/*
else
- prop = (UInt64)0;
+ PropVarEm_Set_UInt64(value, 0);
*/
}
else
- prop = (UInt64)0;
+ PropVarEm_Set_UInt64(value, 0);
}
break;
}
- case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) prop = v; break; }
- case kpidCTime: SetPropFromUInt64Def(_db.CTime, index2, prop); break;
- case kpidATime: SetPropFromUInt64Def(_db.ATime, index2, prop); break;
- case kpidMTime: SetPropFromUInt64Def(_db.MTime, index2, prop); break;
- case kpidAttrib: if (item.AttribDefined) prop = item.Attrib; break;
- case kpidCRC: if (item.CrcDefined) prop = item.Crc; break;
- case kpidEncrypted: prop = IsEncrypted(index2); break;
- case kpidIsAnti: prop = _db.IsItemAnti(index2); break;
- #ifndef _SFX
- case kpidMethod:
+ // case kpidIsAux: prop = _db.IsItemAux(index2); break;
+ case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) PropVarEm_Set_UInt64(value, v); break; }
+ case kpidCTime: SetFileTimeProp_From_UInt64Def(value, _db.CTime, index2); break;
+ case kpidATime: SetFileTimeProp_From_UInt64Def(value, _db.ATime, index2); break;
+ case kpidMTime: SetFileTimeProp_From_UInt64Def(value, _db.MTime, index2); break;
+ case kpidAttrib: if (item.AttribDefined) PropVarEm_Set_UInt32(value, item.Attrib); break;
+ case kpidCRC: if (item.CrcDefined) PropVarEm_Set_UInt32(value, item.Crc); break;
+ case kpidEncrypted: PropVarEm_Set_Bool(value, IsFolderEncrypted(_db.FileIndexToFolderIndexMap[index2])); break;
+ case kpidIsAnti: PropVarEm_Set_Bool(value, _db.IsItemAnti(index2)); break;
+ /*
+ case kpidIsAltStream: prop = item.IsAltStream; break;
+ case kpidNtSecure:
{
- CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
- if (folderIndex != kNumNoIndex)
+ int id = _db.SecureIDs[index];
+ size_t offs = _db.SecureOffsets[id];
+ size_t size = _db.SecureOffsets[id + 1] - offs;
+ if (size >= 0)
{
- const CFolder &folderInfo = _db.Folders[folderIndex];
- UString methodsString;
- for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
- {
- const CCoderInfo &coder = folderInfo.Coders[i];
- if (!methodsString.IsEmpty())
- methodsString += L' ';
-
- UString methodName, propsString;
- bool methodIsKnown = FindMethod(
- EXTERNAL_CODECS_VARS
- coder.MethodID, methodName);
-
- if (!methodIsKnown)
- methodsString += ConvertMethodIdToString(coder.MethodID);
- else
- {
- methodsString += methodName;
- if (coder.MethodID == k_Delta && coder.Props.GetCapacity() == 1)
- propsString = ConvertUInt32ToString((UInt32)coder.Props[0] + 1);
- else if (coder.MethodID == k_LZMA && coder.Props.GetCapacity() == 5)
- {
- UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);
- propsString = GetStringForSizeValue(dicSize);
- }
- else if (coder.MethodID == k_LZMA2 && coder.Props.GetCapacity() == 1)
- {
- Byte p = coder.Props[0];
- UInt32 dicSize = (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11));
- propsString = GetStringForSizeValue(dicSize);
- }
- else if (coder.MethodID == k_PPMD && coder.Props.GetCapacity() == 5)
- {
- Byte order = *(const Byte *)coder.Props;
- propsString = L'o';
- propsString += ConvertUInt32ToString(order);
- propsString += L":mem";
- UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);
- propsString += GetStringForSizeValue(dicSize);
- }
- else if (coder.MethodID == k_AES && coder.Props.GetCapacity() >= 1)
- {
- const Byte *data = (const Byte *)coder.Props;
- Byte firstByte = *data++;
- UInt32 numCyclesPower = firstByte & 0x3F;
- propsString = ConvertUInt32ToString(numCyclesPower);
- /*
- if ((firstByte & 0xC0) != 0)
- {
- UInt32 saltSize = (firstByte >> 7) & 1;
- UInt32 ivSize = (firstByte >> 6) & 1;
- if (coder.Props.GetCapacity() >= 2)
- {
- Byte secondByte = *data++;
- saltSize += (secondByte >> 4);
- ivSize += (secondByte & 0x0F);
- }
- }
- */
- }
- }
- if (!propsString.IsEmpty())
- {
- methodsString += L':';
- methodsString += propsString;
- }
- else if (coder.Props.GetCapacity() > 0)
- {
- methodsString += L":[";
- for (size_t bi = 0; bi < coder.Props.GetCapacity(); bi++)
- {
- if (bi > 5 && bi + 1 < coder.Props.GetCapacity())
- {
- methodsString += L"..";
- break;
- }
- else
- AddHexToString(methodsString, coder.Props[bi]);
- }
- methodsString += L']';
- }
- }
- prop = methodsString;
+ prop.SetBlob(_db.SecureBuf + offs, (ULONG)size);
}
+ break;
}
- break;
+ */
+
+ case kpidPath: return _db.GetPath_Prop(index, value);
+ #ifndef _SFX
+ case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value);
case kpidBlock:
{
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
- prop = (UInt32)folderIndex;
+ PropVarEm_Set_UInt32(value, (UInt32)folderIndex);
}
break;
case kpidPackedSize0:
@@ -358,6 +623,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
case kpidPackedSize3:
case kpidPackedSize4:
{
+ /*
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
@@ -372,13 +638,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
}
else
prop = (UInt64)0;
+ */
}
break;
#endif
}
- prop.Detach(value);
+ // prop.Detach(value);
return S_OK;
- COM_TRY_END
+ // COM_TRY_END
}
STDMETHODIMP CHandler::Open(IInStream *stream,
@@ -390,6 +657,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
#ifndef _SFX
_fileInfoPopIDs.Clear();
#endif
+
try
{
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
@@ -397,31 +665,30 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
#ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (openArchiveCallback)
- {
- openArchiveCallbackTemp.QueryInterface(
- IID_ICryptoGetTextPassword, &getTextPassword);
- }
+ openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
#endif
+
CInArchive archive;
+ _db.IsArc = false;
RINOK(archive.Open(stream, maxCheckStartPosition));
- #ifndef _NO_CRYPTO
- _passwordIsDefined = false;
- UString password;
- #endif
+ _db.IsArc = true;
+
HRESULT result = archive.ReadDatabase(
- EXTERNAL_CODECS_VARS
- _db
- #ifndef _NO_CRYPTO
- , getTextPassword, _passwordIsDefined
- #endif
- );
+ EXTERNAL_CODECS_VARS
+ _db
+ #ifndef _NO_CRYPTO
+ , getTextPassword, _isEncrypted, _passwordIsDefined
+ #endif
+ );
RINOK(result);
- _db.Fill();
+
_inStream = stream;
}
catch(...)
{
Close();
+ // return E_INVALIDARG;
+ // we must return out_of_memory here
return S_FALSE;
}
// _inStream = stream;
@@ -437,6 +704,10 @@ STDMETHODIMP CHandler::Close()
COM_TRY_BEGIN
_inStream.Release();
_db.Clear();
+ #ifndef _NO_CRYPTO
+ _isEncrypted = false;
+ _passwordIsDefined = false;
+ #endif
return S_OK;
COM_TRY_END
}
@@ -444,16 +715,16 @@ STDMETHODIMP CHandler::Close()
#ifdef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
-STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps)
{
COM_TRY_BEGIN
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
_numThreads = numProcessors;
- for (int i = 0; i < numProperties; i++)
+ for (UInt32 i = 0; i < numProps; i++)
{
UString name = names[i];
- name.MakeUpper();
+ name.MakeLower_Ascii();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
@@ -461,9 +732,9 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
int index = ParseStringToUInt32(name, number);
if (index == 0)
{
- if(name.Left(2).CompareNoCase(L"MT") == 0)
+ if (name.IsPrefixedBy(L"mt"))
{
- RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
+ RINOK(ParseMtProp(name.Ptr(2), value, numProcessors, _numThreads));
continue;
}
else
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandler.h b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandler.h
index 56062d464..677a3e10a 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandler.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandler.h
@@ -18,6 +18,16 @@
namespace NArchive {
namespace N7z {
+const UInt32 k_Copy = 0x0;
+const UInt32 k_Delta = 3;
+const UInt32 k_LZMA2 = 0x21;
+const UInt32 k_LZMA = 0x030101;
+const UInt32 k_PPMD = 0x030401;
+const UInt32 k_BCJ = 0x03030103;
+const UInt32 k_BCJ2 = 0x0303011B;
+const UInt32 k_Deflate = 0x040108;
+const UInt32 k_BZip2 = 0x040202;
+
#ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
@@ -31,11 +41,53 @@ namespace N7z {
#endif
+#ifndef EXTRACT_ONLY
+
+class COutHandler: public CMultiMethodProps
+{
+ HRESULT SetSolidFromString(const UString &s);
+ HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value);
+public:
+ bool _removeSfxBlock;
+
+ UInt64 _numSolidFiles;
+ UInt64 _numSolidBytes;
+ bool _numSolidBytesDefined;
+ bool _solidExtension;
+
+ bool _compressHeaders;
+ bool _encryptHeadersSpecified;
+ bool _encryptHeaders;
+ // bool _useParents; 9.26
+
+ CBoolPair Write_CTime;
+ CBoolPair Write_ATime;
+ CBoolPair Write_MTime;
+
+ bool _volumeMode;
+
+ void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
+ void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
+ void InitSolid()
+ {
+ InitSolidFiles();
+ InitSolidSize();
+ _solidExtension = false;
+ _numSolidBytesDefined = false;
+ }
+
+ void InitProps();
+
+ COutHandler() { InitProps(); }
+
+ HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
+};
+
+#endif
+
class CHandler:
- #ifndef EXTRACT_ONLY
- public NArchive::COutHandler,
- #endif
public IInArchive,
+ public IArchiveGetRawProps,
#ifdef __7Z_SET_PROPERTIES
public ISetProperties,
#endif
@@ -44,9 +96,13 @@ class CHandler:
#endif
PUBLIC_ISetCompressCodecsInfo
public CMyUnknownImp
+ #ifndef EXTRACT_ONLY
+ , public COutHandler
+ #endif
{
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
+ MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
#ifdef __7Z_SET_PROPERTIES
MY_QUERYINTERFACE_ENTRY(ISetProperties)
#endif
@@ -58,9 +114,10 @@ public:
MY_ADDREF_RELEASE
INTERFACE_IInArchive(;)
+ INTERFACE_IArchiveGetRawProps(;)
#ifdef __7Z_SET_PROPERTIES
- STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps);
#endif
#ifndef EXTRACT_ONLY
@@ -73,13 +130,14 @@ public:
private:
CMyComPtr<IInStream> _inStream;
- NArchive::N7z::CArchiveDatabaseEx _db;
+ NArchive::N7z::CDbEx _db;
#ifndef _NO_CRYPTO
+ bool _isEncrypted;
bool _passwordIsDefined;
#endif
#ifdef EXTRACT_ONLY
-
+
#ifdef __7Z_SET_PROPERTIES
UInt32 _numThreads;
#endif
@@ -87,27 +145,29 @@ private:
UInt32 _crcSize;
#else
-
+
CRecordVector<CBind> _binds;
- HRESULT SetCompressionMethod(CCompressionMethodMode &method,
+ HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
+ HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
+ void AddDefaultMethod();
+ HRESULT SetMainMethod(CCompressionMethodMode &method,
CObjectVector<COneMethodInfo> &methodsInfo
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
);
- HRESULT SetCompressionMethod(
- CCompressionMethodMode &method,
- CCompressionMethodMode &headerMethod);
#endif
- bool IsEncrypted(UInt32 index2) const;
+ bool IsFolderEncrypted(CNum folderIndex) const;
#ifndef _SFX
CRecordVector<UInt64> _fileInfoPopIDs;
void FillPopIDs();
+ void AddMethodName(AString &s, UInt64 id);
+ HRESULT SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const;
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandlerOut.cpp
index a8ccab6df..7de5b8140 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandlerOut.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHandlerOut.cpp
@@ -2,12 +2,9 @@
#include "StdAfx.h"
-#include "../../../Windows/PropVariant.h"
-
#include "../../../Common/ComTry.h"
#include "../../../Common/StringToInt.h"
-
-#include "../../ICoder.h"
+#include "../../../Common/Wildcard.h"
#include "../Common/ItemNameUtils.h"
#include "../Common/ParseProperties.h"
@@ -21,24 +18,19 @@ using namespace NWindows;
namespace NArchive {
namespace N7z {
-static const wchar_t *kLZMAMethodName = L"LZMA";
-static const wchar_t *kCopyMethod = L"Copy";
-static const wchar_t *kDefaultMethodName = kLZMAMethodName;
+static const wchar_t *k_LZMA_Name = L"LZMA";
+static const wchar_t *kDefaultMethodName = L"LZMA2";
+static const wchar_t *k_Copy_Name = L"Copy";
-static const UInt32 kLzmaAlgorithmX5 = 1;
-static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
-static const UInt32 kDictionaryForHeaders =
+static const wchar_t *k_MatchFinder_ForHeaders = L"BT2";
+static const UInt32 k_NumFastBytes_ForHeaders = 273;
+static const UInt32 k_Level_ForHeaders = 5;
+static const UInt32 k_Dictionary_ForHeaders =
#ifdef UNDER_CE
- 1 << 18
+ 1 << 18;
#else
- 1 << 20
+ 1 << 20;
#endif
-;
-static const UInt32 kNumFastBytesForHeaders = 273;
-static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
-
-static inline bool IsCopyMethod(const UString &methodName)
- { return (methodName.CompareNoCase(kCopyMethod) == 0); }
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
@@ -46,132 +38,112 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
return S_OK;
}
-HRESULT CHandler::SetCompressionMethod(
- CCompressionMethodMode &methodMode,
- CCompressionMethodMode &headerMethod)
+HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m)
{
- HRESULT res = SetCompressionMethod(methodMode, _methods
- #ifndef _7ZIP_ST
- , _numThreads
- #endif
- );
- RINOK(res);
- methodMode.Binds = _binds;
+ if (!FindMethod(
+ EXTERNAL_CODECS_VARS
+ m.MethodName, dest.Id, dest.NumInStreams, dest.NumOutStreams))
+ return E_INVALIDARG;
+ (CProps &)dest = (CProps &)m;
+ return S_OK;
+}
- if (_compressHeaders)
- {
- // headerMethod.Methods.Add(methodMode.Methods.Back());
+HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
+{
+ if (!_compressHeaders)
+ return S_OK;
+ COneMethodInfo m;
+ m.MethodName = k_LZMA_Name;
+ m.AddPropString(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
+ m.AddProp32(NCoderPropID::kLevel, k_Level_ForHeaders);
+ m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders);
+ m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders);
+ m.AddNumThreadsProp(1);
+
+ CMethodFull methodFull;
+ RINOK(PropsMethod_To_FullMethod(methodFull, m));
+ headerMethod.Methods.Add(methodFull);
+ return S_OK;
+}
- CObjectVector<COneMethodInfo> headerMethodInfoVector;
- COneMethodInfo oneMethodInfo;
- oneMethodInfo.MethodName = kLZMAMethodName;
- {
- CProp prop;
- prop.Id = NCoderPropID::kMatchFinder;
- prop.Value = kLzmaMatchFinderForHeaders;
- oneMethodInfo.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kAlgorithm;
- prop.Value = kAlgorithmForHeaders;
- oneMethodInfo.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kNumFastBytes;
- prop.Value = (UInt32)kNumFastBytesForHeaders;
- oneMethodInfo.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kDictionarySize;
- prop.Value = (UInt32)kDictionaryForHeaders;
- oneMethodInfo.Props.Add(prop);
- }
- headerMethodInfoVector.Add(oneMethodInfo);
- HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
- #ifndef _7ZIP_ST
- , 1
- #endif
- );
- RINOK(res);
+void CHandler::AddDefaultMethod()
+{
+ FOR_VECTOR (i, _methods)
+ {
+ UString &methodName = _methods[i].MethodName;
+ if (methodName.IsEmpty())
+ methodName = kDefaultMethodName;
+ }
+ if (_methods.IsEmpty())
+ {
+ COneMethodInfo m;
+ m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName);
+ _methods.Add(m);
}
- return S_OK;
}
-HRESULT CHandler::SetCompressionMethod(
+HRESULT CHandler::SetMainMethod(
CCompressionMethodMode &methodMode,
- CObjectVector<COneMethodInfo> &methodsInfo
+ CObjectVector<COneMethodInfo> &methods
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
)
{
- UInt32 level = _level;
-
- if (methodsInfo.IsEmpty())
- {
- COneMethodInfo oneMethodInfo;
- oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName);
- methodsInfo.Add(oneMethodInfo);
- }
+ AddDefaultMethod();
+
+ const UInt64 kSolidBytes_Min = (1 << 24);
+ const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
bool needSolid = false;
- for(int i = 0; i < methodsInfo.Size(); i++)
+ FOR_VECTOR (i, methods)
{
- COneMethodInfo &oneMethodInfo = methodsInfo[i];
- SetCompressionMethod2(oneMethodInfo
+ COneMethodInfo &oneMethodInfo = methods[i];
+ SetGlobalLevelAndThreads(oneMethodInfo
#ifndef _7ZIP_ST
, numThreads
#endif
);
- if (!IsCopyMethod(oneMethodInfo.MethodName))
- needSolid = true;
-
CMethodFull methodFull;
-
- if (!FindMethod(
- EXTERNAL_CODECS_VARS
- oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams))
- return E_INVALIDARG;
- methodFull.Props = oneMethodInfo.Props;
+ RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
methodMode.Methods.Add(methodFull);
- if (!_numSolidBytesDefined)
+ if (methodFull.Id != k_Copy)
+ needSolid = true;
+
+ if (_numSolidBytesDefined)
+ continue;
+
+ UInt32 dicSize;
+ switch (methodFull.Id)
{
- for (int j = 0; j < methodFull.Props.Size(); j++)
- {
- const CProp &prop = methodFull.Props[j];
- if ((prop.Id == NCoderPropID::kDictionarySize ||
- prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
- {
- _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
- const UInt64 kMinSize = (1 << 24);
- if (_numSolidBytes < kMinSize)
- _numSolidBytes = kMinSize;
- _numSolidBytesDefined = true;
- break;
- }
- }
+ case k_LZMA:
+ case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break;
+ case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break;
+ case k_Deflate: dicSize = (UInt32)1 << 15; break;
+ case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
+ default: continue;
}
- }
-
- if (!needSolid && !_numSolidBytesDefined)
- {
+ _numSolidBytes = (UInt64)dicSize << 7;
+ if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
+ if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
_numSolidBytesDefined = true;
- _numSolidBytes = 0;
}
+
+ if (!_numSolidBytesDefined)
+ if (needSolid)
+ _numSolidBytes = kSolidBytes_Max;
+ else
+ _numSolidBytes = 0;
+ _numSolidBytesDefined = true;
return S_OK;
}
-static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool writeTime, PROPID propID, UInt64 &ft, bool &ftDefined)
+static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, UInt64 &ft, bool &ftDefined)
{
- ft = 0;
- ftDefined = false;
- if (!writeTime)
- return S_OK;
+ // ft = 0;
+ // ftDefined = false;
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(index, propID, &prop));
if (prop.vt == VT_FILETIME)
@@ -181,15 +153,87 @@ static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool w
}
else if (prop.vt != VT_EMPTY)
return E_INVALIDARG;
+ else
+ {
+ ft = 0;
+ ftDefined = false;
+ }
return S_OK;
}
+/*
+
+#ifdef _WIN32
+static const wchar_t kDirDelimiter1 = L'\\';
+#endif
+static const wchar_t kDirDelimiter2 = L'/';
+
+static inline bool IsCharDirLimiter(wchar_t c)
+{
+ return (
+ #ifdef _WIN32
+ c == kDirDelimiter1 ||
+ #endif
+ c == kDirDelimiter2);
+}
+
+static int FillSortIndex(CObjectVector<CTreeFolder> &treeFolders, int cur, int curSortIndex)
+{
+ CTreeFolder &tf = treeFolders[cur];
+ tf.SortIndex = curSortIndex++;
+ for (int i = 0; i < tf.SubFolders.Size(); i++)
+ curSortIndex = FillSortIndex(treeFolders, tf.SubFolders[i], curSortIndex);
+ tf.SortIndexEnd = curSortIndex;
+ return curSortIndex;
+}
+
+static int FindSubFolder(const CObjectVector<CTreeFolder> &treeFolders, int cur, const UString &name, int &insertPos)
+{
+ const CIntVector &subFolders = treeFolders[cur].SubFolders;
+ int left = 0, right = subFolders.Size();
+ insertPos = -1;
+ for (;;)
+ {
+ if (left == right)
+ {
+ insertPos = left;
+ return -1;
+ }
+ int mid = (left + right) / 2;
+ int midFolder = subFolders[mid];
+ int compare = CompareFileNames(name, treeFolders[midFolder].Name);
+ if (compare == 0)
+ return midFolder;
+ if (compare < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+}
+
+static int AddFolder(CObjectVector<CTreeFolder> &treeFolders, int cur, const UString &name)
+{
+ int insertPos;
+ int folderIndex = FindSubFolder(treeFolders, cur, name, insertPos);
+ if (folderIndex < 0)
+ {
+ folderIndex = treeFolders.Size();
+ CTreeFolder &newFolder = treeFolders.AddNew();
+ newFolder.Parent = cur;
+ newFolder.Name = name;
+ treeFolders[cur].SubFolders.Insert(insertPos, folderIndex);
+ }
+ // else if (treeFolders[folderIndex].IsAltStreamFolder != isAltStreamFolder) throw 1123234234;
+ return folderIndex;
+}
+*/
+
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
{
COM_TRY_BEGIN
- const CArchiveDatabaseEx *db = 0;
+ const CDbEx *db = 0;
#ifdef _7Z_VOL
if (_volumes.Size() > 1)
return E_FAIL;
@@ -204,8 +248,35 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
db = &_db;
#endif
+ /*
+ CMyComPtr<IArchiveGetRawProps> getRawProps;
+ updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps);
+
+ CUniqBlocks secureBlocks;
+ secureBlocks.AddUniq(NULL, 0);
+
+ CObjectVector<CTreeFolder> treeFolders;
+ {
+ CTreeFolder folder;
+ folder.Parent = -1;
+ treeFolders.Add(folder);
+ }
+ */
+
CObjectVector<CUpdateItem> updateItems;
-
+
+ bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
+ bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
+ bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
+ if (db)
+ {
+ if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
+ if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
+ if (!Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty();
+ }
+
+ UString s;
+
for (UInt32 i = 0; i < numItems; i++)
{
Int32 newData, newProps;
@@ -221,24 +292,32 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
ui.IsAnti = false;
ui.Size = 0;
+ UString name;
+ // bool isAltStream = false;
if (ui.IndexInArchive != -1)
{
- if (db == 0 || ui.IndexInArchive >= db->Files.Size())
+ if (db == 0 || (unsigned)ui.IndexInArchive >= db->Files.Size())
return E_INVALIDARG;
const CFileItem &fi = db->Files[ui.IndexInArchive];
- ui.Name = fi.Name;
+ if (!ui.NewProps)
+ {
+ _db.GetPath(ui.IndexInArchive, name);
+ }
ui.IsDir = fi.IsDir;
ui.Size = fi.Size;
+ // isAltStream = fi.IsAltStream;
ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
-
- ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
- ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
- ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
+
+ if (!ui.NewProps)
+ {
+ ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
+ ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
+ ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
+ }
}
if (ui.NewProps)
{
- bool nameIsDefined;
bool folderStatusIsDefined;
{
NCOM::CPropVariant prop;
@@ -253,23 +332,37 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
ui.AttribDefined = true;
}
}
-
+
// we need MTime to sort files.
- RINOK(GetTime(updateCallback, i, WriteCTime, kpidCTime, ui.CTime, ui.CTimeDefined));
- RINOK(GetTime(updateCallback, i, WriteATime, kpidATime, ui.ATime, ui.ATimeDefined));
- RINOK(GetTime(updateCallback, i, true, kpidMTime, ui.MTime, ui.MTimeDefined));
+ if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined));
+ if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined));
+ if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined));
+
+ /*
+ if (getRawProps)
+ {
+ const void *data;
+ UInt32 dataSize;
+ UInt32 propType;
+
+ getRawProps->GetRawProp(i, kpidNtSecure, &data, &dataSize, &propType);
+ if (dataSize != 0 && propType != NPropDataType::kRaw)
+ return E_FAIL;
+ ui.SecureIndex = secureBlocks.AddUniq((const Byte *)data, dataSize);
+ }
+ */
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
if (prop.vt == VT_EMPTY)
- nameIsDefined = false;
+ {
+ }
else if (prop.vt != VT_BSTR)
return E_INVALIDARG;
else
{
- ui.Name = NItemName::MakeLegalName(prop.bstrVal);
- nameIsDefined = true;
+ name = NItemName::MakeLegalName(prop.bstrVal);
}
}
{
@@ -297,6 +390,19 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
ui.IsAnti = (prop.boolVal != VARIANT_FALSE);
}
+ /*
+ {
+ NCOM::CPropVariant prop;
+ RINOK(updateCallback->GetProperty(i, kpidIsAltStream, &prop));
+ if (prop.vt == VT_EMPTY)
+ isAltStream = false;
+ else if (prop.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ isAltStream = (prop.boolVal != VARIANT_FALSE);
+ }
+ */
+
if (ui.IsAnti)
{
ui.AttribDefined = false;
@@ -304,13 +410,87 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
ui.CTimeDefined = false;
ui.ATimeDefined = false;
ui.MTimeDefined = false;
-
+
ui.Size = 0;
}
if (!folderStatusIsDefined && ui.AttribDefined)
ui.SetDirStatusFromAttrib();
}
+ else
+ {
+ /*
+ if (_db.SecureIDs.IsEmpty())
+ ui.SecureIndex = secureBlocks.AddUniq(NULL, 0);
+ else
+ {
+ int id = _db.SecureIDs[ui.IndexInArchive];
+ size_t offs = _db.SecureOffsets[id];
+ size_t size = _db.SecureOffsets[id + 1] - offs;
+ ui.SecureIndex = secureBlocks.AddUniq(_db.SecureBuf + offs, size);
+ }
+ */
+ }
+
+ /*
+ {
+ int folderIndex = 0;
+ if (_useParents)
+ {
+ int j;
+ s.Empty();
+ for (j = 0; j < name.Len(); j++)
+ {
+ wchar_t c = name[j];
+ if (IsCharDirLimiter(c))
+ {
+ folderIndex = AddFolder(treeFolders, folderIndex, s);
+ s.Empty();
+ continue;
+ }
+ s += c;
+ }
+ if (isAltStream)
+ {
+ int colonPos = s.Find(':');
+ if (colonPos < 0)
+ {
+ // isAltStream = false;
+ return E_INVALIDARG;
+ }
+ UString mainName = s.Left(colonPos);
+ int newFolderIndex = AddFolder(treeFolders, folderIndex, mainName);
+ if (treeFolders[newFolderIndex].UpdateItemIndex < 0)
+ {
+ for (int j = updateItems.Size() - 1; j >= 0; j--)
+ {
+ CUpdateItem &ui2 = updateItems[j];
+ if (ui2.ParentFolderIndex == folderIndex
+ && ui2.Name == mainName)
+ {
+ ui2.TreeFolderIndex = newFolderIndex;
+ treeFolders[newFolderIndex].UpdateItemIndex = j;
+ }
+ }
+ }
+ folderIndex = newFolderIndex;
+ s.Delete(0, colonPos + 1);
+ }
+ ui.Name = s;
+ }
+ else
+ ui.Name = name;
+ ui.IsAltStream = isAltStream;
+ ui.ParentFolderIndex = folderIndex;
+ ui.TreeFolderIndex = -1;
+ if (ui.IsDir && !s.IsEmpty())
+ {
+ ui.TreeFolderIndex = AddFolder(treeFolders, folderIndex, s);
+ treeFolders[ui.TreeFolderIndex].UpdateItemIndex = updateItems.Size();
+ }
+ }
+ */
+ ui.Name = name;
if (ui.NewData)
{
@@ -325,8 +505,27 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
updateItems.Add(ui);
}
+ /*
+ FillSortIndex(treeFolders, 0, 0);
+ for (i = 0; i < (UInt32)updateItems.Size(); i++)
+ {
+ CUpdateItem &ui = updateItems[i];
+ ui.ParentSortIndex = treeFolders[ui.ParentFolderIndex].SortIndex;
+ ui.ParentSortIndexEnd = treeFolders[ui.ParentFolderIndex].SortIndexEnd;
+ }
+ */
+
CCompressionMethodMode methodMode, headerMethod;
- RINOK(SetCompressionMethod(methodMode, headerMethod));
+
+ HRESULT res = SetMainMethod(methodMode, _methods
+ #ifndef _7ZIP_ST
+ , _numThreads
+ #endif
+ );
+ RINOK(res);
+ methodMode.Binds = _binds;
+
+ RINOK(SetHeaderMethod(headerMethod));
#ifndef _7ZIP_ST
methodMode.NumThreads = _numThreads;
headerMethod.NumThreads = 1;
@@ -335,17 +534,17 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CMyComPtr<ICryptoGetTextPassword2> getPassword2;
updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2);
+ methodMode.PasswordIsDefined = false;
+ methodMode.Password.Empty();
if (getPassword2)
{
CMyComBSTR password;
Int32 passwordIsDefined;
RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password));
methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
- if (methodMode.PasswordIsDefined)
+ if (methodMode.PasswordIsDefined && (BSTR)password)
methodMode.Password = password;
}
- else
- methodMode.PasswordIsDefined = false;
bool compressMainHeader = _compressHeaders; // check it
@@ -373,14 +572,17 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CUpdateOptions options;
options.Method = &methodMode;
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
- options.UseFilters = _level != 0 && _autoFilter;
- options.MaxFilter = _level >= 8;
+ int level = GetLevel();
+ options.UseFilters = level != 0 && _autoFilter;
+ options.MaxFilter = level >= 8;
options.HeaderOptions.CompressMainHeader = compressMainHeader;
- options.HeaderOptions.WriteCTime = WriteCTime;
- options.HeaderOptions.WriteATime = WriteATime;
- options.HeaderOptions.WriteMTime = WriteMTime;
-
+ /*
+ options.HeaderOptions.WriteCTime = Write_CTime;
+ options.HeaderOptions.WriteATime = Write_ATime;
+ options.HeaderOptions.WriteMTime = Write_MTime;
+ */
+
options.NumSolidFiles = _numSolidFiles;
options.NumSolidBytes = _numSolidBytes;
options.SolidExtension = _solidExtension;
@@ -388,12 +590,24 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options.VolumeMode = _volumeMode;
COutArchive archive;
- CArchiveDatabase newDatabase;
+ CArchiveDatabaseOut newDatabase;
CMyComPtr<ICryptoGetTextPassword> getPassword;
updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword);
-
- HRESULT res = Update(
+
+ /*
+ if (secureBlocks.Sorted.Size() > 1)
+ {
+ secureBlocks.GetReverseMap();
+ for (int i = 0; i < updateItems.Size(); i++)
+ {
+ int &secureIndex = updateItems[i].SecureIndex;
+ secureIndex = secureBlocks.BufIndexToSortedIndex[secureIndex];
+ }
+ }
+ */
+
+ res = Update(
EXTERNAL_CODECS_VARS
#ifdef _7Z_VOL
volume ? volume->Stream: 0,
@@ -403,6 +617,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
db,
#endif
updateItems,
+ // treeFolders,
+ // secureBlocks,
archive, newDatabase, outStream, updateCallback, options
#ifndef _NO_CRYPTO
, getPassword
@@ -426,7 +642,7 @@ static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream
if (index == 0)
return E_INVALIDARG;
srcString.Delete(0, index);
- if (srcString[0] == 'S')
+ if (srcString[0] == 's')
{
srcString.Delete(0);
int index = ParseStringToUInt32(srcString, stream);
@@ -437,38 +653,173 @@ static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream
return S_OK;
}
-static HRESULT GetBindInfo(UString &srcString, CBind &bind)
+void COutHandler::InitProps()
{
- RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream));
- if (srcString[0] != ':')
- return E_INVALIDARG;
- srcString.Delete(0);
- RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream));
- if (!srcString.IsEmpty())
- return E_INVALIDARG;
+ CMultiMethodProps::Init();
+
+ _removeSfxBlock = false;
+ _compressHeaders = true;
+ _encryptHeadersSpecified = false;
+ _encryptHeaders = false;
+ // _useParents = false;
+
+ Write_CTime.Init();
+ Write_ATime.Init();
+ Write_MTime.Init();
+
+ _volumeMode = false;
+ InitSolid();
+}
+
+HRESULT COutHandler::SetSolidFromString(const UString &s)
+{
+ UString s2 = s;
+ s2.MakeLower_Ascii();
+ for (unsigned i = 0; i < s2.Len();)
+ {
+ const wchar_t *start = ((const wchar_t *)s2) + i;
+ const wchar_t *end;
+ UInt64 v = ConvertStringToUInt64(start, &end);
+ if (start == end)
+ {
+ if (s2[i++] != 'e')
+ return E_INVALIDARG;
+ _solidExtension = true;
+ continue;
+ }
+ i += (int)(end - start);
+ if (i == s2.Len())
+ return E_INVALIDARG;
+ wchar_t c = s2[i++];
+ if (c == 'f')
+ {
+ if (v < 1)
+ v = 1;
+ _numSolidFiles = v;
+ }
+ else
+ {
+ unsigned numBits;
+ switch (c)
+ {
+ case 'b': numBits = 0; break;
+ case 'k': numBits = 10; break;
+ case 'm': numBits = 20; break;
+ case 'g': numBits = 30; break;
+ case 't': numBits = 40; break;
+ default: return E_INVALIDARG;
+ }
+ _numSolidBytes = (v << numBits);
+ _numSolidBytesDefined = true;
+ }
+ }
return S_OK;
}
-STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value)
+{
+ bool isSolid;
+ switch (value.vt)
+ {
+ case VT_EMPTY: isSolid = true; break;
+ case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break;
+ case VT_BSTR:
+ if (StringToBool(value.bstrVal, isSolid))
+ break;
+ return SetSolidFromString(value.bstrVal);
+ default: return E_INVALIDARG;
+ }
+ if (isSolid)
+ InitSolid();
+ else
+ _numSolidFiles = 1;
+ return S_OK;
+}
+
+static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest)
+{
+ RINOK(PROPVARIANT_to_bool(prop, dest.Val));
+ dest.Def = true;
+ return S_OK;
+}
+
+HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
+{
+ UString name = nameSpec;
+ name.MakeLower_Ascii();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+
+ if (name[0] == L's')
+ {
+ name.Delete(0);
+ if (name.IsEmpty())
+ return SetSolidFromPROPVARIANT(value);
+ if (value.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ return SetSolidFromString(name);
+ }
+
+ UInt32 number;
+ int index = ParseStringToUInt32(name, number);
+ UString realName = name.Ptr(index);
+ if (index == 0)
+ {
+ if (name.IsEqualTo("rsfx")) return PROPVARIANT_to_bool(value, _removeSfxBlock);
+ if (name.IsEqualTo("hc")) return PROPVARIANT_to_bool(value, _compressHeaders);
+ // if (name.IsEqualToNoCase(L"HS")) return PROPVARIANT_to_bool(value, _useParents);
+
+ if (name.IsEqualTo("hcf"))
+ {
+ bool compressHeadersFull = true;
+ RINOK(PROPVARIANT_to_bool(value, compressHeadersFull));
+ return compressHeadersFull ? S_OK: E_INVALIDARG;
+ }
+
+ if (name.IsEqualTo("he"))
+ {
+ RINOK(PROPVARIANT_to_bool(value, _encryptHeaders));
+ _encryptHeadersSpecified = true;
+ return S_OK;
+ }
+
+ if (name.IsEqualTo("tc")) return PROPVARIANT_to_BoolPair(value, Write_CTime);
+ if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
+ if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
+
+ if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode);
+ }
+ return CMultiMethodProps::SetProperty(name, value);
+}
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps)
{
COM_TRY_BEGIN
_binds.Clear();
- BeforeSetProperty();
+ InitProps();
- for (int i = 0; i < numProperties; i++)
+ for (UInt32 i = 0; i < numProps; i++)
{
UString name = names[i];
- name.MakeUpper();
+ name.MakeLower_Ascii();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
- if (name[0] == 'B')
+ if (name[0] == 'b')
{
+ if (value.vt != VT_EMPTY)
+ return E_INVALIDARG;
name.Delete(0);
CBind bind;
- RINOK(GetBindInfo(name, bind));
+ RINOK(GetBindInfoPart(name, bind.OutCoder, bind.OutStream));
+ if (name[0] != ':')
+ return E_INVALIDARG;
+ name.Delete(0);
+ RINOK(GetBindInfoPart(name, bind.InCoder, bind.InStream));
+ if (!name.IsEmpty())
+ return E_INVALIDARG;
_binds.Add(bind);
continue;
}
@@ -476,6 +827,47 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
RINOK(SetProperty(name, value));
}
+ unsigned numEmptyMethods = GetNumEmptyMethods();
+ if (numEmptyMethods > 0)
+ {
+ unsigned k;
+ for (k = 0; k < _binds.Size(); k++)
+ {
+ const CBind &bind = _binds[k];
+ if (bind.InCoder < (UInt32)numEmptyMethods ||
+ bind.OutCoder < (UInt32)numEmptyMethods)
+ return E_INVALIDARG;
+ }
+ for (k = 0; k < _binds.Size(); k++)
+ {
+ CBind &bind = _binds[k];
+ bind.InCoder -= (UInt32)numEmptyMethods;
+ bind.OutCoder -= (UInt32)numEmptyMethods;
+ }
+ _methods.DeleteFrontal(numEmptyMethods);
+ }
+
+ AddDefaultMethod();
+
+ if (!_filterMethod.MethodName.IsEmpty())
+ {
+ FOR_VECTOR (k, _binds)
+ {
+ CBind &bind = _binds[k];
+ bind.InCoder++;
+ bind.OutCoder++;
+ }
+ _methods.Insert(0, _filterMethod);
+ }
+
+ FOR_VECTOR (k, _binds)
+ {
+ const CBind &bind = _binds[k];
+ if (bind.InCoder >= (UInt32)_methods.Size() ||
+ bind.OutCoder >= (UInt32)_methods.Size())
+ return E_INVALIDARG;
+ }
+
return S_OK;
COM_TRY_END
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHeader.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHeader.cpp
index 5b5f2fb37..acff2fdd8 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHeader.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHeader.cpp
@@ -1,6 +1,7 @@
// 7zHeader.cpp
#include "StdAfx.h"
+
#include "7zHeader.h"
namespace NArchive {
@@ -11,4 +12,8 @@ Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
#endif
+// We can change signature. So file doesn't contain correct signature.
+// struct SignatureInitializer { SignatureInitializer() { kSignature[0]--; } };
+// static SignatureInitializer g_SignatureInitializer;
+
}}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHeader.h b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHeader.h
index 30622b90e..61dad655d 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHeader.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zHeader.h
@@ -3,12 +3,12 @@
#ifndef __7Z_HEADER_H
#define __7Z_HEADER_H
-#include "../../../Common/Types.h"
+#include "../../../Common/MyTypes.h"
namespace NArchive {
namespace N7z {
-const int kSignatureSize = 6;
+const unsigned kSignatureSize = 6;
extern Byte kSignature[kSignatureSize];
// #define _7Z_VOL
@@ -57,11 +57,11 @@ namespace NID
kHeader,
kArchiveProperties,
-
+
kAdditionalStreamsInfo,
kMainStreamsInfo,
kFilesInfo,
-
+
kPackInfo,
kUnpackInfo,
kSubStreamsInfo,
@@ -82,13 +82,17 @@ namespace NID
kCTime,
kATime,
kMTime,
- kWinAttributes,
+ kWinAttrib,
kComment,
kEncodedHeader,
kStartPos,
kDummy
+
+ // kNtSecure,
+ // kParent,
+ // kIsAux
};
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zIn.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zIn.cpp
index b11819616..28ec5e083 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zIn.cpp
@@ -2,6 +2,12 @@
#include "StdAfx.h"
+#ifdef _WIN32
+#include <wchar.h>
+#else
+#include <ctype.h>
+#endif
+
#include "../../../../C/7zCrc.h"
#include "../../../../C/CpuArch.h"
@@ -20,15 +26,21 @@
#define FORMAT_7Z_RECOVERY
#endif
+using namespace NWindows;
+using namespace NCOM;
+
namespace NArchive {
namespace N7z {
-static void BoolVector_Fill_False(CBoolVector &v, int size)
+static const UInt32 k_LZMA2 = 0x21;
+static const UInt32 k_LZMA = 0x030101;
+
+static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
{
- v.Clear();
- v.Reserve(size);
- for (int i = 0; i < size; i++)
- v.Add(false);
+ v.ClearAndSetSize(size);
+ bool *p = &v[0];
+ for (unsigned i = 0; i < size; i++)
+ p[i] = false;
}
static bool BoolVector_GetAndSet(CBoolVector &v, UInt32 index)
@@ -40,11 +52,11 @@ static bool BoolVector_GetAndSet(CBoolVector &v, UInt32 index)
return res;
}
-bool CFolder::CheckStructure() const
+bool CFolder::CheckStructure(unsigned numUnpackSizes) const
{
- const int kNumCodersMax = sizeof(UInt32) * 8; // don't change it
- const int kMaskSize = sizeof(UInt32) * 8; // it must be >= kNumCodersMax
- const int kNumBindsMax = 32;
+ const unsigned kNumCodersMax = sizeof(UInt32) * 8; // don't change it
+ const unsigned kMaskSize = sizeof(UInt32) * 8; // it must be >= kNumCodersMax
+ const unsigned kNumBindsMax = 32;
if (Coders.Size() > kNumCodersMax || BindPairs.Size() > kNumBindsMax)
return false;
@@ -52,28 +64,28 @@ bool CFolder::CheckStructure() const
{
CBoolVector v;
BoolVector_Fill_False(v, BindPairs.Size() + PackStreams.Size());
-
- int i;
+
+ unsigned i;
for (i = 0; i < BindPairs.Size(); i++)
if (BoolVector_GetAndSet(v, BindPairs[i].InIndex))
return false;
for (i = 0; i < PackStreams.Size(); i++)
if (BoolVector_GetAndSet(v, PackStreams[i]))
return false;
-
- BoolVector_Fill_False(v, UnpackSizes.Size());
+
+ BoolVector_Fill_False(v, numUnpackSizes);
for (i = 0; i < BindPairs.Size(); i++)
if (BoolVector_GetAndSet(v, BindPairs[i].OutIndex))
return false;
}
-
+
UInt32 mask[kMaskSize];
- int i;
+ unsigned i;
for (i = 0; i < kMaskSize; i++)
mask[i] = 0;
{
- CIntVector inStreamToCoder, outStreamToCoder;
+ CUIntVector inStreamToCoder, outStreamToCoder;
for (i = 0; i < Coders.Size(); i++)
{
CNum j;
@@ -83,16 +95,16 @@ bool CFolder::CheckStructure() const
for (j = 0; j < coder.NumOutStreams; j++)
outStreamToCoder.Add(i);
}
-
+
for (i = 0; i < BindPairs.Size(); i++)
{
const CBindPair &bp = BindPairs[i];
mask[inStreamToCoder[bp.InIndex]] |= (1 << outStreamToCoder[bp.OutIndex]);
}
}
-
+
for (i = 0; i < kMaskSize; i++)
- for (int j = 0; j < kMaskSize; j++)
+ for (unsigned j = 0; j < kMaskSize; j++)
if (((1 << j) & mask[i]) != 0)
mask[i] |= mask[j];
@@ -104,43 +116,23 @@ bool CFolder::CheckStructure() const
}
class CInArchiveException {};
+class CUnsupportedFeatureException: public CInArchiveException {};
static void ThrowException() { throw CInArchiveException(); }
static inline void ThrowEndOfData() { ThrowException(); }
-static inline void ThrowUnsupported() { ThrowException(); }
+static inline void ThrowUnsupported() { throw CUnsupportedFeatureException(); }
static inline void ThrowIncorrect() { ThrowException(); }
-static inline void ThrowUnsupportedVersion() { ThrowException(); }
-
-/*
-class CInArchiveException
-{
-public:
- enum CCauseType
- {
- kUnsupportedVersion = 0,
- kUnsupported,
- kIncorrect,
- kEndOfData
- } Cause;
- CInArchiveException(CCauseType cause): Cause(cause) {};
-};
-
-static void ThrowException(CInArchiveException::CCauseType c) { throw CInArchiveException(c); }
-static void ThrowEndOfData() { ThrowException(CInArchiveException::kEndOfData); }
-static void ThrowUnsupported() { ThrowException(CInArchiveException::kUnsupported); }
-static void ThrowIncorrect() { ThrowException(CInArchiveException::kIncorrect); }
-static void ThrowUnsupportedVersion() { ThrowException(CInArchiveException::kUnsupportedVersion); }
-*/
class CStreamSwitch
{
CInArchive *_archive;
bool _needRemove;
+ bool _needUpdatePos;
public:
- CStreamSwitch(): _needRemove(false) {}
+ CStreamSwitch(): _needRemove(false), _needUpdatePos(false) {}
~CStreamSwitch() { Remove(); }
void Remove();
- void Set(CInArchive *archive, const Byte *data, size_t size);
+ void Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos);
void Set(CInArchive *archive, const CByteBuffer &byteBuffer);
void Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector);
};
@@ -149,22 +141,25 @@ void CStreamSwitch::Remove()
{
if (_needRemove)
{
- _archive->DeleteByteStream();
+ if (_archive->_inByteBack->GetRem() != 0)
+ _archive->ThereIsHeaderError = true;
+ _archive->DeleteByteStream(_needUpdatePos);
_needRemove = false;
}
}
-void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size)
+void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos)
{
Remove();
_archive = archive;
_archive->AddByteStream(data, size);
_needRemove = true;
+ _needUpdatePos = needUpdatePos;
}
void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer)
{
- Set(archive, byteBuffer, byteBuffer.GetCapacity());
+ Set(archive, byteBuffer, byteBuffer.Size(), false);
}
void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector)
@@ -173,13 +168,22 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *d
Byte external = archive->ReadByte();
if (external != 0)
{
- int dataIndex = (int)archive->ReadNum();
- if (dataIndex < 0 || dataIndex >= dataVector->Size())
+ CNum dataIndex = archive->ReadNum();
+ if (dataIndex >= dataVector->Size())
ThrowIncorrect();
Set(archive, (*dataVector)[dataIndex]);
}
}
+void CInArchive::AddByteStream(const Byte *buf, size_t size)
+{
+ if (_numInByteBufs == kNumBufLevelsMax)
+ ThrowIncorrect();
+ _inByteBack = &_inByteVector[_numInByteBufs++];
+ _inByteBack->Init(buf, size);
+}
+
+
Byte CInByte2::ReadByte()
{
if (_pos >= _size)
@@ -191,8 +195,8 @@ void CInByte2::ReadBytes(Byte *data, size_t size)
{
if (size > _size - _pos)
ThrowEndOfData();
- for (size_t i = 0; i < size; i++)
- data[i] = _buffer[_pos++];
+ memcpy(data, _buffer + _pos, size);
+ _pos += size;
}
void CInByte2::SkipData(UInt64 size)
@@ -207,31 +211,75 @@ void CInByte2::SkipData()
SkipData(ReadNumber());
}
-UInt64 CInByte2::ReadNumber()
+static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed)
{
- if (_pos >= _size)
- ThrowEndOfData();
- Byte firstByte = _buffer[_pos++];
- Byte mask = 0x80;
- UInt64 value = 0;
- for (int i = 0; i < 8; i++)
+ if (size == 0)
+ {
+ processed = 0;
+ return 0;
+ }
+ Byte firstByte = *p++;
+ size--;
+ if ((firstByte & 0x80) == 0)
+ {
+ processed = 1;
+ return firstByte;
+ }
+ Byte mask = 0x40;
+ if (size == 0)
+ {
+ processed = 0;
+ return 0;
+ }
+ UInt64 value = (UInt64)*p;
+ p++;
+ size--;
+ for (unsigned i = 1; i < 8; i++)
{
if ((firstByte & mask) == 0)
{
UInt64 highPart = firstByte & (mask - 1);
value += (highPart << (i * 8));
+ processed = i + 1;
return value;
}
- if (_pos >= _size)
- ThrowEndOfData();
- value |= ((UInt64)_buffer[_pos++] << (8 * i));
+ if (size == 0)
+ {
+ processed = 0;
+ return 0;
+ }
+ value |= ((UInt64)*p << (i * 8));
+ p++;
+ size--;
mask >>= 1;
}
+ processed = 9;
return value;
}
+UInt64 CInByte2::ReadNumber()
+{
+ size_t processed;
+ UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed);
+ if (processed == 0)
+ ThrowEndOfData();
+ _pos += processed;
+ return res;
+}
+
CNum CInByte2::ReadNum()
{
+ /*
+ if (_pos < _size)
+ {
+ Byte val = _buffer[_pos];
+ if ((unsigned)val < 0x80)
+ {
+ _pos++;
+ return (unsigned)val;
+ }
+ }
+ */
UInt64 value = ReadNumber();
if (value > kNumMax)
ThrowUnsupported();
@@ -256,48 +304,21 @@ UInt64 CInByte2::ReadUInt64()
return res;
}
-void CInByte2::ReadString(UString &s)
-{
- const Byte *buf = _buffer + _pos;
- size_t rem = (_size - _pos) / 2 * 2;
- {
- size_t i;
- for (i = 0; i < rem; i += 2)
- if (buf[i] == 0 && buf[i + 1] == 0)
- break;
- if (i == rem)
- ThrowEndOfData();
- rem = i;
- }
- int len = (int)(rem / 2);
- if (len < 0 || (size_t)len * 2 != rem)
- ThrowUnsupported();
- wchar_t *p = s.GetBuffer(len);
- int i;
- for (i = 0; i < len; i++, buf += 2)
- p[i] = (wchar_t)Get16(buf);
- s.ReleaseBuffer(len);
- _pos += rem + 2;
-}
+#define CHECK_SIGNATURE if (p[0] != '7' || p[1] != 'z' || p[2] != 0xBC || p[3] != 0xAF || p[4] != 0x27 || p[5] != 0x1C) return false;
static inline bool TestSignature(const Byte *p)
{
- for (int i = 0; i < kSignatureSize; i++)
- if (p[i] != kSignature[i])
- return false;
- return CrcCalc(p + 12, 20) == GetUi32(p + 8);
+ CHECK_SIGNATURE
+ return CrcCalc(p + 12, 20) == Get32(p + 8);
}
#ifdef FORMAT_7Z_RECOVERY
static inline bool TestSignature2(const Byte *p)
{
- int i;
- for (i = 0; i < kSignatureSize; i++)
- if (p[i] != kSignature[i])
- return false;
- if (CrcCalc(p + 12, 20) == GetUi32(p + 8))
+ CHECK_SIGNATURE;
+ if (CrcCalc(p + 12, 20) == Get32(p + 8))
return true;
- for (i = 8; i < kHeaderSize; i++)
+ for (unsigned i = 8; i < kHeaderSize; i++)
if (p[i] != 0)
return false;
return (p[6] != 0 || p[7] != 0);
@@ -312,48 +333,52 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
if (TestSignature2(_header))
return S_OK;
+ if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0)
+ return S_FALSE;
+
+ const UInt32 kBufSize = 1 << 15;
+ CByteArr buf(kBufSize);
+ memcpy(buf, _header, kHeaderSize);
+ UInt64 offset = 0;
- CByteBuffer byteBuffer;
- const UInt32 kBufferSize = (1 << 16);
- byteBuffer.SetCapacity(kBufferSize);
- Byte *buffer = byteBuffer;
- UInt32 numPrevBytes = kHeaderSize;
- memcpy(buffer, _header, kHeaderSize);
- UInt64 curTestPos = _arhiveBeginStreamPosition;
for (;;)
{
- if (searchHeaderSizeLimit != NULL)
- if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
- break;
- do
+ UInt32 readSize = kBufSize - kHeaderSize;
{
- UInt32 numReadBytes = kBufferSize - numPrevBytes;
- UInt32 processedSize;
- RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
- numPrevBytes += processedSize;
- if (processedSize == 0)
+ UInt64 rem = *searchHeaderSizeLimit - offset;
+ if (readSize > rem)
+ readSize = (UInt32)rem;
+ if (readSize == 0)
return S_FALSE;
}
- while (numPrevBytes <= kHeaderSize);
- UInt32 numTests = numPrevBytes - kHeaderSize;
- for (UInt32 pos = 0; pos < numTests; pos++)
+ UInt32 processed = 0;
+ RINOK(stream->Read(buf + kHeaderSize, readSize, &processed));
+ if (processed == 0)
+ return S_FALSE;
+ for (UInt32 pos = 0;;)
{
- for (; buffer[pos] != '7' && pos < numTests; pos++) {}
- if (pos == numTests)
+ const Byte *p = buf + pos + 1;
+ const Byte *lim = buf + processed;
+ for (; p <= lim; p += 4)
+ {
+ if (p[0] == '7') break;
+ if (p[1] == '7') { p += 1; break; }
+ if (p[2] == '7') { p += 2; break; }
+ if (p[3] == '7') { p += 3; break; }
+ };
+ if (p > lim)
break;
- if (TestSignature(buffer + pos))
+ pos = (UInt32)(p - buf);
+ if (TestSignature(p))
{
- memcpy(_header, buffer + pos, kHeaderSize);
- curTestPos += pos;
- _arhiveBeginStreamPosition = curTestPos;
- return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
+ memcpy(_header, p, kHeaderSize);
+ _arhiveBeginStreamPosition += offset + pos;
+ return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL);
}
}
- curTestPos += numTests;
- numPrevBytes -= numTests;
- memmove(buffer, buffer + numTests, numPrevBytes);
+ offset += processed;
+ memmove(buf, buf + processed, kHeaderSize);
}
- return S_FALSE;
}
// S_FALSE means that file is not archive
@@ -362,14 +387,18 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
HeadersSize = 0;
Close();
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
+ RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition))
+ RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL))
RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
_stream = stream;
return S_OK;
}
-
+
void CInArchive::Close()
{
+ _numInByteBufs = 0;
_stream.Release();
+ ThereIsHeaderError = false;
}
void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)
@@ -382,30 +411,32 @@ void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)
}
}
-void CInArchive::GetNextFolderItem(CFolder &folder)
+// CFolder &folder can be non empty. So we must set all fields
+
+void CInByte2::ParseFolder(CFolder &folder)
{
CNum numCoders = ReadNum();
- folder.Coders.Clear();
- folder.Coders.Reserve((int)numCoders);
+ folder.Coders.SetSize(numCoders);
+
CNum numInStreams = 0;
CNum numOutStreams = 0;
CNum i;
for (i = 0; i < numCoders; i++)
{
- folder.Coders.Add(CCoderInfo());
- CCoderInfo &coder = folder.Coders.Back();
-
+ CCoderInfo &coder = folder.Coders[i];
{
Byte mainByte = ReadByte();
- int idSize = (mainByte & 0xF);
- Byte longID[15];
- ReadBytes(longID, idSize);
- if (idSize > 8)
+ if ((mainByte & 0xC0) != 0)
ThrowUnsupported();
+ unsigned idSize = (mainByte & 0xF);
+ if (idSize > 8 || idSize > GetRem())
+ ThrowUnsupported();
+ const Byte *longID = GetPtr();
UInt64 id = 0;
- for (int j = 0; j < idSize; j++)
- id |= (UInt64)longID[idSize - 1 - j] << (8 * j);
+ for (unsigned j = 0; j < idSize; j++)
+ id = ((id << 8) | longID[j]);
+ SkipDataNoCheck(idSize);
coder.MethodID = id;
if ((mainByte & 0x10) != 0)
@@ -421,53 +452,171 @@ void CInArchive::GetNextFolderItem(CFolder &folder)
if ((mainByte & 0x20) != 0)
{
CNum propsSize = ReadNum();
- coder.Props.SetCapacity((size_t)propsSize);
+ coder.Props.Alloc((size_t)propsSize);
ReadBytes((Byte *)coder.Props, (size_t)propsSize);
}
- if ((mainByte & 0x80) != 0)
- ThrowUnsupported();
+ else
+ coder.Props.Free();
}
numInStreams += coder.NumInStreams;
numOutStreams += coder.NumOutStreams;
}
CNum numBindPairs = numOutStreams - 1;
- folder.BindPairs.Clear();
- folder.BindPairs.Reserve(numBindPairs);
+ folder.BindPairs.SetSize(numBindPairs);
for (i = 0; i < numBindPairs; i++)
{
- CBindPair bp;
+ CBindPair &bp = folder.BindPairs[i];
bp.InIndex = ReadNum();
bp.OutIndex = ReadNum();
- folder.BindPairs.Add(bp);
}
if (numInStreams < numBindPairs)
ThrowUnsupported();
CNum numPackStreams = numInStreams - numBindPairs;
- folder.PackStreams.Reserve(numPackStreams);
+ folder.PackStreams.SetSize(numPackStreams);
if (numPackStreams == 1)
{
for (i = 0; i < numInStreams; i++)
if (folder.FindBindPairForInStream(i) < 0)
{
- folder.PackStreams.Add(i);
+ folder.PackStreams[0] = i;
break;
}
- if (folder.PackStreams.Size() != 1)
+ if (i == numInStreams)
ThrowUnsupported();
}
else
for (i = 0; i < numPackStreams; i++)
- folder.PackStreams.Add(ReadNum());
+ folder.PackStreams[i] = ReadNum();
+}
+
+void CFolders::ParseFolderInfo(unsigned folderIndex, CFolder &folder) const
+{
+ size_t startPos = FoCodersDataOffset[folderIndex];
+ CInByte2 inByte;
+ inByte.Init(CodersData + startPos, FoCodersDataOffset[folderIndex + 1] - startPos);
+ inByte.ParseFolder(folder);
+ if (inByte.GetRem() != 0)
+ throw 20120424;
+}
+
+
+void CDatabase::GetPath(unsigned index, UString &path) const
+{
+ path.Empty();
+ if (!NameOffsets || !NamesBuf)
+ return;
+
+ size_t offset = NameOffsets[index];
+ size_t size = NameOffsets[index + 1] - offset - 1;
+
+ if (size >= (1 << 20))
+ return;
+
+ wchar_t *s = path.GetBuffer((unsigned)size);
+
+ const Byte *p = ((const Byte *)NamesBuf + offset * 2);
+
+ #if defined(_WIN32) && defined(MY_CPU_LE)
+
+ wmemcpy(s, (const wchar_t *)p, size);
+
+ #else
+
+ for (size_t i = 0; i < size; i++)
+ {
+ *s = Get16(p);
+ p += 2;
+ s++;
+ }
+
+ #endif
+
+ path.ReleaseBuffer((unsigned)size);
+}
+
+HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
+{
+ PropVariant_Clear(path);
+ if (!NameOffsets || !NamesBuf)
+ return S_OK;
+
+ size_t offset = NameOffsets[index];
+ size_t size = NameOffsets[index + 1] - offset;
+
+ if (size >= (1 << 14))
+ return S_OK;
+
+ RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1));
+ wchar_t *s = path->bstrVal;
+
+ const Byte *p = ((const Byte *)NamesBuf + offset * 2);
+
+ for (size_t i = 0; i < size; i++)
+ {
+ wchar_t c = Get16(p);
+ p += 2;
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ if (c == L'/')
+ c = WCHAR_PATH_SEPARATOR;
+ #endif
+ *s++ = c;
+ }
+
+ return S_OK;
+
+ /*
+ unsigned cur = index;
+ unsigned size = 0;
+
+ for (int i = 0;; i++)
+ {
+ size_t len = NameOffsets[cur + 1] - NameOffsets[cur];
+ size += (unsigned)len;
+ if (i > 256 || len > (1 << 14) || size > (1 << 14))
+ return PropVarEm_Set_Str(path, "[TOO-LONG]");
+ cur = Files[cur].Parent;
+ if (cur < 0)
+ break;
+ }
+ size--;
+
+ RINOK(PropVarEm_Alloc_Bstr(path, size));
+ wchar_t *s = path->bstrVal;
+ s += size;
+ *s = 0;
+ cur = index;
+
+ for (;;)
+ {
+ unsigned len = (unsigned)(NameOffsets[cur + 1] - NameOffsets[cur] - 1);
+ const Byte *p = (const Byte *)NamesBuf + (NameOffsets[cur + 1] * 2) - 2;
+ do
+ {
+ p -= 2;
+ --s;
+ wchar_t c = Get16(p);
+ if (c == '/')
+ c = WCHAR_PATH_SEPARATOR;
+ *s = c;
+ }
+ while (--len);
+ const CFileItem &file = Files[cur];
+ cur = file.Parent;
+ if (cur < 0)
+ return S_OK;
+ *(--s) = (file.IsAltStream ? ':' : WCHAR_PATH_SEPARATOR);
+ }
+ */
}
-void CInArchive::WaitAttribute(UInt64 attribute)
+void CInArchive::WaitId(UInt64 id)
{
for (;;)
{
UInt64 type = ReadID();
- if (type == attribute)
+ if (type == id)
return;
if (type == NID::kEnd)
ThrowIncorrect();
@@ -475,91 +624,210 @@ void CInArchive::WaitAttribute(UInt64 attribute)
}
}
-void CInArchive::ReadHashDigests(int numItems,
- CBoolVector &digestsDefined,
- CRecordVector<UInt32> &digests)
+void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
{
- ReadBoolVector2(numItems, digestsDefined);
- digests.Clear();
- digests.Reserve(numItems);
- for (int i = 0; i < numItems; i++)
+ ReadBoolVector2(numItems, crcs.Defs);
+ crcs.Vals.ClearAndSetSize(numItems);
+ UInt32 *p = &crcs.Vals[0];
+ const bool *defs = &crcs.Defs[0];
+ for (unsigned i = 0; i < numItems; i++)
{
UInt32 crc = 0;
- if (digestsDefined[i])
+ if (defs[i])
crc = ReadUInt32();
- digests.Add(crc);
+ p[i] = crc;
}
}
-void CInArchive::ReadPackInfo(
- UInt64 &dataOffset,
- CRecordVector<UInt64> &packSizes,
- CBoolVector &packCRCsDefined,
- CRecordVector<UInt32> &packCRCs)
+void CInArchive::ReadPackInfo(CFolders &f)
{
- dataOffset = ReadNumber();
CNum numPackStreams = ReadNum();
- WaitAttribute(NID::kSize);
- packSizes.Clear();
- packSizes.Reserve(numPackStreams);
+ WaitId(NID::kSize);
+ f.PackPositions.Alloc(numPackStreams + 1);
+ f.NumPackStreams = numPackStreams;
+ UInt64 sum = 0;
for (CNum i = 0; i < numPackStreams; i++)
- packSizes.Add(ReadNumber());
+ {
+ f.PackPositions[i] = sum;
+ UInt64 packSize = ReadNumber();
+ sum += packSize;
+ if (sum < packSize)
+ ThrowIncorrect();
+ }
+ f.PackPositions[numPackStreams] = sum;
UInt64 type;
for (;;)
{
type = ReadID();
if (type == NID::kEnd)
- break;
+ return;
if (type == NID::kCRC)
{
- ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs);
+ CUInt32DefVector PackCRCs;
+ ReadHashDigests(numPackStreams, PackCRCs);
continue;
}
SkipData();
}
- if (packCRCsDefined.IsEmpty())
- {
- BoolVector_Fill_False(packCRCsDefined, numPackStreams);
- packCRCs.Reserve(numPackStreams);
- packCRCs.Clear();
- for (CNum i = 0; i < numPackStreams; i++)
- packCRCs.Add(0);
- }
}
void CInArchive::ReadUnpackInfo(
const CObjectVector<CByteBuffer> *dataVector,
- CObjectVector<CFolder> &folders)
+ CFolders &folders)
{
- WaitAttribute(NID::kFolder);
+ WaitId(NID::kFolder);
CNum numFolders = ReadNum();
+ CNum numCodersOutStreams = 0;
{
CStreamSwitch streamSwitch;
streamSwitch.Set(this, dataVector);
- folders.Clear();
- folders.Reserve(numFolders);
- for (CNum i = 0; i < numFolders; i++)
+ const Byte *startBufPtr = _inByteBack->GetPtr();
+ folders.NumFolders = numFolders;
+
+ folders.FoStartPackStreamIndex.Alloc(numFolders + 1);
+ folders.FoToMainUnpackSizeIndex.Alloc(numFolders);
+ folders.FoCodersDataOffset.Alloc(numFolders + 1);
+ folders.FoToCoderUnpackSizes.Alloc(numFolders + 1);
+
+ CRecordVector<bool> InStreamUsed;
+ CRecordVector<bool> OutStreamUsed;
+
+ CNum packStreamIndex = 0;
+ CNum fo;
+ CInByte2 *inByte = _inByteBack;
+ for (fo = 0; fo < numFolders; fo++)
{
- folders.Add(CFolder());
- GetNextFolderItem(folders.Back());
- }
- }
+ UInt32 numOutStreams = 0;
+ UInt32 indexOfMainStream = 0;
+ UInt32 numPackStreams = 0;
+ folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
+
+ numOutStreams = 0;
+ CNum numInStreams = 0;
+ CNum numCoders = inByte->ReadNum();
+ for (CNum ci = 0; ci < numCoders; ci++)
+ {
+ Byte mainByte = inByte->ReadByte();
+ if ((mainByte & 0xC0) != 0)
+ ThrowUnsupported();
+ unsigned idSize = (mainByte & 0xF);
+ if (idSize > 8)
+ ThrowUnsupported();
+ if (idSize > inByte->GetRem())
+ ThrowEndOfData();
+ const Byte *longID = inByte->GetPtr();
+ UInt64 id = 0;
+ for (unsigned j = 0; j < idSize; j++)
+ id = ((id << 8) | longID[j]);
+ inByte->SkipDataNoCheck(idSize);
+ if (folders.ParsedMethods.IDs.Size() < 128)
+ folders.ParsedMethods.IDs.AddToUniqueSorted(id);
+ CNum coderInStreams = 1;
+ CNum coderOutStreams = 1;
+ if ((mainByte & 0x10) != 0)
+ {
+ coderInStreams = inByte->ReadNum();
+ coderOutStreams = inByte->ReadNum();
+ }
+ numInStreams += coderInStreams;
+ if (numInStreams < coderInStreams)
+ ThrowUnsupported();
+ numOutStreams += coderOutStreams;
+ if (numOutStreams < coderOutStreams)
+ ThrowUnsupported();
+ if ((mainByte & 0x20) != 0)
+ {
+ CNum propsSize = inByte->ReadNum();
+ if (propsSize > inByte->GetRem())
+ ThrowEndOfData();
+ if (id == k_LZMA2 && propsSize == 1)
+ {
+ Byte v = *_inByteBack->GetPtr();
+ if (folders.ParsedMethods.Lzma2Prop < v)
+ folders.ParsedMethods.Lzma2Prop = v;
+ }
+ else if (id == k_LZMA && propsSize == 5)
+ {
+ UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1);
+ if (folders.ParsedMethods.LzmaDic < dicSize)
+ folders.ParsedMethods.LzmaDic = dicSize;
+ }
+ inByte->SkipDataNoCheck((size_t)propsSize);
+ }
+ }
+
+ if (numOutStreams == 1 && numInStreams == 1)
+ {
+ indexOfMainStream = 0;
+ numPackStreams = 1;
+ }
+ else
+ {
+ UInt32 i;
+ if (numOutStreams == 0)
+ ThrowUnsupported();
+ CNum numBindPairs = numOutStreams - 1;
+ if (numInStreams < numBindPairs)
+ ThrowUnsupported();
+ if (numInStreams >= 256 || numOutStreams >= 256)
+ ThrowUnsupported();
+
+ InStreamUsed.ClearAndSetSize(numInStreams);
+ for (i = 0; i < numInStreams; i++)
+ InStreamUsed[i] = false;
+
+ OutStreamUsed.ClearAndSetSize(numOutStreams);
+ for (i = 0; i < numOutStreams; i++)
+ OutStreamUsed[i] = false;
+
+ for (i = 0; i < numBindPairs; i++)
+ {
+ CNum index = ReadNum();
+ if (index >= numInStreams || InStreamUsed[index])
+ ThrowUnsupported();
+ InStreamUsed[index] = true;
+ index = ReadNum();
+ if (index >= numOutStreams || OutStreamUsed[index])
+ ThrowUnsupported();
+ OutStreamUsed[index] = true;
+ }
- WaitAttribute(NID::kCodersUnpackSize);
+ numPackStreams = numInStreams - numBindPairs;
- CNum i;
- for (i = 0; i < numFolders; i++)
- {
- CFolder &folder = folders[i];
- CNum numOutStreams = folder.GetNumOutStreams();
- folder.UnpackSizes.Reserve(numOutStreams);
- for (CNum j = 0; j < numOutStreams; j++)
- folder.UnpackSizes.Add(ReadNumber());
+ if (numPackStreams != 1)
+ for (i = 0; i < numPackStreams; i++)
+ inByte->ReadNum(); // PackStreams
+
+ for (i = 0; i < numOutStreams; i++)
+ if (!OutStreamUsed[i])
+ {
+ indexOfMainStream = i;
+ break;
+ }
+ if (i == numOutStreams)
+ ThrowUnsupported();
+ }
+ folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
+ numCodersOutStreams += numOutStreams;
+ folders.FoStartPackStreamIndex[fo] = packStreamIndex;
+ packStreamIndex += numPackStreams;
+ folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
+ }
+ size_t dataSize = _inByteBack->GetPtr() - startBufPtr;
+ folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
+ folders.FoStartPackStreamIndex[fo] = packStreamIndex;
+ folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
+ folders.CodersData.CopyFrom(startBufPtr, dataSize);
}
+ WaitId(NID::kCodersUnpackSize);
+ folders.CoderUnpackSizes.Alloc(numCodersOutStreams);
+ for (CNum i = 0; i < numCodersOutStreams; i++)
+ folders.CoderUnpackSizes[i] = ReadNumber();
+
for (;;)
{
UInt64 type = ReadID();
@@ -567,15 +835,7 @@ void CInArchive::ReadUnpackInfo(
return;
if (type == NID::kCRC)
{
- CBoolVector crcsDefined;
- CRecordVector<UInt32> crcs;
- ReadHashDigests(numFolders, crcsDefined, crcs);
- for (i = 0; i < numFolders; i++)
- {
- CFolder &folder = folders[i];
- folder.UnpackCRCDefined = crcsDefined[i];
- folder.UnpackCRC = crcs[i];
- }
+ ReadHashDigests(numFolders, folders.FolderCRCs);
continue;
}
SkipData();
@@ -583,170 +843,217 @@ void CInArchive::ReadUnpackInfo(
}
void CInArchive::ReadSubStreamsInfo(
- const CObjectVector<CFolder> &folders,
- CRecordVector<CNum> &numUnpackStreamsInFolders,
+ CFolders &folders,
CRecordVector<UInt64> &unpackSizes,
- CBoolVector &digestsDefined,
- CRecordVector<UInt32> &digests)
+ CUInt32DefVector &digests)
{
- numUnpackStreamsInFolders.Clear();
- numUnpackStreamsInFolders.Reserve(folders.Size());
+ folders.NumUnpackStreamsVector.Alloc(folders.NumFolders);
+ CNum i;
+ for (i = 0; i < folders.NumFolders; i++)
+ folders.NumUnpackStreamsVector[i] = 1;
+
UInt64 type;
+
for (;;)
{
type = ReadID();
if (type == NID::kNumUnpackStream)
{
- for (int i = 0; i < folders.Size(); i++)
- numUnpackStreamsInFolders.Add(ReadNum());
+ for (i = 0; i < folders.NumFolders; i++)
+ folders.NumUnpackStreamsVector[i] = ReadNum();
continue;
}
- if (type == NID::kCRC || type == NID::kSize)
- break;
- if (type == NID::kEnd)
+ if (type == NID::kCRC || type == NID::kSize || type == NID::kEnd)
break;
SkipData();
}
- if (numUnpackStreamsInFolders.IsEmpty())
- for (int i = 0; i < folders.Size(); i++)
- numUnpackStreamsInFolders.Add(1);
-
- int i;
- for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
+ if (type == NID::kSize)
{
- // v3.13 incorrectly worked with empty folders
- // v4.07: we check that folder is empty
- CNum numSubstreams = numUnpackStreamsInFolders[i];
- if (numSubstreams == 0)
- continue;
- UInt64 sum = 0;
- for (CNum j = 1; j < numSubstreams; j++)
- if (type == NID::kSize)
+ for (i = 0; i < folders.NumFolders; i++)
+ {
+ // v3.13 incorrectly worked with empty folders
+ // v4.07: we check that folder is empty
+ CNum numSubstreams = folders.NumUnpackStreamsVector[i];
+ if (numSubstreams == 0)
+ continue;
+ UInt64 sum = 0;
+ for (CNum j = 1; j < numSubstreams; j++)
{
UInt64 size = ReadNumber();
unpackSizes.Add(size);
sum += size;
+ if (sum < size)
+ ThrowIncorrect();
}
- unpackSizes.Add(folders[i].GetUnpackSize() - sum);
- }
- if (type == NID::kSize)
+ UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i);
+ if (folderUnpackSize < sum)
+ ThrowIncorrect();
+ unpackSizes.Add(folderUnpackSize - sum);
+ }
type = ReadID();
+ }
+ else
+ {
+ for (i = 0; i < folders.NumFolders; i++)
+ {
+ /* v9.26 - v9.29 incorrectly worked:
+ if (folders.NumUnpackStreamsVector[i] == 0), it threw error */
+ CNum val = folders.NumUnpackStreamsVector[i];
+ if (val > 1)
+ ThrowIncorrect();
+ if (val == 1)
+ unpackSizes.Add(folders.GetFolderUnpackSize(i));
+ }
+ }
- int numDigests = 0;
- int numDigestsTotal = 0;
- for (i = 0; i < folders.Size(); i++)
+ unsigned numDigests = 0;
+ for (i = 0; i < folders.NumFolders; i++)
{
- CNum numSubstreams = numUnpackStreamsInFolders[i];
- if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
+ CNum numSubstreams = folders.NumUnpackStreamsVector[i];
+ if (numSubstreams != 1 || !folders.FolderCRCs.ValidAndDefined(i))
numDigests += numSubstreams;
- numDigestsTotal += numSubstreams;
}
for (;;)
{
+ if (type == NID::kEnd)
+ break;
if (type == NID::kCRC)
{
- CBoolVector digestsDefined2;
- CRecordVector<UInt32> digests2;
- ReadHashDigests(numDigests, digestsDefined2, digests2);
- int digestIndex = 0;
- for (i = 0; i < folders.Size(); i++)
+ // CUInt32DefVector digests2;
+ // ReadHashDigests(numDigests, digests2);
+ CBoolVector digests2;
+ ReadBoolVector2(numDigests, digests2);
+
+ digests.ClearAndSetSize(unpackSizes.Size());
+
+ unsigned k = 0;
+ unsigned k2 = 0;
+
+ for (i = 0; i < folders.NumFolders; i++)
{
- CNum numSubstreams = numUnpackStreamsInFolders[i];
- const CFolder &folder = folders[i];
- if (numSubstreams == 1 && folder.UnpackCRCDefined)
+ CNum numSubstreams = folders.NumUnpackStreamsVector[i];
+ if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i))
{
- digestsDefined.Add(true);
- digests.Add(folder.UnpackCRC);
+ digests.Defs[k] = true;
+ digests.Vals[k] = folders.FolderCRCs.Vals[i];
+ k++;
+ }
+ else for (CNum j = 0; j < numSubstreams; j++)
+ {
+ bool defined = digests2[k2++];
+ digests.Defs[k] = defined;
+ UInt32 crc = 0;
+ if (defined)
+ crc = ReadUInt32();
+ digests.Vals[k] = crc;
+ k++;
}
- else
- for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
- {
- digestsDefined.Add(digestsDefined2[digestIndex]);
- digests.Add(digests2[digestIndex]);
- }
}
+ // if (k != unpackSizes.Size()) throw 1234567;
}
- else if (type == NID::kEnd)
+ else
+ SkipData();
+
+ type = ReadID();
+ }
+
+ if (digests.Defs.Size() != unpackSizes.Size())
+ {
+ digests.ClearAndSetSize(unpackSizes.Size());
+ unsigned k = 0;
+ for (i = 0; i < folders.NumFolders; i++)
{
- if (digestsDefined.IsEmpty())
+ CNum numSubstreams = folders.NumUnpackStreamsVector[i];
+ if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i))
{
- BoolVector_Fill_False(digestsDefined, numDigestsTotal);
- digests.Clear();
- for (int i = 0; i < numDigestsTotal; i++)
- digests.Add(0);
+ digests.Defs[k] = true;
+ digests.Vals[k] = folders.FolderCRCs.Vals[i];
+ k++;
+ }
+ else for (CNum j = 0; j < numSubstreams; j++)
+ {
+ digests.Defs[k] = false;
+ digests.Vals[k] = 0;
+ k++;
}
- return;
}
- else
- SkipData();
- type = ReadID();
}
}
void CInArchive::ReadStreamsInfo(
const CObjectVector<CByteBuffer> *dataVector,
UInt64 &dataOffset,
- CRecordVector<UInt64> &packSizes,
- CBoolVector &packCRCsDefined,
- CRecordVector<UInt32> &packCRCs,
- CObjectVector<CFolder> &folders,
- CRecordVector<CNum> &numUnpackStreamsInFolders,
+ CFolders &folders,
CRecordVector<UInt64> &unpackSizes,
- CBoolVector &digestsDefined,
- CRecordVector<UInt32> &digests)
+ CUInt32DefVector &digests)
{
- for (;;)
+ UInt64 type = ReadID();
+
+ if (type == NID::kPackInfo)
{
- UInt64 type = ReadID();
- if (type > ((UInt32)1 << 30))
- ThrowIncorrect();
- switch((UInt32)type)
+ dataOffset = ReadNumber();
+ ReadPackInfo(folders);
+ type = ReadID();
+ }
+
+ if (type == NID::kUnpackInfo)
+ {
+ ReadUnpackInfo(dataVector, folders);
+ type = ReadID();
+ }
+
+ if (folders.NumFolders != 0 && !folders.PackPositions)
+ {
+ // if there are folders, we need PackPositions also
+ folders.PackPositions.Alloc(1);
+ folders.PackPositions[0] = 0;
+ }
+
+ if (type == NID::kSubStreamsInfo)
+ {
+ ReadSubStreamsInfo(folders, unpackSizes, digests);
+ type = ReadID();
+ }
+ else
+ {
+ folders.NumUnpackStreamsVector.Alloc(folders.NumFolders);
+ /* If digests.Defs.Size() == 0, it means that there are no crcs.
+ So we don't need to fill digests with values. */
+ // digests.Vals.ClearAndSetSize(folders.NumFolders);
+ // BoolVector_Fill_False(digests.Defs, folders.NumFolders);
+ for (CNum i = 0; i < folders.NumFolders; i++)
{
- case NID::kEnd:
- return;
- case NID::kPackInfo:
- {
- ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs);
- break;
- }
- case NID::kUnpackInfo:
- {
- ReadUnpackInfo(dataVector, folders);
- break;
- }
- case NID::kSubStreamsInfo:
- {
- ReadSubStreamsInfo(folders, numUnpackStreamsInFolders,
- unpackSizes, digestsDefined, digests);
- break;
- }
- default:
- ThrowIncorrect();
+ folders.NumUnpackStreamsVector[i] = 1;
+ unpackSizes.Add(folders.GetFolderUnpackSize(i));
+ // digests.Vals[i] = 0;
}
}
+
+ if (type != NID::kEnd)
+ ThrowIncorrect();
}
-void CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
+void CInArchive::ReadBoolVector(unsigned numItems, CBoolVector &v)
{
- v.Clear();
- v.Reserve(numItems);
+ v.ClearAndSetSize(numItems);
Byte b = 0;
Byte mask = 0;
- for (int i = 0; i < numItems; i++)
+ bool *p = &v[0];
+ for (unsigned i = 0; i < numItems; i++)
{
if (mask == 0)
{
b = ReadByte();
mask = 0x80;
}
- v.Add((b & mask) != 0);
+ p[i] = ((b & mask) != 0);
mask >>= 1;
}
}
-void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
+void CInArchive::ReadBoolVector2(unsigned numItems, CBoolVector &v)
{
Byte allAreDefined = ReadByte();
if (allAreDefined == 0)
@@ -754,27 +1061,30 @@ void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
ReadBoolVector(numItems, v);
return;
}
- v.Clear();
- v.Reserve(numItems);
- for (int i = 0; i < numItems; i++)
- v.Add(true);
+ v.ClearAndSetSize(numItems);
+ bool *p = &v[0];
+ for (unsigned i = 0; i < numItems; i++)
+ p[i] = true;
}
void CInArchive::ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
- CUInt64DefVector &v, int numFiles)
+ CUInt64DefVector &v, unsigned numItems)
{
- ReadBoolVector2(numFiles, v.Defined);
+ ReadBoolVector2(numItems, v.Defs);
CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector);
- v.Values.Reserve(numFiles);
- for (int i = 0; i < numFiles; i++)
+ v.Vals.ClearAndSetSize(numItems);
+ UInt64 *p = &v.Vals[0];
+ const bool *defs = &v.Defs[0];
+
+ for (unsigned i = 0; i < numItems; i++)
{
UInt64 t = 0;
- if (v.Defined[i])
+ if (defs[i])
t = ReadUInt64();
- v.Values.Add(t);
+ p[i] = t;
}
}
@@ -782,35 +1092,19 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 baseOffset,
UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS_DECL
)
{
- CRecordVector<UInt64> packSizes;
- CBoolVector packCRCsDefined;
- CRecordVector<UInt32> packCRCs;
- CObjectVector<CFolder> folders;
-
- CRecordVector<CNum> numUnpackStreamsInFolders;
+ CFolders folders;
CRecordVector<UInt64> unpackSizes;
- CBoolVector digestsDefined;
- CRecordVector<UInt32> digests;
-
+ CUInt32DefVector digests;
+
ReadStreamsInfo(NULL,
dataOffset,
- packSizes,
- packCRCsDefined,
- packCRCs,
folders,
- numUnpackStreamsInFolders,
unpackSizes,
- digestsDefined,
digests);
-
- // db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
-
- CNum packIndex = 0;
+
CDecoder decoder(
#ifdef _ST_MODE
false
@@ -818,134 +1112,107 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
true
#endif
);
- UInt64 dataStartPos = baseOffset + dataOffset;
- for (int i = 0; i < folders.Size(); i++)
+
+ for (CNum i = 0; i < folders.NumFolders; i++)
{
- const CFolder &folder = folders[i];
- dataVector.Add(CByteBuffer());
- CByteBuffer &data = dataVector.Back();
- UInt64 unpackSize64 = folder.GetUnpackSize();
+ CByteBuffer &data = dataVector.AddNew();
+ UInt64 unpackSize64 = folders.GetFolderUnpackSize(i);
size_t unpackSize = (size_t)unpackSize64;
if (unpackSize != unpackSize64)
ThrowUnsupported();
- data.SetCapacity(unpackSize);
-
+ data.Alloc(unpackSize);
+
CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->Init(data, unpackSize);
-
+
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_LOC_VARS
- _stream, dataStartPos,
- &packSizes[packIndex], folder, outStream, NULL
- #ifndef _NO_CRYPTO
- , getTextPassword, passwordIsDefined
- #endif
+ _stream, baseOffset + dataOffset,
+ folders, i,
+ outStream, NULL
+ _7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) && !defined(_SFX)
, false, 1
#endif
);
RINOK(result);
-
- if (folder.UnpackCRCDefined)
- if (CrcCalc(data, unpackSize) != folder.UnpackCRC)
+
+ if (folders.FolderCRCs.ValidAndDefined(i))
+ if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
ThrowIncorrect();
- for (int j = 0; j < folder.PackStreams.Size(); j++)
- {
- UInt64 packSize = packSizes[packIndex++];
- dataStartPos += packSize;
- HeadersSize += packSize;
- }
}
+ HeadersSize += folders.PackPositions[folders.NumPackStreams];
return S_OK;
}
HRESULT CInArchive::ReadHeader(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &db
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ CDbEx &db
+ _7Z_DECODER_CRYPRO_VARS_DECL
)
{
UInt64 type = ReadID();
if (type == NID::kArchiveProperties)
{
- ReadArchiveProperties(db.ArchiveInfo);
+ ReadArchiveProperties(db.ArcInfo);
type = ReadID();
}
-
+
CObjectVector<CByteBuffer> dataVector;
-
+
if (type == NID::kAdditionalStreamsInfo)
{
HRESULT result = ReadAndDecodePackedStreams(
EXTERNAL_CODECS_LOC_VARS
- db.ArchiveInfo.StartPositionAfterHeader,
- db.ArchiveInfo.DataStartPosition2,
+ db.ArcInfo.StartPositionAfterHeader,
+ db.ArcInfo.DataStartPosition2,
dataVector
- #ifndef _NO_CRYPTO
- , getTextPassword, passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS
);
RINOK(result);
- db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
+ db.ArcInfo.DataStartPosition2 += db.ArcInfo.StartPositionAfterHeader;
type = ReadID();
}
CRecordVector<UInt64> unpackSizes;
- CBoolVector digestsDefined;
- CRecordVector<UInt32> digests;
-
+ CUInt32DefVector digests;
+
if (type == NID::kMainStreamsInfo)
{
ReadStreamsInfo(&dataVector,
- db.ArchiveInfo.DataStartPosition,
- db.PackSizes,
- db.PackCRCsDefined,
- db.PackCRCs,
- db.Folders,
- db.NumUnpackStreamsVector,
+ db.ArcInfo.DataStartPosition,
+ (CFolders &)db,
unpackSizes,
- digestsDefined,
digests);
- db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader;
+ db.ArcInfo.DataStartPosition += db.ArcInfo.StartPositionAfterHeader;
type = ReadID();
}
- else
- {
- for (int i = 0; i < db.Folders.Size(); i++)
- {
- db.NumUnpackStreamsVector.Add(1);
- CFolder &folder = db.Folders[i];
- unpackSizes.Add(folder.GetUnpackSize());
- digestsDefined.Add(folder.UnpackCRCDefined);
- digests.Add(folder.UnpackCRC);
- }
- }
db.Files.Clear();
- if (type == NID::kEnd)
- return S_OK;
- if (type != NID::kFilesInfo)
- ThrowIncorrect();
-
+ if (type == NID::kFilesInfo)
+ {
+
CNum numFiles = ReadNum();
+ db.Files.ClearAndSetSize(numFiles);
+ CNum i;
+ /*
db.Files.Reserve(numFiles);
CNum i;
for (i = 0; i < numFiles; i++)
db.Files.Add(CFileItem());
+ */
- db.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
- if (!db.PackSizes.IsEmpty())
- db.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
- if (numFiles > 0 && !digests.IsEmpty())
- db.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
+ db.ArcInfo.FileInfoPopIDs.Add(NID::kSize);
+ // if (!db.PackSizes.IsEmpty())
+ db.ArcInfo.FileInfoPopIDs.Add(NID::kPackInfo);
+ if (numFiles > 0 && !digests.Defs.IsEmpty())
+ db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC);
CBoolVector emptyStreamVector;
- BoolVector_Fill_False(emptyStreamVector, (int)numFiles);
+ BoolVector_Fill_False(emptyStreamVector, (unsigned)numFiles);
CBoolVector emptyFileVector;
CBoolVector antiFileVector;
CNum numEmptyStreams = 0;
@@ -956,7 +1223,10 @@ HRESULT CInArchive::ReadHeader(
if (type == NID::kEnd)
break;
UInt64 size = ReadNumber();
- size_t ppp = _inByteBack->_pos;
+ if (size > _inByteBack->GetRem())
+ ThrowIncorrect();
+ CStreamSwitch switchProp;
+ switchProp.Set(this, _inByteBack->GetPtr(), (size_t)size, true);
bool addPropIdToList = true;
bool isKnownType = true;
if (type > ((UInt32)1 << 30))
@@ -967,11 +1237,29 @@ HRESULT CInArchive::ReadHeader(
{
CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector);
- for (int i = 0; i < db.Files.Size(); i++)
- _inByteBack->ReadString(db.Files[i].Name);
+ size_t rem = _inByteBack->GetRem();
+ db.NamesBuf.Alloc(rem);
+ ReadBytes(db.NamesBuf, rem);
+ db.NameOffsets.Alloc(db.Files.Size() + 1);
+ size_t pos = 0;
+ unsigned i;
+ for (i = 0; i < db.Files.Size(); i++)
+ {
+ size_t curRem = (rem - pos) / 2;
+ const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos);
+ size_t j;
+ for (j = 0; j < curRem && buf[j] != 0; j++);
+ if (j == curRem)
+ ThrowEndOfData();
+ db.NameOffsets[i] = pos / 2;
+ pos += j * 2 + 2;
+ }
+ db.NameOffsets[i] = pos / 2;
+ if (pos != rem)
+ ThereIsHeaderError = true;
break;
}
- case NID::kWinAttributes:
+ case NID::kWinAttrib:
{
CBoolVector boolVector;
ReadBoolVector2(db.Files.Size(), boolVector);
@@ -986,9 +1274,40 @@ HRESULT CInArchive::ReadHeader(
}
break;
}
+ /*
+ case NID::kIsAux:
+ {
+ ReadBoolVector(db.Files.Size(), db.IsAux);
+ break;
+ }
+ case NID::kParent:
+ {
+ db.IsTree = true;
+ // CBoolVector boolVector;
+ // ReadBoolVector2(db.Files.Size(), boolVector);
+ // CStreamSwitch streamSwitch;
+ // streamSwitch.Set(this, &dataVector);
+ CBoolVector boolVector;
+ ReadBoolVector2(db.Files.Size(), boolVector);
+
+ db.ThereAreAltStreams = false;
+ for (i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = db.Files[i];
+ // file.Parent = -1;
+ // if (boolVector[i])
+ file.Parent = (int)ReadUInt32();
+ file.IsAltStream = !boolVector[i];
+ if (file.IsAltStream)
+ db.ThereAreAltStreams = true;
+ }
+ break;
+ }
+ */
case NID::kEmptyStream:
{
ReadBoolVector(numFiles, emptyStreamVector);
+ numEmptyStreams = 0;
for (i = 0; i < (CNum)emptyStreamVector.Size(); i++)
if (emptyStreamVector[i])
numEmptyStreams++;
@@ -1000,34 +1319,83 @@ HRESULT CInArchive::ReadHeader(
}
case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break;
case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break;
- case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (int)numFiles); break;
- case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (int)numFiles); break;
- case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (int)numFiles); break;
- case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (int)numFiles); break;
+ case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (unsigned)numFiles); break;
+ case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (unsigned)numFiles); break;
+ case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (unsigned)numFiles); break;
+ case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (unsigned)numFiles); break;
case NID::kDummy:
{
for (UInt64 j = 0; j < size; j++)
if (ReadByte() != 0)
- ThrowIncorrect();
+ ThereIsHeaderError = true;
addPropIdToList = false;
break;
}
+ /*
+ case NID::kNtSecure:
+ {
+ try
+ {
+ {
+ CStreamSwitch streamSwitch;
+ streamSwitch.Set(this, &dataVector);
+ UInt32 numDescriptors = ReadUInt32();
+ size_t offset = 0;
+ db.SecureOffsets.Clear();
+ for (i = 0; i < numDescriptors; i++)
+ {
+ UInt32 size = ReadUInt32();
+ db.SecureOffsets.Add(offset);
+ offset += size;
+ }
+ // ThrowIncorrect();;
+ db.SecureOffsets.Add(offset);
+ db.SecureBuf.SetCapacity(offset);
+ for (i = 0; i < numDescriptors; i++)
+ {
+ offset = db.SecureOffsets[i];
+ ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset);
+ }
+ db.SecureIDs.Clear();
+ for (unsigned i = 0; i < db.Files.Size(); i++)
+ {
+ db.SecureIDs.Add(ReadNum());
+ // db.SecureIDs.Add(ReadUInt32());
+ }
+ // ReadUInt32();
+ if (_inByteBack->GetRem() != 0)
+ ThrowIncorrect();;
+ }
+ }
+ catch(CInArchiveException &)
+ {
+ ThereIsHeaderError = true;
+ addPropIdToList = isKnownType = false;
+ db.ClearSecure();
+ }
+ break;
+ }
+ */
default:
addPropIdToList = isKnownType = false;
}
if (isKnownType)
{
- if(addPropIdToList)
- db.ArchiveInfo.FileInfoPopIDs.Add(type);
+ if (addPropIdToList)
+ db.ArcInfo.FileInfoPopIDs.Add(type);
}
else
- SkipData(size);
- bool checkRecordsSize = (db.ArchiveInfo.Version.Major > 0 ||
- db.ArchiveInfo.Version.Minor > 2);
- if (checkRecordsSize && _inByteBack->_pos - ppp != size)
+ {
+ db.UnsupportedFeatureWarning = true;
+ _inByteBack->SkipRem();
+ }
+ // SkipData worked incorrectly in some versions before v4.59 (7zVer <= 00.02)
+ if (_inByteBack->GetRem() != 0)
ThrowIncorrect();
}
+ type = ReadID(); // Read (NID::kEnd) end of headers
+
CNum emptyFileIndex = 0;
CNum sizeIndex = 0;
@@ -1035,19 +1403,21 @@ HRESULT CInArchive::ReadHeader(
for (i = 0; i < numEmptyStreams; i++)
if (antiFileVector[i])
numAntiItems++;
-
+
for (i = 0; i < numFiles; i++)
{
CFileItem &file = db.Files[i];
bool isAnti;
file.HasStream = !emptyStreamVector[i];
+ file.Crc = 0;
if (file.HasStream)
{
file.IsDir = false;
isAnti = false;
file.Size = unpackSizes[sizeIndex];
- file.Crc = digests[sizeIndex];
- file.CrcDefined = digestsDefined[sizeIndex];
+ file.CrcDefined = digests.ValidAndDefined(sizeIndex);
+ if (file.CrcDefined)
+ file.Crc = digests.Vals[sizeIndex];
sizeIndex++;
}
else
@@ -1061,162 +1431,187 @@ HRESULT CInArchive::ReadHeader(
if (numAntiItems != 0)
db.IsAnti.Add(isAnti);
}
+ }
+ db.FillLinks();
+ /*
+ if (type != NID::kEnd)
+ ThrowIncorrect();
+ if (_inByteBack->GetRem() != 0)
+ ThrowIncorrect();
+ */
return S_OK;
}
-
-void CArchiveDatabaseEx::FillFolderStartPackStream()
+void CDbEx::FillLinks()
{
- FolderStartPackStreamIndex.Clear();
- FolderStartPackStreamIndex.Reserve(Folders.Size());
- CNum startPos = 0;
- for (int i = 0; i < Folders.Size(); i++)
- {
- FolderStartPackStreamIndex.Add(startPos);
- startPos += (CNum)Folders[i].PackStreams.Size();
- }
-}
+ FolderStartFileIndex.ClearAndSetSize(NumFolders);
-void CArchiveDatabaseEx::FillStartPos()
-{
- PackStreamStartPositions.Clear();
- PackStreamStartPositions.Reserve(PackSizes.Size());
- UInt64 startPos = 0;
- for (int i = 0; i < PackSizes.Size(); i++)
- {
- PackStreamStartPositions.Add(startPos);
- startPos += PackSizes[i];
- }
-}
+ FileIndexToFolderIndexMap.ClearAndSetSize(Files.Size());
-void CArchiveDatabaseEx::FillFolderStartFileIndex()
-{
- FolderStartFileIndex.Clear();
- FolderStartFileIndex.Reserve(Folders.Size());
- FileIndexToFolderIndexMap.Clear();
- FileIndexToFolderIndexMap.Reserve(Files.Size());
-
- int folderIndex = 0;
+ CNum folderIndex = 0;
CNum indexInFolder = 0;
- for (int i = 0; i < Files.Size(); i++)
+ unsigned i;
+ for (i = 0; i < Files.Size(); i++)
{
- const CFileItem &file = Files[i];
- bool emptyStream = !file.HasStream;
- if (emptyStream && indexInFolder == 0)
- {
- FileIndexToFolderIndexMap.Add(kNumNoIndex);
- continue;
- }
+ bool emptyStream = !Files[i].HasStream;
if (indexInFolder == 0)
{
+ if (emptyStream)
+ {
+ FileIndexToFolderIndexMap[i] = kNumNoIndex;
+ continue;
+ }
// v3.13 incorrectly worked with empty folders
- // v4.07: Loop for skipping empty folders
+ // v4.07: we skip empty folders
for (;;)
{
- if (folderIndex >= Folders.Size())
+ if (folderIndex >= NumFolders)
ThrowIncorrect();
- FolderStartFileIndex.Add(i); // check it
+ FolderStartFileIndex[folderIndex] = i;
if (NumUnpackStreamsVector[folderIndex] != 0)
break;
folderIndex++;
}
}
- FileIndexToFolderIndexMap.Add(folderIndex);
+ FileIndexToFolderIndexMap[i] = folderIndex;
if (emptyStream)
continue;
- indexInFolder++;
- if (indexInFolder >= NumUnpackStreamsVector[folderIndex])
+ if (++indexInFolder >= NumUnpackStreamsVector[folderIndex])
{
folderIndex++;
indexInFolder = 0;
}
}
+
+ if (indexInFolder != 0)
+ folderIndex++;
+ /*
+ if (indexInFolder != 0)
+ ThrowIncorrect();
+ */
+ for (;;)
+ {
+ if (folderIndex >= NumFolders)
+ return;
+ FolderStartFileIndex[folderIndex] = i;
+ /*
+ if (NumUnpackStreamsVector[folderIndex] != 0)
+ ThrowIncorrect();;
+ */
+ folderIndex++;
+ }
}
HRESULT CInArchive::ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &db
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ CDbEx &db
+ _7Z_DECODER_CRYPRO_VARS_DECL
)
{
db.Clear();
- db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
+ db.ArcInfo.StartPosition = _arhiveBeginStreamPosition;
- db.ArchiveInfo.Version.Major = _header[6];
- db.ArchiveInfo.Version.Minor = _header[7];
+ db.ArcInfo.Version.Major = _header[6];
+ db.ArcInfo.Version.Minor = _header[7];
- if (db.ArchiveInfo.Version.Major != kMajorVersion)
- ThrowUnsupportedVersion();
+ if (db.ArcInfo.Version.Major != kMajorVersion)
+ {
+ // db.UnsupportedVersion = true;
+ return S_FALSE;
+ }
- UInt32 crcFromArchive = Get32(_header + 8);
- UInt64 nextHeaderOffset = Get64(_header + 0xC);
- UInt64 nextHeaderSize = Get64(_header + 0x14);
- UInt32 nextHeaderCRC = Get32(_header + 0x1C);
- UInt32 crc = CrcCalc(_header + 0xC, 20);
+ UInt64 nextHeaderOffset = Get64(_header + 12);
+ UInt64 nextHeaderSize = Get64(_header + 20);
+ UInt32 nextHeaderCRC = Get32(_header + 28);
#ifdef FORMAT_7Z_RECOVERY
- if (crcFromArchive == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0)
+ UInt32 crcFromArc = Get32(_header + 8);
+ if (crcFromArc == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0)
{
- UInt64 cur, cur2;
+ UInt64 cur, fileSize;
RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur));
- const int kCheckSize = 500;
+ const unsigned kCheckSize = 512;
Byte buf[kCheckSize];
- RINOK(_stream->Seek(0, STREAM_SEEK_END, &cur2));
- int checkSize = kCheckSize;
- if (cur2 - cur < kCheckSize)
- checkSize = (int)(cur2 - cur);
- RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2));
-
+ RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize));
+ UInt64 rem = fileSize - cur;
+ unsigned checkSize = kCheckSize;
+ if (rem < kCheckSize)
+ checkSize = (unsigned)(rem);
+ if (checkSize < 3)
+ return S_FALSE;
+ RINOK(_stream->Seek(fileSize - checkSize, STREAM_SEEK_SET, NULL));
RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize));
- int i;
- for (i = (int)checkSize - 2; i >= 0; i--)
- if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04)
- break;
- if (i < 0)
+ if (buf[checkSize - 1] != 0)
return S_FALSE;
+
+ unsigned i;
+ for (i = checkSize - 2;; i--)
+ {
+ if (buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo ||
+ buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo)
+ break;
+ if (i == 0)
+ return S_FALSE;
+ }
nextHeaderSize = checkSize - i;
- nextHeaderOffset = cur2 - cur + i;
+ nextHeaderOffset = rem - nextHeaderSize;
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
+ db.StartHeaderWasRecovered = true;
}
else
#endif
{
- if (crc != crcFromArchive)
- ThrowIncorrect();
+ // Crc was tested already at signature check
+ // if (CrcCalc(_header + 12, 20) != crcFromArchive) ThrowIncorrect();
}
- db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
+ db.ArcInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
+ db.PhySize = kHeaderSize;
+ db.IsArc = false;
+ if ((Int64)nextHeaderOffset < 0 ||
+ nextHeaderSize > ((UInt64)1 << 62))
+ return S_FALSE;
if (nextHeaderSize == 0)
+ {
+ if (nextHeaderOffset != 0)
+ return S_FALSE;
+ db.IsArc = true;
return S_OK;
+ }
- if (nextHeaderSize > (UInt64)0xFFFFFFFF)
- return S_FALSE;
+ if (!db.StartHeaderWasRecovered)
+ db.IsArc = true;
- if ((Int64)nextHeaderOffset < 0)
+ HeadersSize += kHeaderSize + nextHeaderSize;
+ db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;
+ if (_fileEndPosition - db.ArcInfo.StartPositionAfterHeader < nextHeaderOffset + nextHeaderSize)
+ {
+ db.UnexpectedEnd = true;
return S_FALSE;
-
+ }
RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
- CByteBuffer buffer2;
- buffer2.SetCapacity((size_t)nextHeaderSize);
+ size_t nextHeaderSize_t = (size_t)nextHeaderSize;
+ if (nextHeaderSize_t != nextHeaderSize)
+ return E_OUTOFMEMORY;
+ CByteBuffer buffer2(nextHeaderSize_t);
- RINOK(ReadStream_FALSE(_stream, buffer2, (size_t)nextHeaderSize));
- HeadersSize += kHeaderSize + nextHeaderSize;
- db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;
+ RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t));
- if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC)
+ if (CrcCalc(buffer2, nextHeaderSize_t) != nextHeaderCRC)
ThrowIncorrect();
-
+
+ if (!db.StartHeaderWasRecovered)
+ db.PhySizeWasConfirmed = true;
+
CStreamSwitch streamSwitch;
streamSwitch.Set(this, buffer2);
-
+
CObjectVector<CByteBuffer> dataVector;
-
+
UInt64 type = ReadID();
if (type != NID::kHeader)
{
@@ -1224,12 +1619,10 @@ HRESULT CInArchive::ReadDatabase2(
ThrowIncorrect();
HRESULT result = ReadAndDecodePackedStreams(
EXTERNAL_CODECS_LOC_VARS
- db.ArchiveInfo.StartPositionAfterHeader,
- db.ArchiveInfo.DataStartPosition2,
+ db.ArcInfo.StartPositionAfterHeader,
+ db.ArcInfo.DataStartPosition2,
dataVector
- #ifndef _NO_CRYPTO
- , getTextPassword, passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS
);
RINOK(result);
if (dataVector.Size() == 0)
@@ -1242,35 +1635,45 @@ HRESULT CInArchive::ReadDatabase2(
ThrowIncorrect();
}
+ db.IsArc = true;
+
db.HeadersSize = HeadersSize;
return ReadHeader(
EXTERNAL_CODECS_LOC_VARS
db
- #ifndef _NO_CRYPTO
- , getTextPassword, passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS
);
}
HRESULT CInArchive::ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &db
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ CDbEx &db
+ _7Z_DECODER_CRYPRO_VARS_DECL
)
{
try
{
- return ReadDatabase2(
+ HRESULT res = ReadDatabase2(
EXTERNAL_CODECS_LOC_VARS db
- #ifndef _NO_CRYPTO
- , getTextPassword, passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS
);
+ if (ThereIsHeaderError)
+ db.ThereIsHeaderError = true;
+ if (res == E_NOTIMPL)
+ ThrowUnsupported();
+ return res;
+ }
+ catch(CUnsupportedFeatureException &)
+ {
+ db.UnsupportedFeatureError = true;
+ return S_FALSE;
+ }
+ catch(CInArchiveException &)
+ {
+ db.ThereIsHeaderError = true;
+ return S_FALSE;
}
- catch(CInArchiveException &) { return S_FALSE; }
}
}}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zIn.h b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zIn.h
index 971f27b2a..98f61c81e 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zIn.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zIn.h
@@ -5,6 +5,8 @@
#include "../../../Common/MyCom.h"
+#include "../../../Windows/PropVariant.h"
+
#include "../../IPassword.h"
#include "../../IStream.h"
@@ -12,10 +14,151 @@
#include "../../Common/InBuffer.h"
#include "7zItem.h"
-
+
namespace NArchive {
namespace N7z {
-
+
+/*
+ We don't need to init isEncrypted and passwordIsDefined
+ We must upgrade them only */
+
+#ifdef _NO_CRYPTO
+#define _7Z_DECODER_CRYPRO_VARS_DECL
+#define _7Z_DECODER_CRYPRO_VARS
+#else
+#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined
+#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined
+#endif
+
+struct CParsedMethods
+{
+ Byte Lzma2Prop;
+ UInt32 LzmaDic;
+ CRecordVector<UInt64> IDs;
+
+ CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {}
+};
+
+struct CFolders
+{
+ CNum NumPackStreams;
+ CNum NumFolders;
+
+ CObjArray<UInt64> PackPositions; // NumPackStreams + 1
+ // CUInt32DefVector PackCRCs; // we don't use PackCRCs now
+
+ CUInt32DefVector FolderCRCs; // NumFolders
+ CObjArray<CNum> NumUnpackStreamsVector; // NumFolders
+
+ CObjArray<UInt64> CoderUnpackSizes; // including unpack sizes of bind coders
+ CObjArray<CNum> FoToCoderUnpackSizes; // NumFolders + 1
+ CObjArray<CNum> FoStartPackStreamIndex; // NumFolders + 1
+ CObjArray<Byte> FoToMainUnpackSizeIndex; // NumFolders
+
+ CObjArray<size_t> FoCodersDataOffset; // NumFolders + 1
+ CByteBuffer CodersData;
+
+ CParsedMethods ParsedMethods;
+
+ void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const;
+
+ unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const
+ {
+ return FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex];
+ }
+
+ UInt64 GetFolderUnpackSize(unsigned folderIndex) const
+ {
+ return CoderUnpackSizes[FoToCoderUnpackSizes[folderIndex] + FoToMainUnpackSizeIndex[folderIndex]];
+ }
+
+ UInt64 GetStreamPackSize(unsigned index) const
+ {
+ return PackPositions[index + 1] - PackPositions[index];
+ }
+
+ void Clear()
+ {
+ NumPackStreams = 0;
+ PackPositions.Free();
+ // PackCRCs.Clear();
+
+ NumFolders = 0;
+ FolderCRCs.Clear();
+ NumUnpackStreamsVector.Free();
+ CoderUnpackSizes.Free();
+ FoToCoderUnpackSizes.Free();
+ FoStartPackStreamIndex.Free();
+ FoToMainUnpackSizeIndex.Free();
+ FoCodersDataOffset.Free();
+ CodersData.Free();
+ }
+};
+
+struct CDatabase: public CFolders
+{
+ CRecordVector<CFileItem> Files;
+
+ CUInt64DefVector CTime;
+ CUInt64DefVector ATime;
+ CUInt64DefVector MTime;
+ CUInt64DefVector StartPos;
+ CRecordVector<bool> IsAnti;
+ /*
+ CRecordVector<bool> IsAux;
+ CByteBuffer SecureBuf;
+ CRecordVector<UInt32> SecureIDs;
+ */
+
+ CByteBuffer NamesBuf;
+ CObjArray<size_t> NameOffsets; // numFiles + 1, offsets of utf-16 symbols
+
+ /*
+ void ClearSecure()
+ {
+ SecureBuf.Free();
+ SecureIDs.Clear();
+ }
+ */
+
+ void Clear()
+ {
+ CFolders::Clear();
+ // ClearSecure();
+
+ NamesBuf.Free();
+ NameOffsets.Free();
+
+ Files.Clear();
+ CTime.Clear();
+ ATime.Clear();
+ MTime.Clear();
+ StartPos.Clear();
+ IsAnti.Clear();
+ // IsAux.Clear();
+ }
+
+ bool IsSolid() const
+ {
+ for (CNum i = 0; i < NumFolders; i++)
+ if (NumUnpackStreamsVector[i] > 1)
+ return true;
+ return false;
+ }
+ bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
+ // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
+
+ const void * GetName(unsigned index) const
+ {
+ if (!NameOffsets || !NamesBuf)
+ return NULL;
+ return (const void *)((const Byte *)NamesBuf + NameOffsets[index] * 2);
+ };
+
+ void GetPath(unsigned index, UString &path) const;
+ HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw();
+};
+
struct CInArchiveInfo
{
CArchiveVersion Version;
@@ -24,29 +167,73 @@ struct CInArchiveInfo
UInt64 DataStartPosition;
UInt64 DataStartPosition2;
CRecordVector<UInt64> FileInfoPopIDs;
+
void Clear()
{
+ StartPosition = 0;
+ StartPositionAfterHeader = 0;
+ DataStartPosition = 0;
+ DataStartPosition2 = 0;
FileInfoPopIDs.Clear();
}
};
-struct CArchiveDatabaseEx: public CArchiveDatabase
+struct CDbEx: public CDatabase
{
- CInArchiveInfo ArchiveInfo;
- CRecordVector<UInt64> PackStreamStartPositions;
- CRecordVector<CNum> FolderStartPackStreamIndex;
+ CInArchiveInfo ArcInfo;
CRecordVector<CNum> FolderStartFileIndex;
CRecordVector<CNum> FileIndexToFolderIndexMap;
UInt64 HeadersSize;
UInt64 PhySize;
+ /*
+ CRecordVector<size_t> SecureOffsets;
+ bool IsTree;
+ bool ThereAreAltStreams;
+ */
+
+ bool IsArc;
+ bool PhySizeWasConfirmed;
+
+ bool ThereIsHeaderError;
+ bool UnexpectedEnd;
+ // bool UnsupportedVersion;
+
+ bool StartHeaderWasRecovered;
+ bool UnsupportedFeatureWarning;
+ bool UnsupportedFeatureError;
+
+ /*
+ void ClearSecureEx()
+ {
+ ClearSecure();
+ SecureOffsets.Clear();
+ }
+ */
+
void Clear()
{
- CArchiveDatabase::Clear();
- ArchiveInfo.Clear();
- PackStreamStartPositions.Clear();
- FolderStartPackStreamIndex.Clear();
+ IsArc = false;
+ PhySizeWasConfirmed = false;
+
+ ThereIsHeaderError = false;
+ UnexpectedEnd = false;
+ // UnsupportedVersion = false;
+
+ StartHeaderWasRecovered = false;
+ UnsupportedFeatureError = false;
+ UnsupportedFeatureWarning = false;
+
+ /*
+ IsTree = false;
+ ThereAreAltStreams = false;
+ */
+
+ CDatabase::Clear();
+
+ // SecureOffsets.Clear();
+ ArcInfo.Clear();
FolderStartFileIndex.Clear();
FileIndexToFolderIndexMap.Clear();
@@ -54,36 +241,25 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
PhySize = 0;
}
- void FillFolderStartPackStream();
- void FillStartPos();
- void FillFolderStartFileIndex();
+ void FillLinks();
- void Fill()
- {
- FillFolderStartPackStream();
- FillStartPos();
- FillFolderStartFileIndex();
- }
-
- UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
+ UInt64 GetFolderStreamPos(unsigned folderIndex, unsigned indexInFolder) const
{
- return ArchiveInfo.DataStartPosition +
- PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder];
+ return ArcInfo.DataStartPosition +
+ PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder];
}
-
- UInt64 GetFolderFullPackSize(int folderIndex) const
+
+ UInt64 GetFolderFullPackSize(unsigned folderIndex) const
{
- CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
- const CFolder &folder = Folders[folderIndex];
- UInt64 size = 0;
- for (int i = 0; i < folder.PackStreams.Size(); i++)
- size += PackSizes[packStreamIndex + i];
- return size;
+ return
+ PackPositions[FoStartPackStreamIndex[folderIndex + 1]] -
+ PackPositions[FoStartPackStreamIndex[folderIndex]];
}
-
- UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+
+ UInt64 GetFolderPackStreamSize(unsigned folderIndex, unsigned streamIndex) const
{
- return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+ unsigned i = FoStartPackStreamIndex[folderIndex] + streamIndex;
+ return PackPositions[i + 1] - PackPositions[i];
}
UInt64 GetFilePackSize(CNum fileIndex) const
@@ -96,12 +272,17 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
}
};
-class CInByte2
+const unsigned kNumBufLevelsMax = 4;
+
+struct CInByte2
{
const Byte *_buffer;
- size_t _size;
public:
+ size_t _size;
size_t _pos;
+
+ size_t GetRem() const { return _size - _pos; }
+ const Byte *GetPtr() const { return _buffer + _pos; }
void Init(const Byte *buffer, size_t size)
{
_buffer = buffer;
@@ -110,13 +291,17 @@ public:
}
Byte ReadByte();
void ReadBytes(Byte *data, size_t size);
+ void SkipDataNoCheck(UInt64 size) { _pos += (size_t)size; }
void SkipData(UInt64 size);
+
void SkipData();
+ void SkipRem() { _pos = _size; }
UInt64 ReadNumber();
CNum ReadNum();
UInt32 ReadUInt32();
UInt64 ReadUInt64();
- void ReadString(UString &s);
+
+ void ParseFolder(CFolder &folder);
};
class CStreamSwitch;
@@ -129,32 +314,35 @@ class CInArchive
CMyComPtr<IInStream> _stream;
- CObjectVector<CInByte2> _inByteVector;
+ unsigned _numInByteBufs;
+ CInByte2 _inByteVector[kNumBufLevelsMax];
+
CInByte2 *_inByteBack;
-
+ bool ThereIsHeaderError;
+
UInt64 _arhiveBeginStreamPosition;
+ UInt64 _fileEndPosition;
Byte _header[kHeaderSize];
UInt64 HeadersSize;
- void AddByteStream(const Byte *buffer, size_t size)
- {
- _inByteVector.Add(CInByte2());
- _inByteBack = &_inByteVector.Back();
- _inByteBack->Init(buffer, size);
- }
-
- void DeleteByteStream()
+ void AddByteStream(const Byte *buffer, size_t size);
+
+ void DeleteByteStream(bool needUpdatePos)
{
- _inByteVector.DeleteBack();
- if (!_inByteVector.IsEmpty())
- _inByteBack = &_inByteVector.Back();
+ _numInByteBufs--;
+ if (_numInByteBufs > 0)
+ {
+ _inByteBack = &_inByteVector[_numInByteBufs - 1];
+ if (needUpdatePos)
+ _inByteBack->_pos += _inByteVector[_numInByteBufs]._pos;
+ }
}
private:
HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
-
+
void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
Byte ReadByte() { return _inByteBack->ReadByte(); }
UInt64 ReadNumber() { return _inByteBack->ReadNumber(); }
@@ -164,82 +352,61 @@ private:
UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); }
void SkipData(UInt64 size) { _inByteBack->SkipData(size); }
void SkipData() { _inByteBack->SkipData(); }
- void WaitAttribute(UInt64 attribute);
+ void WaitId(UInt64 id);
void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
- void GetNextFolderItem(CFolder &itemInfo);
- void ReadHashDigests(int numItems,
- CBoolVector &digestsDefined, CRecordVector<UInt32> &digests);
-
- void ReadPackInfo(
- UInt64 &dataOffset,
- CRecordVector<UInt64> &packSizes,
- CBoolVector &packCRCsDefined,
- CRecordVector<UInt32> &packCRCs);
-
+ void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs);
+
+ void ReadPackInfo(CFolders &f);
+
void ReadUnpackInfo(
const CObjectVector<CByteBuffer> *dataVector,
- CObjectVector<CFolder> &folders);
-
+ CFolders &folders);
+
void ReadSubStreamsInfo(
- const CObjectVector<CFolder> &folders,
- CRecordVector<CNum> &numUnpackStreamsInFolders,
+ CFolders &folders,
CRecordVector<UInt64> &unpackSizes,
- CBoolVector &digestsDefined,
- CRecordVector<UInt32> &digests);
+ CUInt32DefVector &digests);
void ReadStreamsInfo(
const CObjectVector<CByteBuffer> *dataVector,
UInt64 &dataOffset,
- CRecordVector<UInt64> &packSizes,
- CBoolVector &packCRCsDefined,
- CRecordVector<UInt32> &packCRCs,
- CObjectVector<CFolder> &folders,
- CRecordVector<CNum> &numUnpackStreamsInFolders,
+ CFolders &folders,
CRecordVector<UInt64> &unpackSizes,
- CBoolVector &digestsDefined,
- CRecordVector<UInt32> &digests);
-
+ CUInt32DefVector &digests);
- void ReadBoolVector(int numItems, CBoolVector &v);
- void ReadBoolVector2(int numItems, CBoolVector &v);
+ void ReadBoolVector(unsigned numItems, CBoolVector &v);
+ void ReadBoolVector2(unsigned numItems, CBoolVector &v);
void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
- CUInt64DefVector &v, int numFiles);
+ CUInt64DefVector &v, unsigned numItems);
HRESULT ReadAndDecodePackedStreams(
DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 baseOffset, UInt64 &dataOffset,
CObjectVector<CByteBuffer> &dataVector
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS_DECL
);
HRESULT ReadHeader(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &db
- #ifndef _NO_CRYPTO
- ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ CDbEx &db
+ _7Z_DECODER_CRYPRO_VARS_DECL
);
HRESULT ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &db
- #ifndef _NO_CRYPTO
- ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ CDbEx &db
+ _7Z_DECODER_CRYPRO_VARS_DECL
);
public:
+ CInArchive(): _numInByteBufs(0) { }
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
void Close();
HRESULT ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &db
- #ifndef _NO_CRYPTO
- ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
- #endif
+ CDbEx &db
+ _7Z_DECODER_CRYPRO_VARS_DECL
);
};
-
+
}}
-
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zItem.h b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zItem.h
index 34f10775c..c112f83fd 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zItem.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zItem.h
@@ -3,7 +3,7 @@
#ifndef __7Z_ITEM_H
#define __7Z_ITEM_H
-#include "../../../Common/Buffer.h"
+#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyString.h"
#include "../../Common/MethodId.h"
@@ -25,6 +25,7 @@ struct CCoderInfo
CByteBuffer Props;
CNum NumInStreams;
CNum NumOutStreams;
+
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
};
@@ -36,55 +37,48 @@ struct CBindPair
struct CFolder
{
- CObjectVector<CCoderInfo> Coders;
- CRecordVector<CBindPair> BindPairs;
- CRecordVector<CNum> PackStreams;
- CRecordVector<UInt64> UnpackSizes;
- UInt32 UnpackCRC;
- bool UnpackCRCDefined;
-
- CFolder(): UnpackCRCDefined(false) {}
-
- UInt64 GetUnpackSize() const // test it
- {
- if (UnpackSizes.IsEmpty())
- return 0;
- for (int i = UnpackSizes.Size() - 1; i >= 0; i--)
- if (FindBindPairForOutStream(i) < 0)
- return UnpackSizes[i];
- throw 1;
- }
+ CObjArray2<CCoderInfo> Coders;
+ CObjArray2<CBindPair> BindPairs;
+ CObjArray2<CNum> PackStreams;
CNum GetNumOutStreams() const
{
CNum result = 0;
- for (int i = 0; i < Coders.Size(); i++)
+ FOR_VECTOR(i, Coders)
result += Coders[i].NumOutStreams;
return result;
}
int FindBindPairForInStream(CNum inStreamIndex) const
{
- for(int i = 0; i < BindPairs.Size(); i++)
+ FOR_VECTOR(i, BindPairs)
if (BindPairs[i].InIndex == inStreamIndex)
return i;
return -1;
}
int FindBindPairForOutStream(CNum outStreamIndex) const
{
- for(int i = 0; i < BindPairs.Size(); i++)
+ FOR_VECTOR(i, BindPairs)
if (BindPairs[i].OutIndex == outStreamIndex)
return i;
return -1;
}
int FindPackStreamArrayIndex(CNum inStreamIndex) const
{
- for(int i = 0; i < PackStreams.Size(); i++)
+ FOR_VECTOR(i, PackStreams)
if (PackStreams[i] == inStreamIndex)
return i;
return -1;
}
+ int GetIndexOfMainOutStream() const
+ {
+ for (int i = (int)GetNumOutStreams() - 1; i >= 0; i--)
+ if (FindBindPairForOutStream(i) < 0)
+ return i;
+ throw 1;
+ }
+
bool IsEncrypted() const
{
for (int i = Coders.Size() - 1; i >= 0; i--)
@@ -93,50 +87,66 @@ struct CFolder
return false;
}
- bool CheckStructure() const;
+ bool CheckStructure(unsigned numUnpackSizes) const;
+};
+
+struct CUInt32DefVector
+{
+ CBoolVector Defs;
+ CRecordVector<UInt32> Vals;
+
+ void ClearAndSetSize(unsigned newSize)
+ {
+ Defs.ClearAndSetSize(newSize);
+ Vals.ClearAndSetSize(newSize);
+ }
+
+ void Clear()
+ {
+ Defs.Clear();
+ Vals.Clear();
+ }
+
+ void ReserveDown()
+ {
+ Defs.ReserveDown();
+ Vals.ReserveDown();
+ }
+
+ bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; }
};
struct CUInt64DefVector
{
- CRecordVector<UInt64> Values;
- CRecordVector<bool> Defined;
-
+ CBoolVector Defs;
+ CRecordVector<UInt64> Vals;
+
void Clear()
{
- Values.Clear();
- Defined.Clear();
+ Defs.Clear();
+ Vals.Clear();
}
-
+
void ReserveDown()
{
- Values.ReserveDown();
- Values.ReserveDown();
+ Defs.ReserveDown();
+ Vals.ReserveDown();
}
- bool GetItem(int index, UInt64 &value) const
+ bool GetItem(unsigned index, UInt64 &value) const
{
- if (index < Defined.Size() && Defined[index])
+ if (index < Defs.Size() && Defs[index])
{
- value = Values[index];
+ value = Vals[index];
return true;
}
value = 0;
return false;
}
-
- void SetItem(int index, bool defined, UInt64 value)
- {
- while (index >= Defined.Size())
- Defined.Add(false);
- Defined[index] = defined;
- if (!defined)
- return;
- while (index >= Values.Size())
- Values.Add(0);
- Values[index] = value;
- }
- bool CheckSize(int size) const { return Defined.Size() == size || Defined.Size() == 0; }
+ void SetItem(unsigned index, bool defined, UInt64 value);
+
+ bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
};
struct CFileItem
@@ -144,8 +154,10 @@ struct CFileItem
UInt64 Size;
UInt32 Attrib;
UInt32 Crc;
- UString Name;
-
+ /*
+ int Parent;
+ bool IsAltStream;
+ */
bool HasStream; // Test it !!! it means that there is
// stream in some folder. It can be empty stream
bool IsDir;
@@ -153,6 +165,10 @@ struct CFileItem
bool AttribDefined;
CFileItem():
+ /*
+ Parent(-1),
+ IsAltStream(false),
+ */
HasStream(true),
IsDir(false),
CrcDefined(false),
@@ -165,104 +181,6 @@ struct CFileItem
}
};
-struct CFileItem2
-{
- UInt64 CTime;
- UInt64 ATime;
- UInt64 MTime;
- UInt64 StartPos;
- bool CTimeDefined;
- bool ATimeDefined;
- bool MTimeDefined;
- bool StartPosDefined;
- bool IsAnti;
-};
-
-struct CArchiveDatabase
-{
- CRecordVector<UInt64> PackSizes;
- CRecordVector<bool> PackCRCsDefined;
- CRecordVector<UInt32> PackCRCs;
- CObjectVector<CFolder> Folders;
- CRecordVector<CNum> NumUnpackStreamsVector;
- CObjectVector<CFileItem> Files;
-
- CUInt64DefVector CTime;
- CUInt64DefVector ATime;
- CUInt64DefVector MTime;
- CUInt64DefVector StartPos;
- CRecordVector<bool> IsAnti;
-
- void Clear()
- {
- PackSizes.Clear();
- PackCRCsDefined.Clear();
- PackCRCs.Clear();
- Folders.Clear();
- NumUnpackStreamsVector.Clear();
- Files.Clear();
- CTime.Clear();
- ATime.Clear();
- MTime.Clear();
- StartPos.Clear();
- IsAnti.Clear();
- }
-
- void ReserveDown()
- {
- PackSizes.ReserveDown();
- PackCRCsDefined.ReserveDown();
- PackCRCs.ReserveDown();
- Folders.ReserveDown();
- NumUnpackStreamsVector.ReserveDown();
- Files.ReserveDown();
- CTime.ReserveDown();
- ATime.ReserveDown();
- MTime.ReserveDown();
- StartPos.ReserveDown();
- IsAnti.ReserveDown();
- }
-
- bool IsEmpty() const
- {
- return (PackSizes.IsEmpty() &&
- PackCRCsDefined.IsEmpty() &&
- PackCRCs.IsEmpty() &&
- Folders.IsEmpty() &&
- NumUnpackStreamsVector.IsEmpty() &&
- Files.IsEmpty());
- }
-
- bool CheckNumFiles() const
- {
- int size = Files.Size();
- return (
- CTime.CheckSize(size) &&
- ATime.CheckSize(size) &&
- MTime.CheckSize(size) &&
- StartPos.CheckSize(size) &&
- (size == IsAnti.Size() || IsAnti.Size() == 0));
- }
-
- bool IsSolid() const
- {
- for (int i = 0; i < NumUnpackStreamsVector.Size(); i++)
- if (NumUnpackStreamsVector[i] > 1)
- return true;
- return false;
- }
- bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); }
- void SetItemAnti(int index, bool isAnti)
- {
- while (index >= IsAnti.Size())
- IsAnti.Add(false);
- IsAnti[index] = isAnti;
- }
-
- void GetFile(int index, CFileItem &file, CFileItem2 &file2) const;
- void AddFile(const CFileItem &file, const CFileItem2 &file2);
-};
-
}}
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.cpp
index 0c8aa7e8c..e20858ea7 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.cpp
@@ -4,41 +4,19 @@
#include "../../../../C/7zCrc.h"
-#include "../../../Common/AutoPtr.h"
-
#include "../../Common/StreamObjects.h"
#include "7zOut.h"
-static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t size)
-{
- while (size > 0)
- {
- UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF);
- UInt32 processedSize;
- RINOK(stream->Write(data, curSize, &processedSize));
- if (processedSize == 0)
- return E_FAIL;
- data = (const void *)((const Byte *)data + processedSize);
- size -= processedSize;
- }
- return S_OK;
-}
-
namespace NArchive {
namespace N7z {
-HRESULT COutArchive::WriteDirect(const void *data, UInt32 size)
-{
- return ::WriteBytes(SeqStream, data, size);
-}
-
HRESULT COutArchive::WriteSignature()
{
Byte buf[8];
memcpy(buf, kSignature, kSignatureSize);
buf[kSignatureSize] = kMajorVersion;
- buf[kSignatureSize + 1] = 3;
+ buf[kSignatureSize + 1] = 4;
return WriteDirect(buf, 8);
}
@@ -145,7 +123,9 @@ HRESULT COutArchive::SkipPrefixArchiveHeader()
if (_endMarker)
return S_OK;
#endif
- return Stream->Seek(24, STREAM_SEEK_CUR, NULL);
+ Byte buf[24];
+ memset(buf, 0, 24);
+ return WriteDirect(buf, 24);
}
UInt64 COutArchive::GetPos() const
@@ -271,19 +251,19 @@ UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props)
void COutArchive::WriteFolder(const CFolder &folder)
{
WriteNumber(folder.Coders.Size());
- int i;
+ unsigned i;
for (i = 0; i < folder.Coders.Size(); i++)
{
const CCoderInfo &coder = folder.Coders[i];
{
- size_t propsSize = coder.Props.GetCapacity();
-
+ size_t propsSize = coder.Props.Size();
+
UInt64 id = coder.MethodID;
int idSize;
for (idSize = 1; idSize < sizeof(id); idSize++)
if ((id >> (8 * idSize)) == 0)
break;
- BYTE longID[15];
+ Byte longID[15];
for (int t = idSize - 1; t >= 0 ; t--, id >>= 8)
longID[t] = (Byte)(id & 0xFF);
Byte b;
@@ -321,7 +301,7 @@ void COutArchive::WriteBoolVector(const CBoolVector &boolVector)
{
Byte b = 0;
Byte mask = 0x80;
- for (int i = 0; i < boolVector.Size(); i++)
+ FOR_VECTOR (i, boolVector)
{
if (boolVector[i])
b |= mask;
@@ -337,37 +317,42 @@ void COutArchive::WriteBoolVector(const CBoolVector &boolVector)
WriteByte(b);
}
+static inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; }
-void COutArchive::WriteHashDigests(
- const CRecordVector<bool> &digestsDefined,
- const CRecordVector<UInt32> &digests)
+void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector)
{
- int numDefined = 0;
- int i;
- for (i = 0; i < digestsDefined.Size(); i++)
- if (digestsDefined[i])
+ WriteByte(id);
+ WriteNumber(Bv_GetSizeInBytes(boolVector));
+ WriteBoolVector(boolVector);
+}
+
+void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
+{
+ unsigned numDefined = 0;
+ unsigned i;
+ for (i = 0; i < digests.Defs.Size(); i++)
+ if (digests.Defs[i])
numDefined++;
if (numDefined == 0)
return;
WriteByte(NID::kCRC);
- if (numDefined == digestsDefined.Size())
+ if (numDefined == digests.Defs.Size())
WriteByte(1);
else
{
WriteByte(0);
- WriteBoolVector(digestsDefined);
+ WriteBoolVector(digests.Defs);
}
- for (i = 0; i < digests.Size(); i++)
- if (digestsDefined[i])
- WriteUInt32(digests[i]);
+ for (i = 0; i < digests.Defs.Size(); i++)
+ if (digests.Defs[i])
+ WriteUInt32(digests.Vals[i]);
}
void COutArchive::WritePackInfo(
UInt64 dataOffset,
const CRecordVector<UInt64> &packSizes,
- const CRecordVector<bool> &packCRCsDefined,
- const CRecordVector<UInt32> &packCRCs)
+ const CUInt32DefVector &packCRCs)
{
if (packSizes.IsEmpty())
return;
@@ -375,15 +360,15 @@ void COutArchive::WritePackInfo(
WriteNumber(dataOffset);
WriteNumber(packSizes.Size());
WriteByte(NID::kSize);
- for (int i = 0; i < packSizes.Size(); i++)
+ FOR_VECTOR (i, packSizes)
WriteNumber(packSizes[i]);
- WriteHashDigests(packCRCsDefined, packCRCs);
-
+ WriteHashDigests(packCRCs);
+
WriteByte(NID::kEnd);
}
-void COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders)
+void COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders, const COutFolders &outFolders)
{
if (folders.IsEmpty())
return;
@@ -394,44 +379,29 @@ void COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders)
WriteNumber(folders.Size());
{
WriteByte(0);
- for (int i = 0; i < folders.Size(); i++)
+ FOR_VECTOR (i, folders)
WriteFolder(folders[i]);
}
-
+
WriteByte(NID::kCodersUnpackSize);
- int i;
- for (i = 0; i < folders.Size(); i++)
- {
- const CFolder &folder = folders[i];
- for (int j = 0; j < folder.UnpackSizes.Size(); j++)
- WriteNumber(folder.UnpackSizes[j]);
- }
+ FOR_VECTOR (i, outFolders.CoderUnpackSizes)
+ WriteNumber(outFolders.CoderUnpackSizes[i]);
- CRecordVector<bool> unpackCRCsDefined;
- CRecordVector<UInt32> unpackCRCs;
- for (i = 0; i < folders.Size(); i++)
- {
- const CFolder &folder = folders[i];
- unpackCRCsDefined.Add(folder.UnpackCRCDefined);
- unpackCRCs.Add(folder.UnpackCRC);
- }
- WriteHashDigests(unpackCRCsDefined, unpackCRCs);
+ WriteHashDigests(outFolders.FolderUnpackCRCs);
WriteByte(NID::kEnd);
}
-void COutArchive::WriteSubStreamsInfo(
- const CObjectVector<CFolder> &folders,
- const CRecordVector<CNum> &numUnpackStreamsInFolders,
+void COutArchive::WriteSubStreamsInfo(const CObjectVector<CFolder> &folders,
+ const COutFolders &outFolders,
const CRecordVector<UInt64> &unpackSizes,
- const CRecordVector<bool> &digestsDefined,
- const CRecordVector<UInt32> &digests)
+ const CUInt32DefVector &digests)
{
+ const CRecordVector<CNum> &numUnpackStreamsInFolders = outFolders.NumUnpackStreamsVector;
WriteByte(NID::kSubStreamsInfo);
- int i;
+ unsigned i;
for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
- {
if (numUnpackStreamsInFolders[i] != 1)
{
WriteByte(NID::kNumUnpackStream);
@@ -439,54 +409,50 @@ void COutArchive::WriteSubStreamsInfo(
WriteNumber(numUnpackStreamsInFolders[i]);
break;
}
- }
-
- bool needFlag = true;
- CNum index = 0;
for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
- for (CNum j = 0; j < numUnpackStreamsInFolders[i]; j++)
+ if (numUnpackStreamsInFolders[i] > 1)
{
- if (j + 1 != numUnpackStreamsInFolders[i])
+ WriteByte(NID::kSize);
+ CNum index = 0;
+ for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
{
- if (needFlag)
- WriteByte(NID::kSize);
- needFlag = false;
- WriteNumber(unpackSizes[index]);
+ CNum num = numUnpackStreamsInFolders[i];
+ for (CNum j = 0; j < num; j++)
+ {
+ if (j + 1 != num)
+ WriteNumber(unpackSizes[index]);
+ index++;
+ }
}
- index++;
+ break;
}
- CRecordVector<bool> digestsDefined2;
- CRecordVector<UInt32> digests2;
+ CUInt32DefVector digests2;
- int digestIndex = 0;
+ unsigned digestIndex = 0;
for (i = 0; i < folders.Size(); i++)
{
- int numSubStreams = (int)numUnpackStreamsInFolders[i];
- if (numSubStreams == 1 && folders[i].UnpackCRCDefined)
+ unsigned numSubStreams = (unsigned)numUnpackStreamsInFolders[i];
+ if (numSubStreams == 1 && outFolders.FolderUnpackCRCs.ValidAndDefined(i))
digestIndex++;
else
- for (int j = 0; j < numSubStreams; j++, digestIndex++)
+ for (unsigned j = 0; j < numSubStreams; j++, digestIndex++)
{
- digestsDefined2.Add(digestsDefined[digestIndex]);
- digests2.Add(digests[digestIndex]);
+ digests2.Defs.Add(digests.Defs[digestIndex]);
+ digests2.Vals.Add(digests.Vals[digestIndex]);
}
}
- WriteHashDigests(digestsDefined2, digests2);
+ WriteHashDigests(digests2);
WriteByte(NID::kEnd);
}
-void COutArchive::SkipAlign(unsigned /* pos */, unsigned /* alignSize */)
-{
- return;
-}
-
-/*
-7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field.
+// 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field.
void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
{
+ if (!_useAlign)
+ return;
pos += (unsigned)GetPos();
pos &= (alignSize - 1);
if (pos == 0)
@@ -500,11 +466,8 @@ void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
for (unsigned i = 0; i < skip; i++)
WriteByte(0);
}
-*/
-static inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; }
-
-void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize)
+void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize)
{
const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);
const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2;
@@ -524,49 +487,54 @@ void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, B
void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type)
{
- int numDefined = 0;
+ unsigned numDefined = 0;
- int i;
- for (i = 0; i < v.Defined.Size(); i++)
- if (v.Defined[i])
+ unsigned i;
+ for (i = 0; i < v.Defs.Size(); i++)
+ if (v.Defs[i])
numDefined++;
if (numDefined == 0)
return;
- WriteAlignedBoolHeader(v.Defined, numDefined, type, 8);
-
- for (i = 0; i < v.Defined.Size(); i++)
- if (v.Defined[i])
- WriteUInt64(v.Values[i]);
+ WriteAlignedBoolHeader(v.Defs, numDefined, type, 8);
+
+ for (i = 0; i < v.Defs.Size(); i++)
+ if (v.Defs[i])
+ WriteUInt64(v.Vals[i]);
}
HRESULT COutArchive::EncodeStream(
DECL_EXTERNAL_CODECS_LOC_VARS
CEncoder &encoder, const CByteBuffer &data,
- CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
+ CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders)
{
CBufInStream *streamSpec = new CBufInStream;
CMyComPtr<ISequentialInStream> stream = streamSpec;
- streamSpec->Init(data, data.GetCapacity());
- CFolder folderItem;
- folderItem.UnpackCRCDefined = true;
- folderItem.UnpackCRC = CrcCalc(data, data.GetCapacity());
- UInt64 dataSize64 = data.GetCapacity();
+ streamSpec->Init(data, data.Size());
+ outFolders.FolderUnpackCRCs.Defs.Add(true);
+ outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size()));
+ // outFolders.NumUnpackStreamsVector.Add(1);
+ UInt64 dataSize64 = data.Size();
+ UInt64 unpackSize;
RINOK(encoder.Encode(
EXTERNAL_CODECS_LOC_VARS
- stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL))
- folders.Add(folderItem);
+ stream, NULL, &dataSize64, folders.AddNew(), outFolders.CoderUnpackSizes, unpackSize, SeqStream, packSizes, NULL))
return S_OK;
}
void COutArchive::WriteHeader(
- const CArchiveDatabase &db,
- const CHeaderOptions &headerOptions,
+ const CArchiveDatabaseOut &db,
+ // const CHeaderOptions &headerOptions,
UInt64 &headerOffset)
{
- int i;
-
+ /*
+ bool thereIsSecure = (db.SecureBuf.Size() != 0);
+ */
+ _useAlign = true;
+
+ unsigned i;
+
UInt64 packedSize = 0;
for (i = 0; i < db.PackSizes.Size(); i++)
packedSize += db.PackSizes[i];
@@ -580,31 +548,22 @@ void COutArchive::WriteHeader(
if (db.Folders.Size() > 0)
{
WriteByte(NID::kMainStreamsInfo);
- WritePackInfo(0, db.PackSizes,
- db.PackCRCsDefined,
- db.PackCRCs);
-
- WriteUnpackInfo(db.Folders);
+ WritePackInfo(0, db.PackSizes, db.PackCRCs);
+ WriteUnpackInfo(db.Folders, (const COutFolders &)db);
CRecordVector<UInt64> unpackSizes;
- CRecordVector<bool> digestsDefined;
- CRecordVector<UInt32> digests;
+ CUInt32DefVector digests;
for (i = 0; i < db.Files.Size(); i++)
{
const CFileItem &file = db.Files[i];
if (!file.HasStream)
continue;
unpackSizes.Add(file.Size);
- digestsDefined.Add(file.CrcDefined);
- digests.Add(file.Crc);
+ digests.Defs.Add(file.CrcDefined);
+ digests.Vals.Add(file.Crc);
}
- WriteSubStreamsInfo(
- db.Folders,
- db.NumUnpackStreamsVector,
- unpackSizes,
- digestsDefined,
- digests);
+ WriteSubStreamsInfo(db.Folders, (const COutFolders &)db, unpackSizes, digests);
WriteByte(NID::kEnd);
}
@@ -618,85 +577,75 @@ void COutArchive::WriteHeader(
WriteNumber(db.Files.Size());
{
- /* ---------- Empty Streams ---------- */
- CBoolVector emptyStreamVector;
- emptyStreamVector.Reserve(db.Files.Size());
- int numEmptyStreams = 0;
- for (i = 0; i < db.Files.Size(); i++)
- if (db.Files[i].HasStream)
- emptyStreamVector.Add(false);
- else
- {
- emptyStreamVector.Add(true);
- numEmptyStreams++;
- }
- if (numEmptyStreams > 0)
- {
- WriteByte(NID::kEmptyStream);
- WriteNumber(Bv_GetSizeInBytes(emptyStreamVector));
- WriteBoolVector(emptyStreamVector);
-
- CBoolVector emptyFileVector, antiVector;
- emptyFileVector.Reserve(numEmptyStreams);
- antiVector.Reserve(numEmptyStreams);
- CNum numEmptyFiles = 0, numAntiItems = 0;
+ /* ---------- Empty Streams ---------- */
+ CBoolVector emptyStreamVector;
+ emptyStreamVector.ClearAndSetSize(db.Files.Size());
+ unsigned numEmptyStreams = 0;
for (i = 0; i < db.Files.Size(); i++)
+ if (db.Files[i].HasStream)
+ emptyStreamVector[i] = false;
+ else
+ {
+ emptyStreamVector[i] = true;
+ numEmptyStreams++;
+ }
+ if (numEmptyStreams != 0)
{
- const CFileItem &file = db.Files[i];
- if (!file.HasStream)
+ WritePropBoolVector(NID::kEmptyStream, emptyStreamVector);
+
+ CBoolVector emptyFileVector, antiVector;
+ emptyFileVector.ClearAndSetSize(numEmptyStreams);
+ antiVector.ClearAndSetSize(numEmptyStreams);
+ bool thereAreEmptyFiles = false, thereAreAntiItems = false;
+ unsigned cur = 0;
+ for (i = 0; i < db.Files.Size(); i++)
{
- emptyFileVector.Add(!file.IsDir);
+ const CFileItem &file = db.Files[i];
+ if (file.HasStream)
+ continue;
+ emptyFileVector[cur] = !file.IsDir;
if (!file.IsDir)
- numEmptyFiles++;
+ thereAreEmptyFiles = true;
bool isAnti = db.IsItemAnti(i);
- antiVector.Add(isAnti);
+ antiVector[cur] = isAnti;
if (isAnti)
- numAntiItems++;
+ thereAreAntiItems = true;
+ cur++;
}
- }
- if (numEmptyFiles > 0)
- {
- WriteByte(NID::kEmptyFile);
- WriteNumber(Bv_GetSizeInBytes(emptyFileVector));
- WriteBoolVector(emptyFileVector);
- }
-
- if (numAntiItems > 0)
- {
- WriteByte(NID::kAnti);
- WriteNumber(Bv_GetSizeInBytes(antiVector));
- WriteBoolVector(antiVector);
+ if (thereAreEmptyFiles)
+ WritePropBoolVector(NID::kEmptyFile, emptyFileVector);
+ if (thereAreAntiItems)
+ WritePropBoolVector(NID::kAnti, antiVector);
}
}
- }
{
/* ---------- Names ---------- */
-
- int numDefined = 0;
+
+ unsigned numDefined = 0;
size_t namesDataSize = 0;
- for (int i = 0; i < db.Files.Size(); i++)
+ FOR_VECTOR (i, db.Files)
{
- const UString &name = db.Files[i].Name;
+ const UString &name = db.Names[i];
if (!name.IsEmpty())
numDefined++;
- namesDataSize += (name.Length() + 1) * 2;
+ namesDataSize += (name.Len() + 1) * 2;
}
-
+
if (numDefined > 0)
{
namesDataSize++;
- SkipAlign(2 + GetBigNumberSize(namesDataSize), 2);
+ SkipAlign(2 + GetBigNumberSize(namesDataSize), 16);
WriteByte(NID::kName);
WriteNumber(namesDataSize);
WriteByte(0);
- for (int i = 0; i < db.Files.Size(); i++)
+ FOR_VECTOR (i, db.Files)
{
- const UString &name = db.Files[i].Name;
- for (int t = 0; t <= name.Length(); t++)
+ const UString &name = db.Names[i];
+ for (unsigned t = 0; t <= name.Len(); t++)
{
wchar_t c = name[t];
WriteByte((Byte)c);
@@ -706,26 +655,26 @@ void COutArchive::WriteHeader(
}
}
- if (headerOptions.WriteCTime) WriteUInt64DefVector(db.CTime, NID::kCTime);
- if (headerOptions.WriteATime) WriteUInt64DefVector(db.ATime, NID::kATime);
- if (headerOptions.WriteMTime) WriteUInt64DefVector(db.MTime, NID::kMTime);
+ /* if (headerOptions.WriteCTime) */ WriteUInt64DefVector(db.CTime, NID::kCTime);
+ /* if (headerOptions.WriteATime) */ WriteUInt64DefVector(db.ATime, NID::kATime);
+ /* if (headerOptions.WriteMTime) */ WriteUInt64DefVector(db.MTime, NID::kMTime);
WriteUInt64DefVector(db.StartPos, NID::kStartPos);
-
+
{
/* ---------- Write Attrib ---------- */
CBoolVector boolVector;
- boolVector.Reserve(db.Files.Size());
- int numDefined = 0;
+ boolVector.ClearAndSetSize(db.Files.Size());
+ unsigned numDefined = 0;
for (i = 0; i < db.Files.Size(); i++)
{
bool defined = db.Files[i].AttribDefined;
- boolVector.Add(defined);
+ boolVector[i] = defined;
if (defined)
numDefined++;
}
- if (numDefined > 0)
+ if (numDefined != 0)
{
- WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttributes, 4);
+ WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttrib, 4);
for (i = 0; i < db.Files.Size(); i++)
{
const CFileItem &file = db.Files[i];
@@ -735,13 +684,95 @@ void COutArchive::WriteHeader(
}
}
+ /*
+ {
+ // ---------- Write IsAux ----------
+ unsigned numAux = 0;
+ const CBoolVector &isAux = db.IsAux;
+ for (i = 0; i < isAux.Size(); i++)
+ if (isAux[i])
+ numAux++;
+ if (numAux > 0)
+ {
+ const unsigned bvSize = Bv_GetSizeInBytes(isAux);
+ WriteByte(NID::kIsAux);
+ WriteNumber(bvSize);
+ WriteBoolVector(isAux);
+ }
+ }
+
+ {
+ // ---------- Write Parent ----------
+ CBoolVector boolVector;
+ boolVector.Reserve(db.Files.Size());
+ unsigned numIsDir = 0;
+ unsigned numParentLinks = 0;
+ for (i = 0; i < db.Files.Size(); i++)
+ {
+ const CFileItem &file = db.Files[i];
+ bool defined = !file.IsAltStream;
+ boolVector.Add(defined);
+ if (defined)
+ numIsDir++;
+ if (file.Parent >= 0)
+ numParentLinks++;
+ }
+ if (numParentLinks > 0)
+ {
+ // WriteAlignedBoolHeader(boolVector, numDefined, NID::kParent, 4);
+ const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector);
+ const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1;
+ SkipAlign(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 4);
+
+ WriteByte(NID::kParent);
+ WriteNumber(dataSize);
+ if (numIsDir == boolVector.Size())
+ WriteByte(1);
+ else
+ {
+ WriteByte(0);
+ WriteBoolVector(boolVector);
+ }
+ for (i = 0; i < db.Files.Size(); i++)
+ {
+ const CFileItem &file = db.Files[i];
+ // if (file.Parent >= 0)
+ WriteUInt32(file.Parent);
+ }
+ }
+ }
+
+ if (thereIsSecure)
+ {
+ UInt64 secureDataSize = 1 + 4 +
+ db.SecureBuf.Size() +
+ db.SecureSizes.Size() * 4;
+ // secureDataSize += db.SecureIDs.Size() * 4;
+ for (i = 0; i < db.SecureIDs.Size(); i++)
+ secureDataSize += GetBigNumberSize(db.SecureIDs[i]);
+ SkipAlign(2 + GetBigNumberSize(secureDataSize), 4);
+ WriteByte(NID::kNtSecure);
+ WriteNumber(secureDataSize);
+ WriteByte(0);
+ WriteUInt32(db.SecureSizes.Size());
+ for (i = 0; i < db.SecureSizes.Size(); i++)
+ WriteUInt32(db.SecureSizes[i]);
+ WriteBytes(db.SecureBuf, db.SecureBuf.Size());
+ for (i = 0; i < db.SecureIDs.Size(); i++)
+ {
+ WriteNumber(db.SecureIDs[i]);
+ // WriteUInt32(db.SecureIDs[i]);
+ }
+ }
+ */
+
WriteByte(NID::kEnd); // for files
WriteByte(NID::kEnd); // for headers
}
HRESULT COutArchive::WriteDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
- const CArchiveDatabase &db,
+ const CArchiveDatabaseOut &db,
const CCompressionMethodMode *options,
const CHeaderOptions &headerOptions)
{
@@ -773,18 +804,17 @@ HRESULT COutArchive::WriteDatabase(
_countMode = encodeHeaders;
_writeToStream = true;
_countSize = 0;
- WriteHeader(db, headerOptions, headerOffset);
+ WriteHeader(db, /* headerOptions, */ headerOffset);
if (encodeHeaders)
{
- CByteBuffer buf;
- buf.SetCapacity(_countSize);
+ CByteBuffer buf(_countSize);
_outByte2.Init((Byte *)buf, _countSize);
-
+
_countMode = false;
_writeToStream = false;
- WriteHeader(db, headerOptions, headerOffset);
-
+ WriteHeader(db, /* headerOptions, */ headerOffset);
+
if (_countSize != _outByte2.GetPos())
return E_FAIL;
@@ -794,22 +824,23 @@ HRESULT COutArchive::WriteDatabase(
CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions);
CRecordVector<UInt64> packSizes;
CObjectVector<CFolder> folders;
+ COutFolders outFolders;
+
RINOK(EncodeStream(
EXTERNAL_CODECS_LOC_VARS
encoder, buf,
- packSizes, folders));
+ packSizes, folders, outFolders));
_writeToStream = true;
-
+
if (folders.Size() == 0)
throw 1;
WriteID(NID::kEncodedHeader);
- WritePackInfo(headerOffset, packSizes,
- CRecordVector<bool>(), CRecordVector<UInt32>());
- WriteUnpackInfo(folders);
+ WritePackInfo(headerOffset, packSizes, CUInt32DefVector());
+ WriteUnpackInfo(folders, outFolders);
WriteByte(NID::kEnd);
- for (int i = 0; i < packSizes.Size(); i++)
+ FOR_VECTOR (i, packSizes)
headerOffset += packSizes[i];
}
RINOK(_outByte.Flush());
@@ -842,24 +873,28 @@ HRESULT COutArchive::WriteDatabase(
}
}
-void CArchiveDatabase::GetFile(int index, CFileItem &file, CFileItem2 &file2) const
+void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value)
{
- file = Files[index];
- file2.CTimeDefined = CTime.GetItem(index, file2.CTime);
- file2.ATimeDefined = ATime.GetItem(index, file2.ATime);
- file2.MTimeDefined = MTime.GetItem(index, file2.MTime);
- file2.StartPosDefined = StartPos.GetItem(index, file2.StartPos);
- file2.IsAnti = IsItemAnti(index);
+ while (index >= Defs.Size())
+ Defs.Add(false);
+ Defs[index] = defined;
+ if (!defined)
+ return;
+ while (index >= Vals.Size())
+ Vals.Add(0);
+ Vals[index] = value;
}
-void CArchiveDatabase::AddFile(const CFileItem &file, const CFileItem2 &file2)
+void CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name)
{
- int index = Files.Size();
+ unsigned index = Files.Size();
CTime.SetItem(index, file2.CTimeDefined, file2.CTime);
ATime.SetItem(index, file2.ATimeDefined, file2.ATime);
MTime.SetItem(index, file2.MTimeDefined, file2.MTime);
StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos);
- SetItemAnti(index, file2.IsAnti);
+ SetItem_Anti(index, file2.IsAnti);
+ // SetItem_Aux(index, file2.IsAux);
+ Names.Add(name);
Files.Add(file);
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.h b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.h
index 7b1b528e6..391ca9d02 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.h
@@ -9,6 +9,7 @@
#include "7zItem.h"
#include "../../Common/OutBuffer.h"
+#include "../../Common/StreamUtils.h"
namespace NArchive {
namespace N7z {
@@ -45,27 +46,191 @@ public:
struct CHeaderOptions
{
bool CompressMainHeader;
+ /*
bool WriteCTime;
bool WriteATime;
bool WriteMTime;
+ */
CHeaderOptions():
- CompressMainHeader(true),
- WriteCTime(false),
- WriteATime(false),
- WriteMTime(true)
+ CompressMainHeader(true)
+ /*
+ , WriteCTime(false)
+ , WriteATime(false)
+ , WriteMTime(true)
+ */
{}
};
+
+struct CFileItem2
+{
+ UInt64 CTime;
+ UInt64 ATime;
+ UInt64 MTime;
+ UInt64 StartPos;
+ bool CTimeDefined;
+ bool ATimeDefined;
+ bool MTimeDefined;
+ bool StartPosDefined;
+ bool IsAnti;
+ // bool IsAux;
+
+ void Init()
+ {
+ CTimeDefined = false;
+ ATimeDefined = false;
+ MTimeDefined = false;
+ StartPosDefined = false;
+ IsAnti = false;
+ // IsAux = false;
+ }
+};
+
+struct COutFolders
+{
+ CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
+
+ CRecordVector<CNum> NumUnpackStreamsVector;
+ CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bind coders
+
+ void OutFoldersClear()
+ {
+ FolderUnpackCRCs.Clear();
+ NumUnpackStreamsVector.Clear();
+ CoderUnpackSizes.Clear();
+ }
+
+ void OutFoldersReserveDown()
+ {
+ FolderUnpackCRCs.ReserveDown();
+ NumUnpackStreamsVector.ReserveDown();
+ CoderUnpackSizes.ReserveDown();
+ }
+};
+
+struct CArchiveDatabaseOut: public COutFolders
+{
+ CRecordVector<UInt64> PackSizes;
+ CUInt32DefVector PackCRCs;
+ CObjectVector<CFolder> Folders;
+
+ CRecordVector<CFileItem> Files;
+ UStringVector Names;
+ CUInt64DefVector CTime;
+ CUInt64DefVector ATime;
+ CUInt64DefVector MTime;
+ CUInt64DefVector StartPos;
+ CRecordVector<bool> IsAnti;
+
+ /*
+ CRecordVector<bool> IsAux;
+
+ CByteBuffer SecureBuf;
+ CRecordVector<UInt32> SecureSizes;
+ CRecordVector<UInt32> SecureIDs;
+
+ void ClearSecure()
+ {
+ SecureBuf.Free();
+ SecureSizes.Clear();
+ SecureIDs.Clear();
+ }
+ */
+
+ void Clear()
+ {
+ OutFoldersClear();
+
+ PackSizes.Clear();
+ PackCRCs.Clear();
+ Folders.Clear();
+
+ Files.Clear();
+ Names.Clear();
+ CTime.Clear();
+ ATime.Clear();
+ MTime.Clear();
+ StartPos.Clear();
+ IsAnti.Clear();
+
+ /*
+ IsAux.Clear();
+ ClearSecure();
+ */
+ }
+
+ void ReserveDown()
+ {
+ OutFoldersReserveDown();
+
+ PackSizes.ReserveDown();
+ PackCRCs.ReserveDown();
+ Folders.ReserveDown();
+
+ Files.ReserveDown();
+ Names.ReserveDown();
+ CTime.ReserveDown();
+ ATime.ReserveDown();
+ MTime.ReserveDown();
+ StartPos.ReserveDown();
+ IsAnti.ReserveDown();
+
+ /*
+ IsAux.ReserveDown();
+ */
+ }
+
+ bool IsEmpty() const
+ {
+ return (
+ PackSizes.IsEmpty() &&
+ NumUnpackStreamsVector.IsEmpty() &&
+ Folders.IsEmpty() &&
+ Files.IsEmpty());
+ }
+
+ bool CheckNumFiles() const
+ {
+ unsigned size = Files.Size();
+ return (
+ CTime.CheckSize(size) &&
+ ATime.CheckSize(size) &&
+ MTime.CheckSize(size) &&
+ StartPos.CheckSize(size) &&
+ (size == IsAnti.Size() || IsAnti.Size() == 0));
+ }
+
+ bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
+ // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
+
+ void SetItem_Anti(unsigned index, bool isAnti)
+ {
+ while (index >= IsAnti.Size())
+ IsAnti.Add(false);
+ IsAnti[index] = isAnti;
+ }
+ /*
+ void SetItem_Aux(unsigned index, bool isAux)
+ {
+ while (index >= IsAux.Size())
+ IsAux.Add(false);
+ IsAux[index] = isAux;
+ }
+ */
+
+ void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name);
+};
+
class COutArchive
{
UInt64 _prefixHeaderPos;
- HRESULT WriteDirect(const void *data, UInt32 size);
-
+ HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); }
+
UInt64 GetPos() const;
void WriteBytes(const void *data, size_t size);
- void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.GetCapacity()); }
+ void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.Size()); }
void WriteByte(Byte b);
void WriteUInt32(UInt32 value);
void WriteUInt64(UInt64 value);
@@ -75,38 +240,38 @@ class COutArchive
void WriteFolder(const CFolder &folder);
HRESULT WriteFileHeader(const CFileItem &itemInfo);
void WriteBoolVector(const CBoolVector &boolVector);
- void WriteHashDigests(
- const CRecordVector<bool> &digestsDefined,
- const CRecordVector<UInt32> &hashDigests);
+ void WritePropBoolVector(Byte id, const CBoolVector &boolVector);
+
+ void WriteHashDigests(const CUInt32DefVector &digests);
void WritePackInfo(
UInt64 dataOffset,
const CRecordVector<UInt64> &packSizes,
- const CRecordVector<bool> &packCRCsDefined,
- const CRecordVector<UInt32> &packCRCs);
+ const CUInt32DefVector &packCRCs);
- void WriteUnpackInfo(const CObjectVector<CFolder> &folders);
+ void WriteUnpackInfo(
+ const CObjectVector<CFolder> &folders,
+ const COutFolders &outFolders);
void WriteSubStreamsInfo(
const CObjectVector<CFolder> &folders,
- const CRecordVector<CNum> &numUnpackStreamsInFolders,
+ const COutFolders &outFolders,
const CRecordVector<UInt64> &unpackSizes,
- const CRecordVector<bool> &digestsDefined,
- const CRecordVector<UInt32> &hashDigests);
+ const CUInt32DefVector &digests);
void SkipAlign(unsigned pos, unsigned alignSize);
- void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize);
+ void WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize);
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
HRESULT EncodeStream(
DECL_EXTERNAL_CODECS_LOC_VARS
CEncoder &encoder, const CByteBuffer &data,
- CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
+ CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders);
void WriteHeader(
- const CArchiveDatabase &db,
- const CHeaderOptions &headerOptions,
+ const CArchiveDatabaseOut &db,
+ // const CHeaderOptions &headerOptions,
UInt64 &headerOffset);
-
+
bool _countMode;
bool _writeToStream;
size_t _countSize;
@@ -118,6 +283,8 @@ class COutArchive
bool _endMarker;
#endif
+ bool _useAlign;
+
HRESULT WriteSignature();
#ifdef _7Z_VOL
HRESULT WriteFinishSignature();
@@ -136,7 +303,7 @@ public:
HRESULT SkipPrefixArchiveHeader();
HRESULT WriteDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
- const CArchiveDatabase &db,
+ const CArchiveDatabaseOut &db,
const CCompressionMethodMode *options,
const CHeaderOptions &headerOptions);
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zProperties.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zProperties.cpp
index fd4af49c7..a29f8abe9 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zProperties.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zProperties.cpp
@@ -17,12 +17,12 @@ struct CPropMap
STATPROPSTG StatPROPSTG;
};
-CPropMap kPropMap[] =
+static const CPropMap kPropMap[] =
{
{ NID::kName, { NULL, kpidPath, VT_BSTR } },
{ NID::kSize, { NULL, kpidSize, VT_UI8 } },
{ NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },
-
+
#ifdef _MULTI_PACK
{ 100, { L"Pack0", kpidPackedSize0, VT_UI8 } },
{ 101, { L"Pack1", kpidPackedSize1, VT_UI8 } },
@@ -34,11 +34,12 @@ CPropMap kPropMap[] =
{ NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },
{ NID::kMTime, { NULL, kpidMTime, VT_FILETIME } },
{ NID::kATime, { NULL, kpidATime, VT_FILETIME } },
- { NID::kWinAttributes, { NULL, kpidAttrib, VT_UI4 } },
+ { NID::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } },
{ NID::kStartPos, { NULL, kpidPosition, VT_UI4 } },
{ NID::kCRC, { NULL, kpidCRC, VT_UI4 } },
-
+
+// { NID::kIsAux, { NULL, kpidIsAux, VT_BOOL } },
{ NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } }
#ifndef _SFX
@@ -49,11 +50,9 @@ CPropMap kPropMap[] =
#endif
};
-static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
-
static int FindPropInMap(UInt64 filePropID)
{
- for (int i = 0; i < kPropMapSize; i++)
+ for (int i = 0; i < ARRAY_SIZE(kPropMap); i++)
if (kPropMap[i].FilePropID == filePropID)
return i;
return -1;
@@ -62,7 +61,7 @@ static int FindPropInMap(UInt64 filePropID)
static void CopyOneItem(CRecordVector<UInt64> &src,
CRecordVector<UInt64> &dest, UInt32 item)
{
- for (int i = 0; i < src.Size(); i++)
+ FOR_VECTOR (i, src)
if (src[i] == item)
{
dest.Add(item);
@@ -73,7 +72,7 @@ static void CopyOneItem(CRecordVector<UInt64> &src,
static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
{
- for (int i = 0; i < src.Size(); i++)
+ FOR_VECTOR (i, src)
if (src[i] == item)
{
src.Delete(i);
@@ -83,7 +82,7 @@ static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
{
- for (int i = 0; i < dest.Size(); i++)
+ FOR_VECTOR (i, dest)
if (dest[i] == item)
{
dest.Delete(i);
@@ -92,34 +91,41 @@ static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
dest.Insert(0, item);
}
+#define COPY_ONE_ITEM(id) CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::id);
+
void CHandler::FillPopIDs()
{
_fileInfoPopIDs.Clear();
#ifdef _7Z_VOL
- if(_volumes.Size() < 1)
+ if (_volumes.Size() < 1)
return;
const CVolume &volume = _volumes.Front();
const CArchiveDatabaseEx &_db = volume.Database;
#endif
- CRecordVector<UInt64> fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs;
+ CRecordVector<UInt64> fileInfoPopIDs = _db.ArcInfo.FileInfoPopIDs;
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
+ /*
+ RemoveOneItem(fileInfoPopIDs, NID::kParent);
+ RemoveOneItem(fileInfoPopIDs, NID::kNtSecure);
+ */
+
+ COPY_ONE_ITEM(kName);
+ COPY_ONE_ITEM(kAnti);
+ COPY_ONE_ITEM(kSize);
+ COPY_ONE_ITEM(kPackInfo);
+ COPY_ONE_ITEM(kCTime);
+ COPY_ONE_ITEM(kMTime);
+ COPY_ONE_ITEM(kATime);
+ COPY_ONE_ITEM(kWinAttrib);
+ COPY_ONE_ITEM(kCRC);
+ COPY_ONE_ITEM(kComment);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
- CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
_fileInfoPopIDs += fileInfoPopIDs;
-
+
#ifndef _SFX
_fileInfoPopIDs.Add(97);
_fileInfoPopIDs.Add(98);
@@ -141,9 +147,9 @@ void CHandler::FillPopIDs()
#endif
}
-STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
{
- *numProperties = _fileInfoPopIDs.Size();
+ *numProps = _fileInfoPopIDs.Size();
return S_OK;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zRegister.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zRegister.cpp
index 6e9bf6b99..37ea29d30 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zRegister.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zRegister.cpp
@@ -5,14 +5,21 @@
#include "../../Common/RegisterArc.h"
#include "7zHandler.h"
-static IInArchive *CreateArc() { return new NArchive::N7z::CHandler; }
-#ifndef EXTRACT_ONLY
-static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler; }
-#else
-#define CreateArcOut 0
-#endif
+
+namespace NArchive {
+namespace N7z {
+
+IMP_CreateArcIn
+IMP_CreateArcOut
static CArcInfo g_ArcInfo =
- { L"7z", L"7z", 0, 7, {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut };
+ { "7z", "7z", 0, 7,
+ 6, {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C},
+ 0,
+ NArcInfoFlags::kFindSignature,
+ REF_CreateArc_Pair };
+
+REGISTER_ARC_DEC_SIG(7z)
+// REGISTER_ARC(7z)
-REGISTER_ARC(7z)
+}}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zSpecStream.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zSpecStream.cpp
index 06969636d..8e45d9875 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zSpecStream.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zSpecStream.cpp
@@ -9,16 +9,14 @@ STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32
UInt32 realProcessedSize;
HRESULT result = _stream->Read(data, size, &realProcessedSize);
_size += realProcessedSize;
- if (processedSize != 0)
+ if (processedSize)
*processedSize = realProcessedSize;
return result;
}
-STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
- UInt64 subStream, UInt64 *value)
+STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
- if (_getSubStreamSize == NULL)
+ if (!_getSubStreamSize)
return E_NOTIMPL;
- return _getSubStreamSize->GetSubStreamSize(subStream, value);
+ return _getSubStreamSize->GetSubStreamSize(subStream, value);
}
-
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zUpdate.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zUpdate.cpp
index f07efc178..c745e32f0 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zUpdate.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zUpdate.cpp
@@ -4,10 +4,11 @@
#include "../../../../C/CpuArch.h"
-#include "../../Common/LimitedStreams.h"
-#include "../../Common/ProgressUtils.h"
+#include "../../../Common/Wildcard.h"
#include "../../Common/CreateCoder.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/ProgressUtils.h"
#include "../../Compress/CopyCoder.h"
@@ -28,15 +29,6 @@
namespace NArchive {
namespace N7z {
-static const UInt64 k_LZMA = 0x030101;
-static const UInt64 k_BCJ = 0x03030103;
-static const UInt64 k_BCJ2 = 0x0303011B;
-
-static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2";
-static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
-static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
-static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
-
#ifdef MY_CPU_X86_OR_AMD64
#define USE_86_FILTER
#endif
@@ -71,19 +63,20 @@ int CUpdateItem::GetExtensionPos() const
int slashPos = GetReverseSlashPos(Name);
int dotPos = Name.ReverseFind(L'.');
if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
- return Name.Length();
+ return Name.Len();
return dotPos + 1;
}
UString CUpdateItem::GetExtension() const
{
- return Name.Mid(GetExtensionPos());
+ return Name.Ptr(GetExtensionPos());
}
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
#define RINOZ_COMP(a, b) RINOZ(MyCompare(a, b))
+/*
static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
{
size_t c1 = a1.GetCapacity();
@@ -123,11 +116,12 @@ static int CompareFolders(const CFolder &f1, const CFolder &f2)
RINOZ(CompareBindPairs(f1.BindPairs[i], f2.BindPairs[i]));
return 0;
}
+*/
/*
static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
{
- return MyStringCompareNoCase(f1.Name, f2.Name);
+ return CompareFileNames(f1.Name, f2.Name);
}
*/
@@ -138,15 +132,19 @@ struct CFolderRepack
CNum NumCopyFiles;
};
-static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2, void *param)
+static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2, void * /* param */)
{
RINOZ_COMP(p1->Group, p2->Group);
int i1 = p1->FolderIndex;
int i2 = p2->FolderIndex;
- const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param;
+ /*
+ // In that version we don't want to parse folders here, so we don't compare folders
+ // probably it must be improved in future
+ const CDbEx &db = *(const CDbEx *)param;
RINOZ(CompareFolders(
db.Folders[i1],
db.Folders[i2]));
+ */
return MyCompare(i1, i2);
/*
RINOZ_COMP(
@@ -160,25 +158,31 @@ static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2
*/
}
-////////////////////////////////////////////////////////////
+/*
+ we sort empty files and dirs in such order:
+ - Dir.NonAnti (name sorted)
+ - File.NonAnti (name sorted)
+ - File.Anti (name sorted)
+ - Dir.Anti (reverse name sorted)
+*/
static int CompareEmptyItems(const int *p1, const int *p2, void *param)
{
const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
const CUpdateItem &u1 = updateItems[*p1];
const CUpdateItem &u2 = updateItems[*p2];
+ // NonAnti < Anti
+ if (u1.IsAnti != u2.IsAnti)
+ return (u1.IsAnti ? 1 : -1);
if (u1.IsDir != u2.IsDir)
- return (u1.IsDir) ? 1 : -1;
- if (u1.IsDir)
{
- if (u1.IsAnti != u2.IsAnti)
+ // Dir.NonAnti < File < Dir.Anti
+ if (u1.IsDir)
return (u1.IsAnti ? 1 : -1);
- int n = MyStringCompareNoCase(u1.Name, u2.Name);
- return -n;
+ return (u2.IsAnti ? -1 : 1);
}
- if (u1.IsAnti != u2.IsAnti)
- return (u1.IsAnti ? 1 : -1);
- return MyStringCompareNoCase(u1.Name, u2.Name);
+ int n = CompareFileNames(u1.Name, u2.Name);
+ return (u1.IsDir && u1.IsAnti) ? -n : n;
}
static const char *g_Exts =
@@ -211,7 +215,7 @@ static const char *g_Exts =
" exe dll ocx vbx sfx sys tlb awx com obj lib out o so "
" pdb pch idb ncb opt";
-int GetExtIndex(const char *ext)
+static int GetExtIndex(const char *ext)
{
int extIndex = 1;
const char *p = g_Exts;
@@ -250,7 +254,9 @@ struct CRefItem
UInt32 Index;
UInt32 ExtensionPos;
UInt32 NamePos;
- int ExtensionIndex;
+ unsigned ExtensionIndex;
+
+ CRefItem() {};
CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType):
UpdateItem(&ui),
Index(index),
@@ -261,64 +267,134 @@ struct CRefItem
if (sortByType)
{
int slashPos = GetReverseSlashPos(ui.Name);
- NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0);
+ NamePos = slashPos + 1;
int dotPos = ui.Name.ReverseFind(L'.');
- if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
- ExtensionPos = ui.Name.Length();
+ if (dotPos < 0 || dotPos < slashPos)
+ ExtensionPos = ui.Name.Len();
else
{
ExtensionPos = dotPos + 1;
- UString us = ui.Name.Mid(ExtensionPos);
- if (!us.IsEmpty())
+ if (ExtensionPos != ui.Name.Len())
{
- us.MakeLower();
- int i;
AString s;
- for (i = 0; i < us.Length(); i++)
+ for (unsigned pos = ExtensionPos;; pos++)
{
- wchar_t c = us[i];
+ wchar_t c = ui.Name[pos];
if (c >= 0x80)
break;
- s += (char)c;
+ if (c == 0)
+ {
+ ExtensionIndex = GetExtIndex(s);
+ break;
+ }
+ s += (char)MyCharLower_Ascii((char)c);
}
- if (i == us.Length())
- ExtensionIndex = GetExtIndex(s);
- else
- ExtensionIndex = 0;
}
}
}
}
};
+struct CSortParam
+{
+ // const CObjectVector<CTreeFolder> *TreeFolders;
+ bool SortByType;
+};
+
+/*
+ we sort files in such order:
+ - Dir.NonAnti (name sorted)
+ - alt streams
+ - Dirs
+ - Dir.Anti (reverse name sorted)
+*/
+
+
static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param)
{
const CRefItem &a1 = *p1;
const CRefItem &a2 = *p2;
const CUpdateItem &u1 = *a1.UpdateItem;
const CUpdateItem &u2 = *a2.UpdateItem;
- int n;
+
+ /*
+ if (u1.IsAltStream != u2.IsAltStream)
+ return u1.IsAltStream ? 1 : -1;
+ */
+
+ // Actually there are no dirs that time. They were stored in other steps
+ // So that code is unused?
if (u1.IsDir != u2.IsDir)
- return (u1.IsDir) ? 1 : -1;
+ return u1.IsDir ? 1 : -1;
if (u1.IsDir)
{
if (u1.IsAnti != u2.IsAnti)
return (u1.IsAnti ? 1 : -1);
- n = MyStringCompareNoCase(u1.Name, u2.Name);
+ int n = CompareFileNames(u1.Name, u2.Name);
return -n;
}
- bool sortByType = *(bool *)param;
+
+ // bool sortByType = *(bool *)param;
+ const CSortParam *sortParam = (const CSortParam *)param;
+ bool sortByType = sortParam->SortByType;
if (sortByType)
{
RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex);
- RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
- RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
+ RINOZ(CompareFileNames(u1.Name.Ptr(a1.ExtensionPos), u2.Name.Ptr(a2.ExtensionPos)));
+ RINOZ(CompareFileNames(u1.Name.Ptr(a1.NamePos), u2.Name.Ptr(a2.NamePos)));
if (!u1.MTimeDefined && u2.MTimeDefined) return 1;
if (u1.MTimeDefined && !u2.MTimeDefined) return -1;
if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime);
RINOZ_COMP(u1.Size, u2.Size);
}
- return MyStringCompareNoCase(u1.Name, u2.Name);
+ /*
+ int par1 = a1.UpdateItem->ParentFolderIndex;
+ int par2 = a2.UpdateItem->ParentFolderIndex;
+ const CTreeFolder &tf1 = (*sortParam->TreeFolders)[par1];
+ const CTreeFolder &tf2 = (*sortParam->TreeFolders)[par2];
+
+ int b1 = tf1.SortIndex, e1 = tf1.SortIndexEnd;
+ int b2 = tf2.SortIndex, e2 = tf2.SortIndexEnd;
+ if (b1 < b2)
+ {
+ if (e1 <= b2)
+ return -1;
+ // p2 in p1
+ int par = par2;
+ for (;;)
+ {
+ const CTreeFolder &tf = (*sortParam->TreeFolders)[par];
+ par = tf.Parent;
+ if (par == par1)
+ {
+ RINOZ(CompareFileNames(u1.Name, tf.Name));
+ break;
+ }
+ }
+ }
+ else if (b2 < b1)
+ {
+ if (e2 <= b1)
+ return 1;
+ // p1 in p2
+ int par = par1;
+ for (;;)
+ {
+ const CTreeFolder &tf = (*sortParam->TreeFolders)[par];
+ par = tf.Parent;
+ if (par == par2)
+ {
+ RINOZ(CompareFileNames(tf.Name, u2.Name));
+ break;
+ }
+ }
+ }
+ */
+ // RINOZ_COMP(a1.UpdateItem->ParentSortIndex, a2.UpdateItem->ParentSortIndex);
+ RINOK(CompareFileNames(u1.Name, u2.Name));
+ RINOZ_COMP(a1.UpdateItem->IndexInClient, a2.UpdateItem->IndexInClient);
+ RINOZ_COMP(a1.UpdateItem->IndexInArchive, a2.UpdateItem->IndexInArchive);
+ return 0;
}
struct CSolidGroup
@@ -327,19 +403,19 @@ struct CSolidGroup
};
#ifdef _WIN32
-static wchar_t *g_ExeExts[] =
+static const wchar_t *g_ExeExts[] =
{
- L"dll",
- L"exe",
- L"ocx",
- L"sfx",
- L"sys"
+ L"dll"
+ , L"exe"
+ , L"ocx"
+ , L"sfx"
+ , L"sys"
};
-static bool IsExeExt(const UString &ext)
+static bool IsExeExt(const wchar_t *ext)
{
- for (int i = 0; i < sizeof(g_ExeExts) / sizeof(g_ExeExts[0]); i++)
- if (ext.CompareNoCase(g_ExeExts[i]) == 0)
+ for (int i = 0; i < ARRAY_SIZE(g_ExeExts); i++)
+ if (MyStringCompareNoCase(ext, g_ExeExts[i]) == 0)
return true;
return false;
}
@@ -361,7 +437,7 @@ static bool IsExeFile(const CUpdateItem &ui)
{
for(UInt32 i = 0; i < processedSize ; i++)
{
- if (buffer[i] == 0)
+ if (buffer[i] == 0)
{
return true; // this file is not a text (ascii, utf8, ...) !
}
@@ -369,112 +445,97 @@ static bool IsExeFile(const CUpdateItem &ui)
}
}
}
- }
+ }
return false;
}
#endif
-#ifdef USE_86_FILTER
-static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult)
+static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &m)
+{
+ m.Id = methodID;
+ m.NumInStreams = numInStreams;
+ m.NumOutStreams = 1;
+}
+
+static void AddBcj2Methods(CCompressionMethodMode &mode)
{
- methodResult.Id = methodID;
- methodResult.NumInStreams = numInStreams;
- methodResult.NumOutStreams = 1;
+ CMethodFull m;
+ GetMethodFull(k_LZMA, 1, m);
+
+ m.AddProp32(NCoderPropID::kDictionarySize, 1 << 20);
+ m.AddProp32(NCoderPropID::kNumFastBytes, 128);
+ m.AddProp32(NCoderPropID::kNumThreads, 1);
+ m.AddProp32(NCoderPropID::kLitPosBits, 2);
+ m.AddProp32(NCoderPropID::kLitContextBits, 0);
+ // m.AddPropString(NCoderPropID::kMatchFinder, L"BT2");
+
+ mode.Methods.Add(m);
+ mode.Methods.Add(m);
+
+ CBind bind;
+ bind.OutCoder = 0;
+ bind.InStream = 0;
+ bind.InCoder = 1; bind.OutStream = 0; mode.Binds.Add(bind);
+ bind.InCoder = 2; bind.OutStream = 1; mode.Binds.Add(bind);
+ bind.InCoder = 3; bind.OutStream = 2; mode.Binds.Add(bind);
}
-static void MakeExeMethod(const CCompressionMethodMode &method,
- bool bcj2Filter, CCompressionMethodMode &exeMethod)
+static void MakeExeMethod(CCompressionMethodMode &mode,
+ bool useFilters, bool addFilter, bool bcj2Filter)
{
- exeMethod = method;
+ if (!mode.Binds.IsEmpty() || !useFilters || mode.Methods.Size() > 2)
+ return;
+ if (mode.Methods.Size() == 2)
+ {
+ if (mode.Methods[0].Id == k_BCJ2)
+ AddBcj2Methods(mode);
+ return;
+ }
+ if (!addFilter)
+ return;
+ bcj2Filter = bcj2Filter;
+ #ifdef USE_86_FILTER
if (bcj2Filter)
{
- CMethodFull methodFull;
- GetMethodFull(k_BCJ2, 4, methodFull);
- exeMethod.Methods.Insert(0, methodFull);
- GetMethodFull(k_LZMA, 1, methodFull);
- {
- CProp prop;
- prop.Id = NCoderPropID::kAlgorithm;
- prop.Value = kAlgorithmForBCJ2_LZMA;
- methodFull.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kMatchFinder;
- prop.Value = kMatchFinderForBCJ2_LZMA;
- methodFull.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kDictionarySize;
- prop.Value = kDictionaryForBCJ2_LZMA;
- methodFull.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kNumFastBytes;
- prop.Value = kNumFastBytesForBCJ2_LZMA;
- methodFull.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kNumThreads;
- prop.Value = (UInt32)1;
- methodFull.Props.Add(prop);
- }
-
- exeMethod.Methods.Add(methodFull);
- exeMethod.Methods.Add(methodFull);
- CBind bind;
-
- bind.OutCoder = 0;
- bind.InStream = 0;
-
- bind.InCoder = 1;
- bind.OutStream = 0;
- exeMethod.Binds.Add(bind);
-
- bind.InCoder = 2;
- bind.OutStream = 1;
- exeMethod.Binds.Add(bind);
-
- bind.InCoder = 3;
- bind.OutStream = 2;
- exeMethod.Binds.Add(bind);
+ CMethodFull m;
+ GetMethodFull(k_BCJ2, 4, m);
+ mode.Methods.Insert(0, m);
+ AddBcj2Methods(mode);
}
else
{
- CMethodFull methodFull;
- GetMethodFull(k_BCJ, 1, methodFull);
- exeMethod.Methods.Insert(0, methodFull);
+ CMethodFull m;
+ GetMethodFull(k_BCJ, 1, m);
+ mode.Methods.Insert(0, m);
CBind bind;
bind.OutCoder = 0;
bind.InStream = 0;
bind.InCoder = 1;
bind.OutStream = 0;
- exeMethod.Binds.Add(bind);
+ mode.Binds.Add(bind);
}
+ #endif
}
-#endif
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
CFileItem &file, CFileItem2 &file2)
{
- file.Name = NItemName::MakeLegalName(ui.Name);
if (ui.AttribDefined)
file.SetAttrib(ui.Attrib);
-
+
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;
file.Size = ui.Size;
file.IsDir = ui.IsDir;
file.HasStream = ui.HasStream();
+ // file.IsAltStream = ui.IsAltStream;
}
class CFolderOutStream2:
@@ -483,11 +544,11 @@ class CFolderOutStream2:
{
COutStreamWithCRC *_crcStreamSpec;
CMyComPtr<ISequentialOutStream> _crcStream;
- const CArchiveDatabaseEx *_db;
+ const CDbEx *_db;
const CBoolVector *_extractStatuses;
CMyComPtr<ISequentialOutStream> _outStream;
UInt32 _startIndex;
- int _currentIndex;
+ unsigned _currentIndex;
bool _fileIsOpen;
UInt64 _rem;
@@ -497,14 +558,14 @@ class CFolderOutStream2:
HRESULT ProcessEmptyFiles();
public:
MY_UNKNOWN_IMP
-
+
CFolderOutStream2()
{
_crcStreamSpec = new COutStreamWithCRC;
_crcStream = _crcStreamSpec;
}
- HRESULT Init(const CArchiveDatabaseEx *db, UInt32 startIndex,
+ HRESULT Init(const CDbEx *db, UInt32 startIndex,
const CBoolVector *extractStatuses, ISequentialOutStream *outStream);
void ReleaseOutStream();
HRESULT CheckFinishedState() const { return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; }
@@ -512,7 +573,7 @@ public:
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
-HRESULT CFolderOutStream2::Init(const CArchiveDatabaseEx *db, UInt32 startIndex,
+HRESULT CFolderOutStream2::Init(const CDbEx *db, UInt32 startIndex,
const CBoolVector *extractStatuses, ISequentialOutStream *outStream)
{
_db = db;
@@ -611,13 +672,13 @@ public:
CMyComPtr<ISequentialOutStream> Fos;
UInt64 StartPos;
- const UInt64 *PackSizes;
- const CFolder *Folder;
+ const CFolders *Folders;
+ int FolderIndex;
#ifndef _NO_CRYPTO
- CMyComPtr<ICryptoGetTextPassword> GetTextPassword;
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
#endif
- DECL_EXTERNAL_CODECS_VARS
+ DECL_EXTERNAL_CODECS_LOC_VARS2;
CDecoder Decoder;
#ifndef _7ZIP_ST
@@ -636,6 +697,7 @@ public:
Fos = FosSpec;
Result = E_FAIL;
}
+ ~CThreadDecoder() { CVirtThread::WaitThreadFinish(); }
virtual void Execute();
};
@@ -644,21 +706,20 @@ void CThreadDecoder::Execute()
try
{
#ifndef _NO_CRYPTO
- bool passwordIsDefined;
+ bool isEncrypted = false;
+ bool passwordIsDefined = false;
#endif
+
Result = Decoder.Decode(
- EXTERNAL_CODECS_VARS
+ EXTERNAL_CODECS_LOC_VARS
InStream,
StartPos,
- PackSizes,
- *Folder,
+ *Folders, FolderIndex,
Fos,
NULL
- #ifndef _NO_CRYPTO
- , GetTextPassword, passwordIsDefined
- #endif
+ _7Z_DECODER_CRYPRO_VARS
#ifndef _7ZIP_ST
- , MtMode, NumThreads
+ , MtMode, NumThreads
#endif
);
}
@@ -673,7 +734,7 @@ void CThreadDecoder::Execute()
bool static Is86FilteredFolder(const CFolder &f)
{
- for (int i = 0; i < f.Coders.Size(); i++)
+ FOR_VECTOR(i, f.Coders)
{
CMethodId m = f.Coders[i].MethodID;
if (m == k_BCJ || m == k_BCJ2)
@@ -704,20 +765,31 @@ STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password)
static const int kNumGroupsMax = 4;
-#ifdef USE_86_FILTER
static bool Is86Group(int group) { return (group & 1) != 0; }
-#endif
static bool IsEncryptedGroup(int group) { return (group & 2) != 0; }
static int GetGroupIndex(bool encrypted, int bcjFiltered)
{ return (encrypted ? 2 : 0) + (bcjFiltered ? 1 : 0); }
+static void GetFile(const CDatabase &inDb, int index, CFileItem &file, CFileItem2 &file2)
+{
+ file = inDb.Files[index];
+ file2.CTimeDefined = inDb.CTime.GetItem(index, file2.CTime);
+ file2.ATimeDefined = inDb.ATime.GetItem(index, file2.ATime);
+ file2.MTimeDefined = inDb.MTime.GetItem(index, file2.MTime);
+ file2.StartPosDefined = inDb.StartPos.GetItem(index, file2.StartPos);
+ file2.IsAnti = inDb.IsItemAnti(index);
+ // file2.IsAux = inDb.IsItemAux(index);
+}
+
HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
- const CArchiveDatabaseEx *db,
+ const CDbEx *db,
const CObjectVector<CUpdateItem> &updateItems,
+ // const CObjectVector<CTreeFolder> &treeFolders,
+ // const CUniqBlocks &secureBlocks,
COutArchive &archive,
- CArchiveDatabase &newDatabase,
+ CArchiveDatabaseOut &newDatabase,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options
@@ -729,6 +801,9 @@ HRESULT Update(
UInt64 numSolidFiles = options.NumSolidFiles;
if (numSolidFiles == 0)
numSolidFiles = 1;
+
+ // size_t totalSecureDataSize = (size_t)secureBlocks.GetTotalSizeInBytes();
+
/*
CMyComPtr<IOutStream> outStream;
RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream));
@@ -736,23 +811,23 @@ HRESULT Update(
return E_NOTIMPL;
*/
- UInt64 startBlockSize = db != 0 ? db->ArchiveInfo.StartPosition: 0;
+ UInt64 startBlockSize = db != 0 ? db->ArcInfo.StartPosition: 0;
if (startBlockSize > 0 && !options.RemoveSfxBlock)
{
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
}
- CRecordVector<int> fileIndexToUpdateIndexMap;
+ CIntArr fileIndexToUpdateIndexMap;
CRecordVector<CFolderRepack> folderRefs;
UInt64 complexity = 0;
UInt64 inSizeForReduce2 = 0;
bool needEncryptedRepack = false;
if (db != 0)
{
- fileIndexToUpdateIndexMap.Reserve(db->Files.Size());
- int i;
+ fileIndexToUpdateIndexMap.Alloc(db->Files.Size());
+ unsigned i;
for (i = 0; i < db->Files.Size(); i++)
- fileIndexToUpdateIndexMap.Add(-1);
+ fileIndexToUpdateIndexMap[i] = -1;
for (i = 0; i < updateItems.Size(); i++)
{
@@ -761,7 +836,7 @@ HRESULT Update(
fileIndexToUpdateIndexMap[index] = i;
}
- for (i = 0; i < db->Folders.Size(); i++)
+ for (i = 0; i < (int)db->NumFolders; i++)
{
CNum indexInFolder = 0;
CNum numCopyItems = 0;
@@ -788,7 +863,8 @@ HRESULT Update(
CFolderRepack rep;
rep.FolderIndex = i;
rep.NumCopyFiles = numCopyItems;
- const CFolder &f = db->Folders[i];
+ CFolder f;
+ db->ParseFolderInfo(i, f);
bool isEncrypted = f.IsEncrypted();
rep.Group = GetGroupIndex(isEncrypted, Is86FilteredFolder(f));
folderRefs.Add(rep);
@@ -807,7 +883,7 @@ HRESULT Update(
}
UInt64 inSizeForReduce = 0;
- int i;
+ unsigned i;
for (i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &ui = updateItems[i];
@@ -824,32 +900,30 @@ HRESULT Update(
if (inSizeForReduce2 > inSizeForReduce)
inSizeForReduce = inSizeForReduce2;
- const UInt32 kMinReduceSize = (1 << 16);
- if (inSizeForReduce < kMinReduceSize)
- inSizeForReduce = kMinReduceSize;
-
RINOK(updateCallback->SetTotal(complexity));
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
+ CStreamBinder sb;
+ RINOK(sb.CreateEvents());
+
CThreadDecoder threadDecoder;
if (!folderRefs.IsEmpty())
{
#ifdef EXTERNAL_CODECS
- threadDecoder._codecsInfo = codecsInfo;
- threadDecoder._externalCodecs = *externalCodecs;
+ threadDecoder.__externalCodecs = __externalCodecs;
#endif
RINOK(threadDecoder.Create());
}
CObjectVector<CSolidGroup> groups;
for (i = 0; i < kNumGroupsMax; i++)
- groups.Add(CSolidGroup());
+ groups.AddNew();
{
- // ---------- Split files to 2 groups ----------
+ // ---------- Split files to groups ----------
bool useFilters = options.UseFilters;
const CCompressionMethodMode &method = *options.Method;
@@ -866,7 +940,7 @@ HRESULT Update(
#ifdef _WIN32
int dotPos = ui.Name.ReverseFind(L'.');
if (dotPos >= 0)
- filteredGroup = IsExeExt(ui.Name.Mid(dotPos + 1));
+ filteredGroup = IsExeExt(ui.Name.Ptr(dotPos + 1));
#else
filteredGroup = IsExeFile(ui);
#endif
@@ -881,7 +955,7 @@ HRESULT Update(
if (needEncryptedRepack)
{
getPasswordSpec = new CCryptoGetTextPassword;
- threadDecoder.GetTextPassword = getPasswordSpec;
+ threadDecoder.getTextPassword = getPasswordSpec;
if (options.Method->PasswordIsDefined)
getPasswordSpec->Password = options.Method->Password;
@@ -891,31 +965,119 @@ HRESULT Update(
return E_NOTIMPL;
CMyComBSTR password;
RINOK(getDecoderPassword->CryptoGetTextPassword(&password));
- getPasswordSpec->Password = password;
+ if ((BSTR)password)
+ getPasswordSpec->Password = password;
}
}
#endif
+
// ---------- Compress ----------
RINOK(archive.Create(seqOutStream, false));
RINOK(archive.SkipPrefixArchiveHeader());
- int folderRefIndex = 0;
+ /*
+ CIntVector treeFolderToArcIndex;
+ treeFolderToArcIndex.Reserve(treeFolders.Size());
+ for (i = 0; i < treeFolders.Size(); i++)
+ treeFolderToArcIndex.Add(-1);
+ // ---------- Write Tree (only AUX dirs) ----------
+ for (i = 1; i < treeFolders.Size(); i++)
+ {
+ const CTreeFolder &treeFolder = treeFolders[i];
+ CFileItem file;
+ CFileItem2 file2;
+ file2.Init();
+ int secureID = 0;
+ if (treeFolder.UpdateItemIndex < 0)
+ {
+ // we can store virtual dir item wuthout attrib, but we want all items have attrib.
+ file.SetAttrib(FILE_ATTRIBUTE_DIRECTORY);
+ file2.IsAux = true;
+ }
+ else
+ {
+ const CUpdateItem &ui = updateItems[treeFolder.UpdateItemIndex];
+ // if item is not dir, then it's parent for alt streams.
+ // we will write such items later
+ if (!ui.IsDir)
+ continue;
+ secureID = ui.SecureIndex;
+ if (ui.NewProps)
+ FromUpdateItemToFileItem(ui, file, file2);
+ else
+ GetFile(*db, ui.IndexInArchive, file, file2);
+ }
+ file.Size = 0;
+ file.HasStream = false;
+ file.IsDir = true;
+ file.Parent = treeFolder.Parent;
+
+ treeFolderToArcIndex[i] = newDatabase.Files.Size();
+ newDatabase.AddFile(file, file2, treeFolder.Name);
+
+ if (totalSecureDataSize != 0)
+ newDatabase.SecureIDs.Add(secureID);
+ }
+ */
+
+ {
+ /* ---------- Write non-AUX dirs and Empty files ---------- */
+ CRecordVector<int> emptyRefs;
+ for (i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &ui = updateItems[i];
+ if (ui.NewData)
+ {
+ if (ui.HasStream())
+ continue;
+ }
+ else if (ui.IndexInArchive != -1 && db->Files[ui.IndexInArchive].HasStream)
+ continue;
+ /*
+ if (ui.TreeFolderIndex >= 0)
+ continue;
+ */
+ emptyRefs.Add(i);
+ }
+ emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
+ for (i = 0; i < emptyRefs.Size(); i++)
+ {
+ const CUpdateItem &ui = updateItems[emptyRefs[i]];
+ CFileItem file;
+ CFileItem2 file2;
+ UString name;
+ if (ui.NewProps)
+ {
+ FromUpdateItemToFileItem(ui, file, file2);
+ name = ui.Name;
+ }
+ else
+ {
+ GetFile(*db, ui.IndexInArchive, file, file2);
+ db->GetPath(ui.IndexInArchive, name);
+ }
+
+ /*
+ if (totalSecureDataSize != 0)
+ newDatabase.SecureIDs.Add(ui.SecureIndex);
+ file.Parent = ui.ParentFolderIndex;
+ */
+ newDatabase.AddFile(file, file2, name);
+ }
+ }
+
+ unsigned folderRefIndex = 0;
lps->ProgressOffset = 0;
for (int groupIndex = 0; groupIndex < kNumGroupsMax; groupIndex++)
{
const CSolidGroup &group = groups[groupIndex];
- CCompressionMethodMode method;
- #ifdef USE_86_FILTER
- if (Is86Group(groupIndex))
- MakeExeMethod(*options.Method, options.MaxFilter, method);
- else
- #endif
- method = *options.Method;
+ CCompressionMethodMode method = *options.Method;
+ MakeExeMethod(method, options.UseFilters, Is86Group(groupIndex), options.MaxFilter);
if (IsEncryptedGroup(groupIndex))
{
@@ -942,36 +1104,36 @@ HRESULT Update(
if (rep.Group != groupIndex)
break;
int folderIndex = rep.FolderIndex;
-
+
if (rep.NumCopyFiles == db->NumUnpackStreamsVector[folderIndex])
{
UInt64 packSize = db->GetFolderFullPackSize(folderIndex);
RINOK(WriteRange(inStream, archive.SeqStream,
db->GetFolderStreamPos(folderIndex, 0), packSize, progress));
lps->ProgressOffset += packSize;
-
- const CFolder &folder = db->Folders[folderIndex];
- CNum startIndex = db->FolderStartPackStreamIndex[folderIndex];
- for (int j = 0; j < folder.PackStreams.Size(); j++)
+
+ CFolder &folder = newDatabase.Folders.AddNew();
+ db->ParseFolderInfo(folderIndex, folder);
+ CNum startIndex = db->FoStartPackStreamIndex[folderIndex];
+ for (unsigned j = 0; j < folder.PackStreams.Size(); j++)
{
- newDatabase.PackSizes.Add(db->PackSizes[startIndex + j]);
+ newDatabase.PackSizes.Add(db->GetStreamPackSize(startIndex + j));
// newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]);
// newDatabase.PackCRCs.Add(db.PackCRCs[startIndex + j]);
}
- newDatabase.Folders.Add(folder);
+
+ UInt32 indexStart = db->FoToCoderUnpackSizes[folderIndex];
+ UInt32 indexEnd = db->FoToCoderUnpackSizes[folderIndex + 1];
+ for (; indexStart < indexEnd; indexStart++)
+ newDatabase.CoderUnpackSizes.Add(db->CoderUnpackSizes[indexStart]);
}
else
{
- CStreamBinder sb;
- RINOK(sb.CreateEvents());
- CMyComPtr<ISequentialOutStream> sbOutStream;
- CMyComPtr<ISequentialInStream> sbInStream;
- sb.CreateStreams(&sbInStream, &sbOutStream);
CBoolVector extractStatuses;
-
+
CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
CNum indexInFolder = 0;
-
+
for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
{
bool needExtract = false;
@@ -985,44 +1147,52 @@ HRESULT Update(
extractStatuses.Add(needExtract);
}
- RINOK(threadDecoder.FosSpec->Init(db, db->FolderStartFileIndex[folderIndex], &extractStatuses, sbOutStream));
- sbOutStream.Release();
-
- threadDecoder.InStream = inStream;
- threadDecoder.Folder = &db->Folders[folderIndex];
- threadDecoder.StartPos = db->GetFolderStreamPos(folderIndex, 0);
- threadDecoder.PackSizes = &db->PackSizes[db->FolderStartPackStreamIndex[folderIndex]];
-
- threadDecoder.Start();
-
- int startPackIndex = newDatabase.PackSizes.Size();
- CFolder newFolder;
- RINOK(encoder.Encode(
- EXTERNAL_CODECS_LOC_VARS
- sbInStream, NULL, &inSizeForReduce, newFolder,
- archive.SeqStream, newDatabase.PackSizes, progress));
-
- threadDecoder.WaitFinish();
+ unsigned startPackIndex = newDatabase.PackSizes.Size();
+ UInt64 curUnpackSize;
+ {
+ CMyComPtr<ISequentialInStream> sbInStream;
+ {
+ CMyComPtr<ISequentialOutStream> sbOutStream;
+ sb.CreateStreams(&sbInStream, &sbOutStream);
+ sb.ReInit();
+ RINOK(threadDecoder.FosSpec->Init(db, db->FolderStartFileIndex[folderIndex], &extractStatuses, sbOutStream));
+ }
+
+ threadDecoder.InStream = inStream;
+ threadDecoder.Folders = (const CFolders *)db;
+ threadDecoder.FolderIndex = folderIndex;
+ threadDecoder.StartPos = db->ArcInfo.DataStartPosition; // db->GetFolderStreamPos(folderIndex, 0);
+
+ threadDecoder.Start();
+
+ RINOK(encoder.Encode(
+ EXTERNAL_CODECS_LOC_VARS
+ sbInStream, NULL, &inSizeForReduce,
+ newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curUnpackSize,
+ archive.SeqStream, newDatabase.PackSizes, progress));
+
+ threadDecoder.WaitExecuteFinish();
+ }
RINOK(threadDecoder.Result);
for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
lps->OutSize += newDatabase.PackSizes[startPackIndex];
- lps->InSize += newFolder.GetUnpackSize();
-
- newDatabase.Folders.Add(newFolder);
+ lps->InSize += curUnpackSize;
}
-
+
newDatabase.NumUnpackStreamsVector.Add(rep.NumCopyFiles);
-
+
CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
-
+
CNum indexInFolder = 0;
for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
{
CFileItem file;
CFileItem2 file2;
- db->GetFile(fi, file, file2);
+ GetFile(*db, fi, file, file2);
+ UString name;
+ db->GetPath(fi, name);
if (file.HasStream)
{
indexInFolder++;
@@ -1041,30 +1211,40 @@ HRESULT Update(
uf.CrcDefined = file.CrcDefined;
uf.HasStream = file.HasStream;
file = uf;
+ name = ui.Name;
}
- newDatabase.AddFile(file, file2);
+ /*
+ file.Parent = ui.ParentFolderIndex;
+ if (ui.TreeFolderIndex >= 0)
+ treeFolderToArcIndex[ui.TreeFolderIndex] = newDatabase.Files.Size();
+ if (totalSecureDataSize != 0)
+ newDatabase.SecureIDs.Add(ui.SecureIndex);
+ */
+ newDatabase.AddFile(file, file2, name);
}
}
}
}
- int numFiles = group.Indices.Size();
+ unsigned numFiles = group.Indices.Size();
if (numFiles == 0)
continue;
CRecordVector<CRefItem> refItems;
- refItems.Reserve(numFiles);
+ refItems.ClearAndSetSize(numFiles);
bool sortByType = (numSolidFiles > 1);
for (i = 0; i < numFiles; i++)
- refItems.Add(CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType));
- refItems.Sort(CompareUpdateItems, (void *)&sortByType);
-
- CRecordVector<UInt32> indices;
- indices.Reserve(numFiles);
+ refItems[i] = CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType);
+ CSortParam sortParam;
+ // sortParam.TreeFolders = &treeFolders;
+ sortParam.SortByType = sortByType;
+ refItems.Sort(CompareUpdateItems, (void *)&sortParam);
+
+ CObjArray<UInt32> indices(numFiles);
for (i = 0; i < numFiles; i++)
{
UInt32 index = refItems[i].Index;
- indices.Add(index);
+ indices[i] = index;
/*
const CUpdateItem &ui = updateItems[index];
CFileItem file;
@@ -1077,7 +1257,7 @@ HRESULT Update(
newDatabase.Files.Add(file);
*/
}
-
+
for (i = 0; i < numFiles;)
{
UInt64 totalSize = 0;
@@ -1096,7 +1276,7 @@ HRESULT Update(
if (numSubFiles == 0)
prevExtension = ext;
else
- if (ext.CompareNoCase(prevExtension) != 0)
+ if (!ext.IsEqualToNoCase(prevExtension))
break;
}
}
@@ -1106,38 +1286,43 @@ HRESULT Update(
CFolderInStream *inStreamSpec = new CFolderInStream;
CMyComPtr<ISequentialInStream> solidInStream(inStreamSpec);
inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
-
- CFolder folderItem;
- int startPackIndex = newDatabase.PackSizes.Size();
+ unsigned startPackIndex = newDatabase.PackSizes.Size();
+ UInt64 curFolderUnpackSize;
RINOK(encoder.Encode(
EXTERNAL_CODECS_LOC_VARS
- solidInStream, NULL, &inSizeForReduce, folderItem,
+ solidInStream, NULL, &inSizeForReduce,
+ newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curFolderUnpackSize,
archive.SeqStream, newDatabase.PackSizes, progress));
for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
lps->OutSize += newDatabase.PackSizes[startPackIndex];
- lps->InSize += folderItem.GetUnpackSize();
+ lps->InSize += curFolderUnpackSize;
// for ()
// newDatabase.PackCRCsDefined.Add(false);
// newDatabase.PackCRCs.Add(0);
-
- newDatabase.Folders.Add(folderItem);
-
+
CNum numUnpackStreams = 0;
for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
{
const CUpdateItem &ui = updateItems[indices[i + subIndex]];
CFileItem file;
CFileItem2 file2;
+ UString name;
if (ui.NewProps)
+ {
FromUpdateItemToFileItem(ui, file, file2);
+ name = ui.Name;
+ }
else
- db->GetFile(ui.IndexInArchive, file, file2);
+ {
+ GetFile(*db, ui.IndexInArchive, file, file2);
+ db->GetPath(ui.IndexInArchive, name);
+ }
if (file2.IsAnti || file.IsDir)
return E_FAIL;
-
+
/*
CFileItem &file = newDatabase.Files[
startFileIndexInDatabase + i + subIndex];
@@ -1161,7 +1346,14 @@ HRESULT Update(
file.CrcDefined = false;
file.HasStream = false;
}
- newDatabase.AddFile(file, file2);
+ /*
+ file.Parent = ui.ParentFolderIndex;
+ if (ui.TreeFolderIndex >= 0)
+ treeFolderToArcIndex[ui.TreeFolderIndex] = newDatabase.Files.Size();
+ if (totalSecureDataSize != 0)
+ newDatabase.SecureIDs.Add(ui.SecureIndex);
+ */
+ newDatabase.AddFile(file, file2, name);
}
// numUnpackStreams = 0 is very bad case for locked files
// v3.13 doesn't understand it.
@@ -1173,42 +1365,36 @@ HRESULT Update(
if (folderRefIndex != folderRefs.Size())
return E_FAIL;
+ RINOK(lps->SetCur());
+
/*
folderRefs.ClearAndFree();
fileIndexToUpdateIndexMap.ClearAndFree();
groups.ClearAndFree();
*/
+ /*
+ for (i = 0; i < newDatabase.Files.Size(); i++)
{
- // ---------- Write Folders & Empty Files ----------
-
- CRecordVector<int> emptyRefs;
- for (i = 0; i < updateItems.Size(); i++)
- {
- const CUpdateItem &ui = updateItems[i];
- if (ui.NewData)
- {
- if (ui.HasStream())
- continue;
- }
- else if (ui.IndexInArchive != -1 && db->Files[ui.IndexInArchive].HasStream)
- continue;
- emptyRefs.Add(i);
- }
- emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
- for (i = 0; i < emptyRefs.Size(); i++)
+ CFileItem &file = newDatabase.Files[i];
+ file.Parent = treeFolderToArcIndex[file.Parent];
+ }
+
+ if (totalSecureDataSize != 0)
+ {
+ newDatabase.SecureBuf.SetCapacity(totalSecureDataSize);
+ size_t pos = 0;
+ newDatabase.SecureSizes.Reserve(secureBlocks.Sorted.Size());
+ for (i = 0; i < secureBlocks.Sorted.Size(); i++)
{
- const CUpdateItem &ui = updateItems[emptyRefs[i]];
- CFileItem file;
- CFileItem2 file2;
- if (ui.NewProps)
- FromUpdateItemToFileItem(ui, file, file2);
- else
- db->GetFile(ui.IndexInArchive, file, file2);
- newDatabase.AddFile(file, file2);
+ const CByteBuffer &buf = secureBlocks.Bufs[secureBlocks.Sorted[i]];
+ size_t size = buf.GetCapacity();
+ memcpy(newDatabase.SecureBuf + pos, buf, size);
+ newDatabase.SecureSizes.Add((UInt32)size);
+ pos += size;
}
}
-
+ */
newDatabase.ReserveDown();
return S_OK;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zUpdate.h b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zUpdate.h
index 31e362246..aee2d5ed3 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zUpdate.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zUpdate.h
@@ -3,29 +3,54 @@
#ifndef __7Z_UPDATE_H
#define __7Z_UPDATE_H
+#include "../IArchive.h"
+
+// #include "../../Common/UniqBlocks.h"
+
#include "7zCompressionMode.h"
#include "7zIn.h"
#include "7zOut.h"
-#include "../IArchive.h"
-
namespace NArchive {
namespace N7z {
+/*
+struct CTreeFolder
+{
+ UString Name;
+ int Parent;
+ CIntVector SubFolders;
+ int UpdateItemIndex;
+ int SortIndex;
+ int SortIndexEnd;
+
+ CTreeFolder(): UpdateItemIndex(-1) {}
+};
+*/
+
struct CUpdateItem
{
int IndexInArchive;
int IndexInClient;
-
+
UInt64 CTime;
UInt64 ATime;
UInt64 MTime;
UInt64 Size;
UString Name;
+ /*
+ bool IsAltStream;
+ int ParentFolderIndex;
+ int TreeFolderIndex;
+ */
+
+ // that code is not used in 9.26
+ // int ParentSortIndex;
+ // int ParentSortIndexEnd;
UInt32 Attrib;
-
+
bool NewData;
bool NewProps;
@@ -37,15 +62,20 @@ struct CUpdateItem
bool ATimeDefined;
bool MTimeDefined;
+ // int SecureIndex; // 0 means (no_security)
+
bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }
CUpdateItem():
+ // ParentSortIndex(-1),
+ // IsAltStream(false),
IsAnti(false),
IsDir(false),
AttribDefined(false),
CTimeDefined(false),
ATimeDefined(false),
MTimeDefined(false)
+ // SecureIndex(0)
{}
void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); };
@@ -72,10 +102,12 @@ struct CUpdateOptions
HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
- const CArchiveDatabaseEx *db,
+ const CDbEx *db,
const CObjectVector<CUpdateItem> &updateItems,
+ // const CObjectVector<CTreeFolder> &treeFolders, // treeFolders[0] is root
+ // const CUniqBlocks &secureBlocks,
COutArchive &archive,
- CArchiveDatabase &newDatabase,
+ CArchiveDatabaseOut &newDatabase,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Archive.pri b/src/libs/7zip/unix/CPP/7zip/Archive/Archive.pri
new file mode 100644
index 000000000..fe77cb0d4
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Archive.pri
@@ -0,0 +1,5 @@
+HEADERS += $$7ZIP_BASE/CPP/7zip/Archive/IArchive.h
+
+SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/LzmaHandler.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/SplitHandler.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/XzHandler.cpp
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/ArchiveExports.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/ArchiveExports.cpp
deleted file mode 100644
index c7908b591..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Archive/ArchiveExports.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-// ArchiveExports.cpp
-
-#include "StdAfx.h"
-
-#include "../../Common/ComTry.h"
-
-#include "../../Windows/PropVariant.h"
-
-#include "../Common/RegisterArc.h"
-
-static const unsigned int kNumArcsMax = 48;
-static unsigned int g_NumArcs = 0;
-static unsigned int g_DefaultArcIndex = 0;
-static const CArcInfo *g_Arcs[kNumArcsMax];
-void RegisterArc(const CArcInfo *arcInfo)
-{
- if (g_NumArcs < kNumArcsMax)
- {
- const wchar_t *p = arcInfo->Name;
- if (p[0] == '7' && p[1] == 'z' && p[2] == 0)
- g_DefaultArcIndex = g_NumArcs;
- g_Arcs[g_NumArcs++] = arcInfo;
- }
-}
-
-DEFINE_GUID(CLSID_CArchiveHandler,
-0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
-
-#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
-
-static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value)
-{
- if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
- value->vt = VT_BSTR;
- return S_OK;
-}
-
-static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
-{
- return SetPropString((const char *)&guid, sizeof(GUID), value);
-}
-
-int FindFormatCalssId(const GUID *clsID)
-{
- GUID cls = *clsID;
- CLS_ARC_ID_ITEM(cls) = 0;
- if (cls != CLSID_CArchiveHandler)
- return -1;
- Byte id = CLS_ARC_ID_ITEM(*clsID);
- for (unsigned i = 0; i < g_NumArcs; i++)
- if (g_Arcs[i]->ClassId == id)
- return (int)i;
- return -1;
-}
-
-STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
-{
- COM_TRY_BEGIN
- {
- int needIn = (*iid == IID_IInArchive);
- int needOut = (*iid == IID_IOutArchive);
- if (!needIn && !needOut)
- return E_NOINTERFACE;
- int formatIndex = FindFormatCalssId(clsid);
- if (formatIndex < 0)
- return CLASS_E_CLASSNOTAVAILABLE;
-
- const CArcInfo &arc = *g_Arcs[formatIndex];
- if (needIn)
- {
- *outObject = arc.CreateInArchive();
- ((IInArchive *)*outObject)->AddRef();
- }
- else
- {
- if (!arc.CreateOutArchive)
- return CLASS_E_CLASSNOTAVAILABLE;
- *outObject = arc.CreateOutArchive();
- ((IOutArchive *)*outObject)->AddRef();
- }
- }
- COM_TRY_END
- return S_OK;
-}
-
-STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
-{
- COM_TRY_BEGIN
- if (formatIndex >= g_NumArcs)
- return E_INVALIDARG;
- const CArcInfo &arc = *g_Arcs[formatIndex];
- NWindows::NCOM::CPropVariant prop;
- switch(propID)
- {
- case NArchive::kName:
- prop = arc.Name;
- break;
- case NArchive::kClassID:
- {
- GUID clsId = CLSID_CArchiveHandler;
- CLS_ARC_ID_ITEM(clsId) = arc.ClassId;
- return SetPropGUID(clsId, value);
- }
- case NArchive::kExtension:
- if (arc.Ext != 0)
- prop = arc.Ext;
- break;
- case NArchive::kAddExtension:
- if (arc.AddExt != 0)
- prop = arc.AddExt;
- break;
- case NArchive::kUpdate:
- prop = (bool)(arc.CreateOutArchive != 0);
- break;
- case NArchive::kKeepName:
- prop = arc.KeepName;
- break;
- case NArchive::kStartSignature:
- return SetPropString((const char *)arc.Signature, arc.SignatureSize, value);
- }
- prop.Detach(value);
- return S_OK;
- COM_TRY_END
-}
-
-STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
-{
- return GetHandlerProperty2(g_DefaultArcIndex, propID, value);
-}
-
-STDAPI GetNumberOfFormats(UINT32 *numFormats)
-{
- *numFormats = g_NumArcs;
- return S_OK;
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2.cpp
index 0b06a489f..e562fec58 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2.cpp
@@ -11,16 +11,23 @@ CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo):
{
srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams);
- UInt32 j;
+ UInt32 j;
+ _srcInToDestOutMap.ClearAndSetSize(NumSrcInStreams);
+ DestOutToSrcInMap.ClearAndSetSize(NumSrcInStreams);
+
for (j = 0; j < NumSrcInStreams; j++)
{
- _srcInToDestOutMap.Add(0);
- DestOutToSrcInMap.Add(0);
+ _srcInToDestOutMap[j] = 0;
+ DestOutToSrcInMap[j] = 0;
}
+
+ _srcOutToDestInMap.ClearAndSetSize(_numSrcOutStreams);
+ _destInToSrcOutMap.ClearAndSetSize(_numSrcOutStreams);
+
for (j = 0; j < _numSrcOutStreams; j++)
{
- _srcOutToDestInMap.Add(0);
- _destInToSrcOutMap.Add(0);
+ _srcOutToDestInMap[j] = 0;
+ _destInToSrcOutMap[j] = 0;
}
UInt32 destInOffset = 0;
@@ -34,7 +41,7 @@ CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo):
srcInOffset -= srcCoderInfo.NumInStreams;
srcOutOffset -= srcCoderInfo.NumOutStreams;
-
+
UInt32 j;
for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++)
{
@@ -53,66 +60,57 @@ CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo):
void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo)
{
- destBindInfo.Coders.Clear();
- destBindInfo.BindPairs.Clear();
- destBindInfo.InStreams.Clear();
- destBindInfo.OutStreams.Clear();
+ destBindInfo.Coders.ClearAndReserve(_srcBindInfo.Coders.Size());
+ destBindInfo.BindPairs.ClearAndReserve(_srcBindInfo.BindPairs.Size());
+ destBindInfo.InStreams.ClearAndReserve(_srcBindInfo.OutStreams.Size());
+ destBindInfo.OutStreams.ClearAndReserve(_srcBindInfo.InStreams.Size());
- int i;
- for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+ unsigned i;
+ for (i = _srcBindInfo.Coders.Size(); i != 0;)
{
+ i--;
const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i];
CCoderStreamsInfo destCoderInfo;
destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams;
destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams;
- destBindInfo.Coders.Add(destCoderInfo);
+ destBindInfo.Coders.AddInReserved(destCoderInfo);
}
- for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--)
+ for (i = _srcBindInfo.BindPairs.Size(); i != 0;)
{
+ i--;
const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i];
CBindPair destBindPair;
destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex];
destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex];
- destBindInfo.BindPairs.Add(destBindPair);
+ destBindInfo.BindPairs.AddInReserved(destBindPair);
}
for (i = 0; i < _srcBindInfo.InStreams.Size(); i++)
- destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]);
+ destBindInfo.OutStreams.AddInReserved(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]);
for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++)
- destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]);
-}
-
-CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
- NumInStreams(numInStreams),
- NumOutStreams(numOutStreams)
-{
- InSizes.Reserve(NumInStreams);
- InSizePointers.Reserve(NumInStreams);
- OutSizes.Reserve(NumOutStreams);
- OutSizePointers.Reserve(NumOutStreams);
+ destBindInfo.InStreams.AddInReserved(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]);
}
-static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
+void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
{
- sizes.Clear();
- sizePointers.Clear();
- for(UInt32 i = 0; i < numItems; i++)
+ sizes.ClearAndSetSize(numItems);
+ sizePointers.ClearAndSetSize(numItems);
+ for (UInt32 i = 0; i < numItems; i++)
{
- if (srcSizes == 0 || srcSizes[i] == NULL)
+ if (!srcSizes || !srcSizes[i])
{
- sizes.Add(0);
- sizePointers.Add(NULL);
+ sizes[i] = 0;
+ sizePointers[i] = NULL;
}
else
{
- sizes.Add(*srcSizes[i]);
- sizePointers.Add(&sizes.Back());
+ sizes[i] = *(srcSizes[i]);
+ sizePointers[i] = &sizes[i];
}
}
}
-void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes,
- const UInt64 **outSizes)
+void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)
{
SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2.h b/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2.h
index a03722d61..50e7077ae 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2.h
@@ -3,9 +3,9 @@
#ifndef __CODER_MIXER2_H
#define __CODER_MIXER2_H
-#include "../../../Common/MyVector.h"
-#include "../../../Common/Types.h"
#include "../../../Common/MyCom.h"
+#include "../../../Common/MyVector.h"
+
#include "../../ICoder.h"
namespace NCoderMixer {
@@ -52,7 +52,7 @@ struct CBindInfo
{
numInStreams = 0;
numOutStreams = 0;
- for (int i = 0; i < Coders.Size(); i++)
+ FOR_VECTOR (i, Coders)
{
const CCoderStreamsInfo &coderStreamsInfo = Coders[i];
numInStreams += coderStreamsInfo.NumInStreams;
@@ -62,14 +62,14 @@ struct CBindInfo
int FindBinderForInStream(UInt32 inStream) const
{
- for (int i = 0; i < BindPairs.Size(); i++)
+ FOR_VECTOR (i, BindPairs)
if (BindPairs[i].InIndex == inStream)
return i;
return -1;
}
int FindBinderForOutStream(UInt32 outStream) const
{
- for (int i = 0; i < BindPairs.Size(); i++)
+ FOR_VECTOR (i, BindPairs)
if (BindPairs[i].OutIndex == outStream)
return i;
return -1;
@@ -139,6 +139,9 @@ public:
void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo);
};
+void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
+ CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems);
+
struct CCoderInfo2
{
CMyComPtr<ICompressCoder> Coder;
@@ -151,7 +154,9 @@ struct CCoderInfo2
CRecordVector<const UInt64 *> InSizePointers;
CRecordVector<const UInt64 *> OutSizePointers;
- CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams);
+ CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
+ NumInStreams(numInStreams),
+ NumOutStreams(numOutStreams) {}
void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
HRESULT QueryInterface(REFGUID iid, void** pp) const
@@ -170,5 +175,5 @@ public:
};
}
-#endif
+#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
index d76450bd1..36b252600 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
@@ -9,30 +9,28 @@ namespace NCoderMixer {
CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams):
CCoderInfo2(numInStreams, numOutStreams)
{
- InStreams.Reserve(NumInStreams);
- InStreamPointers.Reserve(NumInStreams);
- OutStreams.Reserve(NumOutStreams);
- OutStreamPointers.Reserve(NumOutStreams);
+ InStreams.ClearAndReserve(NumInStreams);
+ OutStreams.ClearAndReserve(NumOutStreams);
}
void CCoder2::Execute() { Code(NULL); }
void CCoder2::Code(ICompressProgressInfo *progress)
{
- InStreamPointers.Clear();
- OutStreamPointers.Clear();
+ InStreamPointers.ClearAndReserve(NumInStreams);
+ OutStreamPointers.ClearAndReserve(NumOutStreams);
UInt32 i;
for (i = 0; i < NumInStreams; i++)
{
- if (InSizePointers[i] != NULL)
+ if (InSizePointers[i])
InSizePointers[i] = &InSizes[i];
- InStreamPointers.Add((ISequentialInStream *)InStreams[i]);
+ InStreamPointers.AddInReserved((ISequentialInStream *)InStreams[i]);
}
for (i = 0; i < NumOutStreams; i++)
{
- if (OutSizePointers[i] != NULL)
+ if (OutSizePointers[i])
OutSizePointers[i] = &OutSizes[i];
- OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]);
+ OutStreamPointers.AddInReserved((ISequentialOutStream *)OutStreams[i]);
}
if (Coder)
Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],
@@ -41,7 +39,7 @@ void CCoder2::Code(ICompressProgressInfo *progress)
Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams,
&OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress);
{
- int i;
+ unsigned i;
for (i = 0; i < InStreams.Size(); i++)
InStreams[i].Release();
for (i = 0; i < OutStreams.Size(); i++)
@@ -49,32 +47,13 @@ void CCoder2::Code(ICompressProgressInfo *progress)
}
}
-static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
- CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
-{
- sizes.Clear();
- sizePointers.Clear();
- for (UInt32 i = 0; i < numItems; i++)
- {
- if (srcSizes == 0 || srcSizes[i] == NULL)
- {
- sizes.Add(0);
- sizePointers.Add(NULL);
- }
- else
- {
- sizes.Add(*srcSizes[i]);
- sizePointers.Add(&sizes.Back());
- }
- }
-}
-
-
+/*
void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)
{
SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
}
+*/
//////////////////////////////////////
// CCoderMixer2MT
@@ -83,10 +62,9 @@ HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
{
_bindInfo = bindInfo;
_streamBinders.Clear();
- for (int i = 0; i < _bindInfo.BindPairs.Size(); i++)
+ FOR_VECTOR (i, _bindInfo.BindPairs)
{
- _streamBinders.Add(CStreamBinder());
- RINOK(_streamBinders.Back().CreateEvents());
+ RINOK(_streamBinders.AddNew().CreateEvents());
}
return S_OK;
}
@@ -113,7 +91,7 @@ void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
void CCoderMixer2MT::ReInit()
{
- for (int i = 0; i < _streamBinders.Size(); i++)
+ FOR_VECTOR (i, _streamBinders)
_streamBinders[i].ReInit();
}
@@ -124,7 +102,7 @@ HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStre
if (_coders.Size() != _bindInfo.Coders.Size())
throw 0;
*/
- int i;
+ unsigned i;
for (i = 0; i < _coders.Size(); i++)
{
CCoder2 &coderInfo = _coders[i];
@@ -167,7 +145,7 @@ HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStre
_bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
_coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
}
-
+
for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
{
UInt32 outCoderIndex, outCoderStreamIndex;
@@ -179,7 +157,7 @@ HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStre
HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)
{
- for (int i = 0; i < _coders.Size(); i++)
+ FOR_VECTOR (i, _coders)
if (_coders[i].Result == code)
return code;
return S_OK;
@@ -199,7 +177,7 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
Init(inStreams, outStreams);
- int i;
+ unsigned i;
for (i = 0; i < _coders.Size(); i++)
if (i != _progressCoderIndex)
{
@@ -214,7 +192,7 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
for (i = 0; i < _coders.Size(); i++)
if (i != _progressCoderIndex)
- _coders[i].WaitFinish();
+ _coders[i].WaitExecuteFinish();
RINOK(ReturnIfError(E_ABORT));
RINOK(ReturnIfError(E_OUTOFMEMORY));
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2MT.h b/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2MT.h
index d1c7f4d07..2190cf867 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2MT.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/CoderMixer2MT.h
@@ -12,14 +12,17 @@ namespace NCoderMixer {
struct CCoder2: public CCoderInfo2, public CVirtThread
{
+ CRecordVector<ISequentialInStream*> InStreamPointers;
+ CRecordVector<ISequentialOutStream*> OutStreamPointers;
+
+public:
HRESULT Result;
CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
- CRecordVector<ISequentialInStream*> InStreamPointers;
- CRecordVector<ISequentialOutStream*> OutStreamPointers;
CCoder2(UInt32 numInStreams, UInt32 numOutStreams);
- void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
+ ~CCoder2() { CVirtThread::WaitThreadFinish(); }
+ // void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
virtual void Execute();
void Code(ICompressProgressInfo *progress);
};
@@ -30,7 +33,7 @@ struct CCoder2: public CCoderInfo2, public CVirtThread
for each coder
AddCoder[2]()
SetProgressIndex(UInt32 coderIndex);
-
+
for each file
{
ReInit()
@@ -47,7 +50,7 @@ class CCoderMixer2MT:
{
CBindInfo _bindInfo;
CObjectVector<CStreamBinder> _streamBinders;
- int _progressCoderIndex;
+ unsigned _progressCoderIndex;
void AddCoderCommon();
HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams);
@@ -67,7 +70,7 @@ public:
HRESULT SetBindInfo(const CBindInfo &bindInfo);
void AddCoder(ICompressCoder *coder);
void AddCoder2(ICompressCoder2 *coder);
- void SetProgressCoderIndex(int coderIndex) { _progressCoderIndex = coderIndex; }
+ void SetProgressCoderIndex(unsigned coderIndex) { _progressCoderIndex = coderIndex; }
void ReInit();
void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/Common.pri b/src/libs/7zip/unix/CPP/7zip/Archive/Common/Common.pri
new file mode 100644
index 000000000..5443ba297
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/Common.pri
@@ -0,0 +1,18 @@
+HEADERS += $$7ZIP_BASE/CPP/7zip/Archive/Common/CoderMixer2.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/CoderMixer2MT.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/DummyOutStream.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/HandlerOut.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/InStreamWithCRC.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/ItemNameUtils.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/MultiStream.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/OutStreamWithCRC.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/ParseProperties.h
+
+SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/Common/CoderMixer2.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/CoderMixer2MT.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/DummyOutStream.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/HandlerOut.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/InStreamWithCRC.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/ItemNameUtils.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/MultiStream.cpp \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/CrossThreadProgress.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
deleted file mode 100644
index a974b54c7..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-// CrossThreadProgress.cpp
-
-#include "StdAfx.h"
-
-#include "CrossThreadProgress.h"
-
-STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
-{
- InSize = inSize;
- OutSize = outSize;
- ProgressEvent.Set();
- WaitEvent.Lock();
- return Result;
-}
-
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/CrossThreadProgress.h b/src/libs/7zip/unix/CPP/7zip/Archive/Common/CrossThreadProgress.h
deleted file mode 100644
index 7e0b10538..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/CrossThreadProgress.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// CrossThreadProgress.h
-
-#ifndef __CROSSTHREADPROGRESS_H
-#define __CROSSTHREADPROGRESS_H
-
-#include "../../ICoder.h"
-#include "../../../Windows/Synchronization.h"
-#include "../../../Common/MyCom.h"
-
-class CCrossThreadProgress:
- public ICompressProgressInfo,
- public CMyUnknownImp
-{
-public:
- const UInt64 *InSize;
- const UInt64 *OutSize;
- HRESULT Result;
- NWindows::NSynchronization::CAutoResetEvent ProgressEvent;
- NWindows::NSynchronization::CAutoResetEvent WaitEvent;
-
- HRes Create()
- {
- RINOK(ProgressEvent.CreateIfNotCreated());
- return WaitEvent.CreateIfNotCreated();
- }
- void Init()
- {
- ProgressEvent.Reset();
- WaitEvent.Reset();
- }
-
- MY_UNKNOWN_IMP
-
- STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
-};
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/DummyOutStream.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/Common/DummyOutStream.cpp
index 54bcfec11..7c4f54879 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/DummyOutStream.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/DummyOutStream.cpp
@@ -4,19 +4,14 @@
#include "DummyOutStream.h"
-STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- UInt32 realProcessedSize;
- HRESULT result;
- if(!_stream)
- {
- realProcessedSize = size;
- result = S_OK;
- }
- else
- result = _stream->Write(data, size, &realProcessedSize);
+ UInt32 realProcessedSize = size;
+ HRESULT res = S_OK;
+ if (_stream)
+ res = _stream->Write(data, size, &realProcessedSize);
_size += realProcessedSize;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
- return result;
+ return res;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/DummyOutStream.h b/src/libs/7zip/unix/CPP/7zip/Archive/Common/DummyOutStream.h
index 13d5b62ca..b5a51fc07 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/DummyOutStream.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/DummyOutStream.h
@@ -1,10 +1,11 @@
// DummyOutStream.h
-#ifndef __DUMMYOUTSTREAM_H
-#define __DUMMYOUTSTREAM_H
+#ifndef __DUMMY_OUT_STREAM_H
+#define __DUMMY_OUT_STREAM_H
+
+#include "../../../Common/MyCom.h"
#include "../../IStream.h"
-#include "Common/MyCom.h"
class CDummyOutStream:
public ISequentialOutStream,
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/HandlerOut.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/Common/HandlerOut.cpp
index 70ad47aad..7b875fbd0 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/HandlerOut.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/HandlerOut.cpp
@@ -2,16 +2,10 @@
#include "StdAfx.h"
-#include "../../../Common/StringToInt.h"
-
-#include "../../../Windows/PropVariant.h"
-
#ifndef _7ZIP_ST
#include "../../../Windows/System.h"
#endif
-#include "../../ICoder.h"
-
#include "../Common/ParseProperties.h"
#include "HandlerOut.h"
@@ -20,602 +14,126 @@ using namespace NWindows;
namespace NArchive {
-static const wchar_t *kCopyMethod = L"Copy";
-static const wchar_t *kLZMAMethodName = L"LZMA";
-static const wchar_t *kLZMA2MethodName = L"LZMA2";
-static const wchar_t *kBZip2MethodName = L"BZip2";
-static const wchar_t *kPpmdMethodName = L"PPMd";
-static const wchar_t *kDeflateMethodName = L"Deflate";
-static const wchar_t *kDeflate64MethodName = L"Deflate64";
-
-static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
-static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
-
-static const UInt32 kLzmaAlgoX1 = 0;
-static const UInt32 kLzmaAlgoX5 = 1;
-
-static const UInt32 kLzmaDicSizeX1 = 1 << 16;
-static const UInt32 kLzmaDicSizeX3 = 1 << 20;
-static const UInt32 kLzmaDicSizeX5 = 1 << 24;
-static const UInt32 kLzmaDicSizeX7 = 1 << 25;
-static const UInt32 kLzmaDicSizeX9 = 1 << 26;
-
-static const UInt32 kLzmaFastBytesX1 = 32;
-static const UInt32 kLzmaFastBytesX7 = 64;
-
-static const UInt32 kPpmdMemSizeX1 = (1 << 22);
-static const UInt32 kPpmdMemSizeX5 = (1 << 24);
-static const UInt32 kPpmdMemSizeX7 = (1 << 26);
-static const UInt32 kPpmdMemSizeX9 = (192 << 20);
-
-static const UInt32 kPpmdOrderX1 = 4;
-static const UInt32 kPpmdOrderX5 = 6;
-static const UInt32 kPpmdOrderX7 = 16;
-static const UInt32 kPpmdOrderX9 = 32;
-
-static const UInt32 kDeflateAlgoX1 = 0;
-static const UInt32 kDeflateAlgoX5 = 1;
-
-static const UInt32 kDeflateFastBytesX1 = 32;
-static const UInt32 kDeflateFastBytesX7 = 64;
-static const UInt32 kDeflateFastBytesX9 = 128;
-
-static const UInt32 kDeflatePassesX1 = 1;
-static const UInt32 kDeflatePassesX7 = 3;
-static const UInt32 kDeflatePassesX9 = 10;
-
-static const UInt32 kBZip2NumPassesX1 = 1;
-static const UInt32 kBZip2NumPassesX7 = 2;
-static const UInt32 kBZip2NumPassesX9 = 7;
-
-static const UInt32 kBZip2DicSizeX1 = 100000;
-static const UInt32 kBZip2DicSizeX3 = 500000;
-static const UInt32 kBZip2DicSizeX5 = 900000;
-
-static const wchar_t *kDefaultMethodName = kLZMAMethodName;
-
-static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
-static const UInt32 kDictionaryForHeaders = 1 << 20;
-static const UInt32 kNumFastBytesForHeaders = 273;
-static const UInt32 kAlgorithmForHeaders = kLzmaAlgoX5;
-
-static bool AreEqual(const UString &methodName, const wchar_t *s)
- { return (methodName.CompareNoCase(s) == 0); }
-
-bool COneMethodInfo::IsLzma() const
-{
- return
- AreEqual(MethodName, kLZMAMethodName) ||
- AreEqual(MethodName, kLZMA2MethodName);
-}
-
-static inline bool IsBZip2Method(const UString &methodName)
- { return AreEqual(methodName, kBZip2MethodName); }
-
-static inline bool IsPpmdMethod(const UString &methodName)
- { return AreEqual(methodName, kPpmdMethodName); }
-
-static inline bool IsDeflateMethod(const UString &methodName)
-{
- return
- AreEqual(methodName, kDeflateMethodName) ||
- AreEqual(methodName, kDeflate64MethodName);
-}
-
-struct CNameToPropID
-{
- PROPID PropID;
- VARTYPE VarType;
- const wchar_t *Name;
-};
-
-static CNameToPropID g_NameToPropID[] =
-{
- { NCoderPropID::kBlockSize, VT_UI4, L"C" },
- { NCoderPropID::kDictionarySize, VT_UI4, L"D" },
- { NCoderPropID::kUsedMemorySize, VT_UI4, L"MEM" },
-
- { NCoderPropID::kOrder, VT_UI4, L"O" },
- { NCoderPropID::kPosStateBits, VT_UI4, L"PB" },
- { NCoderPropID::kLitContextBits, VT_UI4, L"LC" },
- { NCoderPropID::kLitPosBits, VT_UI4, L"LP" },
- { NCoderPropID::kEndMarker, VT_BOOL, L"eos" },
-
- { NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
- { NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
- { NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },
- { NCoderPropID::kAlgorithm, VT_UI4, L"a" },
- { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
- { NCoderPropID::kNumThreads, VT_UI4, L"mt" },
- { NCoderPropID::kDefaultProp, VT_UI4, L"" }
-};
-
-static bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, NCOM::CPropVariant &destProp)
-{
- if (varType == srcProp.vt)
- {
- destProp = srcProp;
- return true;
- }
- if (varType == VT_UI1)
- {
- if (srcProp.vt == VT_UI4)
- {
- UInt32 value = srcProp.ulVal;
- if (value > 0xFF)
- return false;
- destProp = (Byte)value;
- return true;
- }
- }
- else if (varType == VT_BOOL)
- {
- bool res;
- if (SetBoolProperty(res, srcProp) != S_OK)
- return false;
- destProp = res;
- return true;
- }
- return false;
-}
-
-static int FindPropIdExact(const UString &name)
+static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
{
- for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
- if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)
- return i;
- return -1;
+ if (m.FindProp(propID) < 0)
+ m.AddProp32(propID, value);
}
-static int FindPropIdStart(const UString &name)
-{
- for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
- {
- UString t = g_NameToPropID[i].Name;
- if (t.CompareNoCase(name.Left(t.Length())) == 0)
- return i;
- }
- return -1;
-}
-
-static void SetMethodProp(COneMethodInfo &m, PROPID propID, const NCOM::CPropVariant &value)
-{
- for (int j = 0; j < m.Props.Size(); j++)
- if (m.Props[j].Id == propID)
- return;
- CProp prop;
- prop.Id = propID;
- prop.Value = value;
- m.Props.Add(prop);
-}
-
-void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo
+void CMultiMethodProps::SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
)
{
UInt32 level = _level;
- if (oneMethodInfo.MethodName.IsEmpty())
- oneMethodInfo.MethodName = kDefaultMethodName;
-
- if (oneMethodInfo.IsLzma())
- {
- UInt32 dicSize =
- (level >= 9 ? kLzmaDicSizeX9 :
- (level >= 7 ? kLzmaDicSizeX7 :
- (level >= 5 ? kLzmaDicSizeX5 :
- (level >= 3 ? kLzmaDicSizeX3 :
- kLzmaDicSizeX1))));
-
- UInt32 algo =
- (level >= 5 ? kLzmaAlgoX5 :
- kLzmaAlgoX1);
-
- UInt32 fastBytes =
- (level >= 7 ? kLzmaFastBytesX7 :
- kLzmaFastBytesX1);
-
- const wchar_t *matchFinder =
- (level >= 5 ? kLzmaMatchFinderX5 :
- kLzmaMatchFinderX1);
-
- SetMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
- SetMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
- SetMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
- SetMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
- #ifndef _7ZIP_ST
- SetMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
- #endif
- }
- else if (IsDeflateMethod(oneMethodInfo.MethodName))
- {
- UInt32 fastBytes =
- (level >= 9 ? kDeflateFastBytesX9 :
- (level >= 7 ? kDeflateFastBytesX7 :
- kDeflateFastBytesX1));
-
- UInt32 numPasses =
- (level >= 9 ? kDeflatePassesX9 :
- (level >= 7 ? kDeflatePassesX7 :
- kDeflatePassesX1));
-
- UInt32 algo =
- (level >= 5 ? kDeflateAlgoX5 :
- kDeflateAlgoX1);
-
- SetMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
- SetMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
- SetMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
- }
- else if (IsBZip2Method(oneMethodInfo.MethodName))
- {
- UInt32 numPasses =
- (level >= 9 ? kBZip2NumPassesX9 :
- (level >= 7 ? kBZip2NumPassesX7 :
- kBZip2NumPassesX1));
-
- UInt32 dicSize =
- (level >= 5 ? kBZip2DicSizeX5 :
- (level >= 3 ? kBZip2DicSizeX3 :
- kBZip2DicSizeX1));
-
- SetMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
- SetMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
- #ifndef _7ZIP_ST
- SetMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
- #endif
- }
- else if (IsPpmdMethod(oneMethodInfo.MethodName))
- {
- UInt32 useMemSize =
- (level >= 9 ? kPpmdMemSizeX9 :
- (level >= 7 ? kPpmdMemSizeX7 :
- (level >= 5 ? kPpmdMemSizeX5 :
- kPpmdMemSizeX1)));
-
- UInt32 order =
- (level >= 9 ? kPpmdOrderX9 :
- (level >= 7 ? kPpmdOrderX7 :
- (level >= 5 ? kPpmdOrderX5 :
- kPpmdOrderX1)));
-
- SetMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
- SetMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
- }
-}
-
-static void SplitParams(const UString &srcString, UStringVector &subStrings)
-{
- subStrings.Clear();
- UString name;
- int len = srcString.Length();
- if (len == 0)
- return;
- for (int i = 0; i < len; i++)
- {
- wchar_t c = srcString[i];
- if (c == L':')
- {
- subStrings.Add(name);
- name.Empty();
- }
- else
- name += c;
- }
- subStrings.Add(name);
-}
-
-static void SplitParam(const UString &param, UString &name, UString &value)
-{
- int eqPos = param.Find(L'=');
- if (eqPos >= 0)
- {
- name = param.Left(eqPos);
- value = param.Mid(eqPos + 1);
- return;
- }
- for(int i = 0; i < param.Length(); i++)
- {
- wchar_t c = param[i];
- if (c >= L'0' && c <= L'9')
- {
- name = param.Left(i);
- value = param.Mid(i);
- return;
- }
- }
- name = param;
-}
-
-HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value)
-{
- CProp prop;
- int index = FindPropIdExact(name);
- if (index < 0)
- return E_INVALIDARG;
- const CNameToPropID &nameToPropID = g_NameToPropID[index];
- prop.Id = nameToPropID.PropID;
-
- if (prop.Id == NCoderPropID::kBlockSize ||
- prop.Id == NCoderPropID::kDictionarySize ||
- prop.Id == NCoderPropID::kUsedMemorySize)
- {
- UInt32 dicSize;
- RINOK(ParsePropDictionaryValue(value, dicSize));
- prop.Value = dicSize;
- }
- else
- {
- NCOM::CPropVariant propValue;
-
- if (nameToPropID.VarType == VT_BSTR)
- propValue = value;
- else if (nameToPropID.VarType == VT_BOOL)
- {
- bool res;
- if (!StringToBool(value, res))
- return E_INVALIDARG;
- propValue = res;
- }
- else
- {
- UInt32 number;
- if (ParseStringToUInt32(value, number) == value.Length())
- propValue = number;
- else
- propValue = value;
- }
-
- if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value))
- return E_INVALIDARG;
- }
- oneMethodInfo.Props.Add(prop);
- return S_OK;
-}
-
-HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString)
-{
- UStringVector params;
- SplitParams(srcString, params);
- if (params.Size() > 0)
- oneMethodInfo.MethodName = params[0];
- for (int i = 1; i < params.Size(); i++)
- {
- const UString &param = params[i];
- UString name, value;
- SplitParam(param, name, value);
- RINOK(SetParam(oneMethodInfo, name, value));
- }
- return S_OK;
-}
-
-HRESULT COutHandler::SetSolidSettings(const UString &s)
-{
- UString s2 = s;
- s2.MakeUpper();
- for (int i = 0; i < s2.Length();)
- {
- const wchar_t *start = ((const wchar_t *)s2) + i;
- const wchar_t *end;
- UInt64 v = ConvertStringToUInt64(start, &end);
- if (start == end)
- {
- if (s2[i++] != 'E')
- return E_INVALIDARG;
- _solidExtension = true;
- continue;
- }
- i += (int)(end - start);
- if (i == s2.Length())
- return E_INVALIDARG;
- wchar_t c = s2[i++];
- switch(c)
- {
- case 'F':
- if (v < 1)
- v = 1;
- _numSolidFiles = v;
- break;
- case 'B':
- _numSolidBytes = v;
- _numSolidBytesDefined = true;
- break;
- case 'K':
- _numSolidBytes = (v << 10);
- _numSolidBytesDefined = true;
- break;
- case 'M':
- _numSolidBytes = (v << 20);
- _numSolidBytesDefined = true;
- break;
- case 'G':
- _numSolidBytes = (v << 30);
- _numSolidBytesDefined = true;
- break;
- default:
- return E_INVALIDARG;
- }
- }
- return S_OK;
-}
-
-HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value)
-{
- bool isSolid;
- switch(value.vt)
- {
- case VT_EMPTY:
- isSolid = true;
- break;
- case VT_BOOL:
- isSolid = (value.boolVal != VARIANT_FALSE);
- break;
- case VT_BSTR:
- if (StringToBool(value.bstrVal, isSolid))
- break;
- return SetSolidSettings(value.bstrVal);
- default:
- return E_INVALIDARG;
- }
- if (isSolid)
- InitSolid();
- else
- _numSolidFiles = 1;
- return S_OK;
-}
-
-void COutHandler::Init()
-{
- _removeSfxBlock = false;
- _compressHeaders = true;
- _encryptHeadersSpecified = false;
- _encryptHeaders = false;
-
- WriteCTime = false;
- WriteATime = false;
- WriteMTime = true;
-
+ if (level != (UInt32)(Int32)-1)
+ SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
#ifndef _7ZIP_ST
- _numThreads = NSystem::GetNumberOfProcessors();
+ SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
#endif
-
- _level = 5;
- _autoFilter = true;
- _volumeMode = false;
- _crcSize = 4;
- InitSolid();
}
-void COutHandler::BeforeSetProperty()
+void CMultiMethodProps::Init()
{
- Init();
#ifndef _7ZIP_ST
- numProcessors = NSystem::GetNumberOfProcessors();
+ _numProcessors = _numThreads = NSystem::GetNumberOfProcessors();
#endif
- mainDicSize = 0xFFFFFFFF;
- mainDicMethodIndex = 0xFFFFFFFF;
- minNumber = 0;
+ _level = (UInt32)(Int32)-1;
+ _autoFilter = true;
_crcSize = 4;
+ _filterMethod.Clear();
+ _methods.Clear();
}
-HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
+HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
UString name = nameSpec;
- name.MakeUpper();
+ name.MakeLower_Ascii();
if (name.IsEmpty())
return E_INVALIDARG;
-
- if (name[0] == 'X')
+
+ if (name[0] == 'x')
{
name.Delete(0);
_level = 9;
- return ParsePropValue(name, value, _level);
+ return ParsePropToUInt32(name, value, _level);
}
-
- if (name[0] == L'S')
- {
- name.Delete(0);
- if (name.IsEmpty())
- return SetSolidSettings(value);
- if (value.vt != VT_EMPTY)
- return E_INVALIDARG;
- return SetSolidSettings(name);
- }
-
- if (name == L"CRC")
+
+ if (name == L"crc")
{
- _crcSize = 4;
name.Delete(0, 3);
- return ParsePropValue(name, value, _crcSize);
+ _crcSize = 4;
+ return ParsePropToUInt32(name, value, _crcSize);
}
-
+
UInt32 number;
int index = ParseStringToUInt32(name, number);
- UString realName = name.Mid(index);
+ UString realName = name.Ptr(index);
if (index == 0)
{
- if(name.Left(2).CompareNoCase(L"MT") == 0)
+ if (name.IsPrefixedBy(L"mt"))
{
#ifndef _7ZIP_ST
- RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
+ RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads));
#endif
return S_OK;
}
- if (name.CompareNoCase(L"RSFX") == 0) return SetBoolProperty(_removeSfxBlock, value);
- if (name.CompareNoCase(L"F") == 0) return SetBoolProperty(_autoFilter, value);
- if (name.CompareNoCase(L"HC") == 0) return SetBoolProperty(_compressHeaders, value);
- if (name.CompareNoCase(L"HCF") == 0)
+ if (name.IsEqualTo("f"))
{
- bool compressHeadersFull = true;
- RINOK(SetBoolProperty(compressHeadersFull, value));
- if (!compressHeadersFull)
+ HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
+ if (res == S_OK)
+ return res;
+ if (value.vt != VT_BSTR)
return E_INVALIDARG;
- return S_OK;
- }
- if (name.CompareNoCase(L"HE") == 0)
- {
- RINOK(SetBoolProperty(_encryptHeaders, value));
- _encryptHeadersSpecified = true;
- return S_OK;
+ return _filterMethod.ParseMethodFromPROPVARIANT(L"", value);
}
- if (name.CompareNoCase(L"TC") == 0) return SetBoolProperty(WriteCTime, value);
- if (name.CompareNoCase(L"TA") == 0) return SetBoolProperty(WriteATime, value);
- if (name.CompareNoCase(L"TM") == 0) return SetBoolProperty(WriteMTime, value);
- if (name.CompareNoCase(L"V") == 0) return SetBoolProperty(_volumeMode, value);
number = 0;
}
- if (number > 10000)
+ if (number > 64)
return E_FAIL;
- if (number < minNumber)
- return E_INVALIDARG;
- number -= minNumber;
- for(int j = _methods.Size(); j <= (int)number; j++)
- {
- COneMethodInfo oneMethodInfo;
- _methods.Add(oneMethodInfo);
- }
-
- COneMethodInfo &oneMethodInfo = _methods[number];
-
- if (realName.Length() == 0)
- {
- if (value.vt != VT_BSTR)
- return E_INVALIDARG;
-
- RINOK(SetParams(oneMethodInfo, value.bstrVal));
- }
- else
+ for (int j = _methods.Size(); j <= (int)number; j++)
+ _methods.Add(COneMethodInfo());
+ return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
+}
+
+void CSingleMethodProps::Init()
+{
+ Clear();
+ #ifndef _7ZIP_ST
+ _numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+ AddNumThreadsProp(_numThreads);
+ #endif
+ _level = (UInt32)(Int32)-1;
+}
+
+HRESULT CSingleMethodProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps)
+{
+ Init();
+ for (UInt32 i = 0; i < numProps; i++)
{
- int index = FindPropIdStart(realName);
- if (index < 0)
+ UString name = names[i];
+ name.MakeLower_Ascii();
+ if (name.IsEmpty())
return E_INVALIDARG;
- const CNameToPropID &nameToPropID = g_NameToPropID[index];
- CProp prop;
- prop.Id = nameToPropID.PropID;
-
- if (prop.Id == NCoderPropID::kBlockSize ||
- prop.Id == NCoderPropID::kDictionarySize ||
- prop.Id == NCoderPropID::kUsedMemorySize)
+ const PROPVARIANT &value = values[i];
+ if (name[0] == L'x')
{
- UInt32 dicSize;
- RINOK(ParsePropDictionaryValue(realName.Mid(MyStringLen(nameToPropID.Name)), value, dicSize));
- prop.Value = dicSize;
- if (number <= mainDicMethodIndex)
- mainDicSize = dicSize;
+ UInt32 a = 9;
+ RINOK(ParsePropToUInt32(name.Ptr(1), value, a));
+ _level = a;
+ AddLevelProp(a);
}
- else
+ else if (name.IsPrefixedBy(L"mt"))
{
- int index = FindPropIdExact(realName);
- if (index < 0)
- return E_INVALIDARG;
- const CNameToPropID &nameToPropID = g_NameToPropID[index];
- prop.Id = nameToPropID.PropID;
- if (!ConvertProperty(value, nameToPropID.VarType, prop.Value))
- return E_INVALIDARG;
+ #ifndef _7ZIP_ST
+ RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads));
+ AddNumThreadsProp(_numThreads);
+ #endif
}
- oneMethodInfo.Props.Add(prop);
+ else
+ return ParseMethodFromPROPVARIANT(names[i], value);
}
return S_OK;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/HandlerOut.h b/src/libs/7zip/unix/CPP/7zip/Archive/Common/HandlerOut.h
index 72ea40321..eba2a19e1 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/HandlerOut.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/HandlerOut.h
@@ -3,83 +3,61 @@
#ifndef __HANDLER_OUT_H
#define __HANDLER_OUT_H
-#include "../../../Common/MyString.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
-struct COneMethodInfo
-{
- CObjectVector<CProp> Props;
- UString MethodName;
-
- bool IsLzma() const;
-};
-
-class COutHandler
+class CMultiMethodProps
{
+ UInt32 _level;
public:
- HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
-
- HRESULT SetSolidSettings(const UString &s);
- HRESULT SetSolidSettings(const PROPVARIANT &value);
-
#ifndef _7ZIP_ST
UInt32 _numThreads;
+ UInt32 _numProcessors;
#endif
UInt32 _crcSize;
-
CObjectVector<COneMethodInfo> _methods;
- bool _removeSfxBlock;
-
- UInt64 _numSolidFiles;
- UInt64 _numSolidBytes;
- bool _numSolidBytesDefined;
- bool _solidExtension;
-
- bool _compressHeaders;
- bool _encryptHeadersSpecified;
- bool _encryptHeaders;
-
- bool WriteCTime;
- bool WriteATime;
- bool WriteMTime;
-
+ COneMethodInfo _filterMethod;
bool _autoFilter;
- UInt32 _level;
-
- bool _volumeMode;
- HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
- HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
-
- void SetCompressionMethod2(COneMethodInfo &oneMethodInfo
+ void SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
);
- void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
- void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
- void InitSolid()
+ unsigned GetNumEmptyMethods() const
{
- InitSolidFiles();
- InitSolidSize();
- _solidExtension = false;
- _numSolidBytesDefined = false;
+ unsigned i;
+ for (i = 0; i < _methods.Size(); i++)
+ if (!_methods[i].IsEmpty())
+ break;
+ return i;
}
+ int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; }
+
void Init();
- COutHandler() { Init(); }
+ CMultiMethodProps() { Init(); }
+ HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
+};
+
+class CSingleMethodProps: public COneMethodInfo
+{
+ UInt32 _level;
- void BeforeSetProperty();
+public:
+ #ifndef _7ZIP_ST
+ UInt32 _numThreads;
+ UInt32 _numProcessors;
+ #endif
- UInt32 minNumber;
- UInt32 numProcessors;
- UInt32 mainDicSize;
- UInt32 mainDicMethodIndex;
+ void Init();
+ CSingleMethodProps() { Init(); }
+ int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; }
+ HRESULT SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps);
};
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/InStreamWithCRC.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
index 569a56f3b..a2d688328 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
@@ -6,29 +6,33 @@
STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- UInt32 realProcessedSize;
- HRESULT result = _stream->Read(data, size, &realProcessedSize);
- _size += realProcessedSize;
- if (size > 0 && realProcessedSize == 0)
+ UInt32 realProcessed = 0;
+ HRESULT result = S_OK;
+ if (_stream)
+ result = _stream->Read(data, size, &realProcessed);
+ _size += realProcessed;
+ if (size != 0 && realProcessed == 0)
_wasFinished = true;
- _crc = CrcUpdate(_crc, data, realProcessedSize);
- if(processedSize != NULL)
- *processedSize = realProcessedSize;
+ _crc = CrcUpdate(_crc, data, realProcessed);
+ if (processedSize)
+ *processedSize = realProcessed;
return result;
}
STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- UInt32 realProcessedSize;
- HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ UInt32 realProcessed = 0;
+ HRESULT result = S_OK;
+ if (_stream)
+ result = _stream->Read(data, size, &realProcessed);
+ _size += realProcessed;
/*
- if (size > 0 && realProcessedSize == 0)
+ if (size != 0 && realProcessed == 0)
_wasFinished = true;
*/
- _size += realProcessedSize;
- _crc = CrcUpdate(_crc, data, realProcessedSize);
- if(processedSize != NULL)
- *processedSize = realProcessedSize;
+ _crc = CrcUpdate(_crc, data, realProcessed);
+ if (processedSize)
+ *processedSize = realProcessed;
return result;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/Common/ItemNameUtils.cpp
index a5e0dc0be..7cd3037be 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/ItemNameUtils.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/ItemNameUtils.cpp
@@ -2,8 +2,6 @@
#include "StdAfx.h"
-#include "../../../../C/Types.h"
-
#include "ItemNameUtils.h"
namespace NArchive {
@@ -12,6 +10,21 @@ namespace NItemName {
static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR;
static const wchar_t kDirDelimiter = L'/';
+void ReplaceToOsPathSeparator(wchar_t *s)
+{
+ #ifdef _WIN32
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c == 0)
+ break;
+ if (c == kDirDelimiter)
+ *s = kOSDirDelimiter;
+ s++;
+ }
+ #endif
+}
+
UString MakeLegalName(const UString &name)
{
UString zipName = name;
@@ -31,20 +44,34 @@ UString GetOSName2(const UString &name)
if (name.IsEmpty())
return UString();
UString newName = GetOSName(name);
- if (newName[newName.Length() - 1] == kOSDirDelimiter)
- newName.Delete(newName.Length() - 1);
+ if (newName.Back() == kOSDirDelimiter)
+ newName.DeleteBack();
return newName;
}
-bool HasTailSlash(const AString &name, UINT codePage)
+void ConvertToOSName2(UString &name)
+{
+ if (!name.IsEmpty())
+ {
+ name.Replace(kDirDelimiter, kOSDirDelimiter);
+ if (name.Back() == kOSDirDelimiter)
+ name.DeleteBack();
+ }
+}
+
+bool HasTailSlash(const AString &name, UINT
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ codePage
+ #endif
+ )
{
if (name.IsEmpty())
return false;
LPCSTR prev =
#if defined(_WIN32) && !defined(UNDER_CE)
- CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);
+ CharPrevExA((WORD)codePage, name, &name[name.Len()], 0);
#else
- (LPCSTR)(name) + (name.Length() - 1);
+ (LPCSTR)(name) + (name.Len() - 1);
#endif
return (*prev == '/');
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/ItemNameUtils.h b/src/libs/7zip/unix/CPP/7zip/Archive/Common/ItemNameUtils.h
index 5eafacb12..d0dc76a41 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/ItemNameUtils.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/ItemNameUtils.h
@@ -1,16 +1,19 @@
// Archive/Common/ItemNameUtils.h
-#ifndef __ARCHIVE_ITEMNAMEUTILS_H
-#define __ARCHIVE_ITEMNAMEUTILS_H
+#ifndef __ARCHIVE_ITEM_NAME_UTILS_H
+#define __ARCHIVE_ITEM_NAME_UTILS_H
#include "../../../Common/MyString.h"
namespace NArchive {
namespace NItemName {
+ void ReplaceToOsPathSeparator(wchar_t *s);
+
UString MakeLegalName(const UString &name);
UString GetOSName(const UString &name);
UString GetOSName2(const UString &name);
+ void ConvertToOSName2(UString &name);
bool HasTailSlash(const AString &name, UINT codePage);
#ifdef _WIN32
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/MultiStream.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/Common/MultiStream.cpp
index 04d11cafb..17f749058 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/MultiStream.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/MultiStream.cpp
@@ -11,10 +11,10 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
if (size == 0)
return S_OK;
if (_pos >= _totalLength)
- return (_pos == _totalLength) ? S_OK : E_FAIL;
+ return S_OK;
{
- int left = 0, mid = _streamIndex, right = Streams.Size();
+ unsigned left = 0, mid = _streamIndex, right = Streams.Size();
for (;;)
{
CSubStreamInfo &m = Streams[mid];
@@ -31,7 +31,7 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
}
_streamIndex = mid;
}
-
+
CSubStreamInfo &s = Streams[_streamIndex];
UInt64 localPos = _pos - s.GlobalOffset;
if (localPos != s.LocalPos)
@@ -48,18 +48,21 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
*processedSize = size;
return result;
}
-
+
STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET: _pos = offset; break;
- case STREAM_SEEK_CUR: _pos = _pos + offset; break;
- case STREAM_SEEK_END: _pos = _totalLength + offset; break;
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _pos; break;
+ case STREAM_SEEK_END: offset += _totalLength; break;
default: return STG_E_INVALIDFUNCTION;
}
- if (newPosition != 0)
- *newPosition = _pos;
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _pos = offset;
+ if (newPosition)
+ *newPosition = offset;
return S_OK;
}
@@ -69,7 +72,7 @@ class COutVolumeStream:
public ISequentialOutStream,
public CMyUnknownImp
{
- int _volIndex;
+ unsigned _volIndex;
UInt64 _volSize;
UInt64 _curPos;
CMyComPtr<ISequentialOutStream> _volumeStream;
@@ -88,12 +91,12 @@ public:
_file.Name = name;
_file.IsStartPosDefined = true;
_file.StartPos = 0;
-
+
VolumeCallback = volumeCallback;
_volIndex = 0;
_volSize = 0;
}
-
+
HRESULT Flush();
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
@@ -116,9 +119,9 @@ HRESULT COutVolumeStream::Flush()
/*
STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if(processedSize != NULL)
+ if (processedSize != NULL)
*processedSize = 0;
- while(size > 0)
+ while (size > 0)
{
if (_streamIndex >= Streams.Size())
{
@@ -154,7 +157,7 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce
_absPos += realProcessed;
if (_absPos > _length)
_length = _absPos;
- if(processedSize != NULL)
+ if (processedSize != NULL)
*processedSize += realProcessed;
if (subStream.Pos == subStream.Size)
{
@@ -169,22 +172,20 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce
STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- if(seekOrigin >= 3)
- return STG_E_INVALIDFUNCTION;
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET:
- _absPos = offset;
- break;
- case STREAM_SEEK_CUR:
- _absPos += offset;
- break;
- case STREAM_SEEK_END:
- _absPos = _length + offset;
- break;
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _absPos; break;
+ case STREAM_SEEK_END: offset += _length; break;
+ default: return STG_E_INVALIDFUNCTION;
}
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _absPos = offset;
_offsetPos = _absPos;
_streamIndex = 0;
+ if (newPosition)
+ *newPosition = offset;
return S_OK;
}
*/
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/MultiStream.h b/src/libs/7zip/unix/CPP/7zip/Archive/Common/MultiStream.h
index 3fceb7cce..93aff33bf 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/MultiStream.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/MultiStream.h
@@ -14,21 +14,26 @@ class CMultiStream:
{
UInt64 _pos;
UInt64 _totalLength;
- int _streamIndex;
+ unsigned _streamIndex;
+
public:
+
struct CSubStreamInfo
{
CMyComPtr<IInStream> Stream;
UInt64 Size;
UInt64 GlobalOffset;
UInt64 LocalPos;
+
+ CSubStreamInfo(): Size(0), GlobalOffset(0), LocalPos(0) {}
};
+
CObjectVector<CSubStreamInfo> Streams;
-
+
HRESULT Init()
{
UInt64 total = 0;
- for (int i = 0; i < Streams.Size(); i++)
+ FOR_VECTOR (i, Streams)
{
CSubStreamInfo &s = Streams[i];
s.GlobalOffset = total;
@@ -52,7 +57,7 @@ class COutMultiStream:
public IOutStream,
public CMyUnknownImp
{
- int _streamIndex; // required stream
+ unsigned _streamIndex; // required stream
UInt64 _offsetPos; // offset from start of _streamIndex index
UInt64 _absPos;
UInt64 _length;
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/OutStreamWithCRC.h b/src/libs/7zip/unix/CPP/7zip/Archive/Common/OutStreamWithCRC.h
index 115b442aa..09b899bbd 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/OutStreamWithCRC.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/OutStreamWithCRC.h
@@ -28,6 +28,7 @@ public:
_calculate = calculate;
_crc = CRC_INIT_VAL;
}
+ void EnableCalc(bool calculate) { _calculate = calculate; }
void InitCRC() { _crc = CRC_INIT_VAL; }
UInt64 GetSize() const { return _size; }
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/ParseProperties.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/Common/ParseProperties.cpp
deleted file mode 100644
index 5cd849e29..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/ParseProperties.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-// ParseProperties.cpp
-
-#include "StdAfx.h"
-
-#include "ParseProperties.h"
-
-#include "Common/StringToInt.h"
-#include "Common/MyCom.h"
-
-HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
-{
- if (prop.vt == VT_UI4)
- {
- if (!name.IsEmpty())
- return E_INVALIDARG;
- resValue = prop.ulVal;
- }
- else if (prop.vt == VT_EMPTY)
- {
- if(!name.IsEmpty())
- {
- const wchar_t *start = name;
- const wchar_t *end;
- UInt64 v = ConvertStringToUInt64(start, &end);
- if (end - start != name.Length())
- return E_INVALIDARG;
- resValue = (UInt32)v;
- }
- }
- else
- return E_INVALIDARG;
- return S_OK;
-}
-
-static const int kLogarithmicSizeLimit = 32;
-static const wchar_t kByteSymbol = L'B';
-static const wchar_t kKiloByteSymbol = L'K';
-static const wchar_t kMegaByteSymbol = L'M';
-
-HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)
-{
- UString srcString = srcStringSpec;
- srcString.MakeUpper();
-
- const wchar_t *start = srcString;
- const wchar_t *end;
- UInt64 number = ConvertStringToUInt64(start, &end);
- int numDigits = (int)(end - start);
- if (numDigits == 0 || srcString.Length() > numDigits + 1)
- return E_INVALIDARG;
- if (srcString.Length() == numDigits)
- {
- if (number >= kLogarithmicSizeLimit)
- return E_INVALIDARG;
- dicSize = (UInt32)1 << (int)number;
- return S_OK;
- }
- switch (srcString[numDigits])
- {
- case kByteSymbol:
- if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
- return E_INVALIDARG;
- dicSize = (UInt32)number;
- break;
- case kKiloByteSymbol:
- if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
- return E_INVALIDARG;
- dicSize = (UInt32)(number << 10);
- break;
- case kMegaByteSymbol:
- if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
- return E_INVALIDARG;
- dicSize = (UInt32)(number << 20);
- break;
- default:
- return E_INVALIDARG;
- }
- return S_OK;
-}
-
-HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
-{
- if (name.IsEmpty())
- {
- if (prop.vt == VT_UI4)
- {
- UInt32 logDicSize = prop.ulVal;
- if (logDicSize >= 32)
- return E_INVALIDARG;
- resValue = (UInt32)1 << logDicSize;
- return S_OK;
- }
- if (prop.vt == VT_BSTR)
- return ParsePropDictionaryValue(prop.bstrVal, resValue);
- return E_INVALIDARG;
- }
- return ParsePropDictionaryValue(name, resValue);
-}
-
-bool StringToBool(const UString &s, bool &res)
-{
- if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0)
- {
- res = true;
- return true;
- }
- if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0)
- {
- res = false;
- return true;
- }
- return false;
-}
-
-HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
-{
- switch(value.vt)
- {
- case VT_EMPTY:
- dest = true;
- return S_OK;
- case VT_BOOL:
- dest = (value.boolVal != VARIANT_FALSE);
- return S_OK;
- /*
- case VT_UI4:
- dest = (value.ulVal != 0);
- break;
- */
- case VT_BSTR:
- return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG;
- }
- return E_INVALIDARG;
-}
-
-int ParseStringToUInt32(const UString &srcString, UInt32 &number)
-{
- const wchar_t *start = srcString;
- const wchar_t *end;
- UInt64 number64 = ConvertStringToUInt64(start, &end);
- if (number64 > 0xFFFFFFFF)
- {
- number = 0;
- return 0;
- }
- number = (UInt32)number64;
- return (int)(end - start);
-}
-
-HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
-{
- if (name.IsEmpty())
- {
- switch(prop.vt)
- {
- case VT_UI4:
- numThreads = prop.ulVal;
- break;
- default:
- {
- bool val;
- RINOK(SetBoolProperty(val, prop));
- numThreads = (val ? defaultNumThreads : 1);
- break;
- }
- }
- }
- else
- {
- UInt32 number;
- int index = ParseStringToUInt32(name, number);
- if (index != name.Length())
- return E_INVALIDARG;
- numThreads = number;
- }
- return S_OK;
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/Common/ParseProperties.h b/src/libs/7zip/unix/CPP/7zip/Archive/Common/ParseProperties.h
index 6f80f6344..1038a8c02 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/Common/ParseProperties.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/Common/ParseProperties.h
@@ -1,18 +1,6 @@
// ParseProperties.h
-#ifndef __PARSEPROPERTIES_H
-#define __PARSEPROPERTIES_H
-
-#include "Common/MyString.h"
-#include "Common/Types.h"
-
-HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
-HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize);
-HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
-
-bool StringToBool(const UString &s, bool &res);
-HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value);
-int ParseStringToUInt32(const UString &srcString, UInt32 &number);
-HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
+#ifndef __PARSE_PROPERTIES_H
+#define __PARSE_PROPERTIES_H
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/DllExports2.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/DllExports2.cpp
deleted file mode 100644
index 1febea714..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Archive/DllExports2.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-// DLLExports.cpp
-
-#include "StdAfx.h"
-
-#include "../../Common/MyInitGuid.h"
-
-#if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
-#include "../../../C/Alloc.h"
-#endif
-
-#include "../../Common/ComTry.h"
-
-#include "../../Windows/NtCheck.h"
-#include "../../Windows/PropVariant.h"
-
-#include "../ICoder.h"
-#include "../IPassword.h"
-
-#include "IArchive.h"
-
-HINSTANCE g_hInstance;
-
-#define NT_CHECK_FAIL_ACTION return FALSE;
-
-#ifdef _WIN32
-extern "C"
-BOOL WINAPI DllMain(
- #ifdef UNDER_CE
- HANDLE
- #else
- HINSTANCE
- #endif
- hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
-{
- if (dwReason == DLL_PROCESS_ATTACH)
- {
- g_hInstance = (HINSTANCE)hInstance;
- NT_CHECK;
- }
- return TRUE;
-}
-#endif
-
-DEFINE_GUID(CLSID_CArchiveHandler,
-0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
-
-static const UInt16 kDecodeId = 0x2790;
-
-DEFINE_GUID(CLSID_CCodec,
-0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
-
-STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject);
-STDAPI CreateArchiver(const GUID *classID, const GUID *iid, void **outObject);
-
-STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
-{
- // COM_TRY_BEGIN
- *outObject = 0;
- if (*iid == IID_ICompressCoder || *iid == IID_ICompressCoder2 || *iid == IID_ICompressFilter)
- {
- return CreateCoder(clsid, iid, outObject);
- }
- else
- {
- return CreateArchiver(clsid, iid, outObject);
- }
- // COM_TRY_END
-}
-
-STDAPI SetLargePageMode()
-{
- #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
- SetLargePageSize();
- #endif
- return S_OK;
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/IArchive.h b/src/libs/7zip/unix/CPP/7zip/Archive/IArchive.h
index 853202767..038e05ed2 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/IArchive.h
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/IArchive.h
@@ -20,20 +20,43 @@ namespace NFileTimeType
};
}
+namespace NArcInfoFlags
+{
+ const UInt32 kKeepName = 1 << 0; // keep name of file in archive name
+ const UInt32 kAltStreams = 1 << 1; // the handler supports alt streams
+ const UInt32 kNtSecure = 1 << 2; // the handler supports NT security
+ const UInt32 kFindSignature = 1 << 3; // the handler can find start of archive
+ const UInt32 kMultiSignature = 1 << 4; // there are several signatures
+ const UInt32 kUseGlobalOffset = 1 << 5; // the seek position of stream must be set as global offset
+ const UInt32 kStartOpen = 1 << 6; // call handler for each start position
+ const UInt32 kPureStartOpen = 1 << 7; // call handler only for start of file
+ const UInt32 kBackwardOpen = 1 << 8; // archive can be open backward
+ const UInt32 kPreArc = 1 << 9; // such archive can be stored before real archive (like SFX stub)
+ const UInt32 kSymLinks = 1 << 10; // the handler supports symbolic links
+ const UInt32 kHardLinks = 1 << 11; // the handler supports hard links
+}
+
namespace NArchive
{
- enum
+ namespace NHandlerPropID
{
- kName = 0,
- kClassID,
- kExtension,
- kAddExtension,
- kUpdate,
- kKeepName,
- kStartSignature,
- kFinishSignature,
- kAssociate
- };
+ enum
+ {
+ kName = 0, // VT_BSTR
+ kClassID, // binary GUID in VT_BSTR
+ kExtension, // VT_BSTR
+ kAddExtension, // VT_BSTR
+ kUpdate, // VT_BOOL
+ kKeepName, // VT_BOOL
+ kSignature, // binary in VT_BSTR
+ kMultiSignature, // binary in VT_BSTR
+ kSignatureOffset, // VT_UI4
+ kAltStreams, // VT_BOOL
+ kNtSecure, // VT_BOOL
+ kFlags // VT_UI4
+ // kVersion // VT_UI4 ((VER_MAJOR << 8) | VER_MINOR)
+ };
+ }
namespace NExtract
{
@@ -46,25 +69,32 @@ namespace NArchive
kSkip
};
}
+
namespace NOperationResult
{
enum
{
kOK = 0,
- kUnSupportedMethod,
+ kUnsupportedMethod,
kDataError,
- kCRCError
+ kCRCError,
+ kUnavailable,
+ kUnexpectedEnd,
+ kDataAfterEnd,
+ kIsNotArc,
+ kHeadersError
};
}
}
+
namespace NUpdate
{
namespace NOperationResult
{
enum
{
- kOK = 0,
- kError
+ kOK = 0
+ , // kError
};
}
}
@@ -79,10 +109,16 @@ ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)
INTERFACE_IArchiveOpenCallback(PURE);
};
+/*
+IArchiveExtractCallback::GetStream
+ Result:
+ (*inStream == NULL) - for directories
+ (*inStream == NULL) - if link (hard link or symbolic link) was created
+*/
#define INTERFACE_IArchiveExtractCallback(x) \
INTERFACE_IProgress(x) \
- STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \
+ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \
STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \
STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) x; \
@@ -115,41 +151,184 @@ ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50)
/*
+IInArchive::Open
+ stream
+ if (kUseGlobalOffset), stream current position can be non 0.
+ if (!kUseGlobalOffset), stream current position is 0.
+ if (maxCheckStartPosition == NULL), the handler can try to search archive start in stream
+ if (*maxCheckStartPosition == 0), the handler must check only current position as archive start
+
IInArchive::Extract:
indices must be sorted
- numItems = 0xFFFFFFFF means "all files"
+ numItems = (UInt32)(Int32)-1 = 0xFFFFFFFF means "all files"
testMode != 0 means "test files without writing to outStream"
+
+IInArchive::GetArchiveProperty:
+ kpidOffset - start offset of archive.
+ VT_EMPTY : means offset = 0.
+ VT_UI4, VT_UI8, VT_I8 : result offset; negative values is allowed
+ kpidPhySize - size of archive. VT_EMPTY means unknown size.
+ kpidPhySize is allowed to be larger than file size. In that case it must show
+ supposed size.
+
+ kpidIsDeleted:
+ kpidIsAltStream:
+ kpidIsAux:
+ kpidINode:
+ must return VARIANT_TRUE (VT_BOOL), if archive can support that property in GetProperty.
+
+
+Notes:
+ Don't call IInArchive functions for same IInArchive object from different threads simultaneously.
+ Some IInArchive handlers will work incorrectly in that case.
*/
+/* MSVC allows the code where there is throw() in declaration of function,
+ but there is no throw() in definition of function. */
+
+#ifdef _MSC_VER
+ #define MY_NO_THROW_DECL_ONLY throw()
+#else
+ #define MY_NO_THROW_DECL_ONLY
+#endif
+
#define INTERFACE_IInArchive(x) \
- STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \
- STDMETHOD(Close)() x; \
- STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \
- STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
- STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \
- STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \
- STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \
- STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \
- STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \
- STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x;
+ STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
+ STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x;
ARCHIVE_INTERFACE(IInArchive, 0x60)
{
INTERFACE_IInArchive(PURE)
};
+namespace NParentType
+{
+ enum
+ {
+ kDir = 0,
+ kAltStream
+ };
+};
+
+namespace NPropDataType
+{
+ const UInt32 kMask_ZeroEnd = 1 << 4;
+ // const UInt32 kMask_BigEndian = 1 << 5;
+ const UInt32 kMask_Utf = 1 << 6;
+ // const UInt32 kMask_Utf8 = kMask_Utf | 0;
+ const UInt32 kMask_Utf16 = kMask_Utf | 1;
+ // const UInt32 kMask_Utf32 = kMask_Utf | 2;
+
+ const UInt32 kNotDefined = 0;
+ const UInt32 kRaw = 1;
+ const UInt32 kUtf16z = kMask_Utf16 | kMask_ZeroEnd;
+};
+
+// UTF string (pointer to wchar_t) with zero end and little-endian.
+#define PROP_DATA_TYPE_wchar_t_PTR_Z_LE ((NPropDataType::kMask_Utf | NPropDataType::kMask_ZeroEnd) + (sizeof(wchar_t) >> 1))
+
+/*
+GetRawProp:
+ Result:
+ S_OK - even if property is not set
+*/
+
+#define INTERFACE_IArchiveGetRawProps(x) \
+ STDMETHOD(GetParent)(UInt32 index, UInt32 *parent, UInt32 *parentType) x; \
+ STDMETHOD(GetRawProp)(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \
+ STDMETHOD(GetNumRawProps)(UInt32 *numProps) x; \
+ STDMETHOD(GetRawPropInfo)(UInt32 index, BSTR *name, PROPID *propID) x;
+
+ARCHIVE_INTERFACE(IArchiveGetRawProps, 0x70)
+{
+ INTERFACE_IArchiveGetRawProps(PURE)
+};
+
+#define INTERFACE_IArchiveGetRootProps(x) \
+ STDMETHOD(GetRootProp)(PROPID propID, PROPVARIANT *value) x; \
+ STDMETHOD(GetRootRawProp)(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \
+
+ARCHIVE_INTERFACE(IArchiveGetRootProps, 0x71)
+{
+ INTERFACE_IArchiveGetRootProps(PURE)
+};
+
ARCHIVE_INTERFACE(IArchiveOpenSeq, 0x61)
{
STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE;
};
+/*
+ OpenForSize
+ Result:
+ S_FALSE - is not archive
+ ? - DATA error
+*/
+
+/*
+const UInt32 kOpenFlags_RealPhySize = 1 << 0;
+const UInt32 kOpenFlags_NoSeek = 1 << 1;
+// const UInt32 kOpenFlags_BeforeExtract = 1 << 2;
+*/
+
+/*
+Flags:
+ 0 - opens archive with IInStream, if IInStream interface is supported
+ - if phySize is not available, it doesn't try to make full parse to get phySize
+ kOpenFlags_NoSeek - ArcOpen2 function doesn't use IInStream interface, even if it's available
+ kOpenFlags_RealPhySize - the handler will try to get PhySize, even if it requires full decompression for file
+
+ if handler is not allowed to use IInStream and the flag kOpenFlags_RealPhySize is not specified,
+ the handler can return S_OK, but it doesn't check even Signature.
+ So next Extract can be called for that sequential stream.
+*/
+
+/*
+ARCHIVE_INTERFACE(IArchiveOpen2, 0x62)
+{
+ STDMETHOD(ArcOpen2)(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback) PURE;
+};
+*/
+
+// ---------- UPDATE ----------
+
+/*
+GetUpdateItemInfo outs:
+*newData *newProps
+ 0 0 - Copy data and properties from archive
+ 0 1 - Copy data from archive, request new properties
+ 1 0 - that combination is unused now
+ 1 1 - Request new data and new properties. It can be used even for folders
+
+ indexInArchive = -1 if there is no item in archive, or if it doesn't matter.
+
+
+GetStream out:
+ Result:
+ S_OK:
+ (*inStream == NULL) - only for directories
+ - the bug was fixed in 9.33: (*Stream == NULL) was in case of anti-file
+ (*inStream != NULL) - for any file, even for empty file or anti-file
+ S_FALSE - skip that file (don't add item to archive) - (client code can't open stream of that file by some reason)
+ (*inStream == NULL)
+
+The order of calling for hard links:
+ - GetStream()
+ - GetProperty(kpidHardLink)
+
+*/
+
#define INTERFACE_IArchiveUpdateCallback(x) \
INTERFACE_IProgress(x); \
- STDMETHOD(GetUpdateItemInfo)(UInt32 index, \
- Int32 *newData, /*1 - new data, 0 - old data */ \
- Int32 *newProperties, /* 1 - new properties, 0 - old properties */ \
- UInt32 *indexInArchive /* -1 if there is no in archive, or if doesn't matter */ \
- ) x; \
+ STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive) x; \
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \
STDMETHOD(SetOperationResult)(Int32 operationResult) x; \
@@ -169,6 +348,27 @@ ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
INTERFACE_IArchiveUpdateCallback2(PURE);
};
+/*
+UpdateItems()
+-------------
+
+ outStream: output stream. (the handler) MUST support the case when
+ Seek position in outStream is not ZERO.
+ but the caller calls with empty outStream and seek position is ZERO??
+
+ archives with stub:
+
+ If archive is open and the handler and (Offset > 0), then the handler
+ knows about stub size.
+ UpdateItems():
+ 1) the handler MUST copy that stub to outStream
+ 2) the caller MUST NOT copy the stub to outStream, if
+ "rsfx" property is set with SetProperties
+
+ the handler must support the case where
+ ISequentialOutStream *outStream
+*/
+
#define INTERFACE_IOutArchive(x) \
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \
@@ -182,47 +382,61 @@ ARCHIVE_INTERFACE(IOutArchive, 0xA0)
ARCHIVE_INTERFACE(ISetProperties, 0x03)
{
- STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE;
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps) PURE;
+};
+
+ARCHIVE_INTERFACE(IArchiveKeepModeForNextOpen, 0x04)
+{
+ STDMETHOD(KeepModeForNextOpen)() PURE;
+};
+
+/* Exe handler: the handler for executable format (PE, ELF, Mach-O).
+ SFX archive: executable stub + some tail data.
+ before 9.31: exe handler didn't parse SFX archives as executable format.
+ for 9.31+: exe handler parses SFX archives as executable format, only if AllowTail(1) was called */
+
+ARCHIVE_INTERFACE(IArchiveAllowTail, 0x05)
+{
+ STDMETHOD(AllowTail)(Int32 allowTail) PURE;
};
#define IMP_IInArchive_GetProp(k) \
(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
- { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
- const STATPROPSTG &srcItem = k[index]; \
- *propID = srcItem.propid; *varType = srcItem.vt; *name = 0; return S_OK; } \
+ { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \
+ *propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; *name = 0; return S_OK; } \
#define IMP_IInArchive_GetProp_WITH_NAME(k) \
(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
- { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
+ { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \
const STATPROPSTG &srcItem = k[index]; \
*propID = srcItem.propid; *varType = srcItem.vt; \
if (srcItem.lpwstrName == 0) *name = 0; else *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } \
#define IMP_IInArchive_Props \
- STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
- { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
+ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \
+ { *numProps = ARRAY_SIZE(kProps); return S_OK; } \
STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps)
#define IMP_IInArchive_Props_WITH_NAME \
- STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
- { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
+ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \
+ { *numProps = ARRAY_SIZE(kProps); return S_OK; } \
STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps)
#define IMP_IInArchive_ArcProps \
- STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
- { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
+ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
+ { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \
STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps)
#define IMP_IInArchive_ArcProps_WITH_NAME \
- STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
- { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
+ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
+ { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \
STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps)
#define IMP_IInArchive_ArcProps_NO_Table \
- STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
- { *numProperties = 0; return S_OK; } \
+ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
+ { *numProps = 0; return S_OK; } \
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \
{ return E_NOTIMPL; } \
@@ -231,4 +445,21 @@ ARCHIVE_INTERFACE(ISetProperties, 0x03)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \
{ value->vt = VT_EMPTY; return S_OK; }
+
+
+#define k_IsArc_Res_NO 0
+#define k_IsArc_Res_YES 1
+#define k_IsArc_Res_NEED_MORE 2
+// #define k_IsArc_Res_YES_LOW_PROB 3
+
+#define API_FUNC_IsArc EXTERN_C UInt32 WINAPI
+#define API_FUNC_static_IsArc extern "C" { static UInt32 WINAPI
+
+extern "C"
+{
+ typedef UInt32 (*Func_IsArc)(const Byte *p, size_t size);
+ typedef IOutArchive * (*Func_CreateOutArchive)();
+ typedef IInArchive * (*Func_CreateInArchive)();
+}
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/LzmaHandler.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/LzmaHandler.cpp
index a83e6a1ad..279cdefb7 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/LzmaHandler.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/LzmaHandler.cpp
@@ -4,10 +4,10 @@
#include "../../../C/CpuArch.h"
-#include "Common/ComTry.h"
-#include "Common/IntToString.h"
+#include "../../Common/ComTry.h"
+#include "../../Common/IntToString.h"
-#include "Windows/PropVariant.h"
+#include "../../Windows/PropVariant.h"
#include "../Common/CreateCoder.h"
#include "../Common/ProgressUtils.h"
@@ -26,17 +26,24 @@ namespace NLzma {
static bool CheckDicSize(const Byte *p)
{
UInt32 dicSize = GetUi32(p);
- for (int i = 1; i <= 30; i++)
+ if (dicSize == 1)
+ return true;
+ for (unsigned i = 0; i <= 30; i++)
if (dicSize == ((UInt32)2 << i) || dicSize == ((UInt32)3 << i))
return true;
return (dicSize == 0xFFFFFFFF);
}
-STATPROPSTG kProps[] =
+static const Byte kProps[] =
{
- { NULL, kpidSize, VT_UI8},
- { NULL, kpidPackSize, VT_UI8},
- { NULL, kpidMethod, VT_BSTR}
+ kpidSize,
+ kpidPackSize,
+ kpidMethod
+};
+
+static const Byte kArcProps[] =
+{
+ kpidNumStreams
};
struct CHeader
@@ -62,16 +69,17 @@ bool CHeader::Parse(const Byte *buf, bool isThereFilter)
return
LzmaProps[0] < 5 * 5 * 9 &&
FilterID < 2 &&
- (!HasSize() || Size < ((UInt64)1 << 56)) &&
- CheckDicSize(LzmaProps + 1);
+ (!HasSize() || Size < ((UInt64)1 << 56))
+ && CheckDicSize(LzmaProps + 1);
}
class CDecoder
{
- NCompress::NLzma::CDecoder *_lzmaDecoderSpec;
CMyComPtr<ICompressCoder> _lzmaDecoder;
CMyComPtr<ISequentialOutStream> _bcjStream;
public:
+ NCompress::NLzma::CDecoder *_lzmaDecoderSpec;
+
~CDecoder();
HRESULT Create(DECL_EXTERNAL_CODECS_LOC_VARS
bool filtered, ISequentialInStream *inStream);
@@ -86,8 +94,8 @@ public:
{ return _lzmaDecoderSpec->ReadFromInputStream(data, size, processedSize); }
};
-static const UInt64 k_BCJ = 0x03030103;
-
+static const UInt32 k_BCJ = 0x03030103;
+
HRESULT CDecoder::Create(
DECL_EXTERNAL_CODECS_LOC_VARS
bool filteredMode, ISequentialInStream *inStream)
@@ -95,6 +103,7 @@ HRESULT CDecoder::Create(
if (!_lzmaDecoder)
{
_lzmaDecoderSpec = new NCompress::NLzma::CDecoder;
+ _lzmaDecoderSpec->FinishStream = true;
_lzmaDecoder = _lzmaDecoderSpec;
}
@@ -166,6 +175,10 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,
}
RINOK(res);
+ if (header.HasSize())
+ if (_lzmaDecoderSpec->GetOutputProcessedSize() != header.Size)
+ return S_FALSE;
+
return S_OK;
}
@@ -178,12 +191,25 @@ class CHandler:
{
CHeader _header;
bool _lzma86;
- UInt64 _startPosition;
- UInt64 _packSize;
- bool _packSizeDefined;
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
+ bool _isArc;
+ bool _needSeekToStart;
+ bool _dataAfterEnd;
+ bool _needMoreInput;
+
+ bool _packSize_Defined;
+ bool _unpackSize_Defined;
+ bool _numStreams_Defined;
+
+ bool _unsupported;
+ bool _dataError;
+
+ UInt64 _packSize;
+ UInt64 _unpackSize;
+ UInt64 _numStreams;
+
DECL_EXTERNAL_CODECS_VARS
DECL_ISetCompressCodecsInfo
@@ -204,14 +230,26 @@ public:
};
IMP_IInArchive_Props
-IMP_IInArchive_ArcProps_NO_Table
+IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
- switch(propID)
+ switch (propID)
{
- case kpidPhySize: if (_packSizeDefined) prop = _packSize; break;
+ case kpidPhySize: if (_packSize_Defined) prop = _packSize; break;
+ case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break;
+ case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break;
+ case kpidErrorFlags:
+ {
+ UInt32 v = 0;
+ if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;;
+ if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd;
+ if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
+ if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
+ if (_dataError) v |= kpv_ErrorFlags_DataError;
+ prop = v;
+ }
}
prop.Detach(value);
return S_OK;
@@ -226,50 +264,37 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
static void DictSizeToString(UInt32 value, char *s)
{
for (int i = 0; i <= 31; i++)
- if ((UInt32(1) << i) == value)
+ if (((UInt32)1 << i) == value)
{
::ConvertUInt32ToString(i, s);
return;
}
char c = 'b';
- if ((value & ((1 << 20) - 1)) == 0)
- {
- value >>= 20;
- c = 'm';
- }
- else if ((value & ((1 << 10) - 1)) == 0)
- {
- value >>= 10;
- c = 'k';
- }
+ if ((value & ((1 << 20) - 1)) == 0) { value >>= 20; c = 'm'; }
+ else if ((value & ((1 << 10) - 1)) == 0) { value >>= 10; c = 'k'; }
::ConvertUInt32ToString(value, s);
- int p = MyStringLen(s);
- s[p++] = c;
- s[p++] = '\0';
-}
-
-static void MyStrCat(char *d, const char *s)
-{
- MyStringCopy(d + MyStringLen(d), s);
+ s += MyStringLen(s);
+ *s++ = c;
+ *s = 0;
}
-STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
+STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
- switch(propID)
+ switch (propID)
{
case kpidSize: if (_stream && _header.HasSize()) prop = _header.Size; break;
- case kpidPackSize: if (_packSizeDefined) prop = _packSize; break;
+ case kpidPackSize: if (_packSize_Defined) prop = _packSize; break;
case kpidMethod:
if (_stream)
{
- char s[64];
- s[0] = '\0';
+ char sz[64];
+ char *s = sz;
if (_header.FilterID != 0)
- MyStrCat(s, "BCJ ");
- MyStrCat(s, "LZMA:");
- DictSizeToString(_header.GetDicSize(), s + MyStringLen(s));
- prop = s;
+ s = MyStpCpy(s, "BCJ ");
+ s = MyStpCpy(s, "LZMA:");
+ DictSizeToString(_header.GetDicSize(), s);
+ prop = sz;
}
break;
}
@@ -277,46 +302,126 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA
return S_OK;
}
+API_FUNC_static_IsArc IsArc_Lzma(const Byte *p, size_t size)
+{
+ const UInt32 kHeaderSize = 1 + 4 + 8;
+ if (size < kHeaderSize)
+ return k_IsArc_Res_NEED_MORE;
+ if (p[0] >= 5 * 5 * 9)
+ return k_IsArc_Res_NO;
+ UInt64 unpackSize = GetUi64(p + 1 + 4);
+ if (unpackSize != (UInt64)(Int64)-1)
+ {
+ if (size >= ((UInt64)1 << 56))
+ return k_IsArc_Res_NO;
+ }
+ if (unpackSize != 0)
+ {
+ if (size < kHeaderSize + 2)
+ return k_IsArc_Res_NEED_MORE;
+ if (p[kHeaderSize] != 0)
+ return k_IsArc_Res_NO;
+ if (unpackSize != (UInt64)(Int64)-1)
+ {
+ if ((p[kHeaderSize + 1] & 0x80) != 0)
+ return k_IsArc_Res_NO;
+ }
+ }
+ if (!CheckDicSize(p + 1))
+ // return k_IsArc_Res_YES_LOW_PROB;
+ return k_IsArc_Res_NO;
+ return k_IsArc_Res_YES;
+}
+}
+
+API_FUNC_static_IsArc IsArc_Lzma86(const Byte *p, size_t size)
+{
+ if (size < 1)
+ return k_IsArc_Res_NEED_MORE;
+ Byte filterID = p[0];
+ if (filterID != 0 && filterID != 1)
+ return k_IsArc_Res_NO;
+ return IsArc_Lzma(p + 1, size - 1);
+}
+}
+
STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)
{
- RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &_startPosition));
-
- const UInt32 kBufSize = 1 + 5 + 8 + 1;
+ Close();
+
+ const UInt32 kBufSize = 1 + 5 + 8 + 2;
Byte buf[kBufSize];
-
+
RINOK(ReadStream_FALSE(inStream, buf, kBufSize));
-
+
if (!_header.Parse(buf, _lzma86))
return S_FALSE;
const Byte *start = buf + GetHeaderSize();
- if (start[0] != 0)
+ if (start[0] != 0 /* || (start[1] & 0x80) != 0 */ ) // empty stream with EOS is not 0x80
+ return S_FALSE;
+
+ RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize));
+ if (_packSize >= 24 && _header.Size == 0 && _header.FilterID == 0 && _header.LzmaProps[0] == 0)
return S_FALSE;
-
- UInt64 endPos;
- RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos));
- _packSize = endPos - _startPosition;
- _packSizeDefined = true;
-
+ _isArc = true;
_stream = inStream;
_seqStream = inStream;
+ _needSeekToStart = true;
return S_OK;
}
STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
{
Close();
+ _isArc = true;
_seqStream = stream;
return S_OK;
}
STDMETHODIMP CHandler::Close()
{
- _packSizeDefined = false;
+ _isArc = false;
+ _packSize_Defined = false;
+ _unpackSize_Defined = false;
+ _numStreams_Defined = false;
+
+ _dataAfterEnd = false;
+ _needMoreInput = false;
+ _unsupported = false;
+ _dataError = false;
+
+ _packSize = 0;
+
+ _needSeekToStart = false;
+
_stream.Release();
_seqStream.Release();
return S_OK;
}
+class CCompressProgressInfoImp:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ CMyComPtr<IArchiveOpenCallback> Callback;
+public:
+ UInt64 Offset;
+
+ MY_UNKNOWN_IMP1(ICompressProgressInfo)
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+ void Init(IArchiveOpenCallback *callback) { Callback = callback; }
+};
+
+STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)
+{
+ if (Callback)
+ {
+ UInt64 files = 0;
+ UInt64 value = Offset + *inSize;
+ return Callback->SetCompleted(&files, &value);
+ }
+ return S_OK;
+}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
@@ -324,13 +429,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
COM_TRY_BEGIN
if (numItems == 0)
return S_OK;
- if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
+ if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
- if (_stream)
+ if (_packSize_Defined)
extractCallback->SetTotal(_packSize);
-
-
+
+
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
@@ -338,7 +443,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
if (!testMode && !realOutStream)
return S_OK;
-
+
extractCallback->PrepareOperation(askMode);
CDummyOutStream *outStreamSpec = new CDummyOutStream;
@@ -351,78 +456,147 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, true);
- if (_stream)
+ if (_needSeekToStart)
{
- RINOK(_stream->Seek(_startPosition, STREAM_SEEK_SET, NULL));
+ if (!_stream)
+ return E_FAIL;
+ RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
}
+ else
+ _needSeekToStart = true;
CDecoder decoder;
HRESULT result = decoder.Create(
EXTERNAL_CODECS_VARS
_lzma86, _seqStream);
RINOK(result);
-
- Int32 opRes = NExtract::NOperationResult::kOK;
+
bool firstItem = true;
+ UInt64 packSize = 0;
+ UInt64 unpackSize = 0;
+ UInt64 numStreams = 0;
+
+ bool dataAfterEnd = false;
+
for (;;)
{
- lps->OutSize = outStreamSpec->GetSize();
- lps->InSize = _packSize = decoder.GetInputProcessedSize();
- _packSizeDefined = true;
+ lps->InSize = packSize;
+ lps->OutSize = unpackSize;
RINOK(lps->SetCur());
- CHeader st;
-
const UInt32 kBufSize = 1 + 5 + 8;
Byte buf[kBufSize];
const UInt32 headerSize = GetHeaderSize();
UInt32 processed;
RINOK(decoder.ReadInput(buf, headerSize, &processed));
if (processed != headerSize)
+ {
+ if (processed != 0)
+ dataAfterEnd = true;
break;
-
+ }
+
+ CHeader st;
if (!st.Parse(buf, _lzma86))
+ {
+ dataAfterEnd = true;
break;
+ }
+ numStreams++;
firstItem = false;
result = decoder.Code(st, outStream, progress);
+
+ packSize = decoder.GetInputProcessedSize();
+ unpackSize = outStreamSpec->GetSize();
+
if (result == E_NOTIMPL)
{
- opRes = NExtract::NOperationResult::kUnSupportedMethod;
+ _unsupported = true;
+ result = S_FALSE;
break;
}
if (result == S_FALSE)
- {
- opRes = NExtract::NOperationResult::kDataError;
break;
- }
RINOK(result);
}
+
if (firstItem)
- return E_FAIL;
+ {
+ _isArc = false;
+ result = S_FALSE;
+ }
+ else if (result == S_OK || result == S_FALSE)
+ {
+ if (dataAfterEnd)
+ _dataAfterEnd = true;
+ else if (decoder._lzmaDecoderSpec->NeedMoreInput)
+ _needMoreInput = true;
+
+ _packSize = packSize;
+ _unpackSize = unpackSize;
+ _numStreams = numStreams;
+
+ _packSize_Defined = true;
+ _unpackSize_Defined = true;
+ _numStreams_Defined = true;
+ }
+
+ Int32 opResult = NExtract::NOperationResult::kOK;
+
+ if (!_isArc)
+ opResult = NExtract::NOperationResult::kIsNotArc;
+ else if (_needMoreInput)
+ opResult = NExtract::NOperationResult::kUnexpectedEnd;
+ else if (_unsupported)
+ opResult = NExtract::NOperationResult::kUnsupportedMethod;
+ else if (_dataAfterEnd)
+ opResult = NExtract::NOperationResult::kDataAfterEnd;
+ else if (result == S_FALSE)
+ opResult = NExtract::NOperationResult::kDataError;
+ else if (result == S_OK)
+ opResult = NExtract::NOperationResult::kOK;
+ else
+ return result;
+
outStream.Release();
- return extractCallback->SetOperationResult(opRes);
+ return extractCallback->SetOperationResult(opResult);
COM_TRY_END
}
IMPL_ISetCompressCodecsInfo
-static IInArchive *CreateArc() { return new CHandler(false); }
-static IInArchive *CreateArc86() { return new CHandler(true); }
-
namespace NLzmaAr {
-
+
+IMP_CreateArcIn_2(CHandler(false))
+
static CArcInfo g_ArcInfo =
- { L"lzma", L"lzma", 0, 0xA, { 0 }, 0, true, CreateArc, NULL };
+ { "lzma", "lzma", 0, 0xA,
+ 0, { 0 },
+ // 2, { 0x5D, 0x00 },
+ 0,
+ NArcInfoFlags::kStartOpen |
+ NArcInfoFlags::kKeepName,
+ CreateArc, NULL,
+ IsArc_Lzma };
+
REGISTER_ARC(Lzma)
}
namespace NLzma86Ar {
+IMP_CreateArcIn_2(CHandler(true))
+
static CArcInfo g_ArcInfo =
- { L"lzma86", L"lzma86", 0, 0xB, { 0 }, 0, true, CreateArc86, NULL };
+ { "lzma86", "lzma86", 0, 0xB,
+ 0, { 0 },
+ 0,
+ NArcInfoFlags::kKeepName,
+ CreateArc, NULL,
+ IsArc_Lzma86 };
+
REGISTER_ARC(Lzma86)
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/SplitHandler.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/SplitHandler.cpp
index 5d84de4ed..db9f49aa0 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/SplitHandler.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/SplitHandler.cpp
@@ -2,10 +2,10 @@
#include "StdAfx.h"
-#include "Common/ComTry.h"
-#include "Common/MyString.h"
+#include "../../Common/ComTry.h"
+#include "../../Common/MyString.h"
-#include "Windows/PropVariant.h"
+#include "../../Windows/PropVariant.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
@@ -19,15 +19,16 @@ using namespace NWindows;
namespace NArchive {
namespace NSplit {
-STATPROPSTG kProps[] =
+static const Byte kProps[] =
{
- { NULL, kpidPath, VT_BSTR},
- { NULL, kpidSize, VT_UI8}
+ kpidPath,
+ kpidSize
};
-STATPROPSTG kArcProps[] =
+static const Byte kArcProps[] =
{
- { NULL, kpidNumVolumes, VT_UI4}
+ kpidNumVolumes,
+ kpidTotalPhySize
};
class CHandler:
@@ -35,10 +36,12 @@ class CHandler:
public IInArchiveGetStream,
public CMyUnknownImp
{
- UString _subName;
CObjectVector<CMyComPtr<IInStream> > _streams;
CRecordVector<UInt64> _sizes;
+ UString _subName;
UInt64 _totalSize;
+
+ HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback);
public:
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
INTERFACE_IInArchive(;)
@@ -51,9 +54,11 @@ IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
- switch(propID)
+ switch (propID)
{
case kpidMainSubfile: prop = (UInt32)0; break;
+ case kpidPhySize: if (!_sizes.IsEmpty()) prop = _sizes[0]; break;
+ case kpidTotalPhySize: prop = _totalSize; break;
case kpidNumVolumes: prop = (UInt32)_streams.Size(); break;
}
prop.Detach(value);
@@ -65,27 +70,25 @@ struct CSeqName
UString _unchangedPart;
UString _changedPart;
bool _splitStyle;
-
+
UString GetNextName()
{
UString newName;
if (_splitStyle)
{
int i;
- int numLetters = _changedPart.Length();
+ int numLetters = _changedPart.Len();
for (i = numLetters - 1; i >= 0; i--)
{
wchar_t c = _changedPart[i];
if (c == 'z')
{
- c = 'a';
- newName = c + newName;
+ newName.InsertAtFront('a');
continue;
}
else if (c == 'Z')
{
- c = 'A';
- newName = c + newName;
+ newName.InsertAtFront('A');
continue;
}
c++;
@@ -99,33 +102,32 @@ struct CSeqName
newName += newChar;
break;
}
- newName = c + newName;
+ newName.InsertAtFront(c);
i--;
for (; i >= 0; i--)
- newName = _changedPart[i] + newName;
+ newName.InsertAtFront(_changedPart[i]);
break;
}
}
else
{
int i;
- int numLetters = _changedPart.Length();
+ int numLetters = _changedPart.Len();
for (i = numLetters - 1; i >= 0; i--)
{
wchar_t c = _changedPart[i];
- if (c == L'9')
+ if (c == '9')
{
- c = L'0';
- newName = c + newName;
+ newName.InsertAtFront('0');
if (i == 0)
- newName = UString(L'1') + newName;
+ newName.InsertAtFront('1');
continue;
}
c++;
- newName = c + newName;
+ newName.InsertAtFront(c);
i--;
for (; i >= 0; i--)
- newName = _changedPart[i] + newName;
+ newName.InsertAtFront(_changedPart[i]);
break;
}
}
@@ -134,142 +136,139 @@ struct CSeqName
}
};
-STDMETHODIMP CHandler::Open(IInStream *stream,
- const UInt64 * /* maxCheckStartPosition */,
- IArchiveOpenCallback *openArchiveCallback)
+HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{
- COM_TRY_BEGIN
Close();
- if (openArchiveCallback == 0)
+ if (!callback)
+ return S_FALSE;
+
+ CMyComPtr<IArchiveOpenVolumeCallback> volumeCallback;
+ callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback);
+ if (!volumeCallback)
return S_FALSE;
- // try
+
+ UString name;
{
- CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
- CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback;
- if (openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback,
- &openVolumeCallback) != S_OK)
+ NCOM::CPropVariant prop;
+ RINOK(volumeCallback->GetProperty(kpidName, &prop));
+ if (prop.vt != VT_BSTR)
return S_FALSE;
-
- UString name;
- {
- NCOM::CPropVariant prop;
- RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
- if (prop.vt != VT_BSTR)
- return S_FALSE;
- name = prop.bstrVal;
- }
-
- int dotPos = name.ReverseFind('.');
- UString prefix, ext;
- if (dotPos >= 0)
- {
- prefix = name.Left(dotPos + 1);
- ext = name.Mid(dotPos + 1);
- }
- else
- ext = name;
- UString extBig = ext;
- extBig.MakeUpper();
+ name = prop.bstrVal;
+ }
+
+ int dotPos = name.ReverseFind('.');
+ const UString prefix = name.Left(dotPos + 1);
+ const UString ext = name.Ptr(dotPos + 1);
+ UString ext2 = ext;
+ ext2.MakeLower_Ascii();
- CSeqName seqName;
+ CSeqName seqName;
- int numLetters = 2;
- bool splitStyle = false;
- if (extBig.Right(2) == L"AA")
+ unsigned numLetters = 2;
+ bool splitStyle = false;
+
+ if (ext2.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "aa"))
+ {
+ splitStyle = true;
+ while (numLetters < ext2.Len())
{
- splitStyle = true;
- while (numLetters < extBig.Length())
- {
- if (extBig[extBig.Length() - numLetters - 1] != 'A')
- break;
- numLetters++;
- }
+ if (ext2[ext2.Len() - numLetters - 1] != 'a')
+ break;
+ numLetters++;
}
- else if (ext.Right(2) == L"01")
+ }
+ else if (ext.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "01"))
+ {
+ while (numLetters < ext2.Len())
{
- while (numLetters < extBig.Length())
- {
- if (extBig[extBig.Length() - numLetters - 1] != '0')
- break;
- numLetters++;
- }
- if (numLetters != ext.Length())
- return S_FALSE;
+ if (ext2[ext2.Len() - numLetters - 1] != '0')
+ break;
+ numLetters++;
}
- else
+ if (numLetters != ext.Len())
return S_FALSE;
+ }
+ else
+ return S_FALSE;
- _streams.Add(stream);
+ seqName._unchangedPart = prefix + ext.Left(ext2.Len() - numLetters);
+ seqName._changedPart = ext.RightPtr(numLetters);
+ seqName._splitStyle = splitStyle;
- seqName._unchangedPart = prefix + ext.Left(extBig.Length() - numLetters);
- seqName._changedPart = ext.Right(numLetters);
- seqName._splitStyle = splitStyle;
+ if (prefix.Len() < 1)
+ _subName = L"file";
+ else
+ _subName.SetFrom(prefix, prefix.Len() - 1);
- if (prefix.Length() < 1)
- _subName = L"file";
- else
- _subName = prefix.Left(prefix.Length() - 1);
+ UInt64 size;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(volumeCallback->GetProperty(kpidSize, &prop));
+ if (prop.vt != VT_UI8)
+ return E_INVALIDARG;
+ size = prop.uhVal.QuadPart;
+ }
+
+ _totalSize += size;
+ _sizes.Add(size);
+ _streams.Add(stream);
- _totalSize = 0;
- UInt64 size;
+ {
+ UInt64 numFiles = _streams.Size();
+ RINOK(callback->SetCompleted(&numFiles, NULL));
+ }
+
+ for (;;)
+ {
+ const UString fullName = seqName.GetNextName();
+ CMyComPtr<IInStream> nextStream;
+ HRESULT result = volumeCallback->GetStream(fullName, &nextStream);
+ if (result == S_FALSE)
+ break;
+ if (result != S_OK)
+ return result;
+ if (!stream)
+ break;
{
NCOM::CPropVariant prop;
- RINOK(openVolumeCallback->GetProperty(kpidSize, &prop));
+ RINOK(volumeCallback->GetProperty(kpidSize, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
_totalSize += size;
_sizes.Add(size);
-
- if (openArchiveCallback != NULL)
+ _streams.Add(nextStream);
{
UInt64 numFiles = _streams.Size();
- RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
- }
-
- for (;;)
- {
- UString fullName = seqName.GetNextName();
- CMyComPtr<IInStream> nextStream;
- HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream);
- if (result == S_FALSE)
- break;
- if (result != S_OK)
- return result;
- if (!stream)
- break;
- {
- NCOM::CPropVariant prop;
- RINOK(openVolumeCallback->GetProperty(kpidSize, &prop));
- if (prop.vt != VT_UI8)
- return E_INVALIDARG;
- size = prop.uhVal.QuadPart;
- }
- _totalSize += size;
- _sizes.Add(size);
- _streams.Add(nextStream);
- if (openArchiveCallback != NULL)
- {
- UInt64 numFiles = _streams.Size();
- RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
- }
+ RINOK(callback->SetCompleted(&numFiles, NULL));
}
}
- /*
- catch(...)
+
+ if (_streams.Size() == 1)
{
- return S_FALSE;
+ if (splitStyle)
+ return S_FALSE;
}
- */
return S_OK;
+}
+
+STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)
+{
+ COM_TRY_BEGIN
+ HRESULT res = Open2(stream, callback);
+ if (res != S_OK)
+ Close();
+ return res;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
- _sizes.Clear();
+ _totalSize = 0;
+ _subName.Empty();
_streams.Clear();
+ _sizes.Clear();
return S_OK;
}
@@ -281,8 +280,8 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
- NWindows::NCOM::CPropVariant prop;
- switch(propID)
+ NCOM::CPropVariant prop;
+ switch (propID)
{
case kpidPath: prop = _subName; break;
case kpidSize:
@@ -300,7 +299,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
COM_TRY_BEGIN
if (numItems == 0)
return S_OK;
- if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
+ if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
UInt64 currentTotalSize = 0;
@@ -313,7 +312,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (!testMode && !outStream)
return S_OK;
RINOK(extractCallback->PrepareOperation(askMode));
-
+
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
@@ -321,7 +320,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
- for (int i = 0; i < _streams.Size(); i++)
+ FOR_VECTOR (i, _streams)
{
lps->InSize = lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
@@ -343,7 +342,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
*stream = 0;
CMultiStream *streamSpec = new CMultiStream;
CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
- for (int i = 0; i < _streams.Size(); i++)
+ FOR_VECTOR (i, _streams)
{
CMultiStream::CSubStreamInfo subStreamInfo;
subStreamInfo.Stream = _streams[i];
@@ -356,10 +355,14 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
COM_TRY_END
}
-static IInArchive *CreateArc() { return new CHandler; }
+IMP_CreateArcIn
static CArcInfo g_ArcInfo =
-{ L"Split", L"001", 0, 0xEA, { 0 }, 0, false, CreateArc, 0 };
+ { "Split", "001", 0, 0xEA,
+ 0, { 0 },
+ 0,
+ 0,
+ CreateArc };
REGISTER_ARC(Split)
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/XzHandler.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/XzHandler.cpp
index 64b7a5863..789f41a72 100644
--- a/src/libs/7zip/unix/CPP/7zip/Archive/XzHandler.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Archive/XzHandler.cpp
@@ -7,6 +7,7 @@
#include "../../../C/XzEnc.h"
#include "../../Common/ComTry.h"
+#include "../../Common/Defs.h"
#include "../../Common/IntToString.h"
#include "../ICoder.h"
@@ -40,37 +41,120 @@ namespace NXz {
struct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit;
+static const wchar_t *k_LZMA2_Name = L"LZMA2";
+
+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()
+ {
+ InSize = 0;
+ OutSize = 0;
+ PhySize = 0;
+
+ NumStreams = 0;
+ NumBlocks = 0;
+
+ UnpackSize_Defined = false;
+
+ NumStreams_Defined = false;
+ NumBlocks_Defined = false;
+
+ UnexpectedEnd = false;
+ DataAfterEnd = false;
+ Unsupported = false;
+ HeadersError = false;
+ DataError = false;
+ CrcError = false;
+ IsArc = false;
+ }
+
+};
+
+struct IDecodeState: public CStatInfo
+{
+ SRes DecodeRes;
+
+ IDecodeState(): DecodeRes(SZ_OK) {}
+ virtual HRESULT Progress() = 0;
+
+ HRESULT Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream);
+};
+
+struct CVirtProgress_To_LocalProgress: public IDecodeState
+{
+ CLocalProgress *lps;
+ CMyComPtr<ICompressProgressInfo> progress;
+
+ HRESULT Progress();
+};
+
+HRESULT CVirtProgress_To_LocalProgress::Progress()
+{
+ lps->InSize = InSize;
+ lps->OutSize = OutSize;
+ return lps->SetCur();
+}
+
+
class CHandler:
public IInArchive,
public IArchiveOpenSeq,
#ifndef EXTRACT_ONLY
public IOutArchive,
public ISetProperties,
- public COutHandler,
+ public CMultiMethodProps,
#endif
public CMyUnknownImp
{
- Int64 _startPosition;
- UInt64 _packSize;
- UInt64 _unpackSize;
- UInt64 _numBlocks;
- AString _methodsString;
- bool _useSeq;
- UInt64 _unpackSizeDefined;
- UInt64 _packSizeDefined;
-
+ CStatInfo _stat;
+
+ bool _isArc;
+ bool _needSeekToStart;
+ bool _phySize_Defined;
+
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
- UInt32 _crcSize;
+ UInt32 _filterId;
+ AString _methodsString;
void Init()
{
- _crcSize = 4;
- COutHandler::Init();
+ _filterId = 0;
+ CMultiMethodProps::Init();
}
- HRESULT Open2(IInStream *inStream, IArchiveOpenCallback *callback);
+ HRESULT Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback);
+
+ HRESULT Decode2(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, IDecodeState &progress)
+ {
+ RINOK(progress.Decode(seqInStream, outStream));
+ _stat = progress;
+ _phySize_Defined = true;
+ return S_OK;
+ }
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
@@ -87,7 +171,7 @@ public:
#ifndef EXTRACT_ONLY
INTERFACE_IOutArchive(;)
- STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps);
#endif
CHandler();
@@ -98,60 +182,60 @@ CHandler::CHandler()
Init();
}
-STATPROPSTG kProps[] =
+static const Byte kProps[] =
{
- { NULL, kpidSize, VT_UI8},
- { NULL, kpidPackSize, VT_UI8},
- { NULL, kpidMethod, VT_BSTR}
+ kpidSize,
+ kpidPackSize,
+ kpidMethod
};
-STATPROPSTG kArcProps[] =
+static const Byte kArcProps[] =
{
- { NULL, kpidMethod, VT_BSTR},
- { NULL, kpidNumBlocks, VT_UI4}
+ kpidMethod,
+ kpidNumStreams,
+ kpidNumBlocks
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
-static char GetHex(Byte value)
+static inline char GetHex(unsigned value)
{
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
}
-static inline void AddHexToString(AString &res, Byte value)
+static inline void AddHexToString(AString &s, Byte value)
{
- res += GetHex((Byte)(value >> 4));
- res += GetHex((Byte)(value & 0xF));
+ s += GetHex(value >> 4);
+ s += GetHex(value & 0xF);
}
-static AString ConvertUInt32ToString(UInt32 value)
+static void AddUInt32ToString(AString &s, UInt32 value)
{
- char temp[32];
- ::ConvertUInt32ToString(value, temp);
- return temp;
+ char temp[16];
+ ConvertUInt32ToString(value, temp);
+ s += temp;
}
-static AString Lzma2PropToString(int prop)
+static void Lzma2PropToString(AString &s, unsigned prop)
{
+ char c = 0;
+ UInt32 size;
if ((prop & 1) == 0)
- return ConvertUInt32ToString(prop / 2 + 12);
- AString res;
- char c;
-
- UInt32 size = (2 | ((prop) & 1)) << ((prop) / 2 + 1);
-
- if (prop > 17)
- {
- res = ConvertUInt32ToString(size >> 10);
- c = 'm';
- }
+ size = prop / 2 + 12;
else
{
- res = ConvertUInt32ToString(size);
c = 'k';
+ size = (UInt32)(2 | (prop & 1)) << (prop / 2 + 1);
+ if (prop > 17)
+ {
+ size >>= 10;
+ c = 'm';
+ }
}
- return res + c;
+ AddUInt32ToString(s, size);
+ if (c != 0)
+ s += c;
}
struct CMethodNamePair
@@ -160,11 +244,11 @@ struct CMethodNamePair
const char *Name;
};
-static CMethodNamePair g_NamePairs[] =
+static const CMethodNamePair g_NamePairs[] =
{
{ XZ_ID_Subblock, "SB" },
{ XZ_ID_Delta, "Delta" },
- { XZ_ID_X86, "x86" },
+ { XZ_ID_X86, "BCJ" },
{ XZ_ID_PPC, "PPC" },
{ XZ_ID_IA64, "IA64" },
{ XZ_ID_ARM, "ARM" },
@@ -175,25 +259,29 @@ static CMethodNamePair g_NamePairs[] =
static AString GetMethodString(const CXzFilter &f)
{
- AString s;
-
- for (int i = 0; i < sizeof(g_NamePairs) / sizeof(g_NamePairs[i]); i++)
+ const char *p = NULL;
+ for (unsigned i = 0; i < ARRAY_SIZE(g_NamePairs); i++)
if (g_NamePairs[i].Id == f.id)
- s = g_NamePairs[i].Name;
- if (s.IsEmpty())
+ {
+ p = g_NamePairs[i].Name;
+ break;
+ }
+ char temp[32];
+ if (!p)
{
- char temp[32];
::ConvertUInt64ToString(f.id, temp);
- s = temp;
+ p = temp;
}
+ AString s = p;
+
if (f.propsSize > 0)
{
s += ':';
if (f.id == XZ_ID_LZMA2 && f.propsSize == 1)
- s += Lzma2PropToString(f.props[0]);
+ Lzma2PropToString(s, f.props[0]);
else if (f.id == XZ_ID_Delta && f.propsSize == 1)
- s += ConvertUInt32ToString((UInt32)f.props[0] + 1);
+ AddUInt32ToString(s, (UInt32)f.props[0] + 1);
else
{
s += '[';
@@ -214,22 +302,22 @@ static void AddString(AString &dest, const AString &src)
static const char *kChecks[] =
{
- "NoCheck",
- "CRC32",
- NULL,
- NULL,
- "CRC64",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- "SHA256",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
+ "NoCheck"
+ , "CRC32"
+ , NULL
+ , NULL
+ , "CRC64"
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , "SHA256"
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
};
static AString GetCheckString(const CXzs &xzs)
@@ -246,7 +334,10 @@ static AString GetCheckString(const CXzs &xzs)
if (kChecks[i])
s2 = kChecks[i];
else
- s2 = "Check-" + ConvertUInt32ToString((UInt32)i);
+ {
+ s2 = "Check-";
+ AddUInt32ToString(s2, (UInt32)i);
+ }
AddString(s, s2);
}
return s;
@@ -255,12 +346,26 @@ static AString GetCheckString(const CXzs &xzs)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
- NWindows::NCOM::CPropVariant prop;
- switch(propID)
+ NCOM::CPropVariant prop;
+ switch (propID)
{
- case kpidNumBlocks: if (!_useSeq) prop = _numBlocks; break;
- case kpidPhySize: if (_packSizeDefined) prop = _packSize; break;
+ case kpidPhySize: if (_phySize_Defined) prop = _stat.PhySize; break;
+ case kpidNumStreams: if (_stat.NumStreams_Defined) prop = _stat.NumStreams; break;
+ case kpidNumBlocks: if (_stat.NumBlocks_Defined) prop = _stat.NumBlocks; break;
+ case kpidUnpackSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break;
case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;
+ case kpidErrorFlags:
+ {
+ UInt32 v = 0;
+ if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;;
+ if (_stat.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
+ if (_stat.DataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
+ if (_stat.HeadersError) v |= kpv_ErrorFlags_HeadersError;
+ if (_stat.Unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
+ if (_stat.DataError) v |= kpv_ErrorFlags_DataError;
+ if (_stat.CrcError) v |= kpv_ErrorFlags_CrcError;
+ prop = v;
+ }
}
prop.Detach(value);
return S_OK;
@@ -273,14 +378,14 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
-STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)
+STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
- NWindows::NCOM::CPropVariant prop;
- switch(propID)
+ NCOM::CPropVariant prop;
+ switch (propID)
{
- case kpidSize: if (_unpackSizeDefined) prop = _unpackSize; break;
- case kpidPackSize: if (_packSizeDefined) prop = _packSize; break;
+ case kpidSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break;
+ case kpidPackSize: if (_phySize_Defined) prop = _stat.PhySize; break;
case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;
}
prop.Detach(value);
@@ -318,82 +423,124 @@ struct CXzsCPP
~CXzsCPP() { Xzs_Free(&p, &g_Alloc); }
};
-HRESULT CHandler::Open2(IInStream *inStream, IArchiveOpenCallback *callback)
+
+struct CVirtProgress_To_OpenProgress: public IDecodeState
{
- CSeekInStreamWrap inStreamImp(inStream);
+ IArchiveOpenCallback *Callback;
+ UInt64 Offset;
- CLookToRead lookStream;
- LookToRead_CreateVTable(&lookStream, True);
- lookStream.realStream = &inStreamImp.p;
- LookToRead_Init(&lookStream);
+ HRESULT Progress();
+};
- COpenCallbackWrap openWrap(callback);
- RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize));
- RINOK(callback->SetTotal(NULL, &_packSize));
+HRESULT CVirtProgress_To_OpenProgress::Progress()
+{
+ if (Callback)
+ {
+ UInt64 files = 0;
+ UInt64 value = Offset + InSize;
+ return Callback->SetCompleted(&files, &value);
+ }
+ return S_OK;
+}
- CXzsCPP xzs;
- SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.s, &_startPosition, &openWrap.p, &g_Alloc);
- if (res == SZ_ERROR_NO_ARCHIVE && xzs.p.num > 0)
- res = SZ_OK;
- if (res == SZ_OK)
+static HRESULT SRes_to_Open_HRESULT(SRes res)
+{
+ switch (res)
{
- _packSize -= _startPosition;
- _unpackSize = Xzs_GetUnpackSize(&xzs.p);
- _unpackSizeDefined = _packSizeDefined = true;
- _numBlocks = (UInt64)Xzs_GetNumBlocks(&xzs.p);
+ case SZ_OK: return S_OK;
+ case SZ_ERROR_MEM: return E_OUTOFMEMORY;
+ case SZ_ERROR_PROGRESS: return E_ABORT;
+ /*
+ case SZ_ERROR_UNSUPPORTED:
+ case SZ_ERROR_CRC:
+ case SZ_ERROR_DATA:
+ case SZ_ERROR_ARCHIVE:
+ case SZ_ERROR_NO_ARCHIVE:
+ return S_FALSE;
+ */
+ }
+ return S_FALSE;
+}
+
+HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback)
+{
+ _needSeekToStart = true;
- RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+ {
CXzStreamFlags st;
CSeqInStreamWrap inStreamWrap(inStream);
- SRes res2 = Xz_ReadHeader(&st, &inStreamWrap.p);
+ SRes res = Xz_ReadHeader(&st, &inStreamWrap.p);
+ if (res != SZ_OK)
+ return SRes_to_Open_HRESULT(res);
- if (res2 == SZ_OK)
{
CXzBlock block;
Bool isIndex;
UInt32 headerSizeRes;
- res2 = XzBlock_ReadHeader(&block, &inStreamWrap.p, &isIndex, &headerSizeRes);
+ SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.p, &isIndex, &headerSizeRes);
if (res2 == SZ_OK && !isIndex)
{
- int numFilters = XzBlock_GetNumFilters(&block);
- for (int i = 0; i < numFilters; i++)
+ unsigned numFilters = XzBlock_GetNumFilters(&block);
+ for (unsigned i = 0; i < numFilters; i++)
AddString(_methodsString, GetMethodString(block.filters[i]));
}
}
- AddString(_methodsString, GetCheckString(xzs.p));
}
- if (res != SZ_OK || _startPosition != 0)
+ RINOK(inStream->Seek(0, STREAM_SEEK_END, &_stat.PhySize));
+ RINOK(callback->SetTotal(NULL, &_stat.PhySize));
+
+ CSeekInStreamWrap inStreamImp(inStream);
+
+ CLookToRead lookStream;
+ LookToRead_CreateVTable(&lookStream, True);
+ lookStream.realStream = &inStreamImp.p;
+ LookToRead_Init(&lookStream);
+
+ COpenCallbackWrap openWrap(callback);
+
+ CXzsCPP xzs;
+ Int64 startPosition;
+ SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.s, &startPosition, &openWrap.p, &g_Alloc);
+ if (res == SZ_ERROR_PROGRESS)
+ return (openWrap.Res == S_OK) ? E_FAIL : openWrap.Res;
+ /*
+ if (res == SZ_ERROR_NO_ARCHIVE && xzs.p.num > 0)
+ res = SZ_OK;
+ */
+ if (res == SZ_OK && startPosition == 0)
{
- RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
- CXzStreamFlags st;
- CSeqInStreamWrap inStreamWrap(inStream);
- SRes res2 = Xz_ReadHeader(&st, &inStreamWrap.p);
- if (res2 == SZ_OK)
- {
- res = res2;
- _startPosition = 0;
- _useSeq = True;
- _unpackSizeDefined = _packSizeDefined = false;
- }
+ _phySize_Defined = true;
+
+ _stat.OutSize = Xzs_GetUnpackSize(&xzs.p);
+ _stat.UnpackSize_Defined = true;
+
+ _stat.NumStreams = xzs.p.num;
+ _stat.NumStreams_Defined = true;
+
+ _stat.NumBlocks = Xzs_GetNumBlocks(&xzs.p);
+ _stat.NumBlocks_Defined = true;
+
+ AddString(_methodsString, GetCheckString(xzs.p));
}
- if (res == SZ_ERROR_NO_ARCHIVE)
- return S_FALSE;
- RINOK(SResToHRESULT(res));
+ else
+ {
+ res = SZ_OK;
+ }
+ RINOK(SRes_to_Open_HRESULT(res));
_stream = inStream;
_seqStream = inStream;
+ _isArc = true;
return S_OK;
}
STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)
{
COM_TRY_BEGIN
- try
{
Close();
- return Open2(inStream, callback);
+ return Open2(inStream, /* 0, */ callback);
}
- catch(...) { return S_FALSE; }
COM_TRY_END
}
@@ -401,15 +548,21 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
{
Close();
_seqStream = stream;
+ _isArc = true;
+ _needSeekToStart = false;
return S_OK;
}
STDMETHODIMP CHandler::Close()
{
- _numBlocks = 0;
- _useSeq = true;
- _unpackSizeDefined = _packSizeDefined = false;
- _methodsString.Empty();
+ _stat.Clear();
+
+ _isArc = false;
+ _needSeekToStart = false;
+
+ _phySize_Defined = false;
+
+ _methodsString.Empty();
_stream.Release();
_seqStream.Release();
return S_OK;
@@ -439,7 +592,11 @@ struct CXzUnpackerCPP
Byte *InBuf;
Byte *OutBuf;
CXzUnpacker p;
- CXzUnpackerCPP(): InBuf(0), OutBuf(0) {}
+
+ CXzUnpackerCPP(): InBuf(0), OutBuf(0)
+ {
+ XzUnpacker_Construct(&p, &g_Alloc);
+ }
~CXzUnpackerCPP()
{
XzUnpacker_Free(&p);
@@ -448,133 +605,195 @@ struct CXzUnpackerCPP
}
};
-STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
- Int32 testMode, IArchiveExtractCallback *extractCallback)
+HRESULT IDecodeState::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream)
{
- COM_TRY_BEGIN
- if (numItems == 0)
- return S_OK;
- if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
- return E_INVALIDARG;
-
- extractCallback->SetTotal(_packSize);
- UInt64 currentTotalPacked = 0;
- RINOK(extractCallback->SetCompleted(&currentTotalPacked));
- CMyComPtr<ISequentialOutStream> realOutStream;
- Int32 askMode = testMode ?
- NExtract::NAskMode::kTest :
- NExtract::NAskMode::kExtract;
-
- RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
-
- if (!testMode && !realOutStream)
- return S_OK;
-
- extractCallback->PrepareOperation(askMode);
+ const size_t kInBufSize = 1 << 15;
+ const size_t kOutBufSize = 1 << 21;
- if (_stream)
- {
- RINOK(_stream->Seek(_startPosition, STREAM_SEEK_SET, NULL));
- }
-
- CLocalProgress *lps = new CLocalProgress;
- CMyComPtr<ICompressProgressInfo> progress = lps;
- lps->Init(extractCallback, true);
+ DecodeRes = SZ_OK;
- CCompressProgressWrap progressWrap(progress);
-
- SRes res;
-
- const UInt32 kInBufSize = 1 << 15;
- const UInt32 kOutBufSize = 1 << 21;
+ CXzUnpackerCPP xzu;
+ XzUnpacker_Init(&xzu.p);
+ xzu.InBuf = (Byte *)MyAlloc(kInBufSize);
+ xzu.OutBuf = (Byte *)MyAlloc(kOutBufSize);
+ if (!xzu.InBuf || !xzu.OutBuf)
+ return E_OUTOFMEMORY;
- UInt32 inPos = 0;
UInt32 inSize = 0;
- UInt32 outPos = 0;
- CXzUnpackerCPP xzu;
- res = XzUnpacker_Create(&xzu.p, &g_Alloc);
- if (res == SZ_OK)
- {
- xzu.InBuf = (Byte *)MyAlloc(kInBufSize);
- xzu.OutBuf = (Byte *)MyAlloc(kOutBufSize);
- if (xzu.InBuf == 0 || xzu.OutBuf == 0)
- res = SZ_ERROR_MEM;
- }
- if (res == SZ_OK)
+ SizeT inPos = 0;
+ SizeT outPos = 0;
+
for (;;)
{
if (inPos == inSize)
{
inPos = inSize = 0;
- RINOK(_seqStream->Read(xzu.InBuf, kInBufSize, &inSize));
+ RINOK(seqInStream->Read(xzu.InBuf, kInBufSize, &inSize));
}
SizeT inLen = inSize - inPos;
SizeT outLen = kOutBufSize - outPos;
ECoderStatus status;
- res = XzUnpacker_Code(&xzu.p,
+
+ SRes res = XzUnpacker_Code(&xzu.p,
xzu.OutBuf + outPos, &outLen,
xzu.InBuf + inPos, &inLen,
(inSize == 0 ? CODER_FINISH_END : CODER_FINISH_ANY), &status);
- // printf("\n_inPos = %6d inLen = %5d, outLen = %5d", inPos, inLen, outLen);
+ inPos += inLen;
+ outPos += outLen;
- inPos += (UInt32)inLen;
- outPos += (UInt32)outLen;
- lps->InSize += inLen;
- lps->OutSize += outLen;
+ InSize += inLen;
+ OutSize += outLen;
- bool finished = (((inLen == 0) && (outLen == 0)) || res != SZ_OK);
+ DecodeRes = res;
- if (outPos == kOutBufSize || finished)
+ bool finished = ((inLen == 0 && outLen == 0) || res != SZ_OK);
+
+ if (outStream)
{
- if (realOutStream && outPos > 0)
+ if (outPos == kOutBufSize || finished)
{
- RINOK(WriteStream(realOutStream, xzu.OutBuf, outPos));
+ if (outPos != 0)
+ {
+ RINOK(WriteStream(outStream, xzu.OutBuf, outPos));
+ outPos = 0;
+ }
}
- outPos = 0;
}
+ else
+ outPos = 0;
+
+ RINOK(Progress());
+
if (finished)
{
- _packSize = lps->InSize;
- _unpackSize = lps->OutSize;
- _packSizeDefined = _unpackSizeDefined = true;
+ PhySize = InSize;
+ NumStreams = xzu.p.numStartedStreams;
+ if (NumStreams > 0)
+ IsArc = true;
+ NumBlocks = xzu.p.numTotalBlocks;
+
+ UnpackSize_Defined = true;
+ NumStreams_Defined = true;
+ NumBlocks_Defined = true;
+
+ UInt64 extraSize = XzUnpacker_GetExtraSize(&xzu.p);
+
if (res == SZ_OK)
{
if (status == CODER_STATUS_NEEDS_MORE_INPUT)
{
- if (XzUnpacker_IsStreamWasFinished(&xzu.p))
- _packSize -= xzu.p.padSize;
- else
+ extraSize = 0;
+ if (!XzUnpacker_IsStreamWasFinished(&xzu.p))
+ {
+ // finished at padding bytes, but padding is not aligned for 4
+ UnexpectedEnd = true;
res = SZ_ERROR_DATA;
+ }
}
- else
+ else // status == CODER_STATUS_NOT_FINISHED
res = SZ_ERROR_DATA;
}
+ else if (res == SZ_ERROR_NO_ARCHIVE)
+ {
+ if (InSize == extraSize)
+ IsArc = false;
+ else
+ {
+ if (extraSize != 0 || inPos != inSize)
+ {
+ DataAfterEnd = true;
+ res = SZ_OK;
+ }
+ }
+ }
+
+ DecodeRes = res;
+ PhySize -= extraSize;
+
+ switch (res)
+ {
+ case SZ_OK: break;
+ case SZ_ERROR_NO_ARCHIVE: IsArc = false; break;
+ case SZ_ERROR_ARCHIVE: HeadersError = true; break;
+ case SZ_ERROR_UNSUPPORTED: Unsupported = true; break;
+ case SZ_ERROR_CRC: CrcError = true; break;
+ case SZ_ERROR_DATA: DataError = true; break;
+ default: DataError = true; break;
+ }
+
break;
}
- RINOK(lps->SetCur());
}
- Int32 opRes;
- switch(res)
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ if (numItems == 0)
+ return S_OK;
+ if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
+ return E_INVALIDARG;
+
+ extractCallback->SetTotal(_stat.PhySize);
+ UInt64 currentTotalPacked = 0;
+ RINOK(extractCallback->SetCompleted(&currentTotalPacked));
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode = testMode ?
+ NExtract::NAskMode::kTest :
+ NExtract::NAskMode::kExtract;
+
+ RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
+
+ if (!testMode && !realOutStream)
+ return S_OK;
+
+ extractCallback->PrepareOperation(askMode);
+
+ CVirtProgress_To_LocalProgress vp;
+ vp.lps = new CLocalProgress;
+ vp.progress = vp.lps;
+ vp.lps->Init(extractCallback, true);
+
+
+ if (_needSeekToStart)
{
- case SZ_OK:
- opRes = NExtract::NOperationResult::kOK; break;
- case SZ_ERROR_UNSUPPORTED:
- opRes = NExtract::NOperationResult::kUnSupportedMethod; break;
- case SZ_ERROR_CRC:
- opRes = NExtract::NOperationResult::kCRCError; break;
- case SZ_ERROR_DATA:
- case SZ_ERROR_ARCHIVE:
- case SZ_ERROR_NO_ARCHIVE:
- opRes = NExtract::NOperationResult::kDataError; break;
- default:
- return SResToHRESULT(res);
+ if (!_stream)
+ return E_FAIL;
+ RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
}
+ else
+ _needSeekToStart = true;
+
+ RINOK(Decode2(_seqStream, realOutStream, vp));
+
+ Int32 opRes;
+
+ if (!vp.IsArc)
+ opRes = NExtract::NOperationResult::kIsNotArc;
+ else if (vp.UnexpectedEnd)
+ opRes = NExtract::NOperationResult::kUnexpectedEnd;
+ else if (vp.DataAfterEnd)
+ opRes = NExtract::NOperationResult::kDataAfterEnd;
+ else if (vp.CrcError)
+ opRes = NExtract::NOperationResult::kCRCError;
+ else if (vp.Unsupported)
+ opRes = NExtract::NOperationResult::kUnsupportedMethod;
+ else if (vp.HeadersError)
+ opRes = NExtract::NOperationResult::kDataError;
+ else if (vp.DataError)
+ opRes = NExtract::NOperationResult::kDataError;
+ else if (vp.DecodeRes != SZ_OK)
+ opRes = NExtract::NOperationResult::kDataError;
+ else
+ opRes = NExtract::NOperationResult::kOK;
+
realOutStream.Release();
- RINOK(extractCallback->SetOperationResult(opRes));
- return S_OK;
+ return extractCallback->SetOperationResult(opRes);
COM_TRY_END
}
@@ -590,13 +809,13 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
IArchiveUpdateCallback *updateCallback)
{
CSeqOutStreamWrap seqOutStream(outStream);
-
+
if (numItems == 0)
{
SRes res = Xz_EncodeEmpty(&seqOutStream.p);
return SResToHRESULT(res);
}
-
+
if (numItems != 1)
return E_INVALIDARG;
@@ -619,8 +838,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (IntToBool(newData))
{
+ UInt64 size;
{
- UInt64 size;
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
if (prop.vt != VT_UI8)
@@ -632,24 +851,28 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CLzma2EncProps lzma2Props;
Lzma2EncProps_Init(&lzma2Props);
- lzma2Props.lzmaProps.level = _level;
+ lzma2Props.lzmaProps.level = GetLevel();
CMyComPtr<ISequentialInStream> fileInStream;
RINOK(updateCallback->GetStream(0, &fileInStream));
CSeqInStreamWrap seqInStream(fileInStream);
- for (int i = 0; i < _methods.Size(); i++)
+ {
+ NCOM::CPropVariant prop = (UInt64)size;
+ RINOK(NCompress::NLzma2::SetLzma2Prop(NCoderPropID::kReduceSize, prop, lzma2Props));
+ }
+
+ FOR_VECTOR (i, _methods)
{
COneMethodInfo &m = _methods[i];
- SetCompressionMethod2(m
+ SetGlobalLevelAndThreads(m
#ifndef _7ZIP_ST
, _numThreads
#endif
);
- if (m.IsLzma())
{
- for (int j = 0; j < m.Props.Size(); j++)
+ FOR_VECTOR (j, m.Props)
{
const CProp &prop = m.Props[j];
RINOK(NCompress::NLzma2::SetLzma2Prop(prop.Id, prop.Value, lzma2Props));
@@ -666,7 +889,40 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
lps->Init(updateCallback, true);
CCompressProgressWrap progressWrap(progress);
- SRes res = Xz_Encode(&seqOutStream.p, &seqInStream.p, &lzma2Props, False, &progressWrap.p);
+ CXzProps xzProps;
+ CXzFilterProps filter;
+ XzProps_Init(&xzProps);
+ XzFilterProps_Init(&filter);
+ xzProps.lzma2Props = &lzma2Props;
+ xzProps.filterProps = (_filterId != 0 ? &filter : NULL);
+ switch (_crcSize)
+ {
+ case 0: xzProps.checkId = XZ_CHECK_NO; break;
+ case 4: xzProps.checkId = XZ_CHECK_CRC32; break;
+ case 8: xzProps.checkId = XZ_CHECK_CRC64; break;
+ case 32: xzProps.checkId = XZ_CHECK_SHA256; break;
+ default: return E_INVALIDARG;
+ }
+ filter.id = _filterId;
+ if (_filterId == XZ_ID_Delta)
+ {
+ bool deltaDefined = false;
+ FOR_VECTOR (j, _filterMethod.Props)
+ {
+ const CProp &prop = _filterMethod.Props[j];
+ if (prop.Id == NCoderPropID::kDefaultProp && prop.Value.vt == VT_UI4)
+ {
+ UInt32 delta = (UInt32)prop.Value.ulVal;
+ if (delta < 1 || delta > 256)
+ return E_INVALIDARG;
+ filter.delta = delta;
+ deltaDefined = true;
+ }
+ }
+ if (!deltaDefined)
+ return E_INVALIDARG;
+ }
+ SRes res = Xz_Encode(&seqOutStream.p, &seqInStream.p, &xzProps, &progressWrap.p);
if (res == SZ_OK)
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
return SResToHRESULT(res);
@@ -674,33 +930,61 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (indexInArchive != 0)
return E_INVALIDARG;
if (_stream)
- RINOK(_stream->Seek(_startPosition, STREAM_SEEK_SET, NULL));
- return NCompress::CopyStream(_stream, outStream, 0);
+ RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
+ return NCompress::CopyStream(_stream, outStream, NULL);
}
-STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps)
{
COM_TRY_BEGIN
- BeforeSetProperty();
- for (int i = 0; i < numProps; i++)
+ Init();
+ for (UInt32 i = 0; i < numProps; i++)
{
RINOK(SetProperty(names[i], values[i]));
}
+
+ if (!_filterMethod.MethodName.IsEmpty())
+ {
+ unsigned k;
+ for (k = 0; k < ARRAY_SIZE(g_NamePairs); k++)
+ {
+ const CMethodNamePair &pair = g_NamePairs[k];
+ if (StringsAreEqualNoCase_Ascii(_filterMethod.MethodName, pair.Name))
+ {
+ _filterId = pair.Id;
+ break;
+ }
+ }
+ if (k == ARRAY_SIZE(g_NamePairs))
+ return E_INVALIDARG;
+ }
+
+ _methods.DeleteFrontal(GetNumEmptyMethods());
+ if (_methods.Size() > 1)
+ return E_INVALIDARG;
+ if (_methods.Size() == 1)
+ {
+ UString &methodName = _methods[0].MethodName;
+ if (methodName.IsEmpty())
+ methodName = k_LZMA2_Name;
+ else if (!methodName.IsEqualToNoCase(k_LZMA2_Name))
+ return E_INVALIDARG;
+ }
return S_OK;
COM_TRY_END
}
#endif
-static IInArchive *CreateArc() { return new NArchive::NXz::CHandler; }
-#ifndef EXTRACT_ONLY
-static IOutArchive *CreateArcOut() { return new NArchive::NXz::CHandler; }
-#else
-#define CreateArcOut 0
-#endif
+IMP_CreateArcIn
+IMP_CreateArcOut
static CArcInfo g_ArcInfo =
- { L"xz", L"xz txz", L"* .tar", 0xC, {0xFD, '7' , 'z', 'X', 'Z', '\0'}, 6, true, CreateArc, CreateArcOut };
+ { "xz", "xz txz", "* .tar", 0xC,
+ 6, { 0xFD, '7' , 'z', 'X', 'Z', 0 },
+ 0,
+ NArcInfoFlags::kKeepName,
+ REF_CreateArc_Pair };
REGISTER_ARC(xz)
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.cpp b/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.cpp
index 358f0b503..a15794e2a 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.cpp
@@ -12,14 +12,14 @@
#define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x)
-static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize)
+static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize) throw()
{
CCompressProgressWrap *p = (CCompressProgressWrap *)pp;
p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize));
return (SRes)p->Res;
}
-CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress)
+CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress) throw()
{
p.Progress = CompressProgress;
Progress = progress;
@@ -30,29 +30,31 @@ static const UInt32 kStreamStepSize = (UInt32)1 << 31;
SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes)
{
- switch(res)
+ switch (res)
{
case S_OK: return SZ_OK;
case E_OUTOFMEMORY: return SZ_ERROR_MEM;
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)
+static SRes MyRead(void *object, void *data, size_t *size) throw()
{
CSeqInStreamWrap *p = (CSeqInStreamWrap *)object;
UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
p->Res = (p->Stream->Read(data, curSize, &curSize));
*size = curSize;
+ p->Processed += curSize;
if (p->Res == S_OK)
return SZ_OK;
return HRESULT_To_SRes(p->Res, SZ_ERROR_READ);
}
-static size_t MyWrite(void *object, const void *data, size_t size)
+static size_t MyWrite(void *object, const void *data, size_t size) throw()
{
CSeqOutStreamWrap *p = (CSeqOutStreamWrap *)object;
if (p->Stream)
@@ -67,13 +69,14 @@ static size_t MyWrite(void *object, const void *data, size_t size)
return size;
}
-CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream)
+CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream) throw()
{
p.Read = MyRead;
Stream = stream;
+ Processed = 0;
}
-CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream)
+CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw()
{
p.Write = MyWrite;
Stream = stream;
@@ -81,7 +84,7 @@ CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream)
Processed = 0;
}
-HRESULT SResToHRESULT(SRes res)
+HRESULT SResToHRESULT(SRes res) throw()
{
switch(res)
{
@@ -90,11 +93,12 @@ HRESULT SResToHRESULT(SRes res)
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)
+static SRes InStreamWrap_Read(void *pp, void *data, size_t *size) throw()
{
CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;
UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
@@ -103,7 +107,7 @@ static SRes InStreamWrap_Read(void *pp, void *data, size_t *size)
return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
}
-static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin)
+static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw()
{
CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;
UInt32 moveMethod;
@@ -120,7 +124,7 @@ static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin)
return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
}
-CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream)
+CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw()
{
Stream = stream;
p.Read = InStreamWrap_Read;
@@ -131,13 +135,13 @@ CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream)
/* ---------- CByteInBufWrap ---------- */
-void CByteInBufWrap::Free()
+void CByteInBufWrap::Free() throw()
{
::MidFree(Buf);
Buf = 0;
}
-bool CByteInBufWrap::Alloc(UInt32 size)
+bool CByteInBufWrap::Alloc(UInt32 size) throw()
{
if (Buf == 0 || size != Size)
{
@@ -148,7 +152,7 @@ bool CByteInBufWrap::Alloc(UInt32 size)
return (Buf != 0);
}
-Byte CByteInBufWrap::ReadByteFromNewBlock()
+Byte CByteInBufWrap::ReadByteFromNewBlock() throw()
{
if (Res == S_OK)
{
@@ -164,7 +168,7 @@ Byte CByteInBufWrap::ReadByteFromNewBlock()
return 0;
}
-static Byte Wrap_ReadByte(void *pp)
+static Byte Wrap_ReadByte(void *pp) throw()
{
CByteInBufWrap *p = (CByteInBufWrap *)pp;
if (p->Cur != p->Lim)
@@ -180,13 +184,13 @@ CByteInBufWrap::CByteInBufWrap(): Buf(0)
/* ---------- CByteOutBufWrap ---------- */
-void CByteOutBufWrap::Free()
+void CByteOutBufWrap::Free() throw()
{
::MidFree(Buf);
Buf = 0;
}
-bool CByteOutBufWrap::Alloc(size_t size)
+bool CByteOutBufWrap::Alloc(size_t size) throw()
{
if (Buf == 0 || size != Size)
{
@@ -197,7 +201,7 @@ bool CByteOutBufWrap::Alloc(size_t size)
return (Buf != 0);
}
-HRESULT CByteOutBufWrap::Flush()
+HRESULT CByteOutBufWrap::Flush() throw()
{
if (Res == S_OK)
{
@@ -210,7 +214,7 @@ HRESULT CByteOutBufWrap::Flush()
return Res;
}
-static void Wrap_WriteByte(void *pp, Byte b)
+static void Wrap_WriteByte(void *pp, Byte b) throw()
{
CByteOutBufWrap *p = (CByteOutBufWrap *)pp;
Byte *dest = p->Cur;
@@ -220,7 +224,7 @@ static void Wrap_WriteByte(void *pp, Byte b)
p->Flush();
}
-CByteOutBufWrap::CByteOutBufWrap(): Buf(0)
+CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0)
{
p.Write = Wrap_WriteByte;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.h b/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.h
index 80a8a1b61..4fe7dea3e 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/CWrappers.h
@@ -11,7 +11,8 @@ struct CCompressProgressWrap
ICompressProgress p;
ICompressProgressInfo *Progress;
HRESULT Res;
- CCompressProgressWrap(ICompressProgressInfo *progress);
+
+ CCompressProgressWrap(ICompressProgressInfo *progress) throw();
};
struct CSeqInStreamWrap
@@ -19,7 +20,9 @@ struct CSeqInStreamWrap
ISeqInStream p;
ISequentialInStream *Stream;
HRESULT Res;
- CSeqInStreamWrap(ISequentialInStream *stream);
+ UInt64 Processed;
+
+ CSeqInStreamWrap(ISequentialInStream *stream) throw();
};
struct CSeekInStreamWrap
@@ -27,7 +30,8 @@ struct CSeekInStreamWrap
ISeekInStream p;
IInStream *Stream;
HRESULT Res;
- CSeekInStreamWrap(IInStream *stream);
+
+ CSeekInStreamWrap(IInStream *stream) throw();
};
struct CSeqOutStreamWrap
@@ -36,10 +40,11 @@ struct CSeqOutStreamWrap
ISequentialOutStream *Stream;
HRESULT Res;
UInt64 Processed;
- CSeqOutStreamWrap(ISequentialOutStream *stream);
+
+ CSeqOutStreamWrap(ISequentialOutStream *stream) throw();
};
-HRESULT SResToHRESULT(SRes res);
+HRESULT SResToHRESULT(SRes res) throw();
struct CByteInBufWrap
{
@@ -52,11 +57,11 @@ struct CByteInBufWrap
UInt64 Processed;
bool Extra;
HRESULT Res;
-
+
CByteInBufWrap();
- ~CByteInBufWrap() { Free(); }
- void Free();
- bool Alloc(UInt32 size);
+ ~CByteInBufWrap() { Free(); }
+ void Free() throw();
+ bool Alloc(UInt32 size) throw();
void Init()
{
Lim = Cur = Buf;
@@ -65,7 +70,7 @@ struct CByteInBufWrap
Res = S_OK;
}
UInt64 GetProcessed() const { return Processed + (Cur - Buf); }
- Byte ReadByteFromNewBlock();
+ Byte ReadByteFromNewBlock() throw();
Byte ReadByte()
{
if (Cur != Lim)
@@ -84,11 +89,11 @@ struct CByteOutBufWrap
ISequentialOutStream *Stream;
UInt64 Processed;
HRESULT Res;
-
- CByteOutBufWrap();
- ~CByteOutBufWrap() { Free(); }
- void Free();
- bool Alloc(size_t size);
+
+ CByteOutBufWrap() throw();
+ ~CByteOutBufWrap() { Free(); }
+ void Free() throw();
+ bool Alloc(size_t size) throw();
void Init()
{
Cur = Buf;
@@ -97,7 +102,7 @@ struct CByteOutBufWrap
Res = S_OK;
}
UInt64 GetProcessed() const { return Processed + (Cur - Buf); }
- HRESULT Flush();
+ HRESULT Flush() throw();
void WriteByte(Byte b)
{
*Cur++ = b;
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/Common.pri b/src/libs/7zip/unix/CPP/7zip/Common/Common.pri
new file mode 100644
index 000000000..a23ad30b1
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Common/Common.pri
@@ -0,0 +1,39 @@
+HEADERS += $$7ZIP_BASE/CPP/7zip/Common/CWrappers.h \
+ $$7ZIP_BASE/CPP/7zip/Common/CreateCoder.h \
+ $$7ZIP_BASE/CPP/7zip/Common/FilePathAutoRename.h \
+ $$7ZIP_BASE/CPP/7zip/Common/FileStreams.h \
+ $$7ZIP_BASE/CPP/7zip/Common/FilterCoder.h \
+ $$7ZIP_BASE/CPP/7zip/Common/InBuffer.h \
+ $$7ZIP_BASE/CPP/7zip/Common/InOutTempBuffer.h \
+ $$7ZIP_BASE/CPP/7zip/Common/LimitedStreams.h \
+ $$7ZIP_BASE/CPP/7zip/Common/LockedStream.h \
+ $$7ZIP_BASE/CPP/7zip/Common/MethodId.h \
+ $$7ZIP_BASE/CPP/7zip/Common/MethodProps.h \
+ $$7ZIP_BASE/CPP/7zip/Common/OutBuffer.h \
+ $$7ZIP_BASE/CPP/7zip/Common/ProgressUtils.h \
+ $$7ZIP_BASE/CPP/7zip/Common/RegisterArc.h \
+ $$7ZIP_BASE/CPP/7zip/Common/RegisterCodec.h \
+ $$7ZIP_BASE/CPP/7zip/Common/StreamBinder.h \
+ $$7ZIP_BASE/CPP/7zip/Common/StreamObjects.h \
+ $$7ZIP_BASE/CPP/7zip/Common/StreamUtils.h \
+ $$7ZIP_BASE/CPP/7zip/Common/UniqBlocks.h \
+ $$7ZIP_BASE/CPP/7zip/Common/VirtThread.h
+
+SOURCES += $$7ZIP_BASE/CPP/7zip/Common/CWrappers.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/CreateCoder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/FilePathAutoRename.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/FileStreams.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/FilterCoder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/InBuffer.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/InOutTempBuffer.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/LimitedStreams.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/LockedStream.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/MethodProps.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/OutBuffer.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/ProgressUtils.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/PropId.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/StreamBinder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/StreamObjects.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/StreamUtils.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/UniqBlocks.cpp \
+ $$7ZIP_BASE/CPP/7zip/Common/VirtThread.cpp
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp b/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp
index cc82a0db5..01ccbe12a 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.cpp
@@ -13,12 +13,21 @@
static const unsigned int kNumCodecsMax = 64;
unsigned int g_NumCodecs = 0;
const CCodecInfo *g_Codecs[kNumCodecsMax];
-void RegisterCodec(const CCodecInfo *codecInfo)
+void RegisterCodec(const CCodecInfo *codecInfo) throw()
{
if (g_NumCodecs < kNumCodecsMax)
g_Codecs[g_NumCodecs++] = codecInfo;
}
+static const unsigned int kNumHashersMax = 16;
+unsigned int g_NumHashers = 0;
+const CHasherInfo *g_Hashers[kNumHashersMax];
+void RegisterHasher(const CHasherInfo *hashInfo) throw()
+{
+ if (g_NumHashers < kNumHashersMax)
+ g_Hashers[g_NumHashers++] = hashInfo;
+}
+
#ifdef EXTERNAL_CODECS
static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res)
{
@@ -46,56 +55,74 @@ static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index,
return S_OK;
}
-HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs)
+HRESULT CExternalCodecs::LoadCodecs()
{
- UInt32 num;
- RINOK(codecsInfo->GetNumberOfMethods(&num));
- for (UInt32 i = 0; i < num; i++)
+ if (GetCodecs)
{
- CCodecInfoEx info;
- NWindows::NCOM::CPropVariant prop;
- RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop));
- // if (prop.vt != VT_BSTR)
- // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);
- // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize);
- if (prop.vt != VT_UI8)
+ UInt32 num;
+ RINOK(GetCodecs->GetNumberOfMethods(&num));
+ for (UInt32 i = 0; i < num; i++)
{
- continue; // old Interface
- // return E_INVALIDARG;
+ CCodecInfoEx info;
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(GetCodecs->GetProperty(i, NMethodPropID::kID, &prop));
+ // if (prop.vt != VT_BSTR)
+ // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);
+ // memcpy(info.Id.ID, prop.bstrVal, info.Id.IDSize);
+ if (prop.vt != VT_UI8)
+ continue; // old Interface
+ info.Id = prop.uhVal.QuadPart;
+ prop.Clear();
+
+ RINOK(GetCodecs->GetProperty(i, NMethodPropID::kName, &prop));
+ if (prop.vt == VT_BSTR)
+ info.Name = prop.bstrVal;
+ else if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+
+ RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kInStreams, info.NumInStreams));
+ RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kOutStreams, info.NumOutStreams));
+ RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
+ RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
+
+ Codecs.Add(info);
+ }
+ }
+ if (GetHashers)
+ {
+ UInt32 num = GetHashers->GetNumHashers();
+ for (UInt32 i = 0; i < num; i++)
+ {
+ CHasherInfoEx info;
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kID, &prop));
+ if (prop.vt != VT_UI8)
+ continue;
+ info.Id = prop.uhVal.QuadPart;
+ prop.Clear();
+
+ RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kName, &prop));
+ if (prop.vt == VT_BSTR)
+ info.Name = prop.bstrVal;
+ else if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+
+ Hashers.Add(info);
}
- info.Id = prop.uhVal.QuadPart;
- prop.Clear();
-
- RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop));
- if (prop.vt == VT_BSTR)
- info.Name = prop.bstrVal;
- else if (prop.vt != VT_EMPTY)
- return E_INVALIDARG;;
-
- RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams));
- RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams));
- RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
- RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
-
- externalCodecs.Add(info);
}
return S_OK;
}
#endif
-bool FindMethod(
- #ifdef EXTERNAL_CODECS
- ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
- #endif
- const UString &name,
- CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)
+bool FindMethod(DECL_EXTERNAL_CODECS_LOC_VARS
+ const UString &name, CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)
{
UInt32 i;
for (i = 0; i < g_NumCodecs; i++)
{
const CCodecInfo &codec = *g_Codecs[i];
- if (name.CompareNoCase(codec.Name) == 0)
+ if (name.IsEqualToNoCase(codec.Name))
{
methodId = codec.Id;
numInStreams = codec.NumInStreams;
@@ -104,11 +131,11 @@ bool FindMethod(
}
}
#ifdef EXTERNAL_CODECS
- if (externalCodecs)
- for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+ if (__externalCodecs)
+ for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++)
{
- const CCodecInfoEx &codec = (*externalCodecs)[i];
- if (codec.Name.CompareNoCase(name) == 0)
+ const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
+ if (codec.Name.IsEqualToNoCase(name))
{
methodId = codec.Id;
numInStreams = codec.NumInStreams;
@@ -120,11 +147,8 @@ bool FindMethod(
return false;
}
-bool FindMethod(
- #ifdef EXTERNAL_CODECS
- ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
- #endif
- CMethodId methodId, UString &name)
+bool FindMethod(DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, UString &name)
{
UInt32 i;
for (i = 0; i < g_NumCodecs; i++)
@@ -137,10 +161,10 @@ bool FindMethod(
}
}
#ifdef EXTERNAL_CODECS
- if (externalCodecs)
- for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+ if (__externalCodecs)
+ for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++)
{
- const CCodecInfoEx &codec = (*externalCodecs)[i];
+ const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
if (methodId == codec.Id)
{
name = codec.Name;
@@ -151,6 +175,49 @@ bool FindMethod(
return false;
}
+bool FindHashMethod(DECL_EXTERNAL_CODECS_LOC_VARS
+ const UString &name,
+ CMethodId &methodId)
+{
+ UInt32 i;
+ for (i = 0; i < g_NumHashers; i++)
+ {
+ const CHasherInfo &codec = *g_Hashers[i];
+ if (name.IsEqualToNoCase(codec.Name))
+ {
+ methodId = codec.Id;
+ return true;
+ }
+ }
+ #ifdef EXTERNAL_CODECS
+ if (__externalCodecs)
+ for (i = 0; i < (UInt32)__externalCodecs->Hashers.Size(); i++)
+ {
+ const CHasherInfoEx &codec = __externalCodecs->Hashers[i];
+ if (codec.Name.IsEqualToNoCase(name))
+ {
+ methodId = codec.Id;
+ return true;
+ }
+ }
+ #endif
+ return false;
+}
+
+void GetHashMethods(DECL_EXTERNAL_CODECS_LOC_VARS
+ CRecordVector<CMethodId> &methods)
+{
+ methods.ClearAndSetSize(g_NumHashers);
+ UInt32 i;
+ for (i = 0; i < g_NumHashers; i++)
+ methods[i] = (*g_Hashers[i]).Id;
+ #ifdef EXTERNAL_CODECS
+ if (__externalCodecs)
+ for (i = 0; i < (UInt32)__externalCodecs->Hashers.Size(); i++)
+ methods.Add(__externalCodecs->Hashers[i].Id);
+ #endif
+}
+
HRESULT CreateCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId,
@@ -159,7 +226,6 @@ HRESULT CreateCoder(
CMyComPtr<ICompressCoder2> &coder2,
bool encode, bool onlyCoder)
{
- bool created = false;
UInt32 i;
for (i = 0; i < g_NumCodecs; i++)
{
@@ -174,7 +240,6 @@ HRESULT CreateCoder(
if (codec.IsFilter) filter = (ICompressFilter *)p;
else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
else coder2 = (ICompressCoder2 *)p;
- created = (p != 0);
break;
}
}
@@ -185,17 +250,16 @@ HRESULT CreateCoder(
if (codec.IsFilter) filter = (ICompressFilter *)p;
else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
else coder2 = (ICompressCoder2 *)p;
- created = (p != 0);
break;
}
}
}
#ifdef EXTERNAL_CODECS
- if (!created && externalCodecs)
- for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+ if (!filter && !coder && !coder2 && __externalCodecs)
+ for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++)
{
- const CCodecInfoEx &codec = (*externalCodecs)[i];
+ const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
if (codec.Id == methodId)
{
if (encode)
@@ -204,17 +268,17 @@ HRESULT CreateCoder(
{
if (codec.IsSimpleCodec())
{
- HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);
+ HRESULT result = __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);
if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
return result;
if (!coder)
{
- RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));
+ RINOK(__externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));
}
}
else
{
- RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));
+ RINOK(__externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));
}
break;
}
@@ -224,17 +288,17 @@ HRESULT CreateCoder(
{
if (codec.IsSimpleCodec())
{
- HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);
+ HRESULT result = __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);
if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
return result;
if (!coder)
{
- RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));
+ RINOK(__externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));
}
}
else
{
- RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2));
+ RINOK(__externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2));
}
break;
}
@@ -291,3 +355,37 @@ HRESULT CreateFilter(
methodId,
filter, coder, coder2, encode, false);
}
+
+HRESULT CreateHasher(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ UString &name,
+ CMyComPtr<IHasher> &hasher)
+{
+ UInt32 i;
+ for (i = 0; i < g_NumHashers; i++)
+ {
+ const CHasherInfo &codec = *g_Hashers[i];
+ if (codec.Id == methodId)
+ {
+ hasher = (IHasher *)codec.CreateHasher();
+ name = codec.Name;
+ break;
+ }
+ }
+
+ #ifdef EXTERNAL_CODECS
+ if (!hasher && __externalCodecs)
+ for (i = 0; i < (UInt32)__externalCodecs->Hashers.Size(); i++)
+ {
+ const CHasherInfoEx &codec = __externalCodecs->Hashers[i];
+ if (codec.Id == methodId)
+ {
+ name = codec.Name;
+ return __externalCodecs->GetHashers->CreateHasher(i, &hasher);
+ }
+ }
+ #endif
+
+ return S_OK;
+}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.h b/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.h
index bf0e96a38..fe1f6ccfe 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/CreateCoder.h
@@ -19,27 +19,43 @@ struct CCodecInfoEx
UInt32 NumOutStreams;
bool EncoderIsAssigned;
bool DecoderIsAssigned;
+
bool IsSimpleCodec() const { return NumOutStreams == 1 && NumInStreams == 1; }
CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {}
};
-HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs);
+struct CHasherInfoEx
+{
+ UString Name;
+ CMethodId Id;
+};
#define PUBLIC_ISetCompressCodecsInfo public ISetCompressCodecsInfo,
#define QUERY_ENTRY_ISetCompressCodecsInfo MY_QUERYINTERFACE_ENTRY(ISetCompressCodecsInfo)
#define DECL_ISetCompressCodecsInfo STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo);
#define IMPL_ISetCompressCodecsInfo2(x) \
STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) { \
- COM_TRY_BEGIN _codecsInfo = compressCodecsInfo; return LoadExternalCodecs(_codecsInfo, _externalCodecs); COM_TRY_END }
+ COM_TRY_BEGIN __externalCodecs.GetCodecs = compressCodecsInfo; return __externalCodecs.LoadCodecs(); COM_TRY_END }
#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler)
-#define EXTERNAL_CODECS_VARS2 _codecsInfo, &_externalCodecs
+struct CExternalCodecs
+{
+ CMyComPtr<ICompressCodecsInfo> GetCodecs;
+ CMyComPtr<IHashers> GetHashers;
+
+ CObjectVector<CCodecInfoEx> Codecs;
+ CObjectVector<CHasherInfoEx> Hashers;
+
+ HRESULT LoadCodecs();
+};
+
+#define EXTERNAL_CODECS_VARS2 &__externalCodecs
-#define DECL_EXTERNAL_CODECS_VARS CMyComPtr<ICompressCodecsInfo> _codecsInfo; CObjectVector<CCodecInfoEx> _externalCodecs;
+#define DECL_EXTERNAL_CODECS_VARS CExternalCodecs __externalCodecs;
#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2,
-#define DECL_EXTERNAL_CODECS_LOC_VARS2 ICompressCodecsInfo *codecsInfo, const CObjectVector<CCodecInfoEx> *externalCodecs
-#define EXTERNAL_CODECS_LOC_VARS2 codecsInfo, externalCodecs
+#define DECL_EXTERNAL_CODECS_LOC_VARS2 const CExternalCodecs *__externalCodecs
+#define EXTERNAL_CODECS_LOC_VARS2 __externalCodecs
#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2,
#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2,
@@ -68,6 +84,13 @@ bool FindMethod(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, UString &name);
+bool FindHashMethod(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const UString &name, CMethodId &methodId);
+
+void GetHashMethods(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CRecordVector<CMethodId> &methods);
HRESULT CreateCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
@@ -95,4 +118,10 @@ HRESULT CreateFilter(
CMyComPtr<ICompressFilter> &filter,
bool encode);
+HRESULT CreateHasher(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ UString &name,
+ CMyComPtr<IHasher> &hacher);
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp b/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp
index 7d6e36f14..958360fac 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.cpp
@@ -2,19 +2,19 @@
#include "StdAfx.h"
-#include "Common/Defs.h"
-#include "Common/IntToString.h"
+#include "../../Common/Defs.h"
+#include "../../Common/IntToString.h"
-#include "Windows/FileFind.h"
+#include "../../Windows/FileFind.h"
#include "FilePathAutoRename.h"
using namespace NWindows;
-static bool MakeAutoName(const UString &name,
- const UString &extension, unsigned value, UString &path)
+static bool MakeAutoName(const FString &name,
+ const FString &extension, unsigned value, FString &path)
{
- wchar_t number[16];
+ FChar number[16];
ConvertUInt32ToString(value, number);
path = name;
path += number;
@@ -22,22 +22,22 @@ static bool MakeAutoName(const UString &name,
return NFile::NFind::DoesFileOrDirExist(path);
}
-bool AutoRenamePath(UString &fullProcessedPath)
+bool AutoRenamePath(FString &fullProcessedPath)
{
- UString path;
- int dotPos = fullProcessedPath.ReverseFind(L'.');
+ FString path;
+ int dotPos = fullProcessedPath.ReverseFind(FTEXT('.'));
- int slashPos = fullProcessedPath.ReverseFind(L'/');
+ int slashPos = fullProcessedPath.ReverseFind(FTEXT('/'));
#ifdef _WIN32
- int slash1Pos = fullProcessedPath.ReverseFind(L'\\');
+ int slash1Pos = fullProcessedPath.ReverseFind(FTEXT('\\'));
slashPos = MyMax(slashPos, slash1Pos);
#endif
- UString name, extension;
+ FString name, extension;
if (dotPos > slashPos && dotPos > 0)
{
- name = fullProcessedPath.Left(dotPos);
- extension = fullProcessedPath.Mid(dotPos);
+ name.SetFrom(fullProcessedPath, dotPos);
+ extension = fullProcessedPath.Ptr(dotPos);
}
else
name = fullProcessedPath;
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h b/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h
index 3ef87f482..7b576591c 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/FilePathAutoRename.h
@@ -1,10 +1,10 @@
-// Util/FilePathAutoRename.h
+// FilePathAutoRename.h
-#ifndef __FILEPATHAUTORENAME_H
-#define __FILEPATHAUTORENAME_H
+#ifndef __FILE_PATH_AUTO_RENAME_H
+#define __FILE_PATH_AUTO_RENAME_H
-#include "Common/MyString.h"
+#include "../../Common/MyString.h"
-bool AutoRenamePath(UString &fullProcessedPath);
+bool AutoRenamePath(FString &fullProcessedPath);
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.cpp b/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.cpp
index 76ab5ee29..ee1cc54e2 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.cpp
@@ -8,6 +8,11 @@
#include <errno.h>
#endif
+#ifdef SUPPORT_DEVICE_FILE
+#include "../../../C/Alloc.h"
+#include "../../Common/Defs.h"
+#endif
+
#include "FileStreams.h"
static inline HRESULT ConvertBoolToHRESULT(bool result)
@@ -24,86 +29,175 @@ static inline HRESULT ConvertBoolToHRESULT(bool result)
#endif
}
-bool CInFileStream::Open(LPCTSTR fileName)
-{
-#ifdef ENV_UNIX
- return File.Open(fileName,_ignoreSymbolicLink);
-#else
- return File.Open(fileName);
-#endif
-}
+#ifdef SUPPORT_DEVICE_FILE
-#ifdef USE_WIN_FILE
-#ifndef _UNICODE
-bool CInFileStream::Open(LPCWSTR fileName)
+static const UInt32 kClusterSize = 1 << 18;
+CInFileStream::CInFileStream():
+ VirtPos(0),
+ PhyPos(0),
+ Buf(0),
+ BufSize(0),
+ SupportHardLinks(false)
{
-#ifdef ENV_UNIX
- return File.Open(fileName,_ignoreSymbolicLink);
-#else
- return File.Open(fileName);
-#endif
}
-#endif
-#endif
-bool CInFileStream::OpenShared(LPCTSTR fileName, bool shareForWrite)
-{
-#ifdef ENV_UNIX
- return File.Open(fileName,_ignoreSymbolicLink);
-#else
- return File.OpenShared(fileName, shareForWrite);
#endif
-}
-#ifdef USE_WIN_FILE
-#ifndef _UNICODE
-bool CInFileStream::OpenShared(LPCWSTR fileName, bool shareForWrite)
+CInFileStream::~CInFileStream()
{
- return File.OpenShared(fileName, shareForWrite);
+ #ifdef SUPPORT_DEVICE_FILE
+ MidFree(Buf);
+ #endif
}
-#endif
-#endif
STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
#ifdef USE_WIN_FILE
-
+
+ #ifdef SUPPORT_DEVICE_FILE
+ if (processedSize)
+ *processedSize = 0;
+ if (size == 0)
+ return S_OK;
+ if (File.IsDeviceFile)
+ {
+ if (File.SizeDefined)
+ {
+ if (VirtPos >= File.Size)
+ return VirtPos == File.Size ? S_OK : E_FAIL;
+ UInt64 rem = File.Size - VirtPos;
+ if (size > rem)
+ size = (UInt32)rem;
+ }
+ for (;;)
+ {
+ const UInt32 mask = kClusterSize - 1;
+ const UInt64 mask2 = ~(UInt64)mask;
+ UInt64 alignedPos = VirtPos & mask2;
+ if (BufSize > 0 && BufStartPos == alignedPos)
+ {
+ UInt32 pos = (UInt32)VirtPos & mask;
+ if (pos >= BufSize)
+ return S_OK;
+ UInt32 rem = MyMin(BufSize - pos, size);
+ memcpy(data, Buf + pos, rem);
+ VirtPos += rem;
+ if (processedSize)
+ *processedSize += rem;
+ return S_OK;
+ }
+
+ bool useBuf = false;
+ if ((VirtPos & mask) != 0 || ((ptrdiff_t)data & mask) != 0 )
+ useBuf = true;
+ else
+ {
+ UInt64 end = VirtPos + size;
+ if ((end & mask) != 0)
+ {
+ end &= mask2;
+ if (end <= VirtPos)
+ useBuf = true;
+ else
+ size = (UInt32)(end - VirtPos);
+ }
+ }
+ if (!useBuf)
+ break;
+ if (alignedPos != PhyPos)
+ {
+ UInt64 realNewPosition;
+ bool result = File.Seek(alignedPos, FILE_BEGIN, realNewPosition);
+ if (!result)
+ return ConvertBoolToHRESULT(result);
+ PhyPos = realNewPosition;
+ }
+
+ BufStartPos = alignedPos;
+ UInt32 readSize = kClusterSize;
+ if (File.SizeDefined)
+ readSize = (UInt32)MyMin(File.Size - PhyPos, (UInt64)kClusterSize);
+
+ if (!Buf)
+ {
+ Buf = (Byte *)MidAlloc(kClusterSize);
+ if (!Buf)
+ return E_OUTOFMEMORY;
+ }
+ bool result = File.Read1(Buf, readSize, BufSize);
+ if (!result)
+ return ConvertBoolToHRESULT(result);
+
+ if (BufSize == 0)
+ return S_OK;
+ PhyPos += BufSize;
+ }
+
+ if (VirtPos != PhyPos)
+ {
+ UInt64 realNewPosition;
+ bool result = File.Seek(VirtPos, FILE_BEGIN, realNewPosition);
+ if (!result)
+ return ConvertBoolToHRESULT(result);
+ PhyPos = VirtPos = realNewPosition;
+ }
+ }
+ #endif
+
UInt32 realProcessedSize;
bool result = File.ReadPart(data, size, realProcessedSize);
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
+ #ifdef SUPPORT_DEVICE_FILE
+ VirtPos += realProcessedSize;
+ PhyPos += realProcessedSize;
+ #endif
return ConvertBoolToHRESULT(result);
-
+
#else
-
- if(processedSize != NULL)
+
+ if (processedSize)
*processedSize = 0;
ssize_t res = File.Read(data, (size_t)size);
if (res == -1)
return E_FAIL;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = (UInt32)res;
return S_OK;
#endif
}
-#ifndef _WIN32_WCE
+#ifdef UNDER_CE
+STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ size_t s2 = fread(data, 1, size, stdin);
+ int error = ferror(stdin);
+ if (processedSize)
+ *processedSize = s2;
+ if (s2 <= size && error == 0)
+ return S_OK;
+ return E_FAIL;
+}
+#else
STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
#ifdef _WIN32
- UInt32 realProcessedSize;
- BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE),
- data, size, (DWORD *)&realProcessedSize, NULL);
- if(processedSize != NULL)
+
+ DWORD realProcessedSize;
+ UInt32 sizeTemp = (1 << 20);
+ if (sizeTemp > size)
+ sizeTemp = size;
+ BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL);
+ if (processedSize)
*processedSize = realProcessedSize;
if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
return S_OK;
return ConvertBoolToHRESULT(res != FALSE);
-
+
#else
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
ssize_t res;
do
@@ -113,38 +207,61 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi
while (res < 0 && (errno == EINTR));
if (res == -1)
return E_FAIL;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = (UInt32)res;
return S_OK;
-
+
#endif
}
-
+
#endif
-STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
- UInt64 *newPosition)
+STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- if(seekOrigin >= 3)
+ if (seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
#ifdef USE_WIN_FILE
+ #ifdef SUPPORT_DEVICE_FILE
+ if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END))
+ {
+ switch (seekOrigin)
+ {
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += VirtPos; break;
+ case STREAM_SEEK_END: offset += File.Size; break;
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ VirtPos = offset;
+ if (newPosition)
+ *newPosition = offset;
+ return S_OK;
+ }
+ #endif
+
UInt64 realNewPosition;
bool result = File.Seek(offset, seekOrigin, realNewPosition);
- if(newPosition != NULL)
+
+ #ifdef SUPPORT_DEVICE_FILE
+ PhyPos = VirtPos = realNewPosition;
+ #endif
+
+ if (newPosition)
*newPosition = realNewPosition;
return ConvertBoolToHRESULT(result);
-
+
#else
-
- off_t res = File.Seek(offset, seekOrigin);
+
+ off_t res = File.Seek((off_t)offset, seekOrigin);
if (res == -1)
return E_FAIL;
- if(newPosition != NULL)
+ if (newPosition)
*newPosition = (UInt64)res;
return S_OK;
-
+
#endif
}
@@ -153,6 +270,43 @@ STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
return ConvertBoolToHRESULT(File.GetLength(*size));
}
+#if 0 // FIXME #ifdef USE_WIN_FILE
+
+STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ if (File.GetFileInformation(&info))
+ {
+ if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
+ if (cTime) *cTime = info.ftCreationTime;
+ if (aTime) *aTime = info.ftLastAccessTime;
+ if (mTime) *mTime = info.ftLastWriteTime;
+ if (attrib) *attrib = info.dwFileAttributes;
+ return S_OK;
+ }
+ return GetLastError();
+}
+
+STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ if (File.GetFileInformation(&info))
+ {
+ props->Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
+ props->VolID = info.dwVolumeSerialNumber;
+ props->FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
+ props->FileID_High = 0;
+ props->NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1;
+ props->Attrib = info.dwFileAttributes;
+ props->CTime = info.ftCreationTime;
+ props->ATime = info.ftLastAccessTime;
+ props->MTime = info.ftLastWriteTime;
+ return S_OK;
+ }
+ return GetLastError();
+}
+
+#endif
//////////////////////////
// COutFileStream
@@ -169,46 +323,46 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces
UInt32 realProcessedSize;
bool result = File.WritePart(data, size, realProcessedSize);
ProcessedSize += realProcessedSize;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
return ConvertBoolToHRESULT(result);
-
+
#else
-
- if(processedSize != NULL)
+
+ if (processedSize)
*processedSize = 0;
ssize_t res = File.Write(data, (size_t)size);
if (res == -1)
return E_FAIL;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = (UInt32)res;
ProcessedSize += res;
return S_OK;
-
+
#endif
}
-
+
STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- if(seekOrigin >= 3)
+ if (seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
#ifdef USE_WIN_FILE
UInt64 realNewPosition;
bool result = File.Seek(offset, seekOrigin, realNewPosition);
- if(newPosition != NULL)
+ if (newPosition)
*newPosition = realNewPosition;
return ConvertBoolToHRESULT(result);
-
+
#else
-
- off_t res = File.Seek(offset, seekOrigin);
+
+ off_t res = File.Seek((off_t)offset, seekOrigin);
if (res == -1)
return E_FAIL;
- if(newPosition != NULL)
+ if (newPosition)
*newPosition = (UInt64)res;
return S_OK;
-
+
#endif
}
@@ -216,7 +370,7 @@ STDMETHODIMP COutFileStream::SetSize(UInt64 newSize)
{
#ifdef USE_WIN_FILE
UInt64 currentPos;
- if(!File.Seek(0, FILE_CURRENT, currentPos))
+ if (!File.Seek(0, FILE_CURRENT, currentPos))
return E_FAIL;
bool result = File.SetLength(newSize);
UInt64 currentPos2;
@@ -227,10 +381,18 @@ STDMETHODIMP COutFileStream::SetSize(UInt64 newSize)
#endif
}
-#ifndef _WIN32_WCE
+#ifdef UNDER_CE
+STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ size_t s2 = fwrite(data, 1, size, stdout);
+ if (processedSize)
+ *processedSize = s2;
+ return (s2 == size) ? S_OK : E_FAIL;
+}
+#else
STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
#ifdef _WIN32
@@ -247,13 +409,13 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
size -= realProcessedSize;
data = (const void *)((const Byte *)data + realProcessedSize);
- if(processedSize != NULL)
+ if (processedSize)
*processedSize += realProcessedSize;
}
return ConvertBoolToHRESULT(res != FALSE);
#else
-
+
ssize_t res;
do
{
@@ -262,12 +424,12 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
while (res < 0 && (errno == EINTR));
if (res == -1)
return E_FAIL;
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = (UInt32)res;
return S_OK;
-
+
return S_OK;
#endif
}
-
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.h b/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.h
index f70905b56..a80cbad4d 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/FileStreams.h
@@ -1,12 +1,14 @@
// FileStreams.h
-#ifndef __FILESTREAMS_H
-#define __FILESTREAMS_H
+#ifndef __FILE_STREAMS_H
+#define __FILE_STREAMS_H
#if defined(_WIN32) || defined(ENV_UNIX)
#define USE_WIN_FILE
#endif
+#include "../../Common/MyString.h"
+
#ifdef USE_WIN_FILE
#include "../../Windows/FileIO.h"
#else
@@ -14,43 +16,67 @@
#endif
#include "../../Common/MyCom.h"
+
#include "../IStream.h"
class CInFileStream:
public IInStream,
public IStreamGetSize,
+ #if 0 // #ifdef USE_WIN_FILE
+ public IStreamGetProps,
+ public IStreamGetProps2,
+ #endif
public CMyUnknownImp
{
bool _ignoreSymbolicLink;
public:
#ifdef USE_WIN_FILE
NWindows::NFile::NIO::CInFile File;
+
+ #ifdef SUPPORT_DEVICE_FILE
+ UInt64 VirtPos;
+ UInt64 PhyPos;
+ UInt64 BufStartPos;
+ Byte *Buf;
+ UInt32 BufSize;
+ #endif
+
#else
NC::NFile::NIO::CInFile File;
#endif
+
+ bool SupportHardLinks;
+
CInFileStream(bool b=false) { _ignoreSymbolicLink = b; }
- virtual ~CInFileStream() {}
+ virtual ~CInFileStream();
- bool Open(LPCTSTR fileName);
- #ifdef USE_WIN_FILE
- #ifndef _UNICODE
- bool Open(LPCWSTR fileName);
- #endif
- #endif
+ bool Open(CFSTR fileName)
+ {
+ return File.Open(fileName,_ignoreSymbolicLink);
+ }
- bool OpenShared(LPCTSTR fileName, bool shareForWrite);
- #ifdef USE_WIN_FILE
- #ifndef _UNICODE
- bool OpenShared(LPCWSTR fileName, bool shareForWrite);
- #endif
- #endif
+ bool OpenShared(CFSTR fileName , bool /* shareForWrite */ )
+ {
+ return File.Open(fileName,_ignoreSymbolicLink);
+ }
- MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
+ MY_QUERYINTERFACE_BEGIN2(IInStream)
+ MY_QUERYINTERFACE_ENTRY(IStreamGetSize)
+ #if 0 // #ifdef USE_WIN_FILE
+ MY_QUERYINTERFACE_ENTRY(IStreamGetProps)
+ MY_QUERYINTERFACE_ENTRY(IStreamGetProps2)
+ #endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
STDMETHOD(GetSize)(UInt64 *size);
+ #if 0 // #ifdef USE_WIN_FILE
+ STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib);
+ STDMETHOD(GetProps2)(CStreamFileProps *props);
+ #endif
};
class CStdInFileStream:
@@ -68,40 +94,26 @@ class COutFileStream:
public IOutStream,
public CMyUnknownImp
{
+public:
#ifdef USE_WIN_FILE
NWindows::NFile::NIO::COutFile File;
#else
NC::NFile::NIO::COutFile File;
#endif
-public:
virtual ~COutFileStream() {}
- bool Create(LPCTSTR fileName, bool createAlways)
+ bool Create(CFSTR fileName, bool createAlways)
{
ProcessedSize = 0;
return File.Create(fileName, createAlways);
}
- bool Open(LPCTSTR fileName, DWORD creationDisposition)
+ bool Open(CFSTR fileName, DWORD creationDisposition)
{
ProcessedSize = 0;
return File.Open(fileName, creationDisposition);
}
- #ifdef USE_WIN_FILE
- #ifndef _UNICODE
- bool Create(LPCWSTR fileName, bool createAlways)
- {
- ProcessedSize = 0;
- return File.Create(fileName, createAlways);
- }
- bool Open(LPCWSTR fileName, DWORD creationDisposition)
- {
- ProcessedSize = 0;
- return File.Open(fileName, creationDisposition);
- }
- #endif
- #endif
HRESULT Close();
-
+
UInt64 ProcessedSize;
#ifdef USE_WIN_FILE
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.cpp b/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.cpp
index 696735278..3a2023b35 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.cpp
@@ -48,10 +48,10 @@ STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStr
while (!_outSizeIsDefined || _nowPos64 < _outSize)
{
size_t processedSize = kBufferSize - bufferPos;
-
+
// Change it: It can be optimized using ReadPart
RINOK(ReadStream(inStream, _buffer + bufferPos, &processedSize));
-
+
UInt32 endPos = bufferPos + (UInt32)processedSize;
bufferPos = Filter->Filter(_buffer, endPos);
@@ -153,10 +153,16 @@ STDMETHODIMP CFilterCoder::Flush()
}
-STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
+void CFilterCoder::SetInStream_NoSubFilterInit(ISequentialInStream *inStream)
{
_convertedPosBegin = _convertedPosEnd = _bufferPos = 0;
_inStream = inStream;
+ Init2();
+}
+
+STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
+{
+ SetInStream_NoSubFilterInit(inStream);
return Init();
}
@@ -210,10 +216,22 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
}
#ifndef _NO_CRYPTO
+
STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)
{
return _setPassword->CryptoSetPassword(data, size);
}
+
+STDMETHODIMP CFilterCoder::SetKey(const Byte *data, UInt32 size)
+{
+ return _cryptoProperties->SetKey(data, size);
+}
+
+STDMETHODIMP CFilterCoder::SetInitVector(const Byte *data, UInt32 size)
+{
+ return _cryptoProperties->SetInitVector(data, size);
+}
+
#endif
#ifndef EXTRACT_ONLY
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.h b/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.h
index 8132a6dd7..2b8f142f5 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/FilterCoder.h
@@ -7,9 +7,9 @@
#include "../ICoder.h"
#include "../IPassword.h"
-#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \
-{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
-*outObject = (void *)(i *)this; AddRef(); return S_OK; }
+#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) else if (iid == IID_ ## i) \
+ { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
+ *outObject = (void *)(i *)this; }
class CFilterCoder:
public ICompressCoder,
@@ -21,6 +21,7 @@ class CFilterCoder:
#ifndef _NO_CRYPTO
public ICryptoSetPassword,
+ public ICryptoProperties,
#endif
#ifndef EXTRACT_ONLY
public ICompressSetCoderProperties,
@@ -42,14 +43,20 @@ protected:
UInt64 _outSize;
UInt64 _nowPos64;
- HRESULT Init()
+ void Init2()
{
_nowPos64 = 0;
_outSizeIsDefined = false;
+ }
+
+ HRESULT Init()
+ {
+ Init2();
return Filter->Init();
}
CMyComPtr<ICryptoSetPassword> _setPassword;
+ CMyComPtr<ICryptoProperties> _cryptoProperties;
#ifndef EXTRACT_ONLY
CMyComPtr<ICompressSetCoderProperties> _SetCoderProperties;
CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties;
@@ -74,6 +81,7 @@ public:
#ifndef _NO_CRYPTO
MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword)
+ MY_QUERYINTERFACE_ENTRY_AG(ICryptoProperties, Filter, _cryptoProperties)
#endif
#ifndef EXTRACT_ONLY
@@ -98,6 +106,9 @@ public:
#ifndef _NO_CRYPTO
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size);
+ STDMETHOD(SetInitVector)(const Byte *data, UInt32 size);
#endif
#ifndef EXTRACT_ONLY
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
@@ -107,6 +118,9 @@ public:
STDMETHOD(ResetInitVector)();
#endif
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+
+ void SetInStream_NoSubFilterInit(ISequentialInStream *inStream);
+
};
class CInStreamReleaser
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.cpp b/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.cpp
index ad4f8825e..133d95b38 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.cpp
@@ -6,50 +6,49 @@
#include "InBuffer.h"
-CInBuffer::CInBuffer():
- _buffer(0),
- _bufferLimit(0),
- _bufferBase(0),
+CInBufferBase::CInBufferBase() throw():
+ _buf(0),
+ _bufLim(0),
+ _bufBase(0),
_stream(0),
- _bufferSize(0)
+ _processedSize(0),
+ _bufSize(0),
+ _wasFinished(false),
+ NumExtraBytes(0)
{}
-bool CInBuffer::Create(UInt32 bufferSize)
+bool CInBuffer::Create(size_t bufSize) throw()
{
- const UInt32 kMinBlockSize = 1;
- if (bufferSize < kMinBlockSize)
- bufferSize = kMinBlockSize;
- if (_bufferBase != 0 && _bufferSize == bufferSize)
+ const unsigned kMinBlockSize = 1;
+ if (bufSize < kMinBlockSize)
+ bufSize = kMinBlockSize;
+ if (_bufBase != 0 && _bufSize == bufSize)
return true;
Free();
- _bufferSize = bufferSize;
- _bufferBase = (Byte *)::MidAlloc(bufferSize);
- return (_bufferBase != 0);
+ _bufSize = bufSize;
+ _bufBase = (Byte *)::MidAlloc(bufSize);
+ return (_bufBase != 0);
}
-void CInBuffer::Free()
+void CInBuffer::Free() throw()
{
- ::MidFree(_bufferBase);
- _bufferBase = 0;
+ ::MidFree(_bufBase);
+ _bufBase = 0;
}
-void CInBuffer::SetStream(ISequentialInStream *stream)
-{
- _stream = stream;
-}
-
-void CInBuffer::Init()
+void CInBufferBase::Init() throw()
{
_processedSize = 0;
- _buffer = _bufferBase;
- _bufferLimit = _buffer;
+ _buf = _bufBase;
+ _bufLim = _buf;
_wasFinished = false;
#ifdef _NO_EXCEPTIONS
ErrorCode = S_OK;
#endif
+ NumExtraBytes = 0;
}
-bool CInBuffer::ReadBlock()
+bool CInBufferBase::ReadBlock()
{
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
@@ -57,27 +56,80 @@ bool CInBuffer::ReadBlock()
#endif
if (_wasFinished)
return false;
- _processedSize += (_buffer - _bufferBase);
- UInt32 numProcessedBytes;
- HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
+ _processedSize += (_buf - _bufBase);
+ _buf = _bufBase;
+ _bufLim = _bufBase;
+ UInt32 processed;
+ // FIX_ME: we can improve it to support (_bufSize >= (1 << 32))
+ HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed);
#ifdef _NO_EXCEPTIONS
ErrorCode = result;
#else
if (result != S_OK)
throw CInBufferException(result);
#endif
- _buffer = _bufferBase;
- _bufferLimit = _buffer + numProcessedBytes;
- _wasFinished = (numProcessedBytes == 0);
- return (!_wasFinished);
+ _bufLim = _buf + processed;
+ _wasFinished = (processed == 0);
+ return !_wasFinished;
}
-Byte CInBuffer::ReadBlock2()
+bool CInBufferBase::ReadByte_FromNewBlock(Byte &b)
{
if (!ReadBlock())
{
- _processedSize++;
+ NumExtraBytes++;
+ b = 0xFF;
+ return false;
+ }
+ b = *_buf++;
+ return true;
+}
+
+Byte CInBufferBase::ReadByte_FromNewBlock()
+{
+ if (!ReadBlock())
+ {
+ NumExtraBytes++;
return 0xFF;
}
- return *_buffer++;
+ return *_buf++;
+}
+
+size_t CInBufferBase::ReadBytes(Byte *buf, size_t size)
+{
+ if ((size_t)(_bufLim - _buf) >= size)
+ {
+ const Byte *src = _buf;
+ for (size_t i = 0; i < size; i++)
+ buf[i] = src[i];
+ _buf += size;
+ return size;
+ }
+ for (size_t i = 0; i < size; i++)
+ {
+ if (_buf >= _bufLim)
+ if (!ReadBlock())
+ return i;
+ buf[i] = *_buf++;
+ }
+ return size;
+}
+
+size_t CInBufferBase::Skip(size_t size)
+{
+ size_t processed = 0;
+ for (;;)
+ {
+ size_t rem = (_bufLim - _buf);
+ if (rem >= size)
+ {
+ _buf += size;
+ return processed + size;
+ }
+ _buf += rem;
+ processed += rem;
+ size -= rem;
+ if (!ReadBlock())
+ return processed;
+ }
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.h b/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.h
index 75625bfd9..dd3c66808 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/InBuffer.h
@@ -1,11 +1,10 @@
// InBuffer.h
-#ifndef __INBUFFER_H
-#define __INBUFFER_H
+#ifndef __IN_BUFFER_H
+#define __IN_BUFFER_H
-#include "../IStream.h"
-#include "../../Common/MyCom.h"
#include "../../Common/MyException.h"
+#include "../IStream.h"
#ifndef _NO_EXCEPTIONS
struct CInBufferException: public CSystemException
@@ -14,68 +13,78 @@ struct CInBufferException: public CSystemException
};
#endif
-class CInBuffer
+class CInBufferBase
{
- Byte *_buffer;
- Byte *_bufferLimit;
- Byte *_bufferBase;
- CMyComPtr<ISequentialInStream> _stream;
+protected:
+ Byte *_buf;
+ Byte *_bufLim;
+ Byte *_bufBase;
+
+ ISequentialInStream *_stream;
UInt64 _processedSize;
- UInt32 _bufferSize;
+ size_t _bufSize; // actually it's number of Bytes for next read. The buf can be larger
+ // only up to 32-bits values now are supported!
bool _wasFinished;
bool ReadBlock();
- Byte ReadBlock2();
+ bool ReadByte_FromNewBlock(Byte &b);
+ Byte ReadByte_FromNewBlock();
public:
#ifdef _NO_EXCEPTIONS
HRESULT ErrorCode;
#endif
+ UInt32 NumExtraBytes;
- CInBuffer();
- ~CInBuffer() { Free(); }
+ CInBufferBase() throw();
+
+ UInt64 GetStreamSize() const { return _processedSize + (_buf - _bufBase); }
+ UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (_buf - _bufBase); }
+ bool WasFinished() const { return _wasFinished; }
+
+ void SetStream(ISequentialInStream *stream) { _stream = stream; }
+
+ void SetBuf(Byte *buf, size_t bufSize, size_t end, size_t pos)
+ {
+ _bufBase = buf;
+ _bufSize = bufSize;
+ _processedSize = 0;
+ _buf = buf + pos;
+ _bufLim = buf + end;
+ _wasFinished = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+ NumExtraBytes = 0;
+ }
- bool Create(UInt32 bufferSize);
- void Free();
-
- void SetStream(ISequentialInStream *stream);
- void Init();
- void ReleaseStream() { _stream.Release(); }
+ void Init() throw();
bool ReadByte(Byte &b)
{
- if (_buffer >= _bufferLimit)
- if (!ReadBlock())
- return false;
- b = *_buffer++;
+ if (_buf >= _bufLim)
+ return ReadByte_FromNewBlock(b);
+ b = *_buf++;
return true;
}
+
Byte ReadByte()
{
- if (_buffer >= _bufferLimit)
- return ReadBlock2();
- return *_buffer++;
- }
- UInt32 ReadBytes(Byte *buf, UInt32 size)
- {
- if ((UInt32)(_bufferLimit - _buffer) >= size)
- {
- for (UInt32 i = 0; i < size; i++)
- buf[i] = _buffer[i];
- _buffer += size;
- return size;
- }
- for (UInt32 i = 0; i < size; i++)
- {
- if (_buffer >= _bufferLimit)
- if (!ReadBlock())
- return i;
- buf[i] = *_buffer++;
- }
- return size;
+ if (_buf >= _bufLim)
+ return ReadByte_FromNewBlock();
+ return *_buf++;
}
- UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
- bool WasFinished() const { return _wasFinished; }
+
+ size_t ReadBytes(Byte *buf, size_t size);
+ size_t Skip(size_t size);
+};
+
+class CInBuffer: public CInBufferBase
+{
+public:
+ ~CInBuffer() { Free(); }
+ bool Create(size_t bufSize) throw(); // only up to 32-bits values now are supported!
+ void Free() throw();
};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp b/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp
index dfe8b3d32..be65ba32f 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.cpp
@@ -4,16 +4,18 @@
#include "../../../C/7zCrc.h"
+#include "../../Common/Defs.h"
+
#include "InOutTempBuffer.h"
#include "StreamUtils.h"
using namespace NWindows;
using namespace NFile;
-using namespace NDirectory;
+using namespace NDir;
static const UInt32 kTempBufSize = (1 << 20);
-static LPCTSTR kTempFilePrefixString = TEXT("7zt");
+static CFSTR kTempFilePrefixString = FTEXT("7zt");
CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { }
@@ -42,12 +44,7 @@ bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
return true;
if (!_tempFileCreated)
{
- CSysString tempDirPath;
- if (!MyGetTempPath(tempDirPath))
- return false;
- if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tempFileName) == 0)
- return false;
- if (!_outFile.Create(_tempFileName, true))
+ if (!_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile))
return false;
_tempFileCreated = true;
}
@@ -91,7 +88,7 @@ HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
if (_tempFileCreated)
{
NIO::CInFile inFile;
- if (!inFile.Open(_tempFileName))
+ if (!inFile.Open(_tempFile.GetPath()))
return E_FAIL;
while (size < _size)
{
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h b/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h
index 073f95acf..256d72420 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/InOutTempBuffer.h
@@ -5,17 +5,15 @@
#include "../../Common/MyCom.h"
#include "../../Windows/FileDir.h"
-#include "../../Windows/FileIO.h"
#include "../IStream.h"
class CInOutTempBuffer
{
- NWindows::NFile::NDirectory::CTempFile _tempFile;
+ NWindows::NFile::NDir::CTempFile _tempFile;
NWindows::NFile::NIO::COutFile _outFile;
Byte *_buf;
UInt32 _bufPos;
- CSysString _tempFileName;
bool _tempFileCreated;
UInt64 _size;
UInt32 _crc;
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp b/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp
index 1837e3201..5f20dcda4 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.cpp
@@ -17,17 +17,21 @@ STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *p
if (realProcessedSize == 0)
_wasFinished = true;
}
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
return result;
}
STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
if (_virtPos >= _size)
- return (_virtPos == _size) ? S_OK: E_FAIL;
+ {
+ // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case.
+ return S_OK;
+ // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF
+ }
UInt64 rem = _size - _virtPos;
if (rem < size)
size = (UInt32)rem;
@@ -38,7 +42,7 @@ STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSi
RINOK(SeekToPhys());
}
HRESULT res = _stream->Read(data, size, &size);
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
_physPos += size;
_virtPos += size;
@@ -47,24 +51,39 @@ STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSi
STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET: _virtPos = offset; break;
- case STREAM_SEEK_CUR: _virtPos += offset; break;
- case STREAM_SEEK_END: _virtPos = _size + offset; break;
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END: offset += _size; break;
default: return STG_E_INVALIDFUNCTION;
}
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
if (newPosition)
*newPosition = _virtPos;
return S_OK;
}
+HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream)
+{
+ *resStream = 0;
+ CLimitedInStream *streamSpec = new CLimitedInStream;
+ CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
+ streamSpec->SetStream(inStream);
+ RINOK(streamSpec->InitAndSeek(pos, size));
+ streamSpec->SeekToStart();
+ *resStream = streamTemp.Detach();
+ return S_OK;
+}
+
STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
if (_virtPos >= Size)
- return (_virtPos == Size) ? S_OK: E_FAIL;
+ return S_OK;
if (_curRem == 0)
{
@@ -88,49 +107,98 @@ STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSi
if (size > _curRem)
size = _curRem;
HRESULT res = Stream->Read(data, size, &size);
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
_physPos += size;
_virtPos += size;
_curRem -= size;
return res;
}
-
+
STDMETHODIMP CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- UInt64 newVirtPos = offset;
- switch(seekOrigin)
+ switch (seekOrigin)
{
case STREAM_SEEK_SET: break;
- case STREAM_SEEK_CUR: newVirtPos += _virtPos; break;
- case STREAM_SEEK_END: newVirtPos += Size; break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END: offset += Size; break;
default: return STG_E_INVALIDFUNCTION;
}
- if (_virtPos != newVirtPos)
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ if (_virtPos != (UInt64)offset)
_curRem = 0;
- _virtPos = newVirtPos;
+ _virtPos = offset;
if (newPosition)
- *newPosition = newVirtPos;
+ *newPosition = offset;
return S_OK;
}
-HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream)
+STDMETHODIMP CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- *resStream = 0;
- CLimitedInStream *streamSpec = new CLimitedInStream;
- CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
- streamSpec->SetStream(inStream);
- RINOK(streamSpec->InitAndSeek(pos, size));
- streamSpec->SeekToStart();
- *resStream = streamTemp.Detach();
+ if (processedSize)
+ *processedSize = 0;
+ if (_virtPos >= Extents.Back().Virt)
+ return S_OK;
+ if (size == 0)
+ return S_OK;
+
+ unsigned left = 0, right = Extents.Size() - 1;
+ for (;;)
+ {
+ unsigned mid = (left + right) / 2;
+ if (mid == left)
+ break;
+ if (_virtPos < Extents[mid].Virt)
+ right = mid;
+ else
+ left = mid;
+ }
+
+ const CSeekExtent &extent = Extents[left];
+ UInt64 phyPos = extent.Phy + (_virtPos - extent.Virt);
+ if (_needStartSeek || _phyPos != phyPos)
+ {
+ _needStartSeek = false;
+ _phyPos = phyPos;
+ RINOK(SeekToPhys());
+ }
+
+ UInt64 rem = Extents[left + 1].Virt - _virtPos;
+ if (size > rem)
+ size = (UInt32)rem;
+
+ HRESULT res = Stream->Read(data, size, &size);
+ _phyPos += size;
+ _virtPos += size;
+ if (processedSize)
+ *processedSize = size;
+ return res;
+}
+
+STDMETHODIMP CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ switch (seekOrigin)
+ {
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END: offset += Extents.Back().Virt; break;
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
+ if (newPosition)
+ *newPosition = _virtPos;
return S_OK;
}
+
STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
HRESULT result = S_OK;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
if (size > _size)
{
@@ -139,7 +207,7 @@ STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, U
_overflow = true;
if (!_overflowIsAllowed)
return E_FAIL;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
return S_OK;
}
@@ -148,7 +216,134 @@ STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, U
if (_stream)
result = _stream->Write(data, size, &size);
_size -= size;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
return result;
}
+
+
+STDMETHODIMP CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 cur;
+ HRESULT res = Stream->Read(data, size, &cur);
+ if (processedSize)
+ *processedSize = cur;
+ _virtPos += cur;
+ return res;
+}
+
+STDMETHODIMP CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ switch (seekOrigin)
+ {
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END:
+ {
+ UInt64 pos = 0;
+ RINOK(Stream->Seek(offset, STREAM_SEEK_END, &pos));
+ if (pos < Offset)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = pos - Offset;
+ if (newPosition)
+ *newPosition = _virtPos;
+ return S_OK;
+ }
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
+ if (newPosition)
+ *newPosition = _virtPos;
+ return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL);
+}
+
+STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+ if (_virtPos >= _size)
+ {
+ // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case.
+ return S_OK;
+ // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF
+ }
+ UInt64 rem = _size - _virtPos;
+ if (rem < size)
+ size = (UInt32)rem;
+
+ UInt64 newPos = _startOffset + _virtPos;
+ UInt64 offsetInCache = newPos - _cachePhyPos;
+ HRESULT res = S_OK;
+ if (newPos >= _cachePhyPos &&
+ offsetInCache <= _cacheSize &&
+ size <= _cacheSize - (size_t)offsetInCache)
+ memcpy(data, _cache + (size_t)offsetInCache, size);
+ else
+ {
+ if (newPos != _physPos)
+ {
+ _physPos = newPos;
+ RINOK(SeekToPhys());
+ }
+ res = _stream->Read(data, size, &size);
+ _physPos += size;
+ }
+ if (processedSize)
+ *processedSize = size;
+ _virtPos += size;
+ return res;
+}
+
+STDMETHODIMP CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ switch (seekOrigin)
+ {
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END: offset += _size; break;
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
+ if (newPosition)
+ *newPosition = _virtPos;
+ return S_OK;
+}
+
+STDMETHODIMP CTailOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 cur;
+ HRESULT res = Stream->Write(data, size, &cur);
+ if (processedSize)
+ *processedSize = cur;
+ _virtPos += cur;
+ if (_virtSize < _virtPos)
+ _virtSize = _virtPos;
+ return res;
+}
+
+STDMETHODIMP CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ switch (seekOrigin)
+ {
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END: offset += _virtSize; break;
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = offset;
+ if (newPosition)
+ *newPosition = _virtPos;
+ return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL);
+}
+
+STDMETHODIMP CTailOutStream::SetSize(UInt64 newSize)
+{
+ _virtSize = newSize;
+ return Stream->SetSize(Offset + newSize);
+}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.h b/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.h
index 2cbe18e48..b14616f3b 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/LimitedStreams.h
@@ -3,6 +3,7 @@
#ifndef __LIMITED_STREAMS_H
#define __LIMITED_STREAMS_H
+#include "../../Common/MyBuffer.h"
#include "../../Common/MyCom.h"
#include "../../Common/MyVector.h"
#include "../IStream.h"
@@ -24,8 +25,8 @@ public:
_pos = 0;
_wasFinished = false;
}
-
- MY_UNKNOWN_IMP
+
+ MY_UNKNOWN_IMP1(ISequentialInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
UInt64 GetSize() const { return _pos; }
@@ -53,8 +54,8 @@ public:
_size = size;
return SeekToPhys();
}
-
- MY_UNKNOWN_IMP1(IInStream)
+
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
@@ -62,6 +63,8 @@ public:
HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); }
};
+HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream);
+
class CClusterInStream:
public IInStream,
public CMyUnknownImp
@@ -73,7 +76,7 @@ public:
CMyComPtr<IInStream> Stream;
UInt64 StartOffset;
UInt64 Size;
- int BlockSizeLog;
+ unsigned BlockSizeLog;
CRecordVector<UInt32> Vector;
HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
@@ -91,13 +94,44 @@ public:
return S_OK;
}
- MY_UNKNOWN_IMP1(IInStream)
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
-HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream);
+struct CSeekExtent
+{
+ UInt64 Phy;
+ UInt64 Virt;
+};
+
+class CExtentsStream:
+ public IInStream,
+ public CMyUnknownImp
+{
+ UInt64 _phyPos;
+ UInt64 _virtPos;
+ bool _needStartSeek;
+
+ HRESULT SeekToPhys() { return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); }
+
+public:
+ CMyComPtr<IInStream> Stream;
+ CRecordVector<CSeekExtent> Extents;
+
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ void ReleaseStream() { Stream.Release(); }
+
+ void Init()
+ {
+ _virtPos = 0;
+ _phyPos = 0;
+ _needStartSeek = true;
+ }
+};
class CLimitedSequentialOutStream:
public ISequentialOutStream,
@@ -108,7 +142,7 @@ class CLimitedSequentialOutStream:
bool _overflow;
bool _overflowIsAllowed;
public:
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
@@ -122,4 +156,96 @@ public:
UInt64 GetRem() const { return _size; }
};
+
+class CTailInStream:
+ public IInStream,
+ public CMyUnknownImp
+{
+ UInt64 _virtPos;
+public:
+ CMyComPtr<IInStream> Stream;
+ UInt64 Offset;
+
+ void Init()
+ {
+ _virtPos = 0;
+ }
+
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+
+ HRESULT SeekToStart() { return Stream->Seek(Offset, STREAM_SEEK_SET, NULL); }
+};
+
+class CLimitedCachedInStream:
+ public IInStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<IInStream> _stream;
+ UInt64 _virtPos;
+ UInt64 _physPos;
+ UInt64 _size;
+ UInt64 _startOffset;
+
+ const Byte *_cache;
+ size_t _cacheSize;
+ size_t _cachePhyPos;
+
+
+ HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
+public:
+ CByteBuffer Buffer;
+
+ void SetStream(IInStream *stream) { _stream = stream; }
+ void SetCache(size_t cacheSize, size_t cachePos)
+ {
+ _cache = Buffer;
+ _cacheSize = cacheSize;
+ _cachePhyPos = cachePos;
+ }
+
+ HRESULT InitAndSeek(UInt64 startOffset, UInt64 size)
+ {
+ _startOffset = startOffset;
+ _physPos = startOffset;
+ _virtPos = 0;
+ _size = size;
+ return SeekToPhys();
+ }
+
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+
+ HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); }
+};
+
+class CTailOutStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ UInt64 _virtPos;
+ UInt64 _virtSize;
+public:
+ CMyComPtr<IOutStream> Stream;
+ UInt64 Offset;
+
+ virtual ~CTailOutStream() {}
+
+ MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStream)
+
+ void Init()
+ {
+ _virtPos = 0;
+ _virtSize = 0;
+ }
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(UInt64 newSize);
+};
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/MethodId.cpp b/src/libs/7zip/unix/CPP/7zip/Common/MethodId.cpp
deleted file mode 100644
index b797b6857..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Common/MethodId.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// MethodId.cpp
-
-#include "StdAfx.h"
-
-#include "MethodId.h"
-#include "../../Common/MyString.h"
-
-static inline wchar_t GetHex(Byte value)
-{
- return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
-}
-
-UString ConvertMethodIdToString(UInt64 id)
-{
- wchar_t s[32];
- int len = 32;
- s[--len] = 0;
- do
- {
- s[--len] = GetHex((Byte)id & 0xF);
- id >>= 4;
- s[--len] = GetHex((Byte)id & 0xF);
- id >>= 4;
- }
- while (id != 0);
- return s + len;
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/MethodId.h b/src/libs/7zip/unix/CPP/7zip/Common/MethodId.h
index 54ebc9f7d..28b615fcd 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/MethodId.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/MethodId.h
@@ -3,7 +3,7 @@
#ifndef __7Z_METHOD_ID_H
#define __7Z_METHOD_ID_H
-#include "../../Common/Types.h"
+#include "../../Common/MyTypes.h"
typedef UInt64 CMethodId;
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.cpp b/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.cpp
index 5836d0f84..ff61995b7 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.cpp
@@ -2,98 +2,440 @@
#include "StdAfx.h"
-#include "../../Common/MyCom.h"
-
-#include "../ICoder.h"
+#include "../../Common/StringToInt.h"
#include "MethodProps.h"
-static const UInt64 k_LZMA = 0x030101;
-static const UInt64 k_LZMA2 = 0x21;
+using namespace NWindows;
+
+bool StringToBool(const UString &s, bool &res)
+{
+ if (s.IsEmpty() || s == L"+" || StringsAreEqualNoCase_Ascii(s, "ON"))
+ {
+ res = true;
+ return true;
+ }
+ if (s == L"-" || StringsAreEqualNoCase_Ascii(s, "OFF"))
+ {
+ res = false;
+ return true;
+ }
+ return false;
+}
+
+HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest)
+{
+ switch (prop.vt)
+ {
+ case VT_EMPTY: dest = true; return S_OK;
+ case VT_BOOL: dest = (prop.boolVal != VARIANT_FALSE); return S_OK;
+ case VT_BSTR: return StringToBool(prop.bstrVal, dest) ? S_OK : E_INVALIDARG;
+ }
+ return E_INVALIDARG;
+}
+
+unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number)
+{
+ const wchar_t *start = srcString;
+ const wchar_t *end;
+ number = ConvertStringToUInt32(start, &end);
+ return (unsigned)(end - start);
+}
+
+HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
+{
+ // =VT_UI4
+ // =VT_EMPTY
+ // {stringUInt32}=VT_EMPTY
-HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder)
+ if (prop.vt == VT_UI4)
+ {
+ if (!name.IsEmpty())
+ return E_INVALIDARG;
+ resValue = prop.ulVal;
+ return S_OK;
+ }
+ if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ if (name.IsEmpty())
+ return S_OK;
+ UInt32 v;
+ if (ParseStringToUInt32(name, v) != name.Len())
+ return E_INVALIDARG;
+ resValue = v;
+ return S_OK;
+}
+
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
{
- bool tryReduce = false;
- UInt32 reducedDictionarySize = 1 << 10;
- if (inSizeForReduce != 0 && (method.Id == k_LZMA || method.Id == k_LZMA2))
+ if (name.IsEmpty())
{
- for (;;)
+ switch (prop.vt)
{
- const UInt32 step = (reducedDictionarySize >> 1);
- if (reducedDictionarySize >= *inSizeForReduce)
- {
- tryReduce = true;
+ case VT_UI4:
+ numThreads = prop.ulVal;
break;
- }
- reducedDictionarySize += step;
- if (reducedDictionarySize >= *inSizeForReduce)
+ default:
{
- tryReduce = true;
+ bool val;
+ RINOK(PROPVARIANT_to_bool(prop, val));
+ numThreads = (val ? defaultNumThreads : 1);
break;
}
- if (reducedDictionarySize >= ((UInt32)3 << 30))
- break;
- reducedDictionarySize += step;
}
+ return S_OK;
+ }
+ if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ return ParsePropToUInt32(name, prop, numThreads);
+}
+
+static HRESULT StringToDictSize(const UString &s, UInt32 &dicSize)
+{
+ const wchar_t *end;
+ UInt32 number = ConvertStringToUInt32(s, &end);
+ unsigned numDigits = (unsigned)(end - s);
+ if (numDigits == 0 || s.Len() > numDigits + 1)
+ return E_INVALIDARG;
+ const unsigned kLogDictSizeLimit = 32;
+ if (s.Len() == numDigits)
+ {
+ if (number >= kLogDictSizeLimit)
+ return E_INVALIDARG;
+ dicSize = (UInt32)1 << (unsigned)number;
+ return S_OK;
+ }
+ unsigned numBits;
+ switch (MyCharLower_Ascii(s[numDigits]))
+ {
+ case 'b': dicSize = number; return S_OK;
+ case 'k': numBits = 10; break;
+ case 'm': numBits = 20; break;
+ case 'g': numBits = 30; break;
+ default: return E_INVALIDARG;
+ }
+ if (number >= ((UInt32)1 << (kLogDictSizeLimit - numBits)))
+ return E_INVALIDARG;
+ dicSize = number << numBits;
+ return S_OK;
+}
+
+static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, UInt32 &resValue)
+{
+ if (prop.vt == VT_UI4)
+ {
+ UInt32 v = prop.ulVal;
+ if (v >= 32)
+ return E_INVALIDARG;
+ resValue = (UInt32)1 << v;
+ return S_OK;
+ }
+ if (prop.vt == VT_BSTR)
+ return StringToDictSize(prop.bstrVal, resValue);
+ return E_INVALIDARG;
+}
+
+void CProps::AddProp32(PROPID propid, UInt32 level)
+{
+ CProp prop;
+ prop.IsOptional = true;
+ prop.Id = propid;
+ prop.Value = (UInt32)level;
+ Props.Add(prop);
+}
+
+class CCoderProps
+{
+ PROPID *_propIDs;
+ NCOM::CPropVariant *_props;
+ unsigned _numProps;
+ unsigned _numPropsMax;
+public:
+ CCoderProps(unsigned numPropsMax)
+ {
+ _numPropsMax = numPropsMax;
+ _numProps = 0;
+ _propIDs = new PROPID[numPropsMax];
+ _props = new NCOM::CPropVariant[numPropsMax];
+ }
+ ~CCoderProps()
+ {
+ delete []_propIDs;
+ delete []_props;
+ }
+ void AddProp(const CProp &prop);
+ HRESULT SetProps(ICompressSetCoderProperties *setCoderProperties)
+ {
+ return setCoderProperties->SetCoderProperties(_propIDs, _props, _numProps);
+ }
+};
+
+void CCoderProps::AddProp(const CProp &prop)
+{
+ if (_numProps >= _numPropsMax)
+ throw 1;
+ _propIDs[_numProps] = prop.Id;
+ _props[_numProps] = prop.Value;
+ _numProps++;
+}
+
+HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const
+{
+ CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0));
+ FOR_VECTOR (i, Props)
+ coderProps.AddProp(Props[i]);
+ if (dataSizeReduce)
+ {
+ CProp prop;
+ prop.Id = NCoderPropID::kReduceSize;
+ prop.Value = *dataSizeReduce;
+ coderProps.AddProp(prop);
+ }
+ return coderProps.SetProps(scp);
+}
+
+
+int CMethodProps::FindProp(PROPID id) const
+{
+ for (int i = Props.Size() - 1; i >= 0; i--)
+ if (Props[i].Id == id)
+ return i;
+ return -1;
+}
+
+int CMethodProps::GetLevel() const
+{
+ int i = FindProp(NCoderPropID::kLevel);
+ if (i < 0)
+ return 5;
+ if (Props[i].Value.vt != VT_UI4)
+ return 9;
+ UInt32 level = Props[i].Value.ulVal;
+ return level > 9 ? 9 : (int)level;
+}
+
+struct CNameToPropID
+{
+ VARTYPE VarType;
+ const char *Name;
+};
+
+static const CNameToPropID g_NameToPropID[] =
+{
+ { VT_UI4, "" },
+ { VT_UI4, "d" },
+ { VT_UI4, "mem" },
+ { VT_UI4, "o" },
+ { VT_UI4, "c" },
+ { VT_UI4, "pb" },
+ { VT_UI4, "lc" },
+ { VT_UI4, "lp" },
+ { VT_UI4, "fb" },
+ { VT_BSTR, "mf" },
+ { VT_UI4, "mc" },
+ { VT_UI4, "pass" },
+ { VT_UI4, "a" },
+ { VT_UI4, "mt" },
+ { VT_BOOL, "eos" },
+ { VT_UI4, "x" },
+ { VT_UI4, "reduceSize" }
+};
+
+static int FindPropIdExact(const UString &name)
+{
+ for (unsigned i = 0; i < ARRAY_SIZE(g_NameToPropID); i++)
+ if (StringsAreEqualNoCase_Ascii(name, g_NameToPropID[i].Name))
+ return i;
+ return -1;
+}
+
+static bool ConvertProperty(const PROPVARIANT &srcProp, VARTYPE varType, NCOM::CPropVariant &destProp)
+{
+ if (varType == srcProp.vt)
+ {
+ destProp = srcProp;
+ return true;
+ }
+ if (varType == VT_BOOL)
+ {
+ bool res;
+ if (PROPVARIANT_to_bool(srcProp, res) != S_OK)
+ return false;
+ destProp = res;
+ return true;
+ }
+ if (srcProp.vt == VT_EMPTY)
+ {
+ destProp = srcProp;
+ return true;
+ }
+ return false;
+}
+
+static void SplitParams(const UString &srcString, UStringVector &subStrings)
+{
+ subStrings.Clear();
+ UString s;
+ int len = srcString.Len();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = srcString[i];
+ if (c == L':')
+ {
+ subStrings.Add(s);
+ s.Empty();
+ }
+ else
+ s += c;
+ }
+ subStrings.Add(s);
+}
+
+static void SplitParam(const UString &param, UString &name, UString &value)
+{
+ int eqPos = param.Find(L'=');
+ if (eqPos >= 0)
+ {
+ name.SetFrom(param, eqPos);
+ value = param.Ptr(eqPos + 1);
+ return;
}
+ unsigned i;
+ for (i = 0; i < param.Len(); i++)
+ {
+ wchar_t c = param[i];
+ if (c >= L'0' && c <= L'9')
+ break;
+ }
+ name.SetFrom(param, i);
+ value = param.Ptr(i);
+}
+
+static bool IsLogSizeProp(PROPID propid)
+{
+ switch (propid)
+ {
+ case NCoderPropID::kDictionarySize:
+ case NCoderPropID::kUsedMemorySize:
+ case NCoderPropID::kBlockSize:
+ case NCoderPropID::kReduceSize:
+ return true;
+ }
+ return false;
+}
+HRESULT CMethodProps::SetParam(const UString &name, const UString &value)
+{
+ int index = FindPropIdExact(name);
+ if (index < 0)
+ return E_INVALIDARG;
+ const CNameToPropID &nameToPropID = g_NameToPropID[index];
+ CProp prop;
+ prop.Id = index;
+
+ if (IsLogSizeProp(prop.Id))
{
- int numProps = method.Props.Size();
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
- if (setCoderProperties == NULL)
+ UInt32 dicSize;
+ RINOK(StringToDictSize(value, dicSize));
+ prop.Value = dicSize;
+ }
+ else
+ {
+ NCOM::CPropVariant propValue;
+ if (nameToPropID.VarType == VT_BSTR)
+ propValue = value;
+ else if (nameToPropID.VarType == VT_BOOL)
{
- if (numProps != 0)
+ bool res;
+ if (!StringToBool(value, res))
return E_INVALIDARG;
+ propValue = res;
}
- else
+ else if (!value.IsEmpty())
{
- CRecordVector<PROPID> propIDs;
- NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProps];
- HRESULT res = S_OK;
- try
- {
- for (int i = 0; i < numProps; i++)
- {
- const CProp &prop = method.Props[i];
- propIDs.Add(prop.Id);
- NWindows::NCOM::CPropVariant &value = values[i];
- value = prop.Value;
- // if (tryReduce && prop.Id == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
- if (tryReduce)
- if (prop.Id == NCoderPropID::kDictionarySize)
- if (value.vt == VT_UI4)
- if (reducedDictionarySize < value.ulVal)
- value.ulVal = reducedDictionarySize;
- }
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
- res = setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProps);
- }
- catch(...)
- {
- delete []values;
- throw;
- }
- delete []values;
- RINOK(res);
+ UInt32 number;
+ if (ParseStringToUInt32(value, number) == value.Len())
+ propValue = number;
+ else
+ propValue = value;
}
+ if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value))
+ return E_INVALIDARG;
+ }
+ Props.Add(prop);
+ return S_OK;
+}
+
+HRESULT CMethodProps::ParseParamsFromString(const UString &srcString)
+{
+ UStringVector params;
+ SplitParams(srcString, params);
+ FOR_VECTOR (i, params)
+ {
+ const UString &param = params[i];
+ UString name, value;
+ SplitParam(param, name, value);
+ RINOK(SetParam(name, value));
+ }
+ return S_OK;
+}
+
+HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value)
+{
+ if (realName.Len() == 0)
+ {
+ // [empty]=method
+ return E_INVALIDARG;
}
-
- /*
- CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
- coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
- if (writeCoderProperties != NULL)
- {
- CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
- CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
- outStreamSpec->Init();
- RINOK(writeCoderProperties->WriteCoderProperties(outStream));
- size_t size = outStreamSpec->GetSize();
- filterProps.SetCapacity(size);
- memmove(filterProps, outStreamSpec->GetBuffer(), size);
- }
- */
+ if (value.vt == VT_EMPTY)
+ {
+ // {realName}=[empty]
+ UString name, value;
+ SplitParam(realName, name, value);
+ return SetParam(name, value);
+ }
+
+ // {realName}=value
+ int index = FindPropIdExact(realName);
+ if (index < 0)
+ return E_INVALIDARG;
+ const CNameToPropID &nameToPropID = g_NameToPropID[index];
+ CProp prop;
+ prop.Id = index;
+
+ if (IsLogSizeProp(prop.Id))
+ {
+ UInt32 dicSize;
+ RINOK(PROPVARIANT_to_DictSize(value, dicSize));
+ prop.Value = dicSize;
+ }
+ else
+ {
+ if (!ConvertProperty(value, nameToPropID.VarType, prop.Value))
+ return E_INVALIDARG;
+ }
+ Props.Add(prop);
return S_OK;
}
+HRESULT COneMethodInfo::ParseMethodFromString(const UString &s)
+{
+ int splitPos = s.Find(':');
+ MethodName = s;
+ if (splitPos < 0)
+ return S_OK;
+ MethodName.DeleteFrom(splitPos);
+ return ParseParamsFromString(s.Ptr(splitPos + 1));
+}
+
+HRESULT COneMethodInfo::ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value)
+{
+ if (!realName.IsEmpty() && !StringsAreEqualNoCase_Ascii(realName, "m"))
+ return ParseParamsFromPROPVARIANT(realName, value);
+ // -m{N}=method
+ if (value.vt != VT_BSTR)
+ return E_INVALIDARG;
+ return ParseMethodFromString(value.bstrVal);
+}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.h b/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.h
index 8127e21ee..39e2ee937 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/MethodProps.h
@@ -3,39 +3,183 @@
#ifndef __7Z_METHOD_PROPS_H
#define __7Z_METHOD_PROPS_H
-#include "../../Common/MyVector.h"
+#include "../../Common/MyString.h"
#include "../../Windows/PropVariant.h"
-#include "MethodId.h"
+#include "../ICoder.h"
+
+bool StringToBool(const UString &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);
+
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
struct CProp
{
PROPID Id;
+ bool IsOptional;
NWindows::NCOM::CPropVariant Value;
+ CProp(): IsOptional(false) {}
};
-struct CMethod
+struct CProps
{
- CMethodId Id;
CObjectVector<CProp> Props;
+
+ void Clear() { Props.Clear(); }
+
+ bool AreThereNonOptionalProps() const
+ {
+ FOR_VECTOR (i, Props)
+ if (!Props[i].IsOptional)
+ return true;
+ return false;
+ }
+
+ void AddProp32(PROPID propid, UInt32 level);
+
+ void AddPropString(PROPID propid, const wchar_t *s)
+ {
+ CProp prop;
+ prop.IsOptional = true;
+ prop.Id = propid;
+ prop.Value = s;
+ Props.Add(prop);
+ }
+
+ HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const;
};
-struct CMethodsMode
+class CMethodProps: public CProps
{
- CObjectVector<CMethod> Methods;
- #ifndef _7ZIP_ST
- UInt32 NumThreads;
- #endif
-
- CMethodsMode()
- #ifndef _7ZIP_ST
- : NumThreads(1)
- #endif
- {}
- bool IsEmpty() const { return Methods.IsEmpty() ; }
+ HRESULT SetParam(const UString &name, const UString &value);
+public:
+ int GetLevel() const;
+ int Get_NumThreads() const
+ {
+ int i = FindProp(NCoderPropID::kNumThreads);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ return (int)Props[i].Value.ulVal;
+ return -1;
+ }
+
+ bool Get_DicSize(UInt32 &res) const
+ {
+ res = 0;
+ int i = FindProp(NCoderPropID::kDictionarySize);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ {
+ res = Props[i].Value.ulVal;
+ return true;
+ }
+ return false;
+ }
+
+ int FindProp(PROPID id) const;
+
+ UInt32 Get_Lzma_Algo() const
+ {
+ int i = FindProp(NCoderPropID::kAlgorithm);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ return Props[i].Value.ulVal;
+ return GetLevel() >= 5 ? 1 : 0;
+ }
+
+ UInt32 Get_Lzma_DicSize() const
+ {
+ int i = FindProp(NCoderPropID::kDictionarySize);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ return Props[i].Value.ulVal;
+ int level = GetLevel();
+ return level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26));
+ }
+
+ UInt32 Get_Lzma_NumThreads(bool &fixedNumber) const
+ {
+ fixedNumber = false;
+ int numThreads = Get_NumThreads();
+ if (numThreads >= 0)
+ {
+ fixedNumber = true;
+ return numThreads < 2 ? 1 : 2;
+ }
+ return Get_Lzma_Algo() == 0 ? 1 : 2;
+ }
+
+ UInt32 Get_BZip2_NumThreads(bool &fixedNumber) const
+ {
+ fixedNumber = false;
+ int numThreads = Get_NumThreads();
+ if (numThreads >= 0)
+ {
+ fixedNumber = true;
+ if (numThreads < 1) return 1;
+ if (numThreads > 64) return 64;
+ return numThreads;
+ }
+ return 1;
+ }
+
+ UInt32 Get_BZip2_BlockSize() const
+ {
+ int i = FindProp(NCoderPropID::kDictionarySize);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ {
+ UInt32 blockSize = Props[i].Value.ulVal;
+ const UInt32 kDicSizeMin = 100000;
+ const UInt32 kDicSizeMax = 900000;
+ if (blockSize < kDicSizeMin) blockSize = kDicSizeMin;
+ if (blockSize > kDicSizeMax) blockSize = kDicSizeMax;
+ return blockSize;
+ }
+ int level = GetLevel();
+ return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1));
+ }
+
+ UInt32 Get_Ppmd_MemSize() const
+ {
+ int i = FindProp(NCoderPropID::kUsedMemorySize);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ return Props[i].Value.ulVal;
+ int level = GetLevel();
+ return level >= 9 ? (192 << 20) : ((UInt32)1 << (level + 19));
+ }
+
+ void AddLevelProp(UInt32 level)
+ {
+ AddProp32(NCoderPropID::kLevel, level);
+ }
+
+ void AddNumThreadsProp(UInt32 numThreads)
+ {
+ AddProp32(NCoderPropID::kNumThreads, numThreads);
+ }
+
+ HRESULT ParseParamsFromString(const UString &srcString);
+ HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
};
-HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder);
+class COneMethodInfo: public CMethodProps
+{
+public:
+ UString MethodName;
+
+ void Clear()
+ {
+ CMethodProps::Clear();
+ MethodName.Empty();
+ }
+ bool IsEmpty() const { return MethodName.IsEmpty() && Props.IsEmpty(); }
+ HRESULT ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
+ HRESULT ParseMethodFromString(const UString &s);
+};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.cpp b/src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.cpp
deleted file mode 100644
index c5e4e6da4..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-// OffsetStream.cpp
-
-#include "StdAfx.h"
-
-#include "Common/Defs.h"
-#include "OffsetStream.h"
-
-HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset)
-{
- _offset = offset;
- _stream = stream;
- return _stream->Seek(offset, STREAM_SEEK_SET, NULL);
-}
-
-STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return _stream->Write(data, size, processedSize);
-}
-
-STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin,
- UInt64 *newPosition)
-{
- UInt64 absoluteNewPosition;
- if (seekOrigin == STREAM_SEEK_SET)
- offset += _offset;
- HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition);
- if (newPosition != NULL)
- *newPosition = absoluteNewPosition - _offset;
- return result;
-}
-
-STDMETHODIMP COffsetOutStream::SetSize(UInt64 newSize)
-{
- return _stream->SetSize(_offset + newSize);
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.h b/src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.h
deleted file mode 100644
index de9d06dd0..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Common/OffsetStream.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// OffsetStream.h
-
-#ifndef __OFFSETSTREAM_H
-#define __OFFSETSTREAM_H
-
-#include "Common/MyCom.h"
-#include "../IStream.h"
-
-class COffsetOutStream:
- public IOutStream,
- public CMyUnknownImp
-{
- UInt64 _offset;
- CMyComPtr<IOutStream> _stream;
-public:
- HRESULT Init(IOutStream *stream, UInt64 offset);
-
- MY_UNKNOWN_IMP
-
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
- STDMETHOD(SetSize)(UInt64 newSize);
-};
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.cpp b/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.cpp
index 2e5debd83..4ba34a053 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.cpp
@@ -6,34 +6,29 @@
#include "OutBuffer.h"
-bool COutBuffer::Create(UInt32 bufferSize)
+bool COutBuffer::Create(UInt32 bufSize) throw()
{
const UInt32 kMinBlockSize = 1;
- if (bufferSize < kMinBlockSize)
- bufferSize = kMinBlockSize;
- if (_buffer != 0 && _bufferSize == bufferSize)
+ if (bufSize < kMinBlockSize)
+ bufSize = kMinBlockSize;
+ if (_buf != 0 && _bufSize == bufSize)
return true;
Free();
- _bufferSize = bufferSize;
- _buffer = (Byte *)::MidAlloc(bufferSize);
- return (_buffer != 0);
+ _bufSize = bufSize;
+ _buf = (Byte *)::MidAlloc(bufSize);
+ return (_buf != 0);
}
-void COutBuffer::Free()
+void COutBuffer::Free() throw()
{
- ::MidFree(_buffer);
- _buffer = 0;
+ ::MidFree(_buf);
+ _buf = 0;
}
-void COutBuffer::SetStream(ISequentialOutStream *stream)
-{
- _stream = stream;
-}
-
-void COutBuffer::Init()
+void COutBuffer::Init() throw()
{
_streamPos = 0;
- _limitPos = _bufferSize;
+ _limitPos = _bufSize;
_pos = 0;
_processedSize = 0;
_overDict = false;
@@ -42,27 +37,27 @@ void COutBuffer::Init()
#endif
}
-UInt64 COutBuffer::GetProcessedSize() const
+UInt64 COutBuffer::GetProcessedSize() const throw()
{
UInt64 res = _processedSize + _pos - _streamPos;
if (_streamPos > _pos)
- res += _bufferSize;
+ res += _bufSize;
return res;
}
-HRESULT COutBuffer::FlushPart()
+HRESULT COutBuffer::FlushPart() throw()
{
- // _streamPos < _bufferSize
- UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
+ // _streamPos < _bufSize
+ UInt32 size = (_streamPos >= _pos) ? (_bufSize - _streamPos) : (_pos - _streamPos);
HRESULT result = S_OK;
#ifdef _NO_EXCEPTIONS
result = ErrorCode;
#endif
- if (_buffer2 != 0)
+ if (_buf2 != 0)
{
- memmove(_buffer2, _buffer + _streamPos, size);
- _buffer2 += size;
+ memcpy(_buf2, _buf + _streamPos, size);
+ _buf2 += size;
}
if (_stream != 0
@@ -72,30 +67,30 @@ HRESULT COutBuffer::FlushPart()
)
{
UInt32 processedSize = 0;
- result = _stream->Write(_buffer + _streamPos, size, &processedSize);
+ result = _stream->Write(_buf + _streamPos, size, &processedSize);
size = processedSize;
}
_streamPos += size;
- if (_streamPos == _bufferSize)
+ if (_streamPos == _bufSize)
_streamPos = 0;
- if (_pos == _bufferSize)
+ if (_pos == _bufSize)
{
_overDict = true;
_pos = 0;
}
- _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
+ _limitPos = (_streamPos > _pos) ? _streamPos : _bufSize;
_processedSize += size;
return result;
}
-HRESULT COutBuffer::Flush()
+HRESULT COutBuffer::Flush() throw()
{
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
return ErrorCode;
#endif
- while(_streamPos != _pos)
+ while (_streamPos != _pos)
{
HRESULT result = FlushPart();
if (result != S_OK)
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.h b/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.h
index 62e77caae..0baad3636 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/OutBuffer.h
@@ -1,7 +1,7 @@
// OutBuffer.h
-#ifndef __OUTBUFFER_H
-#define __OUTBUFFER_H
+#ifndef __OUT_BUFFER_H
+#define __OUT_BUFFER_H
#include "../IStream.h"
#include "../../Common/MyCom.h"
@@ -17,39 +17,38 @@ struct COutBufferException: public CSystemException
class COutBuffer
{
protected:
- Byte *_buffer;
+ Byte *_buf;
UInt32 _pos;
UInt32 _limitPos;
UInt32 _streamPos;
- UInt32 _bufferSize;
- CMyComPtr<ISequentialOutStream> _stream;
+ UInt32 _bufSize;
+ ISequentialOutStream *_stream;
UInt64 _processedSize;
- Byte *_buffer2;
+ Byte *_buf2;
bool _overDict;
- HRESULT FlushPart();
+ HRESULT FlushPart() throw();
public:
#ifdef _NO_EXCEPTIONS
HRESULT ErrorCode;
#endif
- COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
+ COutBuffer(): _buf(0), _pos(0), _stream(0), _buf2(0) {}
~COutBuffer() { Free(); }
-
- bool Create(UInt32 bufferSize);
- void Free();
- void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
- void SetStream(ISequentialOutStream *stream);
- void Init();
- HRESULT Flush();
+ bool Create(UInt32 bufSize) throw();
+ void Free() throw();
+
+ void SetMemStream(Byte *buf) { _buf2 = buf; }
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void Init() throw();
+ HRESULT Flush() throw();
void FlushWithCheck();
- void ReleaseStream() { _stream.Release(); }
void WriteByte(Byte b)
{
- _buffer[_pos++] = b;
- if(_pos == _limitPos)
+ _buf[_pos++] = b;
+ if (_pos == _limitPos)
FlushWithCheck();
}
void WriteBytes(const void *data, size_t size)
@@ -58,7 +57,7 @@ public:
WriteByte(((const Byte *)data)[i]);
}
- UInt64 GetProcessedSize() const;
+ UInt64 GetProcessedSize() const throw();
};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp b/src/libs/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp
index f24ff6b6f..bac45c1c2 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/ProgressUtils.cpp
@@ -1,4 +1,4 @@
-// ProgressUtils.h
+// ProgressUtils.cpp
#include "StdAfx.h"
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/PropId.cpp b/src/libs/7zip/unix/CPP/7zip/Common/PropId.cpp
new file mode 100644
index 000000000..10daef715
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Common/PropId.cpp
@@ -0,0 +1,99 @@
+// PropId.cpp
+
+#include "StdAfx.h"
+
+#include "../PropID.h"
+
+// VARTYPE
+Byte k7z_PROPID_To_VARTYPE[kpid_NUM_DEFINED] =
+{
+ VT_EMPTY,
+ VT_UI4,
+ VT_UI4,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BOOL,
+ VT_UI8,
+ VT_UI8,
+ VT_UI4,
+ VT_FILETIME,
+ VT_FILETIME,
+ VT_FILETIME,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_UI4,
+ VT_UI4,
+ VT_BSTR,
+ VT_BOOL,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_UI8,
+ VT_BSTR,
+ VT_UI8,
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_BSTR, // or VT_UI8 kpidUnpackVer
+ VT_UI4, // or VT_UI8 kpidVolume
+ VT_BOOL,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI4,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_UI4, // kpidChecksum
+ VT_BSTR,
+ VT_UI8,
+ VT_BSTR, // or VT_UI8 kpidId
+ VT_BSTR,
+ VT_BSTR,
+ VT_UI4,
+ VT_UI4,
+ VT_BSTR,
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_UI4,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR, // kpidNtSecure
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BSTR, // SHA-1
+ VT_BSTR, // SHA-256
+ VT_BSTR,
+ VT_UI8,
+ VT_UI4,
+ VT_UI4,
+ VT_BSTR,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_UI8,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BSTR,
+ VT_BOOL,
+ VT_BOOL,
+ VT_BOOL,
+ VT_UI8,
+ VT_UI8
+};
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h b/src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h
index 305aac1fd..82bd09673 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h
@@ -5,28 +5,69 @@
#include "../Archive/IArchive.h"
-typedef IInArchive * (*CreateInArchiveP)();
-typedef IOutArchive * (*CreateOutArchiveP)();
+#include <mutex>
struct CArcInfo
{
- const wchar_t *Name;
- const wchar_t *Ext;
- const wchar_t *AddExt;
+ const char *Name;
+ const char *Ext;
+ const char *AddExt;
+
Byte ClassId;
- Byte Signature[28]; // FIXME Byte Signature[16]; adding 22 bytes to insure kSignature[0x1A]!= 0 and kSignature[0x1B] != 0
- int SignatureSize;
- bool KeepName;
- CreateInArchiveP CreateInArchive;
- CreateOutArchiveP CreateOutArchive;
+
+ Byte SignatureSize;
+ Byte Signature[20];
+ UInt16 SignatureOffset;
+
+ UInt16 Flags;
+
+ Func_CreateInArchive CreateInArchive;
+ Func_CreateOutArchive CreateOutArchive;
+ Func_IsArc IsArc;
+
+ bool IsMultiSignature() const { return (Flags & NArcInfoFlags::kMultiSignature) != 0; }
+
+ std::once_flag once;
};
-void RegisterArc(const CArcInfo *arcInfo);
+void RegisterArc(const CArcInfo *arcInfo) throw();
#define REGISTER_ARC_NAME(x) CRegister ## x
-#define REGISTER_ARC(x) struct REGISTER_ARC_NAME(x) { \
- REGISTER_ARC_NAME(x)() { RegisterArc(&g_ArcInfo); }}; \
+#define REGISTER_ARC(x) struct REGISTER_ARC_NAME(x) \
+ { \
+ REGISTER_ARC_NAME(x)() \
+ { \
+ std::call_once(g_ArcInfo.once, [] { RegisterArc(&g_ArcInfo); }); \
+ } \
+ }; \
static REGISTER_ARC_NAME(x) g_RegisterArc; \
void registerArc##x() { static REGISTER_ARC_NAME(x) g_RegisterArc; }
+
+#define REGISTER_ARC_DEC_SIG(x) struct REGISTER_ARC_NAME(x) \
+ { \
+ REGISTER_ARC_NAME(x)() { \
+ std::call_once(g_ArcInfo.once, [] { \
+ g_ArcInfo.Signature[0]--; \
+ RegisterArc(&g_ArcInfo); \
+ }); \
+ } \
+ }; \
+ static REGISTER_ARC_NAME(x) g_RegisterArc; \
+ void registerArcDec##x() { static REGISTER_ARC_NAME(x) g_RegisterArc; }
+
+
+#define IMP_CreateArcIn_2(c) \
+ static IInArchive *CreateArc() { return new c; }
+
+#define IMP_CreateArcIn IMP_CreateArcIn_2(CHandler)
+
+#ifdef EXTRACT_ONLY
+ #define IMP_CreateArcOut
+ #define REF_CreateArc_Pair CreateArc, NULL
+#else
+ #define IMP_CreateArcOut static IOutArchive *CreateArcOut() { return new CHandler; }
+ #define REF_CreateArc_Pair CreateArc, CreateArcOut
+#endif
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h b/src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h
index d53c4344a..0c6662a6c 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h
@@ -1,9 +1,12 @@
// RegisterCodec.h
-#ifndef __REGISTERCODEC_H
-#define __REGISTERCODEC_H
+#ifndef __REGISTER_CODEC_H
+#define __REGISTER_CODEC_H
#include "../Common/MethodId.h"
+#include "../ICoder.h"
+
+#include <mutex>
typedef void * (*CreateCodecP)();
struct CCodecInfo
@@ -14,21 +17,50 @@ struct CCodecInfo
const wchar_t *Name;
UInt32 NumInStreams;
bool IsFilter;
+ std::once_flag once;
};
-void RegisterCodec(const CCodecInfo *codecInfo);
+void RegisterCodec(const CCodecInfo *codecInfo) throw();
#define REGISTER_CODEC_NAME(x) CRegisterCodec ## x
-#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \
- REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo); }}; \
+#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) \
+ { \
+ REGISTER_CODEC_NAME(x)() \
+ { \
+ std::call_once(g_CodecInfo.once, [] { RegisterCodec(&g_CodecInfo); }); \
+ } \
+ }; \
static REGISTER_CODEC_NAME(x) g_RegisterCodec; \
void registerCodec##x() { static REGISTER_CODEC_NAME(x) g_RegisterCodecs; }
#define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x
-#define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \
- REGISTER_CODECS_NAME(x)() { for (int i = 0; i < sizeof(g_CodecsInfo) / sizeof(g_CodecsInfo[0]); i++) \
- RegisterCodec(&g_CodecsInfo[i]); }}; \
+#define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) \
+ { \
+ REGISTER_CODECS_NAME(x)() \
+ { \
+ for (unsigned i = 0; i < ARRAY_SIZE(g_CodecsInfo); i++) \
+ std::call_once(g_CodecsInfo[i].once, [&i] { RegisterCodec(&g_CodecsInfo[i]); }); \
+ } \
+ }; \
static REGISTER_CODECS_NAME(x) g_RegisterCodecs; \
void registerCodec##x() { static REGISTER_CODECS_NAME(x) g_RegisterCodecs; }
+
+
+struct CHasherInfo
+{
+ IHasher * (*CreateHasher)();
+ CMethodId Id;
+ const wchar_t *Name;
+ UInt32 DigestSize;
+};
+
+void RegisterHasher(const CHasherInfo *hasher) throw();
+
+#define REGISTER_HASHER_NAME(x) CRegisterHasher ## x
+
+#define REGISTER_HASHER(x) struct REGISTER_HASHER_NAME(x) { \
+ REGISTER_HASHER_NAME(x)() { RegisterHasher(&g_HasherInfo); }}; \
+ static REGISTER_HASHER_NAME(x) g_RegisterHasher;
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.cpp b/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.cpp
index 9dfa3fb75..43feef1ba 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.cpp
@@ -2,151 +2,128 @@
#include "StdAfx.h"
-#include "StreamBinder.h"
-#include "../../Common/Defs.h"
#include "../../Common/MyCom.h"
-using namespace NWindows;
-using namespace NSynchronization;
+#include "StreamBinder.h"
-class CSequentialInStreamForBinder:
+class CBinderInStream:
public ISequentialInStream,
public CMyUnknownImp
{
+ CStreamBinder *_binder;
public:
MY_UNKNOWN_IMP
-
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
-private:
- CStreamBinder *m_StreamBinder;
-public:
- ~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); }
- void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+ ~CBinderInStream() { _binder->CloseRead(); }
+ CBinderInStream(CStreamBinder *binder): _binder(binder) {}
};
-STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
- { return m_StreamBinder->Read(data, size, processedSize); }
+STDMETHODIMP CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+ { return _binder->Read(data, size, processedSize); }
-class CSequentialOutStreamForBinder:
+class CBinderOutStream:
public ISequentialOutStream,
public CMyUnknownImp
{
+ CStreamBinder *_binder;
public:
MY_UNKNOWN_IMP
-
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
-
-private:
- CStreamBinder *m_StreamBinder;
-public:
- ~CSequentialOutStreamForBinder() { m_StreamBinder->CloseWrite(); }
- void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+ ~CBinderOutStream() { _binder->CloseWrite(); }
+ CBinderOutStream(CStreamBinder *binder): _binder(binder) {}
};
-STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
- { return m_StreamBinder->Write(data, size, processedSize); }
+STDMETHODIMP CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+ { return _binder->Write(data, size, processedSize); }
-//////////////////////////
-// CStreamBinder
-// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished.
-HRes CStreamBinder::CreateEvents()
+WRes CStreamBinder::CreateEvents()
{
- _synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent = new NWindows::NSynchronization::CSynchro();
- _synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent->Create();
- RINOK(_allBytesAreWritenEvent.Create(_synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent,true));
- RINOK(_thereAreBytesToReadEvent.Create());
- return _readStreamIsClosedEvent.Create(_synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent);
+ _synchroFor_canWrite_Event_and_readingWasClosed_Event = new NWindows::NSynchronization::CSynchro();
+ _synchroFor_canWrite_Event_and_readingWasClosed_Event->Create();
+ RINOK(_canWrite_Event.Create(_synchroFor_canWrite_Event_and_readingWasClosed_Event,true));
+ // RINOK(_canWrite_Event.Create(true));
+ RINOK(_canRead_Event.Create());
+ return _readingWasClosed_Event.Create(_synchroFor_canWrite_Event_and_readingWasClosed_Event);
}
void CStreamBinder::ReInit()
{
- _thereAreBytesToReadEvent.Reset();
- _readStreamIsClosedEvent.Reset();
+ _waitWrite = true;
+ _canRead_Event.Reset();
+ _readingWasClosed_Event.Reset();
ProcessedSize = 0;
}
-
-void CStreamBinder::CreateStreams(ISequentialInStream **inStream,
- ISequentialOutStream **outStream)
+void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream)
{
- CSequentialInStreamForBinder *inStreamSpec = new
- CSequentialInStreamForBinder;
+ _waitWrite = true;
+ _bufSize = 0;
+ _buf = NULL;
+ ProcessedSize = 0;
+
+ CBinderInStream *inStreamSpec = new CBinderInStream(this);
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
- inStreamSpec->SetBinder(this);
*inStream = inStreamLoc.Detach();
- CSequentialOutStreamForBinder *outStreamSpec = new
- CSequentialOutStreamForBinder;
+ CBinderOutStream *outStreamSpec = new CBinderOutStream(this);
CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec);
- outStreamSpec->SetBinder(this);
*outStream = outStreamLoc.Detach();
-
- _buffer = NULL;
- _bufferSize= 0;
- ProcessedSize = 0;
}
+// (_canRead_Event && _bufSize == 0) means that stream is finished.
+
HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- UInt32 sizeToRead = size;
- if (size > 0)
+ if (processedSize)
+ *processedSize = 0;
+ if (size != 0)
{
- RINOK(_thereAreBytesToReadEvent.Lock());
- sizeToRead = MyMin(_bufferSize, size);
- if (_bufferSize > 0)
+ if (_waitWrite)
{
- memcpy(data, _buffer, sizeToRead);
- _buffer = ((const Byte *)_buffer) + sizeToRead;
- _bufferSize -= sizeToRead;
- if (_bufferSize == 0)
+ RINOK(_canRead_Event.Lock());
+ _waitWrite = false;
+ }
+ if (size > _bufSize)
+ size = _bufSize;
+ if (size != 0)
+ {
+ memcpy(data, _buf, size);
+ _buf = ((const Byte *)_buf) + size;
+ ProcessedSize += size;
+ if (processedSize)
+ *processedSize = size;
+ _bufSize -= size;
+ if (_bufSize == 0)
{
- _thereAreBytesToReadEvent.Reset();
- _allBytesAreWritenEvent.Set();
+ _waitWrite = true;
+ _canRead_Event.Reset();
+ _canWrite_Event.Set();
}
}
}
- if (processedSize != NULL)
- *processedSize = sizeToRead;
- ProcessedSize += sizeToRead;
return S_OK;
}
-void CStreamBinder::CloseRead()
-{
- _readStreamIsClosedEvent.Set();
-}
-
HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if (size > 0)
+ if (processedSize)
+ *processedSize = 0;
+ if (size != 0)
{
- _buffer = data;
- _bufferSize = size;
- _allBytesAreWritenEvent.Reset();
- _thereAreBytesToReadEvent.Set();
-
- HANDLE events[2];
- events[0] = _allBytesAreWritenEvent;
- events[1] = _readStreamIsClosedEvent;
+ _buf = data;
+ _bufSize = size;
+ _canWrite_Event.Reset();
+ _canRead_Event.Set();
+
+ HANDLE events[2] = { _canWrite_Event, _readingWasClosed_Event };
DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
if (waitResult != WAIT_OBJECT_0 + 0)
- {
- // ReadingWasClosed = true;
return S_FALSE;
- }
- // if(!_allBytesAreWritenEvent.Lock())
- // return E_FAIL;
+ if (processedSize)
+ *processedSize = size;
}
- if (processedSize != NULL)
- *processedSize = size;
return S_OK;
}
-
-void CStreamBinder::CloseWrite()
-{
- // _bufferSize must be = 0
- _thereAreBytesToReadEvent.Set();
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.h b/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.h
index 47743dee2..aba6b8e17 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/StreamBinder.h
@@ -1,38 +1,35 @@
// StreamBinder.h
-#ifndef __STREAMBINDER_H
-#define __STREAMBINDER_H
+#ifndef __STREAM_BINDER_H
+#define __STREAM_BINDER_H
-#include "../IStream.h"
#include "../../Windows/Synchronization.h"
+#include "../IStream.h"
+
class CStreamBinder
{
- NWindows::NSynchronization::CManualResetEventWFMO _allBytesAreWritenEvent;
- NWindows::NSynchronization::CManualResetEvent _thereAreBytesToReadEvent;
- NWindows::NSynchronization::CManualResetEventWFMO _readStreamIsClosedEvent;
- NWindows::NSynchronization::CSynchro * _synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent;
- UInt32 _bufferSize;
- const void *_buffer;
+ NWindows::NSynchronization::CManualResetEventWFMO _canWrite_Event;
+ NWindows::NSynchronization::CManualResetEvent _canRead_Event;
+ NWindows::NSynchronization::CManualResetEventWFMO _readingWasClosed_Event;
+ NWindows::NSynchronization::CSynchro * _synchroFor_canWrite_Event_and_readingWasClosed_Event;
+ bool _waitWrite;
+ UInt32 _bufSize;
+ const void *_buf;
public:
- // bool ReadingWasClosed;
UInt64 ProcessedSize;
- CStreamBinder() { _synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent = 0; }
- ~CStreamBinder() {
- if (_synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent)
- delete _synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent;
- _synchroFor_allBytesAreWritenEvent_and_readStreamIsClosedEvent = 0;
- }
- HRes CreateEvents();
- void CreateStreams(ISequentialInStream **inStream,
- ISequentialOutStream **outStream);
+ WRes CreateEvents();
+ void CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream);
+ void ReInit();
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
- void CloseRead();
-
HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);
- void CloseWrite();
- void ReInit();
+ void CloseRead() { _readingWasClosed_Event.Set(); }
+ void CloseWrite()
+ {
+ // _bufSize must be = 0
+ _canRead_Event.Set();
+ }
};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.cpp b/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.cpp
index 24253a9ed..7721c3a7e 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include <stdlib.h>
+
#include "../../../C/Alloc.h"
#include "StreamObjects.h"
@@ -12,8 +14,8 @@ STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
*processedSize = 0;
if (size == 0)
return S_OK;
- if (_pos > _size)
- return E_FAIL;
+ if (_pos >= _size)
+ return S_OK;
size_t rem = _size - (size_t)_pos;
if (rem > size)
rem = (size_t)size;
@@ -26,26 +28,51 @@ STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET: _pos = offset; break;
- case STREAM_SEEK_CUR: _pos += offset; break;
- case STREAM_SEEK_END: _pos = _size + offset; break;
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _pos; break;
+ case STREAM_SEEK_END: offset += _size; break;
default: return STG_E_INVALIDFUNCTION;
}
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _pos = offset;
if (newPosition)
- *newPosition = _pos;
+ *newPosition = offset;
return S_OK;
}
-void CByteDynBuffer::Free()
+/*
+void Create_BufInStream_WithReference(const void *data, size_t size, ISequentialInStream **stream)
+{
+ CBufInStream *inStreamSpec = new CBufInStream;
+ CMyComPtr<ISequentialInStream> streamTemp = inStreamSpec;
+ inStreamSpec->Init((const Byte *)data, size);
+ *stream = streamTemp.Detach();
+}
+*/
+
+void Create_BufInStream_WithNewBuf(const void *data, size_t size, ISequentialInStream **stream)
+{
+ CReferenceBuf *referenceBuf = new CReferenceBuf;
+ CMyComPtr<IUnknown> ref = referenceBuf;
+ referenceBuf->Buf.CopyFrom((const Byte *)data, size);
+
+ CBufInStream *inStreamSpec = new CBufInStream;
+ CMyComPtr<ISequentialInStream> streamTemp = inStreamSpec;
+ inStreamSpec->Init(referenceBuf);
+ *stream = streamTemp.Detach();
+}
+
+void CByteDynBuffer::Free() throw()
{
free(_buf);
_buf = 0;
_capacity = 0;
}
-bool CByteDynBuffer::EnsureCapacity(size_t cap)
+bool CByteDynBuffer::EnsureCapacity(size_t cap) throw()
{
if (cap <= _capacity)
return true;
@@ -77,8 +104,7 @@ Byte *CDynBufSeqOutStream::GetBufPtrForWriting(size_t addSize)
void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const
{
- dest.SetCapacity(_size);
- memcpy((Byte *)dest, (const Byte *)_buffer, _size);
+ dest.CopyFrom((const Byte *)_buffer, _size);
}
STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
@@ -121,7 +147,7 @@ STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size,
static const UInt64 kEmptyTag = (UInt64)(Int64)-1;
-void CCachedInStream::Free()
+void CCachedInStream::Free() throw()
{
MyFree(_tags);
_tags = 0;
@@ -129,7 +155,7 @@ void CCachedInStream::Free()
_data = 0;
}
-bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog)
+bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw()
{
unsigned sizeLog = blockSizeLog + numBlocksLog;
if (sizeLog >= sizeof(size_t) * 8)
@@ -155,7 +181,7 @@ bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog)
return true;
}
-void CCachedInStream::Init(UInt64 size)
+void CCachedInStream::Init(UInt64 size) throw()
{
_size = size;
_pos = 0;
@@ -170,8 +196,8 @@ STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
*processedSize = 0;
if (size == 0)
return S_OK;
- if (_pos > _size)
- return E_FAIL;
+ if (_pos >= _size)
+ return S_OK;
{
UInt64 rem = _size - _pos;
@@ -205,17 +231,20 @@ STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
return S_OK;
}
-
+
STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET: _pos = offset; break;
- case STREAM_SEEK_CUR: _pos = _pos + offset; break;
- case STREAM_SEEK_END: _pos = _size + offset; break;
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _pos; break;
+ case STREAM_SEEK_END: offset += _size; break;
default: return STG_E_INVALIDFUNCTION;
}
- if (newPosition != 0)
- *newPosition = _pos;
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _pos = offset;
+ if (newPosition)
+ *newPosition = offset;
return S_OK;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.h b/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.h
index 5c8b5e51b..d0c86b566 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/StreamObjects.h
@@ -3,8 +3,10 @@
#ifndef __STREAM_OBJECTS_H
#define __STREAM_OBJECTS_H
-#include "../../Common/Buffer.h"
+#include "../../Common/MyBuffer.h"
#include "../../Common/MyCom.h"
+#include "../../Common/MyVector.h"
+
#include "../IStream.h"
struct CReferenceBuf:
@@ -31,13 +33,16 @@ public:
_pos = 0;
_ref = ref;
}
- void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.GetCapacity(), ref); }
+ void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.Size(), ref); }
- MY_UNKNOWN_IMP1(IInStream)
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
+// void Create_BufInStream_WithReference(const void *data, size_t size, ISequentialInStream **stream);
+void Create_BufInStream_WithNewBuf(const void *data, size_t size, ISequentialInStream **stream);
+
class CByteDynBuffer
{
size_t _capacity;
@@ -46,11 +51,11 @@ public:
CByteDynBuffer(): _capacity(0), _buf(0) {};
// there is no copy constructor. So don't copy this object.
~CByteDynBuffer() { Free(); }
- void Free();
- size_t GetCapacity() const { return _capacity; }
- operator Byte*() { return _buf; };
+ void Free() throw();
+ size_t GetCapacity() const { return _capacity; }
+ operator Byte*() const { return _buf; };
operator const Byte*() const { return _buf; };
- bool EnsureCapacity(size_t capacity);
+ bool EnsureCapacity(size_t capacity) throw();
};
class CDynBufSeqOutStream:
@@ -68,7 +73,7 @@ public:
Byte *GetBufPtrForWriting(size_t addSize);
void UpdateSize(size_t addSize) { _size += addSize; }
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
@@ -88,7 +93,7 @@ public:
}
size_t GetPos() const { return _pos; }
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
@@ -103,7 +108,7 @@ public:
void Init() { _size = 0; }
UInt64 GetSize() const { return _size; }
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
@@ -123,9 +128,9 @@ protected:
public:
CCachedInStream(): _tags(0), _data(0) {}
virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (release calls it) !!!
- void Free();
- bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog);
- void Init(UInt64 size);
+ void Free() throw();
+ bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw();
+ void Init(UInt64 size) throw();
MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.cpp b/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.cpp
index 049e4aa17..1402f4205 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.cpp
@@ -6,7 +6,7 @@
static const UInt32 kBlockSize = ((UInt32)1 << 31);
-HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize)
+HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) throw()
{
size_t size = *processedSize;
*processedSize = 0;
@@ -25,21 +25,21 @@ HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSiz
return S_OK;
}
-HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size)
+HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw()
{
size_t processedSize = size;
RINOK(ReadStream(stream, data, &processedSize));
return (size == processedSize) ? S_OK : S_FALSE;
}
-HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size)
+HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw()
{
size_t processedSize = size;
RINOK(ReadStream(stream, data, &processedSize));
return (size == processedSize) ? S_OK : E_FAIL;
}
-HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size)
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw()
{
while (size != 0)
{
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.h b/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.h
index f1cfd1848..ae914c004 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/StreamUtils.h
@@ -1,13 +1,13 @@
// StreamUtils.h
-#ifndef __STREAMUTILS_H
-#define __STREAMUTILS_H
+#ifndef __STREAM_UTILS_H
+#define __STREAM_UTILS_H
#include "../IStream.h"
-HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *size);
-HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size);
-HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size);
-HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size);
+HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *size) throw();
+HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw();
+HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw();
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw();
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.cpp b/src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.cpp
new file mode 100644
index 000000000..7fcc88f5e
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.cpp
@@ -0,0 +1,56 @@
+// UniqBlocks.cpp
+
+#include "StdAfx.h"
+
+#include "UniqBlocks.h"
+
+int CUniqBlocks::AddUniq(const Byte *data, size_t size)
+{
+ unsigned left = 0, right = Sorted.Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ int index = Sorted[mid];
+ const CByteBuffer &buf = Bufs[index];
+ size_t sizeMid = buf.Size();
+ if (size < sizeMid)
+ right = mid;
+ else if (size > sizeMid)
+ left = mid + 1;
+ else
+ {
+ int cmp = memcmp(data, buf, size);
+ if (cmp == 0)
+ return index;
+ if (cmp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ }
+ int index = Bufs.Size();
+ Sorted.Insert(left, index);
+ CByteBuffer &buf = Bufs.AddNew();
+ buf.CopyFrom(data, size);
+ return index;
+}
+
+UInt64 CUniqBlocks::GetTotalSizeInBytes() const
+{
+ UInt64 size = 0;
+ FOR_VECTOR (i, Bufs)
+ size += Bufs[i].Size();
+ return size;
+}
+
+void CUniqBlocks::GetReverseMap()
+{
+ unsigned num = Sorted.Size();
+ BufIndexToSortedIndex.ClearAndSetSize(num);
+ int *p = &BufIndexToSortedIndex[0];
+ unsigned i;
+ for (i = 0; i < num; i++)
+ p[i] = 0;
+ for (i = 0; i < num; i++)
+ p[Sorted[i]] = i;
+}
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.h b/src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.h
new file mode 100644
index 000000000..9c08b09f4
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Common/UniqBlocks.h
@@ -0,0 +1,30 @@
+// UniqBlocks.h
+
+#ifndef __UNIQ_BLOCKS_H
+#define __UNIQ_BLOCKS_H
+
+#include "../../Common/MyTypes.h"
+#include "../../Common/MyBuffer.h"
+#include "../../Common/MyVector.h"
+
+struct CUniqBlocks
+{
+ CObjectVector<CByteBuffer> Bufs;
+ CIntVector Sorted;
+ CIntVector BufIndexToSortedIndex;
+
+ int AddUniq(const Byte *data, size_t size);
+ UInt64 GetTotalSizeInBytes() const;
+ void GetReverseMap();
+
+ bool IsOnlyEmpty() const
+ {
+ if (Bufs.Size() == 0)
+ return true;
+ if (Bufs.Size() > 1)
+ return false;
+ return Bufs[0].Size() == 0;
+ }
+};
+
+#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.cpp b/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.cpp
index cf39bd023..77e3c1acf 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.cpp
@@ -10,7 +10,7 @@ static THREAD_FUNC_DECL CoderThread(void *p)
{
CVirtThread *t = (CVirtThread *)p;
t->StartEvent.Lock();
- if (t->ExitEvent)
+ if (t->Exit)
return 0;
t->Execute();
t->FinishedEvent.Set();
@@ -23,7 +23,7 @@ WRes CVirtThread::Create()
RINOK(FinishedEvent.CreateIfNotCreated());
StartEvent.Reset();
FinishedEvent.Reset();
- ExitEvent = false;
+ Exit = false;
if (Thread.IsCreated())
return S_OK;
return Thread.Create(CoderThread, this);
@@ -31,16 +31,18 @@ WRes CVirtThread::Create()
void CVirtThread::Start()
{
- ExitEvent = false;
+ Exit = false;
StartEvent.Set();
}
-CVirtThread::~CVirtThread()
+void CVirtThread::WaitThreadFinish()
{
- ExitEvent = true;
+ Exit = true;
if (StartEvent.IsCreated())
StartEvent.Set();
if (Thread.IsCreated())
+ {
Thread.Wait();
+ Thread.Close();
+ }
}
-
diff --git a/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.h b/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.h
index f14a1f223..ebee158ca 100644
--- a/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.h
+++ b/src/libs/7zip/unix/CPP/7zip/Common/VirtThread.h
@@ -1,7 +1,7 @@
// VirtThread.h
-#ifndef __VIRTTHREAD_H
-#define __VIRTTHREAD_H
+#ifndef __VIRT_THREAD_H
+#define __VIRT_THREAD_H
#include "../../Windows/Synchronization.h"
#include "../../Windows/Thread.h"
@@ -11,13 +11,14 @@ struct CVirtThread
NWindows::NSynchronization::CAutoResetEvent StartEvent;
NWindows::NSynchronization::CAutoResetEvent FinishedEvent;
NWindows::CThread Thread;
- bool ExitEvent;
+ bool Exit;
- ~CVirtThread();
+ ~CVirtThread() { WaitThreadFinish(); }
+ void WaitThreadFinish(); // call it in destructor of child class !
WRes Create();
void Start();
- void WaitFinish() { FinishedEvent.Lock(); }
virtual void Execute() = 0;
+ void WaitExecuteFinish() { FinishedEvent.Lock(); }
};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/Bcj2Coder.cpp b/src/libs/7zip/unix/CPP/7zip/Compress/Bcj2Coder.cpp
index 684da5abf..9da6b9c28 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/Bcj2Coder.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/Bcj2Coder.cpp
@@ -15,35 +15,22 @@ inline unsigned GetIndex(Byte b0, Byte b1) { return ((b1 == 0xE8) ? b0 : ((b1 ==
#ifndef EXTRACT_ONLY
-static const int kBufferSize = 1 << 17;
+static const unsigned kBufSize = 1 << 17;
-static bool inline Test86MSByte(Byte b)
-{
- return (b == 0 || b == 0xFF);
-}
+#define NUM_BITS 2
+#define SIGN_BIT (1 << NUM_BITS)
+#define MASK_HIGH (0x100 - (1 << (NUM_BITS + 1)))
-bool CEncoder::Create()
+static const UInt32 kDefaultLimit = (1 << (24 + NUM_BITS));
+
+static bool inline Test86MSByte(Byte b)
{
- if (!_mainStream.Create(1 << 18))
- return false;
- if (!_callStream.Create(1 << 18))
- return false;
- if (!_jumpStream.Create(1 << 18))
- return false;
- if (!_rangeEncoder.Create(1 << 20))
- return false;
- if (_buffer == 0)
- {
- _buffer = (Byte *)MidAlloc(kBufferSize);
- if (_buffer == 0)
- return false;
- }
- return true;
+ return (((b) + SIGN_BIT) & MASK_HIGH) == 0;
}
CEncoder::~CEncoder()
{
- ::MidFree(_buffer);
+ ::MidFree(_buf);
}
HRESULT CEncoder::Flush()
@@ -51,12 +38,10 @@ HRESULT CEncoder::Flush()
RINOK(_mainStream.Flush());
RINOK(_callStream.Flush());
RINOK(_jumpStream.Flush());
- _rangeEncoder.FlushData();
- return _rangeEncoder.FlushStream();
+ _rc.FlushData();
+ return _rc.FlushStream();
}
-const UInt32 kDefaultLimit = (1 << 24);
-
HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams,
ICompressProgressInfo *progress)
@@ -64,32 +49,34 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSiz
if (numInStreams != 1 || numOutStreams != 4)
return E_INVALIDARG;
- if (!Create())
- return E_OUTOFMEMORY;
+ if (!_mainStream.Create(1 << 18)) return E_OUTOFMEMORY;
+ if (!_callStream.Create(1 << 18)) return E_OUTOFMEMORY;
+ if (!_jumpStream.Create(1 << 18)) return E_OUTOFMEMORY;
+ if (!_rc.Create(1 << 20)) return E_OUTOFMEMORY;
+ if (_buf == 0)
+ {
+ _buf = (Byte *)MidAlloc(kBufSize);
+ if (_buf == 0)
+ return E_OUTOFMEMORY;
+ }
bool sizeIsDefined = false;
UInt64 inSize = 0;
- if (inSizes != NULL)
- if (inSizes[0] != NULL)
+ if (inSizes)
+ if (inSizes[0])
{
inSize = *inSizes[0];
if (inSize <= kDefaultLimit)
sizeIsDefined = true;
}
- CCoderReleaser releaser(this);
-
ISequentialInStream *inStream = inStreams[0];
- _mainStream.SetStream(outStreams[0]);
- _mainStream.Init();
- _callStream.SetStream(outStreams[1]);
- _callStream.Init();
- _jumpStream.SetStream(outStreams[2]);
- _jumpStream.Init();
- _rangeEncoder.SetStream(outStreams[3]);
- _rangeEncoder.Init();
- for (int i = 0; i < 256 + 2; i++)
+ _mainStream.SetStream(outStreams[0]); _mainStream.Init();
+ _callStream.SetStream(outStreams[1]); _callStream.Init();
+ _jumpStream.SetStream(outStreams[2]); _jumpStream.Init();
+ _rc.SetStream(outStreams[3]); _rc.Init();
+ for (unsigned i = 0; i < 256 + 2; i++)
_statusEncoder[i].Init();
CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
@@ -99,12 +86,12 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSiz
UInt32 nowPos = 0;
UInt64 nowPos64 = 0;
- UInt32 bufferPos = 0;
+ UInt32 bufPos = 0;
Byte prevByte = 0;
UInt64 subStreamIndex = 0;
- UInt64 subStreamStartPos = 0;
+ UInt64 subStreamStartPos = 0;
UInt64 subStreamEndPos = 0;
for (;;)
@@ -112,23 +99,23 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSiz
UInt32 processedSize = 0;
for (;;)
{
- UInt32 size = kBufferSize - (bufferPos + processedSize);
+ UInt32 size = kBufSize - (bufPos + processedSize);
UInt32 processedSizeLoc;
if (size == 0)
break;
- RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc));
+ RINOK(inStream->Read(_buf + bufPos + processedSize, size, &processedSizeLoc));
if (processedSizeLoc == 0)
break;
processedSize += processedSizeLoc;
}
- UInt32 endPos = bufferPos + processedSize;
-
+ UInt32 endPos = bufPos + processedSize;
+
if (endPos < 5)
{
// change it
- for (bufferPos = 0; bufferPos < endPos; bufferPos++)
+ for (bufPos = 0; bufPos < endPos; bufPos++)
{
- Byte b = _buffer[bufferPos];
+ Byte b = _buf[bufPos];
_mainStream.WriteByte(b);
UInt32 index;
if (b == 0xE8)
@@ -142,37 +129,37 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSiz
prevByte = b;
continue;
}
- _statusEncoder[index].Encode(&_rangeEncoder, 0);
+ _statusEncoder[index].Encode(&_rc, 0);
prevByte = b;
}
return Flush();
}
- bufferPos = 0;
+ bufPos = 0;
UInt32 limit = endPos - 5;
- while(bufferPos <= limit)
+ while (bufPos <= limit)
{
- Byte b = _buffer[bufferPos];
+ Byte b = _buf[bufPos];
_mainStream.WriteByte(b);
if (!IsJ(prevByte, b))
{
- bufferPos++;
+ bufPos++;
prevByte = b;
continue;
}
- Byte nextByte = _buffer[bufferPos + 4];
+ Byte nextByte = _buf[bufPos + 4];
UInt32 src =
(UInt32(nextByte) << 24) |
- (UInt32(_buffer[bufferPos + 3]) << 16) |
- (UInt32(_buffer[bufferPos + 2]) << 8) |
- (_buffer[bufferPos + 1]);
- UInt32 dest = (nowPos + bufferPos + 5) + src;
+ (UInt32(_buf[bufPos + 3]) << 16) |
+ (UInt32(_buf[bufPos + 2]) << 8) |
+ (_buf[bufPos + 1]);
+ UInt32 dest = (nowPos + bufPos + 5) + src;
// if (Test86MSByte(nextByte))
bool convert;
- if (getSubStreamSize != NULL)
+ if (getSubStreamSize)
{
- UInt64 currentPos = (nowPos64 + bufferPos);
+ UInt64 currentPos = (nowPos64 + bufPos);
while (subStreamEndPos < currentPos)
{
UInt64 subStreamSize;
@@ -214,8 +201,8 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSiz
unsigned index = GetIndex(prevByte, b);
if (convert)
{
- _statusEncoder[index].Encode(&_rangeEncoder, 1);
- bufferPos += 5;
+ _statusEncoder[index].Encode(&_rc, 1);
+ bufPos += 5;
COutBuffer &s = (b == 0xE8) ? _callStream : _jumpStream;
for (int i = 24; i >= 0; i -= 8)
s.WriteByte((Byte)(dest >> i));
@@ -223,30 +210,30 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSiz
}
else
{
- _statusEncoder[index].Encode(&_rangeEncoder, 0);
- bufferPos++;
+ _statusEncoder[index].Encode(&_rc, 0);
+ bufPos++;
prevByte = b;
}
}
- nowPos += bufferPos;
- nowPos64 += bufferPos;
+ nowPos += bufPos;
+ nowPos64 += bufPos;
- if (progress != NULL)
+ if (progress)
{
/*
const UInt64 compressedSize =
_mainStream.GetProcessedSize() +
_callStream.GetProcessedSize() +
_jumpStream.GetProcessedSize() +
- _rangeEncoder.GetProcessedSize();
+ _rc.GetProcessedSize();
*/
RINOK(progress->SetRatioInfo(&nowPos64, NULL));
}
-
+
UInt32 i = 0;
- while(bufferPos < endPos)
- _buffer[i++] = _buffer[bufferPos++];
- bufferPos = i;
+ while (bufPos < endPos)
+ _buf[i++] = _buf[bufPos++];
+ bufPos = i;
}
}
@@ -284,46 +271,39 @@ HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams, const UInt64 ** /* i
if (numInStreams != 4 || numOutStreams != 1)
return E_INVALIDARG;
- if (!_mainInStream.Create(_inBufSizes[0]))
- return E_OUTOFMEMORY;
- if (!_callStream.Create(_inBufSizes[1]))
- return E_OUTOFMEMORY;
- if (!_jumpStream.Create(_inBufSizes[2]))
- return E_OUTOFMEMORY;
- if (!_rangeDecoder.Create(_inBufSizes[3]))
- return E_OUTOFMEMORY;
- if (!_outStream.Create(_outBufSize))
- return E_OUTOFMEMORY;
-
- CCoderReleaser releaser(this);
+ if (!_mainStream.Create(_inBufSizes[0])) return E_OUTOFMEMORY;
+ if (!_callStream.Create(_inBufSizes[1])) return E_OUTOFMEMORY;
+ if (!_jumpStream.Create(_inBufSizes[2])) return E_OUTOFMEMORY;
+ if (!_rc.Create(_inBufSizes[3])) return E_OUTOFMEMORY;
+ if (!_outStream.Create(_outBufSize)) return E_OUTOFMEMORY;
- _mainInStream.SetStream(inStreams[0]);
+ _mainStream.SetStream(inStreams[0]);
_callStream.SetStream(inStreams[1]);
_jumpStream.SetStream(inStreams[2]);
- _rangeDecoder.SetStream(inStreams[3]);
+ _rc.SetStream(inStreams[3]);
_outStream.SetStream(outStreams[0]);
- _mainInStream.Init();
+ _mainStream.Init();
_callStream.Init();
_jumpStream.Init();
- _rangeDecoder.Init();
+ _rc.Init();
_outStream.Init();
- for (int i = 0; i < 256 + 2; i++)
+ for (unsigned i = 0; i < 256 + 2; i++)
_statusDecoder[i].Init();
Byte prevByte = 0;
UInt32 processedBytes = 0;
for (;;)
{
- if (processedBytes >= (1 << 20) && progress != NULL)
+ if (processedBytes >= (1 << 20) && progress)
{
/*
const UInt64 compressedSize =
- _mainInStream.GetProcessedSize() +
+ _mainStream.GetProcessedSize() +
_callStream.GetProcessedSize() +
_jumpStream.GetProcessedSize() +
- _rangeDecoder.GetProcessedSize();
+ _rc.GetProcessedSize();
*/
const UInt64 nowPos64 = _outStream.GetProcessedSize();
RINOK(progress->SetRatioInfo(NULL, &nowPos64));
@@ -334,8 +314,8 @@ HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams, const UInt64 ** /* i
const UInt32 kBurstSize = (1 << 18);
for (i = 0; i < kBurstSize; i++)
{
- if (!_mainInStream.ReadByte(b))
- return Flush();
+ if (!_mainStream.ReadByte(b))
+ return _outStream.Flush();
_outStream.WriteByte(b);
if (IsJ(prevByte, b))
break;
@@ -345,14 +325,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams, const UInt64 ** /* i
if (i == kBurstSize)
continue;
unsigned index = GetIndex(prevByte, b);
- if (_statusDecoder[index].Decode(&_rangeDecoder) == 1)
+ if (_statusDecoder[index].Decode(&_rc) == 1)
{
UInt32 src = 0;
CInBuffer &s = (b == 0xE8) ? _callStream : _jumpStream;
- for (int i = 0; i < 4; i++)
+ for (unsigned i = 0; i < 4; i++)
{
Byte b0;
- if(!s.ReadByte(b0))
+ if (!s.ReadByte(b0))
return S_FALSE;
src <<= 8;
src |= ((UInt32)b0);
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/Bcj2Coder.h b/src/libs/7zip/unix/CPP/7zip/Compress/Bcj2Coder.h
index 79a713f17..e7bd37951 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/Bcj2Coder.h
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/Bcj2Coder.h
@@ -12,7 +12,7 @@
namespace NCompress {
namespace NBcj2 {
-const int kNumMoveBits = 5;
+const unsigned kNumMoveBits = 5;
#ifndef EXTRACT_ONLY
@@ -20,32 +20,15 @@ class CEncoder:
public ICompressCoder2,
public CMyUnknownImp
{
- Byte *_buffer;
- bool Create();
+ Byte *_buf;
COutBuffer _mainStream;
COutBuffer _callStream;
COutBuffer _jumpStream;
- NCompress::NRangeCoder::CEncoder _rangeEncoder;
- NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusEncoder[256 + 2];
+ NRangeCoder::CEncoder _rc;
+ NRangeCoder::CBitEncoder<kNumMoveBits> _statusEncoder[256 + 2];
HRESULT Flush();
-public:
- void ReleaseStreams()
- {
- _mainStream.ReleaseStream();
- _callStream.ReleaseStream();
- _jumpStream.ReleaseStream();
- _rangeEncoder.ReleaseStream();
- }
-
- class CCoderReleaser
- {
- CEncoder *_coder;
- public:
- CCoderReleaser(CEncoder *coder): _coder(coder) {}
- ~CCoderReleaser() { _coder->ReleaseStreams(); }
- };
public:
MY_UNKNOWN_IMP
@@ -56,7 +39,8 @@ public:
STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
ICompressProgressInfo *progress);
- CEncoder(): _buffer(0) {};
+
+ CEncoder(): _buf(0) {};
~CEncoder();
};
@@ -67,37 +51,19 @@ class CDecoder:
public ICompressSetBufSize,
public CMyUnknownImp
{
- CInBuffer _mainInStream;
+ CInBuffer _mainStream;
CInBuffer _callStream;
CInBuffer _jumpStream;
- NCompress::NRangeCoder::CDecoder _rangeDecoder;
- NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusDecoder[256 + 2];
+ NRangeCoder::CDecoder _rc;
+ NRangeCoder::CBitDecoder<kNumMoveBits> _statusDecoder[256 + 2];
COutBuffer _outStream;
UInt32 _inBufSizes[4];
UInt32 _outBufSize;
public:
- void ReleaseStreams()
- {
- _mainInStream.ReleaseStream();
- _callStream.ReleaseStream();
- _jumpStream.ReleaseStream();
- _rangeDecoder.ReleaseStream();
- _outStream.ReleaseStream();
- }
-
- HRESULT Flush() { return _outStream.Flush(); }
- class CCoderReleaser
- {
- CDecoder *_coder;
- public:
- CCoderReleaser(CDecoder *coder): _coder(coder) {}
- ~CCoderReleaser() { _coder->ReleaseStreams(); }
- };
-
-public:
MY_UNKNOWN_IMP1(ICompressSetBufSize);
+
HRESULT CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
ICompressProgressInfo *progress);
@@ -107,6 +73,7 @@ public:
STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
+
CDecoder();
};
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/BranchMisc.cpp b/src/libs/7zip/unix/CPP/7zip/Compress/BranchMisc.cpp
index 423b723ab..239f25138 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/BranchMisc.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/BranchMisc.cpp
@@ -6,32 +6,16 @@
#include "BranchMisc.h"
-UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::ARM_Convert(data, size, _bufferPos, 1); }
-
-UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::ARM_Convert(data, size, _bufferPos, 0); }
-
-UInt32 CBC_ARMT_Encoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::ARMT_Convert(data, size, _bufferPos, 1); }
-
-UInt32 CBC_ARMT_Decoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::ARMT_Convert(data, size, _bufferPos, 0); }
-
-UInt32 CBC_PPC_Encoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::PPC_Convert(data, size, _bufferPos, 1); }
-
-UInt32 CBC_PPC_Decoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::PPC_Convert(data, size, _bufferPos, 0); }
-
-UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::SPARC_Convert(data, size, _bufferPos, 1); }
-
-UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::SPARC_Convert(data, size, _bufferPos, 0); }
-
-UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::IA64_Convert(data, size, _bufferPos, 1); }
-
-UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size)
- { return (UInt32)::IA64_Convert(data, size, _bufferPos, 0); }
+#define SUB_FILTER_IMP2(name, coderStr, coderNum) \
+ UInt32 CBC_ ## name ## coderStr::SubFilter(Byte *data, UInt32 size) \
+ { return (UInt32)::name ## Convert(data, size, _bufferPos, coderNum); }
+
+#define SUB_FILTER_IMP(name) \
+ SUB_FILTER_IMP2(name, Encoder, 1) \
+ SUB_FILTER_IMP2(name, Decoder, 0) \
+
+SUB_FILTER_IMP(ARM_)
+SUB_FILTER_IMP(ARMT_)
+SUB_FILTER_IMP(PPC_)
+SUB_FILTER_IMP(SPARC_)
+SUB_FILTER_IMP(IA64_)
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/CodecExports.cpp b/src/libs/7zip/unix/CPP/7zip/Compress/CodecExports.cpp
deleted file mode 100644
index 4ff1c0fcb..000000000
--- a/src/libs/7zip/unix/CPP/7zip/Compress/CodecExports.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-// CodecExports.cpp
-
-#include "StdAfx.h"
-
-#include "../../Common/ComTry.h"
-
-#include "../../Windows/PropVariant.h"
-
-#include "../ICoder.h"
-
-#include "../Common/RegisterCodec.h"
-
-extern unsigned int g_NumCodecs;
-extern const CCodecInfo *g_Codecs[];
-
-static const UInt16 kDecodeId = 0x2790;
-
-DEFINE_GUID(CLSID_CCodec,
-0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
-
-static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value)
-{
- if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
- value->vt = VT_BSTR;
- return S_OK;
-}
-
-static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
-{
- return SetPropString((const char *)&guid, sizeof(GUID), value);
-}
-
-static HRESULT SetClassID(CMethodId id, bool encode, PROPVARIANT *value)
-{
- GUID clsId = CLSID_CCodec;
- for (int i = 0; i < sizeof(id); i++, id >>= 8)
- clsId.Data4[i] = (Byte)(id & 0xFF);
- if (encode)
- clsId.Data3++;
- return SetPropGUID(clsId, value);
-}
-
-static HRESULT FindCodecClassId(const GUID *clsID, UInt32 isCoder2, bool isFilter, bool &encode, int &index)
-{
- index = -1;
- if (clsID->Data1 != CLSID_CCodec.Data1 ||
- clsID->Data2 != CLSID_CCodec.Data2 ||
- (clsID->Data3 & ~1) != kDecodeId)
- return S_OK;
- encode = (clsID->Data3 != kDecodeId);
- UInt64 id = 0;
- for (int j = 0; j < 8; j++)
- id |= ((UInt64)clsID->Data4[j]) << (8 * j);
- for (unsigned i = 0; i < g_NumCodecs; i++)
- {
- const CCodecInfo &codec = *g_Codecs[i];
- if (id != codec.Id || encode && !codec.CreateEncoder || !encode && !codec.CreateDecoder)
- continue;
- if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter ||
- codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2)
- return E_NOINTERFACE;
- index = i;
- return S_OK;
- }
- return S_OK;
-}
-
-STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject)
-{
- COM_TRY_BEGIN
- *outObject = 0;
- bool isCoder = (*iid == IID_ICompressCoder) != 0;
- bool isCoder2 = (*iid == IID_ICompressCoder2) != 0;
- bool isFilter = (*iid == IID_ICompressFilter) != 0;
- const CCodecInfo &codec = *g_Codecs[index];
- if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter ||
- codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2)
- return E_NOINTERFACE;
- if (encode)
- {
- if (!codec.CreateEncoder)
- return CLASS_E_CLASSNOTAVAILABLE;
- *outObject = codec.CreateEncoder();
- }
- else
- {
- if (!codec.CreateDecoder)
- return CLASS_E_CLASSNOTAVAILABLE;
- *outObject = codec.CreateDecoder();
- }
- if (isCoder)
- ((ICompressCoder *)*outObject)->AddRef();
- else if (isCoder2)
- ((ICompressCoder2 *)*outObject)->AddRef();
- else
- ((ICompressFilter *)*outObject)->AddRef();
- return S_OK;
- COM_TRY_END
-}
-
-STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject)
-{
- *outObject = 0;
- bool isCoder = (*iid == IID_ICompressCoder) != 0;
- bool isCoder2 = (*iid == IID_ICompressCoder2) != 0;
- bool isFilter = (*iid == IID_ICompressFilter) != 0;
- if (!isCoder && !isCoder2 && !isFilter)
- return E_NOINTERFACE;
- bool encode;
- int codecIndex;
- HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex);
- if (res != S_OK)
- return res;
- if (codecIndex < 0)
- return CLASS_E_CLASSNOTAVAILABLE;
- return CreateCoder2(encode, codecIndex, iid, outObject);
-}
-
-STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)
-{
- ::VariantClear((VARIANTARG *)value);
- const CCodecInfo &codec = *g_Codecs[codecIndex];
- switch(propID)
- {
- case NMethodPropID::kID:
- {
- value->uhVal.QuadPart = (UInt64)codec.Id;
- value->vt = VT_UI8;
- break;
- }
- case NMethodPropID::kName:
- if ((value->bstrVal = ::SysAllocString(codec.Name)) != 0)
- value->vt = VT_BSTR;
- break;
- case NMethodPropID::kDecoder:
- if (codec.CreateDecoder)
- return SetClassID(codec.Id, false, value);
- break;
- case NMethodPropID::kEncoder:
- if (codec.CreateEncoder)
- return SetClassID(codec.Id, true, value);
- break;
- case NMethodPropID::kInStreams:
- {
- if (codec.NumInStreams != 1)
- {
- value->vt = VT_UI4;
- value->ulVal = (ULONG)codec.NumInStreams;
- }
- break;
- }
- }
- return S_OK;
-}
-
-STDAPI GetNumberOfMethods(UINT32 *numCodecs)
-{
- *numCodecs = g_NumCodecs;
- return S_OK;
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/Compress.pri b/src/libs/7zip/unix/CPP/7zip/Compress/Compress.pri
new file mode 100644
index 000000000..c9a7a5045
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/Compress.pri
@@ -0,0 +1,29 @@
+HEADERS += $$7ZIP_BASE/CPP/7zip/Compress/Bcj2Coder.h \
+ $$7ZIP_BASE/CPP/7zip/Compress/BcjCoder.h \
+ $$7ZIP_BASE/CPP/7zip/Compress/BranchCoder.h \
+ $$7ZIP_BASE/CPP/7zip/Compress/BranchMisc.h \
+ $$7ZIP_BASE/CPP/7zip/Compress/CopyCoder.h \
+ $$7ZIP_BASE/CPP/7zip/Compress/Lzma2Decoder.h \
+ $$7ZIP_BASE/CPP/7zip/Compress/Lzma2Encoder.h \
+ $$7ZIP_BASE/CPP/7zip/Compress/LzmaDecoder.h \
+ $$7ZIP_BASE/CPP/7zip/Compress/LzmaEncoder.h \
+ $$7ZIP_BASE/CPP/7zip/Compress/RangeCoder.h \
+ $$7ZIP_BASE/CPP/7zip/Compress/RangeCoderBit.h
+
+SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/Bcj2Coder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/Bcj2Register.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/BcjCoder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/BcjRegister.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/BranchCoder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/BranchMisc.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/BranchRegister.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/ByteSwap.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/CopyCoder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/CopyRegister.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/DeltaFilter.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/Lzma2Decoder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/Lzma2Encoder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/Lzma2Register.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/LzmaDecoder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/LzmaEncoder.cpp \
+ $$7ZIP_BASE/CPP/7zip/Compress/LzmaRegister.cpp
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/CopyCoder.cpp b/src/libs/7zip/unix/CPP/7zip/Compress/CopyCoder.cpp
index f71692a77..f0863202a 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/CopyCoder.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/CopyCoder.cpp
@@ -22,10 +22,10 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
const UInt64 * /* inSize */, const UInt64 *outSize,
ICompressProgressInfo *progress)
{
- if (_buffer == 0)
+ if (!_buffer)
{
_buffer = (Byte *)::MidAlloc(kBufferSize);
- if (_buffer == 0)
+ if (!_buffer)
return E_OUTOFMEMORY;
}
@@ -33,9 +33,8 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
for (;;)
{
UInt32 size = kBufferSize;
- if (outSize != 0)
- if (size > *outSize - TotalSize)
- size = (UInt32)(*outSize - TotalSize);
+ if (outSize && size > *outSize - TotalSize)
+ size = (UInt32)(*outSize - TotalSize);
RINOK(inStream->Read(_buffer, size, &size));
if (size == 0)
break;
@@ -44,7 +43,7 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
RINOK(WriteStream(outStream, _buffer, size));
}
TotalSize += size;
- if (progress != NULL)
+ if (progress)
{
RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
}
@@ -60,8 +59,16 @@ STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value)
HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
{
- CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ CMyComPtr<ICompressCoder> copyCoder = new CCopyCoder;
return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
}
+HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress)
+{
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+ RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress));
+ return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL;
+}
+
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/CopyCoder.h b/src/libs/7zip/unix/CPP/7zip/Compress/CopyCoder.h
index c5445ccf8..5e0bb6436 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/CopyCoder.h
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/CopyCoder.h
@@ -28,6 +28,7 @@ public:
};
HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
+HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress);
}
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/DeltaFilter.cpp b/src/libs/7zip/unix/CPP/7zip/Compress/DeltaFilter.cpp
index 2e421acf4..d8378a60e 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/DeltaFilter.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/DeltaFilter.cpp
@@ -62,9 +62,22 @@ STDMETHODIMP CDeltaEncoder::SetCoderProperties(const PROPID *propIDs, const PROP
for (UInt32 i = 0; i < numProps; i++)
{
const PROPVARIANT &prop = props[i];
- if (propIDs[i] != NCoderPropID::kDefaultProp || prop.vt != VT_UI4 || prop.ulVal < 1 || prop.ulVal > 256)
+ PROPID propID = propIDs[i];
+ if (propID >= NCoderPropID::kReduceSize)
+ continue;
+ if (prop.vt != VT_UI4)
return E_INVALIDARG;
- delta = prop.ulVal;
+ switch (propID)
+ {
+ case NCoderPropID::kDefaultProp:
+ delta = (UInt32)prop.ulVal;
+ if (delta < 1 || delta > 256)
+ return E_INVALIDARG;
+ break;
+ case NCoderPropID::kNumThreads: break;
+ case NCoderPropID::kLevel: break;
+ default: return E_INVALIDARG;
+ }
}
_delta = delta;
return S_OK;
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Decoder.cpp b/src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Decoder.cpp
index 322015e29..b20ae5f5e 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Decoder.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Decoder.cpp
@@ -66,7 +66,7 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
_outSize = *outSize;
Lzma2Dec_Init(&_state);
-
+
_inPos = _inSize = 0;
_inSizeProcessed = _outSizeProcessed = 0;
return S_OK;
@@ -93,7 +93,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
const UInt32 kStepSize = ((UInt32)1 << 22);
if (curSize > kStepSize)
curSize = (SizeT)kStepSize;
-
+
ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
if (_outSizeDefined)
{
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Encoder.cpp b/src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Encoder.cpp
index 5e4c71bea..f867881c0 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Encoder.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Encoder.cpp
@@ -90,5 +90,5 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
return progressWrap.Res;
return SResToHRESULT(res);
}
-
+
}}
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Encoder.h b/src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Encoder.h
index f0fb74d33..6a2318076 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Encoder.h
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/Lzma2Encoder.h
@@ -21,7 +21,7 @@ class CEncoder:
CLzma2EncHandle _encoder;
public:
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties)
-
+
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/LzmaDecoder.cpp b/src/libs/7zip/unix/CPP/7zip/Compress/LzmaDecoder.cpp
index b7c260bd9..d378ba668 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/LzmaDecoder.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/LzmaDecoder.cpp
@@ -27,7 +27,8 @@ namespace NLzma {
CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false),
_inBufSize(1 << 20),
_outBufSize(1 << 22),
- FinishStream(false)
+ FinishStream(false),
+ NeedMoreInput(false)
{
_inSizeProcessed = 0;
_inPos = _inSize = 0;
@@ -81,6 +82,7 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
_inSizeProcessed = 0;
_inPos = _inSize = 0;
+ NeedMoreInput = false;
SetOutStreamSizeResume(outSize);
return S_OK;
}
@@ -103,7 +105,7 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
SizeT dicPos = _state.dicPos;
SizeT curSize = next - dicPos;
-
+
ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
if (_outSizeDefined)
{
@@ -144,9 +146,21 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
return S_FALSE;
RINOK(res2);
if (stopDecoding)
+ {
+ if (status == LZMA_STATUS_NEEDS_MORE_INPUT)
+ NeedMoreInput = true;
+ if (FinishStream &&
+ status != LZMA_STATUS_FINISHED_WITH_MARK &&
+ status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
+ return S_FALSE;
return S_OK;
+ }
if (finished)
+ {
+ if (status == LZMA_STATUS_NEEDS_MORE_INPUT)
+ NeedMoreInput = true;
return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE);
+ }
}
if (progress)
{
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/LzmaDecoder.h b/src/libs/7zip/unix/CPP/7zip/Compress/LzmaDecoder.h
index d28a4634b..140c48b9c 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/LzmaDecoder.h
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/LzmaDecoder.h
@@ -62,7 +62,7 @@ public:
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
#ifndef NO_READ_FROM_CODER
-
+
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
@@ -73,10 +73,14 @@ public:
#endif
- bool FinishStream;
+ bool FinishStream; // set it before decoding, if you need to decode full LZMA stream
+
+ bool NeedMoreInput; // it's set by decoder, if it needs more input data to decode stream
CDecoder();
virtual ~CDecoder();
+
+ UInt64 GetOutputProcessedSize() const { return _outSizeProcessed; }
};
}}
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/LzmaEncoder.cpp b/src/libs/7zip/unix/CPP/7zip/Compress/LzmaEncoder.cpp
index 9bdedaeb6..484d04523 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/LzmaEncoder.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/LzmaEncoder.cpp
@@ -73,6 +73,8 @@ static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes)
return 1;
}
+#define SET_PROP_32(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = v; break;
+
HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
{
if (propID == NCoderPropID::kMatchFinder)
@@ -81,18 +83,29 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
return E_INVALIDARG;
return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG;
}
+ if (propID > NCoderPropID::kReduceSize)
+ return S_OK;
+ if (propID == NCoderPropID::kReduceSize)
+ {
+ if (prop.vt == VT_UI8)
+ ep.reduceSize = prop.uhVal.QuadPart;
+ return S_OK;
+ }
if (prop.vt != VT_UI4)
return E_INVALIDARG;
UInt32 v = prop.ulVal;
switch (propID)
{
- case NCoderPropID::kNumFastBytes: ep.fb = v; break;
- case NCoderPropID::kMatchFinderCycles: ep.mc = v; break;
- case NCoderPropID::kAlgorithm: ep.algo = v; break;
- case NCoderPropID::kDictionarySize: ep.dictSize = v; break;
- case NCoderPropID::kPosStateBits: ep.pb = v; break;
- case NCoderPropID::kLitPosBits: ep.lp = v; break;
- case NCoderPropID::kLitContextBits: ep.lc = v; break;
+ case NCoderPropID::kDefaultProp: if (v > 31) return E_INVALIDARG; ep.dictSize = (UInt32)1 << (unsigned)v; break;
+ SET_PROP_32(kLevel, level)
+ SET_PROP_32(kNumFastBytes, fb)
+ SET_PROP_32(kMatchFinderCycles, mc)
+ SET_PROP_32(kAlgorithm, algo)
+ SET_PROP_32(kDictionarySize, dictSize)
+ SET_PROP_32(kPosStateBits, pb)
+ SET_PROP_32(kLitPosBits, lp)
+ SET_PROP_32(kLitContextBits, lc)
+ SET_PROP_32(kNumThreads, numThreads)
default: return E_INVALIDARG;
}
return S_OK;
@@ -111,9 +124,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
switch (propID)
{
case NCoderPropID::kEndMarker:
- if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal == VARIANT_TRUE); break;
- case NCoderPropID::kNumThreads:
- if (prop.vt != VT_UI4) return E_INVALIDARG; props.numThreads = prop.ulVal; break;
+ if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal != VARIANT_FALSE); break;
default:
RINOK(SetLzmaProp(propID, prop, props));
}
@@ -137,6 +148,7 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
CCompressProgressWrap progressWrap(progress);
SRes res = LzmaEnc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL, &g_Alloc, &g_BigAlloc);
+ _inputProcessed = inWrap.Processed;
if (res == SZ_ERROR_READ && inWrap.Res != S_OK)
return inWrap.Res;
if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK)
@@ -145,5 +157,5 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
return progressWrap.Res;
return SResToHRESULT(res);
}
-
+
}}
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/LzmaEncoder.h b/src/libs/7zip/unix/CPP/7zip/Compress/LzmaEncoder.h
index 904c0002c..7e15a132d 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/LzmaEncoder.h
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/LzmaEncoder.h
@@ -19,9 +19,10 @@ class CEncoder:
public CMyUnknownImp
{
CLzmaEncHandle _encoder;
+ UInt64 _inputProcessed;
public:
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties)
-
+
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
@@ -29,6 +30,7 @@ public:
CEncoder();
virtual ~CEncoder();
+ UInt64 GetInputProcessedSize() const { return _inputProcessed; }
};
}}
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/RangeCoder.h b/src/libs/7zip/unix/CPP/7zip/Compress/RangeCoder.h
index 1eb2a6d47..1555bd705 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/RangeCoder.h
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/RangeCoder.h
@@ -1,5 +1,5 @@
// Compress/RangeCoder.h
-// 2009-05-30 : Igor Pavlov : Public domain
+// 2013-01-10 : Igor Pavlov : Public domain
#ifndef __COMPRESS_RANGE_CODER_H
#define __COMPRESS_RANGE_CODER_H
@@ -10,7 +10,7 @@
namespace NCompress {
namespace NRangeCoder {
-const int kNumTopBits = 24;
+const unsigned kNumTopBits = 24;
const UInt32 kTopValue = (1 << kNumTopBits);
class CEncoder
@@ -21,7 +21,7 @@ public:
UInt64 Low;
UInt32 Range;
COutBuffer Stream;
- bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+ bool Create(UInt32 bufSize) { return Stream.Create(bufSize); }
void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
void Init()
@@ -36,14 +36,12 @@ public:
void FlushData()
{
// Low += 1;
- for(int i = 0; i < 5; i++)
+ for (int i = 0; i < 5; i++)
ShiftLow();
}
HRESULT FlushStream() { return Stream.Flush(); }
- void ReleaseStream() { Stream.ReleaseStream(); }
-
void Encode(UInt32 start, UInt32 size, UInt32 total)
{
Low += start * (Range /= total);
@@ -57,7 +55,7 @@ public:
void ShiftLow()
{
- if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
+ if ((UInt32)Low < (UInt32)0xFF000000 || (unsigned)(Low >> 32) != 0)
{
Byte temp = _cache;
do
@@ -65,13 +63,13 @@ public:
Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
temp = 0xFF;
}
- while(--_cacheSize != 0);
+ while (--_cacheSize != 0);
_cache = (Byte)((UInt32)Low >> 24);
}
_cacheSize++;
Low = (UInt32)Low << 8;
}
-
+
void EncodeDirectBits(UInt32 value, int numBits)
{
for (numBits--; numBits >= 0; numBits--)
@@ -103,7 +101,7 @@ public:
}
}
- UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
+ UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
};
class CDecoder
@@ -112,7 +110,7 @@ public:
CInBuffer Stream;
UInt32 Range;
UInt32 Code;
- bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+ bool Create(UInt32 bufSize) { return Stream.Create(bufSize); }
void Normalize()
{
@@ -122,22 +120,20 @@ public:
Range <<= 8;
}
}
-
+
void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
void Init()
{
Stream.Init();
Code = 0;
Range = 0xFFFFFFFF;
- for(int i = 0; i < 5; i++)
+ for (int i = 0; i < 5; i++)
Code = (Code << 8) | Stream.ReadByte();
}
- void ReleaseStream() { Stream.ReleaseStream(); }
-
UInt32 GetThreshold(UInt32 total)
{
- return (Code) / ( Range /= total);
+ return (Code) / (Range /= total);
}
void Decode(UInt32 start, UInt32 size)
@@ -197,7 +193,7 @@ public:
return symbol;
}
- UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
+ UInt64 GetProcessedSize() { return Stream.GetProcessedSize(); }
};
}}
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/RangeCoderBit.h b/src/libs/7zip/unix/CPP/7zip/Compress/RangeCoderBit.h
index b5a1830d6..0eddd5586 100644
--- a/src/libs/7zip/unix/CPP/7zip/Compress/RangeCoderBit.h
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/RangeCoderBit.h
@@ -1,5 +1,5 @@
// Compress/RangeCoderBit.h
-// 2009-05-30 : Igor Pavlov : Public domain
+// 2013-01-10 : Igor Pavlov : Public domain
#ifndef __COMPRESS_RANGE_CODER_BIT_H
#define __COMPRESS_RANGE_CODER_BIT_H
@@ -9,17 +9,17 @@
namespace NCompress {
namespace NRangeCoder {
-const int kNumBitModelTotalBits = 11;
+const unsigned kNumBitModelTotalBits = 11;
const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
-const int kNumMoveReducingBits = 4;
+const unsigned kNumMoveReducingBits = 4;
-const int kNumBitPriceShiftBits = 4;
+const unsigned kNumBitPriceShiftBits = 4;
const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
extern UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
-template <int numMoveBits>
+template <unsigned numMoveBits>
class CBitModel
{
public:
@@ -39,7 +39,7 @@ public:
void Init() { Prob = kBitModelTotal / 2; }
};
-template <int numMoveBits>
+template <unsigned numMoveBits>
class CBitEncoder: public CBitModel<numMoveBits>
{
public:
@@ -69,14 +69,14 @@ public:
}
UInt32 GetPrice(UInt32 symbol) const
{
- return ProbPrices[(this->Prob ^ ((-(int)symbol)) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
+ return ProbPrices[(this->Prob ^ ((-(int)(Int32)symbol)) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
}
UInt32 GetPrice0() const { return ProbPrices[this->Prob >> kNumMoveReducingBits]; }
UInt32 GetPrice1() const { return ProbPrices[(this->Prob ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]; }
};
-template <int numMoveBits>
+template <unsigned numMoveBits>
class CBitDecoder: public CBitModel<numMoveBits>
{
public:
diff --git a/src/libs/7zip/unix/CPP/7zip/Guid.txt b/src/libs/7zip/unix/CPP/7zip/Guid.txt
index 59a743b96..c1e7446be 100644
--- a/src/libs/7zip/unix/CPP/7zip/Guid.txt
+++ b/src/libs/7zip/unix/CPP/7zip/Guid.txt
@@ -6,14 +6,17 @@
01 IFolderArchive.h
- 05 IArchiveFolder
+ // 05 IArchiveFolder // old
// 06 IInFolderArchive // old
07 IFileExtractCallback.h::IFolderArchiveExtractCallback
- 0A IOutFolderArchive
+ // 0A IOutFolderArchive
0B IFolderArchiveUpdateCallback
0C Agent.h::IArchiveFolderInternal
- 0D
+ 0D IArchiveFolder
0E IInFolderArchive
+ 0F IOutFolderArchive
+ 20 IFileExtractCallback.h::IGetProp
+ 30 IFileExtractCallback.h::IFolderExtractToStreamCallback
03 IStream.h
@@ -23,6 +26,8 @@
04 IOutStream
06 IStreamGetSize
07 IOutStreamFlush
+ 08 IStreamGetProps
+ 09 IStreamGetProps2
04 ICoder.h
@@ -50,6 +55,8 @@
8C ICryptoResetInitVector
90 ICryptoSetPassword
A0 ICryptoSetCRC
+ C0 IHasher
+ C1 IHashers
05 IPassword.h
@@ -61,6 +68,8 @@
06 IArchive.h
03 ISetProperties
+ 04 IArchiveKeepModeForNextOpen
+ 05 IArchiveAllowTail
10 IArchiveOpenCallback
20 IArchiveExtractCallback
@@ -69,6 +78,8 @@
50 IArchiveOpenSetSubArchiveName
60 IInArchive
61 IArchiveOpenSeq
+ 70 IArchiveGetRawProps
+ 71 IArchiveGetRootProps
80 IArchiveUpdateCallback
82 IArchiveUpdateCallback2
@@ -84,18 +95,23 @@
03 IFolderGetPath
04 IFolderWasChanged
05 // IFolderReload
- 06 IFolderOperations
+ 06 // IFolderOperations old
07 IFolderGetSystemIconIndex
08 IFolderGetItemFullSize
09 IFolderClone
0A IFolderSetFlatMode
0B IFolderOperationsExtractCallback
- 0C //
- 0D //
+ 0C //
+ 0D //
0E IFolderProperties
- 0F
+ 0F
10 IFolderArcProps
11 IGetFolderArcProps
+ 12 // IFolderOperations
+ 13 IFolderOperations
+ 14 IFolderCalcItemFullSize
+ 15 IFolderCompare
+ 16 IFolderGetItemName
09 IFolder.h :: FOLDER_MANAGER_INTERFACE
@@ -128,6 +144,11 @@ Handler GUIDs:
0C xz
0D ppmd
+ CD IHex
+ CE Hxs
+ CF TE
+ D0 UEFIc
+ D1 UEFIs
D2 SquashFS
D3 CramFS
D4 APM
@@ -150,7 +171,7 @@ Handler GUIDs:
E5 Compound
E6 Wim
E7 Iso
- E8 Bkf
+ E8
E9 Chm
EA Split
EB Rpm
@@ -168,3 +189,4 @@ Handler GUIDs:
{23170F69-40C1-2790-id} Codec Decoders
{23170F69-40C1-2791-id} Codec Encoders
+{23170F69-40C1-2792-id} Hashers
diff --git a/src/libs/7zip/unix/CPP/7zip/ICoder.h b/src/libs/7zip/unix/CPP/7zip/ICoder.h
index a518de463..74ee0e453 100644
--- a/src/libs/7zip/unix/CPP/7zip/ICoder.h
+++ b/src/libs/7zip/unix/CPP/7zip/ICoder.h
@@ -44,7 +44,9 @@ namespace NCoderPropID
kNumPasses,
kAlgorithm,
kNumThreads,
- kEndMarker
+ kEndMarker,
+ kLevel,
+ kReduceSize // estimated size of data that will be compressed. Encoder can use this value to reduce dictionary size.
};
}
@@ -179,8 +181,31 @@ namespace NMethodPropID
kOutStreams,
kDescription,
kDecoderIsAssigned,
- kEncoderIsAssigned
+ kEncoderIsAssigned,
+ kDigestSize
};
}
+CODER_INTERFACE(IHasher, 0xC0)
+{
+ STDMETHOD_(void, Init)() PURE;
+ STDMETHOD_(void, Update)(const void *data, UInt32 size) PURE;
+ STDMETHOD_(void, Final)(Byte *digest) PURE;
+ STDMETHOD_(UInt32, GetDigestSize)() PURE;
+};
+
+CODER_INTERFACE(IHashers, 0xC1)
+{
+ STDMETHOD_(UInt32, GetNumHashers)() PURE;
+ STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher) PURE;
+};
+
+extern "C"
+{
+ typedef HRESULT (WINAPI *Func_GetNumberOfMethods)(UInt32 *numMethods);
+ typedef HRESULT (WINAPI *Func_GetMethodProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ typedef HRESULT (WINAPI *Func_GetHashers)(IHashers **hashers);
+}
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/IPassword.h b/src/libs/7zip/unix/CPP/7zip/IPassword.h
index 3ca7b090e..7ea45537e 100644
--- a/src/libs/7zip/unix/CPP/7zip/IPassword.h
+++ b/src/libs/7zip/unix/CPP/7zip/IPassword.h
@@ -3,8 +3,8 @@
#ifndef __IPASSWORD_H
#define __IPASSWORD_H
+#include "../Common/MyTypes.h"
#include "../Common/MyUnknown.h"
-#include "../Common/Types.h"
#include "IDecl.h"
@@ -21,4 +21,3 @@ PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11)
};
#endif
-
diff --git a/src/libs/7zip/unix/CPP/7zip/IProgress.h b/src/libs/7zip/unix/CPP/7zip/IProgress.h
index d6093f173..a270e693b 100644
--- a/src/libs/7zip/unix/CPP/7zip/IProgress.h
+++ b/src/libs/7zip/unix/CPP/7zip/IProgress.h
@@ -3,8 +3,8 @@
#ifndef __IPROGRESS_H
#define __IPROGRESS_H
+#include "../Common/MyTypes.h"
#include "../Common/MyUnknown.h"
-#include "../Common/Types.h"
#include "IDecl.h"
diff --git a/src/libs/7zip/unix/CPP/7zip/IStream.h b/src/libs/7zip/unix/CPP/7zip/IStream.h
index 165e8baad..48643e7b3 100644
--- a/src/libs/7zip/unix/CPP/7zip/IStream.h
+++ b/src/libs/7zip/unix/CPP/7zip/IStream.h
@@ -3,8 +3,8 @@
#ifndef __ISTREAM_H
#define __ISTREAM_H
+#include "../Common/MyTypes.h"
#include "../Common/MyUnknown.h"
-#include "../Common/Types.h"
#include "IDecl.h"
@@ -14,26 +14,71 @@
STREAM_INTERFACE(ISequentialInStream, 0x01)
{
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;
+
/*
- Out: if size != 0, return_value = S_OK and (*processedSize == 0),
- then there are no more bytes in stream.
- if (size > 0) && there are bytes in stream,
- this function must read at least 1 byte.
- This function is allowed to read less than number of remaining bytes in stream.
- You must call Read function in loop, if you need exact amount of data
+ The requirement for caller: (processedSize != NULL).
+ The callee can allow (processedSize == NULL) for compatibility reasons.
+
+ if (size == 0), this function returns S_OK and (*processedSize) is set to 0.
+
+ if (size != 0)
+ {
+ Partial read is allowed: (*processedSize <= avail_size && *processedSize <= size),
+ where (avail_size) is the size of remaining bytes in stream.
+ If (avail_size != 0), this function must read at least 1 byte: (*processedSize > 0).
+ You must call Read() in loop, if you need to read exact amount of data.
+ }
+
+ If seek pointer before Read() call was changed to position past the end of stream:
+ if (seek_pointer >= stream_size), this function returns S_OK and (*processedSize) is set to 0.
+
+ ERROR CASES:
+ If the function returns error code, then (*processedSize) is size of
+ data written to (data) buffer (it can be data before error or data with errors).
+ The recommended way for callee to work with reading errors:
+ 1) write part of data before error to (data) buffer and return S_OK.
+ 2) return error code for further calls of Read().
*/
};
STREAM_INTERFACE(ISequentialOutStream, 0x02)
{
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE;
+
/*
- if (size > 0) this function must write at least 1 byte.
- This function is allowed to write less than "size".
- You must call Write function in loop, if you need to write exact amount of data
+ The requirement for caller: (processedSize != NULL).
+ The callee can allow (processedSize == NULL) for compatibility reasons.
+
+ if (size != 0)
+ {
+ Partial write is allowed: (*processedSize <= size),
+ but this function must write at least 1 byte: (*processedSize > 0).
+ You must call Write() in loop, if you need to write exact amount of data.
+ }
+
+ ERROR CASES:
+ If the function returns error code, then (*processedSize) is size of
+ data written from (data) buffer.
*/
};
+#ifdef __HRESULT_FROM_WIN32
+#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK)
+#else
+#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK)
+#endif
+
+/* Seek() Function
+ If you seek before the beginning of the stream, Seek() function returns error code:
+ Recommended error code is __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK).
+ or STG_E_INVALIDFUNCTION
+
+ It is allowed to seek past the end of the stream.
+
+
+ if Seek() returns error, then the value of *newPosition is undefined.
+*/
+
STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
{
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
@@ -55,4 +100,28 @@ STREAM_INTERFACE(IOutStreamFlush, 0x07)
STDMETHOD(Flush)() PURE;
};
+
+STREAM_INTERFACE(IStreamGetProps, 0x08)
+{
+ STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib) PURE;
+};
+
+struct CStreamFileProps
+{
+ UInt64 Size;
+ UInt64 VolID;
+ UInt64 FileID_Low;
+ UInt64 FileID_High;
+ UInt32 NumLinks;
+ UInt32 Attrib;
+ FILETIME CTime;
+ FILETIME ATime;
+ FILETIME MTime;
+};
+
+STREAM_INTERFACE(IStreamGetProps2, 0x09)
+{
+ STDMETHOD(GetProps2)(CStreamFileProps *props) PURE;
+};
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/MyVersion.h b/src/libs/7zip/unix/CPP/7zip/MyVersion.h
deleted file mode 100644
index 3acfb833f..000000000
--- a/src/libs/7zip/unix/CPP/7zip/MyVersion.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#define MY_VER_MAJOR 9
-#define MY_VER_MINOR 20
-#define MY_VER_BUILD 0
-#define MY_VERSION "9.20"
-#define MY_7ZIP_VERSION "7-Zip 9.20"
-#define MY_DATE "2010-11-18"
-#define MY_COPYRIGHT "Copyright (c) 1999-2010 Igor Pavlov"
-#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
-
-#define P7ZIP_VERSION "9.20"
-
diff --git a/src/libs/7zip/unix/CPP/7zip/PropID.h b/src/libs/7zip/unix/CPP/7zip/PropID.h
index 8f8885263..82a7462bb 100644
--- a/src/libs/7zip/unix/CPP/7zip/PropID.h
+++ b/src/libs/7zip/unix/CPP/7zip/PropID.h
@@ -1,13 +1,15 @@
// PropID.h
-#ifndef __7ZIP_PROPID_H
-#define __7ZIP_PROPID_H
+#ifndef __7ZIP_PROP_ID_H
+#define __7ZIP_PROP_ID_H
+
+#include "../Common/MyTypes.h"
enum
{
kpidNoProperty = 0,
- kpidMainSubfile = 1,
- kpidHandlerItemIndex = 2,
+ kpidMainSubfile,
+ kpidHandlerItemIndex,
kpidPath,
kpidName,
kpidExtension,
@@ -59,18 +61,64 @@ enum
kpidCreatorApp,
kpidSectorSize,
kpidPosixAttrib,
- kpidLink,
+ kpidSymLink,
kpidError,
-
- kpidTotalSize = 0x1100,
+ kpidTotalSize,
kpidFreeSpace,
kpidClusterSize,
kpidVolumeName,
-
- kpidLocalName = 0x1200,
+ kpidLocalName,
kpidProvider,
+ kpidNtSecure,
+ kpidIsAltStream,
+ kpidIsAux,
+ kpidIsDeleted,
+ kpidIsTree,
+ kpidSha1,
+ kpidSha256,
+ kpidErrorType,
+ kpidNumErrors,
+ kpidErrorFlags,
+ kpidWarningFlags,
+ kpidWarning,
+ kpidNumStreams,
+ kpidNumAltStreams,
+ kpidAltStreamsSize,
+ kpidVirtualSize,
+ kpidUnpackSize,
+ kpidTotalPhySize,
+ kpidVolumeIndex,
+ kpidSubType,
+ kpidShortComment,
+ kpidCodePage,
+ kpidIsNotArcType,
+ kpidPhySizeCantBeDetected,
+ kpidZerosTailIsAllowed,
+ kpidTailSize,
+ kpidEmbeddedStubSize,
+ kpidNtReparse,
+ kpidHardLink,
+ kpidINode,
+ kpidStreamId,
+
+ kpid_NUM_DEFINED,
kpidUserDefined = 0x10000
};
+extern Byte k7z_PROPID_To_VARTYPE[kpid_NUM_DEFINED]; // VARTYPE
+
+const UInt32 kpv_ErrorFlags_IsNotArc = 1 << 0;
+const UInt32 kpv_ErrorFlags_HeadersError = 1 << 1;
+const UInt32 kpv_ErrorFlags_EncryptedHeadersError = 1 << 2;
+const UInt32 kpv_ErrorFlags_UnavailableStart = 1 << 3;
+const UInt32 kpv_ErrorFlags_UnconfirmedStart = 1 << 4;
+const UInt32 kpv_ErrorFlags_UnexpectedEnd = 1 << 5;
+const UInt32 kpv_ErrorFlags_DataAfterEnd = 1 << 6;
+const UInt32 kpv_ErrorFlags_UnsupportedMethod = 1 << 7;
+const UInt32 kpv_ErrorFlags_UnsupportedFeature = 1 << 8;
+const UInt32 kpv_ErrorFlags_DataError = 1 << 9;
+const UInt32 kpv_ErrorFlags_CrcError = 1 << 10;
+// const UInt32 kpv_ErrorFlags_Unsupported = 1 << 11;
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
index d954129f3..48587264f 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -1,6 +1,8 @@
// ArchiveCommandLine.cpp
#include "StdAfx.h"
+#undef printf
+#undef sprintf
#ifdef _WIN32
#ifndef UNDER_CE
@@ -9,15 +11,15 @@
#endif
#include <stdio.h>
-#include "Common/ListFileUtils.h"
-#include "Common/StringConvert.h"
-#include "Common/StringToInt.h"
+#include "../../../Common/ListFileUtils.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/StringToInt.h"
-#include "Windows/FileDir.h"
-#include "Windows/FileName.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileName.h"
#ifdef _WIN32
-#include "Windows/FileMapping.h"
-#include "Windows/Synchronization.h"
+#include "../../../Windows/FileMapping.h"
+#include "../../../Windows/Synchronization.h"
#else
#include "myPrivate.h"
#endif
@@ -50,6 +52,32 @@ using namespace NCommandLineParser;
using namespace NWindows;
using namespace NFile;
+static bool StringToUInt32(const wchar_t *s, UInt32 &v)
+{
+ if (*s == 0)
+ return false;
+ const wchar_t *end;
+ v = ConvertStringToUInt32(s, &end);
+ return *end == 0;
+}
+
+static void AddNewLine(UString &s)
+{
+ s += L'\n';
+}
+
+CArcCmdLineException::CArcCmdLineException(const char *a, const wchar_t *u)
+{
+ (*this) += MultiByteToUnicodeString(a);
+ if (u)
+ {
+ AddNewLine(*this);
+ (*this) += u;
+ }
+}
+
+int g_CodePage = -1;
+
namespace NKey {
enum Enum
{
@@ -81,22 +109,55 @@ enum Enum
kEmail,
kShowDialog,
kLargePages,
- kUseLStat,
+ // kListfileCharSet,
+ // kConsoleCharSet,
kTechMode,
+#ifdef _WIN32
+ kShareForWrite,
+#endif
+ kUseLStat,
kCaseSensitive,
- kCalcCrc
+ kHash,
+ kArcNameMode,
+
+ kDisableWildcardParsing,
+ kElimDup,
+ kFullPathMode,
+
+ kHardLinks,
+ kSymLinks,
+ kNtSecurity,
+ kAltStreams,
+ kReplaceColonForAltStream,
+ kWriteToAltStreamIfColon,
+
+ kDeleteAfterCompressing,
+ kSetArcMTime,
+ kExcludedArcType
};
}
-static const wchar_t kRecursedIDChar = 'R';
-static const wchar_t *kRecursedPostCharSet = L"0-";
+static const wchar_t kRecursedIDChar = 'r';
+static const char *kRecursedPostCharSet = "0-";
+
+static const char *k_ArcNameMode_PostCharSet = "sea";
+
+static inline const EArcNameMode ParseArcNameMode(int postCharIndex)
+{
+ switch (postCharIndex)
+ {
+ case 1: return k_ArcNameMode_Exact;
+ case 2: return k_ArcNameMode_Add;
+ default: return k_ArcNameMode_Smart;
+ }
+}
namespace NRecursedPostCharIndex {
enum EEnum
{
- kWildCardRecursionOnly = 0,
+ kWildcardRecursionOnly = 0,
kNoRecursion = 1
};
}
@@ -108,133 +169,128 @@ static const char kFileListID = '@';
static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
-static const wchar_t *kOverwritePostCharSet = L"asut";
+static const char *kOverwritePostCharSet = "asut";
NExtract::NOverwriteMode::EEnum k_OverwriteModes[] =
{
- NExtract::NOverwriteMode::kWithoutPrompt,
- NExtract::NOverwriteMode::kSkipExisting,
- NExtract::NOverwriteMode::kAutoRename,
- NExtract::NOverwriteMode::kAutoRenameExisting
+ NExtract::NOverwriteMode::kOverwrite,
+ NExtract::NOverwriteMode::kSkip,
+ NExtract::NOverwriteMode::kRename,
+ NExtract::NOverwriteMode::kRenameExisting
};
static const CSwitchForm kSwitchForms[] =
- {
- { L"?", NSwitchType::kSimple, false },
- { L"H", NSwitchType::kSimple, false },
- { L"-HELP", NSwitchType::kSimple, false },
- { L"BA", NSwitchType::kSimple, false },
- { L"BD", NSwitchType::kSimple, false },
- { L"T", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"Y", NSwitchType::kSimple, false },
- #ifndef _NO_CRYPTO
- { L"P", NSwitchType::kUnLimitedPostString, false, 0 },
- #endif
- { L"M", NSwitchType::kUnLimitedPostString, true, 1 },
- { L"O", NSwitchType::kUnLimitedPostString, false, 1 },
- { L"W", NSwitchType::kUnLimitedPostString, false, 0 },
- { L"I", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
- { L"X", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
- { L"AI", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
- { L"AX", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
- { L"AN", NSwitchType::kSimple, false },
- { L"U", NSwitchType::kUnLimitedPostString, true, 1},
- { L"V", NSwitchType::kUnLimitedPostString, true, 1},
- { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet },
- { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 },
- { L"SI", NSwitchType::kUnLimitedPostString, false, 0 },
- { L"SO", NSwitchType::kSimple, false, 0 },
- { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet},
- { L"SEML", NSwitchType::kUnLimitedPostString, false, 0},
- { L"AD", NSwitchType::kSimple, false },
- { L"SLP", NSwitchType::kUnLimitedPostString, false, 0},
- { L"L", NSwitchType::kSimple, false },
- { L"SLT", NSwitchType::kSimple, false },
- { L"SSC", NSwitchType::kPostChar, false, 0, 0, L"-" },
- { L"SCRC", NSwitchType::kSimple, false }
- };
-
-static const CCommandForm g_CommandForms[] =
-{
- { L"A", false },
- { L"U", false },
- { L"D", false },
- { L"T", false },
- { L"E", false },
- { L"X", false },
- { L"L", false },
- { L"B", false },
- { L"I", false }
+{
+ { "?" },
+ { "h" },
+ { "-help" },
+ { "ba" },
+ { "bd" },
+ { "t", NSwitchType::kString, false, 1 },
+ { "y" },
+ #ifndef _NO_CRYPTO
+ { "p", NSwitchType::kString },
+ #endif
+ { "m", NSwitchType::kString, true, 1 },
+ { "o", NSwitchType::kString, false, 1 },
+ { "w", NSwitchType::kString },
+ { "i", NSwitchType::kString, true, kSomeCludePostStringMinSize},
+ { "x", NSwitchType::kString, true, kSomeCludePostStringMinSize},
+ { "ai", NSwitchType::kString, true, kSomeCludePostStringMinSize},
+ { "ax", NSwitchType::kString, true, kSomeCludePostStringMinSize},
+ { "an" },
+ { "u", NSwitchType::kString, true, 1},
+ { "v", NSwitchType::kString, true, 1},
+ { "r", NSwitchType::kChar, false, 0, kRecursedPostCharSet },
+ { "sfx", NSwitchType::kString },
+ { "si", NSwitchType::kString },
+ { "so" },
+ { "ao", NSwitchType::kChar, false, 1, kOverwritePostCharSet},
+ { "seml", NSwitchType::kString, false, 0},
+ { "ad" },
+ { "slp", NSwitchType::kMinus },
+ // { "scs", NSwitchType::kString },
+ // { "scc", NSwitchType::kString },
+ { "slt" },
+ // { "ssw" },
+ { "l" },
+ { "ssc", NSwitchType::kMinus },
+ { "scrc", NSwitchType::kString, true, 0 },
+ { "sa", NSwitchType::kChar, false, 1, k_ArcNameMode_PostCharSet },
+
+ { "spd" },
+ { "spe", NSwitchType::kMinus },
+ { "spf", NSwitchType::kString, false, 0 },
+
+ { "snh", NSwitchType::kMinus },
+ { "snl", NSwitchType::kMinus },
+ { "sni" },
+ { "sns", NSwitchType::kMinus },
+
+ { "snr" },
+ { "snc" },
+
+ { "sdel" },
+ { "stl" },
+ { "stx", NSwitchType::kString, true, 1 }
};
-static const int kNumCommandForms = sizeof(g_CommandForms) / sizeof(g_CommandForms[0]);
-
static const wchar_t *kUniversalWildcard = L"*";
static const int kMinNonSwitchWords = 1;
static const int kCommandIndex = 0;
-// ---------------------------
-// exception messages
-
-static const char *kUserErrorMessage = "Incorrect command line";
+// static const char *kUserErrorMessage = "Incorrect command line";
static const char *kCannotFindListFile = "Cannot find listfile";
static const char *kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch.";
-static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfile";
-static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line";
+static const char *kIncorrectWildcardInListFile = "Incorrect wildcard in listfile";
+static const char *kIncorrectWildcardInCommandLine = "Incorrect wildcard in command line";
static const char *kTerminalOutError = "I won't write compressed data to a terminal";
static const char *kSameTerminalError = "I won't write data and program's messages to same terminal";
static const char *kEmptyFilePath = "Empty file path";
+static const char *kCannotFindArchive = "Cannot find archive";
-static void ThrowException(const char *errorMessage)
+bool CArcCommand::IsFromExtractGroup() const
{
- throw CArchiveCommandLineException(errorMessage);
-}
-
-static void ThrowUserErrorException()
-{
- ThrowException(kUserErrorMessage);
-}
-
-// ---------------------------
-
-bool CArchiveCommand::IsFromExtractGroup() const
-{
- switch(CommandType)
+ switch (CommandType)
{
case NCommandType::kTest:
case NCommandType::kExtract:
- case NCommandType::kFullExtract:
+ case NCommandType::kExtractFull:
return true;
- default:
- return false;
}
+ return false;
}
-NExtract::NPathMode::EEnum CArchiveCommand::GetPathMode() const
+NExtract::NPathMode::EEnum CArcCommand::GetPathMode() const
{
- switch(CommandType)
+ switch (CommandType)
{
case NCommandType::kTest:
- case NCommandType::kFullExtract:
- return NExtract::NPathMode::kFullPathnames;
- default:
- return NExtract::NPathMode::kNoPathnames;
+ case NCommandType::kExtractFull:
+ return NExtract::NPathMode::kFullPaths;
}
+ return NExtract::NPathMode::kNoPaths;
}
-bool CArchiveCommand::IsFromUpdateGroup() const
+bool CArcCommand::IsFromUpdateGroup() const
{
- return (CommandType == NCommandType::kAdd ||
- CommandType == NCommandType::kUpdate ||
- CommandType == NCommandType::kDelete);
+ switch (CommandType)
+ {
+ case NCommandType::kAdd:
+ case NCommandType::kUpdate:
+ case NCommandType::kDelete:
+ case NCommandType::kRename:
+ return true;
+ }
+ return false;
}
static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
{
switch (index)
{
- case NRecursedPostCharIndex::kWildCardRecursionOnly:
- return NRecursedType::kWildCardOnlyRecursed;
+ case NRecursedPostCharIndex::kWildcardRecursionOnly:
+ return NRecursedType::kWildcardOnlyRecursed;
case NRecursedPostCharIndex::kNoRecursion:
return NRecursedType::kNonRecursed;
default:
@@ -242,170 +298,281 @@ static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
}
}
-static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command)
+static const char *g_Commands = "audtexlbih";
+
+static bool ParseArchiveCommand(const UString &commandString, CArcCommand &command)
{
- UString commandStringUpper = commandString;
- commandStringUpper.MakeUpper();
- UString postString;
- int commandIndex = ParseCommand(kNumCommandForms, g_CommandForms, commandStringUpper,
- postString) ;
- if (commandIndex < 0)
- return false;
- command.CommandType = (NCommandType::EEnum)commandIndex;
- return true;
+ UString s = commandString;
+ s.MakeLower_Ascii();
+ if (s.Len() == 1)
+ {
+ if (s[0] > 0x7F)
+ return false;
+ int index = FindCharPosInString(g_Commands, (char)s[0]);
+ if (index < 0)
+ return false;
+ command.CommandType = (NCommandType::EEnum)index;
+ return true;
+ }
+ if (s.Len() == 2 && s[0] == 'r' && s[1] == 'n')
+ {
+ command.CommandType = (NCommandType::kRename);
+ return true;
+ }
+ return false;
}
// ------------------------------------------------------------------
// filenames functions
-static void AddNameToCensor(NWildcard::CCensor &wildcardCensor,
- const UString &name, bool include, NRecursedType::EEnum type)
+static void AddNameToCensor(NWildcard::CCensor &censor,
+ const UString &name, bool include, NRecursedType::EEnum type, bool wildcardMatching)
{
bool recursed = false;
switch (type)
{
- case NRecursedType::kWildCardOnlyRecursed:
- recursed = DoesNameContainWildCard(name);
+ case NRecursedType::kWildcardOnlyRecursed:
+ recursed = DoesNameContainWildcard(name);
break;
case NRecursedType::kRecursed:
recursed = true;
break;
}
- wildcardCensor.AddItem(include, name, recursed);
+ censor.AddPreItem(include, name, recursed, wildcardMatching);
}
-static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor,
- LPCWSTR fileName, bool include, NRecursedType::EEnum type, UINT codePage)
+static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs,
+ const UString &oldName, const UString &newName, NRecursedType::EEnum type,
+ bool wildcardMatching)
+{
+ CRenamePair &pair = renamePairs->AddNew();
+ pair.OldName = oldName;
+ pair.NewName = newName;
+ pair.RecursedType = type;
+ pair.WildcardParsing = wildcardMatching;
+
+ if (!pair.Prepare())
+ {
+ UString val;
+ val += pair.OldName;
+ AddNewLine(val);
+ val += pair.NewName;
+ AddNewLine(val);
+ if (type == NRecursedType::kRecursed)
+ val += L"-r";
+ else if (type == NRecursedType::kRecursed)
+ val += L"-r0";
+ throw CArcCmdLineException("Unsupported rename command:", val);
+ }
+}
+
+static void AddToCensorFromListFile(
+ CObjectVector<CRenamePair> *renamePairs,
+ NWildcard::CCensor &censor,
+ LPCWSTR fileName, bool include, NRecursedType::EEnum type, bool wildcardMatching, Int32 codePage)
{
UStringVector names;
- if (!NFind::DoesFileExist(fileName))
- throw kCannotFindListFile;
- if (!ReadNamesFromListFile(fileName, names, codePage))
- throw kIncorrectListFile;
- for (int i = 0; i < names.Size(); i++)
- AddNameToCensor(wildcardCensor, names[i], include, type);
+ if (!NFind::DoesFileExist(us2fs(fileName)))
+ throw CArcCmdLineException(kCannotFindListFile, fileName);
+ if (!ReadNamesFromListFile(us2fs(fileName), names, codePage))
+ throw CArcCmdLineException(kIncorrectListFile, fileName);
+ if (renamePairs)
+ {
+ if ((names.Size() & 1) != 0)
+ throw CArcCmdLineException(kIncorrectListFile, fileName);
+ for (unsigned i = 0; i < names.Size(); i += 2)
+ {
+ // change type !!!!
+ AddRenamePair(renamePairs, names[i], names[i + 1], type, wildcardMatching);
+ }
+ }
+ else
+ FOR_VECTOR (i, names)
+ AddNameToCensor(censor, names[i], include, type, wildcardMatching);
}
static void AddToCensorFromNonSwitchesStrings(
- int startIndex,
- NWildcard::CCensor &wildcardCensor,
+ CObjectVector<CRenamePair> *renamePairs,
+ unsigned startIndex,
+ NWildcard::CCensor &censor,
const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,
- bool thereAreSwitchIncludes, UINT codePage)
+ bool wildcardMatching,
+ bool thereAreSwitchIncludes, Int32 codePage)
{
- if (nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes))
- AddNameToCensor(wildcardCensor, kUniversalWildcard, true, type);
- for (int i = startIndex; i < nonSwitchStrings.Size(); i++)
+ if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes)
+ AddNameToCensor(censor, kUniversalWildcard, true, type,
+ true // wildcardMatching
+ );
+
+ int oldIndex = -1;
+
+ for (unsigned i = startIndex; i < nonSwitchStrings.Size(); i++)
{
const UString &s = nonSwitchStrings[i];
if (s.IsEmpty())
- throw kEmptyFilePath;
+ throw CArcCmdLineException(kEmptyFilePath);
if (s[0] == kFileListID)
- AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage);
- else
- AddNameToCensor(wildcardCensor, s, true, type);
- }
-}
-
-#ifdef _WIN32
-static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor,
- const UString &switchParam, bool include,
- NRecursedType::EEnum commonRecursedType)
-{
- int splitPos = switchParam.Find(L':');
- if (splitPos < 0)
- ThrowUserErrorException();
- UString mappingName = switchParam.Left(splitPos);
-
- UString switchParam2 = switchParam.Mid(splitPos + 1);
- splitPos = switchParam2.Find(L':');
- if (splitPos < 0)
- ThrowUserErrorException();
-
- UString mappingSize = switchParam2.Left(splitPos);
- UString eventName = switchParam2.Mid(splitPos + 1);
-
- UInt64 dataSize64 = ConvertStringToUInt64(mappingSize, NULL);
- UInt32 dataSize = (UInt32)dataSize64;
- {
- CFileMapping fileMapping;
- if (fileMapping.Open(FILE_MAP_READ, GetSystemString(mappingName)) != 0)
- ThrowException("Can not open mapping");
- LPVOID data = fileMapping.Map(FILE_MAP_READ, 0, dataSize);
- if (data == NULL)
- ThrowException("MapViewOfFile error");
- try
+ AddToCensorFromListFile(renamePairs, censor, s.Ptr(1), true, type, wildcardMatching, codePage);
+ else if (renamePairs)
{
- const wchar_t *curData = (const wchar_t *)data;
- if (*curData != 0)
- ThrowException("Incorrect mapping data");
- UInt32 numChars = dataSize / sizeof(wchar_t);
- UString name;
- for (UInt32 i = 1; i < numChars; i++)
+ if (oldIndex == -1)
+ oldIndex = startIndex;
+ else
{
- wchar_t c = curData[i];
- if (c == L'\0')
- {
- AddNameToCensor(wildcardCensor, name, include, commonRecursedType);
- name.Empty();
- }
- else
- name += c;
+ // NRecursedType::EEnum type is used for global wildcard (-i! switches)
+ AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, NRecursedType::kNonRecursed, wildcardMatching);
+ // AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, type);
+ oldIndex = -1;
}
- if (!name.IsEmpty())
- ThrowException("data error");
}
- catch(...)
- {
- UnmapViewOfFile(data);
- throw;
- }
- UnmapViewOfFile(data);
+ else
+ AddNameToCensor(censor, s, true, type, wildcardMatching);
}
-
+
+ if (oldIndex != -1)
+ {
+ throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[oldIndex]);
+ }
+}
+
+#ifdef _WIN32
+
+struct CEventSetEnd
+{
+ UString Name;
+
+ CEventSetEnd(const wchar_t *name): Name(name) {}
+ ~CEventSetEnd()
{
NSynchronization::CManualResetEvent event;
- if (event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName)) == S_OK)
+ if (event.Open(EVENT_MODIFY_STATE, false, GetSystemString(Name)) == 0)
event.Set();
}
+};
+
+const char *k_IncorrectMapCommand = "Incorrect Map command";
+
+static const char *ParseMapWithPaths(
+ NWildcard::CCensor &censor,
+ const UString &s2, bool include,
+ NRecursedType::EEnum commonRecursedType,
+ bool wildcardMatching)
+{
+ UString s = s2;
+ int pos = s.Find(L':');
+ if (pos < 0)
+ return k_IncorrectMapCommand;
+ int pos2 = s.Find(L':', pos + 1);
+ if (pos2 < 0)
+ return k_IncorrectMapCommand;
+
+ CEventSetEnd eventSetEnd((const wchar_t *)s + (pos2 + 1));
+ s.DeleteFrom(pos2);
+ UInt32 size;
+ if (!StringToUInt32(s.Ptr(pos + 1), size)
+ || size < sizeof(wchar_t)
+ || size > ((UInt32)1 << 31)
+ || size % sizeof(wchar_t) != 0)
+ return "Unsupported Map data size";
+
+ s.DeleteFrom(pos);
+ CFileMapping map;
+ if (map.Open(FILE_MAP_READ, GetSystemString(s)) != 0)
+ return "Can not open mapping";
+ LPVOID data = map.Map(FILE_MAP_READ, 0, size);
+ if (!data)
+ return "MapViewOfFile error";
+ CFileUnmapper unmapper(data);
+
+ UString name;
+ const wchar_t *p = (const wchar_t *)data;
+ if (*p != 0) // data format marker
+ return "Unsupported Map data";
+ UInt32 numChars = size / sizeof(wchar_t);
+ for (UInt32 i = 1; i < numChars; i++)
+ {
+ wchar_t c = p[i];
+ if (c == 0)
+ {
+ // MessageBoxW(0, name, L"7-Zip", 0);
+ AddNameToCensor(censor, name, include, commonRecursedType, wildcardMatching);
+ name.Empty();
+ }
+ else
+ name += c;
+ }
+ if (!name.IsEmpty())
+ return "Map data error";
+
+ return NULL;
}
+
#endif
-static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
+static void AddSwitchWildcardsToCensor(
+ NWildcard::CCensor &censor,
const UStringVector &strings, bool include,
- NRecursedType::EEnum commonRecursedType, UINT codePage)
+ NRecursedType::EEnum commonRecursedType,
+ bool wildcardMatching,
+ Int32 codePage)
{
- for (int i = 0; i < strings.Size(); i++)
+ const char *errorMessage = NULL;
+ unsigned i;
+ for (i = 0; i < strings.Size(); i++)
{
const UString &name = strings[i];
NRecursedType::EEnum recursedType;
- int pos = 0;
- if (name.Length() < kSomeCludePostStringMinSize)
- ThrowUserErrorException();
- if (::MyCharUpper(name[pos]) == kRecursedIDChar)
+ unsigned pos = 0;
+
+ if (name.Len() < kSomeCludePostStringMinSize)
+ {
+ errorMessage = "Too short switch";
+ break;
+ }
+
+ if (::MyCharLower_Ascii(name[pos]) == kRecursedIDChar)
{
pos++;
- int index = UString(kRecursedPostCharSet).Find(name[pos]);
+ wchar_t c = name[pos];
+ int index = -1;
+ if (c <= 0x7F)
+ index = FindCharPosInString(kRecursedPostCharSet, (char)c);
recursedType = GetRecursedTypeFromIndex(index);
if (index >= 0)
pos++;
}
else
recursedType = commonRecursedType;
- if (name.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize)
- ThrowUserErrorException();
- UString tail = name.Mid(pos + 1);
+
+ if (name.Len() < pos + kSomeCludeAfterRecursedPostStringMinSize)
+ {
+ errorMessage = "Too short switch";
+ break;
+ }
+
+ UString tail = name.Ptr(pos + 1);
+
if (name[pos] == kImmediateNameID)
- AddNameToCensor(wildcardCensor, tail, include, recursedType);
+ AddNameToCensor(censor, tail, include, recursedType, wildcardMatching);
else if (name[pos] == kFileListID)
- AddToCensorFromListFile(wildcardCensor, tail, include, recursedType, codePage);
+ AddToCensorFromListFile(NULL, censor, tail, include, recursedType, wildcardMatching, codePage);
#ifdef _WIN32
else if (name[pos] == kMapNameID)
- ParseMapWithPaths(wildcardCensor, tail, include, recursedType);
+ {
+ errorMessage = ParseMapWithPaths(censor, tail, include, recursedType, wildcardMatching);
+ if (errorMessage)
+ break;
+ }
#endif
else
- ThrowUserErrorException();
+ {
+ errorMessage = "Incorrect wildcarc type marker";
+ break;
+ }
}
+ if (i != strings.Size())
+ throw CArcCmdLineException(errorMessage, strings[i]);
}
#ifdef _WIN32
@@ -414,20 +581,25 @@ static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
static void ConvertToLongName(const UString &prefix, UString &name)
{
- if (name.IsEmpty() || DoesNameContainWildCard(name))
+ if (name.IsEmpty() || DoesNameContainWildcard(name))
return;
- NFind::CFileInfoW fi;
- if (fi.Find(prefix + name))
- name = fi.Name;
+ NFind::CFileInfo fi;
+ const FString path = us2fs(prefix + name);
+ if (NFile::NName::IsDevicePath(path))
+ return;
+ if (fi.Find(path))
+ name = fs2us(fi.Name);
}
static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
{
- for (int i = 0; i < items.Size(); i++)
+ FOR_VECTOR (i, items)
{
NWildcard::CItem &item = items[i];
if (item.Recursive || item.PathParts.Size() != 1)
continue;
+ if (prefix.IsEmpty() && item.IsDriveItem())
+ continue;
ConvertToLongName(prefix, item.PathParts.Front());
}
}
@@ -436,17 +608,22 @@ static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &no
{
ConvertToLongNames(prefix, node.IncludeItems);
ConvertToLongNames(prefix, node.ExcludeItems);
- int i;
+ unsigned i;
for (i = 0; i < node.SubNodes.Size(); i++)
- ConvertToLongName(prefix, node.SubNodes[i].Name);
+ {
+ UString &name = node.SubNodes[i].Name;
+ if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name))
+ continue;
+ ConvertToLongName(prefix, name);
+ }
// mix folders with same name
for (i = 0; i < node.SubNodes.Size(); i++)
{
NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
- for (int j = i + 1; j < node.SubNodes.Size();)
+ for (unsigned j = i + 1; j < node.SubNodes.Size();)
{
const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
- if (nextNode1.Name.CompareNoCase(nextNode2.Name) == 0)
+ if (nextNode1.Name.IsEqualToNoCase(nextNode2.Name))
{
nextNode1.IncludeItems += nextNode2.IncludeItems;
nextNode1.ExcludeItems += nextNode2.ExcludeItems;
@@ -459,13 +636,13 @@ static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &no
for (i = 0; i < node.SubNodes.Size(); i++)
{
NWildcard::CCensorNode &nextNode = node.SubNodes[i];
- ConvertToLongNames(prefix + nextNode.Name + wchar_t(NFile::NName::kDirDelimiter), nextNode);
+ ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode);
}
}
-static void ConvertToLongNames(NWildcard::CCensor &censor)
+void ConvertToLongNames(NWildcard::CCensor &censor)
{
- for (int i = 0; i < censor.Pairs.Size(); i++)
+ FOR_VECTOR (i, censor.Pairs)
{
NWildcard::CPair &pair = censor.Pairs[i];
ConvertToLongNames(pair.Prefix, pair.Head);
@@ -474,9 +651,10 @@ static void ConvertToLongNames(NWildcard::CCensor &censor)
#endif
+/*
static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
{
- switch(i)
+ switch (i)
{
case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore;
case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy;
@@ -485,35 +663,36 @@ static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
}
throw 98111603;
}
+*/
-const UString kUpdatePairStateIDSet = L"PQRXYZW";
-const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
+static const wchar_t *kUpdatePairStateIDSet = L"pqrxyzw";
+static const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
-const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress, Create Anti
-
-const wchar_t *kUpdateIgnoreItselfPostStringID = L"-";
-const wchar_t kUpdateNewArchivePostCharID = '!';
+static const unsigned kNumUpdatePairActions = 4;
+static const char *kUpdateIgnoreItselfPostStringID = "-";
+static const wchar_t kUpdateNewArchivePostCharID = '!';
static bool ParseUpdateCommandString2(const UString &command,
NUpdateArchive::CActionSet &actionSet, UString &postString)
{
- for (int i = 0; i < command.Length();)
+ for (unsigned i = 0; i < command.Len();)
{
- wchar_t c = MyCharUpper(command[i]);
- int statePos = kUpdatePairStateIDSet.Find(c);
+ wchar_t c = MyCharLower_Ascii(command[i]);
+ int statePos = FindCharPosInString(kUpdatePairStateIDSet, c);
if (statePos < 0)
{
- postString = command.Mid(i);
+ postString = command.Ptr(i);
return true;
}
i++;
- if (i >= command.Length())
+ if (i >= command.Len())
return false;
- int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i]));
- if (actionPos < 0)
+ c = command[i];
+ if (c < '0' || c >= '0' + kNumUpdatePairActions)
return false;
- actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos);
+ int actionPos = c - '0';
+ actionSet.StateActions[statePos] = (NUpdateArchive::NPairAction::EEnum)(actionPos);
if (kUpdatePairStateNotSupportedActions[statePos] == actionPos)
return false;
i++;
@@ -526,10 +705,12 @@ static void ParseUpdateCommandString(CUpdateOptions &options,
const UStringVector &updatePostStrings,
const NUpdateArchive::CActionSet &defaultActionSet)
{
- for (int i = 0; i < updatePostStrings.Size(); i++)
+ const char *errorMessage = "incorrect update switch command";
+ unsigned i;
+ for (i = 0; i < updatePostStrings.Size(); i++)
{
const UString &updateString = updatePostStrings[i];
- if (updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0)
+ if (updateString.IsEqualTo(kUpdateIgnoreItselfPostStringID))
{
if (options.UpdateArchiveItself)
{
@@ -543,7 +724,7 @@ static void ParseUpdateCommandString(CUpdateOptions &options,
UString postString;
if (!ParseUpdateCommandString2(updateString, actionSet, postString))
- ThrowUserErrorException();
+ break;
if (postString.IsEmpty())
{
if (options.UpdateArchiveItself)
@@ -551,64 +732,23 @@ static void ParseUpdateCommandString(CUpdateOptions &options,
}
else
{
- if (MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID)
- ThrowUserErrorException();
+ if (postString[0] != kUpdateNewArchivePostCharID)
+ break;
CUpdateArchiveCommand uc;
- UString archivePath = postString.Mid(1);
+ UString archivePath = postString.Ptr(1);
if (archivePath.IsEmpty())
- ThrowUserErrorException();
+ break;
uc.UserArchivePath = archivePath;
uc.ActionSet = actionSet;
options.Commands.Add(uc);
}
}
}
+ if (i != updatePostStrings.Size())
+ throw CArcCmdLineException(errorMessage, updatePostStrings[i]);
}
-static const char kByteSymbol = 'B';
-static const char kKiloSymbol = 'K';
-static const char kMegaSymbol = 'M';
-static const char kGigaSymbol = 'G';
-
-static bool ParseComplexSize(const UString &src, UInt64 &result)
-{
- UString s = src;
- s.MakeUpper();
-
- const wchar_t *start = s;
- const wchar_t *end;
- UInt64 number = ConvertStringToUInt64(start, &end);
- int numDigits = (int)(end - start);
- if (numDigits == 0 || s.Length() > numDigits + 1)
- return false;
- if (s.Length() == numDigits)
- {
- result = number;
- return true;
- }
- int numBits;
- switch (s[numDigits])
- {
- case kByteSymbol:
- result = number;
- return true;
- case kKiloSymbol:
- numBits = 10;
- break;
- case kMegaSymbol:
- numBits = 20;
- break;
- case kGigaSymbol:
- numBits = 30;
- break;
- default:
- return false;
- }
- if (number >= ((UInt64)1 << (64 - numBits)))
- return false;
- result = number << numBits;
- return true;
-}
+bool ParseComplexSize(const wchar_t *s, UInt64 &result);
static void SetAddCommandOptions(
NCommandType::EEnum commandType,
@@ -616,20 +756,20 @@ static void SetAddCommandOptions(
CUpdateOptions &options)
{
NUpdateArchive::CActionSet defaultActionSet;
- switch(commandType)
+ switch (commandType)
{
case NCommandType::kAdd:
- defaultActionSet = NUpdateArchive::kAddActionSet;
+ defaultActionSet = NUpdateArchive::k_ActionSet_Add;
break;
case NCommandType::kDelete:
- defaultActionSet = NUpdateArchive::kDeleteActionSet;
+ defaultActionSet = NUpdateArchive::k_ActionSet_Delete;
break;
default:
- defaultActionSet = NUpdateArchive::kUpdateActionSet;
+ defaultActionSet = NUpdateArchive::k_ActionSet_Update;
}
-
+
options.UpdateArchiveItself = true;
-
+
options.Commands.Clear();
CUpdateArchiveCommand updateMainCommand;
updateMainCommand.ActionSet = defaultActionSet;
@@ -641,22 +781,22 @@ static void SetAddCommandOptions(
{
const UString &postString = parser[NKey::kWorkingDir].PostStrings[0];
if (postString.IsEmpty())
- NDirectory::MyGetTempPath(options.WorkingDir);
+ NDir::MyGetTempPath(options.WorkingDir);
else
- options.WorkingDir = postString;
+ options.WorkingDir = us2fs(postString);
}
options.SfxMode = parser[NKey::kSfx].ThereIs;
if (options.SfxMode)
- options.SfxModule = parser[NKey::kSfx].PostStrings[0];
+ options.SfxModule = us2fs(parser[NKey::kSfx].PostStrings[0]);
if (parser[NKey::kVolume].ThereIs)
{
const UStringVector &sv = parser[NKey::kVolume].PostStrings;
- for (int i = 0; i < sv.Size(); i++)
+ FOR_VECTOR (i, sv)
{
UInt64 size;
- if (!ParseComplexSize(sv[i], size))
- ThrowException("Incorrect volume size");
+ if (!ParseComplexSize(sv[i], size) || size == 0)
+ throw CArcCmdLineException("Incorrect volume size:", sv[i]);
options.VolumesSizes.Add(size);
}
}
@@ -666,38 +806,28 @@ static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &pr
{
if (parser[NKey::kProperty].ThereIs)
{
- // options.MethodMode.Properties.Clear();
- for (int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
+ FOR_VECTOR (i, parser[NKey::kProperty].PostStrings)
{
- CProperty property;
- const UString &postString = parser[NKey::kProperty].PostStrings[i];
- int index = postString.Find(L'=');
- if (index < 0)
- property.Name = postString;
- else
+ CProperty prop;
+ prop.Name = parser[NKey::kProperty].PostStrings[i];
+ int index = prop.Name.Find(L'=');
+ if (index >= 0)
{
- property.Name = postString.Left(index);
- property.Value = postString.Mid(index + 1);
+ prop.Value = prop.Name.Ptr(index + 1);
+ prop.Name.DeleteFrom(index);
}
- properties.Add(property);
+ properties.Add(prop);
}
}
}
-CArchiveCommandLineParser::CArchiveCommandLineParser():
- parser(sizeof(kSwitchForms) / sizeof(kSwitchForms[0])) {}
+CArcCmdLineParser::CArcCmdLineParser(): parser(ARRAY_SIZE(kSwitchForms)) {}
-void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings,
- CArchiveCommandLineOptions &options)
+void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
+ CArcCmdLineOptions &options)
{
- try
- {
- parser.ParseStrings(kSwitchForms, commandStrings);
- }
- catch(...)
- {
- ThrowUserErrorException();
- }
+ if (!parser.ParseStrings(kSwitchForms, commandStrings))
+ throw CArcCmdLineException(parser.ErrorMessage, parser.ErrorLine);
options.IsInTerminal = MY_IS_TERMINAL(stdin);
options.IsStdOutTerminal = MY_IS_TERMINAL(stdout);
@@ -707,44 +837,160 @@ void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings,
options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs;
options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs || parser[NKey::kHelp3].ThereIs;
+ if (parser[NKey::kCaseSensitive].ThereIs)
+ {
+ g_CaseSensitive = !parser[NKey::kCaseSensitive].WithMinus;
+ options.CaseSensitiveChange = true;
+ options.CaseSensitive = g_CaseSensitive;
+ }
+
#ifdef _7ZIP_LARGE_PAGES
options.LargePages = false;
if (parser[NKey::kLargePages].ThereIs)
{
- const UString &postString = parser[NKey::kLargePages].PostStrings.Front();
- if (postString.IsEmpty())
- options.LargePages = true;
+ options.LargePages = !parser[NKey::kLargePages].WithMinus;
}
#endif
}
-static bool ConvertStringToUInt32(const wchar_t *s, UInt32 &v)
+struct CCodePagePair
{
- const wchar_t *end;
- UInt64 number = ConvertStringToUInt64(s, &end);
- if (*end != 0)
- return false;
- if (number > (UInt32)0xFFFFFFFF)
- return false;
- v = (UInt32)number;
- return true;
+ const char *Name;
+ Int32 CodePage;
+};
+
+static const unsigned kNumByteOnlyCodePages = 3;
+
+static CCodePagePair g_CodePagePairs[] =
+{
+ { "utf-8", CP_UTF8 },
+ { "win", CP_ACP },
+ { "dos", CP_OEMCP },
+ { "utf-16le", MY__CP_UTF16 },
+ { "utf-16be", MY__CP_UTF16BE }
+};
+
+static Int32 FindCharset(const NCommandLineParser::CParser &parser, int keyIndex,
+ bool byteOnlyCodePages, Int32 defaultVal)
+{
+ if (!parser[keyIndex].ThereIs)
+ return defaultVal;
+
+ UString name = parser[keyIndex].PostStrings.Back();
+ UInt32 v;
+ if (StringToUInt32(name, v))
+ if (v < ((UInt32)1 << 16))
+ return (Int32)v;
+ name.MakeLower_Ascii();
+ unsigned num = byteOnlyCodePages ? kNumByteOnlyCodePages : ARRAY_SIZE(g_CodePagePairs);
+ for (unsigned i = 0;; i++)
+ {
+ if (i == num) // to disable warnings from different compilers
+ throw CArcCmdLineException("Unsupported charset:", name);
+ const CCodePagePair &pair = g_CodePagePairs[i];
+ if (name.IsEqualTo(pair.Name))
+ return pair.CodePage;
+ }
}
-void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
+void EnumerateDirItemsAndSort(
+ bool storeAltStreams,
+ NWildcard::CCensor &censor,
+ NWildcard::ECensorPathMode censorPathMode,
+ const UString &addPathPrefix,
+ UStringVector &sortedPaths,
+ UStringVector &sortedFullPaths)
+{
+ UStringVector paths;
+ {
+ CDirItems dirItems;
+ {
+ dirItems.ScanAltStreams = storeAltStreams;
+ HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems, NULL);
+ if (res != S_OK || dirItems.ErrorPaths.Size() > 0)
+ {
+ UString errorPath;
+ if (dirItems.ErrorPaths.Size() > 0)
+ errorPath = fs2us(dirItems.ErrorPaths[0]);
+ throw CArcCmdLineException(kCannotFindArchive,
+ dirItems.ErrorPaths.Size() > 0 ? (const wchar_t *)errorPath : NULL);
+ }
+ }
+ FOR_VECTOR (i, dirItems.Items)
+ {
+ const CDirItem &dirItem = dirItems.Items[i];
+ if (!dirItem.IsDir())
+ paths.Add(dirItems.GetPhyPath(i));
+ }
+ }
+
+ if (paths.Size() == 0)
+ throw CArcCmdLineException(kCannotFindArchive);
+
+ UStringVector fullPaths;
+
+ unsigned i;
+ for (i = 0; i < paths.Size(); i++)
+ {
+ FString fullPath;
+ NFile::NDir::MyGetFullPathName(us2fs(paths[i]), fullPath);
+ fullPaths.Add(fs2us(fullPath));
+ }
+ CUIntVector indices;
+ SortFileNames(fullPaths, indices);
+ sortedPaths.ClearAndReserve(indices.Size());
+ sortedFullPaths.ClearAndReserve(indices.Size());
+ for (i = 0; i < indices.Size(); i++)
+ {
+ unsigned index = indices[i];
+ sortedPaths.AddInReserved(paths[index]);
+ sortedFullPaths.AddInReserved(fullPaths[index]);
+ if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0)
+ throw CArcCmdLineException("Duplicate archive path:", sortedFullPaths[i]);
+ }
+}
+
+static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp)
+{
+ bp.Def = parser[switchID].ThereIs;
+ if (bp.Def)
+ bp.Val = !parser[switchID].WithMinus;
+}
+
+void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
{
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
int numNonSwitchStrings = nonSwitchStrings.Size();
if (numNonSwitchStrings < kMinNonSwitchWords)
- ThrowUserErrorException();
+ throw CArcCmdLineException("The command must be spcified");
if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command))
- ThrowUserErrorException();
+ throw CArcCmdLineException("Unsupported command:", nonSwitchStrings[kCommandIndex]);
options.TechMode = parser[NKey::kTechMode].ThereIs;
- options.CalcCrc = parser[NKey::kCalcCrc].ThereIs;
+ if (parser[NKey::kHash].ThereIs)
+ options.HashMethods = parser[NKey::kHash].PostStrings;
- if (parser[NKey::kCaseSensitive].ThereIs)
- g_CaseSensitive = (parser[NKey::kCaseSensitive].PostCharIndex < 0);
+ if (parser[NKey::kElimDup].ThereIs)
+ {
+ options.ExtractOptions.ElimDup.Def = true;
+ options.ExtractOptions.ElimDup.Val = !parser[NKey::kElimDup].WithMinus;
+ }
+
+ NWildcard::ECensorPathMode censorPathMode = NWildcard::k_RelatPath;
+ bool fullPathMode = parser[NKey::kFullPathMode].ThereIs;
+ if (fullPathMode)
+ {
+ censorPathMode = NWildcard::k_AbsPath;
+ const UString &s = parser[NKey::kFullPathMode].PostStrings[0];
+ if (!s.IsEmpty())
+ {
+ if (s == L"2")
+ censorPathMode = NWildcard::k_FullPath;
+ else
+ throw CArcCmdLineException("Unsupported -spf:", s);
+ }
+ }
NRecursedType::EEnum recursedType;
if (parser[NKey::kRecursed].ThereIs)
@@ -752,48 +998,57 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
else
recursedType = NRecursedType::kNonRecursed;
- UINT codePage = CP_ACP;
+ bool wildcardMatching = true;
+ if (parser[NKey::kDisableWildcardParsing].ThereIs)
+ wildcardMatching = false;
+
+ Int32 codePage = CP_ACP;
bool thereAreSwitchIncludes = false;
+
if (parser[NKey::kInclude].ThereIs)
{
thereAreSwitchIncludes = true;
- AddSwitchWildCardsToCensor(options.WildcardCensor,
- parser[NKey::kInclude].PostStrings, true, recursedType, codePage);
+ AddSwitchWildcardsToCensor(options.Censor,
+ parser[NKey::kInclude].PostStrings, true, recursedType, wildcardMatching, codePage);
}
+
if (parser[NKey::kExclude].ThereIs)
- AddSwitchWildCardsToCensor(options.WildcardCensor,
- parser[NKey::kExclude].PostStrings, false, recursedType, codePage);
-
+ AddSwitchWildcardsToCensor(options.Censor,
+ parser[NKey::kExclude].PostStrings, false, recursedType, wildcardMatching, codePage);
+
int curCommandIndex = kCommandIndex + 1;
bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs &&
options.Command.CommandType != NCommandType::kBenchmark &&
- options.Command.CommandType != NCommandType::kInfo;
+ options.Command.CommandType != NCommandType::kInfo &&
+ options.Command.CommandType != NCommandType::kHash;
bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList;
+ bool isRename = options.Command.CommandType == NCommandType::kRename;
- if (isExtractOrList && options.StdInMode)
+ if ((isExtractOrList || isRename) && options.StdInMode)
thereIsArchiveName = false;
+ if (parser[NKey::kArcNameMode].ThereIs)
+ options.UpdateOptions.ArcNameMode = ParseArcNameMode(parser[NKey::kArcNameMode].PostCharIndex);
+
if (thereIsArchiveName)
{
if (curCommandIndex >= numNonSwitchStrings)
- ThrowUserErrorException();
+ throw CArcCmdLineException("Cannot find archive name");
options.ArchiveName = nonSwitchStrings[curCommandIndex++];
if (options.ArchiveName.IsEmpty())
- ThrowUserErrorException();
+ throw CArcCmdLineException("Archive name cannot by empty");
}
- AddToCensorFromNonSwitchesStrings(
- curCommandIndex, options.WildcardCensor,
- nonSwitchStrings, recursedType, thereAreSwitchIncludes, codePage);
+ AddToCensorFromNonSwitchesStrings(isRename ? &options.UpdateOptions.RenamePairs : NULL,
+ curCommandIndex, options.Censor,
+ nonSwitchStrings, recursedType, wildcardMatching,
+ thereAreSwitchIncludes, codePage);
options.YesToAll = parser[NKey::kYes].ThereIs;
-#ifdef ENV_HAVE_LSTAT
- global_use_lstat = !parser[NKey::kUseLStat].ThereIs;
-#endif
#ifndef _NO_CRYPTO
options.PasswordEnabled = parser[NKey::kPassword].ThereIs;
@@ -806,35 +1061,73 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
if (parser[NKey::kArchiveType].ThereIs)
options.ArcType = parser[NKey::kArchiveType].PostStrings[0];
+ options.ExcludedArcTypes = parser[NKey::kExcludedArcType].PostStrings;
+
+ SetMethodOptions(parser, options.Properties);
+
+ options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs;
+
+ if (options.EnablePercents)
+ {
+ if ((options.StdOutMode && !options.IsStdErrTerminal) ||
+ (!options.StdOutMode && !options.IsStdOutTerminal))
+ options.EnablePercents = false;
+ }
+
+ if (parser[NKey::kNtSecurity].ThereIs) options.NtSecurity.SetTrueTrue();
+
+ SetBoolPair(parser, NKey::kAltStreams, options.AltStreams);
+ SetBoolPair(parser, NKey::kHardLinks, options.HardLinks);
+ SetBoolPair(parser, NKey::kSymLinks, options.SymLinks);
+
if (isExtractOrList)
{
- if (!options.WildcardCensor.AllAreRelative())
- ThrowException("Cannot use absolute pathnames for this command");
+ CExtractOptionsBase &eo = options.ExtractOptions;
+
+ {
+ CExtractNtOptions &nt = eo.NtOptions;
+ nt.NtSecurity = options.NtSecurity;
- NWildcard::CCensor archiveWildcardCensor;
+ nt.AltStreams = options.AltStreams;
+ if (!options.AltStreams.Def)
+ nt.AltStreams.Val = true;
+
+ nt.HardLinks = options.HardLinks;
+ if (!options.HardLinks.Def)
+ nt.HardLinks.Val = true;
+
+ nt.SymLinks = options.SymLinks;
+ if (!options.SymLinks.Def)
+ nt.SymLinks.Val = true;
+
+ nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs;
+ nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs;
+ }
+
+ options.Censor.AddPathsToCensor(NWildcard::k_AbsPath);
+ options.Censor.ExtendExclude();
+
+ // are there paths that look as non-relative (!Prefix.IsEmpty())
+ if (!options.Censor.AllAreRelative())
+ throw CArcCmdLineException("Cannot use absolute pathnames for this command");
+
+ NWildcard::CCensor arcCensor;
if (parser[NKey::kArInclude].ThereIs)
- AddSwitchWildCardsToCensor(archiveWildcardCensor,
- parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, codePage);
+ AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, wildcardMatching, codePage);
if (parser[NKey::kArExclude].ThereIs)
- AddSwitchWildCardsToCensor(archiveWildcardCensor,
- parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, codePage);
-
- bool directlyAddArchiveName = false;
- if (thereIsArchiveName) {
- if ((options.ArchiveName.Find(kUniversalWildcard) == -1) && (options.ArchiveName.Find(L"?") == -1)) {
- // no wildcard => no need to scan
- directlyAddArchiveName = true;
- } else {
- AddNameToCensor(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);
- }
- }
+ AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, wildcardMatching, codePage);
+
+ if (thereIsArchiveName)
+ AddNameToCensor(arcCensor, options.ArchiveName, true, NRecursedType::kNonRecursed, wildcardMatching);
+
+ arcCensor.AddPathsToCensor(NWildcard::k_RelatPath);
#ifdef _WIN32
- ConvertToLongNames(archiveWildcardCensor);
+ ConvertToLongNames(arcCensor);
#endif
- archiveWildcardCensor.ExtendExclude();
+ arcCensor.ExtendExclude();
if (options.StdInMode)
{
@@ -844,95 +1137,78 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
}
else
{
-
- UStringVector archivePaths;
-
- {
- CDirItems dirItems;
- {
- UStringVector errorPaths;
- CRecordVector<DWORD> errorCodes;
- HRESULT res = EnumerateItems(archiveWildcardCensor, dirItems, NULL, errorPaths, errorCodes);
- if (res != S_OK || errorPaths.Size() > 0)
- throw "cannot find archive";
- }
- for (int i = 0; i < dirItems.Items.Size(); i++)
- {
- const CDirItem &dirItem = dirItems.Items[i];
- if (!dirItem.IsDir())
- archivePaths.Add(dirItems.GetPhyPath(i));
- }
+ EnumerateDirItemsAndSort(
+ false, // scanAltStreams
+ arcCensor,
+ NWildcard::k_RelatPath,
+ UString(), // addPathPrefix
+ options.ArchivePathsSorted,
+ options.ArchivePathsFullSorted);
}
- // Because the pathname of archive can be a symbolic link
- // do not use "AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName"
- if (directlyAddArchiveName)
- archivePaths.Add(options.ArchiveName);
-
- if (archivePaths.Size() == 0)
- throw "there is no such archive";
-
- UStringVector archivePathsFull;
-
- int i;
- for (i = 0; i < archivePaths.Size(); i++)
- {
- UString fullPath;
- NFile::NDirectory::MyGetFullPathName(archivePaths[i], fullPath);
- archivePathsFull.Add(fullPath);
- }
- CIntVector indices;
- SortFileNames(archivePathsFull, indices);
- options.ArchivePathsSorted.Reserve(indices.Size());
- options.ArchivePathsFullSorted.Reserve(indices.Size());
- for (i = 0; i < indices.Size(); i++)
- {
- options.ArchivePathsSorted.Add(archivePaths[indices[i]]);
- options.ArchivePathsFullSorted.Add(archivePathsFull[indices[i]]);
- }
-
- }
-
if (isExtractGroupCommand)
{
- SetMethodOptions(parser, options.ExtractProperties);
if (options.StdOutMode && options.IsStdOutTerminal && options.IsStdErrTerminal)
- throw kSameTerminalError;
+ throw CArcCmdLineException(kSameTerminalError);
if (parser[NKey::kOutputDir].ThereIs)
{
- options.OutputDir = parser[NKey::kOutputDir].PostStrings[0];
- NFile::NName::NormalizeDirPathPrefix(options.OutputDir);
+ eo.OutputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]);
+ NFile::NName::NormalizeDirPathPrefix(eo.OutputDir);
}
- options.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
+ eo.OverwriteMode = NExtract::NOverwriteMode::kAsk;
if (parser[NKey::kOverwrite].ThereIs)
- options.OverwriteMode = k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex];
+ {
+ eo.OverwriteMode = k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex];
+ eo.OverwriteMode_Force = true;
+ }
else if (options.YesToAll)
- options.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
+ {
+ eo.OverwriteMode = NExtract::NOverwriteMode::kOverwrite;
+ eo.OverwriteMode_Force = true;
+ }
+ }
+
+ eo.PathMode = options.Command.GetPathMode();
+ if (censorPathMode == NWildcard::k_AbsPath)
+ {
+ eo.PathMode = NExtract::NPathMode::kAbsPaths;
+ eo.PathMode_Force = true;
+ }
+ else if (censorPathMode == NWildcard::k_FullPath)
+ {
+ eo.PathMode = NExtract::NPathMode::kFullPaths;
+ eo.PathMode_Force = true;
}
}
else if (options.Command.IsFromUpdateGroup())
{
+ if (parser[NKey::kArInclude].ThereIs)
+ throw CArcCmdLineException("-ai switch is not supported for this command");
+
CUpdateOptions &updateOptions = options.UpdateOptions;
SetAddCommandOptions(options.Command.CommandType, parser, updateOptions);
-
- SetMethodOptions(parser, updateOptions.MethodMode.Properties);
- options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs;
+ updateOptions.MethodMode.Properties = options.Properties;
- if (options.EnablePercents)
- {
- if ((options.StdOutMode && !options.IsStdErrTerminal) ||
- (!options.StdOutMode && !options.IsStdOutTerminal))
- options.EnablePercents = false;
- }
+#ifdef _WIN32
+ if (parser[NKey::kShareForWrite].ThereIs)
+ updateOptions.OpenShareForWrite = true;
+#endif
+
+ updateOptions.PathMode = censorPathMode;
+
+ updateOptions.AltStreams = options.AltStreams;
+ updateOptions.NtSecurity = options.NtSecurity;
+ updateOptions.HardLinks = options.HardLinks;
+ updateOptions.SymLinks = options.SymLinks;
updateOptions.EMailMode = parser[NKey::kEmail].ThereIs;
if (updateOptions.EMailMode)
{
updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front();
- if (updateOptions.EMailAddress.Length() > 0)
+ if (updateOptions.EMailAddress.Len() > 0)
if (updateOptions.EMailAddress[0] == L'.')
{
updateOptions.EMailRemoveAfter = true;
@@ -943,68 +1219,48 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
updateOptions.StdOutMode = options.StdOutMode;
updateOptions.StdInMode = options.StdInMode;
+ updateOptions.DeleteAfterCompressing = parser[NKey::kDeleteAfterCompressing].ThereIs;
+ updateOptions.SetArcMTime = parser[NKey::kSetArcMTime].ThereIs;
+
if (updateOptions.StdOutMode && updateOptions.EMailMode)
- throw "stdout mode and email mode cannot be combined";
+ throw CArcCmdLineException("stdout mode and email mode cannot be combined");
if (updateOptions.StdOutMode && options.IsStdOutTerminal)
- throw kTerminalOutError;
+ throw CArcCmdLineException(kTerminalOutError);
if (updateOptions.StdInMode)
updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front();
- #ifdef _WIN32
- ConvertToLongNames(options.WildcardCensor);
- #endif
+ if (options.Command.CommandType == NCommandType::kRename)
+ if (updateOptions.Commands.Size() != 1)
+ throw CArcCmdLineException("Only one archive can be created with rename command");
}
else if (options.Command.CommandType == NCommandType::kBenchmark)
{
- options.NumThreads = (UInt32)-1;
- options.DictionarySize = (UInt32)-1;
options.NumIterations = 1;
if (curCommandIndex < numNonSwitchStrings)
{
- if (!ConvertStringToUInt32(nonSwitchStrings[curCommandIndex++], options.NumIterations))
- ThrowUserErrorException();
- }
- for (int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
- {
- UString postString = parser[NKey::kProperty].PostStrings[i];
- postString.MakeUpper();
- if (postString.Length() < 2)
- ThrowUserErrorException();
- if (postString[0] == 'D')
- {
- int pos = 1;
- if (postString[pos] == '=')
- pos++;
- UInt32 logSize;
- if (!ConvertStringToUInt32((const wchar_t *)postString + pos, logSize))
- ThrowUserErrorException();
- if (logSize > 31)
- ThrowUserErrorException();
- options.DictionarySize = 1 << logSize;
- }
- else if (postString[0] == 'M' && postString[1] == 'T' )
- {
- int pos = 2;
- if (postString[pos] == '=')
- pos++;
- if (postString[pos] != 0)
- if (!ConvertStringToUInt32((const wchar_t *)postString + pos, options.NumThreads))
- ThrowUserErrorException();
- }
- else if (postString[0] == 'M' && postString[1] == '=' )
- {
- int pos = 2;
- if (postString[pos] != 0)
- options.Method = postString.Mid(2);
- }
- else
- ThrowUserErrorException();
+ if (!StringToUInt32(nonSwitchStrings[curCommandIndex], options.NumIterations))
+ throw CArcCmdLineException("Incorrect Number of benmchmark iterations", nonSwitchStrings[curCommandIndex]);
+ curCommandIndex++;
}
}
+ else if (options.Command.CommandType == NCommandType::kHash)
+ {
+ options.Censor.AddPathsToCensor(censorPathMode);
+ options.Censor.ExtendExclude();
+
+ CHashOptions &hashOptions = options.HashOptions;
+ hashOptions.PathMode = censorPathMode;
+ hashOptions.Methods = options.HashMethods;
+#ifdef _WIN32
+ if (parser[NKey::kShareForWrite].ThereIs)
+ hashOptions.OpenShareForWrite = true;
+#endif
+ hashOptions.StdInMode = options.StdInMode;
+ hashOptions.AltStreamsMode = options.AltStreams.Val;
+ }
else if (options.Command.CommandType == NCommandType::kInfo)
{
}
else
- ThrowUserErrorException();
- options.WildcardCensor.ExtendExclude();
+ throw 815676711; // FIXME 9815676711;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveCommandLine.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveCommandLine.h
index bc7a99b0d..255e12c3c 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveCommandLine.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveCommandLine.h
@@ -3,15 +3,16 @@
#ifndef __ARCHIVE_COMMAND_LINE_H
#define __ARCHIVE_COMMAND_LINE_H
-#include "Common/CommandLineParser.h"
-#include "Common/Wildcard.h"
+#include "../../../Common/CommandLineParser.h"
+#include "../../../Common/Wildcard.h"
#include "Extract.h"
+#include "HashCalc.h"
#include "Update.h"
-struct CArchiveCommandLineException: public AString
+struct CArcCmdLineException: public UString
{
- CArchiveCommandLineException(const char *errorMessage): AString(errorMessage) {}
+ CArcCmdLineException(const char *a, const wchar_t *u = NULL);
};
namespace NCommandType { enum EEnum
@@ -21,35 +22,33 @@ namespace NCommandType { enum EEnum
kDelete,
kTest,
kExtract,
- kFullExtract,
+ kExtractFull,
kList,
kBenchmark,
- kInfo
+ kInfo,
+ kHash,
+ kRename
};}
-namespace NRecursedType { enum EEnum
-{
- kRecursed,
- kWildCardOnlyRecursed,
- kNonRecursed
-};}
-
-struct CArchiveCommand
+struct CArcCommand
{
NCommandType::EEnum CommandType;
+
bool IsFromExtractGroup() const;
bool IsFromUpdateGroup() const;
- bool IsTestMode() const { return CommandType == NCommandType::kTest; }
+ bool IsTestCommand() const { return CommandType == NCommandType::kTest; }
NExtract::NPathMode::EEnum GetPathMode() const;
};
-struct CArchiveCommandLineOptions
+struct CArcCmdLineOptions
{
bool HelpMode;
#ifdef _7ZIP_LARGE_PAGES
bool LargePages;
#endif
+ bool CaseSensitiveChange;
+ bool CaseSensitive;
bool IsInTerminal;
bool IsStdOutTerminal;
@@ -60,10 +59,9 @@ struct CArchiveCommandLineOptions
bool YesToAll;
bool ShowDialog;
- // NWildcard::CCensor ArchiveWildcardCensor;
- NWildcard::CCensor WildcardCensor;
+ NWildcard::CCensor Censor;
- CArchiveCommand Command;
+ CArcCommand Command;
UString ArchiveName;
#ifndef _NO_CRYPTO
@@ -72,39 +70,52 @@ struct CArchiveCommandLineOptions
#endif
bool TechMode;
- // Extract
- bool CalcCrc;
+
+ UStringVector HashMethods;
+
bool AppendName;
- UString OutputDir;
- NExtract::NOverwriteMode::EEnum OverwriteMode;
UStringVector ArchivePathsSorted;
UStringVector ArchivePathsFullSorted;
- CObjectVector<CProperty> ExtractProperties;
+ CObjectVector<CProperty> Properties;
+
+ CExtractOptionsBase ExtractOptions;
+
+ CBoolPair NtSecurity;
+ CBoolPair AltStreams;
+ CBoolPair HardLinks;
+ CBoolPair SymLinks;
CUpdateOptions UpdateOptions;
+ CHashOptions HashOptions;
UString ArcType;
+ UStringVector ExcludedArcTypes;
bool EnablePercents;
// Benchmark
UInt32 NumIterations;
- UInt32 NumThreads;
- UInt32 DictionarySize;
- UString Method;
-
- CArchiveCommandLineOptions(): StdInMode(false), StdOutMode(false) {};
+ CArcCmdLineOptions():
+ StdInMode(false),
+ StdOutMode(false),
+ CaseSensitiveChange(false),
+ CaseSensitive(false)
+ {};
};
-class CArchiveCommandLineParser
+class CArcCmdLineParser
{
NCommandLineParser::CParser parser;
public:
- CArchiveCommandLineParser();
- void Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options);
- void Parse2(CArchiveCommandLineOptions &options);
+ CArcCmdLineParser();
+ void Parse1(const UStringVector &commandStrings, CArcCmdLineOptions &options);
+ void Parse2(CArcCmdLineOptions &options);
};
-void EnumerateDirItemsAndSort(NWildcard::CCensor &wildcardCensor,
+void EnumerateDirItemsAndSort(
+ bool storeAltStreams,
+ NWildcard::CCensor &censor,
+ NWildcard::ECensorPathMode pathMode,
+ const UString &addPathPrefix,
UStringVector &sortedPaths,
UStringVector &sortedFullPaths);
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
index 4c0cc90b5..250f66797 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
@@ -2,40 +2,200 @@
#include "StdAfx.h"
-#include "Common/ComTry.h"
-#include "Common/Wildcard.h"
+#undef sprintf
+#undef printf
-#include "Windows/FileDir.h"
-#include "Windows/FileFind.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
+#include "../../../Common/ComTry.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/PropVariantConv.h"
+
+#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
+#define _USE_SECURITY_CODE
+#include "../../../Windows/SecurityUtils.h"
+#endif
#include "../../Common/FilePathAutoRename.h"
#include "../Common/ExtractingFilePath.h"
+#include "../Common/PropIDUtils.h"
#include "ArchiveExtractCallback.h"
using namespace NWindows;
+using namespace NFile;
+using namespace NDir;
+
+static const char *kCantAutoRename = "Can not create file with auto name";
+static const char *kCantRenameFile = "Can not rename existing file";
+static const char *kCantDeleteOutputFile = "Can not delete output file";
+static const char *kCantDeleteOutputDir = "Can not delete output folder";
+
+
+#ifndef _SFX
+
+STDMETHODIMP COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ HRESULT result = S_OK;
+ if (_stream)
+ result = _stream->Write(data, size, &size);
+ if (_calculate)
+ _hash->Update(data, size);
+ _size += size;
+ if (processedSize)
+ *processedSize = size;
+ return result;
+}
+
+#endif
+
+#ifdef _USE_SECURITY_CODE
+bool InitLocalPrivileges()
+{
+ NSecurity::CAccessToken token;
+ if (!token.OpenProcessToken(GetCurrentProcess(),
+ TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES))
+ return false;
-static const wchar_t *kCantAutoRename = L"ERROR: Can not create file with auto name";
-static const wchar_t *kCantRenameFile = L"ERROR: Can not rename existing file ";
-static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
+ TOKEN_PRIVILEGES tp;
+
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ if (!::LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &tp.Privileges[0].Luid))
+ return false;
+ if (!token.AdjustPrivileges(&tp))
+ return false;
+ return (GetLastError() == ERROR_SUCCESS);
+}
+#endif
+
+#ifdef SUPPORT_LINKS
+
+int CHardLinkNode::Compare(const CHardLinkNode &a) const
+{
+ if (StreamId < a.StreamId) return -1;
+ if (StreamId > a.StreamId) return 1;
+ return MyCompare(INode, a.INode);
+}
+
+HRESULT Archive_Get_HardLinkNode(IInArchive *archive, UInt32 index, CHardLinkNode &h, bool &defined)
+{
+ h.INode = 0;
+ h.StreamId = (UInt64)(Int64)-1;
+ defined = false;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidINode, &prop));
+ if (!ConvertPropVariantToUInt64(prop, h.INode))
+ return S_OK;
+ }
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidStreamId, &prop));
+ ConvertPropVariantToUInt64(prop, h.StreamId);
+ }
+ defined = true;
+ return S_OK;
+}
+
+
+HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *realIndices)
+{
+ _hardLinks.Clear();
+
+ if (!_arc->Ask_INode)
+ return S_OK;
+
+ IInArchive *archive = _arc->Archive;
+ CRecordVector<CHardLinkNode> &hardIDs = _hardLinks.IDs;
+
+ {
+ UInt32 numItems;
+ if (realIndices)
+ numItems = realIndices->Size();
+ else
+ {
+ RINOK(archive->GetNumberOfItems(&numItems));
+ }
+
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ CHardLinkNode h;
+ bool defined;
+ RINOK(Archive_Get_HardLinkNode(archive, realIndices ? (*realIndices)[i] : i, h, defined));
+ if (defined)
+ hardIDs.Add(h);
+ }
+ }
+
+ hardIDs.Sort2();
+
+ {
+ // wee keep only items that have 2 or more items
+ unsigned k = 0;
+ unsigned numSame = 1;
+ for (unsigned i = 1; i < hardIDs.Size(); i++)
+ {
+ if (hardIDs[i].Compare(hardIDs[i - 1]) != 0)
+ numSame = 1;
+ else if (++numSame == 2)
+ {
+ if (i - 1 != k)
+ hardIDs[k] = hardIDs[i - 1];
+ k++;
+ }
+ }
+ hardIDs.DeleteFrom(k);
+ }
+
+ _hardLinks.PrepareLinks();
+ return S_OK;
+}
+
+#endif
+
+CArchiveExtractCallback::CArchiveExtractCallback():
+ WriteCTime(true),
+ WriteATime(true),
+ WriteMTime(true),
+ _multiArchives(false)
+{
+ LocalProgressSpec = new CLocalProgress();
+ _localProgress = LocalProgressSpec;
+
+ #ifdef _USE_SECURITY_CODE
+ _saclEnabled = InitLocalPrivileges();
+ #endif
+}
void CArchiveExtractCallback::Init(
+ const CExtractNtOptions &ntOptions,
const NWildcard::CCensorNode *wildcardCensor,
const CArc *arc,
IFolderArchiveExtractCallback *extractCallback2,
- bool stdOutMode, bool testMode, bool crcMode,
- const UString &directoryPath,
+ bool stdOutMode, bool testMode,
+ const FString &directoryPath,
const UStringVector &removePathParts,
UInt64 packSize)
{
+ _extractedFolderPaths.Clear();
+ _extractedFolderIndices.Clear();
+
+ #ifdef SUPPORT_LINKS
+ _hardLinks.Clear();
+ #endif
+
+ _ntOptions = ntOptions;
_wildcardCensor = wildcardCensor;
_stdOutMode = stdOutMode;
_testMode = testMode;
- _crcMode = crcMode;
_unpTotal = 1;
_packTotal = packSize;
@@ -43,14 +203,31 @@ void CArchiveExtractCallback::Init(
_compressProgress.Release();
_extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);
+ #ifndef _SFX
+
+ _extractCallback2.QueryInterface(IID_IFolderExtractToStreamCallback, &ExtractToStreamCallback);
+ if (ExtractToStreamCallback)
+ {
+ Int32 useStreams = 0;
+ if (ExtractToStreamCallback->UseExtractToStream(&useStreams) != S_OK)
+ useStreams = 0;
+ if (useStreams == 0)
+ ExtractToStreamCallback.Release();
+ }
+
+ #endif
+
LocalProgressSpec->Init(extractCallback2, true);
LocalProgressSpec->SendProgress = false;
-
_removePathParts = removePathParts;
+ _baseParentFolder = (UInt32)(Int32)-1;
+ _use_baseParentFolder_mode = false;
+
_arc = arc;
_directoryPath = directoryPath;
- NFile::NName::NormalizeDirPathPrefix(_directoryPath);
+ NName::NormalizeDirPathPrefix(_directoryPath);
+ NDir::MyGetFullPathName(directoryPath, _directoryPathFull);
}
STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size)
@@ -107,15 +284,48 @@ STDMETHODIMP CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const U
COM_TRY_END
}
-void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath)
+#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
+
+static inline bool IsDriveName(const UString &s)
{
- fullPath = _directoryPath;
- for (int i = 0; i < dirPathParts.Size(); i++)
+ return s.Len() == 2 && s[1] == ':' && IS_LETTER_CHAR(s[0]);
+}
+
+void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath)
+{
+ bool isAbsPath = false;
+
+ if (!dirPathParts.IsEmpty())
+ {
+ const UString &s = dirPathParts[0];
+ if (s.IsEmpty())
+ isAbsPath = true;
+ #ifdef _WIN32
+ else
+ {
+ if (dirPathParts.Size() > 1 && IsDriveName(s))
+ isAbsPath = true;
+ }
+ #endif
+ }
+
+ if (_pathMode == NExtract::NPathMode::kAbsPaths && isAbsPath)
+ fullPath.Empty();
+ else
+ fullPath = _directoryPath;
+
+ FOR_VECTOR (i, dirPathParts)
{
if (i > 0)
- fullPath += wchar_t(NFile::NName::kDirDelimiter);
- fullPath += dirPathParts[i];
- NFile::NDirectory::MyCreateDirectory(fullPath);
+ fullPath += FCHAR_PATH_SEPARATOR;
+ const UString &s = dirPathParts[i];
+ fullPath += us2fs(s);
+ #ifdef _WIN32
+ if (_pathMode == NExtract::NPathMode::kAbsPaths)
+ if (i == 0 && IsDriveName(s))
+ continue;
+ #endif
+ CreateDir(fullPath);
}
}
@@ -136,23 +346,100 @@ HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &fil
HRESULT CArchiveExtractCallback::GetUnpackSize()
{
- NCOM::CPropVariant prop;
- RINOK(_arc->Archive->GetProperty(_index, kpidSize, &prop));
- _curSizeDefined = (prop.vt != VT_EMPTY);
- if (_curSizeDefined)
- _curSize = ConvertPropVariantToUInt64(prop);
- return S_OK;
+ return _arc->GetItemSize(_index, _curSize, _curSizeDefined);
}
+HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FString &path)
+{
+ return _extractCallback2->MessageError(
+ UString(L"ERROR: ") +
+ GetUnicodeString(message) + L": " + fs2us(path));
+}
+
+HRESULT CArchiveExtractCallback::SendMessageError2(const char *message, const FString &path1, const FString &path2)
+{
+ return _extractCallback2->MessageError(
+ UString(L"ERROR: ") +
+ GetUnicodeString(message) + UString(L": ") + fs2us(path1) + UString(L" : ") + fs2us(path2));
+}
+
+#ifndef _SFX
+
+STDMETHODIMP CGetProp::GetProp(PROPID propID, PROPVARIANT *value)
+{
+ if (propID == kpidName)
+ {
+ COM_TRY_BEGIN
+ NCOM::CPropVariant prop = Name.Ptr();
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+ }
+ return Arc->Archive->GetProperty(IndexInArc, propID, value);
+}
+
+#endif
+
+
+#ifdef SUPPORT_LINKS
+
+static UString GetDirPrefixOf(const UString &src)
+{
+ UString s = src;
+ if (!s.IsEmpty())
+ {
+ if (s.Back() == WCHAR_PATH_SEPARATOR)
+ s.DeleteBack();
+ int pos = s.ReverseFind(WCHAR_PATH_SEPARATOR);
+ s.DeleteFrom(pos + 1);
+ }
+ return s;
+}
+
+static bool IsSafePath(const UString &path)
+{
+ UStringVector parts;
+ SplitPathToParts(path, parts);
+ int level = 0;
+ FOR_VECTOR(i, parts)
+ {
+ const UString &s = parts[i];
+ if (s.IsEmpty())
+ continue;
+ if (s == L".")
+ continue;
+ if (s == L"..")
+ {
+ if (level <= 0)
+ return false;
+ level--;
+ }
+ else
+ level++;
+ }
+ return level > 0;
+}
+
+#endif
+
+
STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
{
COM_TRY_BEGIN
- _crcStream.Release();
+
*outStream = 0;
+
+ #ifndef _SFX
+ if (_hashStream)
+ _hashStreamSpec->ReleaseStream();
+ _hashStreamWasUsed = false;
+ #endif
+
_outFileStream.Release();
_encrypted = false;
_isSplit = false;
+ _isAltStream = false;
_curSize = 0;
_curSizeDefined = false;
_index = index;
@@ -161,7 +448,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
IInArchive *archive = _arc->Archive;
RINOK(_arc->GetItemPath(index, fullPath));
- RINOK(IsArchiveItemFolder(archive, index, _fi.IsDir));
+ RINOK(Archive_IsItem_Folder(archive, index, _fi.IsDir));
_filePath = fullPath;
@@ -176,26 +463,220 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
_isSplit = true;
}
}
-
- RINOK(GetArchiveItemBoolProp(archive, index, kpidEncrypted, _encrypted));
+
+ #ifdef SUPPORT_LINKS
+
+ bool isHardLink = false;
+ bool isJunction = false;
+ bool isRelative = false;
+
+ UString linkPath;
+ // RINOK(Archive_GetItemBoolProp(archive, index, kpidIsHardLink, isHardLink));
+ // if (isHardLink)
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidHardLink, &prop));
+ if (prop.vt == VT_BSTR)
+ {
+ isHardLink = true;
+ linkPath = prop.bstrVal;
+ isRelative = false; // TAR: hard links are from root folder of archive
+ }
+ else if (prop.vt == VT_EMPTY)
+ {
+ // linkPath.Empty();
+ }
+ else
+ return E_FAIL;
+ }
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidSymLink, &prop));
+ if (prop.vt == VT_BSTR)
+ {
+ isHardLink = false;
+ linkPath = prop.bstrVal;
+ isRelative = true; // TAR: symbolic links are relative
+ }
+ else if (prop.vt == VT_EMPTY)
+ {
+ // linkPath.Empty();
+ }
+ else
+ return E_FAIL;
+ }
+
+ bool isOkReparse = false;
+
+ if (linkPath.IsEmpty() && _arc->GetRawProps)
+ {
+ const void *data;
+ UInt32 dataSize;
+ UInt32 propType;
+ _arc->GetRawProps->GetRawProp(_index, kpidNtReparse, &data, &dataSize, &propType);
+ if (dataSize != 0)
+ {
+ if (propType != NPropDataType::kRaw)
+ return E_FAIL;
+ UString s;
+ CReparseAttr reparse;
+ isOkReparse = reparse.Parse((const Byte *)data, dataSize);
+ if (isOkReparse)
+ {
+ isHardLink = false;
+ linkPath = reparse.GetPath();
+ isJunction = reparse.IsMountPoint();
+ isRelative = reparse.IsRelative();
+ #ifndef _WIN32
+ linkPath.Replace(WCHAR_PATH_SEPARATOR, '/', );
+ #endif
+ }
+ }
+ }
+
+ if (!linkPath.IsEmpty())
+ {
+ #ifdef _WIN32
+ linkPath.Replace('/', WCHAR_PATH_SEPARATOR);
+ #endif
+
+ for (;;)
+ // while (NName::IsAbsolutePath(linkPath))
+ {
+ unsigned n = NName::GetRootPrefixSize(linkPath);
+ if (n == 0)
+ break;
+ isRelative = false;
+ linkPath.DeleteFrontal(n);
+ }
+ }
+
+ if (!linkPath.IsEmpty() && !isRelative && _removePathParts.Size() != 0)
+ {
+ UStringVector pathParts;
+ SplitPathToParts(linkPath, pathParts);
+ bool badPrefix = false;
+ FOR_VECTOR (i, _removePathParts)
+ {
+ if (CompareFileNames(_removePathParts[i], pathParts[i]) != 0)
+ {
+ badPrefix = true;
+ break;
+ }
+ }
+ if (!badPrefix)
+ pathParts.DeleteFrontal(_removePathParts.Size());
+ linkPath = MakePathNameFromParts(pathParts);
+ }
+
+ #endif
+
+ RINOK(Archive_GetItemBoolProp(archive, index, kpidEncrypted, _encrypted));
RINOK(GetUnpackSize());
+ RINOK(Archive_IsItem_AltStream(archive, index, _isAltStream));
+
+ if (!_ntOptions.AltStreams.Val && _isAltStream)
+ return S_OK;
+
if (_wildcardCensor)
{
- if (!_wildcardCensor->CheckPath(fullPath, !_fi.IsDir))
+ if (!_wildcardCensor->CheckPath(_isAltStream, fullPath, !_fi.IsDir))
return S_OK;
}
- if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
+
+ UStringVector pathParts;
+
+ if (_use_baseParentFolder_mode)
+ {
+ int baseParent = _baseParentFolder;
+ if (_pathMode == NExtract::NPathMode::kFullPaths ||
+ _pathMode == NExtract::NPathMode::kAbsPaths)
+ baseParent = -1;
+ RINOK(_arc->GetItemPathToParent(index, baseParent, pathParts));
+ if (_pathMode == NExtract::NPathMode::kNoPaths && !pathParts.IsEmpty())
+ pathParts.DeleteFrontal(pathParts.Size() - 1);
+ }
+ else
+ {
+ SplitPathToParts(fullPath, pathParts);
+
+ if (pathParts.IsEmpty())
+ return E_FAIL;
+ unsigned numRemovePathParts = 0;
+
+ switch (_pathMode)
+ {
+ case NExtract::NPathMode::kCurPaths:
+ {
+ bool badPrefix = false;
+ if (pathParts.Size() <= _removePathParts.Size())
+ badPrefix = true;
+ else
+ {
+ FOR_VECTOR (i, _removePathParts)
+ {
+ if (!_removePathParts[i].IsEqualToNoCase(pathParts[i]))
+ {
+ badPrefix = true;
+ break;
+ }
+ }
+ }
+ if (badPrefix)
+ {
+ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
+ return E_FAIL;
+ }
+ else
+ numRemovePathParts = _removePathParts.Size();
+ break;
+ }
+ case NExtract::NPathMode::kNoPaths:
+ {
+ numRemovePathParts = pathParts.Size() - 1;
+ break;
+ }
+ /*
+ case NExtract::NPathMode::kFullPaths:
+ case NExtract::NPathMode::kAbsPaths:
+ break;
+ */
+ }
+
+ pathParts.DeleteFrontal(numRemovePathParts);
+ }
+
+ #ifndef _SFX
+
+ if (ExtractToStreamCallback)
{
- if (_stdOutMode)
+ if (!GetProp)
{
- CMyComPtr<ISequentialOutStream> outStreamLoc = new CStdOutFileStream;
- *outStream = outStreamLoc.Detach();
- return S_OK;
+ GetProp_Spec = new CGetProp;
+ GetProp = GetProp_Spec;
}
+ GetProp_Spec->Arc = _arc;
+ GetProp_Spec->IndexInArc = index;
+ GetProp_Spec->Name = MakePathNameFromParts(pathParts);
+
+ return ExtractToStreamCallback->GetStream7(GetProp_Spec->Name, _fi.IsDir, outStream, askExtractMode, GetProp);
+ }
+
+ #endif
+ CMyComPtr<ISequentialOutStream> outStreamLoc;
+
+if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
+{
+ if (_stdOutMode)
+ {
+ outStreamLoc = new CStdOutFileStream;
+ }
+ else
+ {
{
NCOM::CPropVariant prop;
RINOK(archive->GetProperty(index, kpidAttrib, &prop));
@@ -217,35 +698,15 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
bool isAnti = false;
RINOK(_arc->IsItemAnti(index, isAnti));
- UStringVector pathParts;
- SplitPathToParts(fullPath, pathParts);
-
- if (pathParts.IsEmpty())
- return E_FAIL;
- int numRemovePathParts = 0;
- switch(_pathMode)
- {
- case NExtract::NPathMode::kFullPathnames:
- break;
- case NExtract::NPathMode::kCurrentPathnames:
- {
- numRemovePathParts = _removePathParts.Size();
- if (pathParts.Size() <= numRemovePathParts)
- return E_FAIL;
- for (int i = 0; i < numRemovePathParts; i++)
- if (_removePathParts[i].CompareNoCase(pathParts[i]) != 0)
- return E_FAIL;
- break;
- }
- case NExtract::NPathMode::kNoPathnames:
- {
- numRemovePathParts = pathParts.Size() - 1;
- break;
- }
- }
- pathParts.Delete(0, numRemovePathParts);
- MakeCorrectPath(pathParts);
+ bool replace = _isAltStream ?
+ _ntOptions.ReplaceColonForAltStream :
+ !_ntOptions.WriteToAltStreamIfColon;
+
+ if (_pathMode != NExtract::NPathMode::kAbsPaths)
+ MakeCorrectPath(_directoryPath.IsEmpty(), pathParts, replace);
+ Correct_IfEmptyLastPart(pathParts);
UString processedPath = MakePathNameFromParts(pathParts);
+
if (!isAnti)
{
if (!_fi.IsDir)
@@ -253,142 +714,273 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
if (!pathParts.IsEmpty())
pathParts.DeleteBack();
}
-
+
if (!pathParts.IsEmpty())
{
- UString fullPathNew;
+ FString fullPathNew;
CreateComplexDirectory(pathParts, fullPathNew);
if (_fi.IsDir)
- NFile::NDirectory::SetDirTime(fullPathNew,
+ {
+ _extractedFolderPaths.Add(fullPathNew);
+ _extractedFolderIndices.Add(index);
+ SetDirTime(fullPathNew,
(WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
(WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
(WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
+ }
}
}
- UString fullProcessedPath = _directoryPath + processedPath;
+ FString fullProcessedPath = us2fs(processedPath);
+ if (_pathMode != NExtract::NPathMode::kAbsPaths ||
+ !NName::IsAbsolutePath(processedPath))
+ fullProcessedPath = _directoryPath + fullProcessedPath;
if (_fi.IsDir)
{
_diskFilePath = fullProcessedPath;
if (isAnti)
- NFile::NDirectory::MyRemoveDirectory(_diskFilePath);
- return S_OK;
+ RemoveDir(_diskFilePath);
+ #ifdef SUPPORT_LINKS
+ if (linkPath.IsEmpty())
+ #endif
+ return S_OK;
}
-
- if (!_isSplit)
+ else if (!_isSplit)
{
- NFile::NFind::CFileInfoW fileInfo;
+ NFind::CFileInfo fileInfo;
if (fileInfo.Find(fullProcessedPath))
{
- switch(_overwriteMode)
+ switch (_overwriteMode)
{
- case NExtract::NOverwriteMode::kSkipExisting:
+ case NExtract::NOverwriteMode::kSkip:
return S_OK;
- case NExtract::NOverwriteMode::kAskBefore:
+ case NExtract::NOverwriteMode::kAsk:
{
+ int slashPos = fullProcessedPath.ReverseFind(FTEXT('/'));
+ #ifdef _WIN32
+ int slash1Pos = fullProcessedPath.ReverseFind(FTEXT('\\'));
+ slashPos = MyMax(slashPos, slash1Pos);
+ #endif
+ FString realFullProcessedPath = fullProcessedPath.Left(slashPos + 1) + fileInfo.Name;
+
Int32 overwiteResult;
RINOK(_extractCallback2->AskOverwrite(
- fullProcessedPath, &fileInfo.MTime, &fileInfo.Size, fullPath,
+ fs2us(realFullProcessedPath), &fileInfo.MTime, &fileInfo.Size, fullPath,
_fi.MTimeDefined ? &_fi.MTime : NULL,
_curSizeDefined ? &_curSize : NULL,
&overwiteResult))
- switch(overwiteResult)
+ switch (overwiteResult)
{
- case NOverwriteAnswer::kCancel:
- return E_ABORT;
- case NOverwriteAnswer::kNo:
- return S_OK;
- case NOverwriteAnswer::kNoToAll:
- _overwriteMode = NExtract::NOverwriteMode::kSkipExisting;
- return S_OK;
- case NOverwriteAnswer::kYesToAll:
- _overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
- break;
- case NOverwriteAnswer::kYes:
- break;
- case NOverwriteAnswer::kAutoRename:
- _overwriteMode = NExtract::NOverwriteMode::kAutoRename;
- break;
+ case NOverwriteAnswer::kCancel: return E_ABORT;
+ case NOverwriteAnswer::kNo: return S_OK;
+ case NOverwriteAnswer::kNoToAll: _overwriteMode = NExtract::NOverwriteMode::kSkip; return S_OK;
+ case NOverwriteAnswer::kYes: break;
+ case NOverwriteAnswer::kYesToAll: _overwriteMode = NExtract::NOverwriteMode::kOverwrite; break;
+ case NOverwriteAnswer::kAutoRename: _overwriteMode = NExtract::NOverwriteMode::kRename; break;
default:
return E_FAIL;
}
}
}
- if (_overwriteMode == NExtract::NOverwriteMode::kAutoRename)
+ if (_overwriteMode == NExtract::NOverwriteMode::kRename)
{
if (!AutoRenamePath(fullProcessedPath))
{
- UString message = UString(kCantAutoRename) + fullProcessedPath;
- RINOK(_extractCallback2->MessageError(message));
+ RINOK(SendMessageError(kCantAutoRename, fullProcessedPath));
return E_FAIL;
}
}
- else if (_overwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting)
+ else if (_overwriteMode == NExtract::NOverwriteMode::kRenameExisting)
{
- UString existPath = fullProcessedPath;
+ FString existPath = fullProcessedPath;
if (!AutoRenamePath(existPath))
{
- UString message = kCantAutoRename + fullProcessedPath;
- RINOK(_extractCallback2->MessageError(message));
+ RINOK(SendMessageError(kCantAutoRename, fullProcessedPath));
return E_FAIL;
}
- if (!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath))
+ // MyMoveFile can raname folders. So it's OK to use it folders too
+ if (!MyMoveFile(fullProcessedPath, existPath))
{
- UString message = UString(kCantRenameFile) + fullProcessedPath;
- RINOK(_extractCallback2->MessageError(message));
+ RINOK(SendMessageError(kCantRenameFile, fullProcessedPath));
return E_FAIL;
}
}
else
- if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
+ {
+ if (fileInfo.IsDir())
{
- UString message = UString(kCantDeleteOutputFile) + fullProcessedPath;
- RINOK(_extractCallback2->MessageError(message));
+ // do we need to delete all files in folder?
+ if (!RemoveDir(fullProcessedPath))
+ {
+ RINOK(SendMessageError(kCantDeleteOutputDir, fullProcessedPath));
+ return S_OK;
+ }
+ }
+ else if (!DeleteFileAlways(fullProcessedPath))
+ {
+ RINOK(SendMessageError(kCantDeleteOutputFile, fullProcessedPath));
return S_OK;
// return E_FAIL;
}
+ }
}
}
+ _diskFilePath = fullProcessedPath;
+
+
if (!isAnti)
{
- _outFileStreamSpec = new COutFileStream;
- CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
- if (!_outFileStreamSpec->Open(fullProcessedPath, _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS))
+ #ifdef SUPPORT_LINKS
+
+ if (!linkPath.IsEmpty())
{
- // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
+ #ifndef UNDER_CE
+
+ UString relatPath;
+ if (isRelative)
+ relatPath = GetDirPrefixOf(_filePath);
+ relatPath += linkPath;
+
+ if (!IsSafePath(relatPath))
{
- UString message = L"can not open output file " + fullProcessedPath;
- RINOK(_extractCallback2->MessageError(message));
- return S_OK;
+ RINOK(SendMessageError("Dangerous link path was ignored", us2fs(relatPath)));
}
+ else
+ {
+ FString existPath;
+ if (isHardLink || !isRelative)
+ {
+ if (!NName::GetFullPath(_directoryPathFull, us2fs(relatPath), existPath))
+ {
+ RINOK(SendMessageError("Incorrect path", us2fs(relatPath)));
+ }
+ }
+ else
+ {
+ existPath = us2fs(linkPath);
+ }
+
+ if (!existPath.IsEmpty())
+ {
+ if (isHardLink)
+ {
+ if (!MyCreateHardLink(fullProcessedPath, existPath))
+ {
+ RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, existPath));
+ // return S_OK;
+ }
+ }
+ else if (_ntOptions.SymLinks.Val)
+ {
+ // bool isSymLink = true; // = false for junction
+ if (_fi.IsDir && !isRelative)
+ {
+ // if it's before Vista we use Junction Point
+ // isJunction = true;
+ // convertToAbs = true;
+ }
+
+ CByteBuffer data;
+ if (FillLinkData(data, fs2us(existPath), !isJunction))
+ {
+ CReparseAttr attr;
+ if (!attr.Parse(data, data.Size()))
+ {
+ return E_FAIL; // "Internal conversion error";
+ }
+
+ if (!NFile::NIO::SetReparseData(fullProcessedPath, _fi.IsDir, data, (DWORD)data.Size()))
+ {
+ RINOK(SendMessageError("Can not set reparse data", fullProcessedPath));
+ }
+ }
+ }
+ }
+ }
+
+ #endif
}
- if (_isSplit)
+ else
+ #endif // SUPPORT_LINKS
{
- RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL));
+ bool needWriteFile = true;
+
+ #ifdef SUPPORT_LINKS
+ if (!_hardLinks.IDs.IsEmpty())
+ {
+ CHardLinkNode h;
+ bool defined;
+ RINOK(Archive_Get_HardLinkNode(archive, index, h, defined));
+ if (defined)
+ {
+ {
+ int linkIndex = _hardLinks.IDs.FindInSorted2(h);
+ if (linkIndex >= 0)
+ {
+ FString &hl = _hardLinks.Links[linkIndex];
+ if (hl.IsEmpty())
+ hl = fullProcessedPath;
+ else
+ {
+ if (!MyCreateHardLink(fullProcessedPath, hl))
+ {
+ RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, hl));
+ return S_OK;
+ }
+ needWriteFile = false;
+ }
+ }
+ }
+ }
+ }
+ #endif
+
+ if (needWriteFile)
+ {
+ _outFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+ if (!_outFileStreamSpec->Open(fullProcessedPath, _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS))
+ {
+ // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
+ {
+ RINOK(SendMessageError("Can not open output file ", fullProcessedPath));
+ return S_OK;
+ }
+ }
+ if (_isSplit)
+ {
+ RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL));
+ }
+ _outFileStream = outStreamLoc;
+ }
}
- _outFileStream = outStreamLoc;
- *outStream = outStreamLoc.Detach();
}
- _diskFilePath = fullProcessedPath;
- }
- else
- {
- *outStream = NULL;
+
+ outStreamLoc = _outFileStream;
}
- if (_crcMode)
+}
+
+ #ifndef _SFX
+
+ if (_hashStream)
{
- _crcStreamSpec = new COutStreamWithCRC;
- _crcStream = _crcStreamSpec;
- CMyComPtr<ISequentialOutStream> crcStream = _crcStreamSpec;
- _crcStreamSpec->SetStream(*outStream);
- if (*outStream)
- (*outStream)->Release();
- *outStream = crcStream.Detach();
- _crcStreamSpec->Init(true);
+ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract ||
+ askExtractMode == NArchive::NExtract::NAskMode::kTest)
+ {
+ _hashStreamSpec->SetStream(outStreamLoc);
+ outStreamLoc = _hashStream;
+ _hashStreamSpec->Init(true);
+ _hashStreamWasUsed = true;
+ }
}
+
+ #endif
+
+ if (outStreamLoc)
+ *outStream = outStreamLoc.Detach();
return S_OK;
COM_TRY_END
}
@@ -396,6 +988,12 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
{
COM_TRY_BEGIN
+
+ #ifndef _SFX
+ if (ExtractToStreamCallback)
+ return ExtractToStreamCallback->PrepareOperation7(askExtractMode);
+ #endif
+
_extractMode = false;
switch (askExtractMode)
{
@@ -414,24 +1012,25 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
{
COM_TRY_BEGIN
- switch(operationResult)
- {
- case NArchive::NExtract::NOperationResult::kOK:
- case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
- case NArchive::NExtract::NOperationResult::kCRCError:
- case NArchive::NExtract::NOperationResult::kDataError:
- break;
- default:
- _outFileStream.Release();
- return E_FAIL;
- }
- if (_crcStream)
+
+ #ifndef _SFX
+ if (ExtractToStreamCallback)
+ return ExtractToStreamCallback->SetOperationResult7(operationResult, _encrypted);
+ #endif
+
+ #ifndef _SFX
+
+ if (_hashStreamWasUsed)
{
- CrcSum += _crcStreamSpec->GetCRC();
- _curSize = _crcStreamSpec->GetSize();
+ _hashStreamSpec->_hash->Final(_fi.IsDir, _isAltStream, _filePath);
+ _curSize = _hashStreamSpec->GetSize();
_curSizeDefined = true;
- _crcStream.Release();
+ _hashStreamSpec->ReleaseStream();
+ _hashStreamWasUsed = false;
}
+
+ #endif
+
if (_outFileStream)
{
_outFileStreamSpec->SetTime(
@@ -443,17 +1042,48 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
RINOK(_outFileStreamSpec->Close());
_outFileStream.Release();
}
+
+ #ifdef _USE_SECURITY_CODE
+ if (_ntOptions.NtSecurity.Val && _arc->GetRawProps)
+ {
+ const void *data;
+ UInt32 dataSize;
+ UInt32 propType;
+ _arc->GetRawProps->GetRawProp(_index, kpidNtSecure, &data, &dataSize, &propType);
+ if (dataSize != 0)
+ {
+ if (propType != NPropDataType::kRaw)
+ return E_FAIL;
+ if (CheckNtSecure((const Byte *)data, dataSize))
+ {
+ SECURITY_INFORMATION securInfo = DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION;
+ if (_saclEnabled)
+ securInfo |= SACL_SECURITY_INFORMATION;
+ ::SetFileSecurityW(fs2us(_diskFilePath), securInfo, (PSECURITY_DESCRIPTOR)(void *)data);
+ }
+ }
+ }
+ #endif
+
if (!_curSizeDefined)
GetUnpackSize();
if (_curSizeDefined)
- UnpackSize += _curSize;
+ {
+ if (_isAltStream)
+ AltStreams_UnpackSize += _curSize;
+ else
+ UnpackSize += _curSize;
+ }
+
if (_fi.IsDir)
NumFolders++;
+ else if (_isAltStream)
+ NumAltStreams++;
else
NumFiles++;
if (_extractMode && _fi.AttribDefined)
- NFile::NDirectory::MySetFileAttributes(_diskFilePath, _fi.Attrib);
+ SetFileAttrib(_diskFilePath, _fi.Attrib);
RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted));
return S_OK;
COM_TRY_END
@@ -486,3 +1116,76 @@ STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
COM_TRY_END
}
+
+struct CExtrRefSortPair
+{
+ int Len;
+ int Index;
+
+ int Compare(const CExtrRefSortPair &a) const;
+};
+
+#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
+
+int CExtrRefSortPair::Compare(const CExtrRefSortPair &a) const
+{
+ RINOZ(-MyCompare(Len, a.Len));
+ return MyCompare(Index, a.Index);
+}
+
+static int GetNumSlashes(const FChar *s)
+{
+ for (int numSlashes = 0;;)
+ {
+ FChar c = *s++;
+ if (c == 0)
+ return numSlashes;
+ if (
+ #ifdef _WIN32
+ c == FTEXT('\\') ||
+ #endif
+ c == FTEXT('/'))
+ numSlashes++;
+ }
+}
+
+HRESULT CArchiveExtractCallback::SetDirsTimes()
+{
+ CRecordVector<CExtrRefSortPair> pairs;
+ pairs.ClearAndSetSize(_extractedFolderPaths.Size());
+ unsigned i;
+
+ for (i = 0; i < _extractedFolderPaths.Size(); i++)
+ {
+ CExtrRefSortPair &pair = pairs[i];
+ pair.Index = i;
+ pair.Len = GetNumSlashes(_extractedFolderPaths[i]);
+ }
+
+ pairs.Sort2();
+
+ for (i = 0; i < pairs.Size(); i++)
+ {
+ int pairIndex = pairs[i].Index;
+ int index = _extractedFolderIndices[pairIndex];
+
+ FILETIME CTime;
+ FILETIME ATime;
+ FILETIME MTime;
+
+ bool CTimeDefined;
+ bool ATimeDefined;
+ bool MTimeDefined;
+
+ RINOK(GetTime(index, kpidCTime, CTime, CTimeDefined));
+ RINOK(GetTime(index, kpidATime, ATime, ATimeDefined));
+ RINOK(GetTime(index, kpidMTime, MTime, MTimeDefined));
+
+ // printf("\n%S", _extractedFolderPaths[pairIndex]);
+ SetDirTime(_extractedFolderPaths[pairIndex],
+ (WriteCTime && CTimeDefined) ? &CTime : NULL,
+ (WriteATime && ATimeDefined) ? &ATime : NULL,
+ (WriteMTime && MTimeDefined) ? &MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
+ }
+ return S_OK;
+}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveExtractCallback.h
index 367e4b07d..374297651 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveExtractCallback.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveExtractCallback.h
@@ -3,8 +3,8 @@
#ifndef __ARCHIVE_EXTRACT_CALLBACK_H
#define __ARCHIVE_EXTRACT_CALLBACK_H
-#include "Common/MyCom.h"
-#include "Common/Wildcard.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Common/Wildcard.h"
#include "../../IPassword.h"
@@ -13,12 +13,117 @@
#include "../../Archive/IArchive.h"
-#include "../../Archive/Common/OutStreamWithCRC.h"
-
#include "ExtractMode.h"
#include "IFileExtractCallback.h"
#include "OpenArchive.h"
+#include "HashCalc.h"
+
+#ifndef _SFX
+
+class COutStreamWithHash:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _size;
+ bool _calculate;
+public:
+ IHashCalc *_hash;
+
+ MY_UNKNOWN_IMP
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void ReleaseStream() { _stream.Release(); }
+ void Init(bool calculate = true)
+ {
+ InitCRC();
+ _size = 0;
+ _calculate = calculate;
+ }
+ void EnableCalc(bool calculate) { _calculate = calculate; }
+ void InitCRC() { _hash->InitForNewFile(); }
+ UInt64 GetSize() const { return _size; }
+};
+
+#endif
+
+struct CExtractNtOptions
+{
+ CBoolPair NtSecurity;
+ CBoolPair SymLinks;
+ CBoolPair HardLinks;
+ CBoolPair AltStreams;
+ bool ReplaceColonForAltStream;
+ bool WriteToAltStreamIfColon;
+
+ CExtractNtOptions():
+ ReplaceColonForAltStream(false),
+ WriteToAltStreamIfColon(false)
+ {
+ SymLinks.Val = true;
+ HardLinks.Val = true;
+ AltStreams.Val = true;
+ }
+};
+
+#ifndef _SFX
+
+class CGetProp:
+ public IGetProp,
+ public CMyUnknownImp
+{
+public:
+ const CArc *Arc;
+ UInt32 IndexInArc;
+ UString Name; // relative path
+
+ MY_UNKNOWN_IMP1(IGetProp)
+ INTERFACE_IGetProp(;)
+};
+
+#endif
+
+#ifndef _SFX
+#ifndef UNDER_CE
+
+// FIXME #define SUPPORT_LINKS
+
+#endif
+#endif
+
+
+#ifdef SUPPORT_LINKS
+
+struct CHardLinkNode
+{
+ UInt64 StreamId;
+ UInt64 INode;
+
+ int Compare(const CHardLinkNode &a) const;
+};
+
+class CHardLinks
+{
+public:
+ CRecordVector<CHardLinkNode> IDs;
+ CObjectVector<FString> Links;
+
+ void Clear()
+ {
+ IDs.Clear();
+ Links.Clear();
+ }
+
+ void PrepareLinks()
+ {
+ while (Links.Size() < IDs.Size())
+ Links.AddNew();
+ }
+};
+
+#endif
+
class CArchiveExtractCallback:
public IArchiveExtractCallback,
// public IArchiveVolumeExtractCallback,
@@ -27,18 +132,30 @@ class CArchiveExtractCallback:
public CMyUnknownImp
{
const CArc *_arc;
+ CExtractNtOptions _ntOptions;
+
const NWildcard::CCensorNode *_wildcardCensor;
CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
CMyComPtr<ICompressProgressInfo> _compressProgress;
CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
- UString _directoryPath;
+ FString _directoryPath;
+ FString _directoryPathFull;
NExtract::NPathMode::EEnum _pathMode;
NExtract::NOverwriteMode::EEnum _overwriteMode;
- UString _diskFilePath;
+ #ifndef _SFX
+
+ CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
+ CGetProp *GetProp_Spec;
+ CMyComPtr<IGetProp> GetProp;
+
+ #endif
+
+ FString _diskFilePath;
UString _filePath;
UInt64 _position;
bool _isSplit;
+ bool _isAltStream;
bool _extractMode;
@@ -54,7 +171,7 @@ class CArchiveExtractCallback:
FILETIME ATime;
FILETIME MTime;
UInt32 Attrib;
-
+
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
@@ -69,33 +186,50 @@ class CArchiveExtractCallback:
COutFileStream *_outFileStreamSpec;
CMyComPtr<ISequentialOutStream> _outFileStream;
- COutStreamWithCRC *_crcStreamSpec;
- CMyComPtr<ISequentialOutStream> _crcStream;
+ #ifndef _SFX
+
+ COutStreamWithHash *_hashStreamSpec;
+ CMyComPtr<ISequentialOutStream> _hashStream;
+ bool _hashStreamWasUsed;
+
+ #endif
UStringVector _removePathParts;
+ bool _use_baseParentFolder_mode;
+ UInt32 _baseParentFolder;
bool _stdOutMode;
bool _testMode;
- bool _crcMode;
bool _multiArchives;
CMyComPtr<ICompressProgressInfo> _localProgress;
UInt64 _packTotal;
UInt64 _unpTotal;
- void CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath);
+ FStringVector _extractedFolderPaths;
+ CRecordVector<UInt32> _extractedFolderIndices;
+
+ #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
+ bool _saclEnabled;
+ #endif
+
+ void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
HRESULT GetUnpackSize();
+ HRESULT SendMessageError(const char *message, const FString &path);
+ HRESULT SendMessageError2(const char *message, const FString &path1, const FString &path2);
+
public:
CLocalProgress *LocalProgressSpec;
UInt64 NumFolders;
UInt64 NumFiles;
+ UInt64 NumAltStreams;
UInt64 UnpackSize;
- UInt32 CrcSum;
-
+ UInt64 AltStreams_UnpackSize;
+
MY_UNKNOWN_IMP2(ICryptoGetTextPassword, ICompressProgressInfo)
// COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)
@@ -108,15 +242,7 @@ public:
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
- CArchiveExtractCallback():
- WriteCTime(true),
- WriteATime(true),
- WriteMTime(true),
- _multiArchives(false)
- {
- LocalProgressSpec = new CLocalProgress();
- _localProgress = LocalProgressSpec;
- }
+ CArchiveExtractCallback();
void InitForMulti(bool multiArchives,
NExtract::NPathMode::EEnum pathMode,
@@ -125,19 +251,49 @@ public:
_multiArchives = multiArchives;
_pathMode = pathMode;
_overwriteMode = overwriteMode;
- NumFolders = NumFiles = UnpackSize = 0;
- CrcSum = 0;
+ NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0;
+ }
+
+ #ifndef _SFX
+
+ void SetHashMethods(IHashCalc *hash)
+ {
+ if (!hash)
+ return;
+ _hashStreamSpec = new COutStreamWithHash;
+ _hashStream = _hashStreamSpec;
+ _hashStreamSpec->_hash = hash;
}
+ #endif
+
void Init(
+ const CExtractNtOptions &ntOptions,
const NWildcard::CCensorNode *wildcardCensor,
const CArc *arc,
IFolderArchiveExtractCallback *extractCallback2,
- bool stdOutMode, bool testMode, bool crcMode,
- const UString &directoryPath,
+ bool stdOutMode, bool testMode,
+ const FString &directoryPath,
const UStringVector &removePathParts,
UInt64 packSize);
+ #ifdef SUPPORT_LINKS
+private:
+ CHardLinks _hardLinks;
+public:
+ // call PrepareHardLinks() after Init()
+ HRESULT PrepareHardLinks(const CRecordVector<UInt32> *realIndices); // NULL means all items
+ #endif
+
+ // call it after Init()
+
+ void SetBaseParentFolderIndex(UInt32 indexInArc)
+ {
+ _use_baseParentFolder_mode = true;
+ _baseParentFolder = indexInArc;
+ }
+
+ HRESULT SetDirsTimes();
};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveName.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveName.cpp
deleted file mode 100644
index c3684def8..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveName.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// ArchiveName.cpp
-
-#include "StdAfx.h"
-
-#include "Windows/FileDir.h"
-#include "Windows/FileFind.h"
-
-#include "ExtractingFilePath.h"
-
-using namespace NWindows;
-
-static UString CreateArchiveName2(const UString &srcName, bool fromPrev, bool keepName)
-{
- UString resultName = L"Archive";
- if (fromPrev)
- {
- UString dirPrefix;
- if (NFile::NDirectory::GetOnlyDirPrefix(srcName, dirPrefix))
- {
- if (dirPrefix.Length() > 0)
- if (dirPrefix[dirPrefix.Length() - 1] == WCHAR_PATH_SEPARATOR)
- {
- dirPrefix.Delete(dirPrefix.Length() - 1);
- NFile::NFind::CFileInfoW fileInfo;
- if (fileInfo.Find(dirPrefix))
- resultName = fileInfo.Name;
- }
- }
- }
- else
- {
- NFile::NFind::CFileInfoW fileInfo;
- if (!fileInfo.Find(srcName))
- // return resultName;
- return srcName;
- resultName = fileInfo.Name;
- if (!fileInfo.IsDir() && !keepName)
- {
- int dotPos = resultName.ReverseFind('.');
- if (dotPos > 0)
- {
- UString archiveName2 = resultName.Left(dotPos);
- if (archiveName2.ReverseFind('.') < 0)
- resultName = archiveName2;
- }
- }
- }
- return resultName;
-}
-
-UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)
-{
- return GetCorrectFsPath(CreateArchiveName2(srcName, fromPrev, keepName));
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveName.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveName.h
deleted file mode 100644
index 9513fb2ba..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveName.h
+++ /dev/null
@@ -1,10 +0,0 @@
-// ArchiveName.h
-
-#ifndef __ARCHIVENAME_H
-#define __ARCHIVENAME_H
-
-#include "Common/MyString.h"
-
-UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName);
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
index e7e617131..9eab39d31 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
@@ -2,10 +2,10 @@
#include "StdAfx.h"
-#include "Common/StringConvert.h"
-#include "Common/ComTry.h"
+#include "../../../Common/ComTry.h"
-#include "Windows/PropVariant.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/PropVariant.h"
#include "../../Common/FileStreams.h"
@@ -34,7 +34,7 @@ STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *b
return Callback->Open_SetCompleted(files, bytes);
COM_TRY_END
}
-
+
STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -60,55 +60,48 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
COM_TRY_END
}
-int COpenCallbackImp::FindName(const UString &name)
-{
- for (int i = 0; i < FileNames.Size(); i++)
- if (name.CompareNoCase(FileNames[i]) == 0)
- return i;
- return -1;
-}
-
struct CInFileStreamVol: public CInFileStream
{
- UString Name;
+ int FileNameIndex;
COpenCallbackImp *OpenCallbackImp;
CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
+ CInFileStreamVol(bool ignoreLink = false) : CInFileStream(ignoreLink) { }
~CInFileStreamVol()
{
if (OpenCallbackRef)
- {
- int index = OpenCallbackImp->FindName(Name);
- if (index >= 0)
- OpenCallbackImp->FileNames.Delete(index);
- }
+ OpenCallbackImp->FileNames_WasUsed[FileNameIndex] = false;
}
};
STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)
{
COM_TRY_BEGIN
+ *inStream = NULL;
if (_subArchiveMode)
return S_FALSE;
if (Callback)
{
RINOK(Callback->Open_CheckBreak());
}
- *inStream = NULL;
- UString fullPath = _folderPrefix + name;
- if (!_fileInfo.Find(fullPath))
+ FString fullPath;
+ if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name), fullPath))
+ return S_FALSE;
+ if (!_fileInfo.Find(fullPath,true))
return S_FALSE;
if (_fileInfo.IsDir())
return S_FALSE;
- CInFileStreamVol *inFile = new CInFileStreamVol;
+ CInFileStreamVol *inFile = new CInFileStreamVol(true);
CMyComPtr<IInStream> inStreamTemp = inFile;
if (!inFile->Open(fullPath))
return ::GetLastError();
- *inStream = inStreamTemp.Detach();
- inFile->Name = name;
+
+ FileSizes.Add(_fileInfo.Size);
+ FileNames.Add(name);
+ inFile->FileNameIndex = FileNames_WasUsed.Add(true);
inFile->OpenCallbackImp = this;
inFile->OpenCallbackRef = this;
- FileNames.Add(name);
- TotalSize += _fileInfo.Size;
+ // TotalSize += _fileInfo.Size;
+ *inStream = inStreamTemp.Detach();
return S_OK;
COM_TRY_END
}
@@ -130,4 +123,3 @@ STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
COM_TRY_END
}
#endif
-
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveOpenCallback.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveOpenCallback.h
index c6651e8f9..b72892c2f 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveOpenCallback.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/ArchiveOpenCallback.h
@@ -3,10 +3,9 @@
#ifndef __ARCHIVE_OPEN_CALLBACK_H
#define __ARCHIVE_OPEN_CALLBACK_H
-#include "Common/MyCom.h"
-#include "Common/MyString.h"
+#include "../../../Common/MyCom.h"
-#include "Windows/FileFind.h"
+#include "../../../Windows/FileFind.h"
#ifndef _NO_CRYPTO
#include "../../IPassword.h"
@@ -21,10 +20,10 @@
#define INTERFACE_IOpenCallbackUI_Crypto(x) \
virtual HRESULT Open_CryptoGetTextPassword(BSTR *password) x; \
- virtual HRESULT Open_GetPasswordIfAny(UString &password) x; \
+ virtual HRESULT Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) x; \
virtual bool Open_WasPasswordAsked() x; \
virtual void Open_ClearPasswordWasAskedFlag() x; \
-
+
#endif
#define INTERFACE_IOpenCallbackUI(x) \
@@ -72,32 +71,41 @@ public:
{
_subArchiveMode = true;
_subArchiveName = name;
- TotalSize = 0;
- return S_OK;
+ // TotalSize = 0;
+ return S_OK;
}
private:
- UString _folderPrefix;
- NWindows::NFile::NFind::CFileInfoW _fileInfo;
+ FString _folderPrefix;
+ NWindows::NFile::NFind::CFileInfo _fileInfo;
bool _subArchiveMode;
UString _subArchiveName;
+
public:
UStringVector FileNames;
+ CBoolVector FileNames_WasUsed;
+ CRecordVector<UInt64> FileSizes;
+
IOpenCallbackUI *Callback;
CMyComPtr<IArchiveOpenCallback> ReOpenCallback;
- UInt64 TotalSize;
+ // UInt64 TotalSize;
COpenCallbackImp(): Callback(NULL) {}
- void Init(const UString &folderPrefix, const UString &fileName)
+ void Init(const FString &folderPrefix, const FString &fileName)
{
_folderPrefix = folderPrefix;
- if (!_fileInfo.Find(_folderPrefix + fileName))
- throw 1;
+ if (!_fileInfo.Find(_folderPrefix + fileName,true))
+ throw 20121118;
FileNames.Clear();
+ FileNames_WasUsed.Clear();
+ FileSizes.Clear();
_subArchiveMode = false;
- TotalSize = 0;
+ // TotalSize = 0;
+ }
+ bool SetSecondFileInfo(CFSTR newName)
+ {
+ return _fileInfo.Find(newName) && !_fileInfo.IsDir();
}
- int FindName(const UString &name);
};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/Bench.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/Bench.cpp
deleted file mode 100644
index 282f405f1..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/Bench.cpp
+++ /dev/null
@@ -1,1028 +0,0 @@
-// Bench.cpp
-
-#include "StdAfx.h"
-
-#include "Bench.h"
-
-#ifndef _WIN32
-#define USE_POSIX_TIME
-#define USE_POSIX_TIME2
-#endif
-
-#ifdef USE_POSIX_TIME
-#include <time.h>
-#ifdef USE_POSIX_TIME2
-#include <sys/time.h>
-#endif
-#endif
-
-#ifdef _WIN32
-#define USE_ALLOCA
-#endif
-
-#ifdef USE_ALLOCA
-#ifdef _WIN32
-#include <malloc.h>
-#else
-#include <stdlib.h>
-#endif
-#endif
-
-#include "../../../../C/7zCrc.h"
-#include "../../../../C/Alloc.h"
-
-#ifndef _7ZIP_ST
-#include "../../../Windows/Synchronization.h"
-#include "../../../Windows/Thread.h"
-#endif
-
-#include "../../../Windows/PropVariant.h"
-
-static const UInt32 kUncompressMinBlockSize =
-#ifdef UNDER_CE
-1 << 24;
-#else
-1 << 26;
-#endif
-
-static const UInt32 kCrcBlockSize =
-#ifdef UNDER_CE
-1 << 25;
-#else
-1 << 30;
-#endif
-
-static const UInt32 kAdditionalSize = (1 << 16);
-static const UInt32 kCompressedAdditionalSize = (1 << 10);
-static const UInt32 kMaxLzmaPropSize = 5;
-
-class CBaseRandomGenerator
-{
- UInt32 A1;
- UInt32 A2;
-public:
- CBaseRandomGenerator() { Init(); }
- void Init() { A1 = 362436069; A2 = 521288629;}
- UInt32 GetRnd()
- {
- return
- ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) +
- ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) );
- }
-};
-
-class CBenchBuffer
-{
-public:
- size_t BufferSize;
- Byte *Buffer;
- CBenchBuffer(): Buffer(0) {}
- virtual ~CBenchBuffer() { Free(); }
- void Free()
- {
- ::MidFree(Buffer);
- Buffer = 0;
- }
- bool Alloc(size_t bufferSize)
- {
- if (Buffer != 0 && BufferSize == bufferSize)
- return true;
- Free();
- Buffer = (Byte *)::MidAlloc(bufferSize);
- BufferSize = bufferSize;
- return (Buffer != 0);
- }
-};
-
-class CBenchRandomGenerator: public CBenchBuffer
-{
- CBaseRandomGenerator *RG;
-public:
- void Set(CBaseRandomGenerator *rg) { RG = rg; }
- UInt32 GetVal(UInt32 &res, int numBits)
- {
- UInt32 val = res & (((UInt32)1 << numBits) - 1);
- res >>= numBits;
- return val;
- }
- UInt32 GetLen(UInt32 &res)
- {
- UInt32 len = GetVal(res, 2);
- return GetVal(res, 1 + len);
- }
- void Generate()
- {
- UInt32 pos = 0;
- UInt32 rep0 = 1;
- while (pos < BufferSize)
- {
- UInt32 res = RG->GetRnd();
- res >>= 1;
- if (GetVal(res, 1) == 0 || pos < 1024)
- Buffer[pos++] = (Byte)(res & 0xFF);
- else
- {
- UInt32 len;
- len = 1 + GetLen(res);
- if (GetVal(res, 3) != 0)
- {
- len += GetLen(res);
- do
- {
- UInt32 ppp = GetVal(res, 5) + 6;
- res = RG->GetRnd();
- if (ppp > 30)
- continue;
- rep0 = /* (1 << ppp) +*/ GetVal(res, ppp);
- res = RG->GetRnd();
- }
- while (rep0 >= pos);
- rep0++;
- }
-
- for (UInt32 i = 0; i < len && pos < BufferSize; i++, pos++)
- Buffer[pos] = Buffer[pos - rep0];
- }
- }
- }
-};
-
-
-class CBenchmarkInStream:
- public ISequentialInStream,
- public CMyUnknownImp
-{
- const Byte *Data;
- size_t Pos;
- size_t Size;
-public:
- MY_UNKNOWN_IMP
- void Init(const Byte *data, size_t size)
- {
- Data = data;
- Size = size;
- Pos = 0;
- }
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
-};
-
-STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
-{
- size_t remain = Size - Pos;
- UInt32 kMaxBlockSize = (1 << 20);
- if (size > kMaxBlockSize)
- size = kMaxBlockSize;
- if (size > remain)
- size = (UInt32)remain;
- for (UInt32 i = 0; i < size; i++)
- ((Byte *)data)[i] = Data[Pos + i];
- Pos += size;
- if(processedSize != NULL)
- *processedSize = size;
- return S_OK;
-}
-
-class CBenchmarkOutStream:
- public ISequentialOutStream,
- public CBenchBuffer,
- public CMyUnknownImp
-{
- // bool _overflow;
-public:
- UInt32 Pos;
- // CBenchmarkOutStream(): _overflow(false) {}
- void Init()
- {
- // _overflow = false;
- Pos = 0;
- }
- MY_UNKNOWN_IMP
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
-};
-
-STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
-{
- size_t curSize = BufferSize - Pos;
- if (curSize > size)
- curSize = size;
- memcpy(Buffer + Pos, data, curSize);
- Pos += (UInt32)curSize;
- if(processedSize != NULL)
- *processedSize = (UInt32)curSize;
- if (curSize != size)
- {
- // _overflow = true;
- return E_FAIL;
- }
- return S_OK;
-}
-
-class CCrcOutStream:
- public ISequentialOutStream,
- public CMyUnknownImp
-{
-public:
- UInt32 Crc;
- MY_UNKNOWN_IMP
- void Init() { Crc = CRC_INIT_VAL; }
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
-};
-
-STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
-{
- Crc = CrcUpdate(Crc, data, size);
- if (processedSize != NULL)
- *processedSize = size;
- return S_OK;
-}
-
-static UInt64 GetTimeCount()
-{
- #ifdef USE_POSIX_TIME
- #ifdef USE_POSIX_TIME2
- timeval v;
- if (gettimeofday(&v, 0) == 0)
- return (UInt64)(v.tv_sec) * 1000000 + v.tv_usec;
- return (UInt64)time(NULL) * 1000000;
- #else
- return time(NULL);
- #endif
- #else
- /*
- LARGE_INTEGER value;
- if (::QueryPerformanceCounter(&value))
- return value.QuadPart;
- */
- return GetTickCount();
- #endif
-}
-
-static UInt64 GetFreq()
-{
- #ifdef USE_POSIX_TIME
- #ifdef USE_POSIX_TIME2
- return 1000000;
- #else
- return 1;
- #endif
- #else
- /*
- LARGE_INTEGER value;
- if (::QueryPerformanceFrequency(&value))
- return value.QuadPart;
- */
- return 1000;
- #endif
-}
-
-#ifndef USE_POSIX_TIME
-static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
-#endif
-
-static UInt64 GetUserTime()
-{
- #ifdef USE_POSIX_TIME
- return clock();
- #else
- FILETIME creationTime, exitTime, kernelTime, userTime;
- if (
- #ifdef UNDER_CE
- ::GetThreadTimes(::GetCurrentThread()
- #else
- ::GetProcessTimes(::GetCurrentProcess()
- #endif
- , &creationTime, &exitTime, &kernelTime, &userTime) != 0)
- return GetTime64(userTime) + GetTime64(kernelTime);
- return (UInt64)GetTickCount() * 10000;
- #endif
-}
-
-static UInt64 GetUserFreq()
-{
- #ifdef USE_POSIX_TIME
- return CLOCKS_PER_SEC;
- #else
- return 10000000;
- #endif
-}
-
-class CBenchProgressStatus
-{
- #ifndef _7ZIP_ST
- NWindows::NSynchronization::CCriticalSection CS;
- #endif
-public:
- HRESULT Res;
- bool EncodeMode;
- void SetResult(HRESULT res)
- {
- #ifndef _7ZIP_ST
- NWindows::NSynchronization::CCriticalSectionLock lock(CS);
- #endif
- Res = res;
- }
- HRESULT GetResult()
- {
- #ifndef _7ZIP_ST
- NWindows::NSynchronization::CCriticalSectionLock lock(CS);
- #endif
- return Res;
- }
-};
-
-class CBenchProgressInfo:
- public ICompressProgressInfo,
- public CMyUnknownImp
-{
-public:
- CBenchProgressStatus *Status;
- CBenchInfo BenchInfo;
- HRESULT Res;
- IBenchCallback *callback;
- CBenchProgressInfo(): callback(0) {}
- MY_UNKNOWN_IMP
- STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
-};
-
-static void SetStartTime(CBenchInfo &bi)
-{
- bi.GlobalFreq = GetFreq();
- bi.UserFreq = GetUserFreq();
- bi.GlobalTime = ::GetTimeCount();
- bi.UserTime = ::GetUserTime();
-}
-
-static void SetFinishTime(const CBenchInfo &biStart, CBenchInfo &dest)
-{
- dest.GlobalFreq = GetFreq();
- dest.UserFreq = GetUserFreq();
- dest.GlobalTime = ::GetTimeCount() - biStart.GlobalTime;
- dest.UserTime = ::GetUserTime() - biStart.UserTime;
-}
-
-STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
-{
- HRESULT res = Status->GetResult();
- if (res != S_OK)
- return res;
- if (!callback)
- return res;
- CBenchInfo info = BenchInfo;
- SetFinishTime(BenchInfo, info);
- if (Status->EncodeMode)
- {
- info.UnpackSize = *inSize;
- info.PackSize = *outSize;
- res = callback->SetEncodeResult(info, false);
- }
- else
- {
- info.PackSize = BenchInfo.PackSize + *inSize;
- info.UnpackSize = BenchInfo.UnpackSize + *outSize;
- res = callback->SetDecodeResult(info, false);
- }
- if (res != S_OK)
- Status->SetResult(res);
- return res;
-}
-
-static const int kSubBits = 8;
-
-static UInt32 GetLogSize(UInt32 size)
-{
- for (int i = kSubBits; i < 32; i++)
- for (UInt32 j = 0; j < (1 << kSubBits); j++)
- if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))
- return (i << kSubBits) + j;
- return (32 << kSubBits);
-}
-
-static void NormalizeVals(UInt64 &v1, UInt64 &v2)
-{
- while (v1 > 1000000)
- {
- v1 >>= 1;
- v2 >>= 1;
- }
-}
-
-UInt64 GetUsage(const CBenchInfo &info)
-{
- UInt64 userTime = info.UserTime;
- UInt64 userFreq = info.UserFreq;
- UInt64 globalTime = info.GlobalTime;
- UInt64 globalFreq = info.GlobalFreq;
- NormalizeVals(userTime, userFreq);
- NormalizeVals(globalFreq, globalTime);
- if (userFreq == 0)
- userFreq = 1;
- if (globalTime == 0)
- globalTime = 1;
- return userTime * globalFreq * 1000000 / userFreq / globalTime;
-}
-
-UInt64 GetRatingPerUsage(const CBenchInfo &info, UInt64 rating)
-{
- UInt64 userTime = info.UserTime;
- UInt64 userFreq = info.UserFreq;
- UInt64 globalTime = info.GlobalTime;
- UInt64 globalFreq = info.GlobalFreq;
- NormalizeVals(userFreq, userTime);
- NormalizeVals(globalTime, globalFreq);
- if (globalFreq == 0)
- globalFreq = 1;
- if (userTime == 0)
- userTime = 1;
- return userFreq * globalTime / globalFreq * rating / userTime;
-}
-
-static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
-{
- UInt64 elTime = elapsedTime;
- NormalizeVals(freq, elTime);
- if (elTime == 0)
- elTime = 1;
- return value * freq / elTime;
-}
-
-UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 freq, UInt64 size)
-{
- UInt64 t = GetLogSize(dictionarySize) - (kBenchMinDicLogSize << kSubBits);
- UInt64 numCommandsForOne = 870 + ((t * t * 5) >> (2 * kSubBits));
- UInt64 numCommands = (UInt64)(size) * numCommandsForOne;
- return MyMultDiv64(numCommands, elapsedTime, freq);
-}
-
-UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations)
-{
- UInt64 numCommands = (inSize * 200 + outSize * 4) * numIterations;
- return MyMultDiv64(numCommands, elapsedTime, freq);
-}
-
-struct CEncoderInfo;
-
-struct CEncoderInfo
-{
- #ifndef _7ZIP_ST
- NWindows::CThread thread[2];
- #endif
- CMyComPtr<ICompressCoder> encoder;
- CBenchProgressInfo *progressInfoSpec[2];
- CMyComPtr<ICompressProgressInfo> progressInfo[2];
- UInt32 NumIterations;
- #ifdef USE_ALLOCA
- size_t AllocaSize;
- #endif
-
- struct CDecoderInfo
- {
- CEncoderInfo *Encoder;
- UInt32 DecoderIndex;
- #ifdef USE_ALLOCA
- size_t AllocaSize;
- #endif
- bool CallbackMode;
- };
- CDecoderInfo decodersInfo[2];
-
- CMyComPtr<ICompressCoder> decoders[2];
- HRESULT Results[2];
- CBenchmarkOutStream *outStreamSpec;
- CMyComPtr<ISequentialOutStream> outStream;
- IBenchCallback *callback;
- UInt32 crc;
- UInt32 kBufferSize;
- UInt32 compressedSize;
- CBenchRandomGenerator rg;
- CBenchmarkOutStream *propStreamSpec;
- CMyComPtr<ISequentialOutStream> propStream;
- HRESULT Init(UInt32 dictionarySize, UInt32 numThreads, CBaseRandomGenerator *rg);
- HRESULT Encode();
- HRESULT Decode(UInt32 decoderIndex);
-
- CEncoderInfo(): outStreamSpec(0), callback(0), propStreamSpec(0) {}
-
- #ifndef _7ZIP_ST
- static THREAD_FUNC_DECL EncodeThreadFunction(void *param)
- {
- CEncoderInfo *encoder = (CEncoderInfo *)param;
- #ifdef USE_ALLOCA
- alloca(encoder->AllocaSize);
- #endif
- HRESULT res = encoder->Encode();
- encoder->Results[0] = res;
- if (res != S_OK)
- encoder->progressInfoSpec[0]->Status->SetResult(res);
-
- return 0;
- }
- static THREAD_FUNC_DECL DecodeThreadFunction(void *param)
- {
- CDecoderInfo *decoder = (CDecoderInfo *)param;
- #ifdef USE_ALLOCA
- alloca(decoder->AllocaSize);
- #endif
- CEncoderInfo *encoder = decoder->Encoder;
- encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex);
- return 0;
- }
-
- HRESULT CreateEncoderThread()
- {
- return thread[0].Create(EncodeThreadFunction, this);
- }
-
- HRESULT CreateDecoderThread(int index, bool callbackMode
- #ifdef USE_ALLOCA
- , size_t allocaSize
- #endif
- )
- {
- CDecoderInfo &decoder = decodersInfo[index];
- decoder.DecoderIndex = index;
- decoder.Encoder = this;
- #ifdef USE_ALLOCA
- decoder.AllocaSize = allocaSize;
- #endif
- decoder.CallbackMode = callbackMode;
- return thread[index].Create(DecodeThreadFunction, &decoder);
- }
- #endif
-};
-
-HRESULT CEncoderInfo::Init(UInt32 dictionarySize, UInt32 numThreads, CBaseRandomGenerator *rgLoc)
-{
- rg.Set(rgLoc);
- kBufferSize = dictionarySize + kAdditionalSize;
- UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
- if (!rg.Alloc(kBufferSize))
- return E_OUTOFMEMORY;
- rg.Generate();
- crc = CrcCalc(rg.Buffer, rg.BufferSize);
-
- outStreamSpec = new CBenchmarkOutStream;
- if (!outStreamSpec->Alloc(kCompressedBufferSize))
- return E_OUTOFMEMORY;
-
- outStream = outStreamSpec;
-
- propStreamSpec = 0;
- if (!propStream)
- {
- propStreamSpec = new CBenchmarkOutStream;
- propStream = propStreamSpec;
- }
- if (!propStreamSpec->Alloc(kMaxLzmaPropSize))
- return E_OUTOFMEMORY;
- propStreamSpec->Init();
-
- PROPID propIDs[] =
- {
- NCoderPropID::kDictionarySize,
- NCoderPropID::kNumThreads
- };
- const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
- PROPVARIANT props[kNumProps];
- props[0].vt = VT_UI4;
- props[0].ulVal = dictionarySize;
-
- props[1].vt = VT_UI4;
- props[1].ulVal = numThreads;
-
- {
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
- if (!setCoderProperties)
- return E_FAIL;
- RINOK(setCoderProperties->SetCoderProperties(propIDs, props, kNumProps));
-
- CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
- encoder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);
- if (writeCoderProperties)
- {
- RINOK(writeCoderProperties->WriteCoderProperties(propStream));
- }
- }
- return S_OK;
-}
-
-HRESULT CEncoderInfo::Encode()
-{
- CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
- CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
- inStreamSpec->Init(rg.Buffer, rg.BufferSize);
- outStreamSpec->Init();
-
- RINOK(encoder->Code(inStream, outStream, 0, 0, progressInfo[0]));
- compressedSize = outStreamSpec->Pos;
- encoder.Release();
- return S_OK;
-}
-
-HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
-{
- CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
- CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
- CMyComPtr<ICompressCoder> &decoder = decoders[decoderIndex];
-
- CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;
- decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties);
- if (!compressSetDecoderProperties)
- return E_FAIL;
-
- CCrcOutStream *crcOutStreamSpec = new CCrcOutStream;
- CMyComPtr<ISequentialOutStream> crcOutStream = crcOutStreamSpec;
-
- CBenchProgressInfo *pi = progressInfoSpec[decoderIndex];
- pi->BenchInfo.UnpackSize = 0;
- pi->BenchInfo.PackSize = 0;
-
- for (UInt32 j = 0; j < NumIterations; j++)
- {
- inStreamSpec->Init(outStreamSpec->Buffer, compressedSize);
- crcOutStreamSpec->Init();
-
- RINOK(compressSetDecoderProperties->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos));
- UInt64 outSize = kBufferSize;
- RINOK(decoder->Code(inStream, crcOutStream, 0, &outSize, progressInfo[decoderIndex]));
- if (CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc)
- return S_FALSE;
- pi->BenchInfo.UnpackSize += kBufferSize;
- pi->BenchInfo.PackSize += compressedSize;
- }
- decoder.Release();
- return S_OK;
-}
-
-static const UInt32 kNumThreadsMax = (1 << 16);
-
-struct CBenchEncoders
-{
- CEncoderInfo *encoders;
- CBenchEncoders(UInt32 num): encoders(0) { encoders = new CEncoderInfo[num]; }
- ~CBenchEncoders() { delete []encoders; }
-};
-
-HRESULT LzmaBench(
- DECL_EXTERNAL_CODECS_LOC_VARS
- UInt32 numThreads, UInt32 dictionarySize, IBenchCallback *callback)
-{
- UInt32 numEncoderThreads =
- #ifndef _7ZIP_ST
- (numThreads > 1 ? numThreads / 2 : 1);
- #else
- 1;
- #endif
- UInt32 numSubDecoderThreads =
- #ifndef _7ZIP_ST
- (numThreads > 1 ? 2 : 1);
- #else
- 1;
- #endif
- if (dictionarySize < (1 << kBenchMinDicLogSize) || numThreads < 1 || numEncoderThreads > kNumThreadsMax)
- {
- return E_INVALIDARG;
- }
-
- CBenchEncoders encodersSpec(numEncoderThreads);
- CEncoderInfo *encoders = encodersSpec.encoders;
-
-
- UInt32 i;
- for (i = 0; i < numEncoderThreads; i++)
- {
- CEncoderInfo &encoder = encoders[i];
- encoder.callback = (i == 0) ? callback : 0;
-
- const UInt32 kLzmaId = 0x030101;
- RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS kLzmaId, encoder.encoder, true));
- if (!encoder.encoder)
- return E_NOTIMPL;
- for (UInt32 j = 0; j < numSubDecoderThreads; j++)
- {
- RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS kLzmaId, encoder.decoders[j], false));
- if (!encoder.decoders[j])
- return E_NOTIMPL;
- }
- }
-
- CBaseRandomGenerator rg;
- rg.Init();
- for (i = 0; i < numEncoderThreads; i++)
- {
- RINOK(encoders[i].Init(dictionarySize, numThreads, &rg));
- }
-
- CBenchProgressStatus status;
- status.Res = S_OK;
- status.EncodeMode = true;
-
- for (i = 0; i < numEncoderThreads; i++)
- {
- CEncoderInfo &encoder = encoders[i];
- for (int j = 0; j < 2; j++)
- {
- encoder.progressInfo[j] = encoder.progressInfoSpec[j] = new CBenchProgressInfo;
- encoder.progressInfoSpec[j]->Status = &status;
- }
- if (i == 0)
- {
- encoder.progressInfoSpec[0]->callback = callback;
- encoder.progressInfoSpec[0]->BenchInfo.NumIterations = numEncoderThreads;
- SetStartTime(encoder.progressInfoSpec[0]->BenchInfo);
- }
-
- #ifndef _7ZIP_ST
- if (numEncoderThreads > 1)
- {
- #ifdef USE_ALLOCA
- encoder.AllocaSize = (i * 16 * 21) & 0x7FF;
- #endif
- RINOK(encoder.CreateEncoderThread())
- }
- else
- #endif
- {
- RINOK(encoder.Encode());
- }
- }
- #ifndef _7ZIP_ST
- if (numEncoderThreads > 1)
- for (i = 0; i < numEncoderThreads; i++)
- encoders[i].thread[0].Wait();
- #endif
-
- RINOK(status.Res);
-
- CBenchInfo info;
-
- SetFinishTime(encoders[0].progressInfoSpec[0]->BenchInfo, info);
- info.UnpackSize = 0;
- info.PackSize = 0;
- info.NumIterations = 1; // progressInfoSpec->NumIterations;
- for (i = 0; i < numEncoderThreads; i++)
- {
- CEncoderInfo &encoder = encoders[i];
- info.UnpackSize += encoder.kBufferSize;
- info.PackSize += encoder.compressedSize;
- }
- RINOK(callback->SetEncodeResult(info, true));
-
-
- status.Res = S_OK;
- status.EncodeMode = false;
-
- UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads;
- for (i = 0; i < numEncoderThreads; i++)
- {
- CEncoderInfo &encoder = encoders[i];
- encoder.NumIterations = 2 + kUncompressMinBlockSize / encoder.kBufferSize;
-
- if (i == 0)
- {
- encoder.progressInfoSpec[0]->callback = callback;
- encoder.progressInfoSpec[0]->BenchInfo.NumIterations = numDecoderThreads;
- SetStartTime(encoder.progressInfoSpec[0]->BenchInfo);
- }
-
- #ifndef _7ZIP_ST
- if (numDecoderThreads > 1)
- {
- for (UInt32 j = 0; j < numSubDecoderThreads; j++)
- {
- HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0)
- #ifdef USE_ALLOCA
- , ((i * numSubDecoderThreads + j) * 16 * 21) & 0x7FF
- #endif
- );
- RINOK(res);
- }
- }
- else
- #endif
- {
- RINOK(encoder.Decode(0));
- }
- }
- #ifndef _7ZIP_ST
- HRESULT res = S_OK;
- if (numDecoderThreads > 1)
- for (i = 0; i < numEncoderThreads; i++)
- for (UInt32 j = 0; j < numSubDecoderThreads; j++)
- {
- CEncoderInfo &encoder = encoders[i];
- encoder.thread[j].Wait();
- if (encoder.Results[j] != S_OK)
- res = encoder.Results[j];
- }
- RINOK(res);
- #endif
- RINOK(status.Res);
- SetFinishTime(encoders[0].progressInfoSpec[0]->BenchInfo, info);
- #ifndef _7ZIP_ST
- #ifdef UNDER_CE
- if (numDecoderThreads > 1)
- for (i = 0; i < numEncoderThreads; i++)
- for (UInt32 j = 0; j < numSubDecoderThreads; j++)
- {
- FILETIME creationTime, exitTime, kernelTime, userTime;
- if (::GetThreadTimes(encoders[i].thread[j], &creationTime, &exitTime, &kernelTime, &userTime) != 0)
- info.UserTime += GetTime64(userTime) + GetTime64(kernelTime);
- }
- #endif
- #endif
- info.UnpackSize = 0;
- info.PackSize = 0;
- info.NumIterations = numSubDecoderThreads * encoders[0].NumIterations;
- for (i = 0; i < numEncoderThreads; i++)
- {
- CEncoderInfo &encoder = encoders[i];
- info.UnpackSize += encoder.kBufferSize;
- info.PackSize += encoder.compressedSize;
- }
- RINOK(callback->SetDecodeResult(info, false));
- RINOK(callback->SetDecodeResult(info, true));
- return S_OK;
-}
-
-
-inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary)
-{
- UInt32 hs = dictionary - 1;
- hs |= (hs >> 1);
- hs |= (hs >> 2);
- hs |= (hs >> 4);
- hs |= (hs >> 8);
- hs >>= 1;
- hs |= 0xFFFF;
- if (hs > (1 << 24))
- hs >>= 1;
- hs++;
- return ((hs + (1 << 16)) + (UInt64)dictionary * 2) * 4 + (UInt64)dictionary * 3 / 2 +
- (1 << 20) + (multiThread ? (6 << 20) : 0);
-}
-
-UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary)
-{
- const UInt32 kBufferSize = dictionary;
- const UInt32 kCompressedBufferSize = (kBufferSize / 2);
- UInt32 numSubThreads = (numThreads > 1) ? 2 : 1;
- UInt32 numBigThreads = numThreads / numSubThreads;
- return (kBufferSize + kCompressedBufferSize +
- GetLZMAUsage((numThreads > 1), dictionary) + (2 << 20)) * numBigThreads;
-}
-
-static bool CrcBig(const void *data, UInt32 size, UInt32 numCycles, UInt32 crcBase)
-{
- for (UInt32 i = 0; i < numCycles; i++)
- if (CrcCalc(data, size) != crcBase)
- return false;
- return true;
-}
-
-#ifndef _7ZIP_ST
-struct CCrcInfo
-{
- NWindows::CThread Thread;
- const Byte *Data;
- UInt32 Size;
- UInt32 NumCycles;
- UInt32 Crc;
- bool Res;
- void Wait()
- {
- Thread.Wait();
- Thread.Close();
- }
-};
-
-static THREAD_FUNC_DECL CrcThreadFunction(void *param)
-{
- CCrcInfo *p = (CCrcInfo *)param;
- p->Res = CrcBig(p->Data, p->Size, p->NumCycles, p->Crc);
- return 0;
-}
-
-struct CCrcThreads
-{
- UInt32 NumThreads;
- CCrcInfo *Items;
- CCrcThreads(): Items(0), NumThreads(0) {}
- void WaitAll()
- {
- for (UInt32 i = 0; i < NumThreads; i++)
- Items[i].Wait();
- NumThreads = 0;
- }
- ~CCrcThreads()
- {
- WaitAll();
- delete []Items;
- }
-};
-#endif
-
-static UInt32 CrcCalc1(const Byte *buf, UInt32 size)
-{
- UInt32 crc = CRC_INIT_VAL;;
- for (UInt32 i = 0; i < size; i++)
- crc = CRC_UPDATE_BYTE(crc, buf[i]);
- return CRC_GET_DIGEST(crc);
-}
-
-static void RandGen(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
-{
- for (UInt32 i = 0; i < size; i++)
- buf[i] = (Byte)RG.GetRnd();
-}
-
-static UInt32 RandGenCrc(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
-{
- RandGen(buf, size, RG);
- return CrcCalc1(buf, size);
-}
-
-bool CrcInternalTest()
-{
- CBenchBuffer buffer;
- const UInt32 kBufferSize0 = (1 << 8);
- const UInt32 kBufferSize1 = (1 << 10);
- const UInt32 kCheckSize = (1 << 5);
- if (!buffer.Alloc(kBufferSize0 + kBufferSize1))
- return false;
- Byte *buf = buffer.Buffer;
- UInt32 i;
- for (i = 0; i < kBufferSize0; i++)
- buf[i] = (Byte)i;
- UInt32 crc1 = CrcCalc1(buf, kBufferSize0);
- if (crc1 != 0x29058C73)
- return false;
- CBaseRandomGenerator RG;
- RandGen(buf + kBufferSize0, kBufferSize1, RG);
- for (i = 0; i < kBufferSize0 + kBufferSize1 - kCheckSize; i++)
- for (UInt32 j = 0; j < kCheckSize; j++)
- if (CrcCalc1(buf + i, j) != CrcCalc(buf + i, j))
- return false;
- return true;
-}
-
-HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed)
-{
- if (numThreads == 0)
- numThreads = 1;
-
- CBenchBuffer buffer;
- size_t totalSize = (size_t)bufferSize * numThreads;
- if (totalSize / numThreads != bufferSize)
- return E_OUTOFMEMORY;
- if (!buffer.Alloc(totalSize))
- return E_OUTOFMEMORY;
-
- Byte *buf = buffer.Buffer;
- CBaseRandomGenerator RG;
- UInt32 numCycles = (kCrcBlockSize) / ((bufferSize >> 2) + 1) + 1;
-
- UInt64 timeVal;
- #ifndef _7ZIP_ST
- CCrcThreads threads;
- if (numThreads > 1)
- {
- threads.Items = new CCrcInfo[numThreads];
- UInt32 i;
- for (i = 0; i < numThreads; i++)
- {
- CCrcInfo &info = threads.Items[i];
- Byte *data = buf + (size_t)bufferSize * i;
- info.Data = data;
- info.NumCycles = numCycles;
- info.Size = bufferSize;
- info.Crc = RandGenCrc(data, bufferSize, RG);
- }
- timeVal = GetTimeCount();
- for (i = 0; i < numThreads; i++)
- {
- CCrcInfo &info = threads.Items[i];
- RINOK(info.Thread.Create(CrcThreadFunction, &info));
- threads.NumThreads++;
- }
- threads.WaitAll();
- for (i = 0; i < numThreads; i++)
- if (!threads.Items[i].Res)
- return S_FALSE;
- }
- else
- #endif
- {
- UInt32 crc = RandGenCrc(buf, bufferSize, RG);
- timeVal = GetTimeCount();
- if (!CrcBig(buf, bufferSize, numCycles, crc))
- return S_FALSE;
- }
- timeVal = GetTimeCount() - timeVal;
- if (timeVal == 0)
- timeVal = 1;
-
- UInt64 size = (UInt64)numCycles * totalSize;
- speed = MyMultDiv64(size, timeVal, GetFreq());
- return S_OK;
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/Bench.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/Bench.h
deleted file mode 100644
index a8d02a19b..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/Bench.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Bench.h
-
-#ifndef __7ZIP_BENCH_H
-#define __7ZIP_BENCH_H
-
-#include "../../Common/CreateCoder.h"
-
-struct CBenchInfo
-{
- UInt64 GlobalTime;
- UInt64 GlobalFreq;
- UInt64 UserTime;
- UInt64 UserFreq;
- UInt64 UnpackSize;
- UInt64 PackSize;
- UInt32 NumIterations;
- CBenchInfo(): NumIterations(0) {}
-};
-
-struct IBenchCallback
-{
- virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0;
- virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0;
-};
-
-UInt64 GetUsage(const CBenchInfo &benchOnfo);
-UInt64 GetRatingPerUsage(const CBenchInfo &info, UInt64 rating);
-UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
-UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations);
-
-HRESULT LzmaBench(
- DECL_EXTERNAL_CODECS_LOC_VARS
- UInt32 numThreads, UInt32 dictionarySize, IBenchCallback *callback);
-
-const int kBenchMinDicLogSize = 18;
-
-UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary);
-
-bool CrcInternalTest();
-HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed);
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/Common.pri b/src/libs/7zip/unix/CPP/7zip/UI/Common/Common.pri
new file mode 100644
index 000000000..a1d75b674
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/Common.pri
@@ -0,0 +1,43 @@
+HEADERS += $$7ZIP_BASE/CPP/7zip/UI/Common/ArchiveOpenCallback.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/ArchiveExtractCallback.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/ArchiveCommandLine.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/DefaultName.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/DirItem.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/EnumDirItems.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/Extract.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/ExtractMode.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/ExtractingFilePath.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/HashCalc.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/IFileExtractCallback.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/LoadCodecs.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/OpenArchive.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/Property.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/PropIDUtils.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/SetProperties.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/SortUtils.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/TempFiles.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/Update.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/UpdateAction.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/UpdateCallback.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/UpdatePair.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/UpdateProduce.h
+
+SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/ArchiveCommandLine.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/DefaultName.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/EnumDirItems.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/Extract.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/ExtractingFilePath.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/HashCalc.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/LoadCodecs.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/OpenArchive.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/PropIDUtils.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/SetProperties.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/SortUtils.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/TempFiles.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/Update.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/UpdateAction.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/UpdateCallback.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/UpdatePair.cpp \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/UpdateProduce.cpp
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/DefaultName.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/DefaultName.cpp
index 4335e2731..ce0b327b5 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/DefaultName.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/DefaultName.cpp
@@ -7,13 +7,13 @@
static UString GetDefaultName3(const UString &fileName,
const UString &extension, const UString &addSubExtension)
{
- int extLength = extension.Length();
- int fileNameLength = fileName.Length();
+ int extLength = extension.Len();
+ int fileNameLength = fileName.Len();
if (fileNameLength > extLength + 1)
{
int dotPos = fileNameLength - (extLength + 1);
if (fileName[dotPos] == '.')
- if (extension.CompareNoCase(fileName.Mid(dotPos + 1)) == 0)
+ if (extension.IsEqualToNoCase(fileName.Ptr(dotPos + 1)))
return fileName.Left(dotPos) + addSubExtension;
}
int dotPos = fileName.ReverseFind(L'.');
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/DefaultName.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/DefaultName.h
index 9764ff871..df1645602 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/DefaultName.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/DefaultName.h
@@ -1,9 +1,9 @@
// DefaultName.h
-#ifndef __DEFAULTNAME_H
-#define __DEFAULTNAME_H
+#ifndef __DEFAULT_NAME_H
+#define __DEFAULT_NAME_H
-#include "Common/MyString.h"
+#include "../../../Common/MyString.h"
UString GetDefaultName2(const UString &fileName,
const UString &extension, const UString &addSubExtension);
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/DirItem.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/DirItem.h
index 29cc60d93..82203c03a 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/DirItem.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/DirItem.h
@@ -3,8 +3,12 @@
#ifndef __DIR_ITEM_H
#define __DIR_ITEM_H
-#include "Common/MyString.h"
-#include "Common/Types.h"
+#include "../../../Common/MyString.h"
+
+#include "../../../Windows/FileFind.h"
+
+#include "../../Common/UniqBlocks.h"
+
#include "../../Archive/IArchive.h"
struct CDirItem
@@ -14,11 +18,23 @@ struct CDirItem
FILETIME ATime;
FILETIME MTime;
UString Name;
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // UString ShortName;
+ CByteBuffer ReparseData;
+ CByteBuffer ReparseData2; // fixed (reduced) absolute links
+
+ bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; }
+ #endif
+
UInt32 Attrib;
int PhyParent;
int LogParent;
-
- CDirItem(): PhyParent(-1), LogParent(-1) {}
+ int SecureIndex;
+
+ bool IsAltStream;
+
+ CDirItem(): PhyParent(-1), LogParent(-1), SecureIndex(-1), IsAltStream(false) {}
bool IsDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
};
@@ -29,24 +45,64 @@ class CDirItems
CIntVector LogParents;
UString GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const;
+
+ void EnumerateDir(int phyParent, int logParent, const FString &phyPrefix);
+
public:
CObjectVector<CDirItem> Items;
- int GetNumFolders() const { return Prefixes.Size(); }
- UString GetPhyPath(int index) const;
- UString GetLogPath(int index) const;
+ bool SymLinks;
+
+ bool ScanAltStreams;
+ FStringVector ErrorPaths;
+ CRecordVector<DWORD> ErrorCodes;
+ UInt64 TotalSize;
- int AddPrefix(int phyParent, int logParent, const UString &prefix);
- void DeleteLastPrefix();
- void EnumerateDirectory(int phyParent, int logParent, const UString &phyPrefix,
- UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes);
+ #ifndef UNDER_CE
+ void SetLinkInfo(CDirItem &dirItem, const NWindows::NFile::NFind::CFileInfo &fi,
+ const FString &phyPrefix);
+ #endif
- void EnumerateDirItems2(
- const UString &phyPrefix,
+ void AddError(const FString &path, DWORD errorCode)
+ {
+ ErrorCodes.Add(errorCode);
+ ErrorPaths.Add(path);
+ }
+
+ void AddError(const FString &path)
+ {
+ AddError(path, ::GetLastError());
+ }
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+
+ CUniqBlocks SecureBlocks;
+ CByteBuffer TempSecureBuf;
+ bool _saclEnabled;
+ bool ReadSecure;
+
+ void AddSecurityItem(const FString &path, int &secureIndex);
+
+ #endif
+
+ CDirItems();
+
+ int GetNumFolders() const { return Prefixes.Size(); }
+ UString GetPhyPath(unsigned index) const;
+ UString GetLogPath(unsigned index) const;
+
+ unsigned AddPrefix(int phyParent, int logParent, const UString &prefix);
+ void DeleteLastPrefix();
+ void EnumerateItems2(
+ const FString &phyPrefix,
const UString &logPrefix,
- const UStringVector &filePaths,
- UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes);
+ const FStringVector &filePaths,
+ FStringVector *requestedPaths);
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ void FillFixedReparse();
+ #endif
void ReserveDown();
};
@@ -57,13 +113,14 @@ struct CArcItem
FILETIME MTime;
UString Name;
bool IsDir;
+ bool IsAltStream;
bool SizeDefined;
bool MTimeDefined;
bool Censored;
UInt32 IndexInServer;
int TimeType;
-
- CArcItem(): IsDir(false), SizeDefined(false), MTimeDefined(false), Censored(false), TimeType(-1) {}
+
+ CArcItem(): IsDir(false), IsAltStream(false), SizeDefined(false), MTimeDefined(false), Censored(false), TimeType(-1) {}
};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/EnumDirItems.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/EnumDirItems.cpp
index ba03ea35c..b94e6274c 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/EnumDirItems.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/EnumDirItems.cpp
@@ -2,14 +2,25 @@
#include "StdAfx.h"
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileIO.h"
+#include "../../../Windows/FileName.h"
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+#define _USE_SECURITY_CODE
+#include "../../../Windows/SecurityUtils.h"
+#endif
+
#include "EnumDirItems.h"
using namespace NWindows;
using namespace NFile;
using namespace NName;
-void AddDirFileInfo(int phyParent, int logParent,
- const NFind::CFileInfoW &fi, CObjectVector<CDirItem> &dirItems)
+void AddDirFileInfo(int phyParent, int logParent, int secureIndex,
+ const NFind::CFileInfo &fi, CObjectVector<CDirItem> &dirItems)
{
CDirItem di;
di.Size = fi.Size;
@@ -17,41 +28,46 @@ void AddDirFileInfo(int phyParent, int logParent,
di.ATime = fi.ATime;
di.MTime = fi.MTime;
di.Attrib = fi.Attrib;
+ // FIXME di.IsAltStream = fi.IsAltStream;
di.PhyParent = phyParent;
di.LogParent = logParent;
- di.Name = fi.Name;
+ di.SecureIndex = secureIndex;
+ di.Name = fs2us(fi.Name);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // di.ShortName = fs2us(fi.ShortName);
+ #endif
dirItems.Add(di);
}
UString CDirItems::GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const
{
UString path;
- int len = name.Length();
+ unsigned len = name.Len();
int i;
for (i = index; i >= 0; i = parents[i])
- len += Prefixes[i].Length();
- int totalLen = len;
+ len += Prefixes[i].Len();
+ unsigned totalLen = len;
wchar_t *p = path.GetBuffer(len);
p[len] = 0;
- len -= name.Length();
- memcpy(p + len, (const wchar_t *)name, name.Length() * sizeof(wchar_t));
+ len -= name.Len();
+ memcpy(p + len, (const wchar_t *)name, name.Len() * sizeof(wchar_t));
for (i = index; i >= 0; i = parents[i])
{
const UString &s = Prefixes[i];
- len -= s.Length();
- memcpy(p + len, (const wchar_t *)s, s.Length() * sizeof(wchar_t));
+ len -= s.Len();
+ memcpy(p + len, (const wchar_t *)s, s.Len() * sizeof(wchar_t));
}
path.ReleaseBuffer(totalLen);
return path;
}
-UString CDirItems::GetPhyPath(int index) const
+UString CDirItems::GetPhyPath(unsigned index) const
{
const CDirItem &di = Items[index];
return GetPrefixesPath(PhyParents, di.PhyParent, di.Name);
}
-UString CDirItems::GetLogPath(int index) const
+UString CDirItems::GetLogPath(unsigned index) const
{
const CDirItem &di = Items[index];
return GetPrefixesPath(LogParents, di.LogParent, di.Name);
@@ -65,7 +81,7 @@ void CDirItems::ReserveDown()
Items.ReserveDown();
}
-int CDirItems::AddPrefix(int phyParent, int logParent, const UString &prefix)
+unsigned CDirItems::AddPrefix(int phyParent, int logParent, const UString &prefix)
{
PhyParents.Add(phyParent);
LogParents.Add(logParent);
@@ -79,162 +95,440 @@ void CDirItems::DeleteLastPrefix()
Prefixes.DeleteBack();
}
-void CDirItems::EnumerateDirectory(int phyParent, int logParent, const UString &phyPrefix,
- UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)
+bool InitLocalPrivileges();
+
+CDirItems::CDirItems():
+ SymLinks(false),
+ TotalSize(0)
+ #ifdef _USE_SECURITY_CODE
+ , ReadSecure(false)
+ #endif
+{
+ #ifdef _USE_SECURITY_CODE
+ _saclEnabled = InitLocalPrivileges();
+ #endif
+}
+
+#ifdef _USE_SECURITY_CODE
+
+void CDirItems::AddSecurityItem(const FString &path, int &secureIndex)
+{
+ secureIndex = -1;
+
+ SECURITY_INFORMATION securInfo =
+ DACL_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ OWNER_SECURITY_INFORMATION;
+ if (_saclEnabled)
+ securInfo |= SACL_SECURITY_INFORMATION;
+
+ DWORD errorCode = 0;
+ DWORD secureSize;
+ BOOL res = ::GetFileSecurityW(fs2us(path), securInfo, TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize);
+ if (res)
+ {
+ if (secureSize == 0)
+ return;
+ if (secureSize > TempSecureBuf.Size())
+ errorCode = ERROR_INVALID_FUNCTION;
+ }
+ else
+ {
+ errorCode = GetLastError();
+ if (errorCode == ERROR_INSUFFICIENT_BUFFER)
+ {
+ if (secureSize <= TempSecureBuf.Size())
+ errorCode = ERROR_INVALID_FUNCTION;
+ else
+ {
+ TempSecureBuf.Alloc(secureSize);
+ res = ::GetFileSecurityW(fs2us(path), securInfo, TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize);
+ if (res)
+ {
+ if (secureSize != TempSecureBuf.Size())
+ errorCode = ERROR_INVALID_FUNCTION;;
+ }
+ else
+ errorCode = GetLastError();
+ }
+ }
+ }
+ if (res)
+ {
+ secureIndex = SecureBlocks.AddUniq(TempSecureBuf, secureSize);
+ return;
+ }
+ if (errorCode == 0)
+ errorCode = ERROR_INVALID_FUNCTION;
+ AddError(path, errorCode);
+}
+
+#endif
+
+void CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phyPrefix)
{
- NFind::CEnumeratorW enumerator(phyPrefix + (wchar_t)kAnyStringWildcard);
+ NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
for (;;)
{
- NFind::CFileInfoW fi;
+ NFind::CFileInfo fi;
bool found;
if (!enumerator.Next(fi, found))
{
- errorCodes.Add(::GetLastError());
- errorPaths.Add(phyPrefix);
+ AddError(phyPrefix);
return;
}
if (!found)
break;
- AddDirFileInfo(phyParent, logParent, fi, Items);
+
+ int secureIndex = -1;
+ #ifdef _USE_SECURITY_CODE
+ if (ReadSecure)
+ AddSecurityItem(phyPrefix + fi.Name, secureIndex);
+ #endif
+
+ AddDirFileInfo(phyParent, logParent, secureIndex, fi, Items);
+
if (fi.IsDir())
{
- const UString name2 = fi.Name + (wchar_t)kDirDelimiter;
- int parent = AddPrefix(phyParent, logParent, name2);
- EnumerateDirectory(parent, parent, phyPrefix + name2, errorPaths, errorCodes);
+ const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR;
+ unsigned parent = AddPrefix(phyParent, logParent, fs2us(name2));
+ EnumerateDir(parent, parent, phyPrefix + name2);
}
}
}
-void CDirItems::EnumerateDirItems2(const UString &phyPrefix, const UString &logPrefix,
- const UStringVector &filePaths, UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)
+void CDirItems::EnumerateItems2(
+ const FString &phyPrefix,
+ const UString &logPrefix,
+ const FStringVector &filePaths,
+ FStringVector *requestedPaths)
{
- int phyParent = phyPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, phyPrefix);
+ int phyParent = phyPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, fs2us(phyPrefix));
int logParent = logPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, logPrefix);
- for (int i = 0; i < filePaths.Size(); i++)
+ FOR_VECTOR (i, filePaths)
{
- const UString &filePath = filePaths[i];
- NFind::CFileInfoW fi;
- const UString phyPath = phyPrefix + filePath;
+ const FString &filePath = filePaths[i];
+ NFind::CFileInfo fi;
+ const FString phyPath = phyPrefix + filePath;
if (!fi.Find(phyPath))
{
- errorCodes.Add(::GetLastError());
- errorPaths.Add(phyPath);
+ AddError(phyPath);
continue;
}
- int delimiter = filePath.ReverseFind((wchar_t)kDirDelimiter);
- UString phyPrefixCur;
+ if (requestedPaths)
+ requestedPaths->Add(phyPath);
+
+ int delimiter = filePath.ReverseFind(FCHAR_PATH_SEPARATOR);
+ FString phyPrefixCur;
int phyParentCur = phyParent;
if (delimiter >= 0)
{
- phyPrefixCur = filePath.Left(delimiter + 1);
- phyParentCur = AddPrefix(phyParent, logParent, phyPrefixCur);
+ phyPrefixCur.SetFrom(filePath, delimiter + 1);
+ phyParentCur = AddPrefix(phyParent, logParent, fs2us(phyPrefixCur));
}
- AddDirFileInfo(phyParentCur, logParent, fi, Items);
+
+ int secureIndex = -1;
+ #ifdef _USE_SECURITY_CODE
+ if (ReadSecure)
+ AddSecurityItem(phyPath, secureIndex);
+ #endif
+
+ AddDirFileInfo(phyParentCur, logParent, secureIndex, fi, Items);
+
if (fi.IsDir())
{
- const UString name2 = fi.Name + (wchar_t)kDirDelimiter;
- int parent = AddPrefix(phyParentCur, logParent, name2);
- EnumerateDirectory(parent, parent, phyPrefix + phyPrefixCur + name2, errorPaths, errorCodes);
+ const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR;
+ unsigned parent = AddPrefix(phyParentCur, logParent, fs2us(name2));
+ EnumerateDir(parent, parent, phyPrefix + phyPrefixCur + name2);
}
}
ReserveDown();
}
-static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
- int phyParent, int logParent, const UString &phyPrefix,
+
+
+
+
+
+static HRESULT EnumerateDirItems(
+ const NWildcard::CCensorNode &curNode,
+ int phyParent, int logParent, const FString &phyPrefix,
const UStringVector &addArchivePrefix,
CDirItems &dirItems,
bool enterToSubFolders,
- IEnumDirItemCallback *callback,
- UStringVector &errorPaths,
- CRecordVector<DWORD> &errorCodes);
+ IEnumDirItemCallback *callback);
-static HRESULT EnumerateDirItems_Spec(const NWildcard::CCensorNode &curNode,
- int phyParent, int logParent, const UString &curFolderName,
- const UString &phyPrefix,
+static HRESULT EnumerateDirItems_Spec(
+ const NWildcard::CCensorNode &curNode,
+ int phyParent, int logParent, const FString &curFolderName,
+ const FString &phyPrefix,
const UStringVector &addArchivePrefix,
CDirItems &dirItems,
bool enterToSubFolders,
- IEnumDirItemCallback *callback,
- UStringVector &errorPaths,
- CRecordVector<DWORD> &errorCodes)
-
+ IEnumDirItemCallback *callback)
{
- const UString name2 = curFolderName + (wchar_t)kDirDelimiter;
- int parent = dirItems.AddPrefix(phyParent, logParent, name2);
- int numItems = dirItems.Items.Size();
- HRESULT res = EnumerateDirItems(curNode, parent, parent, phyPrefix + name2,
- addArchivePrefix, dirItems, enterToSubFolders, callback, errorPaths, errorCodes);
+ const FString name2 = curFolderName + FCHAR_PATH_SEPARATOR;
+ unsigned parent = dirItems.AddPrefix(phyParent, logParent, fs2us(name2));
+ unsigned numItems = dirItems.Items.Size();
+ HRESULT res = EnumerateDirItems(
+ curNode, parent, parent, phyPrefix + name2,
+ addArchivePrefix, dirItems, enterToSubFolders, callback);
if (numItems == dirItems.Items.Size())
dirItems.DeleteLastPrefix();
return res;
}
+#if 0 // #ifndef UNDER_CE
-static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
- int phyParent, int logParent, const UString &phyPrefix,
+static void EnumerateAltStreams(
+ const NFind::CFileInfo &fi,
+ const NWildcard::CCensorNode &curNode,
+ int phyParent, int logParent, const FString &phyPrefix,
+ const UStringVector &addArchivePrefix, // prefix from curNode
+ CDirItems &dirItems)
+{
+ const FString fullPath = phyPrefix + fi.Name;
+ NFind::CStreamEnumerator enumerator(fullPath);
+ for (;;)
+ {
+ NFind::CStreamInfo si;
+ bool found;
+ if (!enumerator.Next(si, found))
+ {
+ dirItems.AddError(fullPath + FTEXT(":*"), (DWORD)E_FAIL);
+ break;
+ }
+ if (!found)
+ break;
+ if (si.IsMainStream())
+ continue;
+ UStringVector addArchivePrefixNew = addArchivePrefix;
+ UString reducedName = si.GetReducedName();
+ addArchivePrefixNew.Back() += reducedName;
+ if (curNode.CheckPathToRoot(false, addArchivePrefixNew, true))
+ continue;
+ NFind::CFileInfo fi2 = fi;
+ fi2.Name += us2fs(reducedName);
+ fi2.Size = si.Size;
+ fi2.Attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
+ fi2.IsAltStream = true;
+ AddDirFileInfo(phyParent, logParent, -1, fi2, dirItems.Items);
+ dirItems.TotalSize += fi2.Size;
+ }
+}
+
+void CDirItems::SetLinkInfo(CDirItem &dirItem, const NFind::CFileInfo &fi,
+ const FString &phyPrefix)
+{
+ if (!SymLinks || !fi.HasReparsePoint())
+ return;
+ const FString path = phyPrefix + fi.Name;
+ CByteBuffer &buf = dirItem.ReparseData;
+ if (NIO::GetReparseData(path, buf))
+ {
+ CReparseAttr attr;
+ if (attr.Parse(buf, buf.Size()))
+ return;
+ }
+ AddError(path);
+ buf.Free();
+}
+
+#endif
+
+static HRESULT EnumerateForItem(
+ NFind::CFileInfo &fi,
+ const NWildcard::CCensorNode &curNode,
+ int phyParent, int logParent, const FString &phyPrefix,
const UStringVector &addArchivePrefix, // prefix from curNode
CDirItems &dirItems,
bool enterToSubFolders,
- IEnumDirItemCallback *callback,
- UStringVector &errorPaths,
- CRecordVector<DWORD> &errorCodes)
+ IEnumDirItemCallback *callback)
+{
+ const UString name = fs2us(fi.Name);
+ bool enterToSubFolders2 = enterToSubFolders;
+ UStringVector addArchivePrefixNew = addArchivePrefix;
+ addArchivePrefixNew.Add(name);
+ {
+ UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);
+ if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fi.IsDir()))
+ return S_OK;
+ }
+ int dirItemIndex = -1;
+
+ if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fi.IsDir()))
+ {
+ int secureIndex = -1;
+ #ifdef _USE_SECURITY_CODE
+ if (dirItems.ReadSecure)
+ dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex);
+ #endif
+
+ dirItemIndex = dirItems.Items.Size();
+ AddDirFileInfo(phyParent, logParent, secureIndex, fi, dirItems.Items);
+ dirItems.TotalSize += fi.Size;
+ if (fi.IsDir())
+ enterToSubFolders2 = true;
+ }
+
+ #if 0 // #ifndef UNDER_CE
+ if (dirItems.ScanAltStreams)
+ {
+ EnumerateAltStreams(fi, curNode, phyParent, logParent, phyPrefix,
+ addArchivePrefixNew, dirItems);
+ }
+
+ if (dirItemIndex >= 0)
+ {
+ CDirItem &dirItem = dirItems.Items[dirItemIndex];
+ dirItems.SetLinkInfo(dirItem, fi, phyPrefix);
+ if (dirItem.ReparseData.Size() != 0)
+ return S_OK;
+ }
+ #endif
+
+ if (!fi.IsDir())
+ return S_OK;
+
+ const NWildcard::CCensorNode *nextNode = 0;
+ if (addArchivePrefix.IsEmpty())
+ {
+ int index = curNode.FindSubNode(name);
+ if (index >= 0)
+ nextNode = &curNode.SubNodes[index];
+ }
+ if (!enterToSubFolders2 && nextNode == 0)
+ return S_OK;
+
+ addArchivePrefixNew = addArchivePrefix;
+ if (nextNode == 0)
+ {
+ nextNode = &curNode;
+ addArchivePrefixNew.Add(name);
+ }
+
+ return EnumerateDirItems_Spec(
+ *nextNode, phyParent, logParent, fi.Name, phyPrefix,
+ addArchivePrefixNew,
+ dirItems,
+ enterToSubFolders2, callback);
+}
+
+
+static bool CanUseFsDirect(const NWildcard::CCensorNode &curNode)
+{
+ FOR_VECTOR (i, curNode.IncludeItems)
+ {
+ const NWildcard::CItem &item = curNode.IncludeItems[i];
+ if (item.Recursive || item.PathParts.Size() != 1)
+ return false;
+ const UString &name = item.PathParts.Front();
+ if (name.IsEmpty())
+ return false;
+
+ /* Windows doesn't support file name with wildcard.
+ but if another system supports file name with wildcard,
+ and wildcard mode is disabled, we can ignore wildcard in name */
+ /*
+ if (!item.WildcardParsing)
+ continue;
+ */
+ if (DoesNameContainWildcard(name))
+ return false;
+ }
+ return true;
+}
+
+
+static HRESULT EnumerateDirItems(
+ const NWildcard::CCensorNode &curNode,
+ int phyParent, int logParent, const FString &phyPrefix,
+ const UStringVector &addArchivePrefix, // prefix from curNode
+ CDirItems &dirItems,
+ bool enterToSubFolders,
+ IEnumDirItemCallback *callback)
{
if (!enterToSubFolders)
if (curNode.NeedCheckSubDirs())
enterToSubFolders = true;
if (callback)
- RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), phyPrefix));
+ RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), dirItems.TotalSize, fs2us(phyPrefix), true));
// try direct_names case at first
if (addArchivePrefix.IsEmpty() && !enterToSubFolders)
{
- // check that all names are direct
- int i;
- for (i = 0; i < curNode.IncludeItems.Size(); i++)
- {
- const NWildcard::CItem &item = curNode.IncludeItems[i];
- if (item.Recursive || item.PathParts.Size() != 1)
- break;
- const UString &name = item.PathParts.Front();
- if (name.IsEmpty() || DoesNameContainWildCard(name))
- break;
- }
- if (i == curNode.IncludeItems.Size())
+ if (CanUseFsDirect(curNode))
{
// all names are direct (no wildcards)
// so we don't need file_system's dir enumerator
CRecordVector<bool> needEnterVector;
+ unsigned i;
+
for (i = 0; i < curNode.IncludeItems.Size(); i++)
{
const NWildcard::CItem &item = curNode.IncludeItems[i];
const UString &name = item.PathParts.Front();
- const UString fullPath = phyPrefix + name;
- NFind::CFileInfoW fi;
+ const FString fullPath = phyPrefix + us2fs(name);
+ NFind::CFileInfo fi;
+ #ifdef _WIN32
+ if (phyPrefix.IsEmpty() && item.IsDriveItem())
+ {
+ fi.SetAsDir();
+ fi.Name = fullPath;
+ }
+ else
+ #endif
if (!fi.Find(fullPath))
{
- errorCodes.Add(::GetLastError());
- errorPaths.Add(fullPath);
+ dirItems.AddError(fullPath);
continue;
}
bool isDir = fi.IsDir();
if (isDir && !item.ForDir || !isDir && !item.ForFile)
{
- errorCodes.Add((DWORD)E_FAIL);
- errorPaths.Add(fullPath);
+ dirItems.AddError(fullPath, (DWORD)E_FAIL);
continue;
}
{
UStringVector pathParts;
- pathParts.Add(fi.Name);
+ pathParts.Add(fs2us(fi.Name));
if (curNode.CheckPathToRoot(false, pathParts, !isDir))
continue;
}
- AddDirFileInfo(phyParent, logParent, fi, dirItems.Items);
+
+ int secureIndex = -1;
+ #ifdef _USE_SECURITY_CODE
+ if (dirItems.ReadSecure)
+ dirItems.AddSecurityItem(fullPath, secureIndex);
+ #endif
+
+ AddDirFileInfo(phyParent, logParent, secureIndex, fi, dirItems.Items);
+
+ #if 0 // #ifndef UNDER_CE
+ {
+ CDirItem &dirItem = dirItems.Items.Back();
+ dirItems.SetLinkInfo(dirItem, fi, phyPrefix);
+ if (dirItem.ReparseData.Size() != 0)
+ continue;
+ }
+ #endif
+
+ dirItems.TotalSize += fi.Size;
+
+ #if 0 // #ifndef UNDER_CE
+ if (dirItems.ScanAltStreams)
+ {
+ UStringVector pathParts;
+ pathParts.Add(fs2us(fi.Name));
+ EnumerateAltStreams(fi, curNode, phyParent, logParent, phyPrefix,
+ pathParts, dirItems);
+ }
+ #endif
+
if (!isDir)
continue;
-
+
UStringVector addArchivePrefixNew;
const NWildcard::CCensorNode *nextNode = 0;
int index = curNode.FindSubNode(name);
@@ -252,110 +546,212 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
}
RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix,
- addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes));
+ addArchivePrefixNew, dirItems, true, callback));
}
+
for (i = 0; i < curNode.SubNodes.Size(); i++)
{
if (i < needEnterVector.Size())
if (!needEnterVector[i])
continue;
const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
- const UString fullPath = phyPrefix + nextNode.Name;
- NFind::CFileInfoW fi;
- if (!fi.Find(fullPath))
+ const FString fullPath = phyPrefix + us2fs(nextNode.Name);
+ NFind::CFileInfo fi;
+ #ifdef _WIN32
+ if (phyPrefix.IsEmpty() && NWildcard::IsDriveColonName(nextNode.Name))
+ {
+ fi.SetAsDir();
+ fi.Name = fullPath;
+ }
+ else
+ #endif
+ if (!fi.Find(fullPath,true))
{
if (!nextNode.AreThereIncludeItems())
continue;
- errorCodes.Add(::GetLastError());
- errorPaths.Add(fullPath);
+ dirItems.AddError(fullPath);
continue;
}
if (!fi.IsDir())
{
- errorCodes.Add((DWORD)E_FAIL);
- errorPaths.Add(fullPath);
+ dirItems.AddError(fullPath, (DWORD)E_FAIL);
continue;
}
RINOK(EnumerateDirItems_Spec(nextNode, phyParent, logParent, fi.Name, phyPrefix,
- UStringVector(), dirItems, false, callback, errorPaths, errorCodes));
+ UStringVector(), dirItems, false, callback));
}
+
return S_OK;
}
}
+ #ifdef _WIN32
+ #ifndef UNDER_CE
- NFind::CEnumeratorW enumerator(phyPrefix + wchar_t(kAnyStringWildcard));
- for (int ttt = 0; ; ttt++)
- {
- NFind::CFileInfoW fi;
- bool found;
- if (!enumerator.Next(fi, found))
- {
- errorCodes.Add(::GetLastError());
- errorPaths.Add(phyPrefix);
- break;
- }
- if (!found)
- break;
+ // scan drives, if wildcard is "*:\"
- if (callback && (ttt & 0xFF) == 0xFF)
- RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), phyPrefix));
- const UString &name = fi.Name;
- bool enterToSubFolders2 = enterToSubFolders;
- UStringVector addArchivePrefixNew = addArchivePrefix;
- addArchivePrefixNew.Add(name);
+ if (phyPrefix.IsEmpty() && curNode.IncludeItems.Size() > 0)
+ {
+ unsigned i;
+ for (i = 0; i < curNode.IncludeItems.Size(); i++)
{
- UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);
- if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fi.IsDir()))
+ const NWildcard::CItem &item = curNode.IncludeItems[i];
+ if (item.PathParts.Size() < 1)
+ break;
+ const UString &name = item.PathParts.Front();
+ if (name.Len() != 2 || name[1] != ':')
+ break;
+ if (item.PathParts.Size() == 1)
+ if (item.ForFile || !item.ForDir)
+ break;
+ if (NWildcard::IsDriveColonName(name))
continue;
+ if (name[0] != '*' && name[0] != '?')
+ break;
}
- if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fi.IsDir()))
+ if (i == curNode.IncludeItems.Size())
{
- AddDirFileInfo(phyParent, logParent, fi, dirItems.Items);
- if (fi.IsDir())
- enterToSubFolders2 = true;
- }
- if (!fi.IsDir())
- continue;
+ FStringVector driveStrings;
+ NFind::MyGetLogicalDriveStrings(driveStrings);
+ for (i = 0; i < driveStrings.Size(); i++)
+ {
+ FString driveName = driveStrings[i];
+ if (driveName.Len() < 3 || driveName.Back() != '\\')
+ return E_FAIL;
+ driveName.DeleteBack();
+ NFind::CFileInfo fi;
+ fi.SetAsDir();
+ fi.Name = driveName;
- const NWildcard::CCensorNode *nextNode = 0;
- if (addArchivePrefix.IsEmpty())
- {
- int index = curNode.FindSubNode(name);
- if (index >= 0)
- nextNode = &curNode.SubNodes[index];
+ RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix,
+ addArchivePrefix, dirItems, enterToSubFolders, callback));
+ }
+ return S_OK;
}
- if (!enterToSubFolders2 && nextNode == 0)
- continue;
+ }
+
+ #endif
+ #endif
- addArchivePrefixNew = addArchivePrefix;
- if (nextNode == 0)
+ NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
+ for (unsigned ttt = 0; ; ttt++)
+ {
+ NFind::CFileInfo fi;
+ bool found;
+ if (!enumerator.Next(fi, found))
{
- nextNode = &curNode;
- addArchivePrefixNew.Add(name);
+ dirItems.AddError(phyPrefix);
+ break;
}
+ if (!found)
+ break;
- RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, name, phyPrefix,
- addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes));
+ if (callback && (ttt & 0xFF) == 0xFF)
+ RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), dirItems.TotalSize, fs2us(phyPrefix), true));
+
+ RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix,
+ addArchivePrefix, dirItems, enterToSubFolders, callback));
}
return S_OK;
}
HRESULT EnumerateItems(
const NWildcard::CCensor &censor,
+ const NWildcard::ECensorPathMode pathMode,
+ const UString &addPathPrefix,
CDirItems &dirItems,
- IEnumDirItemCallback *callback,
- UStringVector &errorPaths,
- CRecordVector<DWORD> &errorCodes)
+ IEnumDirItemCallback *callback)
{
- for (int i = 0; i < censor.Pairs.Size(); i++)
+ FOR_VECTOR (i, censor.Pairs)
{
const NWildcard::CPair &pair = censor.Pairs[i];
int phyParent = pair.Prefix.IsEmpty() ? -1 : dirItems.AddPrefix(-1, -1, pair.Prefix);
- RINOK(EnumerateDirItems(pair.Head, phyParent, -1, pair.Prefix, UStringVector(), dirItems, false,
- callback, errorPaths, errorCodes));
+ int logParent = -1;
+
+ if (pathMode == NWildcard::k_AbsPath)
+ logParent = phyParent;
+ else
+ {
+ if (!addPathPrefix.IsEmpty())
+ logParent = dirItems.AddPrefix(-1, -1, addPathPrefix);
+ }
+
+ RINOK(EnumerateDirItems(pair.Head, phyParent, logParent, us2fs(pair.Prefix), UStringVector(),
+ dirItems,
+ false, // enterToSubFolders
+ callback));
}
dirItems.ReserveDown();
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ dirItems.FillFixedReparse();
+ #endif
+
return S_OK;
}
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+void CDirItems::FillFixedReparse()
+{
+ /* imagex/WIM reduces absolute pathes in links (raparse data),
+ if we archive non root folder. We do same thing here */
+
+ if (!SymLinks)
+ return;
+
+ FOR_VECTOR(i, Items)
+ {
+ CDirItem &item = Items[i];
+ if (item.ReparseData.Size() == 0)
+ continue;
+
+ CReparseAttr attr;
+ if (!attr.Parse(item.ReparseData, item.ReparseData.Size()))
+ continue;
+ if (attr.IsRelative())
+ continue;
+
+ const UString &link = attr.GetPath();
+ if (!IsDrivePath(link))
+ continue;
+ // maybe we need to support networks paths also ?
+
+ FString fullPathF;
+ if (!NDir::MyGetFullPathName(us2fs(GetPhyPath(i)), fullPathF))
+ continue;
+ UString fullPath = fs2us(fullPathF);
+ const UString logPath = GetLogPath(i);
+ if (logPath.Len() >= fullPath.Len())
+ continue;
+ if (CompareFileNames(logPath, fullPath.RightPtr(logPath.Len())) != 0)
+ continue;
+
+ const UString prefix = fullPath.Left(fullPath.Len() - logPath.Len());
+ if (prefix.Back() != WCHAR_PATH_SEPARATOR)
+ continue;
+
+ unsigned rootPrefixSize = GetRootPrefixSize(prefix);
+ if (rootPrefixSize == 0)
+ continue;
+ if (rootPrefixSize == prefix.Len())
+ continue; // simple case: paths are from root
+
+ if (link.Len() <= prefix.Len())
+ continue;
+
+ if (CompareFileNames(link.Left(prefix.Len()), prefix) != 0)
+ continue;
+
+ UString newLink = prefix.Left(rootPrefixSize);
+ newLink += link.Ptr(prefix.Len());
+
+ CByteBuffer data;
+ if (!FillLinkData(data, newLink, attr.IsSymLink()))
+ continue;
+ item.ReparseData2 = data;
+ }
+}
+
+#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/EnumDirItems.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/EnumDirItems.h
index d0ce950e3..803a64e7d 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/EnumDirItems.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/EnumDirItems.h
@@ -3,23 +3,25 @@
#ifndef __ENUM_DIR_ITEMS_H
#define __ENUM_DIR_ITEMS_H
-#include "Common/Wildcard.h"
-#include "Windows/FileFind.h"
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/FileFind.h"
+
#include "DirItem.h"
-void AddDirFileInfo(int phyParent, int logParent,
- const NWindows::NFile::NFind::CFileInfoW &fi, CObjectVector<CDirItem> &dirItems);
+void AddDirFileInfo(int phyParent, int logParent, int secureIndex,
+ const NWindows::NFile::NFind::CFileInfo &fi, CObjectVector<CDirItem> &dirItems);
struct IEnumDirItemCallback
{
- virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path) = 0;
+ virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, bool isDir) = 0;
};
HRESULT EnumerateItems(
const NWildcard::CCensor &censor,
+ NWildcard::ECensorPathMode pathMode,
+ const UString &addPathPrefix,
CDirItems &dirItems,
- IEnumDirItemCallback *callback,
- UStringVector &errorPaths,
- CRecordVector<DWORD> &errorCodes);
+ IEnumDirItemCallback *callback);
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ExitCode.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/ExitCode.h
deleted file mode 100644
index b6d7d4dfc..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ExitCode.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// ExitCode.h
-
-#ifndef __EXIT_CODE_H
-#define __EXIT_CODE_H
-
-namespace NExitCode {
-
-enum EEnum {
-
- kSuccess = 0, // Successful operation
- kWarning = 1, // Non fatal error(s) occurred
- kFatalError = 2, // A fatal error occurred
- // kCRCError = 3, // A CRC error occurred when unpacking
- // kLockedArchive = 4, // Attempt to modify an archive previously locked
- // kWriteError = 5, // Write to disk error
- // kOpenError = 6, // Open file error
- kUserError = 7, // Command line option error
- kMemoryError = 8, // Not enough memory for operation
- // kCreateFileError = 9, // Create file error
-
- kUserBreak = 255 // User stopped the process
-
-};
-
-}
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.cpp
index ca2c8c73d..5f94254ef 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.cpp
@@ -2,11 +2,11 @@
#include "StdAfx.h"
-#include <stdio.h>
+#include "../../../Common/StringConvert.h"
-#include "Windows/FileDir.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/PropVariantConv.h"
#include "../Common/ExtractingFilePath.h"
@@ -14,135 +14,251 @@
#include "SetProperties.h"
using namespace NWindows;
+using namespace NFile;
+using namespace NDir;
static HRESULT DecompressArchive(
- const CArc &arc,
+ CCodecs *codecs,
+ const CArchiveLink &arcLink,
UInt64 packSize,
const NWildcard::CCensorNode &wildcardCensor,
const CExtractOptions &options,
+ bool calcCrc,
IExtractCallbackUI *callback,
- CArchiveExtractCallback *extractCallbackSpec,
+ CArchiveExtractCallback *ecs,
UString &errorMessage,
UInt64 &stdInProcessed)
{
+ const CArc &arc = arcLink.Arcs.Back();
stdInProcessed = 0;
IInArchive *archive = arc.Archive;
CRecordVector<UInt32> realIndices;
+
+ UStringVector removePathParts;
+
+ FString outDir = options.OutputDir;
+ UString replaceName = arc.DefaultName;
+
+ if (arcLink.Arcs.Size() > 1)
+ {
+ // Most "pe" archives have same name of archive subfile "[0]" or ".rsrc_1".
+ // So it extracts different archives to one folder.
+ // We will use top level archive name
+ const CArc &arc0 = arcLink.Arcs[0];
+ if (StringsAreEqualNoCase_Ascii(codecs->Formats[arc0.FormatIndex].Name, "pe"))
+ replaceName = arc0.DefaultName;
+ }
+
+ outDir.Replace(FSTRING_ANY_MASK, us2fs(GetCorrectFsPath(replaceName)));
+
+ bool elimIsPossible = false;
+ UString elimPrefix; // only pure name without dir delimiter
+ FString outDirReduced = outDir;
+
+ if (options.ElimDup.Val)
+ {
+ UString dirPrefix;
+ SplitPathToParts_Smart(fs2us(outDir), dirPrefix, elimPrefix);
+ if (!elimPrefix.IsEmpty())
+ {
+ if (IsCharDirLimiter(elimPrefix.Back()))
+ elimPrefix.DeleteBack();
+ if (!elimPrefix.IsEmpty())
+ {
+ outDirReduced = us2fs(dirPrefix);
+ elimIsPossible = true;
+ }
+ }
+ }
+
if (!options.StdInMode)
{
UInt32 numItems;
RINOK(archive->GetNumberOfItems(&numItems));
-
+
+ UString filePath;
+
for (UInt32 i = 0; i < numItems; i++)
{
- UString filePath;
RINOK(arc.GetItemPath(i, filePath));
+
+ if (elimIsPossible && options.ElimDup.Val)
+ {
+ if (!IsPath1PrefixedByPath2(filePath, elimPrefix))
+ elimIsPossible = false;
+ else
+ {
+ wchar_t c = filePath[elimPrefix.Len()];
+ if (c != 0 && !IsCharDirLimiter(c))
+ elimIsPossible = false;
+ }
+ }
+
bool isFolder;
- RINOK(IsArchiveItemFolder(archive, i, isFolder));
- if (!wildcardCensor.CheckPath(filePath, !isFolder))
+ RINOK(Archive_IsItem_Folder(archive, i, isFolder));
+ bool isAltStream;
+ RINOK(Archive_IsItem_AltStream(archive, i, isAltStream));
+ if (!options.NtOptions.AltStreams.Val && isAltStream)
+ continue;
+ if (!wildcardCensor.CheckPath(isAltStream, filePath, !isFolder))
continue;
realIndices.Add(i);
}
+
if (realIndices.Size() == 0)
{
callback->ThereAreNoFiles();
- return S_OK;
+ return callback->ExtractResult(S_OK);
}
}
- UStringVector removePathParts;
+ if (elimIsPossible)
+ outDir = outDirReduced;
- UString outDir = options.OutputDir;
- outDir.Replace(L"*", GetCorrectFsPath(arc.DefaultName));
#ifdef _WIN32
// GetCorrectFullFsPath doesn't like "..".
// outDir.TrimRight();
// outDir = GetCorrectFullFsPath(outDir);
#endif
- if (!outDir.IsEmpty())
- if (!NFile::NDirectory::CreateComplexDirectory(outDir))
+ if (outDir.IsEmpty())
+ outDir = FString(FTEXT(".")) + FString(FSTRING_PATH_SEPARATOR);
+ else
+ if (!CreateComplexDir(outDir))
{
HRESULT res = ::GetLastError();
if (res == S_OK)
res = E_FAIL;
- errorMessage = ((UString)L"Can not create output directory ") + outDir;
+ errorMessage = ((UString)L"Can not create output directory ") + fs2us(outDir);
return res;
}
- extractCallbackSpec->Init(
+ ecs->Init(
+ options.NtOptions,
options.StdInMode ? &wildcardCensor : NULL,
&arc,
callback,
- options.StdOutMode, options.TestMode, options.CalcCrc,
+ options.StdOutMode, options.TestMode,
outDir,
removePathParts,
packSize);
- #if !defined(_7ZIP_ST) && !defined(_SFX)
- RINOK(SetProperties(archive, options.Properties));
+
+ #ifdef SUPPORT_LINKS
+
+ if (!options.StdInMode &&
+ !options.TestMode &&
+ options.NtOptions.HardLinks.Val)
+ {
+ RINOK(ecs->PrepareHardLinks(&realIndices));
+ }
+
#endif
+
HRESULT result;
- Int32 testMode = (options.TestMode && !options.CalcCrc) ? 1: 0;
+ Int32 testMode = (options.TestMode && !calcCrc) ? 1: 0;
if (options.StdInMode)
{
- result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, extractCallbackSpec);
+ result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, ecs);
NCOM::CPropVariant prop;
if (archive->GetArchiveProperty(kpidPhySize, &prop) == S_OK)
- if (prop.vt == VT_UI8 || prop.vt == VT_UI4)
- stdInProcessed = ConvertPropVariantToUInt64(prop);
+ ConvertPropVariantToUInt64(prop, stdInProcessed);
}
else
- result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallbackSpec);
-
+ result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, ecs);
+ if (result == S_OK && !options.StdInMode)
+ result = ecs->SetDirsTimes();
return callback->ExtractResult(result);
}
-HRESULT DecompressArchives(
- CCodecs *codecs, const CIntVector &formatIndices,
+/* v9.31: BUG was fixed:
+ Sorted list for file paths was sorted with case insensitive compare function.
+ But FindInSorted function did binary search via case sensitive compare function */
+
+int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &name)
+{
+ unsigned left = 0, right = fileName.Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const UString &midValue = fileName[mid];
+ int compare = CompareFileNames(name, midValue);
+ if (compare == 0)
+ return mid;
+ if (compare < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ return -1;
+}
+
+HRESULT Extract(
+ CCodecs *codecs,
+ const CObjectVector<COpenType> &types,
+ const CIntVector &excludedFormats,
UStringVector &arcPaths, UStringVector &arcPathsFull,
const NWildcard::CCensorNode &wildcardCensor,
const CExtractOptions &options,
IOpenCallbackUI *openCallback,
IExtractCallbackUI *extractCallback,
+ #ifndef _SFX
+ IHashCalc *hash,
+ #endif
UString &errorMessage,
CDecompressStat &stat)
{
stat.Clear();
- int i;
UInt64 totalPackSize = 0;
- CRecordVector<UInt64> archiveSizes;
+ CRecordVector<UInt64> arcSizes;
- int numArcs = options.StdInMode ? 1 : arcPaths.Size();
+ unsigned numArcs = options.StdInMode ? 1 : arcPaths.Size();
+ unsigned i;
for (i = 0; i < numArcs; i++)
{
- NFile::NFind::CFileInfoW fi;
+ NFind::CFileInfo fi;
fi.Size = 0;
if (!options.StdInMode)
{
- const UString &arcPath = arcPaths[i];
- if (!fi.Find(arcPath))
+ const FString &arcPath = us2fs(arcPaths[i]);
+ if (!fi.Find(arcPath,true))
throw "there is no such archive";
if (fi.IsDir())
throw "can't decompress folder";
}
- archiveSizes.Add(fi.Size);
+ arcSizes.Add(fi.Size);
totalPackSize += fi.Size;
}
- CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
- CMyComPtr<IArchiveExtractCallback> ec(extractCallbackSpec);
+
+ CBoolArr skipArcs(numArcs);
+ for (i = 0; i < numArcs; i++)
+ skipArcs[i] = false;
+
+ CArchiveExtractCallback *ecs = new CArchiveExtractCallback;
+ CMyComPtr<IArchiveExtractCallback> ec(ecs);
bool multi = (numArcs > 1);
- extractCallbackSpec->InitForMulti(multi, options.PathMode, options.OverwriteMode);
+ ecs->InitForMulti(multi, options.PathMode, options.OverwriteMode);
+ #ifndef _SFX
+ ecs->SetHashMethods(hash);
+ #endif
+
if (multi)
{
RINOK(extractCallback->SetTotal(totalPackSize));
}
+
+ UInt64 totalPackProcessed = 0;
+ bool thereAreNotOpenArcs = false;
+
for (i = 0; i < numArcs; i++)
{
+ if (skipArcs[i])
+ continue;
+
const UString &arcPath = arcPaths[i];
- NFile::NFind::CFileInfoW fi;
+ NFind::CFileInfo fi;
if (options.StdInMode)
{
fi.Size = 0;
@@ -150,7 +266,7 @@ HRESULT DecompressArchives(
}
else
{
- if (!fi.Find(arcPath) || fi.IsDir())
+ if (!fi.Find(us2fs(arcPath),true) || fi.IsDir())
throw "there is no such archive";
}
@@ -159,16 +275,17 @@ HRESULT DecompressArchives(
#endif
RINOK(extractCallback->BeforeOpen(arcPath));
- CArchiveLink archiveLink;
+ CArchiveLink arcLink;
- CIntVector formatIndices2 = formatIndices;
+ CObjectVector<COpenType> types2 = types;
+ /*
#ifndef _SFX
- if (formatIndices.IsEmpty())
+ if (types.IsEmpty())
{
int pos = arcPath.ReverseFind(L'.');
if (pos >= 0)
{
- UString s = arcPath.Mid(pos + 1);
+ UString s = arcPath.Ptr(pos + 1);
int index = codecs->FindFormatForExtension(s);
if (index >= 0 && s == L"001")
{
@@ -176,18 +293,31 @@ HRESULT DecompressArchives(
pos = s.ReverseFind(L'.');
if (pos >= 0)
{
- int index2 = codecs->FindFormatForExtension(s.Mid(pos + 1));
- if (index2 >= 0 && s.CompareNoCase(L"rar") != 0)
+ int index2 = codecs->FindFormatForExtension(s.Ptr(pos + 1));
+ if (index2 >= 0) // && s.CompareNoCase(L"rar") != 0
{
- formatIndices2.Add(index2);
- formatIndices2.Add(index);
+ types2.Add(index2);
+ types2.Add(index);
}
}
}
}
}
#endif
- HRESULT result = archiveLink.Open2(codecs, formatIndices2, options.StdInMode, NULL, arcPath, openCallback);
+ */
+
+ COpenOptions op;
+ #ifndef _SFX
+ op.props = &options.Properties;
+ #endif
+ op.codecs = codecs;
+ op.types = &types2;
+ op.excludedFormats = &excludedFormats;
+ op.stdInMode = options.StdInMode;
+ op.stream = NULL;
+ op.filePath = arcPath;
+ HRESULT result = arcLink.Open2(op, openCallback);
+
if (result == E_ABORT)
return result;
@@ -196,68 +326,148 @@ HRESULT DecompressArchives(
crypted = openCallback->Open_WasPasswordAsked();
#endif
+ if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
+ result = S_FALSE;
+
+ // arcLink.Set_ErrorsText();
RINOK(extractCallback->OpenResult(arcPath, result, crypted));
+
+
+ {
+ FOR_VECTOR (r, arcLink.Arcs)
+ {
+ const CArc &arc = arcLink.Arcs[r];
+ const CArcErrorInfo &er = arc.ErrorInfo;
+ if (er.IsThereErrorOrWarning())
+ {
+ RINOK(extractCallback->SetError(r, arc.Path,
+ er.GetErrorFlags(), er.ErrorMessage,
+ er.GetWarningFlags(), er.WarningMessage));
+ }
+ }
+ }
+
if (result != S_OK)
+ {
+ thereAreNotOpenArcs = true;
+ if (!options.StdInMode)
+ {
+ NFind::CFileInfo fi;
+ if (fi.Find(us2fs(arcPath)))
+ if (!fi.IsDir())
+ totalPackProcessed += fi.Size;
+ }
continue;
+ }
if (!options.StdInMode)
- for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
{
- int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]);
- if (index >= 0 && index > i)
+ // numVolumes += arcLink.VolumePaths.Size();
+ // arcLink.VolumesSize;
+
+ // totalPackSize -= DeleteUsedFileNamesFromList(arcLink, i + 1, arcPaths, arcPathsFull, &arcSizes);
+ // numArcs = arcPaths.Size();
+ if (arcLink.VolumePaths.Size() != 0)
{
- arcPaths.Delete(index);
- arcPathsFull.Delete(index);
- totalPackSize -= archiveSizes[index];
- archiveSizes.Delete(index);
- numArcs = arcPaths.Size();
+ Int64 correctionSize = arcLink.VolumesSize;
+ FOR_VECTOR (v, arcLink.VolumePaths)
+ {
+ int index = Find_FileName_InSortedVector(arcPathsFull, arcLink.VolumePaths[v]);
+ if (index >= 0)
+ {
+ if ((unsigned)index > i)
+ {
+ skipArcs[index] = true;
+ correctionSize -= arcSizes[index];
+ }
+ }
+ }
+ if (correctionSize != 0)
+ {
+ Int64 newPackSize = (Int64)totalPackSize + correctionSize;
+ if (newPackSize < 0)
+ newPackSize = 0;
+ totalPackSize = newPackSize;
+ RINOK(extractCallback->SetTotal(totalPackSize));
+ }
}
}
- if (archiveLink.VolumePaths.Size() != 0)
- {
- totalPackSize += archiveLink.VolumesSize;
- RINOK(extractCallback->SetTotal(totalPackSize));
- }
#ifndef _NO_CRYPTO
+ bool passwordIsDefined;
UString password;
- RINOK(openCallback->Open_GetPasswordIfAny(password));
- if (!password.IsEmpty())
+ RINOK(openCallback->Open_GetPasswordIfAny(passwordIsDefined, password));
+ if (passwordIsDefined)
{
RINOK(extractCallback->SetPassword(password));
}
#endif
- for (int v = 0; v < archiveLink.Arcs.Size(); v++)
+ FOR_VECTOR (k, arcLink.Arcs)
{
- const UString &s = archiveLink.Arcs[v].ErrorMessage;
- if (!s.IsEmpty())
+ const CArc &arc = arcLink.Arcs[k];
+ const CArcErrorInfo &er = arc.ErrorInfo;
+
+ if (er.ErrorFormatIndex >= 0)
{
+ RINOK(extractCallback->OpenTypeWarning(arc.Path,
+ codecs->GetFormatNamePtr(arc.FormatIndex),
+ codecs->GetFormatNamePtr(er.ErrorFormatIndex)))
+ /*
+ UString s = L"Can not open the file as [" + codecs->Formats[arc.ErrorFormatIndex].Name + L"] archive\n";
+ s += L"The file is open as [" + codecs->Formats[arc.FormatIndex].Name + L"] archive";
RINOK(extractCallback->MessageError(s));
+ */
+ }
+ {
+ const UString &s = er.ErrorMessage;
+ if (!s.IsEmpty())
+ {
+ RINOK(extractCallback->MessageError(s));
+ }
}
}
- CArc &arc = archiveLink.Arcs.Back();
+ CArc &arc = arcLink.Arcs.Back();
arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice);
arc.MTime = fi.MTime;
UInt64 packProcessed;
- RINOK(DecompressArchive(arc,
- fi.Size + archiveLink.VolumesSize,
- wildcardCensor, options, extractCallback, extractCallbackSpec, errorMessage, packProcessed));
+ bool calcCrc =
+ #ifndef _SFX
+ (hash != NULL);
+ #else
+ false;
+ #endif
+
+ RINOK(DecompressArchive(
+ codecs,
+ arcLink,
+ fi.Size + arcLink.VolumesSize,
+ wildcardCensor,
+ options,
+ calcCrc,
+ extractCallback, ecs, errorMessage, packProcessed));
if (!options.StdInMode)
- packProcessed = fi.Size + archiveLink.VolumesSize;
- extractCallbackSpec->LocalProgressSpec->InSize += packProcessed;
- extractCallbackSpec->LocalProgressSpec->OutSize = extractCallbackSpec->UnpackSize;
+ packProcessed = fi.Size + arcLink.VolumesSize;
+ totalPackProcessed += packProcessed;
+ ecs->LocalProgressSpec->InSize += packProcessed;
+ ecs->LocalProgressSpec->OutSize = ecs->UnpackSize;
if (!errorMessage.IsEmpty())
return E_FAIL;
}
- stat.NumFolders = extractCallbackSpec->NumFolders;
- stat.NumFiles = extractCallbackSpec->NumFiles;
- stat.UnpackSize = extractCallbackSpec->UnpackSize;
- stat.CrcSum = extractCallbackSpec->CrcSum;
+ if (multi || thereAreNotOpenArcs)
+ {
+ RINOK(extractCallback->SetTotal(totalPackSize));
+ RINOK(extractCallback->SetCompleted(&totalPackProcessed));
+ }
+ stat.NumFolders = ecs->NumFolders;
+ stat.NumFiles = ecs->NumFiles;
+ stat.NumAltStreams = ecs->NumAltStreams;
+ stat.UnpackSize = ecs->UnpackSize;
+ stat.AltStreams_UnpackSize = ecs->AltStreams_UnpackSize;
stat.NumArchives = arcPaths.Size();
- stat.PackSize = extractCallbackSpec->LocalProgressSpec->InSize;
+ stat.PackSize = ecs->LocalProgressSpec->InSize;
return S_OK;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.h
index 5a939ed23..052b2f7d3 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.h
@@ -3,7 +3,7 @@
#ifndef __EXTRACT_H
#define __EXTRACT_H
-#include "Windows/FileFind.h"
+#include "../../../Windows/FileFind.h"
#include "../../Archive/IArchive.h"
@@ -14,21 +14,37 @@
#include "../Common/LoadCodecs.h"
-struct CExtractOptions
+struct CExtractOptionsBase
+{
+ CBoolPair ElimDup;
+
+ bool PathMode_Force;
+ bool OverwriteMode_Force;
+ NExtract::NPathMode::EEnum PathMode;
+ NExtract::NOverwriteMode::EEnum OverwriteMode;
+
+ FString OutputDir;
+ CExtractNtOptions NtOptions;
+
+ CExtractOptionsBase():
+ PathMode_Force(false),
+ OverwriteMode_Force(false),
+ PathMode(NExtract::NPathMode::kFullPaths),
+ OverwriteMode(NExtract::NOverwriteMode::kAsk)
+ {}
+};
+
+struct CExtractOptions: public CExtractOptionsBase
{
bool StdInMode;
bool StdOutMode;
bool YesToAll;
bool TestMode;
- bool CalcCrc;
- NExtract::NPathMode::EEnum PathMode;
- NExtract::NOverwriteMode::EEnum OverwriteMode;
- UString OutputDir;
-
+
// bool ShowDialog;
// bool PasswordEnabled;
// UString Password;
- #if !defined(_7ZIP_ST) && !defined(_SFX)
+ #ifndef _SFX
CObjectVector<CProperty> Properties;
#endif
@@ -37,13 +53,10 @@ struct CExtractOptions
#endif
CExtractOptions():
+ TestMode(false),
StdInMode(false),
StdOutMode(false),
- YesToAll(false),
- TestMode(false),
- CalcCrc(false),
- PathMode(NExtract::NPathMode::kFullPathnames),
- OverwriteMode(NExtract::NOverwriteMode::kAskBefore)
+ YesToAll(false)
{}
};
@@ -51,25 +64,30 @@ struct CDecompressStat
{
UInt64 NumArchives;
UInt64 UnpackSize;
+ UInt64 AltStreams_UnpackSize;
UInt64 PackSize;
UInt64 NumFolders;
UInt64 NumFiles;
- UInt32 CrcSum;
+ UInt64 NumAltStreams;
void Clear()
{
- NumArchives = UnpackSize = PackSize = NumFolders = NumFiles = 0;
- CrcSum = 0;
+ NumArchives = UnpackSize = AltStreams_UnpackSize = PackSize = NumFolders = NumFiles = NumAltStreams = 0;
}
};
-HRESULT DecompressArchives(
- CCodecs *codecs, const CIntVector &formatIndices,
+HRESULT Extract(
+ CCodecs *codecs,
+ const CObjectVector<COpenType> &types,
+ const CIntVector &excludedFormats,
UStringVector &archivePaths, UStringVector &archivePathsFull,
const NWildcard::CCensorNode &wildcardCensor,
const CExtractOptions &options,
IOpenCallbackUI *openCallback,
IExtractCallbackUI *extractCallback,
+ #ifndef _SFX
+ IHashCalc *hash,
+ #endif
UString &errorMessage,
CDecompressStat &stat);
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractMode.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractMode.h
index b448fb30a..a54376705 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractMode.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractMode.h
@@ -4,28 +4,30 @@
#define __EXTRACT_MODE_H
namespace NExtract {
-
- namespace NPathMode
+
+namespace NPathMode
+{
+ enum EEnum
{
- enum EEnum
- {
- kFullPathnames,
- kCurrentPathnames,
- kNoPathnames
- };
- }
-
- namespace NOverwriteMode
+ kFullPaths,
+ kCurPaths,
+ kNoPaths,
+ kAbsPaths
+ };
+}
+
+namespace NOverwriteMode
+{
+ enum EEnum
{
- enum EEnum
- {
- kAskBefore,
- kWithoutPrompt,
- kSkipExisting,
- kAutoRename,
- kAutoRenameExisting
- };
- }
+ kAsk,
+ kOverwrite,
+ kSkip,
+ kRename,
+ kRenameExisting
+ };
+}
+
}
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.cpp
index 8f31708b6..852fd5adb 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.cpp
@@ -2,26 +2,44 @@
#include "StdAfx.h"
-#include "../../../../C/Types.h"
+#include "../../../Common/Wildcard.h"
-#include "Common/Wildcard.h"
+#include "../../../Windows/FileName.h"
#include "ExtractingFilePath.h"
-static UString ReplaceIncorrectChars(const UString &s)
+static UString ReplaceIncorrectChars(const UString &s, bool repaceColon)
{
#ifdef _WIN32
UString res;
- for (int i = 0; i < s.Length(); i++)
+ bool beforeColon = true;
{
- wchar_t c = s[i];
- if (c < 0x20 || c == '*' || c == '?' || c == '<' || c == '>' || c == '|' || c == ':' || c == '"')
- c = '_';
- res += c;
+ for (unsigned i = 0; i < s.Len(); i++)
+ {
+ wchar_t c = s[i];
+ if (beforeColon)
+ if (c == '*' || c == '?' || c < 0x20 || c == '<' || c == '>' || c == '|' || c == '"')
+ c = '_';
+ if (c == ':')
+ {
+ if (repaceColon)
+ c = '_';
+ else
+ beforeColon = false;
+ }
+ res += c;
+ }
+ }
+ if (beforeColon)
+ {
+ for (int i = res.Len() - 1; i >= 0; i--)
+ {
+ wchar_t c = res[i];
+ if (c != '.' && c != ' ')
+ break;
+ res.ReplaceOneCharAtPos(i, '_');
+ }
}
- res.TrimRight();
- while (!res.IsEmpty() && res[res.Length() - 1] == '.')
- res.Delete(res.Length() - 1);
return res;
#else
return s;
@@ -29,27 +47,28 @@ static UString ReplaceIncorrectChars(const UString &s)
}
#ifdef _WIN32
+
static const wchar_t *g_ReservedNames[] =
{
L"CON", L"PRN", L"AUX", L"NUL"
};
-static bool CheckTail(const UString &name, int len)
+static bool CheckTail(const UString &name, unsigned len)
{
int dotPos = name.Find(L'.');
if (dotPos < 0)
- dotPos = name.Length();
+ dotPos = name.Len();
UString s = name.Left(dotPos);
s.TrimRight();
- return (s.Length() != len);
+ return s.Len() != len;
}
static bool CheckNameNum(const UString &name, const wchar_t *reservedName)
{
- int len = MyStringLen(reservedName);
- if (name.Length() <= len)
+ unsigned len = MyStringLen(reservedName);
+ if (name.Len() <= len)
return true;
- if (name.Left(len).CompareNoCase(reservedName) != 0)
+ if (MyStringCompareNoCase_N(name, reservedName, len) != 0)
return true;
wchar_t c = name[len];
if (c < L'0' || c > L'9')
@@ -59,13 +78,13 @@ static bool CheckNameNum(const UString &name, const wchar_t *reservedName)
static bool IsSupportedName(const UString &name)
{
- for (int i = 0; i < sizeof(g_ReservedNames) / sizeof(g_ReservedNames[0]); i++)
+ for (unsigned i = 0; i < ARRAY_SIZE(g_ReservedNames); i++)
{
const wchar_t *reservedName = g_ReservedNames[i];
- int len = MyStringLen(reservedName);
- if (name.Length() < len)
+ unsigned len = MyStringLen(reservedName);
+ if (name.Len() < len)
continue;
- if (name.Left(len).CompareNoCase(reservedName) != 0)
+ if (MyStringCompareNoCase_N(name, reservedName, len) != 0)
continue;
if (!CheckTail(name, len))
return false;
@@ -74,21 +93,34 @@ static bool IsSupportedName(const UString &name)
return false;
return CheckNameNum(name, L"LPT");
}
+
#endif
-static UString GetCorrectFileName(const UString &path)
+static UString GetCorrectFileName(const UString &path, bool repaceColon)
{
if (path == L".." || path == L".")
return UString();
- return ReplaceIncorrectChars(path);
+ return ReplaceIncorrectChars(path, repaceColon);
}
-void MakeCorrectPath(UStringVector &pathParts)
+void MakeCorrectPath(bool isPathFromRoot, UStringVector &pathParts, bool replaceAltStreamColon)
{
- for (int i = 0; i < pathParts.Size();)
+ for (unsigned i = 0; i < pathParts.Size();)
{
UString &s = pathParts[i];
- s = GetCorrectFileName(s);
+ #ifdef _WIN32
+ bool needReplaceColon = (replaceAltStreamColon || i != pathParts.Size() - 1);
+ if (i == 0 && isPathFromRoot && NWindows::NFile::NName::IsDrivePath(s))
+ {
+ UString s2 = s[0];
+ s2 += L'_';
+ s2 += GetCorrectFileName(s.Ptr(2), needReplaceColon);
+ s = s2;
+ }
+ else
+ s = GetCorrectFileName(s, needReplaceColon);
+ #endif
+
if (s.IsEmpty())
pathParts.Delete(i);
else
@@ -105,7 +137,7 @@ void MakeCorrectPath(UStringVector &pathParts)
UString MakePathNameFromParts(const UStringVector &parts)
{
UString result;
- for (int i = 0; i < parts.Size(); i++)
+ FOR_VECTOR (i, parts)
{
if (i != 0)
result += WCHAR_PATH_SEPARATOR;
@@ -114,28 +146,44 @@ UString MakePathNameFromParts(const UStringVector &parts)
return result;
}
+static const wchar_t *k_EmptyReplaceName = L"[]";
+
+void Correct_IfEmptyLastPart(UStringVector &parts)
+{
+ if (parts.IsEmpty())
+ parts.Add(k_EmptyReplaceName);
+ else
+ {
+ UString &s = parts.Back();
+ if (s.IsEmpty())
+ s = k_EmptyReplaceName;
+ }
+}
+
UString GetCorrectFsPath(const UString &path)
{
- UString res = GetCorrectFileName(path);
+ UString res = GetCorrectFileName(path, true);
#ifdef _WIN32
if (!IsSupportedName(res))
res = (UString)L"_" + res;
#endif
+ if (res.IsEmpty())
+ res = k_EmptyReplaceName;
return res;
}
-
+
UString GetCorrectFullFsPath(const UString &path)
{
UStringVector parts;
SplitPathToParts(path, parts);
- for (int i = 0; i < parts.Size(); i++)
+ FOR_VECTOR (i, parts)
{
UString &s = parts[i];
#ifdef _WIN32
- while (!s.IsEmpty() && s[s.Length() - 1] == '.')
- s.Delete(s.Length() - 1);
+ while (!s.IsEmpty() && (s.Back() == '.' || s.Back() == ' '))
+ s.DeleteBack();
if (!IsSupportedName(s))
- s = (UString)L"_" + s;
+ s.InsertAtFront(L'_');
#endif
}
return MakePathNameFromParts(parts);
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.h
index da28bfc23..751248a97 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.h
@@ -3,11 +3,19 @@
#ifndef __EXTRACTING_FILE_PATH_H
#define __EXTRACTING_FILE_PATH_H
-#include "Common/MyString.h"
+#include "../../../Common/MyString.h"
UString MakePathNameFromParts(const UStringVector &parts);
-void MakeCorrectPath(UStringVector &pathParts);
+
+/* for WIN32:
+ if (isRoot == true), and pathParts[0] contains path like "c:name",
+ it thinks that "c:" is drive prefix (it's not ":name alt stream) and
+ the function changes part to c_name */
+void MakeCorrectPath(bool isPathFromRoot, UStringVector &pathParts, bool replaceAltStreamColon);
+
UString GetCorrectFsPath(const UString &path);
UString GetCorrectFullFsPath(const UString &path);
+void Correct_IfEmptyLastPart(UStringVector &parts);
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/HashCalc.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/HashCalc.cpp
new file mode 100644
index 000000000..2d13a2af1
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/HashCalc.cpp
@@ -0,0 +1,361 @@
+// HashCalc.cpp
+
+#include "StdAfx.h"
+
+#include "../../../../C/Alloc.h"
+
+#include "../../../Common/StringToInt.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Common/StreamUtils.h"
+
+#include "EnumDirItems.h"
+#include "HashCalc.h"
+
+using namespace NWindows;
+
+class CHashMidBuf
+{
+ void *_data;
+public:
+ CHashMidBuf(): _data(0) {}
+ operator void *() { return _data; }
+ bool Alloc(size_t size)
+ {
+ if (_data != 0)
+ return false;
+ _data = ::MidAlloc(size);
+ return _data != 0;
+ }
+ ~CHashMidBuf() { ::MidFree(_data); }
+};
+
+struct CEnumDirItemCallback_Hash: public IEnumDirItemCallback
+{
+ IHashCallbackUI *Callback;
+
+ HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, bool isDir)
+ {
+ return Callback->ScanProgress(numFolders, numFiles, totalSize, path, isDir);
+ }
+};
+
+static const wchar_t *k_DefaultHashMethod = L"CRC32";
+
+HRESULT CHashBundle::SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &hashMethods)
+{
+ UStringVector names = hashMethods;
+ if (names.IsEmpty())
+ names.Add(k_DefaultHashMethod);
+
+ CRecordVector<CMethodId> ids;
+ CObjectVector<COneMethodInfo> methods;
+
+ unsigned i;
+ for (i = 0; i < names.Size(); i++)
+ {
+ COneMethodInfo m;
+ RINOK(m.ParseMethodFromString(names[i]));
+
+ if (m.MethodName.IsEmpty())
+ m.MethodName = k_DefaultHashMethod;
+
+ if (m.MethodName == L"*")
+ {
+ CRecordVector<CMethodId> tempMethods;
+ GetHashMethods(EXTERNAL_CODECS_LOC_VARS tempMethods);
+ methods.Clear();
+ ids.Clear();
+ FOR_VECTOR (t, tempMethods)
+ {
+ int index = ids.AddToUniqueSorted(tempMethods[t]);
+ if (ids.Size() != methods.Size())
+ methods.Insert(index, m);
+ }
+ break;
+ }
+ else
+ {
+ // m.MethodName.RemoveChar(L'-');
+ CMethodId id;
+ if (!FindHashMethod(EXTERNAL_CODECS_LOC_VARS m.MethodName, id))
+ return E_NOTIMPL;
+ int index = ids.AddToUniqueSorted(id);
+ if (ids.Size() != methods.Size())
+ methods.Insert(index, m);
+ }
+ }
+
+ for (i = 0; i < ids.Size(); i++)
+ {
+ CMyComPtr<IHasher> hasher;
+ UString name;
+ RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS ids[i], name, hasher));
+ if (!hasher)
+ throw "Can't create hasher";
+ const COneMethodInfo &m = methods[i];
+ {
+ CMyComPtr<ICompressSetCoderProperties> scp;
+ hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
+ if (scp)
+ {
+ RINOK(m.SetCoderProps(scp, NULL));
+ }
+ }
+ UInt32 digestSize = hasher->GetDigestSize();
+ if (digestSize > k_HashCalc_DigestSize_Max)
+ return E_NOTIMPL;
+ CHasherState &h = Hashers.AddNew();
+ h.Hasher = hasher;
+ h.Name = name;
+ h.DigestSize = digestSize;
+ for (int i = 0; i < k_HashCalc_NumGroups; i++)
+ memset(h.Digests[i], 0, digestSize);
+ }
+ return S_OK;
+}
+
+void CHashBundle::InitForNewFile()
+{
+ CurSize = 0;
+ FOR_VECTOR (i, Hashers)
+ {
+ CHasherState &h = Hashers[i];
+ h.Hasher->Init();
+ memset(h.Digests[k_HashCalc_Index_Current], 0, h.DigestSize);
+ }
+}
+
+void CHashBundle::Update(const void *data, UInt32 size)
+{
+ CurSize += size;
+ FOR_VECTOR (i, Hashers)
+ Hashers[i].Hasher->Update(data, size);
+}
+
+void CHashBundle::SetSize(UInt64 size)
+{
+ CurSize = size;
+}
+
+static void AddDigests(Byte *dest, const Byte *src, UInt32 size)
+{
+ unsigned next = 0;
+ for (UInt32 i = 0; i < size; i++)
+ {
+ next += (unsigned)dest[i] + (unsigned)src[i];
+ dest[i] = (Byte)next;
+ next >>= 8;
+ }
+}
+
+void CHashBundle::Final(bool isDir, bool isAltStream, const UString &path)
+{
+ if (isDir)
+ NumDirs++;
+ else if (isAltStream)
+ {
+ NumAltStreams++;
+ AltStreamsSize += CurSize;
+ }
+ else
+ {
+ NumFiles++;
+ FilesSize += CurSize;
+ }
+
+ Byte pre[16];
+ memset(pre, 0, sizeof(pre));
+ if (isDir)
+ pre[0] = 1;
+
+ FOR_VECTOR (i, Hashers)
+ {
+ CHasherState &h = Hashers[i];
+ if (!isDir)
+ {
+ h.Hasher->Final(h.Digests[0]);
+ if (!isAltStream)
+ AddDigests(h.Digests[k_HashCalc_Index_DataSum], h.Digests[0], h.DigestSize);
+ }
+
+ h.Hasher->Init();
+ h.Hasher->Update(pre, sizeof(pre));
+ h.Hasher->Update(h.Digests[0], h.DigestSize);
+
+ for (unsigned k = 0; k < path.Len(); k++)
+ {
+ wchar_t c = path[k];
+ Byte temp[2] = { (Byte)(c & 0xFF), (Byte)((c >> 8) & 0xFF) };
+ h.Hasher->Update(temp, 2);
+ }
+
+ Byte tempDigest[k_HashCalc_DigestSize_Max];
+ h.Hasher->Final(tempDigest);
+ if (!isAltStream)
+ AddDigests(h.Digests[k_HashCalc_Index_NamesSum], tempDigest, h.DigestSize);
+ AddDigests(h.Digests[k_HashCalc_Index_StreamsSum], tempDigest, h.DigestSize);
+ }
+}
+
+
+HRESULT HashCalc(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const NWildcard::CCensor &censor,
+ const CHashOptions &options,
+ UString &errorInfo,
+ IHashCallbackUI *callback)
+{
+ CDirItems dirItems;
+
+ UInt64 numErrors = 0;
+ UInt64 totalBytes = 0;
+ if (options.StdInMode)
+ {
+ CDirItem di;
+ di.Size = (UInt64)(Int64)-1;
+ di.Attrib = 0;
+ di.MTime.dwLowDateTime = 0;
+ di.MTime.dwHighDateTime = 0;
+ di.CTime = di.ATime = di.MTime;
+ dirItems.Items.Add(di);
+ }
+ else
+ {
+ CEnumDirItemCallback_Hash enumCallback;
+ enumCallback.Callback = callback;
+ RINOK(callback->StartScanning());
+ dirItems.ScanAltStreams = options.AltStreamsMode;
+ HRESULT res = EnumerateItems(censor,
+ options.PathMode,
+ UString(),
+ dirItems, &enumCallback);
+ totalBytes = dirItems.TotalSize;
+ FOR_VECTOR (i, dirItems.ErrorPaths)
+ {
+ RINOK(callback->CanNotFindError(fs2us(dirItems.ErrorPaths[i]), dirItems.ErrorCodes[i]));
+ }
+ numErrors = dirItems.ErrorPaths.Size();
+ if (res != S_OK)
+ {
+ if (res != E_ABORT)
+ errorInfo = L"Scanning error";
+ return res;
+ }
+ RINOK(callback->FinishScanning());
+ }
+
+ unsigned i;
+ CHashBundle hb;
+ RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS options.Methods));
+ hb.Init();
+ hb.NumErrors = numErrors;
+
+ if (options.StdInMode)
+ {
+ RINOK(callback->SetNumFiles(1));
+ }
+ else
+ {
+ RINOK(callback->SetTotal(totalBytes));
+ }
+
+ const UInt32 kBufSize = 1 << 15;
+ CHashMidBuf buf;
+ if (!buf.Alloc(kBufSize))
+ return E_OUTOFMEMORY;
+
+ UInt64 completeValue = 0;
+
+ RINOK(callback->BeforeFirstFile(hb));
+
+ for (i = 0; i < dirItems.Items.Size(); i++)
+ {
+ CMyComPtr<ISequentialInStream> inStream;
+ UString path;
+ bool isDir = false;
+ bool isAltStream = false;
+ if (options.StdInMode)
+ {
+ inStream = new CStdInFileStream;
+ }
+ else
+ {
+ CInFileStream *inStreamSpec = new CInFileStream;
+ inStream = inStreamSpec;
+ const CDirItem &dirItem = dirItems.Items[i];
+ isDir = dirItem.IsDir();
+ isAltStream = dirItem.IsAltStream;
+ path = dirItems.GetLogPath(i);
+ if (!isDir)
+ {
+ UString phyPath = dirItems.GetPhyPath(i);
+ if (!inStreamSpec->OpenShared(us2fs(phyPath), options.OpenShareForWrite))
+ {
+ HRESULT res = callback->OpenFileError(phyPath, ::GetLastError());
+ hb.NumErrors++;
+ if (res != S_FALSE)
+ return res;
+ continue;
+ }
+ }
+ }
+ RINOK(callback->GetStream(path, isDir));
+ UInt64 fileSize = 0;
+
+ hb.InitForNewFile();
+ if (!isDir)
+ {
+ for (UInt32 step = 0;; step++)
+ {
+ if ((step & 0xFF) == 0)
+ RINOK(callback->SetCompleted(&completeValue));
+ UInt32 size;
+ RINOK(inStream->Read(buf, kBufSize, &size));
+ if (size == 0)
+ break;
+ hb.Update(buf, size);
+ fileSize += size;
+ completeValue += size;
+ }
+ }
+ hb.Final(isDir, isAltStream, path);
+ RINOK(callback->SetOperationResult(fileSize, hb, !isDir));
+ RINOK(callback->SetCompleted(&completeValue));
+ }
+ return callback->AfterLastFile(hb);
+}
+
+
+static inline char GetHex(Byte value)
+{
+ return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+}
+
+void AddHashHexToString(char *dest, const Byte *data, UInt32 size)
+{
+ dest[size * 2] = 0;
+ if (!data)
+ {
+ for (UInt32 i = 0; i < size; i++)
+ {
+ dest[0] = ' ';
+ dest[1] = ' ';
+ dest += 2;
+ }
+ return;
+ }
+ int step = 2;
+ if (size <= 8)
+ {
+ step = -2;
+ dest += size * 2 - 2;
+ }
+ for (UInt32 i = 0; i < size; i++)
+ {
+ Byte b = data[i];
+ dest[0] = GetHex((Byte)((b >> 4) & 0xF));
+ dest[1] = GetHex((Byte)(b & 0xF));
+ dest += step;
+ }
+}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/HashCalc.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/HashCalc.h
new file mode 100644
index 000000000..68e2404cc
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/HashCalc.h
@@ -0,0 +1,107 @@
+// HashCalc.h
+
+#ifndef __HASH_CALC_H
+#define __HASH_CALC_H
+
+#include "../../../Common/Wildcard.h"
+
+#include "../../Common/CreateCoder.h"
+#include "../../Common/MethodProps.h"
+
+#include "Property.h"
+
+const unsigned k_HashCalc_DigestSize_Max = 64;
+
+const unsigned k_HashCalc_NumGroups = 4;
+
+enum
+{
+ k_HashCalc_Index_Current,
+ k_HashCalc_Index_DataSum,
+ k_HashCalc_Index_NamesSum,
+ k_HashCalc_Index_StreamsSum
+};
+
+struct CHasherState
+{
+ CMyComPtr<IHasher> Hasher;
+ UString Name;
+ UInt32 DigestSize;
+ Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max];
+};
+
+struct IHashCalc
+{
+ virtual void InitForNewFile() = 0;
+ virtual void Update(const void *data, UInt32 size) = 0;
+ virtual void SetSize(UInt64 size) = 0;
+ virtual void Final(bool isDir, bool isAltStream, const UString &path) = 0;
+};
+
+struct CHashBundle: public IHashCalc
+{
+ CObjectVector<CHasherState> Hashers;
+
+ UInt64 NumFiles;
+ UInt64 NumDirs;
+ UInt64 NumAltStreams;
+ UInt64 FilesSize;
+ UInt64 AltStreamsSize;
+ UInt64 NumErrors;
+
+ UInt64 CurSize;
+
+ HRESULT SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &methods);
+
+ void Init()
+ {
+ NumFiles = NumDirs = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0;
+ }
+
+ void InitForNewFile();
+ void Update(const void *data, UInt32 size);
+ void SetSize(UInt64 size);
+ void Final(bool isDir, bool isAltStream, const UString &path);
+};
+
+#define INTERFACE_IHashCallbackUI(x) \
+ virtual HRESULT StartScanning() x; \
+ virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, bool isDir) x; \
+ virtual HRESULT CanNotFindError(const wchar_t *name, DWORD systemError) x; \
+ virtual HRESULT FinishScanning() x; \
+ virtual HRESULT SetNumFiles(UInt64 numFiles) x; \
+ virtual HRESULT SetTotal(UInt64 size) x; \
+ virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \
+ virtual HRESULT CheckBreak() x; \
+ virtual HRESULT BeforeFirstFile(const CHashBundle &hb) x; \
+ virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x; \
+ virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError) x; \
+ virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x; \
+ virtual HRESULT AfterLastFile(const CHashBundle &hb) x; \
+
+struct IHashCallbackUI
+{
+ INTERFACE_IHashCallbackUI(=0)
+};
+
+struct CHashOptions
+{
+ UStringVector Methods;
+ bool OpenShareForWrite;
+ bool StdInMode;
+ bool AltStreamsMode;
+ NWildcard::ECensorPathMode PathMode;
+
+ CHashOptions(): StdInMode(false), OpenShareForWrite(false), AltStreamsMode(false), PathMode(NWildcard::k_RelatPath) {};
+};
+
+HRESULT HashCalc(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const NWildcard::CCensor &censor,
+ const CHashOptions &options,
+ UString &errorInfo,
+ IHashCallbackUI *callback);
+
+void AddHashHexToString(char *dest, const Byte *data, UInt32 size);
+
+#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/IFileExtractCallback.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/IFileExtractCallback.h
index e8dcdce5f..7bb852795 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/IFileExtractCallback.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/IFileExtractCallback.h
@@ -1,9 +1,10 @@
// IFileExtractCallback.h
-#ifndef __IFILEEXTRACTCALLBACK_H
-#define __IFILEEXTRACTCALLBACK_H
+#ifndef __I_FILE_EXTRACT_CALLBACK_H
+#define __I_FILE_EXTRACT_CALLBACK_H
+
+#include "../../../Common/MyString.h"
-#include "Common/MyString.h"
#include "../../IDecl.h"
namespace NOverwriteAnswer
@@ -35,12 +36,37 @@ struct IExtractCallbackUI: IFolderArchiveExtractCallback
{
virtual HRESULT BeforeOpen(const wchar_t *name) = 0;
virtual HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted) = 0;
+ virtual HRESULT SetError(int level, const wchar_t *name,
+ UInt32 errorFlags, const wchar_t *errors,
+ UInt32 warningFlags, const wchar_t *warnings) = 0;
virtual HRESULT ThereAreNoFiles() = 0;
virtual HRESULT ExtractResult(HRESULT result) = 0;
+ virtual HRESULT OpenTypeWarning(const wchar_t *name, const wchar_t *okType, const wchar_t *errorType) = 0;
#ifndef _NO_CRYPTO
virtual HRESULT SetPassword(const UString &password) = 0;
#endif
};
+
+#define INTERFACE_IGetProp(x) \
+ STDMETHOD(GetProp)(PROPID propID, PROPVARIANT *value) x; \
+
+DECL_INTERFACE_SUB(IGetProp, IUnknown, 0x01, 0x20)
+{
+ INTERFACE_IGetProp(PURE)
+};
+
+#define INTERFACE_IFolderExtractToStreamCallback(x) \
+ STDMETHOD(UseExtractToStream)(Int32 *res) x; \
+ STDMETHOD(GetStream7)(const wchar_t *name, Int32 isDir, ISequentialOutStream **outStream, Int32 askExtractMode, IGetProp *getProp) x; \
+ STDMETHOD(PrepareOperation7)(Int32 askExtractMode) x; \
+ STDMETHOD(SetOperationResult7)(Int32 resultEOperationResult, bool encrypted) x; \
+
+DECL_INTERFACE_SUB(IFolderExtractToStreamCallback, IUnknown, 0x01, 0x30)
+{
+ INTERFACE_IFolderExtractToStreamCallback(PURE)
+};
+
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/LoadCodecs.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/LoadCodecs.cpp
index 171b7c104..09c79147d 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/LoadCodecs.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/LoadCodecs.cpp
@@ -2,18 +2,27 @@
#include "StdAfx.h"
-#include "LoadCodecs.h"
+#include "../../../../C/7zVersion.h"
#include "../../../Common/MyCom.h"
+#include "../../../Common/StringToInt.h"
+#include "../../../Common/StringConvert.h"
+
+#include "../../../Windows/PropVariant.h"
+
+#include "LoadCodecs.h"
+
+using namespace NWindows;
+
#ifdef NEW_FOLDER_INTERFACE
#include "../../../Common/StringToInt.h"
#endif
-#include "../../../Windows/PropVariant.h"
#include "../../ICoder.h"
#include "../../Common/RegisterArc.h"
#ifdef EXTERNAL_CODECS
+
#include "../../../Windows/FileFind.h"
#include "../../../Windows/DLL.h"
#ifdef NEW_FOLDER_INTERFACE
@@ -22,106 +31,169 @@ static const UINT kIconTypesResId = 100;
#endif
#ifdef _WIN32
-#include "Windows/Registry.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/Registry.h"
#else
-#include "Common/StringConvert.h"
+#include "../../../Common/StringConvert.h"
#endif
-using namespace NWindows;
using namespace NFile;
#ifdef _WIN32
extern HINSTANCE g_hInstance;
#endif
-static CSysString GetLibraryFolderPrefix()
-{
- #ifdef _WIN32
- TCHAR fullPath[MAX_PATH + 1];
- ::GetModuleFileName(g_hInstance, fullPath, MAX_PATH);
- CSysString path = fullPath;
- int pos = path.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
- return path.Left(pos + 1);
- #else
- const char *p7zip_home_dir = getenv("P7ZIP_HOME_DIR");
- if (p7zip_home_dir == 0) p7zip_home_dir="./";
-#ifdef _UNICODE
- return MultiByteToUnicodeString(p7zip_home_dir);
-#else
- return p7zip_home_dir;
-#endif
- #endif
-}
-
-#define kCodecsFolderName TEXT("Codecs")
-#define kFormatsFolderName TEXT("Formats")
-static const TCHAR *kMainDll = TEXT("7z.dll");
+#define kCodecsFolderName FTEXT("Codecs")
+#define kFormatsFolderName FTEXT("Formats")
+static CFSTR kMainDll = FTEXT("7z.dll");
#ifdef _WIN32
+
static LPCTSTR kRegistryPath = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-zip");
-static LPCTSTR kProgramPathValue = TEXT("Path");
-static bool ReadPathFromRegistry(HKEY baseKey, CSysString &path)
+static LPCWSTR kProgramPathValue = L"Path";
+static LPCWSTR kProgramPath2Value = L"Path"
+ #ifdef _WIN64
+ L"64";
+ #else
+ L"32";
+ #endif
+
+static bool ReadPathFromRegistry(HKEY baseKey, LPCWSTR value, FString &path)
{
NRegistry::CKey key;
- if(key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS)
- if (key.QueryValue(kProgramPathValue, path) == ERROR_SUCCESS)
+ if (key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS)
+ {
+ UString pathU;
+ if (key.QueryValue(value, pathU) == ERROR_SUCCESS)
{
+ path = us2fs(pathU);
NName::NormalizeDirPathPrefix(path);
- return true;
+ return NFind::DoesFileExist(path + kMainDll);
}
+ }
return false;
}
-#endif
+#endif // _WIN32
+
+#endif // EXTERNAL_CODECS
+
-CSysString GetBaseFolderPrefixFromRegistry()
+static const unsigned kNumArcsMax = 48;
+static unsigned g_NumArcs = 0;
+static const CArcInfo *g_Arcs[kNumArcsMax];
+
+void RegisterArc(const CArcInfo *arcInfo) throw()
{
- CSysString moduleFolderPrefix = GetLibraryFolderPrefix();
-#ifdef _UNICODE
- NFind::CFileInfoW fi;
-#else
- NFind::CFileInfo fi;
-#endif
- if (NFind::FindFile(moduleFolderPrefix + kMainDll, fi))
- if (!fi.IsDir())
- return moduleFolderPrefix;
- if (NFind::FindFile(moduleFolderPrefix + kCodecsFolderName, fi))
- if (fi.IsDir())
- return moduleFolderPrefix;
- if (NFind::FindFile(moduleFolderPrefix + kFormatsFolderName, fi))
- if (fi.IsDir())
- return moduleFolderPrefix;
+ if (g_NumArcs < kNumArcsMax)
+ {
+ g_Arcs[g_NumArcs] = arcInfo;
+ g_NumArcs++;
+ }
+}
+
+static void SplitString(const UString &srcString, UStringVector &destStrings)
+{
+ destStrings.Clear();
+ UString s;
+ unsigned len = srcString.Len();
+ if (len == 0)
+ return;
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = srcString[i];
+ if (c == L' ')
+ {
+ if (!s.IsEmpty())
+ {
+ destStrings.Add(s);
+ s.Empty();
+ }
+ }
+ else
+ s += c;
+ }
+ if (!s.IsEmpty())
+ destStrings.Add(s);
+}
+
+int CArcInfoEx::FindExtension(const UString &ext) const
+{
+ FOR_VECTOR (i, Exts)
+ if (ext.IsEqualToNoCase(Exts[i].Ext))
+ return i;
+ return -1;
+}
+
+void CArcInfoEx::AddExts(const UString &ext, const UString &addExt)
+{
+ UStringVector exts, addExts;
+ SplitString(ext, exts);
+ SplitString(addExt, addExts);
+ FOR_VECTOR (i, exts)
+ {
+ CArcExtInfo extInfo;
+ extInfo.Ext = exts[i];
+ if (i < addExts.Size())
+ {
+ extInfo.AddExt = addExts[i];
+ if (extInfo.AddExt == L"*")
+ extInfo.AddExt.Empty();
+ }
+ Exts.Add(extInfo);
+ }
+}
+
+#ifndef _SFX
+
+static bool ParseSignatures(const Byte *data, unsigned size, CObjectVector<CByteBuffer> &signatures)
+{
+ signatures.Clear();
+ while (size > 0)
+ {
+ unsigned len = *data++;
+ size--;
+ if (len > size)
+ return false;
+ signatures.AddNew().CopyFrom(data, len);
+ data += len;
+ size -= len;
+ }
+ return true;
+}
+
+#endif // _SFX
+
+#ifdef EXTERNAL_CODECS
+
+static FString GetBaseFolderPrefixFromRegistry()
+{
+ FString moduleFolderPrefix = NDLL::GetModuleDirPrefix();
#ifdef _WIN32
if (!NFind::DoesFileExist(moduleFolderPrefix + kMainDll) &&
!NFind::DoesDirExist(moduleFolderPrefix + kCodecsFolderName) &&
!NFind::DoesDirExist(moduleFolderPrefix + kFormatsFolderName))
{
- CSysString path;
- if (ReadPathFromRegistry(HKEY_CURRENT_USER, path))
- return path;
- if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path))
- return path;
+ FString path;
+ if (ReadPathFromRegistry(HKEY_CURRENT_USER, kProgramPath2Value, path)) return path;
+ if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, kProgramPath2Value, path)) return path;
+ if (ReadPathFromRegistry(HKEY_CURRENT_USER, kProgramPathValue, path)) return path;
+ if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, kProgramPathValue, path)) return path;
}
#endif
return moduleFolderPrefix;
}
-typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods);
-typedef UInt32 (WINAPI *GetNumberOfFormatsFunc)(UInt32 *numFormats);
-typedef UInt32 (WINAPI *GetHandlerPropertyFunc)(PROPID propID, PROPVARIANT *value);
-typedef UInt32 (WINAPI *GetHandlerPropertyFunc2)(UInt32 index, PROPID propID, PROPVARIANT *value);
-typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *iid, void **outObject);
-typedef UInt32 (WINAPI *SetLargePageModeFunc)();
-
-
-static HRESULT GetCoderClass(GetMethodPropertyFunc getMethodProperty, UInt32 index,
+static HRESULT GetCoderClass(Func_GetMethodProperty getMethodProperty, UInt32 index,
PROPID propId, CLSID &clsId, bool &isAssigned)
{
- NWindows::NCOM::CPropVariant prop;
+ NCOM::CPropVariant prop;
isAssigned = false;
RINOK(getMethodProperty(index, propId, &prop));
if (prop.vt == VT_BSTR)
{
+ if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID))
+ return E_FAIL;
isAssigned = true;
clsId = *(const GUID *)prop.bstrVal;
}
@@ -133,34 +205,48 @@ static HRESULT GetCoderClass(GetMethodPropertyFunc getMethodProperty, UInt32 ind
HRESULT CCodecs::LoadCodecs()
{
CCodecLib &lib = Libs.Back();
- lib.GetMethodProperty = (GetMethodPropertyFunc)lib.Lib.GetProc("GetMethodProperty");
- if (lib.GetMethodProperty == NULL)
- return S_OK;
-
- UInt32 numMethods = 1;
- GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)lib.Lib.GetProc("GetNumberOfMethods");
- if (getNumberOfMethodsFunc != NULL)
+ lib.GetMethodProperty = (Func_GetMethodProperty)lib.Lib.GetProc("GetMethodProperty");
+ if (lib.GetMethodProperty)
{
- RINOK(getNumberOfMethodsFunc(&numMethods));
+ UInt32 numMethods = 1;
+ Func_GetNumberOfMethods getNumberOfMethodsFunc = (Func_GetNumberOfMethods)lib.Lib.GetProc("GetNumberOfMethods");
+ if (getNumberOfMethodsFunc)
+ {
+ RINOK(getNumberOfMethodsFunc(&numMethods));
+ }
+ for (UInt32 i = 0; i < numMethods; i++)
+ {
+ CDllCodecInfo info;
+ info.LibIndex = Libs.Size() - 1;
+ info.CodecIndex = i;
+ RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned));
+ RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned));
+ Codecs.Add(info);
+ }
}
- for(UInt32 i = 0; i < numMethods; i++)
+ Func_GetHashers getHashers = (Func_GetHashers)lib.Lib.GetProc("GetHashers");
+ if (getHashers)
{
- CDllCodecInfo info;
- info.LibIndex = Libs.Size() - 1;
- info.CodecIndex = i;
-
- RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned));
- RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned));
-
- Codecs.Add(info);
+ RINOK(getHashers(&lib.Hashers));
+ if (lib.Hashers)
+ {
+ UInt32 numMethods = lib.Hashers->GetNumHashers();
+ for (UInt32 i = 0; i < numMethods; i++)
+ {
+ CDllHasherInfo info;
+ info.LibIndex = Libs.Size() - 1;
+ info.HasherIndex = i;
+ Hashers.Add(info);
+ }
+ }
}
return S_OK;
}
-static HRESULT ReadProp(
- GetHandlerPropertyFunc getProp,
- GetHandlerPropertyFunc2 getProp2,
+static HRESULT GetProp(
+ Func_GetHandlerProperty getProp,
+ Func_GetHandlerProperty2 getProp2,
UInt32 index, PROPID propID, NCOM::CPropVariant &prop)
{
if (getProp2)
@@ -168,13 +254,14 @@ static HRESULT ReadProp(
return getProp(propID, &prop);
}
-static HRESULT ReadBoolProp(
- GetHandlerPropertyFunc getProp,
- GetHandlerPropertyFunc2 getProp2,
+static HRESULT GetProp_Bool(
+ Func_GetHandlerProperty getProp,
+ Func_GetHandlerProperty2 getProp2,
UInt32 index, PROPID propID, bool &res)
{
+ res = false;
NCOM::CPropVariant prop;
- RINOK(ReadProp(getProp, getProp2, index, propID, prop));
+ RINOK(GetProp(getProp, getProp2, index, propID, prop));
if (prop.vt == VT_BOOL)
res = VARIANT_BOOLToBool(prop.boolVal);
else if (prop.vt != VT_EMPTY)
@@ -182,132 +269,150 @@ static HRESULT ReadBoolProp(
return S_OK;
}
-static HRESULT ReadStringProp(
- GetHandlerPropertyFunc getProp,
- GetHandlerPropertyFunc2 getProp2,
- UInt32 index, PROPID propID, UString &res)
+static HRESULT GetProp_UInt32(
+ Func_GetHandlerProperty getProp,
+ Func_GetHandlerProperty2 getProp2,
+ UInt32 index, PROPID propID, UInt32 &res, bool &defined)
{
+ res = 0;
+ defined = false;
NCOM::CPropVariant prop;
- RINOK(ReadProp(getProp, getProp2, index, propID, prop));
- if (prop.vt == VT_BSTR)
- res = prop.bstrVal;
+ RINOK(GetProp(getProp, getProp2, index, propID, prop));
+ if (prop.vt == VT_UI4)
+ {
+ res = prop.ulVal;
+ defined = true;
+ }
else if (prop.vt != VT_EMPTY)
return E_FAIL;
return S_OK;
}
-#endif
-
-static const unsigned int kNumArcsMax = 48;
-static unsigned int g_NumArcs = 0;
-static const CArcInfo *g_Arcs[kNumArcsMax];
-void RegisterArc(const CArcInfo *arcInfo)
+static HRESULT GetProp_String(
+ Func_GetHandlerProperty getProp,
+ Func_GetHandlerProperty2 getProp2,
+ UInt32 index, PROPID propID, UString &res)
{
- if (g_NumArcs < kNumArcsMax)
- g_Arcs[g_NumArcs++] = arcInfo;
+ res.Empty();
+ NCOM::CPropVariant prop;
+ RINOK(GetProp(getProp, getProp2, index, propID, prop));
+ if (prop.vt == VT_BSTR)
+ res = prop.bstrVal;
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
}
-static void SplitString(const UString &srcString, UStringVector &destStrings)
+static HRESULT GetProp_RawData(
+ Func_GetHandlerProperty getProp,
+ Func_GetHandlerProperty2 getProp2,
+ UInt32 index, PROPID propID, CByteBuffer &bb)
{
- destStrings.Clear();
- UString s;
- int len = srcString.Length();
- if (len == 0)
- return;
- for (int i = 0; i < len; i++)
+ bb.Free();
+ NCOM::CPropVariant prop;
+ RINOK(GetProp(getProp, getProp2, index, propID, prop));
+ if (prop.vt == VT_BSTR)
{
- wchar_t c = srcString[i];
- if (c == L' ')
- {
- if (!s.IsEmpty())
- {
- destStrings.Add(s);
- s.Empty();
- }
- }
- else
- s += c;
+ UINT len = ::SysStringByteLen(prop.bstrVal);
+ bb.CopyFrom((const Byte *)prop.bstrVal, len);
}
- if (!s.IsEmpty())
- destStrings.Add(s);
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
}
-void CArcInfoEx::AddExts(const wchar_t *ext, const wchar_t *addExt)
+static const UInt32 kArcFlagsPars[] =
{
- UStringVector exts, addExts;
- if (ext != 0)
- SplitString(ext, exts);
- if (addExt != 0)
- SplitString(addExt, addExts);
- for (int i = 0; i < exts.Size(); i++)
- {
- CArcExtInfo extInfo;
- extInfo.Ext = exts[i];
- if (i < addExts.Size())
- {
- extInfo.AddExt = addExts[i];
- if (extInfo.AddExt == L"*")
- extInfo.AddExt.Empty();
- }
- Exts.Add(extInfo);
- }
-}
-
-#ifdef EXTERNAL_CODECS
+ NArchive::NHandlerPropID::kKeepName, NArcInfoFlags::kKeepName,
+ NArchive::NHandlerPropID::kAltStreams, NArcInfoFlags::kAltStreams,
+ NArchive::NHandlerPropID::kNtSecure, NArcInfoFlags::kNtSecure
+};
HRESULT CCodecs::LoadFormats()
{
const NDLL::CLibrary &lib = Libs.Back().Lib;
- GetHandlerPropertyFunc getProp = 0;
- GetHandlerPropertyFunc2 getProp2 = (GetHandlerPropertyFunc2)lib.GetProc("GetHandlerProperty2");
- if (getProp2 == NULL)
- {
- getProp = (GetHandlerPropertyFunc)lib.GetProc("GetHandlerProperty");
- if (getProp == NULL)
- return S_OK;
- }
+
+ Func_GetHandlerProperty getProp = NULL;
+ Func_GetHandlerProperty2 getProp2 = (Func_GetHandlerProperty2)lib.GetProc("GetHandlerProperty2");
+ Func_GetIsArc getIsArc = (Func_GetIsArc)lib.GetProc("GetIsArc");
UInt32 numFormats = 1;
- GetNumberOfFormatsFunc getNumberOfFormats = (GetNumberOfFormatsFunc)lib.GetProc("GetNumberOfFormats");
- if (getNumberOfFormats != NULL)
+
+ if (getProp2)
{
- RINOK(getNumberOfFormats(&numFormats));
+ Func_GetNumberOfFormats getNumberOfFormats = (Func_GetNumberOfFormats)lib.GetProc("GetNumberOfFormats");
+ if (getNumberOfFormats)
+ {
+ RINOK(getNumberOfFormats(&numFormats));
+ }
+ }
+ else
+ {
+ getProp = (Func_GetHandlerProperty)lib.GetProc("GetHandlerProperty");
+ if (!getProp)
+ return S_OK;
}
- if (getProp2 == NULL)
- numFormats = 1;
- for(UInt32 i = 0; i < numFormats; i++)
+ for (UInt32 i = 0; i < numFormats; i++)
{
CArcInfoEx item;
item.LibIndex = Libs.Size() - 1;
item.FormatIndex = i;
- RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kName, item.Name));
+ RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kName, item.Name));
- NCOM::CPropVariant prop;
- if (ReadProp(getProp, getProp2, i, NArchive::kClassID, prop) != S_OK)
- continue;
- if (prop.vt != VT_BSTR)
- continue;
- item.ClassID = *(const GUID *)prop.bstrVal;
- prop.Clear();
+ {
+ NCOM::CPropVariant prop;
+ if (GetProp(getProp, getProp2, i, NArchive::NHandlerPropID::kClassID, prop) != S_OK)
+ continue;
+ if (prop.vt != VT_BSTR)
+ continue;
+ if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID))
+ return E_FAIL;
+ item.ClassID = *(const GUID *)prop.bstrVal;
+ prop.Clear();
+ }
UString ext, addExt;
- RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kExtension, ext));
- RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kAddExtension, addExt));
+ RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kExtension, ext));
+ RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kAddExtension, addExt));
item.AddExts(ext, addExt);
- ReadBoolProp(getProp, getProp2, i, NArchive::kUpdate, item.UpdateEnabled);
- if (item.UpdateEnabled)
- ReadBoolProp(getProp, getProp2, i, NArchive::kKeepName, item.KeepName);
-
- if (ReadProp(getProp, getProp2, i, NArchive::kStartSignature, prop) == S_OK)
- if (prop.vt == VT_BSTR)
+ GetProp_Bool(getProp, getProp2, i, NArchive::NHandlerPropID::kUpdate, item.UpdateEnabled);
+ bool flags_Defined = false;
+ RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kFlags, item.Flags, flags_Defined));
+ item.NewInterface = flags_Defined;
+ if (!flags_Defined) // && item.UpdateEnabled
+ {
+ // support for DLL version before 9.31:
+ for (unsigned j = 0; j < ARRAY_SIZE(kArcFlagsPars); j += 2)
{
- UINT len = ::SysStringByteLen(prop.bstrVal);
- item.StartSignature.SetCapacity(len);
- memmove((Byte *)item.StartSignature, prop.bstrVal, len);
+ bool val = false;
+ GetProp_Bool(getProp, getProp2, i, kArcFlagsPars[j], val);
+ if (val)
+ item.Flags |= kArcFlagsPars[j + 1];
}
+ }
+
+ CByteBuffer sig;
+ RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kSignature, sig));
+ if (sig.Size() != 0)
+ item.Signatures.Add(sig);
+ else
+ {
+ RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kMultiSignature, sig));
+ ParseSignatures(sig, (unsigned)sig.Size(), item.Signatures);
+ }
+
+ bool signatureOffset_Defined;
+ RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kSignatureOffset, item.SignatureOffset, signatureOffset_Defined));
+
+ // bool version_Defined;
+ // RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kVersion, item.Version, version_Defined));
+
+ if (getIsArc)
+ getIsArc(i, &item.IsArcFunc);
+
Formats.Add(item);
}
return S_OK;
@@ -317,25 +422,26 @@ HRESULT CCodecs::LoadFormats()
void CCodecIcons::LoadIcons(HMODULE m)
{
#ifdef _WIN32
- UString iconTypes = MyLoadStringW(m, kIconTypesResId);
+ UString iconTypes;
+ MyLoadString(m, kIconTypesResId, iconTypes);
UStringVector pairs;
SplitString(iconTypes, pairs);
- for (int i = 0; i < pairs.Size(); i++)
+ FOR_VECTOR (i, pairs)
{
const UString &s = pairs[i];
int pos = s.Find(L':');
CIconPair iconPair;
iconPair.IconIndex = -1;
if (pos < 0)
- pos = s.Length();
+ pos = s.Len();
else
{
- UString num = s.Mid(pos + 1);
+ UString num = s.Ptr(pos + 1);
if (!num.IsEmpty())
{
const wchar_t *end;
- iconPair.IconIndex = (UInt32)ConvertStringToUInt64(num, &end);
- if (*end != L'\0')
+ iconPair.IconIndex = ConvertStringToUInt32(num, &end);
+ if (*end != 0)
continue;
}
}
@@ -349,10 +455,10 @@ bool CCodecIcons::FindIconIndex(const UString &ext, int &iconIndex) const
{
#ifdef _WIN32
iconIndex = -1;
- for (int i = 0; i < IconPairs.Size(); i++)
+ FOR_VECTOR (i, IconPairs)
{
const CIconPair &pair = IconPairs[i];
- if (ext.CompareNoCase(pair.Ext) == 0)
+ if (ext.IsEqualToNoCase(pair.Ext))
{
iconIndex = pair.IconIndex;
return true;
@@ -361,7 +467,8 @@ bool CCodecIcons::FindIconIndex(const UString &ext, int &iconIndex) const
#endif // #ifdef _WIN32
return false;
}
-#endif
+
+#endif // EXTERNAL_CODECS
#ifdef _7ZIP_LARGE_PAGES
extern "C"
@@ -370,7 +477,7 @@ extern "C"
}
#endif
-HRESULT CCodecs::LoadDll(const CSysString &dllPath, bool needCheckDll)
+HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll)
{
#ifdef _WIN32
if (needCheckDll)
@@ -382,9 +489,7 @@ HRESULT CCodecs::LoadDll(const CSysString &dllPath, bool needCheckDll)
#endif
Libs.Add(CCodecLib());
CCodecLib &lib = Libs.Back();
- #ifdef NEW_FOLDER_INTERFACE
lib.Path = dllPath;
- #endif
bool used = false;
HRESULT res = S_OK;
if (lib.Lib.Load(dllPath))
@@ -396,23 +501,31 @@ HRESULT CCodecs::LoadDll(const CSysString &dllPath, bool needCheckDll)
#ifdef _7ZIP_LARGE_PAGES
if (g_LargePageSize != 0)
{
- SetLargePageModeFunc setLargePageMode = (SetLargePageModeFunc)lib.Lib.GetProc("SetLargePageMode");
- if (setLargePageMode != 0)
+ Func_SetLargePageMode setLargePageMode = (Func_SetLargePageMode)lib.Lib.GetProc("SetLargePageMode");
+ if (setLargePageMode)
setLargePageMode();
}
#endif
- lib.CreateObject = (CreateObjectFunc)lib.Lib.GetProc("CreateObject");
- if (lib.CreateObject != 0)
+ if (CaseSensitiveChange)
{
- int startSize = Codecs.Size();
+ Func_SetCaseSensitive setCaseSensitive = (Func_SetCaseSensitive)lib.Lib.GetProc("SetCaseSensitive");
+ if (setCaseSensitive)
+ setCaseSensitive(CaseSensitive ? 1 : 0);
+ }
+
+ lib.CreateObject = (Func_CreateObject)lib.Lib.GetProc("CreateObject");
+ if (lib.CreateObject)
+ {
+ unsigned startSize = Codecs.Size() + Hashers.Size();
res = LoadCodecs();
- used = (Codecs.Size() != startSize);
+ used = (startSize != Codecs.Size() + Hashers.Size());
if (res == S_OK)
{
startSize = Formats.Size();
res = LoadFormats();
- used = used || (Formats.Size() != startSize);
+ if (startSize != Formats.Size())
+ used = true;
}
}
}
@@ -421,15 +534,10 @@ HRESULT CCodecs::LoadDll(const CSysString &dllPath, bool needCheckDll)
return res;
}
-HRESULT CCodecs::LoadDllsFromFolder(const CSysString &folderPrefix)
+HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPrefix)
{
-#ifdef _UNICODE
- NFile::NFind::CEnumeratorW enumerator(folderPrefix + CSysString(TEXT("*")));
- NFile::NFind::CFileInfoW fi;
-#else
- NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
+ NFile::NFind::CEnumerator enumerator(folderPrefix + FCHAR_ANY_MASK);
NFile::NFind::CFileInfo fi;
-#endif
while (enumerator.Next(fi))
{
if (fi.IsDir())
@@ -441,48 +549,65 @@ HRESULT CCodecs::LoadDllsFromFolder(const CSysString &folderPrefix)
#endif
-#ifndef _SFX
-static inline void SetBuffer(CByteBuffer &bb, const Byte *data, int size)
-{
- bb.SetCapacity(size);
- memmove((Byte *)bb, data, size);
-}
-#endif
-
HRESULT CCodecs::Load()
{
#ifdef NEW_FOLDER_INTERFACE
#ifdef _WIN32
- InternalIcons.LoadIcons(g_hInstance);
+ InternalIcons.LoadIcons(g_hInstance);
#endif
#endif
Formats.Clear();
+
#ifdef EXTERNAL_CODECS
- Codecs.Clear();
+ Codecs.Clear();
+ Hashers.Clear();
#endif
+
for (UInt32 i = 0; i < g_NumArcs; i++)
{
const CArcInfo &arc = *g_Arcs[i];
CArcInfoEx item;
- item.Name = arc.Name;
+
+ item.Name.SetFromAscii(arc.Name);
item.CreateInArchive = arc.CreateInArchive;
- item.CreateOutArchive = arc.CreateOutArchive;
- item.AddExts(arc.Ext, arc.AddExt);
- item.UpdateEnabled = (arc.CreateOutArchive != 0);
- item.KeepName = arc.KeepName;
+ item.IsArcFunc = arc.IsArc;
+ item.Flags = arc.Flags;
+
+ {
+ UString e, ae;
+ if (arc.Ext)
+ e.SetFromAscii(arc.Ext);
+ if (arc.AddExt)
+ ae.SetFromAscii(arc.AddExt);
+ item.AddExts(e, ae);
+ }
#ifndef _SFX
- SetBuffer(item.StartSignature, arc.Signature, arc.SignatureSize);
+
+ item.CreateOutArchive = arc.CreateOutArchive;
+ item.UpdateEnabled = (arc.CreateOutArchive != NULL);
+ item.SignatureOffset = arc.SignatureOffset;
+ // item.Version = MY_VER_MIX;
+ item.NewInterface = true;
+
+ if (arc.IsMultiSignature())
+ ParseSignatures(arc.Signature, arc.SignatureSize, item.Signatures);
+ else
+ item.Signatures.AddNew().CopyFrom(arc.Signature, arc.SignatureSize);
+
#endif
+
Formats.Add(item);
}
+
#ifdef EXTERNAL_CODECS
- const CSysString baseFolder = GetBaseFolderPrefixFromRegistry();
- RINOK(LoadDll(baseFolder + kMainDll, false));
- RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName TEXT(STRING_PATH_SEPARATOR)));
- RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName TEXT(STRING_PATH_SEPARATOR)));
+ const FString baseFolder = GetBaseFolderPrefixFromRegistry();
+ RINOK(LoadDll(baseFolder + kMainDll, false));
+ RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName FSTRING_PATH_SEPARATOR));
+ RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName FSTRING_PATH_SEPARATOR));
#endif
+
return S_OK;
}
@@ -490,17 +615,22 @@ HRESULT CCodecs::Load()
int CCodecs::FindFormatForArchiveName(const UString &arcPath) const
{
- int slashPos1 = arcPath.ReverseFind(WCHAR_PATH_SEPARATOR);
- int slashPos2 = arcPath.ReverseFind(L'.');
+ int slashPos = arcPath.ReverseFind(WCHAR_PATH_SEPARATOR);
int dotPos = arcPath.ReverseFind(L'.');
- if (dotPos < 0 || dotPos < slashPos1 || dotPos < slashPos2)
+ if (dotPos < 0 || dotPos < slashPos)
+ return -1;
+ const UString ext = arcPath.Ptr(dotPos + 1);
+ if (ext.IsEmpty())
return -1;
- UString ext = arcPath.Mid(dotPos + 1);
- for (int i = 0; i < Formats.Size(); i++)
+ if (ext.IsEqualToNoCase(L"exe"))
+ return -1;
+ FOR_VECTOR (i, Formats)
{
const CArcInfoEx &arc = Formats[i];
+ /*
if (!arc.UpdateEnabled)
continue;
+ */
if (arc.FindExtension(ext) >= 0)
return i;
}
@@ -511,7 +641,7 @@ int CCodecs::FindFormatForExtension(const UString &ext) const
{
if (ext.IsEmpty())
return -1;
- for (int i = 0; i < Formats.Size(); i++)
+ FOR_VECTOR (i, Formats)
if (Formats[i].FindExtension(ext) >= 0)
return i;
return -1;
@@ -519,8 +649,8 @@ int CCodecs::FindFormatForExtension(const UString &ext) const
int CCodecs::FindFormatForArchiveType(const UString &arcType) const
{
- for (int i = 0; i < Formats.Size(); i++)
- if (Formats[i].Name.CompareNoCase(arcType) == 0)
+ FOR_VECTOR (i, Formats)
+ if (Formats[i].Name.IsEqualToNoCase(arcType))
return i;
return -1;
}
@@ -528,12 +658,14 @@ int CCodecs::FindFormatForArchiveType(const UString &arcType) const
bool CCodecs::FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const
{
formatIndices.Clear();
- for (int pos = 0; pos < arcType.Length();)
+ for (unsigned pos = 0; pos < arcType.Len();)
{
int pos2 = arcType.Find('.', pos);
if (pos2 < 0)
- pos2 = arcType.Length();
+ pos2 = arcType.Len();
const UString name = arcType.Mid(pos, pos2 - pos);
+ if (name.IsEmpty())
+ return false;
int index = FindFormatForArchiveType(name);
if (index < 0 && name != L"*")
{
@@ -546,24 +678,39 @@ bool CCodecs::FindFormatForArchiveType(const UString &arcType, CIntVector &forma
return true;
}
-#endif
+#endif // _SFX
+
#ifdef EXTERNAL_CODECS
+// #define EXPORT_CODECS
+
#ifdef EXPORT_CODECS
-extern unsigned int g_NumCodecs;
+
+extern unsigned g_NumCodecs;
STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject);
STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value);
-// STDAPI GetNumberOfMethods(UInt32 *numCodecs);
-#endif
+#define NUM_EXPORT_CODECS g_NumCodecs
+
+extern unsigned g_NumHashers;
+STDAPI CreateHasher(UInt32 index, IHasher **hasher);
+STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value);
+#define NUM_EXPORT_HASHERS g_NumHashers
+
+#else // EXPORT_CODECS
+
+#define NUM_EXPORT_CODECS 0
+#define NUM_EXPORT_HASHERS 0
+
+#endif // EXPORT_CODECS
STDMETHODIMP CCodecs::GetNumberOfMethods(UInt32 *numMethods)
{
- *numMethods =
- #ifdef EXPORT_CODECS
- g_NumCodecs +
- #endif
- Codecs.Size();
+ *numMethods = NUM_EXPORT_CODECS
+ #ifdef EXTERNAL_CODECS
+ + Codecs.Size()
+ #endif
+ ;
return S_OK;
}
@@ -574,27 +721,23 @@ STDMETHODIMP CCodecs::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *valu
return GetMethodProperty(index, propID, value);
#endif
- const CDllCodecInfo &ci = Codecs[index
- #ifdef EXPORT_CODECS
- - g_NumCodecs
- #endif
- ];
+ #ifdef EXTERNAL_CODECS
+ const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS];
- if (propID == NMethodPropID::kDecoderIsAssigned)
- {
- NWindows::NCOM::CPropVariant propVariant;
- propVariant = ci.DecoderIsAssigned;
- propVariant.Detach(value);
- return S_OK;
- }
- if (propID == NMethodPropID::kEncoderIsAssigned)
+ if (propID == NMethodPropID::kDecoderIsAssigned ||
+ propID == NMethodPropID::kEncoderIsAssigned)
{
- NWindows::NCOM::CPropVariant propVariant;
- propVariant = ci.EncoderIsAssigned;
- propVariant.Detach(value);
+ NCOM::CPropVariant prop;
+ prop = (propID == NMethodPropID::kDecoderIsAssigned) ?
+ ci.DecoderIsAssigned :
+ ci.EncoderIsAssigned;
+ prop.Detach(value);
return S_OK;
}
return Libs[ci.LibIndex].GetMethodProperty(ci.CodecIndex, propID, value);
+ #else
+ return E_FAIL;
+ #endif
}
STDMETHODIMP CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder)
@@ -603,14 +746,14 @@ STDMETHODIMP CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder)
if (index < g_NumCodecs)
return CreateCoder2(false, index, iid, coder);
#endif
- const CDllCodecInfo &ci = Codecs[index
- #ifdef EXPORT_CODECS
- - g_NumCodecs
- #endif
- ];
+ #ifdef EXTERNAL_CODECS
+ const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS];
if (ci.DecoderIsAssigned)
return Libs[ci.LibIndex].CreateObject(&ci.Decoder, iid, (void **)coder);
return S_OK;
+ #else
+ return E_FAIL;
+ #endif
}
STDMETHODIMP CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder)
@@ -619,35 +762,53 @@ STDMETHODIMP CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder)
if (index < g_NumCodecs)
return CreateCoder2(true, index, iid, coder);
#endif
- const CDllCodecInfo &ci = Codecs[index
- #ifdef EXPORT_CODECS
- - g_NumCodecs
- #endif
- ];
+ #ifdef EXTERNAL_CODECS
+ const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS];
if (ci.EncoderIsAssigned)
return Libs[ci.LibIndex].CreateObject(&ci.Encoder, iid, (void **)coder);
return S_OK;
+ #else
+ return E_FAIL;
+ #endif
}
-HRESULT CCodecs::CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const
+
+STDMETHODIMP_(UInt32) CCodecs::GetNumHashers()
{
- for (int i = 0; i < Codecs.Size(); i++)
- {
- const CDllCodecInfo &codec = Codecs[i];
- if (encode && !codec.EncoderIsAssigned || !encode && !codec.DecoderIsAssigned)
- continue;
- const CCodecLib &lib = Libs[codec.LibIndex];
- UString res;
- NWindows::NCOM::CPropVariant prop;
- RINOK(lib.GetMethodProperty(codec.CodecIndex, NMethodPropID::kName, &prop));
- if (prop.vt == VT_BSTR)
- res = prop.bstrVal;
- else if (prop.vt != VT_EMPTY)
- continue;
- if (name.CompareNoCase(res) == 0)
- return lib.CreateObject(encode ? &codec.Encoder : &codec.Decoder, &IID_ICompressCoder, (void **)&coder);
- }
- return CLASS_E_CLASSNOTAVAILABLE;
+ return NUM_EXPORT_HASHERS
+ #ifdef EXTERNAL_CODECS
+ + Hashers.Size()
+ #endif
+ ;
+}
+
+STDMETHODIMP CCodecs::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ #ifdef EXPORT_CODECS
+ if (index < g_NumHashers)
+ return ::GetHasherProp(index, propID, value);
+ #endif
+
+ #ifdef EXTERNAL_CODECS
+ const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS];
+ return Libs[ci.LibIndex].Hashers->GetHasherProp(ci.HasherIndex, propID, value);
+ #else
+ return E_FAIL;
+ #endif
+}
+
+STDMETHODIMP CCodecs::CreateHasher(UInt32 index, IHasher **hasher)
+{
+ #ifdef EXPORT_CODECS
+ if (index < g_NumHashers)
+ return CreateHasher(index, hasher);
+ #endif
+ #ifdef EXTERNAL_CODECS
+ const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS];
+ return Libs[ci.LibIndex].Hashers->CreateHasher(ci.HasherIndex, hasher);
+ #else
+ return E_FAIL;
+ #endif
}
int CCodecs::GetCodecLibIndex(UInt32 index)
@@ -657,11 +818,21 @@ int CCodecs::GetCodecLibIndex(UInt32 index)
return -1;
#endif
#ifdef EXTERNAL_CODECS
- const CDllCodecInfo &ci = Codecs[index
- #ifdef EXPORT_CODECS
- - g_NumCodecs
- #endif
- ];
+ const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS];
+ return ci.LibIndex;
+ #else
+ return -1;
+ #endif
+}
+
+int CCodecs::GetHasherLibIndex(UInt32 index)
+{
+ #ifdef EXPORT_CODECS
+ if (index < g_NumHashers)
+ return -1;
+ #endif
+ #ifdef EXTERNAL_CODECS
+ const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS];
return ci.LibIndex;
#else
return -1;
@@ -673,7 +844,7 @@ bool CCodecs::GetCodecEncoderIsAssigned(UInt32 index)
#ifdef EXPORT_CODECS
if (index < g_NumCodecs)
{
- NWindows::NCOM::CPropVariant prop;
+ NCOM::CPropVariant prop;
if (GetProperty(index, NMethodPropID::kEncoder, &prop) == S_OK)
if (prop.vt != VT_EMPTY)
return true;
@@ -681,11 +852,7 @@ bool CCodecs::GetCodecEncoderIsAssigned(UInt32 index)
}
#endif
#ifdef EXTERNAL_CODECS
- const CDllCodecInfo &ci = Codecs[index
- #ifdef EXPORT_CODECS
- - g_NumCodecs
- #endif
- ];
+ const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS];
return ci.EncoderIsAssigned;
#else
return false;
@@ -694,8 +861,7 @@ bool CCodecs::GetCodecEncoderIsAssigned(UInt32 index)
HRESULT CCodecs::GetCodecId(UInt32 index, UInt64 &id)
{
- UString s;
- NWindows::NCOM::CPropVariant prop;
+ NCOM::CPropVariant prop;
RINOK(GetProperty(index, NMethodPropID::kID, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
@@ -706,11 +872,39 @@ HRESULT CCodecs::GetCodecId(UInt32 index, UInt64 &id)
UString CCodecs::GetCodecName(UInt32 index)
{
UString s;
- NWindows::NCOM::CPropVariant prop;
+ NCOM::CPropVariant prop;
if (GetProperty(index, NMethodPropID::kName, &prop) == S_OK)
if (prop.vt == VT_BSTR)
s = prop.bstrVal;
return s;
}
-#endif
+UInt64 CCodecs::GetHasherId(UInt32 index)
+{
+ NCOM::CPropVariant prop;
+ RINOK(GetHasherProp(index, NMethodPropID::kID, &prop));
+ if (prop.vt != VT_UI8)
+ return 0;
+ return prop.uhVal.QuadPart;
+}
+
+UString CCodecs::GetHasherName(UInt32 index)
+{
+ UString s;
+ NCOM::CPropVariant prop;
+ if (GetHasherProp(index, NMethodPropID::kName, &prop) == S_OK)
+ if (prop.vt == VT_BSTR)
+ s = prop.bstrVal;
+ return s;
+}
+
+UInt32 CCodecs::GetHasherDigestSize(UInt32 index)
+{
+ NCOM::CPropVariant prop;
+ RINOK(GetHasherProp(index, NMethodPropID::kDigestSize, &prop));
+ if (prop.vt != VT_UI4)
+ return 0;
+ return prop.ulVal;
+}
+
+#endif // EXTERNAL_CODECS
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/LoadCodecs.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/LoadCodecs.h
index a633dd2e1..d254ae659 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/LoadCodecs.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/LoadCodecs.h
@@ -1,12 +1,13 @@
// LoadCodecs.h
-#ifndef __LOADCODECS_H
-#define __LOADCODECS_H
+#ifndef __LOAD_CODECS_H
+#define __LOAD_CODECS_H
-#include "../../../Common/Types.h"
+#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyCom.h"
#include "../../../Common/MyString.h"
-#include "../../../Common/Buffer.h"
+#include "../../../Common/ComTry.h"
+
#include "../../ICoder.h"
#ifdef EXTERNAL_CODECS
@@ -23,15 +24,19 @@ struct CDllCodecInfo
UInt32 CodecIndex;
};
-#include "../../Archive/IArchive.h"
+struct CDllHasherInfo
+{
+ int LibIndex;
+ UInt32 HasherIndex;
+};
-typedef IInArchive * (*CreateInArchiveP)();
-typedef IOutArchive * (*CreateOutArchiveP)();
+#include "../../Archive/IArchive.h"
struct CArcExtInfo
{
UString Ext;
UString AddExt;
+
CArcExtInfo() {}
CArcExtInfo(const UString &ext): Ext(ext) {}
CArcExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}
@@ -40,37 +45,55 @@ struct CArcExtInfo
struct CArcInfoEx
{
- #ifdef EXTERNAL_CODECS
- int LibIndex;
- UInt32 FormatIndex;
- CLSID ClassID;
- #endif
- bool UpdateEnabled;
- CreateInArchiveP CreateInArchive;
- CreateOutArchiveP CreateOutArchive;
+ UInt32 Flags;
+
+ Func_CreateInArchive CreateInArchive;
+ Func_IsArc IsArcFunc;
+
UString Name;
CObjectVector<CArcExtInfo> Exts;
+
#ifndef _SFX
- CByteBuffer StartSignature;
- // CByteBuffer FinishSignature;
- #ifdef NEW_FOLDER_INTERFACE
- UStringVector AssociateExts;
+ Func_CreateOutArchive CreateOutArchive;
+ bool UpdateEnabled;
+ bool NewInterface;
+ // UInt32 Version;
+ UInt32 SignatureOffset;
+ CObjectVector<CByteBuffer> Signatures;
+ #ifdef NEW_FOLDER_INTERFACE
+ UStringVector AssociateExts;
+ #endif
#endif
+
+ #ifdef EXTERNAL_CODECS
+ int LibIndex;
+ UInt32 FormatIndex;
+ CLSID ClassID;
#endif
- bool KeepName;
+
+ bool Flags_KeepName() const { return (Flags & NArcInfoFlags::kKeepName) != 0; }
+ bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; }
+
+ bool Flags_AltStreams() const { return (Flags & NArcInfoFlags::kAltStreams) != 0; }
+ bool Flags_NtSecure() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; }
+ bool Flags_SymLinks() const { return (Flags & NArcInfoFlags::kSymLinks) != 0; }
+ bool Flags_HardLinks() const { return (Flags & NArcInfoFlags::kHardLinks) != 0; }
+
+ bool Flags_UseGlobalOffset() const { return (Flags & NArcInfoFlags::kUseGlobalOffset) != 0; }
+ bool Flags_StartOpen() const { return (Flags & NArcInfoFlags::kStartOpen) != 0; }
+ bool Flags_BackwardOpen() const { return (Flags & NArcInfoFlags::kBackwardOpen) != 0; }
+ bool Flags_PreArc() const { return (Flags & NArcInfoFlags::kPreArc) != 0; }
+ bool Flags_PureStartOpen() const { return (Flags & NArcInfoFlags::kPureStartOpen) != 0; }
+
UString GetMainExt() const
{
if (Exts.IsEmpty())
return UString();
return Exts[0].Ext;
}
- int FindExtension(const UString &ext) const
- {
- for (int i = 0; i < Exts.Size(); i++)
- if (ext.CompareNoCase(Exts[i].Ext) == 0)
- return i;
- return -1;
- }
+ int FindExtension(const UString &ext) const;
+
+ /*
UString GetAllExtensions() const
{
UString s;
@@ -82,25 +105,31 @@ struct CArcInfoEx
}
return s;
}
+ */
+
+ void AddExts(const UString &ext, const UString &addExt);
- void AddExts(const wchar_t* ext, const wchar_t* addExt);
+ bool IsSplit() const { return StringsAreEqualNoCase_Ascii(Name, "Split"); }
+ // bool IsRar() const { return StringsAreEqualNoCase_Ascii(Name, "Rar"); }
CArcInfoEx():
- #ifdef EXTERNAL_CODECS
- LibIndex(-1),
- #endif
- UpdateEnabled(false),
- CreateInArchive(0), CreateOutArchive(0),
- KeepName(false)
- #ifndef _SFX
- #endif
+ Flags(0),
+ CreateInArchive(NULL),
+ IsArcFunc(NULL)
+ #ifndef _SFX
+ , CreateOutArchive(NULL)
+ , UpdateEnabled(false)
+ , NewInterface(false)
+ // , Version(0)
+ , SignatureOffset(0)
+ #endif
+ #ifdef EXTERNAL_CODECS
+ , LibIndex(-1)
+ #endif
{}
};
#ifdef EXTERNAL_CODECS
-typedef UInt32 (WINAPI *GetMethodPropertyFunc)(UInt32 index, PROPID propID, PROPVARIANT *value);
-typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *interfaceID, void **outObject);
-
#ifdef NEW_FOLDER_INTERFACE
struct CCodecIcons
@@ -117,24 +146,28 @@ struct CCodecIcons
#endif
struct CCodecLib
-#ifdef NEW_FOLDER_INTERFACE
-: public CCodecIcons
-#endif
+ #ifdef NEW_FOLDER_INTERFACE
+ : public CCodecIcons
+ #endif
{
NWindows::NDLL::CLibrary Lib;
- GetMethodPropertyFunc GetMethodProperty;
- CreateObjectFunc CreateObject;
+ FString Path;
+ Func_GetMethodProperty GetMethodProperty;
+ Func_CreateObject CreateObject;
+ CMyComPtr<IHashers> Hashers;
+
#ifdef NEW_FOLDER_INTERFACE
- CSysString Path;
void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); }
#endif
- CCodecLib(): GetMethodProperty(0) {}
+
+ CCodecLib(): GetMethodProperty(NULL) {}
};
#endif
class CCodecs:
#ifdef EXTERNAL_CODECS
public ICompressCodecsInfo,
+ public IHashers,
#else
public IUnknown,
#endif
@@ -143,7 +176,8 @@ class CCodecs:
public:
#ifdef EXTERNAL_CODECS
CObjectVector<CCodecLib> Libs;
- CObjectVector<CDllCodecInfo> Codecs;
+ CRecordVector<CDllCodecInfo> Codecs;
+ CRecordVector<CDllHasherInfo> Hashers;
#ifdef NEW_FOLDER_INTERFACE
CCodecIcons InternalIcons;
@@ -151,8 +185,8 @@ public:
HRESULT LoadCodecs();
HRESULT LoadFormats();
- HRESULT LoadDll(const CSysString &path, bool needCheckDll);
- HRESULT LoadDllsFromFolder(const CSysString &folderPrefix);
+ HRESULT LoadDll(const FString &path, bool needCheckDll);
+ HRESULT LoadDllsFromFolder(const FString &folderPrefix);
HRESULT CreateArchiveHandler(const CArcInfoEx &ai, void **archive, bool outHandler) const
{
@@ -162,8 +196,18 @@ public:
public:
CObjectVector<CArcInfoEx> Formats;
+ bool CaseSensitiveChange;
+ bool CaseSensitive;
+
+ CCodecs(): CaseSensitiveChange(false), CaseSensitive(false) {}
+
+ const wchar_t *GetFormatNamePtr(int formatIndex)
+ {
+ return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[formatIndex].Name;
+ }
+
HRESULT Load();
-
+
#ifndef _SFX
int FindFormatForArchiveName(const UString &arcPath) const;
int FindFormatForExtension(const UString &ext) const;
@@ -171,65 +215,89 @@ public:
bool FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const;
#endif
- MY_UNKNOWN_IMP
-
#ifdef EXTERNAL_CODECS
+
+ MY_UNKNOWN_IMP2(ICompressCodecsInfo, IHashers)
+
STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods);
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
STDMETHOD(CreateDecoder)(UInt32 index, const GUID *interfaceID, void **coder);
STDMETHOD(CreateEncoder)(UInt32 index, const GUID *interfaceID, void **coder);
- #endif
+
+ STDMETHOD_(UInt32, GetNumHashers)();
+ STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher);
+
+ #else
+
+ MY_UNKNOWN_IMP
+
+ #endif // EXTERNAL_CODECS
+
+ #ifdef EXTERNAL_CODECS
int GetCodecLibIndex(UInt32 index);
bool GetCodecEncoderIsAssigned(UInt32 index);
HRESULT GetCodecId(UInt32 index, UInt64 &id);
UString GetCodecName(UInt32 index);
- HRESULT CreateInArchive(int formatIndex, CMyComPtr<IInArchive> &archive) const
+ int GetHasherLibIndex(UInt32 index);
+ UInt64 GetHasherId(UInt32 index);
+ UString GetHasherName(UInt32 index);
+ UInt32 GetHasherDigestSize(UInt32 index);
+
+ #endif
+
+ HRESULT CreateInArchive(unsigned formatIndex, CMyComPtr<IInArchive> &archive) const
{
const CArcInfoEx &ai = Formats[formatIndex];
#ifdef EXTERNAL_CODECS
if (ai.LibIndex < 0)
#endif
{
+ COM_TRY_BEGIN
archive = ai.CreateInArchive();
return S_OK;
+ COM_TRY_END
}
#ifdef EXTERNAL_CODECS
return CreateArchiveHandler(ai, (void **)&archive, false);
#endif
}
- HRESULT CreateOutArchive(int formatIndex, CMyComPtr<IOutArchive> &archive) const
+
+ #ifndef _SFX
+
+ HRESULT CreateOutArchive(unsigned formatIndex, CMyComPtr<IOutArchive> &archive) const
{
const CArcInfoEx &ai = Formats[formatIndex];
#ifdef EXTERNAL_CODECS
if (ai.LibIndex < 0)
#endif
{
+ COM_TRY_BEGIN
archive = ai.CreateOutArchive();
return S_OK;
+ COM_TRY_END
}
#ifdef EXTERNAL_CODECS
return CreateArchiveHandler(ai, (void **)&archive, true);
#endif
}
+
int FindOutFormatFromName(const UString &name) const
{
- for (int i = 0; i < Formats.Size(); i++)
+ FOR_VECTOR (i, Formats)
{
const CArcInfoEx &arc = Formats[i];
if (!arc.UpdateEnabled)
continue;
- if (arc.Name.CompareNoCase(name) == 0)
+ if (arc.Name.IsEqualToNoCase(name))
return i;
}
return -1;
}
- #ifdef EXTERNAL_CODECS
- HRESULT CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const;
- #endif
-
+ #endif // _SFX
};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/OpenArchive.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/OpenArchive.cpp
index 5e67915bb..7c53bd99f 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -2,27 +2,487 @@
#include "StdAfx.h"
-#include "Common/Wildcard.h"
+// #define SHOW_DEBUG_INFO
-#include "Windows/FileDir.h"
-#include "Windows/PropVariant.h"
+#ifdef SHOW_DEBUG_INFO
+#include <stdio.h>
+#endif
+
+#include "../../../../C/CpuArch.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/StringToInt.h"
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/FileDir.h"
#include "../../Common/FileStreams.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/ProgressUtils.h"
#include "../../Common/StreamUtils.h"
+#include "../../Compress/CopyCoder.h"
+
#include "DefaultName.h"
#include "OpenArchive.h"
+#ifndef _SFX
+#include "SetProperties.h"
+#endif
+
+#ifdef SHOW_DEBUG_INFO
+#define PRF(x) x
+#else
+#define PRF(x)
+#endif
+
+// increase it, if you need to support larger SFX stubs
+static const UInt64 kMaxCheckStartPosition = 1 << 22;
+
+/*
+Open:
+ - formatIndex >= 0 (exact Format)
+ 1) Open with main type. Archive handler is allowed to use archive start finder.
+ Warning, if there is tail.
+
+ - formatIndex = -1 (Parser:0) (default)
+ - same as #1 but doesn't return Parser
+
+ - formatIndex = -2 (#1)
+ - file has supported extension (like a.7z)
+ Open with that main type (only starting from start of file).
+ - open OK:
+ - if there is no tail - return OK
+ - if there is tail:
+ - archive is not "Self Exe" - return OK with Warning, that there is tail
+ - archive is "Self Exe"
+ ignore "Self Exe" stub, and tries to open tail
+ - tail can be open as archive - shows that archive and stub size property.
+ - tail can't be open as archive - shows Parser ???
+ - open FAIL:
+ Try to open with all other types from offset 0 only.
+ If some open type is OK and physical archive size is uequal or larger
+ than file size, then return that archive with warning that can not be open as [extension type].
+ If extension was EXE, it will try to open as unknown_extension case
+ - file has unknown extension (like a.hhh)
+ It tries to open via parser code.
+ - if there is full archive or tail archive and unknown block or "Self Exe"
+ at front, it shows tail archive and stub size property.
+ - in another cases, if there is some archive inside file, it returns parser/
+ - in another cases, it retuens S_FALSE
+
+
+ - formatIndex = -3 (#2)
+ - same as #1, but
+ - stub (EXE) + archive is open in Parser
+
+ - formatIndex = -4 (#3)
+ - returns only Parser. skip full file archive. And show other sub-archives
+
+ - formatIndex = -5 (#4)
+ - returns only Parser. skip full file archive. And show other sub-archives for each byte pos
+
+*/
+
+
+
+
using namespace NWindows;
-// Static-SFX (for Linux) can be big.
-const UInt64 kMaxCheckStartPosition = 1 << 22;
+/*
+#ifdef _SFX
+#define OPEN_PROPS_PARAM
+#else
+#define OPEN_PROPS_PARAM , props
+#endif
+*/
+
+/*
+CArc::~CArc()
+{
+ GetRawProps.Release();
+ Archive.Release();
+ printf("\nCArc::~CArc()\n");
+}
+*/
+
+#ifndef _SFX
+
+namespace NArchive {
+namespace NParser {
+
+struct CParseItem
+{
+ UInt64 Offset;
+ UInt64 Size;
+ // UInt64 OkSize;
+ UString Name;
+ UString Extension;
+ FILETIME FileTime;
+ UString Comment;
+ UString ArcType;
+
+ bool FileTime_Defined;
+ bool UnpackSize_Defined;
+ bool NumSubDirs_Defined;
+ bool NumSubFiles_Defined;
+
+ bool IsSelfExe;
+ bool IsNotArcType;
+
+ UInt64 UnpackSize;
+ UInt64 NumSubDirs;
+ UInt64 NumSubFiles;
+
+ int FormatIndex;
+
+ bool LenIsUnknown;
+
+ CParseItem():
+ LenIsUnknown(false),
+ FileTime_Defined(false),
+ UnpackSize_Defined(false),
+ NumSubFiles_Defined(false),
+ NumSubDirs_Defined(false),
+ IsSelfExe(false),
+ IsNotArcType(false)
+ // OkSize(0)
+ {}
+
+ /*
+ bool IsEqualTo(const CParseItem &item) const
+ {
+ return Offset == item.Offset && Size == item.Size;
+ }
+ */
+
+ void NormalizeOffset()
+ {
+ if ((Int64)Offset < 0)
+ {
+ Size += Offset;
+ // OkSize += Offset;
+ Offset = 0;
+ }
+ }
+};
+
+class CHandler:
+ public IInArchive,
+ public IInArchiveGetStream,
+ public CMyUnknownImp
+{
+public:
+ CObjectVector<CParseItem> _items;
+ UInt64 _maxEndOffset;
+ CMyComPtr<IInStream> _stream;
+
+ MY_UNKNOWN_IMP2(
+ IInArchive,
+ IInArchiveGetStream)
+
+ INTERFACE_IInArchive(;)
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+
+ UInt64 GetLastEnd() const
+ {
+ if (_items.IsEmpty())
+ return 0;
+ const CParseItem &back = _items.Back();
+ return back.Offset + back.Size;
+ }
+
+ void AddUnknownItem(UInt64 next);
+ int FindInsertPos(const CParseItem &item);
+ void AddItem(const CParseItem &item);
+ // void Init();
+
+ CHandler()
+ {
+ _maxEndOffset = 0;
+ }
+};
+
+int CHandler::FindInsertPos(const CParseItem &item)
+{
+ unsigned left = 0, right = _items.Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const CParseItem & midItem = _items[mid];
+ if (item.Offset < midItem.Offset)
+ right = mid;
+ else if (item.Offset > midItem.Offset)
+ left = mid + 1;
+ else if (item.Size < midItem.Size)
+ right = mid;
+ else if (item.Size > midItem.Size)
+ left = mid + 1;
+ else
+ {
+ left = mid + 1;
+ // return -1;
+ }
+ }
+ return left;
+}
-HRESULT GetArchiveItemBoolProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
+void CHandler::AddUnknownItem(UInt64 next)
+{
+ /*
+ UInt64 prevEnd = 0;
+ if (!_items.IsEmpty())
+ {
+ const CParseItem &back = _items.Back();
+ prevEnd = back.Offset + back.Size;
+ }
+ */
+ if (_maxEndOffset < next)
+ {
+ CParseItem item2;
+ item2.Offset = _maxEndOffset;
+ item2.Size = next - _maxEndOffset;
+ _maxEndOffset = next;
+ _items.Add(item2);
+ }
+ else if (_maxEndOffset > next && !_items.IsEmpty())
+ {
+ CParseItem &back = _items.Back();
+ if (back.LenIsUnknown)
+ {
+ back.Size = next - back.Offset;
+ _maxEndOffset = next;
+ }
+ }
+}
+
+void CHandler::AddItem(const CParseItem &item)
+{
+ AddUnknownItem(item.Offset);
+ int pos = FindInsertPos(item);
+ if (pos >= 0)
+ {
+ _items.Insert(pos, item);
+ UInt64 next = item.Offset + item.Size;
+ if (_maxEndOffset < next)
+ _maxEndOffset = next;
+ }
+}
+
+/*
+static const STATPROPSTG kProps[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidMTime, VT_FILETIME},
+ { NULL, kpidType, VT_BSTR},
+ { NULL, kpidComment, VT_BSTR},
+ { NULL, kpidOffset, VT_UI8},
+ { NULL, kpidUnpackSize, VT_UI8},
+// { NULL, kpidNumSubDirs, VT_UI8},
+};
+*/
+
+static const Byte kProps[] =
+{
+ kpidPath,
+ kpidSize,
+ kpidMTime,
+ kpidType,
+ kpidComment,
+ kpidOffset,
+ kpidUnpackSize
+};
+
+IMP_IInArchive_Props
+IMP_IInArchive_ArcProps_NO
+
+STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* openArchiveCallback */)
+{
+ COM_TRY_BEGIN
+ {
+ Close();
+ _stream = stream;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _items.Clear();
+ _stream.Release();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _items.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NCOM::CPropVariant prop;
+
+ const CParseItem &item = _items[index];
+
+ switch (propID)
+ {
+ case kpidPath:
+ {
+ wchar_t sz[32];
+ ConvertUInt32ToString(index + 1, sz);
+ UString s = sz;
+ if (!item.Name.IsEmpty())
+ {
+ s += L'.';
+ s += item.Name;
+ }
+ if (!item.Extension.IsEmpty())
+ {
+ s += L'.';
+ s += item.Extension;
+ }
+ prop = s; break;
+ }
+ case kpidSize:
+ case kpidPackSize: prop = item.Size; break;
+ case kpidOffset: prop = item.Offset; break;
+ case kpidUnpackSize: if (item.UnpackSize_Defined) prop = item.UnpackSize; break;
+ case kpidNumSubFiles: if (item.NumSubFiles_Defined) prop = item.NumSubFiles; break;
+ case kpidNumSubDirs: if (item.NumSubDirs_Defined) prop = item.NumSubDirs; break;
+ case kpidMTime: if (item.FileTime_Defined) prop = item.FileTime; break;
+ case kpidComment: if (!item.Comment.IsEmpty()) prop = item.Comment; break;
+ case kpidType: if (!item.ArcType.IsEmpty()) prop = item.ArcType; break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == (UInt32)(Int32)-1);
+ if (allFilesMode)
+ numItems = _items.Size();
+ if (_stream && numItems == 0)
+ return S_OK;
+ UInt64 totalSize = 0;
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ totalSize += _items[allFilesMode ? i : indices[i]].Size;
+ extractCallback->SetTotal(totalSize);
+
+ totalSize = 0;
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+ streamSpec->SetStream(_stream);
+
+ CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+
+ for (i = 0; i < numItems; i++)
+ {
+ lps->InSize = totalSize;
+ lps->OutSize = totalSize;
+ RINOK(lps->SetCur());
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode = testMode ?
+ NExtract::NAskMode::kTest :
+ NExtract::NAskMode::kExtract;
+ Int32 index = allFilesMode ? i : indices[i];
+ const CParseItem &item = _items[index];
+
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+ UInt64 unpackSize = item.Size;
+ totalSize += unpackSize;
+ bool skipMode = false;
+ if (!testMode && !realOutStream)
+ continue;
+ RINOK(extractCallback->PrepareOperation(askMode));
+
+ outStreamSpec->SetStream(realOutStream);
+ realOutStream.Release();
+ outStreamSpec->Init(skipMode ? 0 : unpackSize, true);
+
+ Int32 opRes = NExtract::NOperationResult::kOK;
+ RINOK(_stream->Seek(item.Offset, STREAM_SEEK_SET, NULL));
+ streamSpec->Init(unpackSize);
+ RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
+
+ if (outStreamSpec->GetRem() != 0)
+ opRes = NExtract::NOperationResult::kDataError;
+ outStreamSpec->ReleaseStream();
+ RINOK(extractCallback->SetOperationResult(opRes));
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ COM_TRY_BEGIN
+ const CParseItem &item = _items[index];
+ return CreateLimitedInStream(_stream, item.Offset, item.Size, stream);
+ COM_TRY_END
+}
+
+}}
+
+#endif
+
+HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw()
+{
+ NCOM::CPropVariant prop;
+ result = false;
+ RINOK(arc->GetProperty(index, propID, &prop));
+ if (prop.vt == VT_BOOL)
+ result = VARIANT_BOOLToBool(prop.boolVal);
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT Archive_IsItem_Folder(IInArchive *arc, UInt32 index, bool &result) throw()
+{
+ return Archive_GetItemBoolProp(arc, index, kpidIsDir, result);
+}
+
+HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw()
+{
+ return Archive_GetItemBoolProp(arc, index, kpidIsAux, result);
+}
+
+HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw()
+{
+ return Archive_GetItemBoolProp(arc, index, kpidIsAltStream, result);
+}
+
+HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &result) throw()
+{
+ return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result);
+}
+
+static HRESULT Archive_GetArcBoolProp(IInArchive *arc, PROPID propid, bool &result)
{
NCOM::CPropVariant prop;
result = false;
- RINOK(archive->GetProperty(index, propID, &prop));
+ RINOK(arc->GetArchiveProperty(propid, &prop));
if (prop.vt == VT_BOOL)
result = VARIANT_BOOLToBool(prop.boolVal);
else if (prop.vt != VT_EMPTY)
@@ -30,13 +490,179 @@ HRESULT GetArchiveItemBoolProp(IInArchive *archive, UInt32 index, PROPID propID,
return S_OK;
}
-HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
+static HRESULT Archive_GetArcProp_UInt(IInArchive *arc, PROPID propid, UInt64 &result, bool &defined)
+{
+ defined = false;
+ NCOM::CPropVariant prop;
+ RINOK(arc->GetArchiveProperty(propid, &prop));
+ switch (prop.vt)
+ {
+ case VT_UI4: result = prop.ulVal; defined = true; break;
+ case VT_I4: result = prop.lVal; defined = true; break;
+ case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; defined = true; break;
+ case VT_I8: result = (UInt64)prop.hVal.QuadPart; defined = true; break;
+ case VT_EMPTY: break;
+ default: return E_FAIL;
+ }
+ return S_OK;
+}
+
+static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &result, bool &defined)
{
- return GetArchiveItemBoolProp(archive, index, kpidIsDir, result);
+ defined = false;
+ NCOM::CPropVariant prop;
+ RINOK(arc->GetArchiveProperty(propid, &prop));
+ switch (prop.vt)
+ {
+ case VT_UI4: result = prop.ulVal; defined = true; break;
+ case VT_I4: result = prop.lVal; defined = true; break;
+ case VT_UI8: result = (Int64)prop.uhVal.QuadPart; defined = true; break;
+ case VT_I8: result = (Int64)prop.hVal.QuadPart; defined = true; break;
+ case VT_EMPTY: break;
+ default: return E_FAIL;
+ }
+ return S_OK;
+}
+
+HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const
+{
+ if (!GetRawProps)
+ return E_FAIL;
+ UInt32 curIndex = index;
+ bool prevWasAltStream = false;
+ for (;;)
+ {
+ UString s;
+
+ #ifdef MY_CPU_LE
+ const void *p;
+ UInt32 size;
+ UInt32 propType;
+ RINOK(GetRawProps->GetRawProp(curIndex, kpidName, &p, &size, &propType));
+ if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE)
+ s = (const wchar_t *)p;
+ else
+ #endif
+ {
+ NCOM::CPropVariant prop;
+ RINOK(Archive->GetProperty(curIndex, kpidName, &prop));
+ if (prop.vt == VT_BSTR)
+ s = prop.bstrVal;
+ else if (prop.vt == VT_EMPTY)
+ s = L"[Content]";
+ else
+ return E_FAIL;
+ }
+
+ if (prevWasAltStream)
+ parts[0] = s + L":" + parts[0];
+ else
+ parts.Insert(0, s);
+
+ UInt32 curParent = (UInt32)(Int32)-1;
+ UInt32 parentType = 0;
+ RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType));
+ if (parent == curParent)
+ return S_OK;
+ if (curParent == (UInt32)(Int32)-1)
+ return E_FAIL;
+ prevWasAltStream = (parentType == NParentType::kAltStream);
+ curIndex = curParent;
+ }
}
HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
{
+ #ifdef MY_CPU_LE
+ if (GetRawProps)
+ {
+ const void *p;
+ UInt32 size;
+ UInt32 propType;
+ if (!IsTree)
+ {
+ if (GetRawProps->GetRawProp(index, kpidPath, &p, &size, &propType) == S_OK &&
+ propType == NPropDataType::kUtf16z)
+ {
+ unsigned len = size / 2 - 1;
+ wchar_t *s = result.GetBuffer(len);
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = GetUi16(p);
+ p = (const void *)((const Byte *)p + 2);
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ if (c == L'/')
+ c = WCHAR_PATH_SEPARATOR;
+ #endif
+ *s++ = c;
+ }
+ result.ReleaseBuffer(len);
+ if (len != 0)
+ return S_OK;
+ }
+ }
+ /*
+ else if (GetRawProps->GetRawProp(index, kpidName, &p, &size, &propType) == S_OK &&
+ p && propType == NPropDataType::kUtf16z)
+ {
+ UInt32 totalSize = size;
+ bool isOK = false;
+ {
+ UInt32 index2 = index;
+ for (;;)
+ {
+ UInt32 parent = (UInt32)(Int32)-1;
+ UInt32 parentType = 0;
+ if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK)
+ break;
+ if (parent == (UInt32)(Int32)-1)
+ {
+ isOK = true;
+ break;
+ }
+ index2 = parent;
+ UInt32 size2;
+ const void *p2;
+ if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK)
+ break;
+ totalSize += size2;
+ }
+ }
+
+ if (isOK)
+ {
+ wchar_t *sz = result.GetBuffer(totalSize / 2);
+ UInt32 pos = totalSize - size;
+ memcpy((Byte *)sz + pos, p, size - 2);
+ UInt32 index2 = index;
+ for (;;)
+ {
+ UInt32 parent = (UInt32)(Int32)-1;
+ UInt32 parentType = 0;
+ if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK)
+ break;
+ if (parent == (UInt32)(Int32)-1)
+ break;
+ index2 = parent;
+ UInt32 size2;
+ const void *p2;
+ if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK)
+ break;
+ pos -= size2;
+ memcpy((Byte *)sz + pos, p2, size2);
+ sz[(pos + size2 - 2) / 2] = (parentType == 0) ? WCHAR_PATH_SEPARATOR : L':';
+ }
+ result.ReleaseBuffer((totalSize - 2) / 2);
+ #ifdef _WIN32
+ // result.Replace(L'/', WCHAR_PATH_SEPARATOR);
+ #endif
+ return S_OK;
+ }
+ }
+ */
+ }
+ #endif
+
{
NCOM::CPropVariant prop;
RINOK(Archive->GetProperty(index, kpidPath, &prop));
@@ -47,6 +673,7 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
else
return E_FAIL;
}
+
if (result.IsEmpty())
{
result = DefaultName;
@@ -63,6 +690,61 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
return S_OK;
}
+HRESULT CArc::GetItemPath2(UInt32 index, UString &result) const
+{
+ RINOK(GetItemPath(index, result));
+ if (Ask_Deleted)
+ {
+ bool isDeleted = false;
+ RINOK(Archive_IsItem_Deleted(Archive, index, isDeleted));
+ if (isDeleted)
+ result.Insert(0, L"[DELETED]" WSTRING_PATH_SEPARATOR);
+ }
+ return S_OK;
+}
+
+#ifndef _SFX
+
+static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &size, bool &defined)
+{
+ NCOM::CPropVariant prop;
+ defined = false;
+ size = 0;
+ RINOK(archive->GetProperty(index, kpidSize, &prop));
+ switch (prop.vt)
+ {
+ case VT_UI1: size = prop.bVal; break;
+ case VT_UI2: size = prop.uiVal; break;
+ case VT_UI4: size = prop.ulVal; break;
+ case VT_UI8: size = (UInt64)prop.uhVal.QuadPart; break;
+ case VT_EMPTY: return S_OK;
+ default: return E_FAIL;
+ }
+ defined = true;
+ return S_OK;
+}
+
+#endif
+
+HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const
+{
+ NCOM::CPropVariant prop;
+ defined = false;
+ size = 0;
+ RINOK(Archive->GetProperty(index, kpidSize, &prop));
+ switch (prop.vt)
+ {
+ case VT_UI1: size = prop.bVal; break;
+ case VT_UI2: size = prop.uiVal; break;
+ case VT_UI4: size = prop.ulVal; break;
+ case VT_UI8: size = (UInt64)prop.uhVal.QuadPart; break;
+ case VT_EMPTY: return S_OK;
+ default: return E_FAIL;
+ }
+ defined = true;
+ return S_OK;
+}
+
HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const
{
NCOM::CPropVariant prop;
@@ -85,6 +767,7 @@ HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const
}
#ifndef _SFX
+
static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
{
for (size_t i = 0; i < size; i++)
@@ -92,327 +775,2107 @@ static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
return false;
return true;
}
+
+static void MakeCheckOrder(CCodecs *codecs,
+ CIntVector &orderIndices, unsigned numTypes, CIntVector &orderIndices2,
+ const Byte *data, size_t dataSize)
+{
+ for (unsigned i = 0; i < numTypes; i++)
+ {
+ int index = orderIndices[i];
+ if (index < 0)
+ continue;
+ const CArcInfoEx &ai = codecs->Formats[index];
+ if (ai.SignatureOffset != 0)
+ {
+ orderIndices2.Add(index);
+ orderIndices[i] = -1;
+ continue;
+ }
+
+ const CObjectVector<CByteBuffer> &sigs = ai.Signatures;
+ FOR_VECTOR (k, sigs)
+ {
+ const CByteBuffer &sig = sigs[k];
+ if (sig.Size() == 0 && dataSize == 0 ||
+ sig.Size() != 0 && sig.Size() <= dataSize &&
+ TestSignature(data, sig, sig.Size()))
+ {
+ orderIndices2.Add(index);
+ orderIndices[i] = -1;
+ break;
+ }
+ }
+ }
+}
+
#endif
#ifdef UNDER_CE
-static const int kNumHashBytes = 1;
-#define HASH_VAL(buf, pos) ((buf)[pos])
+ static const unsigned kNumHashBytes = 1;
+ #define HASH_VAL(buf, pos) ((buf)[pos])
#else
-static const int kNumHashBytes = 2;
-#define HASH_VAL(buf, pos) ((buf)[pos] | ((UInt32)(buf)[pos + 1] << 8))
+ static const unsigned kNumHashBytes = 2;
+ #define HASH_VAL(buf, pos) ((buf)[pos] | ((UInt32)(buf)[pos + 1] << 8))
#endif
-HRESULT CArc::OpenStream(
- CCodecs *codecs,
- int formatIndex,
- IInStream *stream,
- ISequentialInStream *seqStream,
- IArchiveOpenCallback *callback)
+#ifndef _SFX
+
+static bool IsExeExt(const UString &ext)
{
- Archive.Release();
+ return ext.IsEqualToNoCase(L"exe");
+}
+
+static const char *k_PreArcFormats[] =
+{
+ "pe"
+ , "elf"
+ , "macho"
+ , "mub"
+ , "te"
+};
+
+static bool IsNameFromList(const UString &s, const char *names[], size_t num)
+{
+ for (unsigned i = 0; i < num; i++)
+ if (StringsAreEqualNoCase_Ascii(s, names[i]))
+ return true;
+ return false;
+}
+
+
+static bool IsPreArcFormat(const CArcInfoEx &ai)
+{
+ if (ai.Flags_PreArc())
+ return true;
+ return IsNameFromList(ai.Name, k_PreArcFormats, ARRAY_SIZE(k_PreArcFormats));
+}
+
+static const char *k_Formats_with_simple_signuature[] =
+{
+ "7z"
+ , "xz"
+ , "rar"
+ , "bzip2"
+ , "gzip"
+ , "cab"
+ , "wim"
+ , "rpm"
+ , "vhd"
+ , "xar"
+};
+
+static bool IsNewStyleSignature(const CArcInfoEx &ai)
+{
+ // if (ai.Version >= 0x91F)
+ if (ai.NewInterface)
+ return true;
+ return IsNameFromList(ai.Name, k_Formats_with_simple_signuature, ARRAY_SIZE(k_Formats_with_simple_signuature));
+}
+
+class CArchiveOpenCallback_Offset:
+ public IArchiveOpenCallback,
+ #ifndef _NO_CRYPTO
+ public ICryptoGetTextPassword,
+ #endif
+ public CMyUnknownImp
+{
+public:
+ CMyComPtr<IArchiveOpenCallback> Callback;
+ UInt64 Files;
+ UInt64 Offset;
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoGetTextPassword> GetTextPassword;
+ MY_UNKNOWN_IMP2(
+ IArchiveOpenCallback,
+ ICryptoGetTextPassword)
+ #else
+ MY_UNKNOWN_IMP1(IArchiveOpenCallback)
+ #endif
+ STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
+ STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
+ #ifndef _NO_CRYPTO
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+ #endif
+};
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password)
+{
+ COM_TRY_BEGIN
+ if (GetTextPassword)
+ return GetTextPassword->CryptoGetTextPassword(password);
+ return E_NOTIMPL;
+ COM_TRY_END
+}
+#endif
+
+STDMETHODIMP CArchiveOpenCallback_Offset::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 * /* files */, const UInt64 *bytes)
+{
+ if (!Callback)
+ return S_OK;
+ UInt64 value = Offset;
+ if (bytes)
+ value += *bytes;
+ return Callback->SetCompleted(&Files, &value);
+}
+
+#endif
+
+UInt32 GetOpenArcErrorFlags(const NCOM::CPropVariant &prop, bool *isDefinedProp)
+{
+ if (isDefinedProp != NULL)
+ *isDefinedProp = false;
+
+ switch (prop.vt)
+ {
+ case VT_UI8: if (isDefinedProp) *isDefinedProp = true; return (UInt32)prop.uhVal.QuadPart;
+ case VT_UI4: if (isDefinedProp) *isDefinedProp = true; return prop.ulVal;
+ case VT_EMPTY: return 0;
+ default: throw 151199;
+ }
+}
+
+void CArcErrorInfo::ClearErrors()
+{
+ // ErrorFormatIndex = -1; // we don't need to clear ErrorFormatIndex here !!!
+
+ ThereIsTail = false;
+ UnexpecedEnd = false;
+ IgnoreTail = false;
+ // NonZerosTail = false;
+ ErrorFlags_Defined = false;
+ ErrorFlags = 0;
+ WarningFlags = 0;
+ TailSize = 0;
+
ErrorMessage.Empty();
+ WarningMessage.Empty();
+}
+
+HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes)
+{
+ // OkPhySize_Defined = false;
+ PhySizeDefined = false;
+ PhySize = 0;
+ Offset = 0;
+ AvailPhySize = FileSize - startPos;
+
+ ErrorInfo.ClearErrors();
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidErrorFlags, &prop));
+ ErrorInfo.ErrorFlags = GetOpenArcErrorFlags(prop, &ErrorInfo.ErrorFlags_Defined);
+ }
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidWarningFlags, &prop));
+ ErrorInfo.WarningFlags = GetOpenArcErrorFlags(prop);
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidError, &prop));
+ if (prop.vt != VT_EMPTY)
+ ErrorInfo.ErrorMessage = (prop.vt == VT_BSTR) ? prop.bstrVal : L"Unknown error";
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidWarning, &prop));
+ if (prop.vt != VT_EMPTY)
+ ErrorInfo.WarningMessage = (prop.vt == VT_BSTR) ? prop.bstrVal : L"Unknown warning";
+ }
+
+ if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen())
+ {
+ RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySizeDefined));
+ /*
+ RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined));
+ if (!OkPhySize_Defined)
+ {
+ OkPhySize_Defined = PhySizeDefined;
+ OkPhySize = PhySize;
+ }
+ */
+
+ bool offsetDefined;
+ RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined));
+
+ Int64 globalOffset = startPos + Offset;
+ AvailPhySize = FileSize - globalOffset;
+ if (PhySizeDefined)
+ {
+ UInt64 endPos = globalOffset + PhySize;
+ if (endPos < FileSize)
+ {
+ AvailPhySize = PhySize;
+ ErrorInfo.ThereIsTail = true;
+ ErrorInfo.TailSize = FileSize - endPos;
+ }
+ else if (endPos > FileSize)
+ ErrorInfo.UnexpecedEnd = true;
+ }
+ }
+
+ return S_OK;
+}
+
+/*
+static PrintNumber(const char *s, int n)
+{
+ char temp[100];
+ sprintf(temp, "%s %d", s, n);
+ OutputDebugStringA(temp);
+}
+*/
+
+HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive)
+{
+ // OutputDebugStringW(L"a1");
+ // PrintNumber("formatIndex", formatIndex);
+
+ RINOK(op.codecs->CreateInArchive(formatIndex, archive));
+ // OutputDebugStringW(L"a2");
+ if (!archive)
+ return S_OK;
+
+ #ifdef EXTERNAL_CODECS
+ {
+ CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
+ archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
+ if (setCompressCodecsInfo)
+ {
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(op.codecs));
+ }
+ }
+ #endif
+
+ // OutputDebugStringW(ai.Name);
+ // OutputDebugStringW(L"a3");
+
+ #ifndef _SFX
+ const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
+ if (ai.Flags_PreArc())
+ {
+ /* we notify parsers that extract executables, that they don't need
+ to open archive, if there is tail after executable (for SFX cases) */
+ CMyComPtr<IArchiveAllowTail> allowTail;
+ archive.QueryInterface(IID_IArchiveAllowTail, (void **)&allowTail);
+ if (allowTail)
+ allowTail->AllowTail(BoolToInt(true));
+ }
+ if (op.props)
+ {
+ /*
+ FOR_VECTOR (y, op.props)
+ {
+ const COptionalOpenProperties &optProps = (*op.props)[y];
+ if (optProps.FormatName.IsEmpty() || optProps.FormatName.CompareNoCase(ai.Name) == 0)
+ {
+ RINOK(SetProperties(archive, optProps.Props));
+ break;
+ }
+ }
+ */
+ RINOK(SetProperties(archive, *op.props));
+ }
+ #endif
+ return S_OK;
+}
+
+#ifndef _SFX
+
+static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NArchive::NParser::CParseItem &pi)
+{
+ pi.Extension = ai.GetMainExt();
+ pi.FileTime_Defined = false;
+ pi.ArcType = ai.Name;
+
+ RINOK(Archive_GetArcBoolProp(archive, kpidIsNotArcType, pi.IsNotArcType));
+
+ // RINOK(Archive_GetArcBoolProp(archive, kpidIsSelfExe, pi.IsSelfExe));
+ pi.IsSelfExe = ai.Flags_PreArc();
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidMTime, &prop));
+ if (prop.vt == VT_FILETIME)
+ {
+ pi.FileTime_Defined = true;
+ pi.FileTime = prop.filetime;
+ }
+ }
+
+ if (!pi.FileTime_Defined)
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidCTime, &prop));
+ if (prop.vt == VT_FILETIME)
+ {
+ pi.FileTime_Defined = true;
+ pi.FileTime = prop.filetime;
+ }
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidName, &prop));
+ if (prop.vt == VT_BSTR)
+ {
+ pi.Name = prop.bstrVal;
+ pi.Extension.Empty();
+ }
+ else
+ {
+ RINOK(archive->GetArchiveProperty(kpidExtension, &prop));
+ if (prop.vt == VT_BSTR)
+ pi.Extension = prop.bstrVal;
+ }
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetArchiveProperty(kpidShortComment, &prop));
+ if (prop.vt == VT_BSTR)
+ pi.Comment = prop.bstrVal;
+ }
+
+
+ UInt32 numItems;
+ RINOK(archive->GetNumberOfItems(&numItems));
+
+ // pi.NumSubFiles = numItems;
+ // RINOK(Archive_GetArcProp_UInt(archive, kpidUnpackSize, pi.UnpackSize, pi.UnpackSize_Defined));
+ // if (!pi.UnpackSize_Defined)
+ {
+ pi.NumSubFiles = 0;
+ pi.NumSubDirs = 0;
+ pi.UnpackSize = 0;
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ UInt64 size = 0;
+ bool defined = false;
+ Archive_GetItem_Size(archive, i, size, defined);
+ if (defined)
+ {
+ pi.UnpackSize_Defined = true;
+ pi.UnpackSize += size;
+ }
+
+ bool isDir = false;
+ Archive_IsItem_Folder(archive, i, isDir);
+ if (isDir)
+ pi.NumSubDirs++;
+ else
+ pi.NumSubFiles++;
+ }
+ if (pi.NumSubDirs != 0)
+ pi.NumSubDirs_Defined = true;
+ pi.NumSubFiles_Defined = true;
+ }
+
+ return S_OK;
+}
+
+#endif
+
+HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset)
+{
+ if (!op.stream)
+ return S_OK;
+ RINOK(op.stream->Seek(offset, STREAM_SEEK_SET, NULL));
+ const UInt32 kBufSize = 1 << 11;
+ Byte buf[kBufSize];
+
+ for (;;)
+ {
+ UInt32 processed = 0;
+ RINOK(op.stream->Read(buf, kBufSize, &processed));
+ if (processed == 0)
+ {
+ // ErrorInfo.NonZerosTail = false;
+ ErrorInfo.IgnoreTail = true;
+ return S_OK;
+ }
+ for (size_t i = 0; i < processed; i++)
+ {
+ if (buf[i] != 0)
+ {
+ // ErrorInfo.IgnoreTail = false;
+ // ErrorInfo.NonZerosTail = true;
+ return S_OK;
+ }
+ }
+ }
+}
+
+#ifndef _SFX
+
+class CExtractCallback_To_OpenCallback:
+ public IArchiveExtractCallback,
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+public:
+ CMyComPtr<IArchiveOpenCallback> Callback;
+ UInt64 Files;
+ UInt64 Offset;
+
+ MY_UNKNOWN_IMP2(IArchiveExtractCallback, ICompressProgressInfo)
+ INTERFACE_IArchiveExtractCallback(;)
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+ void Init(IArchiveOpenCallback *callback)
+ {
+ Callback = callback;
+ Files = 0;
+ Offset = 0;
+ }
+};
+
+STDMETHODIMP CExtractCallback_To_OpenCallback::SetTotal(UInt64 /* size */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallback_To_OpenCallback::SetCompleted(const UInt64 * /* completeValue */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)
+{
+ if (Callback)
+ {
+ UInt64 value = Offset;
+ if (inSize)
+ value += *inSize;
+ return Callback->SetCompleted(&Files, &value);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */)
+{
+ *outStream = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallback_To_OpenCallback::PrepareOperation(Int32 /* askExtractMode */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* operationResult */)
+{
+ return S_OK;
+}
+
+static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize,
+ IInStream *stream, const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openCallback,
+ IArchiveExtractCallback *extractCallback)
+{
+ /*
+ if (needPhySize)
+ {
+ CMyComPtr<IArchiveOpen2> open2;
+ archive->QueryInterface(IID_IArchiveOpen2, (void **)&open2);
+ if (open2)
+ return open2->ArcOpen2(stream, kOpenFlags_RealPhySize, openCallback);
+ }
+ */
+ RINOK(archive->Open(stream, maxCheckStartPosition, openCallback));
+ if (needPhySize)
+ {
+ bool phySize_Defined = false;
+ UInt64 phySize = 0;
+ RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, phySize, phySize_Defined));
+ if (phySize_Defined)
+ return S_OK;
+
+ bool phySizeCantBeDetected = false;;
+ RINOK(Archive_GetArcBoolProp(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected));
+
+ if (!phySizeCantBeDetected)
+ {
+ RINOK(archive->Extract(0, (UInt32)(Int32)-1, BoolToInt(true), extractCallback));
+ }
+ }
+ return S_OK;
+}
+
+static int FindFormatForArchiveType(CCodecs *codecs, CIntVector orderIndices, const char *name)
+{
+ FOR_VECTOR (i, orderIndices)
+ if (StringsAreEqualNoCase_Ascii(codecs->Formats[orderIndices[i]].Name, name))
+ return i;
+ return -1;
+}
+
+#endif
+
+HRESULT CArc::OpenStream2(const COpenOptions &op)
+{
+ // fprintf(stdout, "\nOpen: %S", Path); fflush(stdout);
+
+ Archive.Release();
+ GetRawProps.Release();
+ GetRootProps.Release();
+
+ ErrorInfo.ClearErrors();
+ ErrorInfo.ErrorFormatIndex = -1;
+
+ IsParseArc = false;
+ ArcStreamOffset = 0;
+
+ // OutputDebugStringW(L"1");
+ // OutputDebugStringW(Path);
+
const UString fileName = ExtractFileNameFromPath(Path);
UString extension;
{
int dotPos = fileName.ReverseFind(L'.');
if (dotPos >= 0)
- extension = fileName.Mid(dotPos + 1);
+ extension = fileName.Ptr(dotPos + 1);
}
+
CIntVector orderIndices;
+
+ bool searchMarkerInHandler = false;
+ #ifdef _SFX
+ searchMarkerInHandler = true;
+ #endif
+
+ CBoolArr isMainFormatArr(op.codecs->Formats.Size());
+ {
+ FOR_VECTOR(i, op.codecs->Formats)
+ isMainFormatArr[i] = false;
+ }
+
+ UInt64 maxStartOffset =
+ op.openType.MaxStartOffset_Defined ?
+ op.openType.MaxStartOffset :
+ kMaxCheckStartPosition;
+
+ #ifndef _SFX
+ bool isUnknownExt = false;
+ #endif
+
+ bool isForced = false;
+ unsigned numMainTypes = 0;
+ int formatIndex = op.openType.FormatIndex;
+
if (formatIndex >= 0)
+ {
+ isForced = true;
orderIndices.Add(formatIndex);
+ numMainTypes = 1;
+ isMainFormatArr[formatIndex] = true;
+
+ searchMarkerInHandler = true;
+ }
else
{
+ unsigned numFinded = 0;
+ #ifndef _SFX
+ bool isPrearcExt = false;
+ #endif
- int i;
- int numFinded = 0;
- for (i = 0; i < codecs->Formats.Size(); i++)
- if (codecs->Formats[i].FindExtension(extension) >= 0)
- orderIndices.Insert(numFinded++, i);
- else
- orderIndices.Add(i);
-
- if (!stream)
+ {
+ FOR_VECTOR (i, op.codecs->Formats)
+ {
+ const CArcInfoEx &ai = op.codecs->Formats[i];
+
+ if (IgnoreSplit || !op.openType.CanReturnArc)
+ if (ai.IsSplit())
+ continue;
+ if (op.excludedFormats->FindInSorted(i) >= 0)
+ continue;
+
+ #ifndef _SFX
+ if (IsPreArcFormat(ai))
+ isPrearcExt = true;
+ #endif
+
+ if (ai.FindExtension(extension) >= 0)
+ {
+ // PrintNumber("orderIndices.Insert", i);
+ orderIndices.Insert(numFinded++, i);
+ isMainFormatArr[i] = true;
+ }
+ else
+ orderIndices.Add(i);
+ }
+ }
+
+ if (!op.stream)
+ {
+ if (numFinded != 1)
+ return E_NOTIMPL;
+ orderIndices.DeleteFrom(1);
+ }
+ // PrintNumber("numFinded", numFinded );
+
+ /*
+ if (op.openOnlySpecifiedByExtension)
+ {
+ if (numFinded != 0 && !IsExeExt(extension))
+ orderIndices.DeleteFrom(numFinded);
+ }
+ */
+
+ #ifndef _SFX
+
+ if (op.stream && orderIndices.Size() >= 2)
+ {
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+ CByteBuffer byteBuffer;
+ CIntVector orderIndices2;
+ if (numFinded == 0 || IsExeExt(extension))
+ {
+ // signature search was here
+ }
+ else if (extension == L"000" || extension == L"001")
+ {
+ int i = FindFormatForArchiveType(op.codecs, orderIndices, "rar");
+ if (i >= 0)
+ {
+ const size_t kBufSize = (1 << 10);
+ byteBuffer.Alloc(kBufSize);
+ size_t processedSize = kBufSize;
+ RINOK(ReadStream(op.stream, byteBuffer, &processedSize));
+ if (processedSize >= 16)
+ {
+ const Byte *buf = byteBuffer;
+ const Byte kRarHeader[] = { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 };
+ if (TestSignature(buf, kRarHeader, 7) && buf[9] == 0x73 && (buf[10] & 1) != 0)
+ {
+ orderIndices2.Add(orderIndices[i]);
+ orderIndices[i] = -1;
+ if (i >= (int)numFinded)
+ numFinded++;
+ }
+ }
+ }
+ }
+ else
+ {
+ const size_t kBufSize = (1 << 10);
+ byteBuffer.Alloc(kBufSize);
+ size_t processedSize = kBufSize;
+ RINOK(ReadStream(op.stream, byteBuffer, &processedSize));
+ if (processedSize == 0)
+ return S_FALSE;
+
+ /*
+ check type order:
+ 1) matched extension, no signuature
+ 2) matched extension, matched signuature
+ // 3) no signuature
+ // 4) matched signuature
+ */
+
+ MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, NULL, 0);
+ MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, byteBuffer, processedSize);
+ // MakeCheckOrder(op.codecs, orderIndices, orderIndices.Size(), orderIndices2, NULL, 0);
+ // MakeCheckOrder(op.codecs, orderIndices, orderIndices.Size(), orderIndices2, byteBuffer, processedSize);
+ }
+
+ FOR_VECTOR (i, orderIndices)
+ {
+ int val = orderIndices[i];
+ if (val != -1)
+ orderIndices2.Add(val);
+ }
+ orderIndices = orderIndices2;
+ }
+
+ if (orderIndices.Size() >= 2)
+ {
+ int iIso = FindFormatForArchiveType(op.codecs, orderIndices, "iso");
+ int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf");
+ if (iUdf > iIso && iIso >= 0)
+ {
+ int isoIndex = orderIndices[iIso];
+ int udfIndex = orderIndices[iUdf];
+ orderIndices[iUdf] = isoIndex;
+ orderIndices[iIso] = udfIndex;
+ }
+ }
+
+ numMainTypes = numFinded;
+ isUnknownExt = (numMainTypes == 0) || isPrearcExt;
+
+ #else // _SFX
+
+ numMainTypes = orderIndices.Size();
+
+ #endif
+ }
+
+ UInt64 fileSize = 0;
+ if (op.stream)
{
- if (numFinded != 1)
- return E_NOTIMPL;
- orderIndices.DeleteFrom(1);
+ RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize));
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
}
+ FileSize = fileSize;
+
#ifndef _SFX
- if (orderIndices.Size() >= 2 && (numFinded == 0 || extension.CompareNoCase(L"exe") == 0))
+
+ CBoolArr skipFrontalFormat(op.codecs->Formats.Size());
{
- CIntVector orderIndices2;
- CByteBuffer byteBuffer;
- const size_t kBufferSize = (1 << 21);
- byteBuffer.SetCapacity(kBufferSize);
- RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
- size_t processedSize = kBufferSize;
- RINOK(ReadStream(stream, byteBuffer, &processedSize));
- if (processedSize == 0)
- return S_FALSE;
+ FOR_VECTOR(i, op.codecs->Formats)
+ skipFrontalFormat[i] = false;
+ }
- const Byte *buf = byteBuffer;
- CByteBuffer hashBuffer;
- const UInt32 kNumVals = 1 << (kNumHashBytes * 8);
- hashBuffer.SetCapacity(kNumVals);
- Byte *hash = hashBuffer;
- memset(hash, 0xFF, kNumVals);
- Byte prevs[256];
- if (orderIndices.Size() >= 256)
- return S_FALSE;
- int i;
- for (i = 0; i < orderIndices.Size(); i++)
+ #endif
+
+ const COpenType &mode = op.openType;
+
+
+
+
+
+ if (mode.CanReturnArc)
+ {
+ // ---------- OPEN main type by extenssion ----------
+
+ unsigned numCheckTypes = orderIndices.Size();
+ if (formatIndex >= 0)
+ numCheckTypes = numMainTypes;
+
+ for (unsigned i = 0; i < numCheckTypes; i++)
{
- const CArcInfoEx &ai = codecs->Formats[orderIndices[i]];
- const CByteBuffer &sig = ai.StartSignature;
- if (sig.GetCapacity() < kNumHashBytes)
+ FormatIndex = orderIndices[i];
+ const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
+ // OutputDebugStringW(ai.Name);
+
+ bool exactOnly = false;
+ if (i >= numMainTypes)
+ {
+ if (!ai.Flags_BackwardOpen()
+ // && !ai.Flags_PureStartOpen()
+ )
+ continue;
+ exactOnly = true;
+ }
+
+ // Some handlers do not set total bytes. So we set it here
+ RINOK(op.callback->SetTotal(NULL, &fileSize));
+ if (op.stream)
+ {
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+ }
+
+ CMyComPtr<IInArchive> archive;
+
+ RINOK(PrepareToOpen(op, FormatIndex, archive));
+ if (!archive)
continue;
- UInt32 v = HASH_VAL(sig, 0);
- prevs[i] = hash[v];
- hash[v] = (Byte)i;
- }
- processedSize -= (kNumHashBytes - 1);
- for (UInt32 pos = 0; pos < processedSize; pos++)
- {
- for (; pos < processedSize && hash[HASH_VAL(buf, pos)] == 0xFF; pos++) {}
- if (pos == processedSize)
- break;
- UInt32 v = HASH_VAL(buf, pos);
- Byte *ptr = &hash[v];
- int i = *ptr;
- do
+ HRESULT result;
+ if (op.stream)
{
- int index = orderIndices[i];
- const CArcInfoEx &ai = codecs->Formats[index];
- const CByteBuffer &sig = ai.StartSignature;
- if (sig.GetCapacity() != 0 && pos + sig.GetCapacity() <= processedSize + (kNumHashBytes - 1) &&
- TestSignature(buf + pos, sig, sig.GetCapacity()))
+ UInt64 searchLimit = (!exactOnly && searchMarkerInHandler) ? maxStartOffset: 0;
+ result = archive->Open(op.stream, &searchLimit, op.callback);
+ }
+ else
+ {
+ CMyComPtr<IArchiveOpenSeq> openSeq;
+ archive.QueryInterface(IID_IArchiveOpenSeq, (void **)&openSeq);
+ if (!openSeq)
+ return E_NOTIMPL;
+ result = openSeq->OpenSeq(op.seqStream);
+ }
+
+ RINOK(ReadBasicProps(archive, 0, result));
+
+ if (result == S_FALSE)
+ {
+ bool isArc = ErrorInfo.IsArc_After_NonOpen();
+
+ #ifndef _SFX
+ // if it's archive, we allow another open attempt for parser
+ if (!mode.CanReturnParser || !isArc)
+ skipFrontalFormat[FormatIndex] = true;
+ #endif
+
+ if (exactOnly)
+ continue;
+
+ if (i == 0 && numMainTypes == 1)
{
- orderIndices2.Add(index);
- orderIndices[i] = 0xFF;
- *ptr = prevs[i];
+ // we set NonOpenErrorInfo, only if there is only one main format (defined by extension).
+ ErrorInfo.ErrorFormatIndex = FormatIndex;
+ NonOpen_ErrorInfo = ErrorInfo;
+
+ if (!mode.CanReturnParser && isArc)
+ {
+ // if (formatIndex < 0 && !searchMarkerInHandler)
+ {
+ // if bad archive was detected, we don't need additional open attempts
+ #ifndef _SFX
+ if (!IsPreArcFormat(ai) /* || !mode.SkipSfxStub */)
+ #endif
+ return S_FALSE;
+ }
+ }
}
- else
- ptr = &prevs[i];
- i = *ptr;
+
+ /*
+ #ifndef _SFX
+ if (IsExeExt(extension) || ai.Flags_PreArc())
+ {
+ // openOnlyFullArc = false;
+ // canReturnTailArc = true;
+ // limitSignatureSearch = true;
+ }
+ #endif
+ */
+
+ continue;
+ }
+
+ RINOK(result);
+
+ #ifndef _SFX
+
+ bool isMainFormat = isMainFormatArr[FormatIndex];
+ const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);
+
+ bool thereIsTail = ErrorInfo.ThereIsTail;
+ if (thereIsTail && mode.ZerosTailIsAllowed)
+ {
+ RINOK(CheckZerosTail(op, Offset + PhySize));
+ if (ErrorInfo.IgnoreTail)
+ thereIsTail = false;
+ }
+
+ if (Offset > 0)
+ {
+ if (exactOnly
+ || !searchMarkerInHandler
+ || !specFlags.CanReturn_NonStart()
+ || (mode.MaxStartOffset_Defined && (UInt64)Offset > mode.MaxStartOffset))
+ continue;
}
- while (i != 0xFF);
+ if (thereIsTail)
+ {
+ if (Offset > 0)
+ {
+ if (!specFlags.CanReturnMid)
+ continue;
+ }
+ else if (!specFlags.CanReturnFrontal)
+ continue;
+ }
+
+ if (Offset > 0 || thereIsTail)
+ {
+ if (formatIndex < 0)
+ {
+ if (IsPreArcFormat(ai))
+ {
+ // openOnlyFullArc = false;
+ // canReturnTailArc = true;
+ /*
+ if (mode.SkipSfxStub)
+ limitSignatureSearch = true;
+ */
+ // if (mode.SkipSfxStub)
+ {
+ // skipFrontalFormat[FormatIndex] = true;
+ continue;
+ }
+ }
+ }
+ }
+
+ #endif
+
+ Archive = archive;
+ return S_OK;
}
-
- for (i = 0; i < orderIndices.Size(); i++)
+ }
+
+
+
+ #ifndef _SFX
+
+ if (!op.stream)
+ return S_FALSE;
+
+ if (formatIndex >= 0 && !mode.CanReturnParser)
+ {
+ if (mode.MaxStartOffset_Defined)
{
- int val = orderIndices[i];
- if (val != 0xFF)
- orderIndices2.Add(val);
+ if (mode.MaxStartOffset == 0)
+ return S_FALSE;
+ }
+ else
+ {
+ const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
+ if (ai.FindExtension(extension) >= 0)
+ {
+ const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
+ if (ai.Flags_FindSignature() && searchMarkerInHandler)
+ return S_FALSE;
+ }
}
- orderIndices = orderIndices2;
}
- else if (extension == L"000" || extension == L"001")
+
+ NArchive::NParser::CHandler *handlerSpec = new NArchive::NParser::CHandler;
+ CMyComPtr<IInArchive> handler = handlerSpec;
+
+ CExtractCallback_To_OpenCallback *extractCallback_To_OpenCallback_Spec = new CExtractCallback_To_OpenCallback;
+ CMyComPtr<IArchiveExtractCallback> extractCallback_To_OpenCallback = extractCallback_To_OpenCallback_Spec;
+ extractCallback_To_OpenCallback_Spec->Init(op.callback);
+
{
+ // ---------- Check all possible START archives ----------
+ // this code is better for full file archives than Parser's code.
+
CByteBuffer byteBuffer;
- const size_t kBufferSize = (1 << 10);
- byteBuffer.SetCapacity(kBufferSize);
- Byte *buffer = byteBuffer;
- RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
- size_t processedSize = kBufferSize;
- RINOK(ReadStream(stream, buffer, &processedSize));
- if (processedSize >= 16)
- {
- Byte kRarHeader[] = {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00};
- if (TestSignature(buffer, kRarHeader, 7) && buffer[9] == 0x73 && (buffer[10] & 1) != 0)
- {
- for (int i = 0; i < orderIndices.Size(); i++)
- {
- int index = orderIndices[i];
- const CArcInfoEx &ai = codecs->Formats[index];
- if (ai.Name.CompareNoCase(L"rar") != 0)
- continue;
- orderIndices.Delete(i--);
- orderIndices.Insert(0, index);
- break;
- }
+ bool endOfFile = false;
+ size_t processedSize;
+ {
+ size_t bufSize = 1 << 20; // it must be larger than max signature offset or IsArcFunc offset ((1 << 19) + x for UDF)
+ if (bufSize > fileSize)
+ {
+ bufSize = (size_t)fileSize;
+ endOfFile = true;
}
+ byteBuffer.Alloc(bufSize);
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+ processedSize = bufSize;
+ RINOK(ReadStream(op.stream, byteBuffer, &processedSize));
+ if (processedSize == 0)
+ return S_FALSE;
+ if (processedSize < bufSize)
+ endOfFile = true;
}
- }
- if (orderIndices.Size() >= 2)
- {
- int isoIndex = codecs->FindFormatForArchiveType(L"iso");
- int udfIndex = codecs->FindFormatForArchiveType(L"udf");
- int iIso = -1;
- int iUdf = -1;
- for (int i = 0; i < orderIndices.Size(); i++)
+ CUIntVector sortedFormats;
+
+ unsigned i;
+
+ int splitIndex = -1;
+
+ for (i = 0; i < orderIndices.Size(); i++)
{
- if (orderIndices[i] == isoIndex) iIso = i;
- if (orderIndices[i] == udfIndex) iUdf = i;
+ unsigned form = orderIndices[i];
+ if (skipFrontalFormat[form])
+ continue;
+ const CArcInfoEx &ai = op.codecs->Formats[form];
+ if (ai.IsSplit())
+ {
+ splitIndex = form;
+ continue;
+ }
+
+ if (ai.IsArcFunc)
+ {
+ UInt32 isArcRes = ai.IsArcFunc(byteBuffer, processedSize);
+ if (isArcRes == k_IsArc_Res_NO)
+ continue;
+ if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile)
+ continue;
+ // if (isArcRes == k_IsArc_Res_YES_LOW_PROB) continue;
+ sortedFormats.Insert(0, form);
+ continue;
+ }
+
+ bool isNewStyleSignature = IsNewStyleSignature(ai);
+ bool needCheck = !isNewStyleSignature
+ || ai.Signatures.IsEmpty()
+ || ai.Flags_PureStartOpen()
+ || ai.Flags_StartOpen()
+ || ai.Flags_BackwardOpen();
+
+ if (isNewStyleSignature && !ai.Signatures.IsEmpty())
+ {
+ unsigned k;
+ for (k = 0; k < ai.Signatures.Size(); k++)
+ {
+ const CByteBuffer &sig = ai.Signatures[k];
+ UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size();
+ if (processedSize < signatureEnd)
+ {
+ if (!endOfFile)
+ needCheck = true;
+ }
+ else if (memcmp(sig, byteBuffer + ai.SignatureOffset, sig.Size()) == 0)
+ break;
+ }
+ if (k != ai.Signatures.Size())
+ {
+ sortedFormats.Insert(0, form);
+ continue;
+ }
+ }
+ if (needCheck)
+ sortedFormats.Add(form);
}
- if (iUdf > iIso && iIso >= 0)
+
+ if (splitIndex >= 0)
+ sortedFormats.Insert(0, splitIndex);
+
+ for (i = 0; i < sortedFormats.Size(); i++)
{
- orderIndices[iUdf] = isoIndex;
- orderIndices[iIso] = udfIndex;
+ FormatIndex = sortedFormats[i];
+ const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
+
+ RINOK(op.callback->SetTotal(NULL, &fileSize));
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+
+ CMyComPtr<IInArchive> archive;
+ RINOK(PrepareToOpen(op, FormatIndex, archive));
+ if (!archive)
+ continue;
+
+ PRF(printf("\nSorted Open %S", (const wchar_t *)ai.Name));
+ HRESULT result;
+ {
+ UInt64 searchLimit = 0;
+ /*
+ if (mode.CanReturnArc)
+ result = archive->Open(op.stream, &searchLimit, op.callback);
+ else
+ */
+ result = OpenArchiveSpec(archive, !mode.CanReturnArc, op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback);
+ }
+
+ if (result == S_FALSE)
+ {
+ skipFrontalFormat[FormatIndex] = true;
+ // FIXME: maybe we must use LenIsUnknown.
+ // printf(" OpenForSize Error");
+ continue;
+ }
+ RINOK(result);
+
+ RINOK(ReadBasicProps(archive, 0, result));
+
+ if (Offset > 0)
+ {
+ continue; // good handler doesn't return such Offset > 0
+ // but there are some cases like false prefixed PK00 archive, when
+ // we can support it?
+ }
+
+ NArchive::NParser::CParseItem pi;
+ pi.Offset = Offset;
+ pi.Size = AvailPhySize;
+
+ // bool needScan = false;
+
+ if (!PhySizeDefined)
+ {
+ // it's for Z format
+ pi.LenIsUnknown = true;
+ // needScan = true;
+ // phySize = arcRem;
+ // nextNeedCheckStartOpen = false;
+ }
+
+ /*
+ if (OkPhySize_Defined)
+ pi.OkSize = pi.OkPhySize;
+ else
+ pi.OkSize = pi.Size;
+ */
+
+ pi.NormalizeOffset();
+ // printf(" phySize = %8d", (unsigned)phySize);
+
+
+ if (mode.CanReturnArc)
+ {
+ bool isMainFormat = isMainFormatArr[FormatIndex];
+ const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);
+ bool openCur = false;
+
+ if (!ErrorInfo.ThereIsTail)
+ openCur = true;
+ else
+ {
+ if (mode.ZerosTailIsAllowed)
+ {
+ RINOK(CheckZerosTail(op, Offset + PhySize));
+ if (ErrorInfo.IgnoreTail)
+ openCur = true;
+ }
+ if (!openCur)
+ {
+ openCur = specFlags.CanReturnFrontal;
+ if (formatIndex < 0) // format is not forced
+ {
+ if (IsPreArcFormat(ai))
+ {
+ // if (mode.SkipSfxStub)
+ {
+ openCur = false;
+ }
+ }
+ }
+ }
+ }
+
+ if (openCur)
+ {
+ InStream = op.stream;
+ Archive = archive;
+ return S_OK;
+ }
+ }
+
+ skipFrontalFormat[FormatIndex] = true;
+
+
+ // if (!mode.CanReturnArc)
+ /*
+ if (!ErrorInfo.ThereIsTail)
+ continue;
+ */
+ if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize)
+ continue;
+
+ // printf("\nAdd offset = %d", (int)pi.Offset);
+ RINOK(ReadParseItemProps(archive, ai, pi));
+ handlerSpec->AddItem(pi);
}
}
- #endif
+
+
+
+
+ // ---------- PARSER ----------
+
+ CUIntVector arc2sig; // formatIndex to signatureIndex
+ CUIntVector sig2arc; // signatureIndex to formatIndex;
+ {
+ unsigned sum = 0;
+ FOR_VECTOR (i, op.codecs->Formats)
+ {
+ arc2sig.Add(sum);
+ const CObjectVector<CByteBuffer> &sigs = op.codecs->Formats[i].Signatures;
+ sum += sigs.Size();
+ FOR_VECTOR (k, sigs)
+ sig2arc.Add(i);
+ }
}
- for (int i = 0; i < orderIndices.Size(); i++)
{
- if (stream)
+ CArchiveOpenCallback_Offset *openCallback_Offset_Spec = new CArchiveOpenCallback_Offset;
+ CMyComPtr<IArchiveOpenCallback> openCallback_Offset = openCallback_Offset_Spec;
+
+ const size_t kBeforeSize = 1 << 16;
+ const size_t kAfterSize = 1 << 20;
+ const size_t kBufSize = 1 << 22; // it must be more than kBeforeSize + kAfterSize
+
+ const UInt32 kNumVals = (UInt32)1 << (kNumHashBytes * 8);
+ CByteArr hashBuffer(kNumVals);
+ Byte *hash = hashBuffer;
+ memset(hash, 0xFF, kNumVals);
+ Byte prevs[256];
+ memset(prevs, 0xFF, sizeof(prevs));
+ if (sig2arc.Size() >= 0xFF)
+ return S_FALSE;
+
+ CUIntVector difficultFormats;
+ CBoolArr difficultBools(256);
{
- RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
+ for (unsigned i = 0; i < 256; i++)
+ difficultBools[i] = false;
}
- CMyComPtr<IInArchive> archive;
- FormatIndex = orderIndices[i];
- RINOK(codecs->CreateInArchive(FormatIndex, archive));
- if (!archive)
- continue;
+ bool thereAreHandlersForSearch = false;
- #ifdef EXTERNAL_CODECS
+ // UInt32 maxSignatureEnd = 0;
+
+ FOR_VECTOR (i, orderIndices)
{
- CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
- archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
- if (setCompressCodecsInfo)
+ int index = orderIndices[i];
+ if (index < 0)
+ continue;
+ const CArcInfoEx &ai = op.codecs->Formats[index];
+ bool isDifficult = false;
+ // if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31)
+ if (!ai.NewInterface)
+ isDifficult = true;
+ else
+ {
+ if (ai.Flags_StartOpen())
+ isDifficult = true;
+ FOR_VECTOR (k, ai.Signatures)
+ {
+ const CByteBuffer &sig = ai.Signatures[k];
+ /*
+ UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size();
+ if (maxSignatureEnd < signatureEnd)
+ maxSignatureEnd = signatureEnd;
+ */
+ if (sig.Size() < kNumHashBytes)
+ {
+ isDifficult = true;
+ continue;
+ }
+ thereAreHandlersForSearch = true;
+ UInt32 v = HASH_VAL(sig, 0);
+ unsigned sigIndex = arc2sig[index] + k;
+ prevs[sigIndex] = hash[v];
+ hash[v] = (Byte)sigIndex;
+ }
+ }
+ if (isDifficult)
{
- RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));
+ difficultFormats.Add(index);
+ difficultBools[index] = true;
}
}
+
+ if (!thereAreHandlersForSearch)
+ {
+ // openOnlyFullArc = true;
+ // canReturnTailArc = true;
+ }
+
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+
+ CLimitedCachedInStream *limitedStreamSpec = new CLimitedCachedInStream;
+ CMyComPtr<IInStream> limitedStream = limitedStreamSpec;
+ limitedStreamSpec->SetStream(op.stream);
+
+ openCallback_Offset_Spec->Callback = op.callback;
+
+ #ifndef _NO_CRYPTO
+ if (op.callback)
+ {
+ openCallback_Offset_Spec->Callback.QueryInterface(IID_ICryptoGetTextPassword, &openCallback_Offset_Spec->GetTextPassword);
+ }
#endif
- // OutputDebugStringW(codecs->Formats[FormatIndex].Name);
+ RINOK(op.callback->SetTotal(NULL, &fileSize));
+ CByteBuffer &byteBuffer = limitedStreamSpec->Buffer;
+ byteBuffer.Alloc(kBufSize);
- HRESULT result;
- if (stream)
- result = archive->Open(stream, &kMaxCheckStartPosition, callback);
- else
+ UInt64 callbackPrev = 0;
+ bool needCheckStartOpen = true; // = true, if we need to test all archives types for current pos.
+
+ bool endOfFile = false;
+ UInt64 bufPhyPos = 0;
+ size_t bytesInBuf = 0;
+ // UInt64 prevPos = 0;
+
+ // ---------- Main Scan Loop ----------
+
+ UInt64 pos = 0;
+
+ if (!mode.EachPos && handlerSpec->_items.Size() == 1)
{
- CMyComPtr<IArchiveOpenSeq> openSeq;
- archive.QueryInterface(IID_IArchiveOpenSeq, (void **)&openSeq);
- if (!openSeq)
- return E_NOTIMPL;
- result = openSeq->OpenSeq(seqStream);
+ NArchive::NParser::CParseItem &pi = handlerSpec->_items[0];
+ if (!pi.LenIsUnknown && pi.Offset == 0)
+ pos = pi.Size;
}
- if (result == S_FALSE)
- continue;
- RINOK(result);
+ for (;;)
+ {
+ // printf("\nPos = %d", (int)pos);
+ UInt64 posInBuf = pos - bufPhyPos;
+
+ // if (pos > ((UInt64)1 << 35)) break;
+
+ if (!endOfFile)
+ {
+ if (bytesInBuf < kBufSize)
+ {
+ size_t processedSize = kBufSize - bytesInBuf;
+ // printf("\nRead ask = %d", (unsigned)processedSize);
+ UInt64 seekPos = bufPhyPos + bytesInBuf;
+ RINOK(op.stream->Seek(bufPhyPos + bytesInBuf, STREAM_SEEK_SET, NULL));
+ RINOK(ReadStream(op.stream, byteBuffer + bytesInBuf, &processedSize));
+ // printf(" processed = %d", (unsigned)processedSize);
+ if (processedSize == 0)
+ {
+ fileSize = seekPos;
+ endOfFile = true;
+ }
+ else
+ {
+ bytesInBuf += processedSize;
+ limitedStreamSpec->SetCache(processedSize, (size_t)bufPhyPos);
+ }
+ continue;
+ }
+
+ if (bytesInBuf < posInBuf)
+ {
+ UInt64 skipSize = posInBuf - bytesInBuf;
+ if (skipSize <= kBeforeSize)
+ {
+ size_t keepSize = (size_t)(kBeforeSize - skipSize);
+ // printf("\nmemmove skip = %d", (int)keepSize);
+ memmove(byteBuffer, byteBuffer + bytesInBuf - keepSize, keepSize);
+ bytesInBuf = keepSize;
+ bufPhyPos = pos - keepSize;
+ continue;
+ }
+ // printf("\nSkip %d", (int)(skipSize - kBeforeSize));
+ // RINOK(op.stream->Seek(skipSize - kBeforeSize, STREAM_SEEK_CUR, NULL));
+ bytesInBuf = 0;
+ bufPhyPos = pos - kBeforeSize;
+ continue;
+ }
+
+ if (bytesInBuf - posInBuf < kAfterSize)
+ {
+ size_t beg = (size_t)posInBuf - kBeforeSize;
+ // printf("\nmemmove for after beg = %d", (int)beg);
+ memmove(byteBuffer, byteBuffer + beg, bytesInBuf - beg);
+ bufPhyPos += beg;
+ bytesInBuf -= beg;
+ continue;
+ }
+ }
+
+ if (pos >= callbackPrev + (1 << 23))
+ {
+ openCallback_Offset_Spec->Files = handlerSpec->_items.Size();
+ openCallback_Offset_Spec->Offset = pos;
+ RINOK(openCallback_Offset->SetCompleted(NULL, NULL));
+ callbackPrev = pos;
+ }
+
+ {
+ UInt64 endPos = bufPhyPos + bytesInBuf;
+ if (fileSize < endPos)
+ {
+ FileSize = fileSize; // why ????
+ fileSize = endPos;
+ }
+ }
+
+ size_t availSize = bytesInBuf - (size_t)posInBuf;
+ if (availSize < kNumHashBytes)
+ break;
+ size_t scanSize = availSize -
+ ((availSize >= kAfterSize) ? kAfterSize : kNumHashBytes);
+
+ {
+ /*
+ UInt64 scanLimit = openOnlyFullArc ?
+ maxSignatureEnd :
+ op.openType.ScanSize + maxSignatureEnd;
+ */
+ if (!mode.CanReturnParser)
+ {
+ if (pos > maxStartOffset)
+ break;
+ UInt64 remScan = maxStartOffset - pos;
+ if (scanSize > remScan)
+ scanSize = (size_t)remScan;
+ }
+ }
+ scanSize++;
+
+ const Byte *buf = byteBuffer + (size_t)posInBuf;
+ size_t ppp = 0;
+
+ if (!needCheckStartOpen)
+ {
+ for (; ppp < scanSize && hash[HASH_VAL(buf, ppp)] == 0xFF; ppp++);
+ pos += ppp;
+ if (ppp == scanSize)
+ continue;
+ }
+
+ UInt32 v = HASH_VAL(buf, ppp);
+ bool nextNeedCheckStartOpen = true;
+ unsigned i = hash[v];
+ unsigned indexOfDifficult = 0;
+
+ // ---------- Open Loop for Current Pos ----------
+ bool wasOpen = false;
+
+ for (;;)
+ {
+ unsigned index;
+ bool isDifficult;
+ if (needCheckStartOpen && indexOfDifficult < difficultFormats.Size())
+ {
+ index = difficultFormats[indexOfDifficult++];
+ isDifficult = true;
+ }
+ else
+ {
+ if (i == 0xFF)
+ break;
+ index = sig2arc[i];
+ unsigned sigIndex = i - arc2sig[index];
+ i = prevs[i];
+ if (needCheckStartOpen && difficultBools[index])
+ continue;
+ const CArcInfoEx &ai = op.codecs->Formats[index];
+
+ if (pos < ai.SignatureOffset)
+ continue;
+
+ /*
+ if (openOnlyFullArc)
+ if (pos != ai.SignatureOffset)
+ continue;
+ */
+
+ const CByteBuffer &sig = ai.Signatures[sigIndex];
+
+ if (ppp + sig.Size() > availSize
+ || !TestSignature(buf + ppp, sig, sig.Size()))
+ continue;
+ // printf("\nSignature OK: %10S %8x %5d", (const wchar_t *)ai.Name, (int)pos, (int)(pos - prevPos));
+ // prevPos = pos;
+ isDifficult = false;
+ }
+
+ const CArcInfoEx &ai = op.codecs->Formats[index];
+
+
+ if ((isDifficult && pos == 0) || ai.SignatureOffset == pos)
+ {
+ // we don't check same archive second time */
+ if (skipFrontalFormat[index])
+ continue;
+ }
+
+ UInt64 startArcPos = pos;
+ if (!isDifficult)
+ {
+ if (pos < ai.SignatureOffset)
+ continue;
+ startArcPos = pos - ai.SignatureOffset;
+ /*
+ // we don't need the check for Z files
+ if (startArcPos < handlerSpec->GetLastEnd())
+ continue;
+ */
+ }
+
+ if (ai.IsArcFunc && startArcPos >= bufPhyPos)
+ {
+ size_t offsetInBuf = (size_t)(startArcPos - bufPhyPos);
+ if (offsetInBuf < bytesInBuf)
+ {
+ UInt32 isArcRes = ai.IsArcFunc(byteBuffer + offsetInBuf, bytesInBuf - offsetInBuf);
+ if (isArcRes == k_IsArc_Res_NO)
+ continue;
+ if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile)
+ continue;
+ /*
+ if (isArcRes == k_IsArc_Res_YES_LOW_PROB)
+ {
+ // if (pos != ai.SignatureOffset)
+ continue;
+ }
+ */
+ }
+ // printf("\nIsArc OK: %S", (const wchar_t *)ai.Name);
+ }
+
+ /*
+ if (pos == 67109888)
+ pos = pos;
+ */
+ PRF(printf("\npos = %9I64d : %S", pos, (const wchar_t *)ai.Name));
+
+ bool isMainFormat = isMainFormatArr[index];
+ const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);
+
+ CMyComPtr<IInArchive> archive;
+ RINOK(PrepareToOpen(op, index, archive));
+ if (!archive)
+ return E_FAIL;
+
+ // OutputDebugStringW(ai.Name);
+
+ UInt64 rem = fileSize - startArcPos;
+
+ UInt64 arcStreamOffset = 0;
+
+ if (ai.Flags_UseGlobalOffset())
+ {
+ limitedStreamSpec->InitAndSeek(0, fileSize);
+ limitedStream->Seek(startArcPos, STREAM_SEEK_SET, NULL);
+ }
+ else
+ {
+ limitedStreamSpec->InitAndSeek(startArcPos, rem);
+ arcStreamOffset = startArcPos;
+ }
+
+ UInt64 maxCheckStartPosition = 0;
+ openCallback_Offset_Spec->Files = handlerSpec->_items.Size();
+ openCallback_Offset_Spec->Offset = startArcPos;
+ // HRESULT result = archive->Open(limitedStream, &maxCheckStartPosition, openCallback_Offset);
+ extractCallback_To_OpenCallback_Spec->Files = 0;
+ extractCallback_To_OpenCallback_Spec->Offset = startArcPos;
+
+ HRESULT result = OpenArchiveSpec(archive, true, limitedStream, &maxCheckStartPosition, openCallback_Offset, extractCallback_To_OpenCallback);
+
+ RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result));
+
+ bool isOpen = false;
+ if (result == S_FALSE)
+ {
+ if (!mode.CanReturnParser)
+ {
+ if (formatIndex < 0 && ErrorInfo.IsArc_After_NonOpen())
+ {
+ ErrorInfo.ErrorFormatIndex = index;
+ NonOpen_ErrorInfo = ErrorInfo;
+ // if archive was detected, we don't need additional open attempts
+ return S_FALSE;
+ }
+ continue;
+ }
+ if (!ErrorInfo.IsArc_After_NonOpen() || !PhySizeDefined || PhySize == 0)
+ continue;
+ }
+ else
+ {
+ isOpen = true;
+ RINOK(result);
+ PRF(printf(" OK "));
+ }
+
+ // fprintf(stderr, "\n %8X %S", startArcPos, Path);
+ // printf("\nOpen OK: %S", ai.Name);
+
+
+ NArchive::NParser::CParseItem pi;
+ pi.Offset = startArcPos;
+
+ if (ai.Flags_UseGlobalOffset())
+ pi.Offset = Offset;
+ else if (Offset != 0)
+ return E_FAIL;
+ UInt64 arcRem = FileSize - pi.Offset;
+ UInt64 phySize = arcRem;
+ bool phySizeDefined = PhySizeDefined;
+ if (phySizeDefined)
+ {
+ if (pi.Offset + PhySize > FileSize)
+ {
+ // ErrorInfo.ThereIsTail = true;
+ PhySize = FileSize - pi.Offset;
+ }
+ phySize = PhySize;
+ }
+ if (phySize == 0 || (UInt64)phySize > ((UInt64)1 << 63))
+ return E_FAIL;
+
+ /*
+ if (!ai.UseGlobalOffset)
+ {
+ if (phySize > arcRem)
+ {
+ ThereIsTail = true;
+ phySize = arcRem;
+ }
+ }
+ */
+
+ bool needScan = false;
+
+
+ if (isOpen && !phySizeDefined)
+ {
+ // it's for Z format
+ pi.LenIsUnknown = true;
+ needScan = true;
+ phySize = arcRem;
+ nextNeedCheckStartOpen = false;
+ }
+
+ pi.Size = phySize;
+ /*
+ if (OkPhySize_Defined)
+ pi.OkSize = OkPhySize;
+ */
+ pi.NormalizeOffset();
+ // printf(" phySize = %8d", (unsigned)phySize);
+
+ /*
+ if (needSkipFullArc)
+ if (pi.Offset == 0 && phySizeDefined && pi.Size >= fileSize)
+ continue;
+ */
+ if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize)
+ {
+ // it's possible for dmg archives
+ if (!mode.CanReturnArc)
+ continue;
+ }
+
+ if (mode.EachPos)
+ pos++;
+ else if (needScan)
+ {
+ pos++;
+ /*
+ if (!OkPhySize_Defined)
+ pos++;
+ else
+ pos = pi.Offset + pi.OkSize;
+ */
+ }
+ else
+ pos = pi.Offset + pi.Size;
+
+
+ RINOK(ReadParseItemProps(archive, ai, pi));
+
+ if (pi.Offset < startArcPos && !mode.EachPos /* && phySizeDefined */)
+ {
+ /* It's for DMG format.
+ This code deletes all previous items that are included to current item */
+
+ while (!handlerSpec->_items.IsEmpty())
+ {
+ {
+ const NArchive::NParser::CParseItem &back = handlerSpec->_items.Back();
+ if (back.Offset < pi.Offset)
+ break;
+ if (back.Offset + back.Size > pi.Offset + pi.Size)
+ break;
+ }
+ handlerSpec->_items.DeleteBack();
+ }
+ }
+
+
+ if (isOpen && mode.CanReturnArc && phySizeDefined)
+ {
+ // if (pi.Offset + pi.Size >= fileSize)
+ bool openCur = false;
+
+ bool thereIsTail = ErrorInfo.ThereIsTail;
+ if (thereIsTail && mode.ZerosTailIsAllowed)
+ {
+ RINOK(CheckZerosTail(op, arcStreamOffset + Offset + PhySize));
+ if (ErrorInfo.IgnoreTail)
+ thereIsTail = false;
+ }
+
+ if (pi.Offset != 0)
+ {
+ if (!pi.IsNotArcType)
+ if (thereIsTail)
+ openCur = specFlags.CanReturnMid;
+ else
+ openCur = specFlags.CanReturnTail;
+ }
+ else
+ {
+ if (!thereIsTail)
+ openCur = true;
+ else
+ openCur = specFlags.CanReturnFrontal;
+
+
+ if (formatIndex >= -2)
+ openCur = true;
+ }
+ if (formatIndex < 0 && pi.IsSelfExe /* && mode.SkipSfxStub */)
+ openCur = false;
+
+ // We open file as SFX, if there is front archive or first archive is "Self Executable"
+ if (!openCur && !pi.IsSelfExe && !thereIsTail &&
+ (!pi.IsNotArcType || pi.Offset == 0))
+ {
+ if (handlerSpec->_items.IsEmpty())
+ {
+ if (specFlags.CanReturnTail)
+ openCur = true;
+ }
+ else if (handlerSpec->_items.Size() == 1)
+ {
+ if (handlerSpec->_items[0].IsSelfExe)
+ {
+ if (mode.SpecUnknownExt.CanReturnTail)
+ openCur = true;
+ }
+ }
+ }
+
+ if (openCur)
+ {
+ InStream = op.stream;
+ Archive = archive;
+ FormatIndex = index;
+ ArcStreamOffset = arcStreamOffset;
+ return S_OK;
+ }
+ }
+
+ /*
+ if (openOnlyFullArc)
+ {
+ ErrorInfo.ClearErrors();
+ return S_FALSE;
+ }
+ */
+
+ pi.FormatIndex = index;
+
+ // printf("\nAdd offset = %d", (int)pi.Offset);
+ handlerSpec->AddItem(pi);
+ wasOpen = true;
+ break;
+ }
+ // ---------- End of Open Loop for Current Pos ----------
+
+ if (!wasOpen)
+ pos++;
+ needCheckStartOpen = (nextNeedCheckStartOpen && wasOpen);
+ }
+ // ---------- End of Main Scan Loop ----------
+
+ /*
+ if (handlerSpec->_items.Size() == 1)
{
- NCOM::CPropVariant prop;
- archive->GetArchiveProperty(kpidError, &prop);
- if (prop.vt != VT_EMPTY)
- ErrorMessage = (prop.vt == VT_BSTR) ? prop.bstrVal : L"Unknown error";
- }
-
- Archive = archive;
- const CArcInfoEx &format = codecs->Formats[FormatIndex];
- if (format.Exts.Size() == 0)
- DefaultName = GetDefaultName2(fileName, L"", L"");
- else
+ const NArchive::NParser::CParseItem &pi = handlerSpec->_items[0];
+ if (pi.Size == fileSize && pi.Offset == 0)
+ {
+ Archive = archive;
+ FormatIndex2 = pi.FormatIndex;
+ return S_OK;
+ }
+ }
+ */
+
+ if (mode.CanReturnParser)
{
- int subExtIndex = format.FindExtension(extension);
- if (subExtIndex < 0)
- subExtIndex = 0;
- const CArcExtInfo &extInfo = format.Exts[subExtIndex];
- DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt);
+ bool returnParser = (handlerSpec->_items.Size() == 1); // it's possible if fileSize was not correct at start of parsing
+ handlerSpec->AddUnknownItem(fileSize);
+ if (handlerSpec->_items.Size() == 0)
+ return S_FALSE;
+ if (returnParser || handlerSpec->_items.Size() != 1)
+ {
+ // return S_FALSE;
+ handlerSpec->_stream = op.stream;
+ Archive = handler;
+ ErrorInfo.ClearErrors();
+ IsParseArc = true;
+ FormatIndex = -1; // It's parser
+ Offset = 0;
+ return S_OK;
+ }
+ }
+ }
+
+ #endif
+
+ if (!Archive)
+ return S_FALSE;
+ return S_OK;
+}
+
+HRESULT CArc::OpenStream(const COpenOptions &op)
+{
+ RINOK(OpenStream2(op));
+ // PrintNumber("op.formatIndex 3", op.formatIndex);
+
+ if (Archive)
+ {
+ GetRawProps.Release();
+ GetRootProps.Release();
+ Archive->QueryInterface(IID_IArchiveGetRawProps, (void **)&GetRawProps);
+ Archive->QueryInterface(IID_IArchiveGetRootProps, (void **)&GetRootProps);
+
+ RINOK(Archive_GetArcBoolProp(Archive, kpidIsTree, IsTree));
+ RINOK(Archive_GetArcBoolProp(Archive, kpidIsDeleted, Ask_Deleted));
+ RINOK(Archive_GetArcBoolProp(Archive, kpidIsAltStream, Ask_AltStream));
+ RINOK(Archive_GetArcBoolProp(Archive, kpidIsAux, Ask_Aux));
+ RINOK(Archive_GetArcBoolProp(Archive, kpidINode, Ask_INode));
+
+ const UString fileName = ExtractFileNameFromPath(Path);
+ UString extension;
+ {
+ int dotPos = fileName.ReverseFind(L'.');
+ if (dotPos >= 0)
+ extension = fileName.Ptr(dotPos + 1);
+ }
+
+ DefaultName.Empty();
+ if (FormatIndex >= 0)
+ {
+ const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
+ if (ai.Exts.Size() == 0)
+ DefaultName = GetDefaultName2(fileName, L"", L"");
+ else
+ {
+ int subExtIndex = ai.FindExtension(extension);
+ if (subExtIndex < 0)
+ subExtIndex = 0;
+ const CArcExtInfo &extInfo = ai.Exts[subExtIndex];
+ DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt);
+ }
}
- return S_OK;
}
- return S_FALSE;
+
+ return S_OK;
}
-HRESULT CArc::OpenStreamOrFile(
- CCodecs *codecs,
- int formatIndex,
- bool stdInMode,
- IInStream *stream,
- IArchiveOpenCallback *callback)
+#ifdef _SFX
+
+#ifdef _WIN32
+ static const wchar_t *k_ExeExt = L".exe";
+ static const unsigned k_ExeExt_Len = 4;
+#else
+ static const wchar_t *k_ExeExt = L"";
+ static const unsigned k_ExeExt_Len = 0;
+#endif
+
+#endif
+
+HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
{
CMyComPtr<IInStream> fileStream;
CMyComPtr<ISequentialInStream> seqStream;
- if (stdInMode)
+ CInFileStream *fileStreamSpec = NULL;
+ if (op.stdInMode)
+ {
seqStream = new CStdInFileStream;
- else if (!stream)
+ op.seqStream = seqStream;
+ }
+ else if (!op.stream)
{
- CInFileStream *fileStreamSpec = new CInFileStream(true);
+ fileStreamSpec = new CInFileStream(true);
fileStream = fileStreamSpec;
- if (!fileStreamSpec->Open(Path))
+ Path = filePath;
+ if (!fileStreamSpec->Open(us2fs(Path)))
+ {
return GetLastError();
- stream = fileStream;
+ }
+ op.stream = fileStream;
+ #ifdef _SFX
+ IgnoreSplit = true;
+ #endif
}
/*
if (callback)
{
UInt64 fileSize;
- RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize));
- RINOK(callback->SetTotal(NULL, &fileSize))
+ RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize));
+ RINOK(op.callback->SetTotal(NULL, &fileSize))
}
*/
- return OpenStream(codecs, formatIndex, stream, seqStream, callback);
+ HRESULT res = OpenStream(op);
+ IgnoreSplit = false;
+
+ #ifdef _SFX
+
+ if (res != S_FALSE
+ || !fileStreamSpec
+ || !op.callbackSpec
+ || NonOpen_ErrorInfo.IsArc_After_NonOpen())
+ return res;
+ {
+ if (filePath.Len() > k_ExeExt_Len
+ && MyStringCompareNoCase(filePath.RightPtr(k_ExeExt_Len), k_ExeExt) == 0)
+ {
+ const UString path2 = filePath.Left(filePath.Len() - k_ExeExt_Len);
+ FOR_VECTOR (i, op.codecs->Formats)
+ {
+ const CArcInfoEx &ai = op.codecs->Formats[i];
+ if (ai.IsSplit())
+ continue;
+ UString path3 = path2;
+ path3 += L".";
+ path3 += ai.GetMainExt(); // "7z" for SFX.
+ Path = path3 + L".001";
+ bool isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path));
+ if (!isOk)
+ {
+ Path = path3;
+ isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path));
+ }
+ if (isOk)
+ {
+ if (fileStreamSpec->Open(us2fs(Path)))
+ {
+ op.stream = fileStream;
+ NonOpen_ErrorInfo.ClearErrors_Full();
+ if (OpenStream(op) == S_OK)
+ return S_OK;
+ }
+ }
+ }
+ }
+ }
+
+ #endif
+
+ return res;
+}
+
+void CArchiveLink::KeepModeForNextOpen()
+{
+ for (int i = Arcs.Size() - 1; i >= 0; i--)
+ {
+ CMyComPtr<IArchiveKeepModeForNextOpen> keep;
+ Arcs[i].Archive->QueryInterface(IID_IArchiveKeepModeForNextOpen, (void **)&keep);
+ if (keep)
+ keep->KeepModeForNextOpen();
+ }
}
HRESULT CArchiveLink::Close()
{
- for (int i = Arcs.Size() - 1; i >= 0; i--)
+ for (int i = Arcs.Size() - 1; i >= 0; i--)
{
- RINOK(Arcs[i].Archive->Close());
+ RINOK(Arcs[i].Close());
}
IsOpen = false;
+ // ErrorsText.Empty();
return S_OK;
}
void CArchiveLink::Release()
{
+ // NonOpenErrorFormatIndex = -1;
+ NonOpen_ErrorInfo.ClearErrors();
+ NonOpen_ArcPath.Empty();
while (!Arcs.IsEmpty())
Arcs.DeleteBack();
}
-HRESULT CArchiveLink::Open(
- CCodecs *codecs,
- const CIntVector &formatIndices,
- bool stdInMode,
- IInStream *stream,
- const UString &filePath,
- IArchiveOpenCallback *callback)
+/*
+void CArchiveLink::Set_ErrorsText()
+{
+ FOR_VECTOR(i, Arcs)
+ {
+ const CArc &arc = Arcs[i];
+ if (!arc.ErrorFlagsText.IsEmpty())
+ {
+ if (!ErrorsText.IsEmpty())
+ ErrorsText += L'\n';
+ ErrorsText += GetUnicodeString(arc.ErrorFlagsText);
+ }
+ if (!arc.ErrorMessage.IsEmpty())
+ {
+ if (!ErrorsText.IsEmpty())
+ ErrorsText += L'\n';
+ ErrorsText += arc.ErrorMessage;
+ }
+
+ if (!arc.WarningMessage.IsEmpty())
+ {
+ if (!ErrorsText.IsEmpty())
+ ErrorsText += L'\n';
+ ErrorsText += arc.WarningMessage;
+ }
+ }
+}
+*/
+
+HRESULT CArchiveLink::Open(COpenOptions &op)
{
Release();
- if (formatIndices.Size() >= 32)
+ if (op.types->Size() >= 32)
return E_NOTIMPL;
-
+
HRESULT resSpec;
for (;;)
{
resSpec = S_OK;
- int formatIndex = -1;
- if (formatIndices.Size() >= 1)
+
+ op.openType = COpenType();
+ if (op.types->Size() >= 1)
{
- if (Arcs.Size() >= formatIndices.Size())
- break;
- formatIndex = formatIndices[formatIndices.Size() - Arcs.Size() - 1];
+ COpenType latest;
+ if (Arcs.Size() < op.types->Size())
+ latest = (*op.types)[op.types->Size() - Arcs.Size() - 1];
+ else
+ {
+ latest = (*op.types)[0];
+ if (!latest.Recursive)
+ break;
+ }
+ op.openType = latest;
}
else if (Arcs.Size() >= 32)
break;
+ /*
+ op.formatIndex = -1;
+ if (op.types->Size() >= 1)
+ {
+ int latest;
+ if (Arcs.Size() < op.types->Size())
+ latest = (*op.types)[op.types->Size() - Arcs.Size() - 1];
+ else
+ {
+ latest = (*op.types)[0];
+ if (latest != -2 && latest != -3)
+ break;
+ }
+ if (latest >= 0)
+ op.formatIndex = latest;
+ else if (latest == -1 || latest == -2)
+ {
+ // default
+ }
+ else if (latest == -3)
+ op.formatIndex = -2;
+ else
+ op.formatIndex = latest + 2;
+ }
+ else if (Arcs.Size() >= 32)
+ break;
+ */
+
if (Arcs.IsEmpty())
{
CArc arc;
- arc.Path = filePath;
+ arc.filePath = op.filePath;
+ arc.Path = op.filePath;
arc.SubfileIndex = (UInt32)(Int32)-1;
- RINOK(arc.OpenStreamOrFile(codecs, formatIndex, stdInMode, stream, callback));
+ HRESULT result = arc.OpenStreamOrFile(op);
+ if (result != S_OK)
+ {
+ if (result == S_FALSE)
+ {
+ NonOpen_ErrorInfo = arc.NonOpen_ErrorInfo;
+ // NonOpenErrorFormatIndex = arc.ErrorFormatIndex;
+ NonOpen_ArcPath = arc.Path;
+ }
+ return result;
+ }
Arcs.Add(arc);
continue;
}
-
+
+ // PrintNumber("op.formatIndex 11", op.formatIndex);
+
const CArc &arc = Arcs.Back();
-
- resSpec = (formatIndices.Size() == 0 ? S_OK : E_NOTIMPL);
-
+
+ if (op.types->Size() > Arcs.Size())
+ resSpec = E_NOTIMPL;
+
UInt32 mainSubfile;
{
NCOM::CPropVariant prop;
@@ -427,41 +2890,68 @@ HRESULT CArchiveLink::Open(
break;
}
-
+
CMyComPtr<IInArchiveGetStream> getStream;
if (arc.Archive->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream) != S_OK || !getStream)
break;
-
+
CMyComPtr<ISequentialInStream> subSeqStream;
if (getStream->GetStream(mainSubfile, &subSeqStream) != S_OK || !subSeqStream)
break;
-
+
CMyComPtr<IInStream> subStream;
if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK || !subStream)
break;
-
+
CArc arc2;
RINOK(arc.GetItemPath(mainSubfile, arc2.Path));
-
+
+ bool zerosTailIsAllowed;
+ RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed));
+
CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
- callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
+ op.callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
if (setSubArchiveName)
setSubArchiveName->SetSubArchiveName(arc2.Path);
-
+
arc2.SubfileIndex = mainSubfile;
- HRESULT result = arc2.OpenStream(codecs, formatIndex, subStream, NULL, callback);
- resSpec = (formatIndices.Size() == 0 ? S_OK : S_FALSE);
+
+ // CIntVector incl;
+ CIntVector excl;
+
+ COpenOptions op2;
+ #ifndef _SFX
+ op2.props = op.props;
+ #endif
+ op2.codecs = op.codecs;
+ // op2.types = &incl;
+ op2.openType = op.openType;
+ op2.openType.ZerosTailIsAllowed = zerosTailIsAllowed;
+ op2.excludedFormats = &excl;
+ op2.stdInMode = false;
+ op2.stream = subStream;
+ op2.filePath = arc2.Path;
+ op2.callback = op.callback;
+ op2.callbackSpec = op.callbackSpec;
+
+
+ HRESULT result = arc2.OpenStream(op2);
+ resSpec = (op.types->Size() == 0 ? S_OK : S_FALSE);
if (result == S_FALSE)
+ {
+ NonOpen_ErrorInfo = arc2.ErrorInfo;
+ NonOpen_ArcPath = arc2.Path;
break;
+ }
RINOK(result);
RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined));
Arcs.Add(arc2);
}
IsOpen = !Arcs.IsEmpty();
- return S_OK;
+ return resSpec;
}
-static void SetCallback(const UString &filePath,
+static void SetCallback(const FString &filePath,
IOpenCallbackUI *callbackUI,
IArchiveOpenCallback *reOpenCallback,
CMyComPtr<IArchiveOpenCallback> &callback)
@@ -471,19 +2961,12 @@ static void SetCallback(const UString &filePath,
openCallbackSpec->Callback = callbackUI;
openCallbackSpec->ReOpenCallback = reOpenCallback;
- UString fullName;
- int fileNamePartStartIndex;
- NFile::NDirectory::MyGetFullPathName(filePath, fullName, fileNamePartStartIndex);
- openCallbackSpec->Init(
- fullName.Left(fileNamePartStartIndex),
- fullName.Mid(fileNamePartStartIndex));
+ FString dirPrefix, fileName;
+ NFile::NDir::GetFullPathAndSplit(filePath, dirPrefix, fileName);
+ openCallbackSpec->Init(dirPrefix, fileName);
}
-HRESULT CArchiveLink::Open2(CCodecs *codecs,
- const CIntVector &formatIndices,
- bool stdInMode,
- IInStream *stream,
- const UString &filePath,
+HRESULT CArchiveLink::Open2(COpenOptions &op,
IOpenCallbackUI *callbackUI)
{
VolumesSize = 0;
@@ -491,46 +2974,237 @@ HRESULT CArchiveLink::Open2(CCodecs *codecs,
CMyComPtr<IArchiveOpenCallback> callback = openCallbackSpec;
openCallbackSpec->Callback = callbackUI;
- UString fullName, prefix, name;
- if (!stream && !stdInMode)
+ FString prefix, name;
+ if (!op.stream && !op.stdInMode)
{
- int fileNamePartStartIndex;
- if (!NFile::NDirectory::MyGetFullPathName(filePath, fullName, fileNamePartStartIndex))
- return GetLastError();
- prefix = fullName.Left(fileNamePartStartIndex);
- name = fullName.Mid(fileNamePartStartIndex);
+ NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), prefix, name);
openCallbackSpec->Init(prefix, name);
}
else
{
- openCallbackSpec->SetSubArchiveName(filePath);
+ openCallbackSpec->SetSubArchiveName(op.filePath);
}
- RINOK(Open(codecs, formatIndices, stdInMode, stream, filePath, callback));
- VolumePaths.Add(prefix + name);
- for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)
- VolumePaths.Add(prefix + openCallbackSpec->FileNames[i]);
- VolumesSize = openCallbackSpec->TotalSize;
+ op.callback = callback;
+ op.callbackSpec = openCallbackSpec;
+ RINOK(Open(op));
+ // VolumePaths.Add(fs2us(prefix + name));
+
+ FOR_VECTOR (i, openCallbackSpec->FileNames_WasUsed)
+ {
+ if (openCallbackSpec->FileNames_WasUsed[i])
+ {
+ VolumePaths.Add(fs2us(prefix) + openCallbackSpec->FileNames[i]);
+ VolumesSize += openCallbackSpec->FileSizes[i];
+ }
+ }
+ // VolumesSize = openCallbackSpec->TotalSize;
return S_OK;
}
-HRESULT CArchiveLink::ReOpen(CCodecs *codecs, const UString &filePath,
- IArchiveOpenCallback *callback)
+HRESULT CArc::ReOpen(const COpenOptions &op)
+{
+ ErrorInfo.ClearErrors();
+ ErrorInfo.ErrorFormatIndex = -1;
+
+ UInt64 fileSize = 0;
+ if (op.stream)
+ {
+ RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize));
+ RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
+ }
+ FileSize = fileSize;
+
+ CMyComPtr<IInStream> stream2;
+ Int64 globalOffset = GetGlobalOffset();
+ if (globalOffset <= 0)
+ stream2 = op.stream;
+ else
+ {
+ CTailInStream *tailStreamSpec = new CTailInStream;
+ stream2 = tailStreamSpec;
+ tailStreamSpec->Stream = op.stream;
+ tailStreamSpec->Offset = globalOffset;
+ tailStreamSpec->Init();
+ RINOK(tailStreamSpec->SeekToStart());
+ }
+
+ // There are archives with embedded STUBs (like ZIP), so we must support signature scanning
+ // But for another archives we can use 0 here. So the code can be fixed !!!
+ UInt64 maxStartPosition = kMaxCheckStartPosition;
+ HRESULT res = Archive->Open(stream2, &maxStartPosition, op.callback);
+
+ if (res == S_OK)
+ {
+ RINOK(ReadBasicProps(Archive, globalOffset, res));
+ ArcStreamOffset = globalOffset;
+ if (ArcStreamOffset != 0)
+ InStream = op.stream;
+ }
+ return res;
+}
+
+
+HRESULT CArchiveLink::ReOpen(COpenOptions &op)
{
if (Arcs.Size() > 1)
return E_NOTIMPL;
- if (Arcs.Size() == 0)
- return Open2(codecs, CIntVector(), false, NULL, filePath, 0);
+ CObjectVector<COpenType> inc;
+ CIntVector excl;
- CMyComPtr<IArchiveOpenCallback> openCallbackNew;
- SetCallback(filePath, NULL, callback, openCallbackNew);
+ op.types = &inc;
+ op.excludedFormats = &excl;
+ op.stdInMode = false;
+ op.stream = NULL;
+ if (Arcs.Size() == 0) // ???
+ return Open2(op, NULL);
+ CMyComPtr<IArchiveOpenCallback> openCallbackNew;
+ SetCallback(us2fs(op.filePath), NULL, op.callback, openCallbackNew);
CInFileStream *fileStreamSpec = new CInFileStream(true);
CMyComPtr<IInStream> stream(fileStreamSpec);
- if (!fileStreamSpec->Open(filePath))
+ if (!fileStreamSpec->Open(us2fs(op.filePath)))
return GetLastError();
- HRESULT res = GetArchive()->Open(stream, &kMaxCheckStartPosition, callback);
+ op.stream = stream;
+
+ CArc &arc = Arcs[0];
+ HRESULT res = arc.ReOpen(op);
IsOpen = (res == S_OK);
return res;
}
+
+#ifndef _SFX
+
+bool ParseComplexSize(const wchar_t *s, UInt64 &result)
+{
+ result = 0;
+ const wchar_t *end;
+ UInt64 number = ConvertStringToUInt64(s, &end);
+ if (end == s)
+ return false;
+ if (*end == 0)
+ {
+ result = number;
+ return true;
+ }
+ if (end[1] != 0)
+ return false;
+ unsigned numBits;
+ switch (MyCharLower_Ascii(*end))
+ {
+ case 'b': result = number; return true;
+ case 'k': numBits = 10; break;
+ case 'm': numBits = 20; break;
+ case 'g': numBits = 30; break;
+ case 't': numBits = 40; break;
+ default: return false;
+ }
+ if (number >= ((UInt64)1 << (64 - numBits)))
+ return false;
+ result = number << numBits;
+ return true;
+}
+
+static bool ParseTypeParams(const UString &s, COpenType &type)
+{
+ if (s[0] == 0)
+ return true;
+ if (s[1] == 0)
+ {
+ switch ((unsigned)(Byte)s[0])
+ {
+ case 'e': type.EachPos = true; return true;
+ case 'a': type.CanReturnArc = true; return true;
+ case 'r': type.Recursive = true; return true;
+ }
+ return false;
+ }
+ if (s[0] == 's')
+ {
+ UInt64 result;
+ if (!ParseComplexSize(s.Ptr(1), result))
+ return false;
+ type.MaxStartOffset = result;
+ type.MaxStartOffset_Defined = true;
+ return true;
+ }
+
+ return false;
+}
+
+bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
+{
+ int pos2 = s.Find(':');
+ UString name;
+ if (pos2 < 0)
+ {
+ name = s;
+ pos2 = s.Len();
+ }
+ else
+ {
+ name = s.Left(pos2);
+ pos2++;
+ }
+
+ int index = codecs.FindFormatForArchiveType(name);
+ type.Recursive = false;
+
+ if (index < 0)
+ {
+ if (name[0] == '*')
+ {
+ if (name[1] != 0)
+ return false;
+ }
+ else if (name[0] == '#')
+ {
+ if (name[1] != 0)
+ return false;
+ type.CanReturnArc = false;
+ type.CanReturnParser = true;
+ }
+ else
+ return false;
+ }
+
+ type.FormatIndex = index;
+
+ for (unsigned i = pos2; i < s.Len();)
+ {
+ int next = s.Find(':', i);
+ if (next < 0)
+ next = s.Len();
+ UString name = s.Mid(i, next - i);
+ if (name.IsEmpty())
+ return false;
+ if (!ParseTypeParams(name, type))
+ return false;
+ i = next + 1;
+ }
+
+ return true;
+}
+
+bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types)
+{
+ types.Clear();
+ for (unsigned pos = 0; pos < s.Len();)
+ {
+ int pos2 = s.Find('.', pos);
+ if (pos2 < 0)
+ pos2 = s.Len();
+ UString name = s.Mid(pos, pos2 - pos);
+ if (name.IsEmpty())
+ return false;
+ COpenType type;
+ if (!ParseType(codecs, name, type))
+ return false;
+ types.Add(type);
+ pos = pos2 + 1;
+ }
+ return true;
+}
+
+#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/OpenArchive.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/OpenArchive.h
index 4a003ee63..f2a5ce9fe 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/OpenArchive.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/OpenArchive.h
@@ -3,49 +3,309 @@
#ifndef __OPEN_ARCHIVE_H
#define __OPEN_ARCHIVE_H
-#include "Common/MyString.h"
-
-#include "Windows/FileFind.h"
-
-#include "../../Archive/IArchive.h"
+#include "../../../Windows/PropVariant.h"
#include "ArchiveOpenCallback.h"
#include "LoadCodecs.h"
+#include "Property.h"
-HRESULT GetArchiveItemBoolProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result);
-HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);
+HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw();
+HRESULT Archive_IsItem_Folder(IInArchive *arc, UInt32 index, bool &result) throw();
+HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw();
+HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw();
+HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &deleted) throw();
-struct CArc
+/*
+struct COptionalOpenProperties
{
+ UString FormatName;
+ CObjectVector<CProperty> Props;
+};
+*/
+
+#ifdef _SFX
+#define OPEN_PROPS_DECL
+#else
+#define OPEN_PROPS_DECL const CObjectVector<CProperty> *props;
+// #define OPEN_PROPS_DECL , const CObjectVector<COptionalOpenProperties> *props
+#endif
+
+struct COpenSpecFlags
+{
+ // bool CanReturnFull;
+ bool CanReturnFrontal;
+ bool CanReturnTail;
+ bool CanReturnMid;
+
+ bool CanReturn_NonStart() const { return CanReturnTail || CanReturnMid; }
+
+ COpenSpecFlags():
+ // CanReturnFull(true),
+ CanReturnFrontal(false),
+ CanReturnTail(false),
+ CanReturnMid(false)
+ {}
+};
+
+struct COpenType
+{
+ int FormatIndex;
+
+ COpenSpecFlags SpecForcedType;
+ COpenSpecFlags SpecMainType;
+ COpenSpecFlags SpecWrongExt;
+ COpenSpecFlags SpecUnknownExt;
+
+ bool Recursive;
+
+ bool CanReturnArc;
+ bool CanReturnParser;
+ bool EachPos;
+
+ // bool SkipSfxStub;
+ // bool ExeAsUnknown;
+
+ bool ZerosTailIsAllowed;
+
+ bool MaxStartOffset_Defined;
+ UInt64 MaxStartOffset;
+
+ const COpenSpecFlags &GetSpec(bool isForced, bool isMain, bool isUnknown) const
+ {
+ return isForced ? SpecForcedType : (isMain ? SpecMainType : (isUnknown ? SpecUnknownExt : SpecWrongExt));
+ }
+
+ COpenType():
+ FormatIndex(-1),
+ Recursive(true),
+ CanReturnArc(true),
+ CanReturnParser(false),
+ EachPos(false),
+ // SkipSfxStub(true),
+ // ExeAsUnknown(true),
+ ZerosTailIsAllowed(false),
+ MaxStartOffset_Defined(false),
+ MaxStartOffset(0)
+ {
+ SpecForcedType.CanReturnFrontal = true;
+ SpecForcedType.CanReturnTail = true;
+ SpecForcedType.CanReturnMid = true;
+
+ SpecMainType.CanReturnFrontal = true;
+
+ SpecUnknownExt.CanReturnTail = true; // for sfx
+ SpecUnknownExt.CanReturnMid = true;
+ SpecUnknownExt.CanReturnFrontal = true; // for alt streams of sfx with pad
+
+ // ZerosTailIsAllowed = true;
+ }
+};
+
+struct COpenOptions
+{
+ CCodecs *codecs;
+ COpenType openType;
+ const CObjectVector<COpenType> *types;
+ const CIntVector *excludedFormats;
+
+ IInStream *stream;
+ ISequentialInStream *seqStream;
+ IArchiveOpenCallback *callback;
+ COpenCallbackImp *callbackSpec;
+ OPEN_PROPS_DECL
+ // bool openOnlySpecifiedByExtension,
+
+ bool stdInMode;
+ UString filePath;
+
+ COpenOptions():
+ codecs(NULL),
+ types(NULL),
+ excludedFormats(NULL),
+ stream(NULL),
+ seqStream(NULL),
+ callback(NULL),
+ callbackSpec(NULL),
+ stdInMode(false)
+ {}
+
+};
+
+UInt32 GetOpenArcErrorFlags(const NWindows::NCOM::CPropVariant &prop, bool *isDefinedProp = NULL);
+
+struct CArcErrorInfo
+{
+ bool ThereIsTail;
+ bool UnexpecedEnd;
+ bool IgnoreTail; // all are zeros
+ // bool NonZerosTail;
+ bool ErrorFlags_Defined;
+ UInt32 ErrorFlags;
+ UInt32 WarningFlags;
+ int ErrorFormatIndex; // - 1 means no Error.
+ // if FormatIndex == ErrorFormatIndex, the archive is open with offset
+ UInt64 TailSize;
+
+ /* if CArc is Open OK with some format:
+ - ErrorFormatIndex shows error format index, if extension is incorrect
+ - other variables show message and warnings of archive that is open */
+
+ UString ErrorMessage;
+ UString WarningMessage;
+
+ // call IsArc_After_NonOpen only if Open returns S_FALSE
+ bool IsArc_After_NonOpen() const
+ {
+ return (ErrorFlags_Defined && (ErrorFlags & kpv_ErrorFlags_IsNotArc) == 0);
+ }
+
+
+ CArcErrorInfo():
+ ThereIsTail(false),
+ UnexpecedEnd(false),
+ IgnoreTail(false),
+ // NonZerosTail(false),
+ ErrorFlags_Defined(false),
+ ErrorFlags(0),
+ WarningFlags(0),
+ ErrorFormatIndex(-1),
+ TailSize(0)
+ {}
+
+ void ClearErrors();
+
+ void ClearErrors_Full()
+ {
+ ErrorFormatIndex = -1;
+ ClearErrors();
+ }
+
+ bool IsThereErrorOrWarning() const
+ {
+ return ErrorFlags != 0
+ || WarningFlags != 0
+ || NeedTailWarning()
+ || UnexpecedEnd
+ || !ErrorMessage.IsEmpty()
+ || !WarningMessage.IsEmpty();
+ }
+
+ bool AreThereErrors() const { return ErrorFlags != 0 || UnexpecedEnd; }
+ bool AreThereWarnings() const { return WarningFlags != 0 || NeedTailWarning(); }
+
+ bool NeedTailWarning() const { return !IgnoreTail && ThereIsTail; }
+
+ UInt32 GetWarningFlags() const
+ {
+ UInt32 a = WarningFlags;
+ if (NeedTailWarning() && (ErrorFlags & kpv_ErrorFlags_DataAfterEnd) == 0)
+ a |= kpv_ErrorFlags_DataAfterEnd;
+ return a;
+ }
+
+ UInt32 GetErrorFlags() const
+ {
+ UInt32 a = ErrorFlags;
+ if (UnexpecedEnd)
+ a |= kpv_ErrorFlags_UnexpectedEnd;
+ return a;
+ }
+};
+
+class CArc
+{
+ HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive);
+ HRESULT CheckZerosTail(const COpenOptions &op, UInt64 offset);
+ HRESULT OpenStream2(const COpenOptions &options);
+
+public:
CMyComPtr<IInArchive> Archive;
+ CMyComPtr<IInStream> InStream;
+ // we use InStream in 2 cases (ArcStreamOffset != 0):
+ // 1) if we use additional cache stream
+ // 2) we reopen sfx archive with CTailInStream
+
+ CMyComPtr<IArchiveGetRawProps> GetRawProps;
+ CMyComPtr<IArchiveGetRootProps> GetRootProps;
+
+ CArcErrorInfo ErrorInfo; // for OK archives
+ CArcErrorInfo NonOpen_ErrorInfo; // ErrorInfo for mainArchive (false OPEN)
+
UString Path;
+ UString filePath;
UString DefaultName;
- int FormatIndex;
+ int FormatIndex; // - 1 means Parser.
int SubfileIndex;
FILETIME MTime;
bool MTimeDefined;
- UString ErrorMessage;
- CArc(): MTimeDefined(false) {}
+ Int64 Offset; // it's offset of start of archive inside stream that is open by Archive Handler
+ UInt64 PhySize;
+ // UInt64 OkPhySize;
+ bool PhySizeDefined;
+ // bool OkPhySize_Defined;
+ UInt64 FileSize;
+ UInt64 AvailPhySize; // PhySize, but it's reduced if exceed end of file
+ // bool offsetDefined;
+
+ UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler
+ Int64 GetGlobalOffset() const { return ArcStreamOffset + Offset; } // it's global offset of archive
+
+ // AString ErrorFlagsText;
+
+ bool IsParseArc;
+
+ bool IsTree;
+
+ bool Ask_Deleted;
+ bool Ask_AltStream;
+ bool Ask_Aux;
+ bool Ask_INode;
+
+ bool IgnoreSplit; // don't try split handler
+
+ // void Set_ErrorFlagsText();
+
+ CArc():
+ MTimeDefined(false),
+ IsTree(false),
+ Ask_Deleted(false),
+ Ask_AltStream(false),
+ Ask_Aux(false),
+ Ask_INode(false),
+ IgnoreSplit(false)
+ {}
+
+ HRESULT ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes);
+
+ // ~CArc();
+
+ HRESULT Close()
+ {
+ InStream.Release();
+ return Archive->Close();
+ }
+
+ // AltStream's name is concatenated with base file name in one string in parts.Back()
+ HRESULT GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const;
HRESULT GetItemPath(UInt32 index, UString &result) const;
+
+ // GetItemPath2 adds [DELETED] dir prefix for deleted items.
+ HRESULT GetItemPath2(UInt32 index, UString &result) const;
+
+ HRESULT GetItemSize(UInt32 index, UInt64 &size, bool &defined) const;
HRESULT GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const;
HRESULT IsItemAnti(UInt32 index, bool &result) const
- { return GetArchiveItemBoolProp(Archive, index, kpidIsAnti, result); }
-
- HRESULT OpenStream(
- CCodecs *codecs,
- int formatIndex,
- IInStream *stream,
- ISequentialInStream *seqStream,
- IArchiveOpenCallback *callback);
-
- HRESULT OpenStreamOrFile(
- CCodecs *codecs,
- int formatIndex,
- bool stdInMode,
- IInStream *stream,
- IArchiveOpenCallback *callback);
+ { return Archive_GetItemBoolProp(Archive, index, kpidIsAnti, result); }
+
+
+ HRESULT OpenStream(const COpenOptions &options);
+ HRESULT OpenStreamOrFile(COpenOptions &options);
+
+ HRESULT ReOpen(const COpenOptions &options);
+
+ HRESULT CreateNewTailStream(CMyComPtr<IInStream> &stream);
};
struct CArchiveLink
@@ -55,33 +315,32 @@ struct CArchiveLink
UInt64 VolumesSize;
bool IsOpen;
+ // int NonOpenErrorFormatIndex; // - 1 means no Error.
+ UString NonOpen_ArcPath;
+
+ CArcErrorInfo NonOpen_ErrorInfo;
+
+ // UString ErrorsText;
+ // void Set_ErrorsText();
+
CArchiveLink(): VolumesSize(0), IsOpen(false) {}
+ void KeepModeForNextOpen();
HRESULT Close();
void Release();
~CArchiveLink() { Release(); }
+ const CArc *GetArc() const { return &Arcs.Back(); }
IInArchive *GetArchive() const { return Arcs.Back().Archive; }
+ IArchiveGetRawProps *GetArchiveGetRawProps() const { return Arcs.Back().GetRawProps; }
+ IArchiveGetRootProps *GetArchiveGetRootProps() const { return Arcs.Back().GetRootProps; }
+
+ HRESULT Open(COpenOptions &options);
- HRESULT Open(
- CCodecs *codecs,
- const CIntVector &formatIndices,
- bool stdInMode,
- IInStream *stream,
- const UString &filePath,
- IArchiveOpenCallback *callback);
-
- HRESULT Open2(
- CCodecs *codecs,
- const CIntVector &formatIndices,
- bool stdInMode,
- IInStream *stream,
- const UString &filePath,
- IOpenCallbackUI *callbackUI);
-
- HRESULT ReOpen(
- CCodecs *codecs,
- const UString &filePath,
- IArchiveOpenCallback *callback);
+ HRESULT Open2(COpenOptions &options, IOpenCallbackUI *callbackUI);
+
+ HRESULT ReOpen(COpenOptions &options);
};
+bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types);
+
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/PropIDUtils.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/PropIDUtils.cpp
index dacaca5f9..5ba8c7a89 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/PropIDUtils.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/PropIDUtils.cpp
@@ -2,33 +2,29 @@
#include "StdAfx.h"
-#include "Common/IntToString.h"
+#include "../../../../C/CpuArch.h"
-#include "Windows/FileFind.h"
-#include "Windows/PropVariantConversions.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
+
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/FileIO.h"
+#include "../../../Windows/PropVariantConv.h"
#include "../../PropID.h"
#include "PropIDUtils.h"
-using namespace NWindows;
+#define Get16(x) GetUi16(x)
+#define Get32(x) GetUi32(x)
-void ConvertUInt32ToHex(UInt32 value, wchar_t *s)
-{
- for (int i = 0; i < 8; i++)
- {
- int t = value & 0xF;
- value >>= 4;
- s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10)));
- }
- s[8] = L'\0';
-}
+using namespace NWindows;
-static const char g_WinAttrib[17] = "RHS8DAdNTsrCOnE_";
+static const char g_WinAttribChars[16 + 1] = "RHS8DAdNTsLCOnE_";
/*
0 READONLY
1 HIDDEN
-3 SYSTEM
+2 SYSTEM
4 DIRECTORY
5 ARCHIVE
@@ -45,46 +41,45 @@ static const char g_WinAttrib[17] = "RHS8DAdNTsrCOnE_";
16 VIRTUAL
*/
+void ConvertWinAttribToString(char *s, UInt32 wa)
+{
+ for (int i = 0; i < 16; i++)
+ if ((wa & (1 << i)) && i != 7)
+ *s++ = g_WinAttribChars[i];
+ *s = 0;
+}
+
static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' };
-#define MY_ATTR_CHAR(a, n, c) ((a )& (1 << (n))) ? c : L'-';
+#define MY_ATTR_CHAR(a, n, c) ((a) & (1 << (n))) ? c : '-';
-UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool full)
+void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID propID, bool full) throw()
{
- switch(propID)
+ *dest = 0;
+ if (prop.vt == VT_FILETIME)
+ {
+ FILETIME localFileTime;
+ if ((prop.filetime.dwHighDateTime == 0 &&
+ prop.filetime.dwLowDateTime == 0) ||
+ !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
+ return;
+ ConvertFileTimeToString(localFileTime, dest, true, full);
+ return;
+ }
+ switch (propID)
{
- case kpidCTime:
- case kpidATime:
- case kpidMTime:
- {
- if (prop.vt != VT_FILETIME)
- break;
- FILETIME localFileTime;
- if ((prop.filetime.dwHighDateTime == 0 &&
- prop.filetime.dwLowDateTime == 0) ||
- !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
- return UString();
- return ConvertFileTimeToString(localFileTime, true, full);
- }
case kpidCRC:
{
if (prop.vt != VT_UI4)
break;
- wchar_t temp[12];
- ConvertUInt32ToHex(prop.ulVal, temp);
- return temp;
+ ConvertUInt32ToHex8Digits(prop.ulVal, dest);
+ return;
}
case kpidAttrib:
{
if (prop.vt != VT_UI4)
break;
- UInt32 a = prop.ulVal;
- wchar_t sz[32];
- int pos = 0;
- for (int i = 0; i < 16; i++)
- if (a & (1 << i) && i != 7)
- sz[pos++] = g_WinAttrib[i];
- sz[pos] = '\0';
- return sz;
+ ConvertWinAttribToString(dest, prop.ulVal);
+ return;
}
case kpidPosixAttrib:
{
@@ -92,29 +87,469 @@ UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool ful
break;
UString res;
UInt32 a = prop.ulVal;
- wchar_t temp[16];
- temp[0] = kPosixTypes[(a >> 12) & 0xF];
+ dest[0] = kPosixTypes[(a >> 12) & 0xF];
for (int i = 6; i >= 0; i -= 3)
{
- temp[7 - i] = MY_ATTR_CHAR(a, i + 2, L'r');
- temp[8 - i] = MY_ATTR_CHAR(a, i + 1, L'w');
- temp[9 - i] = MY_ATTR_CHAR(a, i + 0, L'x');
+ dest[7 - i] = MY_ATTR_CHAR(a, i + 2, 'r');
+ dest[8 - i] = MY_ATTR_CHAR(a, i + 1, 'w');
+ dest[9 - i] = MY_ATTR_CHAR(a, i + 0, 'x');
}
- if ((a & 0x800) != 0) temp[3] = ((a & (1 << 6)) ? 's' : 'S');
- if ((a & 0x400) != 0) temp[6] = ((a & (1 << 3)) ? 's' : 'S');
- if ((a & 0x200) != 0) temp[9] = ((a & (1 << 0)) ? 't' : 'T');
- temp[10] = 0;
- res = temp;
+ if ((a & 0x800) != 0) dest[3] = ((a & (1 << 6)) ? 's' : 'S');
+ if ((a & 0x400) != 0) dest[6] = ((a & (1 << 3)) ? 's' : 'S');
+ if ((a & 0x200) != 0) dest[9] = ((a & (1 << 0)) ? 't' : 'T');
+ dest[10] = 0;
a &= ~(UInt32)0xFFFF;
if (a != 0)
{
- ConvertUInt32ToHex(a, temp);
- res = UString(temp) + L' ' + res;
+ dest[10] = ' ';
+ ConvertUInt32ToHex8Digits(a, dest + 11);
+ }
+ return;
+ }
+ case kpidINode:
+ {
+ if (prop.vt != VT_UI8)
+ break;
+ ConvertUInt32ToString((UInt32)(prop.uhVal.QuadPart >> 48), dest);
+ dest += strlen(dest);
+ *dest++ = '-';
+ UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1);
+ ConvertUInt64ToString(low, dest);
+ return;
+ }
+ case kpidVa:
+ {
+ UInt64 v = 0;
+ if (ConvertPropVariantToUInt64(prop, v))
+ {
+ dest[0] = '0';
+ dest[1] = 'x';
+ ConvertUInt64ToHex(prop.ulVal, dest + 2);
+ return;
+ }
+ break;
+ }
+ }
+ ConvertPropVariantToShortString(prop, dest);
+}
+
+void ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID propID, bool full)
+{
+ if (prop.vt == VT_BSTR)
+ {
+ dest = prop.bstrVal;
+ return;
+ }
+ char temp[64];
+ ConvertPropertyToShortString(temp, prop, propID, full);
+ int len = MyStringLen(temp);
+ wchar_t *str = dest.GetBuffer(len);
+ for (int i = 0; i < len; i++)
+ str[i] = temp[i];
+ dest.ReleaseBuffer(len);
+}
+
+static inline char GetHex(Byte value)
+{
+ return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+}
+
+#ifndef _SFX
+
+static inline void AddHexToString(AString &res, Byte value)
+{
+ res += GetHex((Byte)(value >> 4));
+ res += GetHex((Byte)(value & 0xF));
+ res += ' ';
+}
+
+/*
+static AString Data_To_Hex(const Byte *data, size_t size)
+{
+ AString s;
+ for (size_t i = 0; i < size; i++)
+ AddHexToString(s, data[i]);
+ return s;
+}
+*/
+
+static const char *sidNames[] =
+{
+ "0",
+ "Dialup",
+ "Network",
+ "Batch",
+ "Interactive",
+ "Logon", // S-1-5-5-X-Y
+ "Service",
+ "Anonymous",
+ "Proxy",
+ "EnterpriseDC",
+ "Self",
+ "AuthenticatedUsers",
+ "RestrictedCode",
+ "TerminalServer",
+ "RemoteInteractiveLogon",
+ "ThisOrganization",
+ "16",
+ "IUserIIS",
+ "LocalSystem",
+ "LocalService",
+ "NetworkService",
+ "Domains"
+};
+
+struct CSecID2Name
+{
+ UInt32 n;
+ const char *sz;
+};
+
+const CSecID2Name sid_32_Names[] =
+{
+ { 544, "Administrators" },
+ { 545, "Users" },
+ { 546, "Guests" },
+ { 547, "PowerUsers" },
+ { 548, "AccountOperators" },
+ { 549, "ServerOperators" },
+ { 550, "PrintOperators" },
+ { 551, "BackupOperators" },
+ { 552, "Replicators" },
+ { 553, "Backup Operators" },
+ { 554, "PreWindows2000CompatibleAccess" },
+ { 555, "RemoteDesktopUsers" },
+ { 556, "NetworkConfigurationOperators" },
+ { 557, "IncomingForestTrustBuilders" },
+ { 558, "PerformanceMonitorUsers" },
+ { 559, "PerformanceLogUsers" },
+ { 560, "WindowsAuthorizationAccessGroup" },
+ { 561, "TerminalServerLicenseServers" },
+ { 562, "DistributedCOMUsers" },
+ { 569, "CryptographicOperators" },
+ { 573, "EventLogReaders" },
+ { 574, "CertificateServiceDCOMAccess" }
+};
+
+static const CSecID2Name sid_21_Names[] =
+{
+ { 500, "Administrator" },
+ { 501, "Guest" },
+ { 502, "KRBTGT" },
+ { 512, "DomainAdmins" },
+ { 513, "DomainUsers" },
+ { 515, "DomainComputers" },
+ { 516, "DomainControllers" },
+ { 517, "CertPublishers" },
+ { 518, "SchemaAdmins" },
+ { 519, "EnterpriseAdmins" },
+ { 520, "GroupPolicyCreatorOwners" },
+ { 553, "RASandIASServers" },
+ { 553, "RASandIASServers" },
+ { 571, "AllowedRODCPasswordReplicationGroup" },
+ { 572, "DeniedRODCPasswordReplicationGroup" }
+};
+
+struct CServicesToName
+{
+ UInt32 n[5];
+ const char *sz;
+};
+
+static const CServicesToName services_to_name[] =
+{
+ { { 0x38FB89B5, 0xCBC28419, 0x6D236C5C, 0x6E770057, 0x876402C0 } , "TrustedInstaller" }
+};
+
+static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
+{
+ sidSize = 0;
+ if (lim < 8)
+ {
+ s += "ERROR";
+ return;
+ }
+ UInt32 rev = p[0];
+ if (rev != 1)
+ {
+ s += "UNSUPPORTED";
+ return;
+ }
+ UInt32 num = p[1];
+ if (8 + num * 4 > lim)
+ {
+ s += "ERROR";
+ return;
+ }
+ sidSize = 8 + num * 4;
+ UInt32 authority = GetBe32(p + 4);
+
+ if (p[2] == 0 && p[3] == 0 && authority == 5 && num >= 1)
+ {
+ UInt32 v0 = Get32(p + 8);
+ if (v0 < ARRAY_SIZE(sidNames))
+ {
+ s += sidNames[v0];
+ return;
+ }
+ if (v0 == 32 && num == 2)
+ {
+ UInt32 v1 = Get32(p + 12);
+ for (int i = 0; i < ARRAY_SIZE(sid_32_Names); i++)
+ if (sid_32_Names[i].n == v1)
+ {
+ s += sid_32_Names[i].sz;
+ return;
+ }
+ }
+ if (v0 == 21 && num == 5)
+ {
+ UInt32 v4 = Get32(p + 8 + 4 * 4);
+ for (int i = 0; i < ARRAY_SIZE(sid_21_Names); i++)
+ if (sid_21_Names[i].n == v4)
+ {
+ s += sid_21_Names[i].sz;
+ return;
+ }
+ }
+ if (v0 == 80 && num == 6)
+ {
+ for (int i = 0; i < ARRAY_SIZE(services_to_name); i++)
+ {
+ const CServicesToName &sn = services_to_name[i];
+ int j;
+ for (j = 0; j < 5 && sn.n[j] == Get32(p + 8 + 4 + j * 4); j++);
+ if (j == 5)
+ {
+ s += sn.sz;
+ return;
+ }
}
- return res;
}
}
- return ConvertPropVariantToString(prop);
+
+ char sz[16];
+ s += "S-1-";
+ if (p[2] == 0 && p[3] == 0)
+ {
+ ConvertUInt32ToString(authority, sz);
+ s += sz;
+ }
+ else
+ {
+ s += "0x";
+ for (int i = 2; i < 8; i++)
+ AddHexToString(s, p[i]);
+ }
+ for (UInt32 i = 0; i < num; i++)
+ {
+ s += '-';
+ ConvertUInt32ToString(Get32(p + 8 + i * 4), sz);
+ s += sz;
+ }
+}
+
+static void ParseOwner(AString &s, const Byte *p, UInt32 size, UInt32 pos)
+{
+ if (pos > size)
+ {
+ s += "ERROR";
+ return;
+ }
+ UInt32 sidSize = 0;
+ ParseSid(s, p + pos, size - pos, sidSize);
+}
+
+static void AddUInt32ToString(AString &s, UInt32 val)
+{
+ char sz[16];
+ ConvertUInt32ToString(val, sz);
+ s += sz;
+}
+
+static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName, UInt32 flags, UInt32 offset)
+{
+ UInt32 control = Get16(p + 2);
+ if ((flags & control) == 0)
+ return;
+ UInt32 pos = Get32(p + offset);
+ s += ' ';
+ s += strName;
+ if (pos >= size)
+ return;
+ p += pos;
+ size -= pos;
+ if (size < 8)
+ return;
+ if (Get16(p) != 2) // revision
+ return;
+ // UInt32 aclSize = Get16(p + 2);
+ UInt32 num = Get32(p + 4);
+ AddUInt32ToString(s, num);
+ /*
+ if (num >= (1 << 16))
+ return;
+ if (aclSize > size)
+ return;
+ size = aclSize;
+ size -= 8;
+ p += 8;
+ for (UInt32 i = 0 ; i < num; i++)
+ {
+ if (size <= 8)
+ return;
+ // Byte type = p[0];
+ // Byte flags = p[1];
+ // UInt32 aceSize = Get16(p + 2);
+ // UInt32 mask = Get32(p + 4);
+ p += 8;
+ size -= 8;
+
+ UInt32 sidSize = 0;
+ s += ' ';
+ s += ParseSid(p, size, sidSize);
+ if (sidSize == 0)
+ return;
+ p += sidSize;
+ size -= sidSize;
+ }
+ if (size != 0)
+ s += " ERROR";
+ */
+}
+
+#define MY_SE_OWNER_DEFAULTED (0x0001)
+#define MY_SE_GROUP_DEFAULTED (0x0002)
+#define MY_SE_DACL_PRESENT (0x0004)
+#define MY_SE_DACL_DEFAULTED (0x0008)
+#define MY_SE_SACL_PRESENT (0x0010)
+#define MY_SE_SACL_DEFAULTED (0x0020)
+#define MY_SE_DACL_AUTO_INHERIT_REQ (0x0100)
+#define MY_SE_SACL_AUTO_INHERIT_REQ (0x0200)
+#define MY_SE_DACL_AUTO_INHERITED (0x0400)
+#define MY_SE_SACL_AUTO_INHERITED (0x0800)
+#define MY_SE_DACL_PROTECTED (0x1000)
+#define MY_SE_SACL_PROTECTED (0x2000)
+#define MY_SE_RM_CONTROL_VALID (0x4000)
+#define MY_SE_SELF_RELATIVE (0x8000)
+
+void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s)
+{
+ s.Empty();
+ if (size < 20 || size > (1 << 18))
+ {
+ s += "ERROR";
+ return;
+ }
+ if (Get16(data) != 1) // revision
+ {
+ s += "UNSUPPORTED";
+ return;
+ }
+ ParseOwner(s, data, size, Get32(data + 4));
+ s += ' ';
+ ParseOwner(s, data, size, Get32(data + 8));
+ ParseAcl(s, data, size, "s:", MY_SE_SACL_PRESENT, 12);
+ ParseAcl(s, data, size, "d:", MY_SE_DACL_PRESENT, 16);
+ s += ' ';
+ AddUInt32ToString(s, size);
+ // s += '\n';
+ // s += Data_To_Hex(data, size);
+}
+
+#ifdef _WIN32
+
+static bool CheckSid(const Byte *data, UInt32 size, UInt32 pos)
+{
+ if (pos >= size)
+ return false;
+ size -= pos;
+ if (size < 8)
+ return false;
+ UInt32 rev = data[pos];
+ if (rev != 1)
+ return false;
+ UInt32 num = data[pos + 1];
+ return (8 + num * 4 <= size);
+}
+
+static bool CheckAcl(const Byte *p, UInt32 size, UInt32 flags, UInt32 offset)
+{
+ UInt32 control = Get16(p + 2);
+ if ((flags & control) == 0)
+ return true;
+ UInt32 pos = Get32(p + offset);
+ if (pos >= size)
+ return false;
+ p += pos;
+ size -= pos;
+ if (size < 8)
+ return false;
+ UInt32 aclSize = Get16(p + 2);
+ return (aclSize <= size);
+}
+
+bool CheckNtSecure(const Byte *data, UInt32 size)
+{
+ if (size < 20)
+ return false;
+ if (Get16(data) != 1) // revision
+ return true; // windows function can handle such error, so we allow it
+ if (size > (1 << 18))
+ return false;
+ if (!CheckSid(data, size, Get32(data + 4))) return false;
+ if (!CheckSid(data, size, Get32(data + 8))) return false;
+ if (!CheckAcl(data, size, MY_SE_SACL_PRESENT, 12)) return false;
+ if (!CheckAcl(data, size, MY_SE_DACL_PRESENT, 16)) return false;
+ return true;
+}
+
+#endif
+
+#ifdef _WIN32
+bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
+{
+ s.Empty();
+ NFile::CReparseAttr attr;
+ if (attr.Parse(data, size))
+ {
+ if (!attr.IsSymLink())
+ s += L"Junction: ";
+ s += attr.GetPath();
+ if (!attr.IsOkNamePair())
+ {
+ s += L" : ";
+ s += attr.PrintName;
+ }
+ return true;
+ }
+
+ if (size < 8)
+ return false;
+ UInt32 tag = Get32(data);
+ UInt32 len = Get16(data + 4);
+ if (len + 8 > size)
+ return false;
+ if (Get16(data + 6) != 0) // padding
+ return false;
+
+ char hex[16];
+ ConvertUInt32ToHex8Digits(tag, hex);
+ s.AddAsciiStr(hex);
+ s += L' ';
+
+ data += 8;
+
+ for (UInt32 i = 0; i < len; i++)
+ {
+ Byte b = ((const Byte *)data)[i];
+ s += (wchar_t)GetHex((Byte)((b >> 4) & 0xF));
+ s += (wchar_t)GetHex((Byte)(b & 0xF));
+ }
+ return true;
}
+#endif
+
+#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/PropIDUtils.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/PropIDUtils.h
index ca14d091d..3ee2981de 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/PropIDUtils.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/PropIDUtils.h
@@ -3,10 +3,15 @@
#ifndef __PROPID_UTILS_H
#define __PROPID_UTILS_H
-#include "Common/MyString.h"
-#include "Common/Types.h"
+#include "../../../Common/MyString.h"
-void ConvertUInt32ToHex(UInt32 value, wchar_t *s);
-UString ConvertPropertyToString(const PROPVARIANT &propVariant, PROPID propID, bool full = true);
+// provide at least 64 bytes for buffer including zero-end
+void ConvertPropertyToShortString(char *dest, const PROPVARIANT &propVariant, PROPID propID, bool full = true) throw();
+void ConvertPropertyToString(UString &dest, const PROPVARIANT &propVariant, PROPID propID, bool full = true);
+
+bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s);
+void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s);
+bool CheckNtSecure(const Byte *data, UInt32 size);
+void ConvertWinAttribToString(char *s, UInt32 wa);
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/Property.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/Property.h
index 9fd340cbc..8b57a2a64 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/Property.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/Property.h
@@ -1,9 +1,9 @@
// Property.h
-#ifndef __PROPERTY_H
-#define __PROPERTY_H
+#ifndef __7Z_PROPERTY_H
+#define __7Z_PROPERTY_H
-#include "Common/MyString.h"
+#include "../../../Common/MyString.h"
struct CProperty
{
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/SetProperties.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/SetProperties.cpp
index 4827f2a78..64b9d92a6 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/SetProperties.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/SetProperties.cpp
@@ -2,25 +2,26 @@
#include "StdAfx.h"
-#include "SetProperties.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Common/MyString.h"
+#include "../../../Common/StringToInt.h"
-#include "Windows/PropVariant.h"
-#include "Common/MyString.h"
-#include "Common/StringToInt.h"
-#include "Common/MyCom.h"
+#include "../../../Windows/PropVariant.h"
#include "../../Archive/IArchive.h"
+#include "SetProperties.h"
+
using namespace NWindows;
using namespace NCOM;
static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
{
- const wchar_t *endPtr;
- UInt64 result = ConvertStringToUInt64(s, &endPtr);
- if (endPtr - (const wchar_t *)s != s.Length())
+ const wchar_t *end;
+ UInt64 result = ConvertStringToUInt64(s, &end);
+ if (*end != 0 || s.IsEmpty())
prop = s;
- else if (result <= 0xFFFFFFFF)
+ else if (result <= (UInt32)0xFFFFFFFF)
prop = (UInt32)result;
else
prop = result;
@@ -39,8 +40,8 @@ HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &propert
CPropVariant *values = new CPropVariant[properties.Size()];
try
{
- int i;
- for(i = 0; i < properties.Size(); i++)
+ unsigned i;
+ for (i = 0; i < properties.Size(); i++)
{
const CProperty &property = properties[i];
NCOM::CPropVariant propVariant;
@@ -49,13 +50,13 @@ HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &propert
{
if (!name.IsEmpty())
{
- wchar_t c = name[name.Length() - 1];
+ wchar_t c = name.Back();
if (c == L'-')
propVariant = false;
else if (c == L'+')
propVariant = true;
if (propVariant.vt != VT_EMPTY)
- name = name.Left(name.Length() - 1);
+ name.DeleteBack();
}
}
else
@@ -64,9 +65,9 @@ HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &propert
values[i] = propVariant;
}
CRecordVector<const wchar_t *> names;
- for(i = 0; i < realNames.Size(); i++)
+ for (i = 0; i < realNames.Size(); i++)
names.Add((const wchar_t *)realNames[i]);
-
+
RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
}
catch(...)
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/SortUtils.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/SortUtils.cpp
index 061e77730..b7e422a29 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/SortUtils.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/SortUtils.cpp
@@ -2,21 +2,22 @@
#include "StdAfx.h"
+#include "../../../Common/Wildcard.h"
+
#include "SortUtils.h"
-#include "Common/Wildcard.h"
-static int CompareStrings(const int *p1, const int *p2, void *param)
+static int CompareStrings(const unsigned *p1, const unsigned *p2, void *param)
{
const UStringVector &strings = *(const UStringVector *)param;
return CompareFileNames(strings[*p1], strings[*p2]);
}
-void SortFileNames(const UStringVector &strings, CIntVector &indices)
+void SortFileNames(const UStringVector &strings, CUIntVector &indices)
{
- indices.Clear();
- int numItems = strings.Size();
- indices.Reserve(numItems);
- for(int i = 0; i < numItems; i++)
- indices.Add(i);
+ unsigned numItems = strings.Size();
+ indices.ClearAndSetSize(numItems);
+ unsigned *vals = &indices[0];
+ for (unsigned i = 0; i < numItems; i++)
+ vals[i] = i;
indices.Sort(CompareStrings, (void *)&strings);
}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/SortUtils.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/SortUtils.h
index e15224611..8e42e0682 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/SortUtils.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/SortUtils.h
@@ -1,10 +1,10 @@
// SortUtils.h
-#ifndef __SORTUTLS_H
-#define __SORTUTLS_H
+#ifndef __SORT_UTLS_H
+#define __SORT_UTLS_H
-#include "Common/MyString.h"
+#include "../../../Common/MyString.h"
-void SortFileNames(const UStringVector &strings, CIntVector &indices);
+void SortFileNames(const UStringVector &strings, CUIntVector &indices);
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/TempFiles.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/TempFiles.cpp
index eeaec1802..0c13ae158 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/TempFiles.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/TempFiles.cpp
@@ -2,19 +2,18 @@
#include "StdAfx.h"
-#include "TempFiles.h"
+#include "../../../Windows/FileDir.h"
-#include "Windows/FileDir.h"
-#include "Windows/FileIO.h"
+#include "TempFiles.h"
using namespace NWindows;
using namespace NFile;
void CTempFiles::Clear()
{
- while(!Paths.IsEmpty())
+ while (!Paths.IsEmpty())
{
- NDirectory::DeleteFileAlways((LPCWSTR)Paths.Back());
+ NDir::DeleteFileAlways(Paths.Back());
Paths.DeleteBack();
}
}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/TempFiles.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/TempFiles.h
index eb474a760..4099e6558 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/TempFiles.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/TempFiles.h
@@ -1,15 +1,15 @@
// TempFiles.h
-#ifndef __TEMPFILES_H
-#define __TEMPFILES_H
+#ifndef __TEMP_FILES_H
+#define __TEMP_FILES_H
-#include "Common/MyString.h"
+#include "../../../Common/MyString.h"
class CTempFiles
{
void Clear();
public:
- UStringVector Paths;
+ FStringVector Paths;
~CTempFiles() { Clear(); }
};
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/Update.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/Update.cpp
index a5db3c18e..4697dca46 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/Update.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/Update.cpp
@@ -4,21 +4,19 @@
#include "Update.h"
-#include "Common/IntToString.h"
-#include "Common/StringConvert.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
-#ifdef _WIN32
-#include "Windows/DLL.h"
-#endif
-
-#include "Windows/FileDir.h"
-#include "Windows/FileFind.h"
-#include "Windows/FileName.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
-#include "Windows/Time.h"
+#include "../../../Windows/DLL.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/PropVariantConv.h"
+#include "../../../Windows/TimeUtils.h"
#include "../../Common/FileStreams.h"
+#include "../../Common/LimitedStreams.h"
#include "../../Compress/CopyCoder.h"
@@ -38,36 +36,71 @@ static const char *kUpdateIsNotSupoorted =
using namespace NWindows;
using namespace NCOM;
using namespace NFile;
+using namespace NDir;
using namespace NName;
-#ifdef _WIN32
-static const wchar_t *kTempFolderPrefix = L"7zE";
+static CFSTR kTempFolderPrefix = FTEXT("7zE");
+
+#ifdef ENV_UNIX
+FString GetModuleDirPrefix()
+{
+ FString s;
+
+ const char *p7zip_home_dir = getenv("P7ZIP_HOME_DIR");
+ if (p7zip_home_dir) {
+ return MultiByteToUnicodeString(p7zip_home_dir,CP_ACP);
+ }
+
+ return FTEXT(".") FSTRING_PATH_SEPARATOR;
+}
#endif
+static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path)
+{
+ NFind::CFileInfo fileInfo;
+ FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
+ {
+ NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK);
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDir())
+ if (!DeleteEmptyFolderAndEmptySubFolders(pathPrefix + fileInfo.Name))
+ return false;
+ }
+ }
+ /*
+ // we don't need clear read-only for folders
+ if (!MySetFileAttributes(path, 0))
+ return false;
+ */
+ return RemoveDir(path);
+}
+
+
using namespace NUpdateArchive;
class COutMultiVolStream:
public IOutStream,
public CMyUnknownImp
{
- int _streamIndex; // required stream
+ unsigned _streamIndex; // required stream
UInt64 _offsetPos; // offset from start of _streamIndex index
UInt64 _absPos;
UInt64 _length;
- struct CSubStreamInfo
+ struct CAltStreamInfo
{
COutFileStream *StreamSpec;
CMyComPtr<IOutStream> Stream;
- UString Name;
+ FString Name;
UInt64 Pos;
UInt64 RealSize;
};
- CObjectVector<CSubStreamInfo> Streams;
+ CObjectVector<CAltStreamInfo> Streams;
public:
// CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
CRecordVector<UInt64> Sizes;
- UString Prefix;
+ FString Prefix;
CTempFiles *TempFiles;
void Init()
@@ -78,6 +111,7 @@ public:
_length = 0;
}
+ bool SetMTime(const FILETIME *mTime);
HRESULT Close();
MY_UNKNOWN_IMP1(IOutStream)
@@ -92,12 +126,12 @@ public:
HRESULT COutMultiVolStream::Close()
{
HRESULT res = S_OK;
- for (int i = 0; i < Streams.Size(); i++)
+ FOR_VECTOR (i, Streams)
{
- CSubStreamInfo &s = Streams[i];
- if (s.StreamSpec)
+ COutFileStream *s = Streams[i].StreamSpec;
+ if (s)
{
- HRESULT res2 = s.StreamSpec->Close();
+ HRESULT res2 = s->Close();
if (res2 != S_OK)
res = res2;
}
@@ -105,40 +139,53 @@ HRESULT COutMultiVolStream::Close()
return res;
}
+bool COutMultiVolStream::SetMTime(const FILETIME *mTime)
+{
+ bool res = true;
+ FOR_VECTOR (i, Streams)
+ {
+ COutFileStream *s = Streams[i].StreamSpec;
+ if (s)
+ if (!s->SetMTime(mTime))
+ res = false;
+ }
+ return res;
+}
+
STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize != NULL)
*processedSize = 0;
- while(size > 0)
+ while (size > 0)
{
if (_streamIndex >= Streams.Size())
{
- CSubStreamInfo subStream;
+ CAltStreamInfo altStream;
- wchar_t temp[16];
+ FChar temp[16];
ConvertUInt32ToString(_streamIndex + 1, temp);
- UString res = temp;
- while (res.Length() < 3)
- res = UString(L'0') + res;
- UString name = Prefix + res;
- subStream.StreamSpec = new COutFileStream;
- subStream.Stream = subStream.StreamSpec;
- if (!subStream.StreamSpec->Create(name, false))
+ FString res = temp;
+ while (res.Len() < 3)
+ res = FString(FTEXT('0')) + res;
+ FString name = Prefix + res;
+ altStream.StreamSpec = new COutFileStream;
+ altStream.Stream = altStream.StreamSpec;
+ if (!altStream.StreamSpec->Create(name, false))
return ::GetLastError();
{
// NSynchronization::CCriticalSectionLock lock(g_TempPathsCS);
TempFiles->Paths.Add(name);
}
- subStream.Pos = 0;
- subStream.RealSize = 0;
- subStream.Name = name;
- Streams.Add(subStream);
+ altStream.Pos = 0;
+ altStream.RealSize = 0;
+ altStream.Name = name;
+ Streams.Add(altStream);
continue;
}
- CSubStreamInfo &subStream = Streams[_streamIndex];
+ CAltStreamInfo &altStream = Streams[_streamIndex];
- int index = _streamIndex;
+ unsigned index = _streamIndex;
if (index >= Sizes.Size())
index = Sizes.Size() - 1;
UInt64 volSize = Sizes[index];
@@ -149,29 +196,29 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
_streamIndex++;
continue;
}
- if (_offsetPos != subStream.Pos)
+ if (_offsetPos != altStream.Pos)
{
// CMyComPtr<IOutStream> outStream;
- // RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
- RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
- subStream.Pos = _offsetPos;
+ // RINOK(altStream.Stream.QueryInterface(IID_IOutStream, &outStream));
+ RINOK(altStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
+ altStream.Pos = _offsetPos;
}
- UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos);
+ UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - altStream.Pos);
UInt32 realProcessed;
- RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
+ RINOK(altStream.Stream->Write(data, curSize, &realProcessed));
data = (void *)((Byte *)data + realProcessed);
size -= realProcessed;
- subStream.Pos += realProcessed;
+ altStream.Pos += realProcessed;
_offsetPos += realProcessed;
_absPos += realProcessed;
if (_absPos > _length)
_length = _absPos;
- if (_offsetPos > subStream.RealSize)
- subStream.RealSize = _offsetPos;
+ if (_offsetPos > altStream.RealSize)
+ altStream.RealSize = _offsetPos;
if (processedSize != NULL)
*processedSize += realProcessed;
- if (subStream.Pos == volSize)
+ if (altStream.Pos == volSize)
{
_streamIndex++;
_offsetPos = 0;
@@ -187,17 +234,11 @@ STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *n
{
if (seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
- switch(seekOrigin)
+ switch (seekOrigin)
{
- case STREAM_SEEK_SET:
- _absPos = offset;
- break;
- case STREAM_SEEK_CUR:
- _absPos += offset;
- break;
- case STREAM_SEEK_END:
- _absPos = _length + offset;
- break;
+ case STREAM_SEEK_SET: _absPos = offset; break;
+ case STREAM_SEEK_CUR: _absPos += offset; break;
+ case STREAM_SEEK_END: _absPos = _length + offset; break;
}
_offsetPos = _absPos;
if (newPosition != NULL)
@@ -210,24 +251,24 @@ STDMETHODIMP COutMultiVolStream::SetSize(UInt64 newSize)
{
if (newSize < 0)
return E_INVALIDARG;
- int i = 0;
+ unsigned i = 0;
while (i < Streams.Size())
{
- CSubStreamInfo &subStream = Streams[i++];
- if ((UInt64)newSize < subStream.RealSize)
+ CAltStreamInfo &altStream = Streams[i++];
+ if ((UInt64)newSize < altStream.RealSize)
{
- RINOK(subStream.Stream->SetSize(newSize));
- subStream.RealSize = newSize;
+ RINOK(altStream.Stream->SetSize(newSize));
+ altStream.RealSize = newSize;
break;
}
- newSize -= subStream.RealSize;
+ newSize -= altStream.RealSize;
}
while (i < Streams.Size())
{
{
- CSubStreamInfo &subStream = Streams.Back();
- subStream.Stream.Release();
- NDirectory::DeleteFileAlways(subStream.Name);
+ CAltStreamInfo &altStream = Streams.Back();
+ altStream.Stream.Release();
+ DeleteFileAlways(altStream.Name);
}
Streams.DeleteBack();
}
@@ -237,7 +278,67 @@ STDMETHODIMP COutMultiVolStream::SetSize(UInt64 newSize)
return S_OK;
}
-static const wchar_t *kDefaultArchiveType = L"7z";
+void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode)
+{
+ OriginalPath = path;
+
+ SplitPathToParts_2(path, Prefix, Name);
+
+ if (mode == k_ArcNameMode_Add)
+ return;
+ if (mode == k_ArcNameMode_Exact)
+ {
+ BaseExtension.Empty();
+ return;
+ }
+
+ int dotPos = Name.ReverseFind(L'.');
+ if (dotPos < 0)
+ return;
+ if ((unsigned)dotPos == Name.Len() - 1)
+ {
+ Name.DeleteBack();
+ BaseExtension.Empty();
+ return;
+ }
+ const UString ext = Name.Ptr(dotPos + 1);
+ if (BaseExtension.IsEqualToNoCase(ext))
+ {
+ BaseExtension = ext;
+ Name.DeleteFrom(dotPos);
+ }
+ else
+ BaseExtension.Empty();
+}
+
+UString CArchivePath::GetFinalPath() const
+{
+ UString path = GetPathWithoutExt();
+ if (!BaseExtension.IsEmpty())
+ path += UString(L'.') + BaseExtension;
+ return path;
+}
+
+UString CArchivePath::GetFinalVolPath() const
+{
+ UString path = GetPathWithoutExt();
+ if (!BaseExtension.IsEmpty())
+ path += UString(L'.') + VolExtension;
+ return path;
+}
+
+FString CArchivePath::GetTempPath() const
+{
+ FString path = TempPrefix + us2fs(Name);
+ if (!BaseExtension.IsEmpty())
+ path += FString(FTEXT('.')) + us2fs(BaseExtension);
+ path += FTEXT(".tmp");
+ path += TempPostfix;
+ return path;
+}
+
+static const wchar_t *kDefaultArcType = L"7z";
+static const wchar_t *kDefaultArcExt = L"7z";
static const wchar_t *kSFXExtension =
#ifdef _WIN32
L"exe";
@@ -245,40 +346,58 @@ static const wchar_t *kSFXExtension =
L"";
#endif
-bool CUpdateOptions::Init(const CCodecs *codecs, const CIntVector &formatIndices, const UString &arcPath)
+bool CUpdateOptions::InitFormatIndex(const CCodecs *codecs,
+ const CObjectVector<COpenType> &types, const UString &arcPath)
{
- if (formatIndices.Size() > 1)
+ if (types.Size() > 1)
return false;
- int arcTypeIndex = -1;
- if (formatIndices.Size() != 0)
- arcTypeIndex = formatIndices[0];
- if (arcTypeIndex >= 0)
- MethodMode.FormatIndex = arcTypeIndex;
+ // int arcTypeIndex = -1;
+ if (types.Size() != 0)
+ {
+ MethodMode.Type = types[0];
+ MethodMode.Type_Defined = true;
+ }
+ if (MethodMode.Type.FormatIndex < 0)
+ {
+ // MethodMode.Type = -1;
+ MethodMode.Type = COpenType();
+ if (ArcNameMode != k_ArcNameMode_Add)
+ {
+ MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveName(arcPath);
+ if (MethodMode.Type.FormatIndex >= 0)
+ MethodMode.Type_Defined = true;
+ }
+ }
+ return true;
+}
+
+bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath)
+{
+ UString typeExt;
+ int formatIndex = MethodMode.Type.FormatIndex;
+ if (formatIndex < 0)
+ {
+ typeExt = kDefaultArcExt;
+ }
else
{
- MethodMode.FormatIndex = codecs->FindFormatForArchiveName(arcPath);
- // It works incorrectly for update command if archive has some non-default extension!
- if (MethodMode.FormatIndex < 0)
- MethodMode.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArchiveType);
+ const CArcInfoEx &arcInfo = codecs->Formats[formatIndex];
+ if (!arcInfo.UpdateEnabled)
+ return false;
+ typeExt = arcInfo.GetMainExt();
}
- if (MethodMode.FormatIndex < 0)
- return false;
- const CArcInfoEx &arcInfo = codecs->Formats[MethodMode.FormatIndex];
- if (!arcInfo.UpdateEnabled)
- return false;
- UString typeExt = arcInfo.GetMainExt();
UString ext = typeExt;
if (SfxMode)
ext = kSFXExtension;
ArchivePath.BaseExtension = ext;
ArchivePath.VolExtension = typeExt;
- ArchivePath.ParseFromPath(arcPath);
- for (int i = 0; i < Commands.Size(); i++)
+ ArchivePath.ParseFromPath(arcPath, ArcNameMode);
+ FOR_VECTOR (i, Commands)
{
CUpdateArchiveCommand &uc = Commands[i];
uc.ArchivePath.BaseExtension = ext;
uc.ArchivePath.VolExtension = typeExt;
- uc.ArchivePath.ParseFromPath(uc.UserArchivePath);
+ uc.ArchivePath.ParseFromPath(uc.UserArchivePath, ArcNameMode);
}
return true;
}
@@ -288,7 +407,7 @@ struct CUpdateProduceCallbackImp: public IUpdateProduceCallback
{
const CObjectVector<CArcItem> *_arcItems;
IUpdateCallbackUI *_callback;
-
+
CUpdateProduceCallbackImp(const CObjectVector<CArcItem> *a,
IUpdateCallbackUI *callback): _arcItems(a), _callback(callback) {}
virtual HRESULT ShowDeleteFile(int arcIndex);
@@ -300,36 +419,98 @@ HRESULT CUpdateProduceCallbackImp::ShowDeleteFile(int arcIndex)
}
*/
+bool CRenamePair::Prepare()
+{
+ if (RecursedType != NRecursedType::kNonRecursed)
+ return false;
+ if (!WildcardParsing)
+ return true;
+ return !DoesNameContainWildcard(OldName);
+}
+
+extern bool g_CaseSensitive;
+
+static int CompareTwoNames(const wchar_t *s1, const wchar_t *s2)
+{
+ for (int i = 0;; i++)
+ {
+ wchar_t c1 = s1[i];
+ wchar_t c2 = s2[i];
+ if (c1 == 0 || c2 == 0)
+ return i;
+ if (c1 == c2)
+ continue;
+ if (!g_CaseSensitive && (MyCharUpper(c1) == MyCharUpper(c2)))
+ continue;
+ if (IsCharDirLimiter(c1) && IsCharDirLimiter(c2))
+ continue;
+ return i;
+ }
+}
+
+bool CRenamePair::GetNewPath(bool isFolder, const UString &src, UString &dest) const
+{
+ int num = CompareTwoNames(OldName, src);
+ if (OldName[num] == 0)
+ {
+ if (src[num] != 0 && !IsCharDirLimiter(src[num]) && num != 0 && !IsCharDirLimiter(src[num - 1]))
+ return false;
+ }
+ else
+ {
+ // OldName[num] != 0
+ // OldName = "1\1a.txt"
+ // src = "1"
+
+ if (!isFolder ||
+ src[num] != 0 ||
+ !IsCharDirLimiter(OldName[num]) ||
+ OldName[num + 1] != 0)
+ return false;
+ }
+ dest = NewName + src.Ptr(num);
+ return true;
+}
+
+static int GetReverseSlashPos(const UString &name)
+{
+ int slashPos = name.ReverseFind(L'/');
+ #ifdef _WIN32
+ int slash1Pos = name.ReverseFind(L'\\');
+ slashPos = MyMax(slashPos, slash1Pos);
+ #endif
+ return slashPos;
+}
+
static HRESULT Compress(
+ const CUpdateOptions &options,
CCodecs *codecs,
const CActionSet &actionSet,
- IInArchive *archive,
- const CCompressionMethodMode &compressionMethod,
+ const CArc *arc,
CArchivePath &archivePath,
const CObjectVector<CArcItem> &arcItems,
- bool shareForWrite,
- bool stdInMode,
- /* const UString & stdInFileName, */
- bool stdOutMode,
+ Byte *processedItemsStatuses,
const CDirItems &dirItems,
- bool sfxMode,
- const UString &sfxModule,
- const CRecordVector<UInt64> &volumesSizes,
+ const CDirItem *parentDirItem,
CTempFiles &tempFiles,
CUpdateErrorInfo &errorInfo,
IUpdateCallbackUI *callback)
{
CMyComPtr<IOutArchive> outArchive;
- if (archive != NULL)
+ int formatIndex = options.MethodMode.Type.FormatIndex;
+ if (arc)
{
- CMyComPtr<IInArchive> archive2 = archive;
+ formatIndex = arc->FormatIndex;
+ if (formatIndex < 0)
+ return E_NOTIMPL;
+ CMyComPtr<IInArchive> archive2 = arc->Archive;
HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive);
if (result != S_OK)
throw kUpdateIsNotSupoorted;
}
else
{
- RINOK(codecs->CreateOutArchive(compressionMethod.FormatIndex, outArchive));
+ RINOK(codecs->CreateOutArchive(formatIndex, outArchive));
#ifdef EXTERNAL_CODECS
{
@@ -344,12 +525,12 @@ static HRESULT Compress(
}
if (outArchive == 0)
throw kUpdateIsNotSupoorted;
-
+
NFileTimeType::EEnum fileTimeType;
UInt32 value;
RINOK(outArchive->GetFileTimeType(&value));
- switch(value)
+ switch (value)
{
case NFileTimeType::kWindows:
case NFileTimeType::kUnix:
@@ -360,8 +541,69 @@ static HRESULT Compress(
return E_FAIL;
}
+ {
+ const CArcInfoEx &arcInfo = codecs->Formats[formatIndex];
+ if (options.AltStreams.Val && !arcInfo.Flags_AltStreams())
+ return E_NOTIMPL;
+ if (options.NtSecurity.Val && !arcInfo.Flags_NtSecure())
+ return E_NOTIMPL;
+ }
+
CRecordVector<CUpdatePair2> updatePairs2;
+ UStringVector newNames;
+
+ if (options.RenamePairs.Size() != 0)
+ {
+ FOR_VECTOR (i, arcItems)
+ {
+ const CArcItem &ai = arcItems[i];
+ bool needRename = false;
+ UString dest;
+ if (ai.Censored)
+ {
+ FOR_VECTOR (j, options.RenamePairs)
+ {
+ const CRenamePair &rp = options.RenamePairs[j];
+ if (rp.GetNewPath(ai.IsDir, ai.Name, dest))
+ {
+ needRename = true;
+ break;
+ }
+ if (ai.IsAltStream)
+ {
+ int colonPos = ai.Name.ReverseFind(':');
+ int slashPosPos = GetReverseSlashPos(ai.Name);
+ if (colonPos > slashPosPos)
+ {
+ UString mainName = ai.Name.Left(colonPos);
+ /*
+ actually we must improve that code to support cases
+ with folder renaming like: rn arc dir1\ dir2\
+ */
+ if (rp.GetNewPath(false, mainName, dest))
+ {
+ needRename = true;
+ dest += ':';
+ dest += ai.Name.Ptr(colonPos + 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+ CUpdatePair2 up2;
+ up2.SetAs_NoChangeArcItem(ai.IndexInServer);
+ if (needRename)
+ {
+ up2.NewProps = true;
+ RINOK(arc->IsItemAnti(i, up2.IsAnti));
+ up2.NewNameIndex = newNames.Add(dest);
+ }
+ updatePairs2.Add(up2);
+ }
+ }
+ else
{
CRecordVector<CUpdatePair> updatePairs;
GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!!
@@ -370,61 +612,81 @@ static HRESULT Compress(
}
UInt32 numFiles = 0;
- for (int i = 0; i < updatePairs2.Size(); i++)
+ FOR_VECTOR (i, updatePairs2)
if (updatePairs2[i].NewData)
numFiles++;
-
+
RINOK(callback->SetNumFiles(numFiles));
-
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
-
- updateCallbackSpec->ShareForWrite = shareForWrite;
- updateCallbackSpec->StdInMode = stdInMode;
+
+ updateCallbackSpec->ShareForWrite = options.OpenShareForWrite;
+ updateCallbackSpec->StdInMode = options.StdInMode;
updateCallbackSpec->Callback = callback;
+
+ if (arc)
+ {
+ // we set Archive to allow to transfer GetProperty requests back to DLL.
+ updateCallbackSpec->Archive = arc->Archive;
+ updateCallbackSpec->GetRawProps = arc->GetRawProps;
+ updateCallbackSpec->GetRootProps = arc->GetRootProps;
+ }
+
updateCallbackSpec->DirItems = &dirItems;
+ updateCallbackSpec->ParentDirItem = parentDirItem;
+
+ updateCallbackSpec->StoreNtSecurity = options.NtSecurity.Val;
+ updateCallbackSpec->StoreHardLinks = options.HardLinks.Val;
+ updateCallbackSpec->StoreSymLinks = options.SymLinks.Val;
+
updateCallbackSpec->ArcItems = &arcItems;
updateCallbackSpec->UpdatePairs = &updatePairs2;
+ updateCallbackSpec->ProcessedItemsStatuses = processedItemsStatuses;
+
+ if (options.RenamePairs.Size() != 0)
+ updateCallbackSpec->NewNames = &newNames;
+
+ CMyComPtr<IOutStream> outSeekStream;
CMyComPtr<ISequentialOutStream> outStream;
- if (!stdOutMode)
+ if (!options.StdOutMode)
{
- UString resultPath;
- int pos;
- if (!NFile::NDirectory::MyGetFullPathName(archivePath.GetFinalPath(), resultPath, pos))
+ FString dirPrefix;
+ if (!GetOnlyDirPrefix(us2fs(archivePath.GetFinalPath()), dirPrefix))
throw 1417161;
- NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
+ CreateComplexDir(dirPrefix);
}
COutFileStream *outStreamSpec = NULL;
COutMultiVolStream *volStreamSpec = NULL;
- if (volumesSizes.Size() == 0)
+ if (options.VolumesSizes.Size() == 0)
{
- if (stdOutMode)
+ if (options.StdOutMode)
outStream = new CStdOutFileStream;
else
{
outStreamSpec = new COutFileStream;
- outStream = outStreamSpec;
+ outSeekStream = outStreamSpec;
+ outStream = outSeekStream;
bool isOK = false;
- UString realPath;
+ FString realPath;
for (int i = 0; i < (1 << 16); i++)
{
if (archivePath.Temp)
{
if (i > 0)
{
- wchar_t s[16];
+ FChar s[16];
ConvertUInt32ToString(i, s);
archivePath.TempPostfix = s;
}
realPath = archivePath.GetTempPath();
}
else
- realPath = archivePath.GetFinalPath();
+ realPath = us2fs(archivePath.GetFinalPath());
if (outStreamSpec->Create(realPath, false))
{
tempFiles.Paths.Add(realPath);
@@ -447,12 +709,16 @@ static HRESULT Compress(
}
else
{
- if (stdOutMode)
+ if (options.StdOutMode)
return E_FAIL;
+ if (arc && arc->GetGlobalOffset() > 0)
+ return E_NOTIMPL;
+
volStreamSpec = new COutMultiVolStream;
- outStream = volStreamSpec;
- volStreamSpec->Sizes = volumesSizes;
- volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L".");
+ outSeekStream = volStreamSpec;
+ outStream = outSeekStream;
+ volStreamSpec->Sizes = options.VolumesSizes;
+ volStreamSpec->Prefix = us2fs(archivePath.GetFinalVolPath() + L".");
volStreamSpec->TempFiles = &tempFiles;
volStreamSpec->Init();
@@ -464,29 +730,29 @@ static HRESULT Compress(
*/
}
- RINOK(SetProperties(outArchive, compressionMethod.Properties));
+ RINOK(SetProperties(outArchive, options.MethodMode.Properties));
- if (sfxMode)
+ if (options.SfxMode)
{
CInFileStream *sfxStreamSpec = new CInFileStream;
CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
- if (!sfxStreamSpec->Open(sfxModule))
+ if (!sfxStreamSpec->Open(options.SfxModule))
{
errorInfo.SystemError = ::GetLastError();
errorInfo.Message = L"7-Zip cannot open SFX module";
- errorInfo.FileName = sfxModule;
+ errorInfo.FileName = options.SfxModule;
return E_FAIL;
}
CMyComPtr<ISequentialOutStream> sfxOutStream;
COutFileStream *outStreamSpec = NULL;
- if (volumesSizes.Size() == 0)
+ if (options.VolumesSizes.Size() == 0)
sfxOutStream = outStream;
else
{
outStreamSpec = new COutFileStream;
sfxOutStream = outStreamSpec;
- UString realPath = archivePath.GetFinalPath();
+ FString realPath = us2fs(archivePath.GetFinalPath());
if (!outStreamSpec->Create(realPath, false))
{
errorInfo.SystemError = ::GetLastError();
@@ -502,9 +768,61 @@ static HRESULT Compress(
}
}
- HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(), updateCallback);
+ CMyComPtr<ISequentialOutStream> tailStream;
+
+ if (options.SfxMode || !arc || arc->ArcStreamOffset == 0)
+ tailStream = outStream;
+ else
+ {
+ // Int64 globalOffset = arc->GetGlobalOffset();
+ RINOK(arc->InStream->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL));
+ if (options.StdOutMode)
+ tailStream = outStream;
+ else
+ {
+ CTailOutStream *tailStreamSpec = new CTailOutStream;
+ tailStream = tailStreamSpec;
+ tailStreamSpec->Stream = outSeekStream;
+ tailStreamSpec->Offset = arc->ArcStreamOffset;
+ tailStreamSpec->Init();
+ }
+ }
+
+
+ HRESULT result = outArchive->UpdateItems(tailStream, updatePairs2.Size(), updateCallback);
callback->Finilize();
RINOK(result);
+
+
+ if (options.SetArcMTime)
+ {
+ FILETIME ft;
+ ft.dwLowDateTime = 0;
+ ft.dwHighDateTime = 0;
+ FOR_VECTOR (i, updatePairs2)
+ {
+ CUpdatePair2 &pair2 = updatePairs2[i];
+ const FILETIME *ft2 = NULL;
+ if (pair2.NewProps && pair2.DirIndex >= 0)
+ ft2 = &dirItems.Items[pair2.DirIndex].MTime;
+ else if (pair2.UseArcProps && pair2.ArcIndex >= 0)
+ ft2 = &arcItems[pair2.ArcIndex].MTime;
+ if (ft2)
+ {
+ if (::CompareFileTime(&ft, ft2) < 0)
+ ft = *ft2;
+ }
+ }
+ if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0)
+ {
+ if (outStreamSpec)
+ outStreamSpec->SetMTime(&ft);
+ else if (volStreamSpec)
+ volStreamSpec->SetMTime(&ft);;
+ }
+ }
+
if (outStreamSpec)
result = outStreamSpec->Close();
else if (volStreamSpec)
@@ -512,7 +830,9 @@ static HRESULT Compress(
return result;
}
-HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
+static HRESULT EnumerateInArchiveItems(
+ // bool storeStreamsMode,
+ const NWildcard::CCensor &censor,
const CArc &arc,
CObjectVector<CArcItem> &arcItems)
{
@@ -520,23 +840,21 @@ HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
UInt32 numItems;
IInArchive *archive = arc.Archive;
RINOK(archive->GetNumberOfItems(&numItems));
- arcItems.Reserve(numItems);
+ arcItems.ClearAndReserve(numItems);
for (UInt32 i = 0; i < numItems; i++)
{
CArcItem ai;
RINOK(arc.GetItemPath(i, ai.Name));
- RINOK(IsArchiveItemFolder(archive, i, ai.IsDir));
- ai.Censored = censor.CheckPath(ai.Name, !ai.IsDir);
+ RINOK(Archive_IsItem_Folder(archive, i, ai.IsDir));
+ RINOK(Archive_IsItem_AltStream(archive, i, ai.IsAltStream));
+ /*
+ if (!storeStreamsMode && ai.IsAltStream)
+ continue;
+ */
+ ai.Censored = censor.CheckPath(ai.IsAltStream, ai.Name, !ai.IsDir);
RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined));
-
- {
- CPropVariant prop;
- RINOK(archive->GetProperty(i, kpidSize, &prop));
- ai.SizeDefined = (prop.vt != VT_EMPTY);
- if (ai.SizeDefined)
- ai.Size = ConvertPropVariantToUInt64(prop);
- }
+ RINOK(arc.GetItemSize(i, ai.Size, ai.SizeDefined));
{
CPropVariant prop;
@@ -544,7 +862,7 @@ HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
if (prop.vt == VT_UI4)
{
ai.TimeType = (int)(NFileTimeType::EEnum)prop.ulVal;
- switch(ai.TimeType)
+ switch (ai.TimeType)
{
case NFileTimeType::kWindows:
case NFileTimeType::kUnix:
@@ -557,99 +875,102 @@ HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
}
ai.IndexInServer = i;
- arcItems.Add(ai);
+ arcItems.AddInReserved(ai);
}
return S_OK;
}
-
-static HRESULT UpdateWithItemLists(
- CCodecs *codecs,
- CUpdateOptions &options,
- IInArchive *archive,
- const CObjectVector<CArcItem> &arcItems,
- CDirItems &dirItems,
- CTempFiles &tempFiles,
- CUpdateErrorInfo &errorInfo,
- IUpdateCallbackUI2 *callback)
+struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback
{
- for(int i = 0; i < options.Commands.Size(); i++)
+ IUpdateCallbackUI2 *Callback;
+ HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, bool isDir)
{
- CUpdateArchiveCommand &command = options.Commands[i];
- if (options.StdOutMode)
- {
- RINOK(callback->StartArchive(L"stdout", archive != 0));
- }
- else
- {
- RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(),
- i == 0 && options.UpdateArchiveItself && archive != 0));
- }
-
- RINOK(Compress(
- codecs,
- command.ActionSet, archive,
- options.MethodMode,
- command.ArchivePath,
- arcItems,
- options.OpenShareForWrite,
- options.StdInMode,
- /* options.StdInFileName, */
- options.StdOutMode,
- dirItems,
- options.SfxMode, options.SfxModule,
- options.VolumesSizes,
- tempFiles,
- errorInfo, callback));
-
- RINOK(callback->FinishArchive());
+ return Callback->ScanProgress(numFolders, numFiles, totalSize, path, isDir);
}
- return S_OK;
-}
+};
#if defined(_WIN32) && !defined(UNDER_CE)
-class CCurrentDirRestorer
+
+#include <mapi.h>
+
+#endif
+
+struct CRefSortPair
{
- UString _path;
-public:
- CCurrentDirRestorer() { NFile::NDirectory::MyGetCurrentDirectory(_path); }
- ~CCurrentDirRestorer() { RestoreDirectory();}
- bool RestoreDirectory() { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(_path)); }
+ int Len;
+ int Index;
};
-#endif
-struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback
+#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
+
+static int CompareRefSortPair(const CRefSortPair *a1, const CRefSortPair *a2, void *)
{
- IUpdateCallbackUI2 *Callback;
- HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path)
+ RINOZ(-MyCompare(a1->Len, a2->Len));
+ return MyCompare(a1->Index, a2->Index);
+}
+
+static int GetNumSlashes(const FChar *s)
+{
+ for (int numSlashes = 0;;)
{
- return Callback->ScanProgress(numFolders, numFiles, path);
+ FChar c = *s++;
+ if (c == 0)
+ return numSlashes;
+ if (
+ #ifdef _WIN32
+ c == FTEXT('\\') ||
+ #endif
+ c == FTEXT('/'))
+ numSlashes++;
}
-};
+}
#ifdef _WIN32
-typedef ULONG (FAR PASCAL MY_MAPISENDDOCUMENTS)(
- ULONG_PTR ulUIParam,
- LPSTR lpszDelimChar,
- LPSTR lpszFilePaths,
- LPSTR lpszFileNames,
- ULONG ulReserved
-);
-typedef MY_MAPISENDDOCUMENTS FAR *MY_LPMAPISENDDOCUMENTS;
+void ConvertToLongNames(NWildcard::CCensor &censor);
#endif
HRESULT UpdateArchive(
CCodecs *codecs,
- const NWildcard::CCensor &censor,
+ const CObjectVector<COpenType> &types,
+ const UString &cmdArcPath2,
+ NWildcard::CCensor &censor,
CUpdateOptions &options,
CUpdateErrorInfo &errorInfo,
IOpenCallbackUI *openCallback,
- IUpdateCallbackUI2 *callback)
+ IUpdateCallbackUI2 *callback,
+ bool needSetPath)
{
if (options.StdOutMode && options.EMailMode)
return E_FAIL;
- if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode))
+ if (types.Size() > 1)
+ return E_NOTIMPL;
+
+ bool renameMode = !options.RenamePairs.IsEmpty();
+ if (renameMode)
+ {
+ if (options.Commands.Size() != 1)
+ return E_FAIL;
+ }
+
+ if (options.DeleteAfterCompressing)
+ {
+ if (options.Commands.Size() != 1)
+ return E_NOTIMPL;
+ const CActionSet &as = options.Commands[0].ActionSet;
+ for (int i = 2; i < NPairState::kNumValues; i++)
+ if (as.StateActions[i] != NPairAction::kCompress)
+ return E_NOTIMPL;
+ }
+
+ censor.AddPathsToCensor(options.PathMode);
+ #ifdef _WIN32
+ ConvertToLongNames(censor);
+ #endif
+ censor.ExtendExclude();
+
+
+ if (options.VolumesSizes.Size() > 0 && (options.EMailMode /* || options.SfxMode */))
return E_NOTIMPL;
if (options.SfxMode)
@@ -663,40 +984,96 @@ HRESULT UpdateArchive(
errorInfo.Message = L"SFX file is not specified";
return E_FAIL;
}
- UString name = options.SfxModule;
- #ifdef UNDER_CE
- if (!NFind::DoesFileExist(name))
- #else
- if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule))
- #endif
+ bool found = false;
+ if (options.SfxModule.Find(FCHAR_PATH_SEPARATOR) < 0)
{
- errorInfo.SystemError = ::GetLastError();
- errorInfo.Message = L"7-Zip cannot find specified SFX module";
- errorInfo.FileName = name;
- return E_FAIL;
+ const FString fullName = ::GetModuleDirPrefix() + options.SfxModule;
+ if (NFind::DoesFileExist(fullName))
+ {
+ options.SfxModule = fullName;
+ found = true;
+ }
+ }
+ if (!found)
+ {
+ if (!NFind::DoesFileExist(options.SfxModule))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"7-Zip cannot find specified SFX module";
+ errorInfo.FileName = options.SfxModule;
+ return E_FAIL;
+ }
}
}
-
CArchiveLink arcLink;
- const UString arcPath = options.ArchivePath.GetFinalPath();
- if (!options.ArchivePath.OriginalPath.IsEmpty())
+
+ if (needSetPath)
{
- NFind::CFileInfoW fi;
- if (fi.Find(arcPath))
+ if (!options.InitFormatIndex(codecs, types, cmdArcPath2) ||
+ !options.SetArcPath(codecs, cmdArcPath2))
+ return E_NOTIMPL;
+ }
+ UString arcPath = options.ArchivePath.GetFinalPath();
+
+ if (cmdArcPath2.IsEmpty())
+ {
+ if (options.MethodMode.Type.FormatIndex < 0)
+ throw "type of archive is not specified";
+ }
+ else
+ {
+ NFind::CFileInfo fi;
+ if (!fi.Find(us2fs(arcPath)))
+ {
+ if (renameMode)
+ throw "can't find archive";;
+ if (options.MethodMode.Type.FormatIndex < 0)
+ {
+ if (!options.SetArcPath(codecs, cmdArcPath2))
+ return E_NOTIMPL;
+ }
+ }
+ else
{
if (fi.IsDir())
throw "there is no such archive";
+ if (fi.IsDevice)
+ return E_NOTIMPL;
if (options.VolumesSizes.Size() > 0)
return E_NOTIMPL;
- CIntVector formatIndices;
- if (options.MethodMode.FormatIndex >= 0)
- formatIndices.Add(options.MethodMode.FormatIndex);
- HRESULT result = arcLink.Open2(codecs, formatIndices, false, NULL, arcPath, openCallback);
+ CObjectVector<COpenType> types;
+ // change it.
+ if (options.MethodMode.Type_Defined)
+ types.Add(options.MethodMode.Type);
+ // We need to set Properties to open archive only in some cases (WIM archives).
+
+ CIntVector excl;
+ COpenOptions op;
+ #ifndef _SFX
+ op.props = &options.MethodMode.Properties;
+ #endif
+ op.codecs = codecs;
+ op.types = &types;
+ op.excludedFormats = &excl;
+ op.stdInMode = false;
+ op.stream = NULL;
+ op.filePath = arcPath;
+
+ HRESULT result = arcLink.Open2(op, openCallback);
+
if (result == E_ABORT)
return result;
- RINOK(callback->OpenResult(arcPath, result));
+
+ const wchar_t *errorArcType = NULL;
+ if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex > 0)
+ errorArcType = codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name;
+ RINOK(callback->OpenResult(arcPath, result, errorArcType));
+ /*
+ if (result == S_FALSE)
+ return E_FAIL;
+ */
RINOK(result);
if (arcLink.VolumePaths.Size() > 1)
{
@@ -704,21 +1081,48 @@ HRESULT UpdateArchive(
errorInfo.Message = L"Updating for multivolume archives is not implemented";
return E_NOTIMPL;
}
-
+
CArc &arc = arcLink.Arcs.Back();
arc.MTimeDefined = !fi.IsDevice;
arc.MTime = fi.MTime;
+
+ if (arc.ErrorInfo.ThereIsTail)
+ {
+ errorInfo.SystemError = (DWORD)E_NOTIMPL;
+ errorInfo.Message = L"There is some data block after the end of the archive";
+ return E_NOTIMPL;
+ }
+ if (options.MethodMode.Type.FormatIndex < 0)
+ {
+ options.MethodMode.Type.FormatIndex = arcLink.GetArc()->FormatIndex;
+ if (!options.SetArcPath(codecs, cmdArcPath2))
+ return E_NOTIMPL;
+ }
}
}
- else
+
+ if (options.MethodMode.Type.FormatIndex < 0)
{
- /*
- if (archiveType.IsEmpty())
- throw "type of archive is not specified";
- */
+ options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArcType);
+ if (options.MethodMode.Type.FormatIndex < 0)
+ return E_NOTIMPL;
}
+ bool thereIsInArchive = arcLink.IsOpen;
+ if (!thereIsInArchive && renameMode)
+ return E_FAIL;
+
CDirItems dirItems;
+ CDirItem parentDirItem;
+ CDirItem *parentDirItem_Ptr = NULL;
+
+ /*
+ FStringVector requestedPaths;
+ FStringVector *requestedPaths_Ptr = NULL;
+ if (options.DeleteAfterCompressing)
+ requestedPaths_Ptr = &requestedPaths;
+ */
+
if (options.StdInMode)
{
CDirItem di;
@@ -732,7 +1136,8 @@ HRESULT UpdateArchive(
else
{
bool needScanning = false;
- for(int i = 0; i < options.Commands.Size(); i++)
+ if (!renameMode)
+ FOR_VECTOR (i, options.Commands)
if (options.Commands[i].ActionSet.NeedScanning())
needScanning = true;
if (needScanning)
@@ -740,12 +1145,21 @@ HRESULT UpdateArchive(
CEnumDirItemUpdateCallback enumCallback;
enumCallback.Callback = callback;
RINOK(callback->StartScanning());
- UStringVector errorPaths;
- CRecordVector<DWORD> errorCodes;
- HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPaths, errorCodes);
- for (int i = 0; i < errorPaths.Size(); i++)
+
+ dirItems.SymLinks = options.SymLinks.Val;
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ dirItems.ReadSecure = options.NtSecurity.Val;
+ #endif
+
+ dirItems.ScanAltStreams = options.AltStreams.Val;
+ HRESULT res = EnumerateItems(censor,
+ options.PathMode,
+ options.AddPathPrefix,
+ dirItems, &enumCallback);
+ FOR_VECTOR (i, dirItems.ErrorPaths)
{
- RINOK(callback->CanNotFindError(errorPaths[i], errorCodes[i]));
+ RINOK(callback->CanNotFindError(fs2us(dirItems.ErrorPaths[i]), dirItems.ErrorCodes[i]));
}
if (res != S_OK)
{
@@ -754,14 +1168,46 @@ HRESULT UpdateArchive(
return res;
}
RINOK(callback->FinishScanning());
+
+ if (censor.Pairs.Size() == 1)
+ {
+ NFind::CFileInfo fi;
+ FString prefix = us2fs(censor.Pairs[0].Prefix) + FTEXT(".");
+ // UString prefix = censor.Pairs[0].Prefix;
+ /*
+ if (prefix.Back() == WCHAR_PATH_SEPARATOR)
+ {
+ prefix.DeleteBack();
+ }
+ */
+ if (fi.Find(prefix))
+ if (fi.IsDir())
+ {
+ parentDirItem.Size = fi.Size;
+ parentDirItem.CTime = fi.CTime;
+ parentDirItem.ATime = fi.ATime;
+ parentDirItem.MTime = fi.MTime;
+ parentDirItem.Attrib = fi.Attrib;
+ parentDirItem_Ptr = &parentDirItem;
+
+ int secureIndex = -1;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (options.NtSecurity.Val)
+ dirItems.AddSecurityItem(prefix, secureIndex);
+ #endif
+ parentDirItem.SecureIndex = secureIndex;
+
+ parentDirItem_Ptr = &parentDirItem;
+ }
+ }
}
}
- UString tempDirPrefix;
+ FString tempDirPrefix;
bool usesTempDir = false;
-
+
#ifdef _WIN32
- NDirectory::CTempDirectoryW tempDirectory;
+ CTempDir tempDirectory;
if (options.EMailMode && options.EMailRemoveAfter)
{
tempDirectory.Create(kTempFolderPrefix);
@@ -775,8 +1221,6 @@ HRESULT UpdateArchive(
bool createTempFile = false;
- bool thereIsInArchive = arcLink.IsOpen;
-
if (!options.StdOutMode && options.UpdateArchiveItself)
{
CArchivePath &ap = options.Commands[0].ArchivePath;
@@ -787,27 +1231,28 @@ HRESULT UpdateArchive(
createTempFile = true;
ap.Temp = true;
if (!options.WorkingDir.IsEmpty())
- {
ap.TempPrefix = options.WorkingDir;
- NormalizeDirPathPrefix(ap.TempPrefix);
- }
+ else
+ ap.TempPrefix = us2fs(ap.Prefix);
+ NormalizeDirPathPrefix(ap.TempPrefix);
}
}
- for(int i = 0; i < options.Commands.Size(); i++)
+ unsigned i;
+ for (i = 0; i < options.Commands.Size(); i++)
{
CArchivePath &ap = options.Commands[i].ArchivePath;
if (usesTempDir)
{
// Check it
- ap.Prefix = tempDirPrefix;
+ ap.Prefix = fs2us(tempDirPrefix);
// ap.Temp = true;
// ap.TempPrefix = tempDirPrefix;
}
if (!options.StdOutMode &&
(i > 0 || !createTempFile))
{
- const UString &path = ap.GetFinalPath();
+ const FString path = us2fs(ap.GetFinalPath());
if (NFind::DoesFileOrDirExist(path))
{
errorInfo.SystemError = 0;
@@ -821,13 +1266,64 @@ HRESULT UpdateArchive(
CObjectVector<CArcItem> arcItems;
if (thereIsInArchive)
{
- RINOK(EnumerateInArchiveItems(censor, arcLink.Arcs.Back(), arcItems));
+ RINOK(EnumerateInArchiveItems(
+ // options.StoreAltStreams,
+ censor, arcLink.Arcs.Back(), arcItems));
+ }
+
+ /*
+ FStringVector processedFilePaths;
+ FStringVector *processedFilePaths_Ptr = NULL;
+ if (options.DeleteAfterCompressing)
+ processedFilePaths_Ptr = &processedFilePaths;
+ */
+
+ CByteBuffer processedItems;
+ if (options.DeleteAfterCompressing)
+ {
+ unsigned num = dirItems.Items.Size();
+ processedItems.Alloc(num);
+ for (i = 0; i < num; i++)
+ processedItems[i] = 0;
+ }
+
+ for (i = 0; i < options.Commands.Size(); i++)
+ {
+ const CArc *arc = thereIsInArchive ? arcLink.GetArc() : 0;
+ // IInArchiveExtra *archiveExtra = thereIsInArchive ? arcLink.GetArchiveExtra() : 0;
+ // IArchiveGetRootProps *archiveGetRootProps = thereIsInArchive ? arcLink.GetArchiveGetRootProps() : 0;
+ CUpdateArchiveCommand &command = options.Commands[i];
+ UString name;
+ bool isUpdating;
+ if (options.StdOutMode)
+ {
+ name = L"stdout";
+ isUpdating = arc != 0;
+ }
+ else
+ {
+ name = command.ArchivePath.GetFinalPath();
+ isUpdating = (i == 0 && options.UpdateArchiveItself && arc != 0);
+ }
+ RINOK(callback->StartArchive(name, isUpdating))
+
+ RINOK(Compress(options,
+ codecs,
+ command.ActionSet,
+ arc,
+ command.ArchivePath,
+ arcItems,
+ options.DeleteAfterCompressing ? (Byte *)processedItems : NULL,
+
+ dirItems,
+ parentDirItem_Ptr,
+
+ tempFiles,
+ errorInfo, callback));
+
+ RINOK(callback->FinishArchive());
}
- RINOK(UpdateWithItemLists(codecs, options,
- thereIsInArchive ? arcLink.GetArchive() : 0,
- arcItems, dirItems,
- tempFiles, errorInfo, callback));
if (thereIsInArchive)
{
@@ -841,21 +1337,21 @@ HRESULT UpdateArchive(
try
{
CArchivePath &ap = options.Commands[0].ArchivePath;
- const UString &tempPath = ap.GetTempPath();
+ const FString &tempPath = ap.GetTempPath();
if (thereIsInArchive)
- if (!NDirectory::DeleteFileAlways(arcPath))
+ if (!DeleteFileAlways(us2fs(arcPath)))
{
errorInfo.SystemError = ::GetLastError();
errorInfo.Message = L"7-Zip cannot delete the file";
- errorInfo.FileName = arcPath;
+ errorInfo.FileName = us2fs(arcPath);
return E_FAIL;
}
- if (!NDirectory::MyMoveFile(tempPath, arcPath))
+ if (!MyMoveFile(tempPath, us2fs(arcPath)))
{
errorInfo.SystemError = ::GetLastError();
errorInfo.Message = L"7-Zip cannot move the file";
errorInfo.FileName = tempPath;
- errorInfo.FileName2 = arcPath;
+ errorInfo.FileName2 = us2fs(arcPath);
return E_FAIL;
}
}
@@ -865,30 +1361,42 @@ HRESULT UpdateArchive(
}
}
+
#if defined(_WIN32) && !defined(UNDER_CE)
if (options.EMailMode)
{
NDLL::CLibrary mapiLib;
- if (!mapiLib.Load(TEXT("Mapi32.dll")))
+ if (!mapiLib.Load(FTEXT("Mapi32.dll")))
{
errorInfo.SystemError = ::GetLastError();
errorInfo.Message = L"7-Zip cannot load Mapi32.dll";
return E_FAIL;
}
- MY_LPMAPISENDDOCUMENTS fnSend = (MY_LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments");
+
+ /*
+ LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments");
if (fnSend == 0)
{
errorInfo.SystemError = ::GetLastError();
errorInfo.Message = L"7-Zip cannot find MAPISendDocuments function";
return E_FAIL;
}
- UStringVector fullPaths;
- int i;
- for(i = 0; i < options.Commands.Size(); i++)
+ */
+ LPMAPISENDMAIL sendMail = (LPMAPISENDMAIL)mapiLib.GetProc("MAPISendMail");
+ if (sendMail == 0)
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"7-Zip cannot find MAPISendMail function";
+ return E_FAIL;
+ }
+
+ FStringVector fullPaths;
+ unsigned i;
+ for (i = 0; i < options.Commands.Size(); i++)
{
CArchivePath &ap = options.Commands[i].ArchivePath;
- UString arcPath;
- if (!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath))
+ FString arcPath;
+ if (!MyGetFullPathName(us2fs(ap.GetFinalPath()), arcPath))
{
errorInfo.SystemError = ::GetLastError();
errorInfo.Message = L"GetFullPathName error";
@@ -897,16 +1405,86 @@ HRESULT UpdateArchive(
fullPaths.Add(arcPath);
}
CCurrentDirRestorer curDirRestorer;
- for(i = 0; i < fullPaths.Size(); i++)
+ for (i = 0; i < fullPaths.Size(); i++)
{
- UString arcPath = fullPaths[i];
+ UString arcPath = fs2us(fullPaths[i]);
UString fileName = ExtractFileNameFromPath(arcPath);
AString path = GetAnsiString(arcPath);
AString name = GetAnsiString(fileName);
// Warning!!! MAPISendDocuments function changes Current directory
- fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
+ // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
+
+ MapiFileDesc f;
+ memset(&f, 0, sizeof(f));
+ f.nPosition = 0xFFFFFFFF;
+ f.lpszPathName = (char *)(const char *)path;
+ f.lpszFileName = (char *)(const char *)name;
+
+ MapiMessage m;
+ memset(&m, 0, sizeof(m));
+ m.nFileCount = 1;
+ m.lpFiles = &f;
+
+ const AString addr = GetAnsiString(options.EMailAddress);
+ MapiRecipDesc rec;
+ if (!addr.IsEmpty())
+ {
+ memset(&rec, 0, sizeof(rec));
+ rec.ulRecipClass = MAPI_TO;
+ rec.lpszAddress = (char *)(const char *)addr;
+ m.nRecipCount = 1;
+ m.lpRecips = &rec;
+ }
+
+ sendMail((LHANDLE)0, 0, &m, MAPI_DIALOG, 0);
}
}
#endif
+
+ if (options.DeleteAfterCompressing)
+ {
+ CRecordVector<CRefSortPair> pairs;
+ FStringVector foldersNames;
+ for (i = 0; i < dirItems.Items.Size(); i++)
+ {
+ const CDirItem &dirItem = dirItems.Items[i];
+ FString phyPath = us2fs(dirItems.GetPhyPath(i));
+ if (dirItem.IsDir())
+ {
+ CRefSortPair pair;
+ pair.Index = i;
+ pair.Len = GetNumSlashes(phyPath);
+ pairs.Add(pair);
+ }
+ else
+ {
+ if (processedItems[i] != 0 || dirItem.Size == 0)
+ {
+ DeleteFileAlways(phyPath);
+ }
+ else
+ {
+ // file was skipped
+ /*
+ errorInfo.SystemError = 0;
+ errorInfo.Message = L"file was not processed";
+ errorInfo.FileName = phyPath;
+ return E_FAIL;
+ */
+ }
+ }
+ }
+
+ pairs.Sort(CompareRefSortPair, NULL);
+ for (i = 0; i < pairs.Size(); i++)
+ {
+ FString phyPath = us2fs(dirItems.GetPhyPath(pairs[i].Index));
+ if (NFind::DoesDirExist(phyPath))
+ {
+ // printf("delete %S\n", phyPath);
+ RemoveDir(phyPath);
+ }
+ }
+ }
return S_OK;
}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/Update.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/Update.h
index ade001303..b2fdb4647 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/Update.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/Update.h
@@ -3,14 +3,22 @@
#ifndef __COMMON_UPDATE_H
#define __COMMON_UPDATE_H
-#include "Common/Wildcard.h"
+#include "../../../Common/Wildcard.h"
#include "ArchiveOpenCallback.h"
#include "LoadCodecs.h"
+#include "OpenArchive.h"
#include "Property.h"
#include "UpdateAction.h"
#include "UpdateCallback.h"
+enum EArcNameMode
+{
+ k_ArcNameMode_Smart,
+ k_ArcNameMode_Exact,
+ k_ArcNameMode_Add,
+};
+
struct CArchivePath
{
UString OriginalPath;
@@ -21,57 +29,16 @@ struct CArchivePath
UString VolExtension; // archive type extension for volumes
bool Temp;
- UString TempPrefix; // path(folder) for temp location
- UString TempPostfix;
+ FString TempPrefix; // path(folder) for temp location
+ FString TempPostfix;
CArchivePath(): Temp(false) {};
-
- void ParseFromPath(const UString &path)
- {
- OriginalPath = path;
-
- SplitPathToParts(path, Prefix, Name);
- int dotPos = Name.ReverseFind(L'.');
- if (dotPos < 0)
- return;
- if (dotPos == Name.Length() - 1)
- {
- Name = Name.Left(dotPos);
- BaseExtension.Empty();
- return;
- }
- if (BaseExtension.CompareNoCase(Name.Mid(dotPos + 1)) == 0)
- {
- BaseExtension = Name.Mid(dotPos + 1);
- Name = Name.Left(dotPos);
- }
- else
- BaseExtension.Empty();
- }
-
- UString GetPathWithoutExt() const
- {
- return Prefix + Name;
- }
- UString GetFinalPath() const
- {
- UString path = GetPathWithoutExt();
- if (!BaseExtension.IsEmpty())
- path += UString(L'.') + BaseExtension;
- return path;
- }
-
-
- UString GetTempPath() const
- {
- UString path = TempPrefix + Name;
- if (!BaseExtension.IsEmpty())
- path += UString(L'.') + BaseExtension;
- path += L".tmp";
- path += TempPostfix;
- return path;
- }
+ void ParseFromPath(const UString &path, EArcNameMode mode);
+ UString GetPathWithoutExt() const { return Prefix + Name; }
+ UString GetFinalPath() const;
+ UString GetFinalVolPath() const;
+ FString GetTempPath() const;
};
struct CUpdateArchiveCommand
@@ -83,9 +50,31 @@ struct CUpdateArchiveCommand
struct CCompressionMethodMode
{
- int FormatIndex;
+ bool Type_Defined;
+ COpenType Type;
CObjectVector<CProperty> Properties;
- CCompressionMethodMode(): FormatIndex(-1) {}
+
+ CCompressionMethodMode(): Type_Defined(false) {}
+};
+
+namespace NRecursedType { enum EEnum
+{
+ kRecursed,
+ kWildcardOnlyRecursed,
+ kNonRecursed
+};}
+
+struct CRenamePair
+{
+ UString OldName;
+ UString NewName;
+ bool WildcardParsing;
+ NRecursedType::EEnum RecursedType;
+
+ CRenamePair(): WildcardParsing(true), RecursedType(NRecursedType::kNonRecursed) {}
+
+ bool Prepare();
+ bool GetNewPath(bool isFolder, const UString &src, UString &dest) const;
};
struct CUpdateOptions
@@ -95,39 +84,60 @@ struct CUpdateOptions
CObjectVector<CUpdateArchiveCommand> Commands;
bool UpdateArchiveItself;
CArchivePath ArchivePath;
-
+ EArcNameMode ArcNameMode;
+
bool SfxMode;
- UString SfxModule;
-
+ FString SfxModule;
+
bool OpenShareForWrite;
bool StdInMode;
UString StdInFileName;
bool StdOutMode;
-
+
bool EMailMode;
bool EMailRemoveAfter;
UString EMailAddress;
- UString WorkingDir;
+ FString WorkingDir;
+ NWildcard::ECensorPathMode PathMode;
+ UString AddPathPrefix;
+
+ CBoolPair NtSecurity;
+ CBoolPair AltStreams;
+ CBoolPair HardLinks;
+ CBoolPair SymLinks;
+
+ bool DeleteAfterCompressing;
+
+ bool SetArcMTime;
- bool Init(const CCodecs *codecs, const CIntVector &formatIndices, const UString &arcPath);
+ CObjectVector<CRenamePair> RenamePairs;
+
+ bool InitFormatIndex(const CCodecs *codecs, const CObjectVector<COpenType> &types, const UString &arcPath);
+ bool SetArcPath(const CCodecs *codecs, const UString &arcPath);
CUpdateOptions():
UpdateArchiveItself(true),
+ ArcNameMode(k_ArcNameMode_Smart),
SfxMode(false),
OpenShareForWrite(false),
StdInMode(false),
StdOutMode(false),
EMailMode(false),
- EMailRemoveAfter(false)
+ EMailRemoveAfter(false),
+ PathMode(NWildcard::k_RelatPath),
+
+ DeleteAfterCompressing(false),
+ SetArcMTime(false)
+
{};
- void SetAddActionCommand()
+ void SetActionCommand_Add()
{
Commands.Clear();
CUpdateArchiveCommand c;
- c.ActionSet = NUpdateArchive::kAddActionSet;
+ c.ActionSet = NUpdateArchive::k_ActionSet_Add;
Commands.Add(c);
}
@@ -137,8 +147,8 @@ struct CUpdateOptions
struct CErrorInfo
{
DWORD SystemError;
- UString FileName;
- UString FileName2;
+ FString FileName;
+ FString FileName2;
UString Message;
// UStringVector ErrorPaths;
// CRecordVector<DWORD> ErrorCodes;
@@ -151,9 +161,9 @@ struct CUpdateErrorInfo: public CErrorInfo
#define INTERFACE_IUpdateCallbackUI2(x) \
INTERFACE_IUpdateCallbackUI(x) \
- virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) x; \
+ virtual HRESULT OpenResult(const wchar_t *name, HRESULT result, const wchar_t *errorArcType) x; \
virtual HRESULT StartScanning() x; \
- virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path) x; \
+ virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, bool isDir) x; \
virtual HRESULT CanNotFindError(const wchar_t *name, DWORD systemError) x; \
virtual HRESULT FinishScanning() x; \
virtual HRESULT StartArchive(const wchar_t *name, bool updating) x; \
@@ -166,10 +176,13 @@ struct IUpdateCallbackUI2: public IUpdateCallbackUI
HRESULT UpdateArchive(
CCodecs *codecs,
- const NWildcard::CCensor &censor,
+ const CObjectVector<COpenType> &types,
+ const UString &cmdArcPath2,
+ NWildcard::CCensor &censor,
CUpdateOptions &options,
CUpdateErrorInfo &errorInfo,
IOpenCallbackUI *openCallback,
- IUpdateCallbackUI2 *callback);
+ IUpdateCallbackUI2 *callback,
+ bool needSetPath);
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateAction.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateAction.cpp
index 879a49c57..a80db7212 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateAction.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateAction.cpp
@@ -6,7 +6,7 @@
namespace NUpdateArchive {
-const CActionSet kAddActionSet =
+const CActionSet k_ActionSet_Add =
{{
NPairAction::kCopy,
NPairAction::kCopy,
@@ -17,7 +17,7 @@ const CActionSet kAddActionSet =
NPairAction::kCompress
}};
-const CActionSet kUpdateActionSet =
+const CActionSet k_ActionSet_Update =
{{
NPairAction::kCopy,
NPairAction::kCopy,
@@ -28,7 +28,7 @@ const CActionSet kUpdateActionSet =
NPairAction::kCompress
}};
-const CActionSet kFreshActionSet =
+const CActionSet k_ActionSet_Fresh =
{{
NPairAction::kCopy,
NPairAction::kCopy,
@@ -39,7 +39,7 @@ const CActionSet kFreshActionSet =
NPairAction::kCompress
}};
-const CActionSet kSynchronizeActionSet =
+const CActionSet k_ActionSet_Sync =
{{
NPairAction::kCopy,
NPairAction::kIgnore,
@@ -50,7 +50,7 @@ const CActionSet kSynchronizeActionSet =
NPairAction::kCompress,
}};
-const CActionSet kDeleteActionSet =
+const CActionSet k_ActionSet_Delete =
{{
NPairAction::kCopy,
NPairAction::kIgnore,
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateAction.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateAction.h
index 0ac1c1080..b6645cbdd 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateAction.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateAction.h
@@ -7,7 +7,7 @@ namespace NUpdateArchive {
namespace NPairState
{
- const int kNumValues = 7;
+ const unsigned kNumValues = 7;
enum EEnum
{
kNotMasked = 0,
@@ -19,7 +19,7 @@ namespace NUpdateArchive {
kUnknowNewerFiles
};
}
-
+
namespace NPairAction
{
enum EEnum
@@ -30,13 +30,22 @@ namespace NUpdateArchive {
kCompressAsAnti
};
}
-
+
struct CActionSet
{
NPairAction::EEnum StateActions[NPairState::kNumValues];
+
+ bool IsEqualTo(const CActionSet &a) const
+ {
+ for (unsigned i = 0; i < NPairState::kNumValues; i++)
+ if (StateActions[i] != a.StateActions[i])
+ return false;
+ return true;
+ }
+
bool NeedScanning() const
{
- int i;
+ unsigned i;
for (i = 0; i < NPairState::kNumValues; i++)
if (StateActions[i] == NPairAction::kCompress)
return true;
@@ -46,12 +55,12 @@ namespace NUpdateArchive {
return false;
}
};
-
- extern const CActionSet kAddActionSet;
- extern const CActionSet kUpdateActionSet;
- extern const CActionSet kFreshActionSet;
- extern const CActionSet kSynchronizeActionSet;
- extern const CActionSet kDeleteActionSet;
+
+ extern const CActionSet k_ActionSet_Add;
+ extern const CActionSet k_ActionSet_Update;
+ extern const CActionSet k_ActionSet_Fresh;
+ extern const CActionSet k_ActionSet_Sync;
+ extern const CActionSet k_ActionSet_Delete;
}
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateCallback.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateCallback.cpp
index 0f229058c..609ece856 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateCallback.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateCallback.cpp
@@ -2,18 +2,32 @@
#include "StdAfx.h"
-#include "Common/ComTry.h"
-#include "Common/Defs.h"
-#include "Common/IntToString.h"
-#include "Common/StringConvert.h"
+#include "../../../Common/ComTry.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/Wildcard.h"
-#include "Windows/PropVariant.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/Synchronization.h"
#include "../../Common/FileStreams.h"
+#include "../../Common/StreamObjects.h"
#include "UpdateCallback.h"
+#if defined(_WIN32) && !defined(UNDER_CE)
+#define _USE_SECURITY_CODE
+#include "../../../Windows/SecurityUtils.h"
+#endif
+
using namespace NWindows;
+using namespace NFile;
+
+#ifdef _USE_SECURITY_CODE
+bool InitLocalPrivileges();
+#endif
CArchiveUpdateCallback::CArchiveUpdateCallback():
Callback(0),
@@ -22,8 +36,19 @@ CArchiveUpdateCallback::CArchiveUpdateCallback():
DirItems(0),
ArcItems(0),
UpdatePairs(0),
- NewNames(0)
- {}
+ NewNames(0),
+ KeepOriginalItemNames(false),
+ ProcessedItemsStatuses(NULL),
+ ParentDirItem(NULL),
+ StoreNtSecurity(false),
+ StoreHardLinks(false),
+ StoreSymLinks(false),
+ _hardIndex_From((UInt32)(Int32)-1)
+{
+ #ifdef _USE_SECURITY_CODE
+ _saclEnabled = InitLocalPrivileges();
+ #endif
+}
STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
@@ -49,7 +74,7 @@ STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UI
/*
-STATPROPSTG kProperties[] =
+static const STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL},
@@ -63,7 +88,7 @@ STATPROPSTG kProperties[] =
STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
{
- return CStatPropEnumerator::CreateEnumerator(kProperties, sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
+ return CStatPropEnumerator::CreateEnumerator(kProps, ARRAY_SIZE(kProps), enumerator);
}
*/
@@ -73,11 +98,11 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
COM_TRY_BEGIN
RINOK(Callback->CheckBreak());
const CUpdatePair2 &up = (*UpdatePairs)[index];
- if (newData != NULL) *newData = BoolToInt(up.NewData);
- if (newProps != NULL) *newProps = BoolToInt(up.NewProps);
- if (indexInArchive != NULL)
+ if (newData) *newData = BoolToInt(up.NewData);
+ if (newProps) *newProps = BoolToInt(up.NewProps);
+ if (indexInArchive)
{
- *indexInArchive = (UInt32)-1;
+ *indexInArchive = (UInt32)(Int32)-1;
if (up.ExistInArchive())
*indexInArchive = (ArcItems == 0) ? up.ArcIndex : (*ArcItems)[up.ArcIndex].IndexInServer;
}
@@ -85,40 +110,289 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+STDMETHODIMP CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value)
{
- COM_TRY_BEGIN
- const CUpdatePair2 &up = (*UpdatePairs)[index];
- NWindows::NCOM::CPropVariant prop;
-
- if (propID == kpidIsAnti)
+ NCOM::CPropVariant prop;
+ switch (propID)
{
- prop = up.IsAnti;
- prop.Detach(value);
+ case kpidIsDir: prop = true; break;
+ case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->Attrib; break;
+ case kpidCTime: if (ParentDirItem) prop = ParentDirItem->CTime; break;
+ case kpidATime: if (ParentDirItem) prop = ParentDirItem->ATime; break;
+ case kpidMTime: if (ParentDirItem) prop = ParentDirItem->MTime; break;
+ }
+ prop.Detach(value);
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)
+{
+ *parentType = NParentType::kDir;
+ *parent = (UInt32)(Int32)-1;
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps)
+{
+ *numProps = 0;
+ if (StoreNtSecurity)
+ *numProps = 1;
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)
+{
+ *name = NULL;
+ *propID = kpidNtSecure;
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID
+ #ifdef _USE_SECURITY_CODE
+ propID
+ #endif
+ , const void **data, UInt32 *dataSize, UInt32 *propType)
+{
+ *data = 0;
+ *dataSize = 0;
+ *propType = 0;
+ if (!StoreNtSecurity)
return S_OK;
+ #ifdef _USE_SECURITY_CODE
+ if (propID == kpidNtSecure)
+ {
+ if (StdInMode)
+ return S_OK;
+
+ if (ParentDirItem)
+ {
+ if (ParentDirItem->SecureIndex < 0)
+ return S_OK;
+ const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[ParentDirItem->SecureIndex];
+ *data = buf;
+ *dataSize = (UInt32)buf.Size();
+ *propType = NPropDataType::kRaw;
+ return S_OK;
+ }
+
+ if (GetRootProps)
+ return GetRootProps->GetRootRawProp(propID, data, dataSize, propType);
}
+ #endif
+ return S_OK;
+}
- if (up.IsAnti)
+// #ifdef _USE_SECURITY_CODE
+// #endif
+
+STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
+{
+ *data = 0;
+ *dataSize = 0;
+ *propType = 0;
+
+ if (propID == kpidNtSecure ||
+ propID == kpidNtReparse)
{
- switch(propID)
+ if (StdInMode)
+ return S_OK;
+
+ const CUpdatePair2 &up = (*UpdatePairs)[index];
+ if (up.UseArcProps && up.ExistInArchive() && GetRawProps)
+ return GetRawProps->GetRawProp(
+ ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex,
+ propID, data, dataSize, propType);
+
{
- case kpidIsDir:
- case kpidPath:
- break;
- case kpidSize:
- prop = (UInt64)0;
+ const CUpdatePair2 &up = (*UpdatePairs)[index];
+ /*
+ if (!up.NewData)
+ return E_FAIL;
+ */
+ if (up.IsAnti)
+ return S_OK;
+
+ #ifndef UNDER_CE
+ const CDirItem &di = DirItems->Items[up.DirIndex];
+ #endif
+
+ #ifdef _USE_SECURITY_CODE
+ if (propID == kpidNtSecure)
+ {
+ if (!StoreNtSecurity)
+ return S_OK;
+ if (di.SecureIndex < 0)
+ return S_OK;
+ const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[di.SecureIndex];
+ *data = buf;
+ *dataSize = (UInt32)buf.Size();
+ *propType = NPropDataType::kRaw;
+ }
+ else
+ #endif
+ {
+ // propID == kpidNtReparse
+ if (!StoreSymLinks)
+ return S_OK;
+ #if 0 // #ifndef UNDER_CE
+ const CByteBuffer *buf = &di.ReparseData2;
+ if (buf->Size() == 0)
+ buf = &di.ReparseData;
+ if (buf->Size() != 0)
+ {
+ *data = *buf;
+ *dataSize = (UInt32)buf->Size();
+ *propType = NPropDataType::kRaw;
+ }
+ #endif
+ }
+
+ return S_OK;
+ }
+ }
+
+ return S_OK;
+}
+
+#ifndef UNDER_CE
+
+static UString GetRelativePath(const UString &to, const UString &from)
+{
+ UStringVector partsTo, partsFrom;
+ SplitPathToParts(to, partsTo);
+ SplitPathToParts(from, partsFrom);
+
+ unsigned i;
+ for (i = 0;; i++)
+ {
+ if (i + 1 >= partsFrom.Size() ||
+ i + 1 >= partsTo.Size())
+ break;
+ if (CompareFileNames(partsFrom[i], partsTo[i]) != 0)
+ break;
+ }
+
+ if (i == 0)
+ {
+ #ifdef _WIN32
+ if (NName::IsDrivePath(to) ||
+ NName::IsDrivePath(from))
+ return to;
+ #endif
+ }
+
+ UString s;
+ unsigned k;
+
+ for (k = i + 1; k < partsFrom.Size(); k++)
+ s += L".." WSTRING_PATH_SEPARATOR;
+
+ for (k = i; k < partsTo.Size(); k++)
+ {
+ if (k != i)
+ s += WCHAR_PATH_SEPARATOR;
+ s += partsTo[k];
+ }
+
+ return s;
+}
+
+#endif
+
+STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ const CUpdatePair2 &up = (*UpdatePairs)[index];
+ NCOM::CPropVariant prop;
+
+ if (up.NewData)
+ {
+ /*
+ if (propID == kpidIsHardLink)
+ {
+ prop = _isHardLink;
+ prop.Detach(value);
+ return S_OK;
+ }
+ */
+ if (propID == kpidSymLink)
+ {
+ if (index == _hardIndex_From)
+ {
+ prop.Detach(value);
+ return S_OK;
+ }
+ if (up.DirIndex >= 0)
+ {
+ #if 0 // #ifndef UNDER_CE
+ const CDirItem &di = DirItems->Items[up.DirIndex];
+ // if (di.IsDir())
+ {
+ CReparseAttr attr;
+ if (attr.Parse(di.ReparseData, di.ReparseData.Size()))
+ {
+ UString simpleName = attr.GetPath();
+ if (attr.IsRelative())
+ prop = simpleName;
+ else
+ {
+ const UString phyPath = DirItems->GetPhyPath(up.DirIndex);
+ FString fullPath;
+ if (NDir::MyGetFullPathName(us2fs(phyPath), fullPath))
+ {
+ prop = GetRelativePath(simpleName, fs2us(fullPath));
+ }
+ }
+ prop.Detach(value);
+ return S_OK;
+ }
+ }
+ #endif
+ }
+ }
+ else if (propID == kpidHardLink)
+ {
+ if (index == _hardIndex_From)
+ {
+ const CKeyKeyValPair &pair = _map[_hardIndex_To];
+ const CUpdatePair2 &up2 = (*UpdatePairs)[pair.Value];
+ prop = DirItems->GetLogPath(up2.DirIndex);
prop.Detach(value);
return S_OK;
- default:
+ }
+ if (up.DirIndex >= 0)
+ {
prop.Detach(value);
return S_OK;
+ }
}
}
-
- if (up.ExistOnDisk())
+
+ if (up.IsAnti
+ && propID != kpidIsDir
+ && propID != kpidPath
+ && propID != kpidIsAltStream)
+ {
+ switch (propID)
+ {
+ case kpidSize: prop = (UInt64)0; break;
+ case kpidIsAnti: prop = true; break;
+ }
+ }
+ else if (propID == kpidPath && up.NewNameIndex >= 0)
+ prop = (*NewNames)[up.NewNameIndex];
+ else if (propID == kpidShortName && up.NewNameIndex >= 0 && up.IsMainRenameItem)
+ {
+ // we can generate new ShortName here;
+ }
+ else if ((up.UseArcProps
+ || (KeepOriginalItemNames && (propID == kpidPath || propID == kpidIsAltStream)))
+ && up.ExistInArchive() && Archive)
+ return Archive->GetProperty(ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex, propID, value);
+ else if (up.ExistOnDisk())
{
const CDirItem &di = DirItems->Items[up.DirIndex];
- switch(propID)
+ switch (propID)
{
case kpidPath: prop = DirItems->GetLogPath(up.DirIndex); break;
case kpidIsDir: prop = di.IsDir(); break;
@@ -127,27 +401,10 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
case kpidCTime: prop = di.CTime; break;
case kpidATime: prop = di.ATime; break;
case kpidMTime: prop = di.MTime; break;
- }
- }
- else
- {
- if (propID == kpidPath)
- {
- if (up.NewNameIndex >= 0)
- {
- prop = (*NewNames)[up.NewNameIndex];
- prop.Detach(value);
- return S_OK;
- }
- }
- if (up.ExistInArchive() && Archive)
- {
- UInt32 indexInArchive;
- if (ArcItems == 0)
- indexInArchive = up.ArcIndex;
- else
- indexInArchive = (*ArcItems)[up.ArcIndex].IndexInServer;
- return Archive->GetProperty(indexInArchive, propID, value);
+ case kpidIsAltStream: prop = di.IsAltStream; break;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // case kpidShortName: prop = di.ShortName; break;
+ #endif
}
}
prop.Detach(value);
@@ -155,24 +412,46 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
COM_TRY_END
}
+static NSynchronization::CCriticalSection CS;
+
STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
{
COM_TRY_BEGIN
+ *inStream = NULL;
const CUpdatePair2 &up = (*UpdatePairs)[index];
if (!up.NewData)
return E_FAIL;
-
+
RINOK(Callback->CheckBreak());
RINOK(Callback->Finilize());
+ bool isDir = IsDir(up);
+
if (up.IsAnti)
{
- return Callback->GetStream((*ArcItems)[up.ArcIndex].Name, true);
+ UString name;
+ if (up.ArcIndex >= 0)
+ name = (*ArcItems)[up.ArcIndex].Name;
+ else if (up.DirIndex >= 0)
+ name = DirItems->GetLogPath(up.DirIndex);
+ RINOK(Callback->GetStream(name, true));
+
+ /* 9.33: fixed. Handlers expect real stream object for files, even for anti-file.
+ so we return empty stream */
+
+ if (!isDir)
+ {
+ CBufInStream *inStreamSpec = new CBufInStream();
+ CMyComPtr<ISequentialInStream> inStreamLoc = inStreamSpec;
+ inStreamSpec->Init(NULL, 0);
+ *inStream = inStreamLoc.Detach();
+ }
+ return S_OK;
}
- const CDirItem &di = DirItems->Items[up.DirIndex];
+
RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), false));
-
- if (di.IsDir())
+
+ if (isDir)
return S_OK;
if (StdInMode)
@@ -185,13 +464,61 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream
{
CInFileStream *inStreamSpec = new CInFileStream;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+
+ inStreamSpec->SupportHardLinks = StoreHardLinks;
+
const UString path = DirItems->GetPhyPath(up.DirIndex);
- if (!inStreamSpec->OpenShared(path, ShareForWrite))
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (DirItems->Items[up.DirIndex].AreReparseData())
+ {
+ if (!inStreamSpec->File.OpenReparse(us2fs(path)))
+ {
+ return Callback->OpenFileError(path, ::GetLastError());
+ }
+ }
+ else
+ #endif
+ if (!inStreamSpec->OpenShared(us2fs(path), ShareForWrite))
{
return Callback->OpenFileError(path, ::GetLastError());
}
+
+#if 0 // FIXME
+ if (StoreHardLinks)
+ {
+ CStreamFileProps props;
+ if (inStreamSpec->GetProps2(&props) == S_OK)
+ {
+ if (props.NumLinks > 1)
+ {
+ CKeyKeyValPair pair;
+ pair.Key1 = props.VolID;
+ pair.Key2 = props.FileID_Low;
+ pair.Value = index;
+ unsigned numItems = _map.Size();
+ unsigned pairIndex = _map.AddToUniqueSorted2(pair);
+ if (numItems == _map.Size())
+ {
+ // const CKeyKeyValPair &pair2 = _map.Pairs[pairIndex];
+ _hardIndex_From = index;
+ _hardIndex_To = pairIndex;
+ // we could return NULL as stream, but it's better to return real stream
+ // return S_OK;
+ }
+ }
+ }
+ }
+#endif
+
+ if (ProcessedItemsStatuses)
+ {
+ NSynchronization::CCriticalSectionLock lock(CS);
+ ProcessedItemsStatuses[up.DirIndex] = 1;
+ }
*inStream = inStreamLoc.Detach();
}
+
return S_OK;
COM_TRY_END
}
@@ -216,12 +543,12 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
{
COM_TRY_BEGIN
- wchar_t temp[16];
+ FChar temp[16];
ConvertUInt32ToString(index + 1, temp);
- UString res = temp;
- while (res.Length() < 2)
- res = UString(L'0') + res;
- UString fileName = VolName;
+ FString res = temp;
+ while (res.Len() < 2)
+ res.InsertAtFront(FTEXT('0'));
+ FString fileName = VolName;
fileName += L'.';
fileName += res;
fileName += VolExt;
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateCallback.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateCallback.h
index 9a20c3159..81982e61d 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateCallback.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateCallback.h
@@ -1,10 +1,9 @@
// UpdateCallback.h
-#ifndef __UPDATECALLBACK_H
-#define __UPDATECALLBACK_H
+#ifndef __UPDATE_CALLBACK_H
+#define __UPDATE_CALLBACK_H
-#include "Common/MyCom.h"
-#include "Common/MyString.h"
+#include "../../../Common/MyCom.h"
#include "../../IPassword.h"
#include "../../ICoder.h"
@@ -32,16 +31,43 @@ struct IUpdateCallbackUI
INTERFACE_IUpdateCallbackUI(=0)
};
+struct CKeyKeyValPair
+{
+ UInt64 Key1;
+ UInt64 Key2;
+ unsigned Value;
+
+ int Compare(const CKeyKeyValPair &a) const
+ {
+ if (Key1 < a.Key1) return -1;
+ if (Key1 > a.Key1) return 1;
+ return MyCompare(Key2, a.Key2);
+ }
+};
+
+
class CArchiveUpdateCallback:
public IArchiveUpdateCallback2,
+ public IArchiveGetRawProps,
+ public IArchiveGetRootProps,
public ICryptoGetTextPassword2,
public ICryptoGetTextPassword,
public ICompressProgressInfo,
public CMyUnknownImp
{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ bool _saclEnabled;
+ #endif
+ CRecordVector<CKeyKeyValPair> _map;
+
+ UInt32 _hardIndex_From;
+ UInt32 _hardIndex_To;
+
public:
- MY_UNKNOWN_IMP4(
+ MY_UNKNOWN_IMP6(
IArchiveUpdateCallback2,
+ IArchiveGetRawProps,
+ IArchiveGetRootProps,
ICryptoGetTextPassword2,
ICryptoGetTextPassword,
ICompressProgressInfo)
@@ -49,26 +75,48 @@ public:
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
INTERFACE_IArchiveUpdateCallback2(;)
+ INTERFACE_IArchiveGetRawProps(;)
+ INTERFACE_IArchiveGetRootProps(;)
STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
-public:
CRecordVector<UInt64> VolumesSizes;
- UString VolName;
- UString VolExt;
+ FString VolName;
+ FString VolExt;
IUpdateCallbackUI *Callback;
bool ShareForWrite;
bool StdInMode;
+
const CDirItems *DirItems;
+ const CDirItem *ParentDirItem;
+
const CObjectVector<CArcItem> *ArcItems;
const CRecordVector<CUpdatePair2> *UpdatePairs;
const UStringVector *NewNames;
CMyComPtr<IInArchive> Archive;
+ CMyComPtr<IArchiveGetRawProps> GetRawProps;
+ CMyComPtr<IArchiveGetRootProps> GetRootProps;
+
+ bool KeepOriginalItemNames;
+ bool StoreNtSecurity;
+ bool StoreHardLinks;
+ bool StoreSymLinks;
+
+ Byte *ProcessedItemsStatuses;
CArchiveUpdateCallback();
+
+ bool IsDir(const CUpdatePair2 &up) const
+ {
+ if (up.DirIndex >= 0)
+ return DirItems->Items[up.DirIndex].IsDir();
+ else if (up.ArcIndex >= 0)
+ return (*ArcItems)[up.ArcIndex].IsDir;
+ return false;
+ }
};
#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdatePair.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdatePair.cpp
index d9396a583..95afdd694 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdatePair.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdatePair.cpp
@@ -4,10 +4,9 @@
#include <time.h>
-#include "Common/Defs.h"
-#include "Common/Wildcard.h"
+#include "../../../Common/Wildcard.h"
-#include "Windows/Time.h"
+#include "../../../Windows/TimeUtils.h"
#include "SortUtils.h"
#include "UpdatePair.h"
@@ -17,7 +16,7 @@ using namespace NTime;
static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time1, const FILETIME &time2)
{
- switch(fileTimeType)
+ switch (fileTimeType)
{
case NFileTimeType::kWindows:
return ::CompareFileTime(&time1, &time2);
@@ -28,28 +27,49 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time
FileTimeToUnixTime(time2, unixTime2);
return MyCompare(unixTime1, unixTime2);
}
+ case NFileTimeType::kDOS:
+ {
+ UInt32 dosTime1, dosTime2;
+ FileTimeToDosTime(time1, dosTime1);
+ FileTimeToDosTime(time2, dosTime2);
+ return MyCompare(dosTime1, dosTime2);
+ }
}
throw 4191618;
}
-static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:";
-static const wchar_t *kNotCensoredCollisionMessaged = L"Internal file name collision (file on disk, file in archive):";
+static const char *k_Duplicate_inArc_Message = "Duplicate filename in archive:";
+static const char *k_Duplicate_inDir_Message = "Duplicate filename on disk:";
+static const char *k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):";
-static void ThrowError(const UString &message, const UString &s1, const UString &s2)
+static void ThrowError(const char *message, const UString &s1, const UString &s2)
{
- UString m = message;
- m += L'\n';
- m += s1;
- m += L'\n';
- m += s2;
+ UString m;
+ m.SetFromAscii(message);
+ m += L'\n'; m += s1;
+ m += L'\n'; m += s2;
throw m;
}
-static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices)
+static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2)
{
- for(int i = 0; i + 1 < indices.Size(); i++)
- if (CompareFileNames(strings[indices[i]], strings[indices[i + 1]]) == 0)
- ThrowError(kDuplicateFileNameMessage, strings[indices[i]], strings[indices[i + 1]]);
+ int res = CompareFileNames(ai1.Name, ai2.Name);
+ if (res != 0)
+ return res;
+ if (ai1.IsDir != ai2.IsDir)
+ return ai1.IsDir ? -1 : 1;
+ return 0;
+}
+
+static int CompareArcItems(const unsigned *p1, const unsigned *p2, void *param)
+{
+ unsigned i1 = *p1;
+ unsigned i2 = *p2;
+ const CObjectVector<CArcItem> &arcItems = *(const CObjectVector<CArcItem> *)param;
+ int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]);
+ if (res != 0)
+ return res;
+ return MyCompare(i1, i2);
}
void GetUpdatePairInfoList(
@@ -58,48 +78,103 @@ void GetUpdatePairInfoList(
NFileTimeType::EEnum fileTimeType,
CRecordVector<CUpdatePair> &updatePairs)
{
- CIntVector dirIndices, arcIndices;
-
- int numDirItems = dirItems.Items.Size();
- int numArcItems = arcItems.Size();
-
-
+ CUIntVector dirIndices, arcIndices;
+
+ unsigned numDirItems = dirItems.Items.Size();
+ unsigned numArcItems = arcItems.Size();
+
+ CIntArr duplicatedArcItem(numArcItems);
{
- UStringVector arcNames;
- arcNames.Reserve(numArcItems);
- for (int i = 0; i < numArcItems; i++)
- arcNames.Add(arcItems[i].Name);
- SortFileNames(arcNames, arcIndices);
- TestDuplicateString(arcNames, arcIndices);
+ int *vals = &duplicatedArcItem[0];
+ for (unsigned i = 0; i < numArcItems; i++)
+ vals[i] = 0;
+ }
+
+ {
+ arcIndices.ClearAndSetSize(numArcItems);
+ {
+ unsigned *vals = &arcIndices[0];
+ for (unsigned i = 0; i < numArcItems; i++)
+ vals[i] = i;
+ }
+ arcIndices.Sort(CompareArcItems, (void *)&arcItems);
+ for (unsigned i = 0; i + 1 < numArcItems; i++)
+ if (CompareArcItemsBase(
+ arcItems[arcIndices[i]],
+ arcItems[arcIndices[i + 1]]) == 0)
+ {
+ duplicatedArcItem[i] = 1;
+ duplicatedArcItem[i + 1] = -1;
+ }
}
UStringVector dirNames;
{
- dirNames.Reserve(numDirItems);
- for (int i = 0; i < numDirItems; i++)
- dirNames.Add(dirItems.GetLogPath(i));
+ dirNames.ClearAndReserve(numDirItems);
+ unsigned i;
+ for (i = 0; i < numDirItems; i++)
+ dirNames.AddInReserved(dirItems.GetLogPath(i));
SortFileNames(dirNames, dirIndices);
- TestDuplicateString(dirNames, dirIndices);
+ for (i = 0; i + 1 < numDirItems; i++)
+ {
+ const UString &s1 = dirNames[dirIndices[i]];
+ const UString &s2 = dirNames[dirIndices[i + 1]];
+ if (CompareFileNames(s1, s2) == 0)
+ ThrowError(k_Duplicate_inDir_Message, s1, s2);
+ }
}
-
- int dirIndex = 0, arcIndex = 0;
- while (dirIndex < numDirItems && arcIndex < numArcItems)
+
+ unsigned dirIndex = 0;
+ unsigned arcIndex = 0;
+
+ int prevHostFile = -1;
+ const UString *prevHostName = NULL;
+
+ while (dirIndex < numDirItems || arcIndex < numArcItems)
{
CUpdatePair pair;
- int dirIndex2 = dirIndices[dirIndex];
- int arcIndex2 = arcIndices[arcIndex];
- const CDirItem &di = dirItems.Items[dirIndex2];
- const CArcItem &ai = arcItems[arcIndex2];
- int compareResult = CompareFileNames(dirNames[dirIndex2], ai.Name);
+
+ int dirIndex2 = -1;
+ int arcIndex2 = -1;
+ const CDirItem *di = NULL;
+ const CArcItem *ai = NULL;
+
+ int compareResult = -1;
+ const UString *name = NULL;
+
+ if (dirIndex < numDirItems)
+ {
+ dirIndex2 = dirIndices[dirIndex];
+ di = &dirItems.Items[dirIndex2];
+ }
+
+ if (arcIndex < numArcItems)
+ {
+ arcIndex2 = arcIndices[arcIndex];
+ ai = &arcItems[arcIndex2];
+ compareResult = 1;
+ if (dirIndex < numDirItems)
+ {
+ compareResult = CompareFileNames(dirNames[dirIndex2], ai->Name);
+ if (compareResult == 0)
+ {
+ if (di->IsDir() != ai->IsDir)
+ compareResult = (ai->IsDir ? 1 : -1);
+ }
+ }
+ }
+
if (compareResult < 0)
{
+ name = &dirNames[dirIndex2];
pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
pair.DirIndex = dirIndex2;
dirIndex++;
}
else if (compareResult > 0)
{
- pair.State = ai.Censored ?
+ name = &ai->Name;
+ pair.State = ai->Censored ?
NUpdateArchive::NPairState::kOnlyInArchive:
NUpdateArchive::NPairState::kNotMasked;
pair.ArcIndex = arcIndex2;
@@ -107,43 +182,50 @@ void GetUpdatePairInfoList(
}
else
{
- if (!ai.Censored)
- ThrowError(kNotCensoredCollisionMessaged, dirNames[dirIndex2], ai.Name);
+ int dupl = duplicatedArcItem[arcIndex];
+ if (dupl != 0)
+ ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[arcIndex + dupl]].Name);
+
+ name = &dirNames[dirIndex2];
+ if (!ai->Censored)
+ ThrowError(k_NotCensoredCollision_Message, *name, ai->Name);
+
pair.DirIndex = dirIndex2;
pair.ArcIndex = arcIndex2;
- switch (ai.MTimeDefined ? MyCompareTime(
- ai.TimeType != - 1 ? (NFileTimeType::EEnum)ai.TimeType : fileTimeType,
- di.MTime, ai.MTime): 0)
+
+ switch (ai->MTimeDefined ? MyCompareTime(
+ ai->TimeType != - 1 ? (NFileTimeType::EEnum)ai->TimeType : fileTimeType,
+ di->MTime, ai->MTime): 0)
{
case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break;
- case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break;
+ case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break;
default:
- pair.State = (ai.SizeDefined && di.Size == ai.Size) ?
+ pair.State = (ai->SizeDefined && di->Size == ai->Size) ?
NUpdateArchive::NPairState::kSameFiles :
NUpdateArchive::NPairState::kUnknowNewerFiles;
}
+
dirIndex++;
arcIndex++;
}
- updatePairs.Add(pair);
- }
- for (; dirIndex < numDirItems; dirIndex++)
- {
- CUpdatePair pair;
- pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
- pair.DirIndex = dirIndices[dirIndex];
- updatePairs.Add(pair);
- }
-
- for (; arcIndex < numArcItems; arcIndex++)
- {
- CUpdatePair pair;
- int arcIndex2 = arcIndices[arcIndex];
- pair.State = arcItems[arcIndex2].Censored ?
- NUpdateArchive::NPairState::kOnlyInArchive:
- NUpdateArchive::NPairState::kNotMasked;
- pair.ArcIndex = arcIndex2;
+ if ((di && di->IsAltStream) ||
+ (ai && ai->IsAltStream))
+ {
+ if (prevHostName)
+ {
+ unsigned hostLen = prevHostName->Len();
+ if (name->Len() > hostLen)
+ if ((*name)[hostLen] == ':' && CompareFileNames(*prevHostName, name->Left(hostLen)) == 0)
+ pair.HostIndex = prevHostFile;
+ }
+ }
+ else
+ {
+ prevHostFile = updatePairs.Size();
+ prevHostName = name;
+ }
+
updatePairs.Add(pair);
}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdatePair.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdatePair.h
index 3a332649c..296d3b097 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdatePair.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdatePair.h
@@ -13,7 +13,9 @@ struct CUpdatePair
NUpdateArchive::NPairState::EEnum State;
int ArcIndex;
int DirIndex;
- CUpdatePair(): ArcIndex(-1), DirIndex(-1) {}
+ int HostIndex; // >= 0 for alt streams only, contains index of host pair
+
+ CUpdatePair(): ArcIndex(-1), DirIndex(-1), HostIndex(-1) {}
};
void GetUpdatePairInfoList(
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateProduce.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateProduce.cpp
index c21db3b2a..2c4c28583 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateProduce.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateProduce.cpp
@@ -14,17 +14,17 @@ void UpdateProduce(
CRecordVector<CUpdatePair2> &operationChain,
IUpdateProduceCallback *callback)
{
- for (int i = 0; i < updatePairs.Size(); i++)
+ FOR_VECTOR (i, updatePairs)
{
const CUpdatePair &pair = updatePairs[i];
CUpdatePair2 up2;
- up2.IsAnti = false;
up2.DirIndex = pair.DirIndex;
up2.ArcIndex = pair.ArcIndex;
up2.NewData = up2.NewProps = true;
-
- switch(actionSet.StateActions[pair.State])
+ up2.UseArcProps = false;
+
+ switch (actionSet.StateActions[pair.State])
{
case NPairAction::kIgnore:
/*
@@ -39,17 +39,32 @@ void UpdateProduce(
case NPairAction::kCopy:
if (pair.State == NPairState::kOnlyOnDisk)
throw kUpdateActionSetCollision;
+ if (pair.State == NPairState::kOnlyInArchive)
+ {
+ if (pair.HostIndex >= 0)
+ {
+ /*
+ ignore alt stream if
+ 1) no such alt stream in Disk
+ 2) there is Host file in disk
+ */
+ if (updatePairs[pair.HostIndex].DirIndex >= 0)
+ continue;
+ }
+ }
up2.NewData = up2.NewProps = false;
+ up2.UseArcProps = true;
break;
-
+
case NPairAction::kCompress:
if (pair.State == NPairState::kOnlyInArchive ||
pair.State == NPairState::kNotMasked)
throw kUpdateActionSetCollision;
break;
-
+
case NPairAction::kCompressAsAnti:
up2.IsAnti = true;
+ up2.UseArcProps = (pair.ArcIndex >= 0);
break;
}
operationChain.Add(up2);
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateProduce.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateProduce.h
index e18648cd9..ef7b0f7a3 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateProduce.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/UpdateProduce.h
@@ -9,16 +9,36 @@ struct CUpdatePair2
{
bool NewData;
bool NewProps;
- bool IsAnti;
-
+ bool UseArcProps; // if (UseArcProps && NewProps), we want to change only some properties.
+ bool IsAnti; // if (!IsAnti) we use other ways to detect Anti status
+
int DirIndex;
int ArcIndex;
int NewNameIndex;
+ bool IsMainRenameItem;
+
+ void SetAs_NoChangeArcItem(int arcIndex)
+ {
+ NewData = NewProps = false;
+ UseArcProps = true;
+ IsAnti = false;
+ ArcIndex = arcIndex;
+ }
+
bool ExistOnDisk() const { return DirIndex != -1; }
bool ExistInArchive() const { return ArcIndex != -1; }
- CUpdatePair2(): IsAnti(false), DirIndex(-1), ArcIndex(-1), NewNameIndex(-1) {}
+ CUpdatePair2():
+ NewData(false),
+ NewProps(false),
+ UseArcProps(false),
+ IsAnti(false),
+ DirIndex(-1),
+ ArcIndex(-1),
+ NewNameIndex(-1),
+ IsMainRenameItem(false)
+ {}
};
struct IUpdateProduceCallback
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/WorkDir.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Common/WorkDir.cpp
deleted file mode 100644
index 28d36df9e..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/WorkDir.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// WorkDir.cpp
-
-#include "StdAfx.h"
-
-#include "Common/StringConvert.h"
-#include "Common/Wildcard.h"
-
-#include "Windows/FileDir.h"
-#include "Windows/FileName.h"
-
-#include "WorkDir.h"
-
-using namespace NWindows;
-using namespace NFile;
-
-UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path)
-{
- NWorkDir::NMode::EEnum mode = workDirInfo.Mode;
- #if !defined(UNDER_CE) && defined(_WIN32)
- if (workDirInfo.ForRemovableOnly)
- {
- mode = NWorkDir::NMode::kCurrent;
- UString prefix = path.Left(3);
- if (prefix[1] == L':' && prefix[2] == L'\\')
- {
- UINT driveType = GetDriveType(GetSystemString(prefix, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP));
- if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE)
- mode = workDirInfo.Mode;
- }
- /*
- CParsedPath parsedPath;
- parsedPath.ParsePath(archiveName);
- UINT driveType = GetDriveType(parsedPath.Prefix);
- if ((driveType != DRIVE_CDROM) && (driveType != DRIVE_REMOVABLE))
- mode = NZipSettings::NWorkDir::NMode::kCurrent;
- */
- }
- #endif
- switch(mode)
- {
- case NWorkDir::NMode::kCurrent:
- {
- return ExtractDirPrefixFromPath(path);
- }
- case NWorkDir::NMode::kSpecified:
- {
- UString tempDir = workDirInfo.Path;
- NName::NormalizeDirPathPrefix(tempDir);
- return tempDir;
- }
- default:
- {
- UString tempDir;
- if (!NDirectory::MyGetTempPath(tempDir))
- throw 141717;
- return tempDir;
- }
- }
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/WorkDir.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/WorkDir.h
deleted file mode 100644
index 0643d67a4..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/WorkDir.h
+++ /dev/null
@@ -1,10 +0,0 @@
-// WorkDir.h
-
-#ifndef __WORKDIR_H
-#define __WORKDIR_H
-
-#include "ZipRegistry.h"
-
-UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path);
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Common/ZipRegistry.h b/src/libs/7zip/unix/CPP/7zip/UI/Common/ZipRegistry.h
deleted file mode 100644
index 378353868..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/ZipRegistry.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// ZipRegistry.h
-
-#ifndef __ZIP_REGISTRY_H
-#define __ZIP_REGISTRY_H
-
-#include "Common/MyString.h"
-#include "Common/Types.h"
-
-#include "ExtractMode.h"
-
-namespace NExtract
-{
- struct CInfo
- {
- NPathMode::EEnum PathMode;
- NOverwriteMode::EEnum OverwriteMode;
- bool ShowPassword;
- UStringVector Paths;
-
- void Save() const;
- void Load();
- };
-}
-
-namespace NCompression
-{
- struct CFormatOptions
- {
- UInt32 Level;
- UInt32 Dictionary;
- UInt32 Order;
- UInt32 BlockLogSize;
- UInt32 NumThreads;
-
- CSysString FormatID;
- UString Method;
- UString Options;
- UString EncryptionMethod;
-
- void ResetForLevelChange()
- {
- BlockLogSize = NumThreads = Level = Dictionary = Order = UInt32(-1);
- Method.Empty();
- // Options.Empty();
- // EncryptionMethod.Empty();
- }
- CFormatOptions() { ResetForLevelChange(); }
- };
-
- struct CInfo
- {
- UInt32 Level;
- bool ShowPassword;
- bool EncryptHeaders;
- UString ArcType;
- UStringVector ArcPaths;
-
- CObjectVector<CFormatOptions> Formats;
-
- void Save() const;
- void Load();
- };
-}
-
-namespace NWorkDir
-{
- namespace NMode
- {
- enum EEnum
- {
- kSystem,
- kCurrent,
- kSpecified
- };
- }
- struct CInfo
- {
- NMode::EEnum Mode;
- UString Path;
- bool ForRemovableOnly;
-
- void SetForRemovableOnlyDefault() { ForRemovableOnly = true; }
- void SetDefault()
- {
- Mode = NMode::kSystem;
- Path.Empty();
- SetForRemovableOnlyDefault();
- }
-
- void Save() const;
- void Load();
- };
-}
-
-
-struct CContextMenuInfo
-{
- bool Cascaded;
- UInt32 Flags;
-
- void Save() const;
- void Load();
-};
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/BenchCon.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Console/BenchCon.cpp
deleted file mode 100644
index 35e868c9b..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/BenchCon.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-// BenchCon.cpp
-
-#include "StdAfx.h"
-
-#include "../../../Common/IntToString.h"
-#include "../../../Common/MyCom.h"
-
-#if !defined(_7ZIP_ST) || defined(_WIN32)
-#include "../../../Windows/System.h"
-#endif
-
-#include "../Common/Bench.h"
-
-#include "BenchCon.h"
-#include "ConsoleClose.h"
-
-struct CTotalBenchRes
-{
- UInt64 NumIterations;
- UInt64 Rating;
- UInt64 Usage;
- UInt64 RPU;
- void Init() { NumIterations = 0; Rating = 0; Usage = 0; RPU = 0; }
- void Normalize()
- {
- if (NumIterations == 0)
- return;
- Rating /= NumIterations;
- Usage /= NumIterations;
- RPU /= NumIterations;
- NumIterations = 1;
- }
- void SetMid(const CTotalBenchRes &r1, const CTotalBenchRes &r2)
- {
- Rating = (r1.Rating + r2.Rating) / 2;
- Usage = (r1.Usage + r2.Usage) / 2;
- RPU = (r1.RPU + r2.RPU) / 2;
- NumIterations = (r1.NumIterations + r2.NumIterations) / 2;
- }
-};
-
-struct CBenchCallback: public IBenchCallback
-{
- CTotalBenchRes EncodeRes;
- CTotalBenchRes DecodeRes;
- FILE *f;
- void Init() { EncodeRes.Init(); DecodeRes.Init(); }
- void Normalize() { EncodeRes.Normalize(); DecodeRes.Normalize(); }
- UInt32 dictionarySize;
- HRESULT SetEncodeResult(const CBenchInfo &info, bool final);
- HRESULT SetDecodeResult(const CBenchInfo &info, bool final);
-};
-
-static void NormalizeVals(UInt64 &v1, UInt64 &v2)
-{
- while (v1 > 1000000)
- {
- v1 >>= 1;
- v2 >>= 1;
- }
-}
-
-static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
-{
- UInt64 elTime = elapsedTime;
- NormalizeVals(freq, elTime);
- if (elTime == 0)
- elTime = 1;
- return value * freq / elTime;
-}
-
-static void PrintNumber(FILE *f, UInt64 value, int size)
-{
- char s[32];
- ConvertUInt64ToString(value, s);
- fprintf(f, " ");
- for (int len = (int)strlen(s); len < size; len++)
- fprintf(f, " ");
- fputs(s, f);
-}
-
-static void PrintRating(FILE *f, UInt64 rating)
-{
- PrintNumber(f, rating / 1000000, 6);
-}
-
-static void PrintResults(FILE *f, UInt64 usage, UInt64 rpu, UInt64 rating)
-{
- PrintNumber(f, (usage + 5000) / 10000, 5);
- PrintRating(f, rpu);
- PrintRating(f, rating);
-}
-
-
-static void PrintResults(FILE *f, const CBenchInfo &info, UInt64 rating, CTotalBenchRes &res)
-{
- UInt64 speed = MyMultDiv64(info.UnpackSize, info.GlobalTime, info.GlobalFreq);
- PrintNumber(f, speed / 1024, 7);
- UInt64 usage = GetUsage(info);
- UInt64 rpu = GetRatingPerUsage(info, rating);
- PrintResults(f, usage, rpu, rating);
- res.NumIterations++;
- res.RPU += rpu;
- res.Rating += rating;
- res.Usage += usage;
-}
-
-static void PrintTotals(FILE *f, const CTotalBenchRes &res)
-{
- fprintf(f, " ");
- PrintResults(f, res.Usage, res.RPU, res.Rating);
-}
-
-
-HRESULT CBenchCallback::SetEncodeResult(const CBenchInfo &info, bool final)
-{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- if (final)
- {
- UInt64 rating = GetCompressRating(dictionarySize, info.GlobalTime, info.GlobalFreq, info.UnpackSize);
- PrintResults(f, info, rating, EncodeRes);
- }
- return S_OK;
-}
-
-static const char *kSep = " | ";
-
-
-HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final)
-{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- if (final)
- {
- UInt64 rating = GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);
- fputs(kSep, f);
- CBenchInfo info2 = info;
- info2.UnpackSize *= info2.NumIterations;
- info2.PackSize *= info2.NumIterations;
- info2.NumIterations = 1;
- PrintResults(f, info2, rating, DecodeRes);
- }
- return S_OK;
-}
-
-static void PrintRequirements(FILE *f, const char *sizeString, UInt64 size, const char *threadsString, UInt32 numThreads)
-{
- fprintf(f, "\nRAM %s ", sizeString);
- PrintNumber(f, (size >> 20), 5);
- fprintf(f, " MB, # %s %3d", threadsString, (unsigned int)numThreads);
-}
-
-HRESULT LzmaBenchCon(
- DECL_EXTERNAL_CODECS_LOC_VARS
- FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary)
-{
- if (!CrcInternalTest())
- return S_FALSE;
- #ifndef _7ZIP_ST
- UInt64 ramSize = NWindows::NSystem::GetRamSize(); //
- UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
- PrintRequirements(f, "size: ", ramSize, "CPU hardware threads:", numCPUs);
- if (numThreads == (UInt32)-1)
- numThreads = numCPUs;
- if (numThreads > 1)
- numThreads &= ~1;
- if (dictionary == (UInt32)-1)
- {
- int dicSizeLog;
- for (dicSizeLog = 25; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)
- if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog)) + (8 << 20) <= ramSize)
- break;
- dictionary = (1 << dicSizeLog);
- }
- #else
- if (dictionary == (UInt32)-1)
- dictionary = (1 << 22);
- numThreads = 1;
- #endif
-
- PrintRequirements(f, "usage:", GetBenchMemoryUsage(numThreads, dictionary), "Benchmark threads: ", numThreads);
-
- CBenchCallback callback;
- callback.Init();
- callback.f = f;
-
- fprintf(f, "\n\nDict Compressing | Decompressing\n ");
- int j;
- for (j = 0; j < 2; j++)
- {
- fprintf(f, " Speed Usage R/U Rating");
- if (j == 0)
- fputs(kSep, f);
- }
- fprintf(f, "\n ");
- for (j = 0; j < 2; j++)
- {
- fprintf(f, " KB/s %% MIPS MIPS");
- if (j == 0)
- fputs(kSep, f);
- }
- fprintf(f, "\n\n");
- for (UInt32 i = 0; i < numIterations; i++)
- {
- const int kStartDicLog = 22;
- int pow = (dictionary < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog;
- while (((UInt32)1 << pow) > dictionary)
- pow--;
- for (; ((UInt32)1 << pow) <= dictionary; pow++)
- {
- fprintf(f, "%2d:", pow);
- callback.dictionarySize = (UInt32)1 << pow;
- HRESULT res = LzmaBench(
- EXTERNAL_CODECS_LOC_VARS
- numThreads, callback.dictionarySize, &callback);
- fprintf(f, "\n");
- RINOK(res);
- }
- }
- callback.Normalize();
- fprintf(f, "----------------------------------------------------------------\nAvr:");
- PrintTotals(f, callback.EncodeRes);
- fprintf(f, " ");
- PrintTotals(f, callback.DecodeRes);
- fprintf(f, "\nTot:");
- CTotalBenchRes midRes;
- midRes.SetMid(callback.EncodeRes, callback.DecodeRes);
- PrintTotals(f, midRes);
- fprintf(f, "\n");
- return S_OK;
-}
-
-struct CTempValues
-{
- UInt64 *Values;
- CTempValues(UInt32 num) { Values = new UInt64[num]; }
- ~CTempValues() { delete []Values; }
-};
-
-HRESULT CrcBenchCon(FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary)
-{
- if (!CrcInternalTest())
- return S_FALSE;
-
- #ifndef _7ZIP_ST
- UInt64 ramSize = NWindows::NSystem::GetRamSize();
- UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
- PrintRequirements(f, "size: ", ramSize, "CPU hardware threads:", numCPUs);
- if (numThreads == (UInt32)-1)
- numThreads = numCPUs;
- #else
- numThreads = 1;
- #endif
- if (dictionary == (UInt32)-1)
- dictionary = (1 << 24);
-
- CTempValues speedTotals(numThreads);
- fprintf(f, "\n\nSize");
- for (UInt32 ti = 0; ti < numThreads; ti++)
- {
- fprintf(f, " %5d", ti + 1);
- speedTotals.Values[ti] = 0;
- }
- fprintf(f, "\n\n");
-
- UInt64 numSteps = 0;
- for (UInt32 i = 0; i < numIterations; i++)
- {
- for (int pow = 10; pow < 32; pow++)
- {
- UInt32 bufSize = (UInt32)1 << pow;
- if (bufSize > dictionary)
- break;
- fprintf(f, "%2d: ", pow);
- UInt64 speed;
- for (UInt32 ti = 0; ti < numThreads; ti++)
- {
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- RINOK(CrcBench(ti + 1, bufSize, speed));
- PrintNumber(f, (speed >> 20), 5);
- speedTotals.Values[ti] += speed;
- }
- fprintf(f, "\n");
- numSteps++;
- }
- }
- if (numSteps != 0)
- {
- fprintf(f, "\nAvg:");
- for (UInt32 ti = 0; ti < numThreads; ti++)
- PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), 5);
- fprintf(f, "\n");
- }
- return S_OK;
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/BenchCon.h b/src/libs/7zip/unix/CPP/7zip/UI/Console/BenchCon.h
deleted file mode 100644
index 966a83a6a..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/BenchCon.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// BenchCon.h
-
-#ifndef __BENCH_CON_H
-#define __BENCH_CON_H
-
-#include <stdio.h>
-
-#include "../../Common/CreateCoder.h"
-
-HRESULT LzmaBenchCon(
- DECL_EXTERNAL_CODECS_LOC_VARS
- FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary);
-
-HRESULT CrcBenchCon(FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary);
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/Console.pri b/src/libs/7zip/unix/CPP/7zip/UI/Console/Console.pri
new file mode 100644
index 000000000..cdb025475
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Console/Console.pri
@@ -0,0 +1,2 @@
+HEADERS += $$7ZIP_BASE/CPP/7zip/UI/Console/PercentPrinter.h
+SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Console/PercentPrinter.cpp
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/ConsoleClose.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Console/ConsoleClose.cpp
deleted file mode 100644
index 9bb2082bf..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/ConsoleClose.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-// ConsoleClose.cpp
-
-#include "StdAfx.h"
-
-#include "ConsoleClose.h"
-
-#include <signal.h>
-
-static int g_BreakCounter = 0;
-static const int kBreakAbortThreshold = 2;
-
-namespace NConsoleClose {
-
-static void HandlerRoutine(int)
-{
- g_BreakCounter++;
- if (g_BreakCounter < kBreakAbortThreshold)
- return ;
- exit(EXIT_FAILURE);
-}
-
-bool TestBreakSignal()
-{
- return (g_BreakCounter > 0);
-}
-
-void CheckCtrlBreak()
-{
- if (TestBreakSignal())
- throw CCtrlBreakException();
-}
-
-CCtrlHandlerSetter::CCtrlHandlerSetter()
-{
- memo_sig_int = signal(SIGINT,HandlerRoutine); // CTRL-C
- if (memo_sig_int == SIG_ERR)
- throw "SetConsoleCtrlHandler fails (SIGINT)";
- memo_sig_term = signal(SIGTERM,HandlerRoutine); // for kill -15 (before "kill -9")
- if (memo_sig_term == SIG_ERR)
- throw "SetConsoleCtrlHandler fails (SIGTERM)";
-}
-
-CCtrlHandlerSetter::~CCtrlHandlerSetter()
-{
- signal(SIGINT,memo_sig_int); // CTRL-C
- signal(SIGTERM,memo_sig_term); // kill {pid}
-}
-
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/ConsoleClose.h b/src/libs/7zip/unix/CPP/7zip/UI/Console/ConsoleClose.h
deleted file mode 100644
index 042aaf2d6..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/ConsoleClose.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// ConsoleCloseUtils.h
-
-#ifndef __CONSOLECLOSEUTILS_H
-#define __CONSOLECLOSEUTILS_H
-
-namespace NConsoleClose {
-
-bool TestBreakSignal();
-
-class CCtrlHandlerSetter
-{
- void (*memo_sig_int)(int);
- void (*memo_sig_term)(int);
-public:
- CCtrlHandlerSetter();
- virtual ~CCtrlHandlerSetter();
-};
-
-class CCtrlBreakException
-{};
-
-void CheckCtrlBreak();
-
-}
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
deleted file mode 100644
index af65739c3..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-// ExtractCallbackConsole.h
-
-#include "StdAfx.h"
-
-#include "ExtractCallbackConsole.h"
-#include "UserInputUtils.h"
-#include "ConsoleClose.h"
-
-#include "Common/Wildcard.h"
-
-#include "Windows/FileDir.h"
-#include "Windows/FileFind.h"
-#include "Windows/Time.h"
-#include "Windows/Defs.h"
-#include "Windows/PropVariant.h"
-#include "Windows/Error.h"
-#include "Windows/PropVariantConversions.h"
-
-#include "../../Common/FilePathAutoRename.h"
-
-#include "../Common/ExtractingFilePath.h"
-
-using namespace NWindows;
-using namespace NFile;
-using namespace NDirectory;
-
-static const char *kTestString = "Testing ";
-static const char *kExtractString = "Extracting ";
-static const char *kSkipString = "Skipping ";
-
-// static const char *kCantAutoRename = "can not create file with auto name\n";
-// static const char *kCantRenameFile = "can not rename existing file\n";
-// static const char *kCantDeleteOutputFile = "can not delete output file ";
-static const char *kError = "ERROR: ";
-static const char *kMemoryExceptionMessage = "Can't allocate required memory!";
-
-static const char *kProcessing = "Processing archive: ";
-static const char *kEverythingIsOk = "Everything is Ok";
-static const char *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 *kUnknownError = "Unknown Error";
-
-STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64)
-{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- return S_OK;
-}
-
-STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *)
-{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- return S_OK;
-}
-
-STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
- const wchar_t *existName, const FILETIME *, const UInt64 *,
- const wchar_t *newName, const FILETIME *, const UInt64 *,
- Int32 *answer)
-{
- (*OutStream) << "file " << existName <<
- "\nalready exists. Overwrite with " << endl;
- (*OutStream) << newName;
-
- NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream);
-
- switch(overwriteAnswer)
- {
- case NUserAnswerMode::kQuit: return E_ABORT;
- case NUserAnswerMode::kNo: *answer = NOverwriteAnswer::kNo; break;
- case NUserAnswerMode::kNoAll: *answer = NOverwriteAnswer::kNoToAll; break;
- case NUserAnswerMode::kYesAll: *answer = NOverwriteAnswer::kYesToAll; break;
- case NUserAnswerMode::kYes: *answer = NOverwriteAnswer::kYes; break;
- case NUserAnswerMode::kAutoRenameAll: *answer = NOverwriteAnswer::kAutoRename; break;
- default: return E_FAIL;
- }
- return S_OK;
-}
-
-STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, bool /* isFolder */, Int32 askExtractMode, const UInt64 *position)
-{
- switch (askExtractMode)
- {
- case NArchive::NExtract::NAskMode::kExtract: (*OutStream) << kExtractString; break;
- case NArchive::NExtract::NAskMode::kTest: (*OutStream) << kTestString; break;
- case NArchive::NExtract::NAskMode::kSkip: (*OutStream) << kSkipString; break;
- };
- (*OutStream) << name;
- if (position != 0)
- (*OutStream) << " <" << *position << ">";
- return S_OK;
-}
-
-STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message)
-{
- (*OutStream) << message << endl;
- NumFileErrorsInCurrentArchive++;
- NumFileErrors++;
- return S_OK;
-}
-
-STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted)
-{
- switch(operationResult)
- {
- case NArchive::NExtract::NOperationResult::kOK:
- break;
- default:
- {
- NumFileErrorsInCurrentArchive++;
- NumFileErrors++;
- (*OutStream) << " ";
- switch(operationResult)
- {
- case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
- (*OutStream) << kUnsupportedMethod;
- break;
- case NArchive::NExtract::NOperationResult::kCRCError:
- (*OutStream) << (encrypted ? kCrcFailedEncrypted: kCrcFailed);
- break;
- case NArchive::NExtract::NOperationResult::kDataError:
- (*OutStream) << (encrypted ? kDataErrorEncrypted : kDataError);
- break;
- default:
- (*OutStream) << kUnknownError;
- }
- }
- }
- (*OutStream) << endl;
- return S_OK;
-}
-
-#ifndef _NO_CRYPTO
-
-HRESULT CExtractCallbackConsole::SetPassword(const UString &password)
-{
- PasswordIsDefined = true;
- Password = password;
- return S_OK;
-}
-
-STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)
-{
- if (!PasswordIsDefined)
- {
- Password = GetPassword(OutStream);
- PasswordIsDefined = true;
- }
- return StringToBstr(Password, password);
-}
-
-#endif
-
-HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name)
-{
- NumArchives++;
- NumFileErrorsInCurrentArchive = 0;
- (*OutStream) << endl << kProcessing << name << endl;
- return S_OK;
-}
-
-HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT result, bool encrypted)
-{
- (*OutStream) << endl;
- if (result != S_OK)
- {
- (*OutStream) << "Error: ";
- if (result == S_FALSE)
- {
- (*OutStream) << (encrypted ?
- "Can not open encrypted archive. Wrong password?" :
- "Can not open file as archive");
- }
- else
- {
- if (result == E_OUTOFMEMORY)
- (*OutStream) << "Can't allocate required memory";
- else
- (*OutStream) << NError::MyFormatMessage(result);
- }
- (*OutStream) << endl;
- NumArchiveErrors++;
- }
- return S_OK;
-}
-
-HRESULT CExtractCallbackConsole::ThereAreNoFiles()
-{
- (*OutStream) << endl << kNoFiles << endl;
- return S_OK;
-}
-
-HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)
-{
- if (result == S_OK)
- {
- (*OutStream) << endl;
- if (NumFileErrorsInCurrentArchive == 0)
- (*OutStream) << kEverythingIsOk << endl;
- else
- {
- NumArchiveErrors++;
- (*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl;
- }
- }
- if (result == S_OK)
- return result;
- NumArchiveErrors++;
- if (result == E_ABORT || result == ERROR_DISK_FULL)
- return result;
- (*OutStream) << endl << kError;
- if (result == E_OUTOFMEMORY)
- (*OutStream) << kMemoryExceptionMessage;
- else
- {
- UString message;
- NError::MyFormatMessage(result, message);
- (*OutStream) << message;
- }
- (*OutStream) << endl;
- return S_OK;
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/ExtractCallbackConsole.h b/src/libs/7zip/unix/CPP/7zip/UI/Console/ExtractCallbackConsole.h
deleted file mode 100644
index e42ca6f40..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/ExtractCallbackConsole.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// ExtractCallbackConsole.h
-
-#ifndef __EXTRACTCALLBACKCONSOLE_H
-#define __EXTRACTCALLBACKCONSOLE_H
-
-#include "Common/MyString.h"
-#include "Common/StdOutStream.h"
-#include "../../Common/FileStreams.h"
-#include "../../IPassword.h"
-#include "../../Archive/IArchive.h"
-#include "../Common/ArchiveExtractCallback.h"
-
-class CExtractCallbackConsole:
- public IExtractCallbackUI,
- #ifndef _NO_CRYPTO
- public ICryptoGetTextPassword,
- #endif
- public CMyUnknownImp
-{
-public:
- MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback)
- #ifndef _NO_CRYPTO
- MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword)
- #endif
- MY_QUERYINTERFACE_END
- MY_ADDREF_RELEASE
-
- STDMETHOD(SetTotal)(UInt64 total);
- STDMETHOD(SetCompleted)(const UInt64 *completeValue);
-
- // IFolderArchiveExtractCallback
- STDMETHOD(AskOverwrite)(
- const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
- const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
- Int32 *answer);
- STDMETHOD (PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position);
-
- STDMETHOD(MessageError)(const wchar_t *message);
- STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted);
-
- HRESULT BeforeOpen(const wchar_t *name);
- HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted);
- HRESULT ThereAreNoFiles();
- HRESULT ExtractResult(HRESULT result);
-
-
- #ifndef _NO_CRYPTO
- HRESULT SetPassword(const UString &password);
- STDMETHOD(CryptoGetTextPassword)(BSTR *password);
-
- bool PasswordIsDefined;
- UString Password;
-
- #endif
-
- UInt64 NumArchives;
- UInt64 NumArchiveErrors;
- UInt64 NumFileErrors;
- UInt64 NumFileErrorsInCurrentArchive;
-
- CStdOutStream *OutStream;
-
- void Init()
- {
- NumArchives = 0;
- NumArchiveErrors = 0;
- NumFileErrors = 0;
- NumFileErrorsInCurrentArchive = 0;
- }
-
-};
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/List.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Console/List.cpp
deleted file mode 100644
index f747cfda8..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/List.cpp
+++ /dev/null
@@ -1,654 +0,0 @@
-// List.cpp
-
-#include "StdAfx.h"
-
-#include "Common/IntToString.h"
-#include "Common/MyCom.h"
-#include "Common/StdOutStream.h"
-#include "Common/StringConvert.h"
-
-#include "Windows/Error.h"
-#include "Windows/FileDir.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
-
-#include "../../Archive/IArchive.h"
-
-#include "../Common/OpenArchive.h"
-#include "../Common/PropIDUtils.h"
-
-#include "ConsoleClose.h"
-#include "List.h"
-#include "OpenCallbackConsole.h"
-
-using namespace NWindows;
-
-struct CPropIdToName
-{
- PROPID PropID;
- const wchar_t *Name;
-};
-
-static const CPropIdToName kPropIdToName[] =
-{
- { kpidPath, L"Path" },
- { kpidName, L"Name" },
- { kpidIsDir, L"Folder" },
- { kpidSize, L"Size" },
- { kpidPackSize, L"Packed Size" },
- { kpidAttrib, L"Attributes" },
- { kpidCTime, L"Created" },
- { kpidATime, L"Accessed" },
- { kpidMTime, L"Modified" },
- { kpidSolid, L"Solid" },
- { kpidCommented, L"Commented" },
- { kpidEncrypted, L"Encrypted" },
- { kpidSplitBefore, L"Split Before" },
- { kpidSplitAfter, L"Split After" },
- { kpidDictionarySize, L"Dictionary Size" },
- { kpidCRC, L"CRC" },
- { kpidType, L"Type" },
- { kpidIsAnti, L"Anti" },
- { kpidMethod, L"Method" },
- { kpidHostOS, L"Host OS" },
- { kpidFileSystem, L"File System" },
- { kpidUser, L"User" },
- { kpidGroup, L"Group" },
- { kpidBlock, L"Block" },
- { kpidComment, L"Comment" },
- { kpidPosition, L"Position" },
- { kpidPrefix, L"Prefix" },
- { kpidNumSubDirs, L"Folders" },
- { kpidNumSubFiles, L"Files" },
- { kpidUnpackVer, L"Version" },
- { kpidVolume, L"Volume" },
- { kpidIsVolume, L"Multivolume" },
- { kpidOffset, L"Offset" },
- { kpidLinks, L"Links" },
- { kpidNumBlocks, L"Blocks" },
- { kpidNumVolumes, L"Volumes" },
-
- { kpidBit64, L"64-bit" },
- { kpidBigEndian, L"Big-endian" },
- { kpidCpu, L"CPU" },
- { kpidPhySize, L"Physical Size" },
- { kpidHeadersSize, L"Headers Size" },
- { kpidChecksum, L"Checksum" },
- { kpidCharacts, L"Characteristics" },
- { kpidVa, L"Virtual Address" },
- { kpidId, L"ID" },
- { kpidShortName, L"Short Name" },
- { kpidCreatorApp, L"Creator Application"},
- { kpidSectorSize, L"Sector Size" },
- { kpidPosixAttrib, L"Mode" },
- { kpidLink, L"Link" },
- { kpidError, L"Error" },
-
- { kpidTotalSize, L"Total Size" },
- { kpidFreeSpace, L"Free Space" },
- { kpidClusterSize, L"Cluster Size" },
- { kpidVolumeName, L"Label" }
-};
-
-static const char kEmptyAttribChar = '.';
-
-static const char *kListing = "Listing archive: ";
-static const wchar_t *kFilesMessage = L"files";
-static const wchar_t *kDirsMessage = L"folders";
-
-static void GetAttribString(DWORD wa, bool isDir, char *s)
-{
- s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : kEmptyAttribChar;
- s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar;
- s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar;
- s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar;
- s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar;
- s[5] = '\0';
-}
-
-enum EAdjustment
-{
- kLeft,
- kCenter,
- kRight
-};
-
-struct CFieldInfo
-{
- PROPID PropID;
- UString Name;
- EAdjustment TitleAdjustment;
- EAdjustment TextAdjustment;
- int PrefixSpacesWidth;
- int Width;
-};
-
-struct CFieldInfoInit
-{
- PROPID PropID;
- const wchar_t *Name;
- EAdjustment TitleAdjustment;
- EAdjustment TextAdjustment;
- int PrefixSpacesWidth;
- int Width;
-};
-
-static CFieldInfoInit kStandardFieldTable[] =
-{
- { kpidMTime, L" Date Time", kLeft, kLeft, 0, 19 },
- { kpidAttrib, L"Attr", kRight, kCenter, 1, 5 },
- { kpidSize, L"Size", kRight, kRight, 1, 12 },
- { kpidPackSize, L"Compressed", kRight, kRight, 1, 12 },
- { kpidPath, L"Name", kLeft, kLeft, 2, 24 }
-};
-
-static void PrintSpaces(int numSpaces)
-{
- for (int i = 0; i < numSpaces; i++)
- g_StdOut << ' ';
-}
-
-static void PrintString(EAdjustment adjustment, int width, const UString &textString)
-{
- const int numSpaces = width - textString.Length();
- int numLeftSpaces = 0;
- switch (adjustment)
- {
- case kLeft:
- numLeftSpaces = 0;
- break;
- case kCenter:
- numLeftSpaces = numSpaces / 2;
- break;
- case kRight:
- numLeftSpaces = numSpaces;
- break;
- }
- PrintSpaces(numLeftSpaces);
- g_StdOut << textString;
- PrintSpaces(numSpaces - numLeftSpaces);
-}
-
-class CFieldPrinter
-{
- CObjectVector<CFieldInfo> _fields;
-public:
- void Clear() { _fields.Clear(); }
- void Init(const CFieldInfoInit *standardFieldTable, int numItems);
- HRESULT Init(IInArchive *archive);
- void PrintTitle();
- void PrintTitleLines();
- HRESULT PrintItemInfo(const CArc &arc, UInt32 index, bool techMode);
- HRESULT PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs,
- const UInt64 *size, const UInt64 *compressedSize);
-};
-
-void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems)
-{
- Clear();
- for (int i = 0; i < numItems; i++)
- {
- CFieldInfo fieldInfo;
- const CFieldInfoInit &fieldInfoInit = standardFieldTable[i];
- fieldInfo.PropID = fieldInfoInit.PropID;
- fieldInfo.Name = fieldInfoInit.Name;
- fieldInfo.TitleAdjustment = fieldInfoInit.TitleAdjustment;
- fieldInfo.TextAdjustment = fieldInfoInit.TextAdjustment;
- fieldInfo.PrefixSpacesWidth = fieldInfoInit.PrefixSpacesWidth;
- fieldInfo.Width = fieldInfoInit.Width;
- _fields.Add(fieldInfo);
- }
-}
-
-static UString GetPropName(PROPID propID, BSTR name)
-{
- for (int i = 0; i < sizeof(kPropIdToName) / sizeof(kPropIdToName[0]); i++)
- {
- const CPropIdToName &propIdToName = kPropIdToName[i];
- if (propIdToName.PropID == propID)
- return propIdToName.Name;
- }
- if (name)
- return name;
- wchar_t s[16];
- ConvertUInt32ToString(propID, s);
- return s;
-}
-
-HRESULT CFieldPrinter::Init(IInArchive *archive)
-{
- Clear();
- UInt32 numProps;
- RINOK(archive->GetNumberOfProperties(&numProps));
- for (UInt32 i = 0; i < numProps; i++)
- {
- CMyComBSTR name;
- PROPID propID;
- VARTYPE vt;
- RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt));
- CFieldInfo fieldInfo;
- fieldInfo.PropID = propID;
- fieldInfo.Name = GetPropName(propID, name);
- _fields.Add(fieldInfo);
- }
- return S_OK;
-}
-
-void CFieldPrinter::PrintTitle()
-{
- for (int i = 0; i < _fields.Size(); i++)
- {
- const CFieldInfo &fieldInfo = _fields[i];
- PrintSpaces(fieldInfo.PrefixSpacesWidth);
- PrintString(fieldInfo.TitleAdjustment,
- ((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name);
- }
-}
-
-void CFieldPrinter::PrintTitleLines()
-{
- for (int i = 0; i < _fields.Size(); i++)
- {
- const CFieldInfo &fieldInfo = _fields[i];
- PrintSpaces(fieldInfo.PrefixSpacesWidth);
- for (int i = 0; i < fieldInfo.Width; i++)
- g_StdOut << '-';
- }
-}
-
-
-static BOOL IsFileTimeZero(CONST FILETIME *lpFileTime)
-{
- return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0);
-}
-
-static const char *kEmptyTimeString = " ";
-static void PrintTime(const NCOM::CPropVariant &prop)
-{
- if (prop.vt != VT_FILETIME)
- throw "incorrect item";
- if (IsFileTimeZero(&prop.filetime))
- g_StdOut << kEmptyTimeString;
- else
- {
- FILETIME localFileTime;
- if (!FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
- throw "FileTimeToLocalFileTime error";
- char s[32];
- if (ConvertFileTimeToString(localFileTime, s, true, true))
- g_StdOut << s;
- else
- g_StdOut << kEmptyTimeString;
- }
-}
-
-HRESULT CFieldPrinter::PrintItemInfo(const CArc &arc, UInt32 index, bool techMode)
-{
- /*
- if (techMode)
- {
- g_StdOut << "Index = ";
- g_StdOut << (UInt64)index;
- g_StdOut << endl;
- }
- */
- for (int i = 0; i < _fields.Size(); i++)
- {
- const CFieldInfo &fieldInfo = _fields[i];
- if (!techMode)
- PrintSpaces(fieldInfo.PrefixSpacesWidth);
-
- NCOM::CPropVariant prop;
- if (fieldInfo.PropID == kpidPath)
- {
- UString s;
- RINOK(arc.GetItemPath(index, s));
- prop = s;
- }
- else
- {
- RINOK(arc.Archive->GetProperty(index, fieldInfo.PropID, &prop));
- }
- if (techMode)
- {
- g_StdOut << fieldInfo.Name << " = ";
- }
- int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width;
- if (fieldInfo.PropID == kpidAttrib && (prop.vt == VT_EMPTY || prop.vt == VT_UI4))
- {
- UInt32 attrib = (prop.vt == VT_EMPTY) ? 0 : prop.ulVal;
- bool isFolder;
- RINOK(IsArchiveItemFolder(arc.Archive, index, isFolder));
- char s[8];
- GetAttribString(attrib, isFolder, s);
- g_StdOut << s;
- }
- else if (prop.vt == VT_EMPTY)
- {
- if (!techMode)
- PrintSpaces(width);
- }
- else if (fieldInfo.PropID == kpidMTime)
- {
- PrintTime(prop);
- }
- else if (prop.vt == VT_BSTR)
- {
- if (techMode)
- g_StdOut << prop.bstrVal;
- else
- PrintString(fieldInfo.TextAdjustment, width, prop.bstrVal);
- }
- else
- {
- UString s = ConvertPropertyToString(prop, fieldInfo.PropID);
- s.Replace(wchar_t(0xA), L' ');
- s.Replace(wchar_t(0xD), L' ');
-
- if (techMode)
- g_StdOut << s;
- else
- PrintString(fieldInfo.TextAdjustment, width, s);
- }
- if (techMode)
- g_StdOut << endl;
- }
- return S_OK;
-}
-
-static void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value)
-{
- wchar_t textString[32] = { 0 };
- if (value != NULL)
- ConvertUInt64ToString(*value, textString);
- PrintString(adjustment, width, textString);
-}
-
-
-HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs,
- const UInt64 *size, const UInt64 *compressedSize)
-{
- for (int i = 0; i < _fields.Size(); i++)
- {
- const CFieldInfo &fieldInfo = _fields[i];
- PrintSpaces(fieldInfo.PrefixSpacesWidth);
- NCOM::CPropVariant prop;
- if (fieldInfo.PropID == kpidSize)
- PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, size);
- else if (fieldInfo.PropID == kpidPackSize)
- PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, compressedSize);
- else if (fieldInfo.PropID == kpidPath)
- {
- wchar_t textString[32];
- ConvertUInt64ToString(numFiles, textString);
- UString temp = textString;
- temp += L" ";
- temp += kFilesMessage;
- temp += L", ";
- ConvertUInt64ToString(numDirs, textString);
- temp += textString;
- temp += L" ";
- temp += kDirsMessage;
- PrintString(fieldInfo.TextAdjustment, 0, temp);
- }
- else
- PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L"");
- }
- return S_OK;
-}
-
-bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value)
-{
- NCOM::CPropVariant prop;
- if (archive->GetProperty(index, propID, &prop) != S_OK)
- throw "GetPropertyValue error";
- if (prop.vt == VT_EMPTY)
- return false;
- value = ConvertPropVariantToUInt64(prop);
- return true;
-}
-
-static void PrintPropPair(const wchar_t *name, const wchar_t *value)
-{
- g_StdOut << name << " = " << value << endl;
-}
-
-HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
- bool stdInMode,
- UStringVector &arcPaths, UStringVector &arcPathsFull,
- const NWildcard::CCensorNode &wildcardCensor,
- bool enableHeaders, bool techMode,
- #ifndef _NO_CRYPTO
- bool &passwordEnabled, UString &password,
- #endif
- UInt64 &numErrors)
-{
- numErrors = 0;
- CFieldPrinter fieldPrinter;
- if (!techMode)
- fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));
-
- UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;
- UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;
- int numArcs = /* stdInMode ? 1 : */ arcPaths.Size();
- for (int i = 0; i < numArcs; i++)
- {
- const UString &archiveName = arcPaths[i];
- UInt64 arcPackSize = 0;
- if (!stdInMode)
- {
- NFile::NFind::CFileInfoW fi;
- if (!fi.Find(archiveName) || fi.IsDir())
- {
- g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;
- numErrors++;
- continue;
- }
- arcPackSize = fi.Size;
- }
-
- CArchiveLink archiveLink;
-
- COpenCallbackConsole openCallback;
- openCallback.OutStream = &g_StdOut;
-
- #ifndef _NO_CRYPTO
-
- openCallback.PasswordIsDefined = passwordEnabled;
- openCallback.Password = password;
-
- #endif
-
- HRESULT result = archiveLink.Open2(codecs, formatIndices, stdInMode, NULL, archiveName, &openCallback);
- if (result != S_OK)
- {
- if (result == E_ABORT)
- return result;
- g_StdOut << endl << "Error: " << archiveName << ": ";
- if (result == S_FALSE)
- {
- #ifndef _NO_CRYPTO
- if (openCallback.Open_WasPasswordAsked())
- g_StdOut << "Can not open encrypted archive. Wrong password?";
- else
- #endif
- g_StdOut << "Can not open file as archive";
- }
- else if (result == E_OUTOFMEMORY)
- g_StdOut << "Can't allocate required memory";
- else
- g_StdOut << NError::MyFormatMessage(result);
- g_StdOut << endl;
- numErrors++;
- continue;
- }
-
- if (!stdInMode)
- for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
- {
- int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]);
- if (index >= 0 && index > i)
- {
- arcPaths.Delete(index);
- arcPathsFull.Delete(index);
- numArcs = arcPaths.Size();
- }
- }
-
- if (enableHeaders)
- {
- g_StdOut << endl << kListing << archiveName << endl << endl;
-
- for (int i = 0; i < archiveLink.Arcs.Size(); i++)
- {
- const CArc &arc = archiveLink.Arcs[i];
-
- g_StdOut << "--\n";
- PrintPropPair(L"Path", arc.Path);
- PrintPropPair(L"Type", codecs->Formats[arc.FormatIndex].Name);
- if (!arc.ErrorMessage.IsEmpty())
- PrintPropPair(L"Error", arc.ErrorMessage);
- UInt32 numProps;
- IInArchive *archive = arc.Archive;
- if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK)
- {
- for (UInt32 j = 0; j < numProps; j++)
- {
- CMyComBSTR name;
- PROPID propID;
- VARTYPE vt;
- RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt));
- NCOM::CPropVariant prop;
- RINOK(archive->GetArchiveProperty(propID, &prop));
- UString s = ConvertPropertyToString(prop, propID);
- if (!s.IsEmpty())
- PrintPropPair(GetPropName(propID, name), s);
- }
- }
- if (i != archiveLink.Arcs.Size() - 1)
- {
- UInt32 numProps;
- g_StdOut << "----\n";
- if (archive->GetNumberOfProperties(&numProps) == S_OK)
- {
- UInt32 mainIndex = archiveLink.Arcs[i + 1].SubfileIndex;
- for (UInt32 j = 0; j < numProps; j++)
- {
- CMyComBSTR name;
- PROPID propID;
- VARTYPE vt;
- RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt));
- NCOM::CPropVariant prop;
- RINOK(archive->GetProperty(mainIndex, propID, &prop));
- UString s = ConvertPropertyToString(prop, propID);
- if (!s.IsEmpty())
- PrintPropPair(GetPropName(propID, name), s);
- }
- }
- }
-
- }
- g_StdOut << endl;
- if (techMode)
- g_StdOut << "----------\n";
- }
-
- if (enableHeaders && !techMode)
- {
- fieldPrinter.PrintTitle();
- g_StdOut << endl;
- fieldPrinter.PrintTitleLines();
- g_StdOut << endl;
- }
-
- const CArc &arc = archiveLink.Arcs.Back();
- IInArchive *archive = arc.Archive;
- if (techMode)
- {
- RINOK(fieldPrinter.Init(archive));
- }
- UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0;
- UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;
- UInt32 numItems;
- RINOK(archive->GetNumberOfItems(&numItems));
- for (UInt32 i = 0; i < numItems; i++)
- {
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
-
- UString filePath;
- HRESULT res = arc.GetItemPath(i, filePath);
- if (stdInMode && res == E_INVALIDARG)
- break;
- RINOK(res);
-
- bool isFolder;
- RINOK(IsArchiveItemFolder(archive, i, isFolder));
- if (!wildcardCensor.CheckPath(filePath, !isFolder))
- continue;
-
- fieldPrinter.PrintItemInfo(arc, i, techMode);
-
- UInt64 packSize, unpackSize;
- if (!GetUInt64Value(archive, i, kpidSize, unpackSize))
- unpackSize = 0;
- else
- totalUnPackSizePointer = &totalUnPackSize;
- if (!GetUInt64Value(archive, i, kpidPackSize, packSize))
- packSize = 0;
- else
- totalPackSizePointer = &totalPackSize;
-
- g_StdOut << endl;
-
- if (isFolder)
- numDirs++;
- else
- numFiles++;
- totalPackSize += packSize;
- totalUnPackSize += unpackSize;
- }
-
- if (!stdInMode && totalPackSizePointer == 0)
- {
- if (archiveLink.VolumePaths.Size() != 0)
- arcPackSize += archiveLink.VolumesSize;
- totalPackSize = (numFiles == 0) ? 0 : arcPackSize;
- totalPackSizePointer = &totalPackSize;
- }
- if (totalUnPackSizePointer == 0 && numFiles == 0)
- {
- totalUnPackSize = 0;
- totalUnPackSizePointer = &totalUnPackSize;
- }
- if (enableHeaders && !techMode)
- {
- fieldPrinter.PrintTitleLines();
- g_StdOut << endl;
- fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer);
- g_StdOut << endl;
- }
- if (totalPackSizePointer != 0)
- {
- totalPackSizePointer2 = &totalPackSize2;
- totalPackSize2 += totalPackSize;
- }
- if (totalUnPackSizePointer != 0)
- {
- totalUnPackSizePointer2 = &totalUnPackSize2;
- totalUnPackSize2 += totalUnPackSize;
- }
- numFiles2 += numFiles;
- numDirs2 += numDirs;
- }
- if (enableHeaders && !techMode && numArcs > 1)
- {
- g_StdOut << endl;
- fieldPrinter.PrintTitleLines();
- g_StdOut << endl;
- fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2);
- g_StdOut << endl;
- g_StdOut << "Archives: " << numArcs << endl;
- }
- return S_OK;
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/List.h b/src/libs/7zip/unix/CPP/7zip/UI/Console/List.h
deleted file mode 100644
index 97d9fb15a..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/List.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// List.h
-
-#ifndef __LIST_H
-#define __LIST_H
-
-#include "Common/Wildcard.h"
-#include "../Common/LoadCodecs.h"
-
-HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
- bool stdInMode,
- UStringVector &archivePaths, UStringVector &archivePathsFull,
- const NWildcard::CCensorNode &wildcardCensor,
- bool enableHeaders, bool techMode,
- #ifndef _NO_CRYPTO
- bool &passwordEnabled, UString &password,
- #endif
- UInt64 &errors);
-
-#endif
-
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/Main.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Console/Main.cpp
deleted file mode 100644
index cebfe2e42..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/Main.cpp
+++ /dev/null
@@ -1,628 +0,0 @@
-// Main.cpp
-
-#include "StdAfx.h"
-
-#if defined( _7ZIP_LARGE_PAGES)
-#include "../../../../C/Alloc.h"
-#endif
-
-#include "Common/MyInitGuid.h"
-
-#include "Common/CommandLineParser.h"
-#include "Common/IntToString.h"
-#include "Common/MyException.h"
-#include "Common/StdOutStream.h"
-#include "Common/StringConvert.h"
-#include "Common/StringToInt.h"
-
-#include "Windows/Error.h"
-#ifdef _WIN32
-#include "Windows/MemoryLock.h"
-#endif
-
-#include "../Common/ArchiveCommandLine.h"
-#include "../Common/ExitCode.h"
-#include "../Common/Extract.h"
-#ifdef EXTERNAL_CODECS
-#include "../Common/LoadCodecs.h"
-#endif
-
-#include "BenchCon.h"
-#include "ExtractCallbackConsole.h"
-#include "List.h"
-#include "OpenCallbackConsole.h"
-#include "UpdateCallbackConsole.h"
-
-#include "../../MyVersion.h"
-
-#include "myPrivate.h"
-#include "Windows/System.h"
-
-using namespace NWindows;
-using namespace NFile;
-using namespace NCommandLineParser;
-
-// HINSTANCE g_hInstance = 0;
-extern CStdOutStream *g_StdStream;
-
-static const char *kCopyrightString = "\n7-Zip"
-#ifndef EXTERNAL_CODECS
-" (A)"
-#endif
-
-#ifdef _WIN64
-" [64]"
-#endif
-
-" " MY_VERSION_COPYRIGHT_DATE "\n"
-"p7zip Version " P7ZIP_VERSION ;
-
-static const char *kHelpString =
- "\nUsage: 7z"
-#ifdef _NO_CRYPTO
- "r"
-#else
-#ifndef EXTERNAL_CODECS
- "a"
-#endif
-#endif
- " <command> [<switches>...] <archive_name> [<file_names>...]\n"
- " [<@listfiles...>]\n"
- "\n"
- "<Commands>\n"
- " a: Add files to archive\n"
- " b: Benchmark\n"
- " d: Delete files from archive\n"
- " e: Extract files from archive (without using directory names)\n"
- " l: List contents of archive\n"
-// " l[a|t][f]: List contents of archive\n"
-// " a - with Additional fields\n"
-// " t - with all fields\n"
-// " f - with Full pathnames\n"
- " t: Test integrity of archive\n"
- " u: Update files to archive\n"
- " x: eXtract files with full paths\n"
- "<Switches>\n"
- " -ai[r[-|0]]{@listfile|!wildcard}: Include archives\n"
- " -ax[r[-|0]]{@listfile|!wildcard}: eXclude archives\n"
- " -bd: Disable percentage indicator\n"
- " -i[r[-|0]]{@listfile|!wildcard}: Include filenames\n"
- " -m{Parameters}: set compression Method\n"
- " -o{Directory}: set Output directory\n"
- #ifndef _NO_CRYPTO
- " -p{Password}: set Password\n"
- #endif
- " -r[-|0]: Recurse subdirectories\n"
- " -scs{UTF-8 | WIN | DOS}: set charset for list files\n"
- " -sfx[{name}]: Create SFX archive\n"
- " -si[{name}]: read data from stdin\n"
- " -slt: show technical information for l (List) command\n"
- " -so: write data to stdout\n"
- " -ssc[-]: set sensitive case mode\n"
- " -t{Type}: Set type of archive\n"
- " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n"
- " -v{Size}[b|k|m|g]: Create volumes\n"
- " -w[{path}]: assign Work directory. Empty path means a temporary directory\n"
- " -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n"
- " -y: assume Yes on all queries\n";
-
-// ---------------------------
-// exception messages
-
-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 wchar_t *kDefaultSfxModule = L"7zCon.sfx";
-
-static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code)
-{
- s << message << endl;
- throw code;
-}
-
-static void PrintHelpAndExit(CStdOutStream &s)
-{
- s << kHelpString;
- ShowMessageAndThrowException(s, kUserErrorMessage, NExitCode::kUserError);
-}
-
-#ifndef _WIN32
-static void GetArguments(int numArgs, const char *args[], UStringVector &parts)
-{
- parts.Clear();
- for (int i = 0; i < numArgs; i++)
- {
- UString s = MultiByteToUnicodeString(args[i]);
- parts.Add(s);
- }
-}
-#endif
-
-static void ShowCopyrightAndHelp(CStdOutStream &s, bool needHelp)
-{
- s << kCopyrightString << " (locale=" << my_getlocale() <<",Utf16=";
- if (global_use_utf16_conversion) s << "on";
- else s << "off";
- s << ",HugeFiles=";
- if (sizeof(off_t) >= 8) s << "on,";
- else s << "off,";
- int nbcpu = NWindows::NSystem::GetNumberOfProcessors();
- if (nbcpu > 1) s << nbcpu << " CPUs)\n";
- else s << nbcpu << " CPU)\n";
-
- if (needHelp)
- s << kHelpString;
-}
-
-#ifdef EXTERNAL_CODECS
-static void PrintString(CStdOutStream &stdStream, const AString &s, int size)
-{
- int len = s.Length();
- stdStream << s;
- for (int i = len; i < size; i++)
- stdStream << ' ';
-}
-#endif
-
-static void PrintString(CStdOutStream &stdStream, const UString &s, int size)
-{
- int len = s.Length();
- stdStream << s;
- for (int i = len; i < size; i++)
- stdStream << ' ';
-}
-
-static inline char GetHex(Byte value)
-{
- return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
-}
-
-int Main2(
- #ifndef _WIN32
- int numArgs, const char *args[]
- #endif
-)
-{
- #if defined(_WIN32) && !defined(UNDER_CE)
- SetFileApisToOEM();
- #endif
-
- UStringVector commandStrings;
- #ifdef _WIN32
- NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
- #else
- // GetArguments(numArgs, args, commandStrings);
- extern void mySplitCommandLine(int numArgs,const char *args[],UStringVector &parts);
- mySplitCommandLine(numArgs,args,commandStrings);
- #endif
-
- if (commandStrings.Size() == 1)
- {
- ShowCopyrightAndHelp(g_StdOut, true);
- return 0;
- }
- commandStrings.Delete(0);
-
- CArchiveCommandLineOptions options;
-
- CArchiveCommandLineParser parser;
-
- parser.Parse1(commandStrings, options);
-
- if (options.HelpMode)
- {
- ShowCopyrightAndHelp(g_StdOut, true);
- return 0;
- }
-
- #if defined(_7ZIP_LARGE_PAGES)
- if (options.LargePages)
- {
- SetLargePageSize();
-#ifdef _WIN32
- NSecurity::EnableLockMemoryPrivilege();
-#endif
- }
- #endif
-
- CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut;
- g_StdStream = &stdStream;
-
- if (options.EnableHeaders)
- ShowCopyrightAndHelp(stdStream, false);
-
- parser.Parse2(options);
-
- CCodecs *codecs = new CCodecs;
- CMyComPtr<
- #ifdef EXTERNAL_CODECS
- ICompressCodecsInfo
- #else
- IUnknown
- #endif
- > compressCodecsInfo = codecs;
- HRESULT result = codecs->Load();
- if (result != S_OK)
- throw CSystemException(result);
-
- bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
-
- if (codecs->Formats.Size() == 0 &&
- (isExtractGroupCommand ||
- options.Command.CommandType == NCommandType::kList ||
- options.Command.IsFromUpdateGroup()))
- throw kNoFormats;
-
- CIntVector formatIndices;
- if (!codecs->FindFormatForArchiveType(options.ArcType, formatIndices))
- throw kUnsupportedArcTypeMessage;
-
- if (options.Command.CommandType == NCommandType::kInfo)
- {
- stdStream << endl << "Formats:" << endl;
- int i;
- for (i = 0; i < codecs->Formats.Size(); i++)
- {
- const CArcInfoEx &arc = codecs->Formats[i];
- #ifdef EXTERNAL_CODECS
- if (arc.LibIndex >= 0)
- {
- char s[16];
- ConvertUInt32ToString(arc.LibIndex, s);
- PrintString(stdStream, s, 2);
- }
- else
- #endif
- stdStream << " ";
- stdStream << ' ';
- stdStream << (char)(arc.UpdateEnabled ? 'C' : ' ');
- stdStream << (char)(arc.KeepName ? 'K' : ' ');
- stdStream << " ";
- PrintString(stdStream, arc.Name, 6);
- stdStream << " ";
- UString s;
- for (int t = 0; t < arc.Exts.Size(); t++)
- {
- const CArcExtInfo &ext = arc.Exts[t];
- s += ext.Ext;
- if (!ext.AddExt.IsEmpty())
- {
- s += L" (";
- s += ext.AddExt;
- s += L')';
- }
- s += L' ';
- }
- PrintString(stdStream, s, 14);
- stdStream << " ";
- const CByteBuffer &sig = arc.StartSignature;
- for (size_t j = 0; j < sig.GetCapacity(); j++)
- {
- Byte b = sig[j];
- if (b > 0x20 && b < 0x80)
- {
- stdStream << (char)b;
- }
- else
- {
- stdStream << GetHex((Byte)((b >> 4) & 0xF));
- stdStream << GetHex((Byte)(b & 0xF));
- }
- stdStream << ' ';
- }
- stdStream << endl;
- }
- stdStream << endl << "Codecs:" << endl;
-
- #ifdef EXTERNAL_CODECS
- UInt32 numMethods;
- if (codecs->GetNumberOfMethods(&numMethods) == S_OK)
- for (UInt32 j = 0; j < numMethods; j++)
- {
- int libIndex = codecs->GetCodecLibIndex(j);
- if (libIndex >= 0)
- {
- char s[16];
- ConvertUInt32ToString(libIndex, s);
- PrintString(stdStream, s, 2);
- }
- else
- stdStream << " ";
- stdStream << ' ';
- stdStream << (char)(codecs->GetCodecEncoderIsAssigned(j) ? 'C' : ' ');
- UInt64 id;
- stdStream << " ";
- HRESULT res = codecs->GetCodecId(j, id);
- if (res != S_OK)
- id = (UInt64)(Int64)-1;
- char s[32];
- ConvertUInt64ToString(id, s, 16);
- PrintString(stdStream, s, 8);
- stdStream << " ";
- PrintString(stdStream, codecs->GetCodecName(j), 11);
- stdStream << endl;
- /*
- if (res != S_OK)
- throw "incorrect Codec ID";
- */
- }
- #endif
- return S_OK;
- }
- else if (options.Command.CommandType == NCommandType::kBenchmark)
- {
- if (options.Method.CompareNoCase(L"CRC") == 0)
- {
- HRESULT res = CrcBenchCon((FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);
- if (res != S_OK)
- {
- if (res == S_FALSE)
- {
- stdStream << "\nCRC Error\n";
- return NExitCode::kFatalError;
- }
- throw CSystemException(res);
- }
- }
- else
- {
- HRESULT res;
- #ifdef EXTERNAL_CODECS
- CObjectVector<CCodecInfoEx> externalCodecs;
- res = LoadExternalCodecs(compressCodecsInfo, externalCodecs);
- if (res != S_OK)
- throw CSystemException(res);
- #endif
- res = LzmaBenchCon(
- #ifdef EXTERNAL_CODECS
- compressCodecsInfo, &externalCodecs,
- #endif
- (FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);
- if (res != S_OK)
- {
- if (res == S_FALSE)
- {
- stdStream << "\nDecoding Error\n";
- return NExitCode::kFatalError;
- }
- throw CSystemException(res);
- }
- }
- }
- else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
- {
- if (isExtractGroupCommand)
- {
- CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
- CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
-
- ecs->OutStream = &stdStream;
-
- #ifndef _NO_CRYPTO
- ecs->PasswordIsDefined = options.PasswordEnabled;
- ecs->Password = options.Password;
- #endif
-
- ecs->Init();
-
- COpenCallbackConsole openCallback;
- openCallback.OutStream = &stdStream;
-
- #ifndef _NO_CRYPTO
- openCallback.PasswordIsDefined = options.PasswordEnabled;
- openCallback.Password = options.Password;
- #endif
-
- CExtractOptions eo;
- eo.StdInMode = options.StdInMode;
- eo.StdOutMode = options.StdOutMode;
- eo.PathMode = options.Command.GetPathMode();
- eo.TestMode = options.Command.IsTestMode();
- eo.OverwriteMode = options.OverwriteMode;
- eo.OutputDir = options.OutputDir;
- eo.YesToAll = options.YesToAll;
- eo.CalcCrc = options.CalcCrc;
- #if !defined(_7ZIP_ST) && !defined(_SFX)
- eo.Properties = options.ExtractProperties;
- #endif
- UString errorMessage;
- CDecompressStat stat;
- HRESULT result = DecompressArchives(
- codecs,
- formatIndices,
- options.ArchivePathsSorted,
- options.ArchivePathsFullSorted,
- options.WildcardCensor.Pairs.Front().Head,
- eo, &openCallback, ecs, errorMessage, stat);
- if (!errorMessage.IsEmpty())
- {
- stdStream << endl << "Error: " << errorMessage;
- if (result == S_OK)
- result = E_FAIL;
- }
-
- stdStream << endl;
- if (ecs->NumArchives > 1)
- stdStream << "Archives: " << ecs->NumArchives << endl;
- if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)
- {
- if (ecs->NumArchives > 1)
- {
- stdStream << endl;
- if (ecs->NumArchiveErrors != 0)
- stdStream << "Archive Errors: " << ecs->NumArchiveErrors << endl;
- if (ecs->NumFileErrors != 0)
- stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl;
- }
- if (result != S_OK)
- throw CSystemException(result);
- return NExitCode::kFatalError;
- }
- if (result != S_OK)
- throw CSystemException(result);
- if (stat.NumFolders != 0)
- stdStream << "Folders: " << stat.NumFolders << endl;
- if (stat.NumFiles != 1 || stat.NumFolders != 0)
- stdStream << "Files: " << stat.NumFiles << endl;
- stdStream
- << "Size: " << stat.UnpackSize << endl
- << "Compressed: " << stat.PackSize << endl;
- if (options.CalcCrc)
- {
- char s[16];
- ConvertUInt32ToHexWithZeros(stat.CrcSum, s);
- stdStream << "CRC: " << s << endl;
- }
- }
- else
- {
- UInt64 numErrors = 0;
- HRESULT result = ListArchives(
- codecs,
- formatIndices,
- options.StdInMode,
- options.ArchivePathsSorted,
- options.ArchivePathsFullSorted,
- options.WildcardCensor.Pairs.Front().Head,
- options.EnableHeaders,
- options.TechMode,
- #ifndef _NO_CRYPTO
- options.PasswordEnabled,
- options.Password,
- #endif
- numErrors);
- if (numErrors > 0)
- {
- g_StdOut << endl << "Errors: " << numErrors;
- return NExitCode::kFatalError;
- }
- if (result != S_OK)
- throw CSystemException(result);
- }
- }
- else if (options.Command.IsFromUpdateGroup())
- {
- CUpdateOptions &uo = options.UpdateOptions;
- if (uo.SfxMode && uo.SfxModule.IsEmpty())
- uo.SfxModule = kDefaultSfxModule;
-
- COpenCallbackConsole openCallback;
- openCallback.OutStream = &stdStream;
-
- #ifndef _NO_CRYPTO
- bool passwordIsDefined =
- options.PasswordEnabled && !options.Password.IsEmpty();
- openCallback.PasswordIsDefined = passwordIsDefined;
- openCallback.Password = options.Password;
- #endif
-
- CUpdateCallbackConsole callback;
- callback.EnablePercents = options.EnablePercents;
-
- #ifndef _NO_CRYPTO
- callback.PasswordIsDefined = passwordIsDefined;
- callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();
- callback.Password = options.Password;
- #endif
- callback.StdOutMode = uo.StdOutMode;
- callback.Init(&stdStream);
-
- CUpdateErrorInfo errorInfo;
-
- if (!uo.Init(codecs, formatIndices, options.ArchiveName))
- throw kUnsupportedArcTypeMessage;
- HRESULT result = UpdateArchive(codecs,
- options.WildcardCensor, uo,
- errorInfo, &openCallback, &callback);
-
-#ifdef ENV_UNIX
- if (uo.SfxMode)
- {
- void myAddExeFlag(const UString &name);
- for(int i = 0; i < uo.Commands.Size(); i++)
- {
- CUpdateArchiveCommand &command = uo.Commands[i];
- if (!uo.StdOutMode)
- {
- myAddExeFlag(command.ArchivePath.GetFinalPath());
- }
- }
- }
-#endif
-
- int exitCode = NExitCode::kSuccess;
- if (callback.CantFindFiles.Size() > 0)
- {
- stdStream << endl;
- stdStream << "WARNINGS for files:" << endl << endl;
- int numErrors = callback.CantFindFiles.Size();
- for (int i = 0; i < numErrors; i++)
- {
- stdStream << callback.CantFindFiles[i] << " : ";
- stdStream << NError::MyFormatMessageW(callback.CantFindCodes[i]) << endl;
- }
- stdStream << "----------------" << endl;
- stdStream << "WARNING: Cannot find " << numErrors << " file";
- if (numErrors > 1)
- stdStream << "s";
- stdStream << endl;
- exitCode = NExitCode::kWarning;
- }
-
- if (result != S_OK)
- {
- UString message;
- if (!errorInfo.Message.IsEmpty())
- {
- message += errorInfo.Message;
- message += L"\n";
- }
- if (!errorInfo.FileName.IsEmpty())
- {
- message += errorInfo.FileName;
- message += L"\n";
- }
- if (!errorInfo.FileName2.IsEmpty())
- {
- message += errorInfo.FileName2;
- message += L"\n";
- }
- if (errorInfo.SystemError != 0)
- {
- message += NError::MyFormatMessageW(errorInfo.SystemError);
- message += L"\n";
- }
- if (!message.IsEmpty())
- stdStream << L"\nError:\n" << message;
- throw CSystemException(result);
- }
- int numErrors = callback.FailedFiles.Size();
- if (numErrors == 0)
- {
- if (callback.CantFindFiles.Size() == 0)
- stdStream << kEverythingIsOk << endl;
- }
- else
- {
- stdStream << endl;
- stdStream << "WARNINGS for files:" << endl << endl;
- for (int i = 0; i < numErrors; i++)
- {
- stdStream << callback.FailedFiles[i] << " : ";
- stdStream << NError::MyFormatMessageW(callback.FailedCodes[i]) << endl;
- }
- stdStream << "----------------" << endl;
- stdStream << "WARNING: Cannot open " << numErrors << " file";
- if (numErrors > 1)
- stdStream << "s";
- stdStream << endl;
- exitCode = NExitCode::kWarning;
- }
- return exitCode;
- }
- else
- PrintHelpAndExit(stdStream);
- return 0;
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/MainAr.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Console/MainAr.cpp
deleted file mode 100644
index 68059575b..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/MainAr.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-// MainAr.cpp
-
-#include "StdAfx.h"
-
-#include "Common/NewHandler.h" // FIXME
-
-#include "Common/MyException.h"
-#include "Common/StdOutStream.h"
-
-#include "Windows/Error.h"
-#include "Windows/NtCheck.h"
-
-#include "../Common/ArchiveCommandLine.h"
-#include "../Common/ExitCode.h"
-
-#include "ConsoleClose.h"
-
-using namespace NWindows;
-
-CStdOutStream *g_StdStream = 0;
-
-extern int Main2(
- #ifndef _WIN32
- int numArgs, const char *args[]
- #endif
-);
-
-static const char *kExceptionErrorMessage = "\n\nError:\n";
-static const char *kUserBreak = "\nBreak signaled\n";
-static const char *kMemoryExceptionMessage = "\n\nERROR: Can't allocate required memory!\n";
-static const char *kUnknownExceptionMessage = "\n\nUnknown Error\n";
-static const char *kInternalExceptionMessage = "\n\nInternal Error #";
-
-#define NT_CHECK_FAIL_ACTION (*g_StdStream) << "Unsupported Windows version"; return NExitCode::kFatalError;
-
-int MY_CDECL main
-(
- #ifndef _WIN32
- int numArgs, const char *args[]
- #endif
-)
-{
- g_StdStream = &g_StdOut;
-
- NT_CHECK
-
- NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter;
- int res = 0;
- try
- {
- res = Main2(
- #ifndef _WIN32
- numArgs, args
- #endif
- );
- }
- catch(const CNewException &)
- {
- (*g_StdStream) << kMemoryExceptionMessage;
- return (NExitCode::kMemoryError);
- }
- catch(const NConsoleClose::CCtrlBreakException &)
- {
- (*g_StdStream) << endl << kUserBreak;
- return (NExitCode::kUserBreak);
- }
- catch(const CArchiveCommandLineException &e)
- {
- (*g_StdStream) << kExceptionErrorMessage << e << endl;
- return (NExitCode::kUserError);
- }
- catch(const CSystemException &systemError)
- {
- if (systemError.ErrorCode == E_OUTOFMEMORY)
- {
- (*g_StdStream) << kMemoryExceptionMessage;
- return (NExitCode::kMemoryError);
- }
- if (systemError.ErrorCode == E_ABORT)
- {
- (*g_StdStream) << endl << kUserBreak;
- return (NExitCode::kUserBreak);
- }
- UString message;
- NError::MyFormatMessage(systemError.ErrorCode, message);
- (*g_StdStream) << endl << endl << "System error:" << endl << message << endl;
- return (NExitCode::kFatalError);
- }
- catch(NExitCode::EEnum &exitCode)
- {
- (*g_StdStream) << kInternalExceptionMessage << exitCode << endl;
- return (exitCode);
- }
- /*
- catch(const NExitCode::CMultipleErrors &multipleErrors)
- {
- (*g_StdStream) << endl << multipleErrors.NumErrors << " errors" << endl;
- return (NExitCode::kFatalError);
- }
- */
- catch(const UString &s)
- {
- (*g_StdStream) << kExceptionErrorMessage << s << endl;
- return (NExitCode::kFatalError);
- }
- catch(const AString &s)
- {
- (*g_StdStream) << kExceptionErrorMessage << s << endl;
- return (NExitCode::kFatalError);
- }
- catch(const char *s)
- {
- (*g_StdStream) << kExceptionErrorMessage << s << endl;
- return (NExitCode::kFatalError);
- }
- catch(int t)
- {
- (*g_StdStream) << kInternalExceptionMessage << t << endl;
- return (NExitCode::kFatalError);
- }
- catch(...)
- {
- (*g_StdStream) << kUnknownExceptionMessage;
- return (NExitCode::kFatalError);
- }
- return res;
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
deleted file mode 100644
index 7dba2ad5d..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-// OpenCallbackConsole.cpp
-
-#include "StdAfx.h"
-
-#include "OpenCallbackConsole.h"
-
-#include "ConsoleClose.h"
-#include "UserInputUtils.h"
-
-HRESULT COpenCallbackConsole::Open_CheckBreak()
-{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- return S_OK;
-}
-
-HRESULT COpenCallbackConsole::Open_SetTotal(const UInt64 *, const UInt64 *)
-{
- return Open_CheckBreak();
-}
-
-HRESULT COpenCallbackConsole::Open_SetCompleted(const UInt64 *, const UInt64 *)
-{
- return Open_CheckBreak();
-}
-
-#ifndef _NO_CRYPTO
-
-HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password)
-{
- PasswordWasAsked = true;
- RINOK(Open_CheckBreak());
- if (!PasswordIsDefined)
- {
- Password = GetPassword(OutStream);
- PasswordIsDefined = true;
- }
- return StringToBstr(Password, password);
-}
-
-HRESULT COpenCallbackConsole::Open_GetPasswordIfAny(UString &password)
-{
- if (PasswordIsDefined)
- password = Password;
- return S_OK;
-}
-
-bool COpenCallbackConsole::Open_WasPasswordAsked()
-{
- return PasswordWasAsked;
-}
-
-void COpenCallbackConsole::Open_ClearPasswordWasAskedFlag()
-{
- PasswordWasAsked = false;
-}
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/OpenCallbackConsole.h b/src/libs/7zip/unix/CPP/7zip/UI/Console/OpenCallbackConsole.h
deleted file mode 100644
index c002e6a72..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/OpenCallbackConsole.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// OpenCallbackConsole.h
-
-#ifndef __OPENCALLBACKCONSOLE_H
-#define __OPENCALLBACKCONSOLE_H
-
-#include "Common/StdOutStream.h"
-#include "../Common/ArchiveOpenCallback.h"
-
-class COpenCallbackConsole: public IOpenCallbackUI
-{
-public:
- INTERFACE_IOpenCallbackUI(;)
-
- CStdOutStream *OutStream;
-
- #ifndef _NO_CRYPTO
- bool PasswordIsDefined;
- bool PasswordWasAsked;
- UString Password;
- COpenCallbackConsole(): PasswordIsDefined(false), PasswordWasAsked(false) {}
- #endif
-};
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/PercentPrinter.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Console/PercentPrinter.cpp
index 28452b177..f2889957a 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/PercentPrinter.cpp
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Console/PercentPrinter.cpp
@@ -2,18 +2,18 @@
#include "StdAfx.h"
-#include "Common/IntToString.h"
-#include "Common/MyString.h"
+#include "../../../Common/Defs.h"
+#include "../../../Common/IntToString.h"
#include "PercentPrinter.h"
-const int kPaddingSize = 2;
-const int kPercentsSize = 4;
-const int kMaxExtraSize = kPaddingSize + 32 + kPercentsSize;
+static const unsigned kPaddingSize = 2;
+static const unsigned kPercentsSize = 4;
+static const unsigned kMaxExtraSize = kPaddingSize + 32 + kPercentsSize;
-static void ClearPrev(char *p, int num)
+static void ClearPrev(char *p, unsigned num)
{
- int i;
+ unsigned i;
for (i = 0; i < num; i++) *p++ = '\b';
for (i = 0; i < num; i++) *p++ = ' ';
for (i = 0; i < num; i++) *p++ = '\b';
@@ -51,18 +51,30 @@ void CPercentPrinter::PrintNewLine()
void CPercentPrinter::RePrintRatio()
{
char s[32];
- ConvertUInt64ToString(((m_Total == 0) ? 0 : (m_CurValue * 100 / m_Total)), s);
- int size = (int)strlen(s);
- s[size++] = '%';
- s[size] = '\0';
+ unsigned size;
+ {
+ char c = '%';
+ UInt64 value = 0;
+ if (m_Total == (UInt64)(Int64)-1)
+ {
+ value = m_CurValue >> 20;
+ c = 'M';
+ }
+ else if (m_Total != 0)
+ value = m_CurValue * 100 / m_Total;
+ ConvertUInt64ToString(value, s);
+ size = (unsigned)strlen(s);
+ s[size++] = c;
+ s[size] = '\0';
+ }
- int extraSize = kPaddingSize + MyMax(size, kPercentsSize);
+ unsigned extraSize = kPaddingSize + MyMax(size, kPercentsSize);
if (extraSize < m_NumExtraChars)
extraSize = m_NumExtraChars;
char fullString[kMaxExtraSize * 3];
char *p = fullString;
- int i;
+ unsigned i;
if (m_NumExtraChars == 0)
{
for (i = 0; i < extraSize; i++)
@@ -73,7 +85,7 @@ void CPercentPrinter::RePrintRatio()
for (i = 0; i < m_NumExtraChars; i++)
*p++ = '\b';
m_NumExtraChars = extraSize;
- for (; size < m_NumExtraChars; size++)
+ for (; size < extraSize; size++)
*p++ = ' ';
MyStringCopy(p, s);
(*OutStream) << fullString;
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/PercentPrinter.h b/src/libs/7zip/unix/CPP/7zip/UI/Console/PercentPrinter.h
index 97f2e6adb..509bab5fc 100644
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/PercentPrinter.h
+++ b/src/libs/7zip/unix/CPP/7zip/UI/Console/PercentPrinter.h
@@ -1,10 +1,9 @@
// PercentPrinter.h
-#ifndef __PERCENTPRINTER_H
-#define __PERCENTPRINTER_H
+#ifndef __PERCENT_PRINTER_H
+#define __PERCENT_PRINTER_H
-#include "Common/Types.h"
-#include "Common/StdOutStream.h"
+#include "../../../Common/StdOutStream.h"
class CPercentPrinter
{
@@ -12,12 +11,12 @@ class CPercentPrinter
UInt64 m_PrevValue;
UInt64 m_CurValue;
UInt64 m_Total;
- int m_NumExtraChars;
+ unsigned m_NumExtraChars;
public:
CStdOutStream *OutStream;
CPercentPrinter(UInt64 minStepSize = 1): m_MinStepSize(minStepSize),
- m_PrevValue(0), m_CurValue(0), m_Total(1), m_NumExtraChars(0) {}
+ m_PrevValue(0), m_CurValue(0), m_Total((UInt64)(Int64)-1), m_NumExtraChars(0) {}
void SetTotal(UInt64 total) { m_Total = total; m_PrevValue = 0; }
void SetRatio(UInt64 doneValue) { m_CurValue = doneValue; }
void PrintString(const char *s);
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
deleted file mode 100644
index e0eb4dec7..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-// UpdateCallbackConsole.cpp
-
-#include "StdAfx.h"
-
-#include "UpdateCallbackConsole.h"
-
-#include "Windows/Error.h"
-#ifndef _7ZIP_ST
-#include "Windows/Synchronization.h"
-#endif
-
-#include "ConsoleClose.h"
-#include "UserInputUtils.h"
-
-using namespace NWindows;
-
-#ifndef _7ZIP_ST
-static NSynchronization::CCriticalSection g_CriticalSection;
-#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
-#else
-#define MT_LOCK
-#endif
-
-static const wchar_t *kEmptyFileAlias = L"[Content]";
-
-static const char *kCreatingArchiveMessage = "Creating archive ";
-static const char *kUpdatingArchiveMessage = "Updating archive ";
-static const char *kScanningMessage = "Scanning";
-
-
-HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result)
-{
- (*OutStream) << endl;
- if (result != S_OK)
- (*OutStream) << "Error: " << name << " is not supported archive" << endl;
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::StartScanning()
-{
- (*OutStream) << kScanningMessage;
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::ScanProgress(UInt64 /* numFolders */, UInt64 /* numFiles */, const wchar_t * /* path */)
-{
- return CheckBreak();
-}
-
-HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError)
-{
- CantFindFiles.Add(name);
- CantFindCodes.Add(systemError);
- // m_PercentPrinter.ClosePrint();
- if (!m_WarningsMode)
- {
- (*OutStream) << endl << endl;
- m_PercentPrinter.PrintNewLine();
- m_WarningsMode = true;
- }
- m_PercentPrinter.PrintString(name);
- m_PercentPrinter.PrintString(": WARNING: ");
- m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
- m_PercentPrinter.PrintNewLine();
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::FinishScanning()
-{
- (*OutStream) << endl << endl;
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating)
-{
- if(updating)
- (*OutStream) << kUpdatingArchiveMessage;
- else
- (*OutStream) << kCreatingArchiveMessage;
- if (name != 0)
- (*OutStream) << name;
- else
- (*OutStream) << "StdOut";
- (*OutStream) << endl << endl;
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::FinishArchive()
-{
- (*OutStream) << endl;
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::CheckBreak()
-{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::Finilize()
-{
- MT_LOCK
- if (m_NeedBeClosed)
- {
- if (EnablePercents)
- {
- m_PercentPrinter.ClosePrint();
- }
- if (!StdOutMode && m_NeedNewLine)
- {
- m_PercentPrinter.PrintNewLine();
- m_NeedNewLine = false;
- }
- m_NeedBeClosed = false;
- }
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::SetNumFiles(UInt64 /* numFiles */)
-{
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size)
-{
- MT_LOCK
- if (EnablePercents)
- m_PercentPrinter.SetTotal(size);
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue)
-{
- MT_LOCK
- if (completeValue != NULL)
- {
- if (EnablePercents)
- {
- m_PercentPrinter.SetRatio(*completeValue);
- m_PercentPrinter.PrintRatio();
- m_NeedBeClosed = true;
- }
- }
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 * /* outSize */)
-{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti)
-{
- MT_LOCK
- if (StdOutMode)
- return S_OK;
- if(isAnti)
- m_PercentPrinter.PrintString("Anti item ");
- else
- m_PercentPrinter.PrintString("Compressing ");
- if (name[0] == 0)
- name = kEmptyFileAlias;
- m_PercentPrinter.PrintString(name);
- if (EnablePercents)
- m_PercentPrinter.RePrintRatio();
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError)
-{
- MT_LOCK
- FailedCodes.Add(systemError);
- FailedFiles.Add(name);
- // if (systemError == ERROR_SHARING_VIOLATION)
- {
- m_PercentPrinter.ClosePrint();
- m_PercentPrinter.PrintNewLine();
- m_PercentPrinter.PrintString("WARNING: ");
- m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
- return S_FALSE;
- }
- // return systemError;
-}
-
-HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 )
-{
- m_NeedBeClosed = true;
- m_NeedNewLine = true;
- return S_OK;
-}
-
-HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
-{
- *password = NULL;
-
- #ifdef _NO_CRYPTO
-
- *passwordIsDefined = false;
- return S_OK;
-
- #else
-
- if (!PasswordIsDefined)
- {
- if (AskPassword)
- {
- Password = GetPassword(OutStream,true);
- PasswordIsDefined = true;
- }
- }
- *passwordIsDefined = BoolToInt(PasswordIsDefined);
- return StringToBstr(Password, password);
-
- #endif
-}
-
-HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password)
-{
- *password = NULL;
-
- #ifdef _NO_CRYPTO
-
- return E_NOTIMPL;
-
- #else
-
- if (!PasswordIsDefined)
- {
- {
- Password = GetPassword(OutStream);
- PasswordIsDefined = true;
- }
- }
- return StringToBstr(Password, password);
-
- #endif
-}
-
-/*
-HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name)
-{
- // MT_LOCK
- if (StdOutMode)
- return S_OK;
- RINOK(Finilize());
- m_PercentPrinter.PrintString("Deleting ");
- if (name[0] == 0)
- name = kEmptyFileAlias;
- m_PercentPrinter.PrintString(name);
- if (EnablePercents)
- m_PercentPrinter.RePrintRatio();
- m_NeedBeClosed = true;
- m_NeedNewLine = true;
- return S_OK;
-}
-*/
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/UpdateCallbackConsole.h b/src/libs/7zip/unix/CPP/7zip/UI/Console/UpdateCallbackConsole.h
deleted file mode 100644
index 5ffe3eb7a..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/UpdateCallbackConsole.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// UpdateCallbackConsole.h
-
-#ifndef __UPDATE_CALLBACK_CONSOLE_H
-#define __UPDATE_CALLBACK_CONSOLE_H
-
-#include "Common/StdOutStream.h"
-
-#include "../Common/Update.h"
-
-#include "PercentPrinter.h"
-
-class CUpdateCallbackConsole: public IUpdateCallbackUI2
-{
- CPercentPrinter m_PercentPrinter;
- bool m_NeedBeClosed;
- bool m_NeedNewLine;
-
- bool m_WarningsMode;
-
- CStdOutStream *OutStream;
-public:
- bool EnablePercents;
- bool StdOutMode;
-
- #ifndef _NO_CRYPTO
- bool PasswordIsDefined;
- UString Password;
- bool AskPassword;
- #endif
-
- CUpdateCallbackConsole():
- m_PercentPrinter(1 << 16),
- #ifndef _NO_CRYPTO
- PasswordIsDefined(false),
- AskPassword(false),
- #endif
- StdOutMode(false),
- EnablePercents(true),
- m_WarningsMode(false)
- {}
-
- ~CUpdateCallbackConsole() { Finilize(); }
- void Init(CStdOutStream *outStream)
- {
- m_NeedBeClosed = false;
- m_NeedNewLine = false;
- FailedFiles.Clear();
- FailedCodes.Clear();
- OutStream = outStream;
- m_PercentPrinter.OutStream = outStream;
- }
-
- INTERFACE_IUpdateCallbackUI2(;)
-
- UStringVector FailedFiles;
- CRecordVector<HRESULT> FailedCodes;
-
- UStringVector CantFindFiles;
- CRecordVector<HRESULT> CantFindCodes;
-};
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/UserInputUtils.cpp b/src/libs/7zip/unix/CPP/7zip/UI/Console/UserInputUtils.cpp
deleted file mode 100644
index 4733e4ffb..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/UserInputUtils.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-// UserInputUtils.cpp
-
-#include "StdAfx.h"
-
-#include "Common/StdInStream.h"
-#include "Common/StringConvert.h"
-
-#include "UserInputUtils.h"
-
-#ifdef USE_FLTK
-// the programs like file-roller or xarchiver do not support archives with password
-// these programs freeze because p7zip is waiting for a password
-// defining USE_FLTK allows p7zip to use a popup in order to ask the password.
-#include <FL/Fl.H>
-#include <FL/Fl_Window.H>
-#include <FL/fl_ask.H>
-#else
-#ifdef ENV_HAVE_GETPASS
-#include <pwd.h>
-#include <unistd.h>
-#include "Common/MyException.h"
-#endif
-#endif
-
-static const char kYes = 'Y';
-static const char kNo = 'N';
-static const char kYesAll = 'A';
-static const char kNoAll = 'S';
-static const char kAutoRenameAll = 'U';
-static const char kQuit = 'Q';
-
-static const char *kFirstQuestionMessage = "?\n";
-static const char *kHelpQuestionMessage =
- "(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? ";
-
-// return true if pressed Quite;
-
-NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
-{
- (*outStream) << kFirstQuestionMessage;
- for (;;)
- {
- (*outStream) << kHelpQuestionMessage;
- outStream->Flush();
- AString scannedString = g_StdIn.ScanStringUntilNewLine();
- scannedString.Trim();
- if (!scannedString.IsEmpty())
- switch(
- ::MyCharUpper(
- #ifdef UNDER_CE
- (wchar_t)
- #endif
- scannedString[0]))
- {
- case kYes:
- return NUserAnswerMode::kYes;
- case kNo:
- return NUserAnswerMode::kNo;
- case kYesAll:
- return NUserAnswerMode::kYesAll;
- case kNoAll:
- return NUserAnswerMode::kNoAll;
- case kAutoRenameAll:
- return NUserAnswerMode::kAutoRenameAll;
- case kQuit:
- return NUserAnswerMode::kQuit;
- }
- }
-}
-
-UString GetPassword(CStdOutStream *outStream,bool verify)
-{
-#ifdef USE_FLTK
- const char *r = fl_password("Enter password", 0);
- AString oemPassword = "";
- if (r) oemPassword = r;
-#else /* USE_FLTK */
-#ifdef ENV_HAVE_GETPASS
- (*outStream) << "\nEnter password (will not be echoed) :";
- outStream->Flush();
- AString oemPassword = getpass("");
- if (verify)
- {
- (*outStream) << "Verify password (will not be echoed) :";
- outStream->Flush();
- AString oemPassword2 = getpass("");
- if (oemPassword != oemPassword2) throw "password verification failed";
- }
-#else
- (*outStream) << "\nEnter password:";
- outStream->Flush();
- AString oemPassword = g_StdIn.ScanStringUntilNewLine();
-#endif
-#endif /* USE_FLTK */
- return MultiByteToUnicodeString(oemPassword, CP_OEMCP);
-}
diff --git a/src/libs/7zip/unix/CPP/7zip/UI/Console/UserInputUtils.h b/src/libs/7zip/unix/CPP/7zip/UI/Console/UserInputUtils.h
deleted file mode 100644
index 8c575194d..000000000
--- a/src/libs/7zip/unix/CPP/7zip/UI/Console/UserInputUtils.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// UserInputUtils.h
-
-#ifndef __USERINPUTUTILS_H
-#define __USERINPUTUTILS_H
-
-#include "Common/StdOutStream.h"
-
-namespace NUserAnswerMode {
-
-enum EEnum
-{
- kYes,
- kNo,
- kYesAll,
- kNoAll,
- kAutoRenameAll,
- kQuit
-};
-}
-
-NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream);
-UString GetPassword(CStdOutStream *outStream,bool verify = false);
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/Common/AutoPtr.h b/src/libs/7zip/unix/CPP/Common/AutoPtr.h
deleted file mode 100644
index 006d31551..000000000
--- a/src/libs/7zip/unix/CPP/Common/AutoPtr.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Common/AutoPtr.h
-
-#ifndef __COMMON_AUTOPTR_H
-#define __COMMON_AUTOPTR_H
-
-template<class T> class CMyAutoPtr
-{
- T *_p;
-public:
- CMyAutoPtr(T *p = 0) : _p(p) {}
- CMyAutoPtr(CMyAutoPtr<T>& p): _p(p.release()) {}
- CMyAutoPtr<T>& operator=(CMyAutoPtr<T>& p)
- {
- reset(p.release());
- return (*this);
- }
- ~CMyAutoPtr() { delete _p; }
- T& operator*() const { return *_p; }
- // T* operator->() const { return (&**this); }
- T* get() const { return _p; }
- T* release()
- {
- T *tmp = _p;
- _p = 0;
- return tmp;
- }
- void reset(T* p = 0)
- {
- if (p != _p)
- delete _p;
- _p = p;
- }
-};
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/Common/Buffer.h b/src/libs/7zip/unix/CPP/Common/Buffer.h
deleted file mode 100644
index 118fe11fc..000000000
--- a/src/libs/7zip/unix/CPP/Common/Buffer.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Common/Buffer.h
-
-#ifndef __COMMON_BUFFER_H
-#define __COMMON_BUFFER_H
-
-#include "Defs.h"
-
-template <class T> class CBuffer
-{
-protected:
- size_t _capacity;
- T *_items;
-public:
- void Free()
- {
- delete []_items;
- _items = 0;
- _capacity = 0;
- }
- CBuffer(): _capacity(0), _items(0) {};
- CBuffer(const CBuffer &buffer): _capacity(0), _items(0) { *this = buffer; }
- CBuffer(size_t size): _items(0), _capacity(0) { SetCapacity(size); }
- virtual ~CBuffer() { delete []_items; }
- operator T *() { return _items; };
- operator const T *() const { return _items; };
- size_t GetCapacity() const { return _capacity; }
- void SetCapacity(size_t newCapacity)
- {
- if (newCapacity == _capacity)
- return;
- T *newBuffer;
- if (newCapacity > 0)
- {
- newBuffer = new T[newCapacity];
- if (_capacity > 0)
- memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T));
- }
- else
- newBuffer = 0;
- delete []_items;
- _items = newBuffer;
- _capacity = newCapacity;
- }
- CBuffer& operator=(const CBuffer &buffer)
- {
- Free();
- if (buffer._capacity > 0)
- {
- SetCapacity(buffer._capacity);
- memmove(_items, buffer._items, buffer._capacity * sizeof(T));
- }
- return *this;
- }
-};
-
-template <class T>
-bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)
-{
- if (b1.GetCapacity() != b2.GetCapacity())
- return false;
- for (size_t i = 0; i < b1.GetCapacity(); i++)
- if (b1[i] != b2[i])
- return false;
- return true;
-}
-
-template <class T>
-bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
-{
- return !(b1 == b2);
-}
-
-typedef CBuffer<char> CCharBuffer;
-typedef CBuffer<wchar_t> CWCharBuffer;
-typedef CBuffer<unsigned char> CByteBuffer;
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/Common/CRC.cpp b/src/libs/7zip/unix/CPP/Common/CRC.cpp
deleted file mode 100644
index 9a9f81fb7..000000000
--- a/src/libs/7zip/unix/CPP/Common/CRC.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-// Common/CRC.cpp
-
-#include "StdAfx.h"
-
-#include "../../C/7zCrc.h"
-
-struct CCRCTableInit { CCRCTableInit() { CrcGenerateTable(); } } g_CRCTableInit;
diff --git a/src/libs/7zip/unix/CPP/Common/C_FileIO.cpp b/src/libs/7zip/unix/CPP/Common/C_FileIO.cpp
deleted file mode 100644
index b4893d658..000000000
--- a/src/libs/7zip/unix/CPP/Common/C_FileIO.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-// Common/C_FileIO.h
-
-#include "C_FileIO.h"
-
-#include <fcntl.h>
-#include <unistd.h>
-
-namespace NC {
-namespace NFile {
-namespace NIO {
-
-bool CFileBase::OpenBinary(const char *name, int flags)
-{
- #ifdef O_BINARY
- flags |= O_BINARY;
- #endif
- Close();
- _handle = ::open(name, flags, 0666);
- return _handle != -1;
-}
-
-bool CFileBase::Close()
-{
- if (_handle == -1)
- return true;
- if (close(_handle) != 0)
- return false;
- _handle = -1;
- return true;
-}
-
-bool CFileBase::GetLength(UInt64 &length) const
-{
- off_t curPos = Seek(0, SEEK_CUR);
- off_t lengthTemp = Seek(0, SEEK_END);
- Seek(curPos, SEEK_SET);
- length = (UInt64)lengthTemp;
- return true;
-}
-
-off_t CFileBase::Seek(off_t distanceToMove, int moveMethod) const
-{
- return ::lseek(_handle, distanceToMove, moveMethod);
-}
-
-/////////////////////////
-// CInFile
-
-bool CInFile::Open(const char *name)
-{
- return CFileBase::OpenBinary(name, O_RDONLY);
-}
-
-bool CInFile::OpenShared(const char *name, bool)
-{
- return Open(name);
-}
-
-ssize_t CInFile::Read(void *data, size_t size)
-{
- return read(_handle, data, size);
-}
-
-/////////////////////////
-// COutFile
-
-bool COutFile::Create(const char *name, bool createAlways)
-{
- if (createAlways)
- {
- Close();
- _handle = ::creat(name, 0666);
- return _handle != -1;
- }
- return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY);
-}
-
-bool COutFile::Open(const char *name, DWORD creationDisposition)
-{
- return Create(name, false);
-}
-
-ssize_t COutFile::Write(const void *data, size_t size)
-{
- return write(_handle, data, size);
-}
-
-}}}
diff --git a/src/libs/7zip/unix/CPP/Common/C_FileIO.h b/src/libs/7zip/unix/CPP/Common/C_FileIO.h
deleted file mode 100644
index 27aa56869..000000000
--- a/src/libs/7zip/unix/CPP/Common/C_FileIO.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Common/C_FileIO.h
-
-#ifndef __COMMON_C_FILEIO_H
-#define __COMMON_C_FILEIO_H
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "Types.h"
-#include "MyWindows.h"
-
-namespace NC {
-namespace NFile {
-namespace NIO {
-
-class CFileBase
-{
-protected:
- int _handle;
- bool OpenBinary(const char *name, int flags);
-public:
- CFileBase(): _handle(-1) {};
- ~CFileBase() { Close(); }
- bool Close();
- bool GetLength(UInt64 &length) const;
- off_t Seek(off_t distanceToMove, int moveMethod) const;
-};
-
-class CInFile: public CFileBase
-{
-public:
- bool Open(const char *name);
- bool OpenShared(const char *name, bool shareForWrite);
- ssize_t Read(void *data, size_t size);
-};
-
-class COutFile: public CFileBase
-{
-public:
- bool Create(const char *name, bool createAlways);
- bool Open(const char *name, DWORD creationDisposition);
- ssize_t Write(const void *data, size_t size);
-};
-
-}}}
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/Common/ComTry.h b/src/libs/7zip/unix/CPP/Common/ComTry.h
index 1f20e5d93..04bfe6320 100644
--- a/src/libs/7zip/unix/CPP/Common/ComTry.h
+++ b/src/libs/7zip/unix/CPP/Common/ComTry.h
@@ -10,7 +10,7 @@
#define COM_TRY_BEGIN try {
#define COM_TRY_END } catch(const char * s) { throw s ; } \
catch(...) { return E_OUTOFMEMORY; }
-
+
// catch(const CNewException &) { return E_OUTOFMEMORY; }
// catch(const CSystemException &e) { return e.ErrorCode; }
// catch(...) { return E_FAIL; }
diff --git a/src/libs/7zip/unix/CPP/Common/CommandLineParser.cpp b/src/libs/7zip/unix/CPP/Common/CommandLineParser.cpp
index 91fecc7af..749c4a2ea 100644
--- a/src/libs/7zip/unix/CPP/Common/CommandLineParser.cpp
+++ b/src/libs/7zip/unix/CPP/Common/CommandLineParser.cpp
@@ -4,6 +4,20 @@
#include "CommandLineParser.h"
+static bool IsString1PrefixedByString2_NoCase(const wchar_t *u, const char *a)
+{
+ for (;;)
+ {
+ char c = *a;
+ if (c == 0)
+ return true;
+ if (MyCharLower_Ascii(c) != MyCharLower_Ascii(*u))
+ return false;
+ a++;
+ u++;
+ }
+}
+
namespace NCommandLineParser {
#ifdef _WIN32
@@ -12,13 +26,13 @@ bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
dest1.Empty();
dest2.Empty();
bool quoteMode = false;
- int i;
- for (i = 0; i < src.Length(); i++)
+ unsigned i;
+ for (i = 0; i < src.Len(); i++)
{
wchar_t c = src[i];
- if (c == L' ' && !quoteMode)
+ if ((c == L' ' || c == L'\t') && !quoteMode)
{
- dest2 = src.Mid(i + 1);
+ dest2 = src.Ptr(i + 1);
return i != 0;
}
if (c == L'\"')
@@ -46,21 +60,18 @@ void SplitCommandLine(const UString &s, UStringVector &parts)
}
#endif
-static const wchar_t kSwitchID1 = '-';
-// static const wchar_t kSwitchID2 = '/';
-
-static const wchar_t kSwitchMinus = '-';
-static const wchar_t *kStopSwitchParsing = L"--";
+static const char *kStopSwitchParsing = "--";
-static bool IsItSwitchChar(wchar_t c)
+static bool inline IsItSwitchChar(wchar_t c)
{
- return (c == kSwitchID1 /*|| c == kSwitchID2 */);
+ return (c == '-');
}
-CParser::CParser(int numSwitches):
- _numSwitches(numSwitches)
+CParser::CParser(unsigned numSwitches):
+ _numSwitches(numSwitches),
+ _switches(0)
{
- _switches = new CSwitchResult[_numSwitches];
+ _switches = new CSwitchResult[numSwitches];
}
CParser::~CParser()
@@ -68,163 +79,121 @@ CParser::~CParser()
delete []_switches;
}
-void CParser::ParseStrings(const CSwitchForm *switchForms,
- const UStringVector &commandStrings)
+
+// if (s) contains switch then function updates switch structures
+// out: true, if (s) is a switch
+bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
{
- int numCommandStrings = commandStrings.Size();
- bool stopSwitch = false;
- for (int i = 0; i < numCommandStrings; i++)
+ if (s.IsEmpty() || !IsItSwitchChar(s[0]))
+ return false;
+
+ unsigned pos = 1;
+ unsigned switchIndex = 0;
+ int maxLen = -1;
+
+ for (unsigned i = 0; i < _numSwitches; i++)
{
- const UString &s = commandStrings[i];
- if (stopSwitch)
- NonSwitchStrings.Add(s);
- else
- if (s == kStopSwitchParsing)
- stopSwitch = true;
- else
- if (!ParseString(s, switchForms))
- NonSwitchStrings.Add(s);
+ const char *key = switchForms[i].Key;
+ unsigned switchLen = MyStringLen(key);
+ if ((int)switchLen <= maxLen || pos + switchLen > s.Len())
+ continue;
+ if (IsString1PrefixedByString2_NoCase((const wchar_t *)s + pos, key))
+ {
+ switchIndex = i;
+ maxLen = switchLen;
+ }
}
-}
-// if string contains switch then function updates switch structures
-// out: (string is a switch)
-bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
-{
- int len = s.Length();
- if (len == 0)
+ if (maxLen < 0)
+ {
+ ErrorMessage = "Unknown switch:";
return false;
- int pos = 0;
- if (!IsItSwitchChar(s[pos]))
+ }
+
+ pos += maxLen;
+
+ CSwitchResult &sw = _switches[switchIndex];
+ const CSwitchForm &form = switchForms[switchIndex];
+
+ if (!form.Multi && sw.ThereIs)
+ {
+ ErrorMessage = "Multiple instances for switch:";
return false;
- while (pos < len)
+ }
+
+ sw.ThereIs = true;
+
+ int rem = s.Len() - pos;
+ if (rem < form.MinLen)
{
- if (IsItSwitchChar(s[pos]))
- pos++;
- const int kNoLen = -1;
- int matchedSwitchIndex = 0; // GCC Warning
- int maxLen = kNoLen;
- for (int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)
- {
- int switchLen = MyStringLen(switchForms[switchIndex].IDString);
- if (switchLen <= maxLen || pos + switchLen > len)
- continue;
+ ErrorMessage = "Too short switch:";
+ return false;
+ }
+
+ sw.WithMinus = false;
+ sw.PostCharIndex = -1;
- UString temp = s + pos;
- temp = temp.Left(switchLen);
- if (temp.CompareNoCase(switchForms[switchIndex].IDString) == 0)
- // if (_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0)
+ switch (form.Type)
+ {
+ case NSwitchType::kMinus:
+ if (rem != 0)
{
- matchedSwitchIndex = switchIndex;
- maxLen = switchLen;
+ sw.WithMinus = (s[pos] == '-');
+ if (sw.WithMinus)
+ pos++;
}
- }
- if (maxLen == kNoLen)
- throw "maxLen == kNoLen";
- CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];
- const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];
- if ((!switchForm.Multi) && matchedSwitch.ThereIs)
- throw "switch must be single";
- matchedSwitch.ThereIs = true;
- pos += maxLen;
- int tailSize = len - pos;
- NSwitchType::EEnum type = switchForm.Type;
- switch(type)
- {
- case NSwitchType::kPostMinus:
- {
- if (tailSize == 0)
- matchedSwitch.WithMinus = false;
- else
- {
- matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);
- if (matchedSwitch.WithMinus)
- pos++;
- }
- break;
- }
- case NSwitchType::kPostChar:
- {
- if (tailSize < switchForm.MinLen)
- throw "switch is not full";
- UString set = switchForm.PostCharSet;
- const int kEmptyCharValue = -1;
- if (tailSize == 0)
- matchedSwitch.PostCharIndex = kEmptyCharValue;
- else
- {
- int index = set.Find(s[pos]);
- if (index < 0)
- matchedSwitch.PostCharIndex = kEmptyCharValue;
- else
- {
- matchedSwitch.PostCharIndex = index;
- pos++;
- }
- }
- break;
- }
- case NSwitchType::kLimitedPostString:
- case NSwitchType::kUnLimitedPostString:
+ break;
+
+ case NSwitchType::kChar:
+ if (rem != 0)
+ {
+ wchar_t c = s[pos];
+ if (c <= 0x7F)
{
- int minLen = switchForm.MinLen;
- if (tailSize < minLen)
- throw "switch is not full";
- if (type == NSwitchType::kUnLimitedPostString)
- {
- matchedSwitch.PostStrings.Add(s.Mid(pos));
- return true;
- }
- int maxLen = switchForm.MaxLen;
- UString stringSwitch = s.Mid(pos, minLen);
- pos += minLen;
- for (int i = minLen; i < maxLen && pos < len; i++, pos++)
- {
- wchar_t c = s[pos];
- if (IsItSwitchChar(c))
- break;
- stringSwitch += c;
- }
- matchedSwitch.PostStrings.Add(stringSwitch);
- break;
+ sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c);
+ if (sw.PostCharIndex >= 0)
+ pos++;
}
- case NSwitchType::kSimple:
- break;
- }
+ }
+ break;
+
+ case NSwitchType::kString:
+ sw.PostStrings.Add((const wchar_t *)s + pos);
+ return true;
+ }
+ if (pos != s.Len())
+ {
+ ErrorMessage = "Too long switch:";
+ return false;
}
return true;
}
-const CSwitchResult& CParser::operator[](size_t index) const
-{
- return _switches[index];
-}
-
-/////////////////////////////////
-// Command parsing procedures
-
-int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
- const UString &commandString, UString &postString)
+bool CParser::ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings)
{
- for (int i = 0; i < numCommandForms; i++)
+ ErrorLine.Empty();
+ bool stopSwitch = false;
+ FOR_VECTOR (i, commandStrings)
{
- const UString id = commandForms[i].IDString;
- if (commandForms[i].PostStringMode)
+ const UString &s = commandStrings[i];
+ if (!stopSwitch)
{
- if (commandString.Find(id) == 0)
+ if (s.IsEqualTo(kStopSwitchParsing))
{
- postString = commandString.Mid(id.Length());
- return i;
+ stopSwitch = true;
+ continue;
}
- }
- else
- if (commandString == id)
+ if (!s.IsEmpty() && IsItSwitchChar(s[0]))
{
- postString.Empty();
- return i;
+ if (ParseString(s, switchForms))
+ continue;
+ ErrorLine = s;
+ return false;
}
+ }
+ NonSwitchStrings.Add(s);
}
- return -1;
+ return true;
}
-
+
}
diff --git a/src/libs/7zip/unix/CPP/Common/CommandLineParser.h b/src/libs/7zip/unix/CPP/Common/CommandLineParser.h
index 3d0b41dd4..e3e6e6b14 100644
--- a/src/libs/7zip/unix/CPP/Common/CommandLineParser.h
+++ b/src/libs/7zip/unix/CPP/Common/CommandLineParser.h
@@ -10,63 +10,54 @@ namespace NCommandLineParser {
bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2);
void SplitCommandLine(const UString &s, UStringVector &parts);
-namespace NSwitchType {
+namespace NSwitchType
+{
enum EEnum
{
kSimple,
- kPostMinus,
- kLimitedPostString,
- kUnLimitedPostString,
- kPostChar
+ kMinus,
+ kString,
+ kChar
};
}
struct CSwitchForm
{
- const wchar_t *IDString;
- NSwitchType::EEnum Type;
+ const char *Key;
+ Byte Type;
bool Multi;
- int MinLen;
- int MaxLen;
- const wchar_t *PostCharSet;
+ Byte MinLen;
+ // int MaxLen;
+ const char *PostCharSet;
};
struct CSwitchResult
{
bool ThereIs;
bool WithMinus;
- UStringVector PostStrings;
int PostCharIndex;
+ UStringVector PostStrings;
+
CSwitchResult(): ThereIs(false) {};
};
-
+
class CParser
{
- int _numSwitches;
+ unsigned _numSwitches;
CSwitchResult *_switches;
+
bool ParseString(const UString &s, const CSwitchForm *switchForms);
public:
UStringVector NonSwitchStrings;
- CParser(int numSwitches);
- ~CParser();
- void ParseStrings(const CSwitchForm *switchForms,
- const UStringVector &commandStrings);
- const CSwitchResult& operator[](size_t index) const;
-};
-
-/////////////////////////////////
-// Command parsing procedures
+ AString ErrorMessage;
+ UString ErrorLine;
-struct CCommandForm
-{
- const wchar_t *IDString;
- bool PostStringMode;
+ CParser(unsigned numSwitches);
+ ~CParser();
+ bool ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings);
+ const CSwitchResult& operator[](size_t index) const { return _switches[index]; }
};
-// Returns: Index of form and postString; -1, if there is no match
-int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
- const UString &commandString, UString &postString);
-
}
#endif
diff --git a/src/libs/7zip/unix/CPP/Common/Common.h b/src/libs/7zip/unix/CPP/Common/Common.h
new file mode 100644
index 000000000..9dd30f4be
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/Common/Common.h
@@ -0,0 +1,13 @@
+// Common.h
+
+#ifndef __COMMON_COMMON_H
+#define __COMMON_COMMON_H
+
+#include "../../C/Compiler.h"
+
+#include "MyWindows.h"
+#include "NewHandler.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[1]))
+
+#endif
diff --git a/src/libs/7zip/unix/CPP/Common/Common.pri b/src/libs/7zip/unix/CPP/Common/Common.pri
new file mode 100644
index 000000000..eec23a144
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/Common/Common.pri
@@ -0,0 +1,34 @@
+HEADERS += $$7ZIP_BASE/CPP/Common/CommandLineParser.h \
+ $$7ZIP_BASE/CPP/Common/ComTry.h \
+ $$7ZIP_BASE/CPP/Common/Common.h \
+ $$7ZIP_BASE/CPP/Common/Defs.h \
+ $$7ZIP_BASE/CPP/Common/IntToString.h \
+ $$7ZIP_BASE/CPP/Common/ListFileUtils.h \
+ $$7ZIP_BASE/CPP/Common/MyBuffer.h \
+ $$7ZIP_BASE/CPP/Common/MyCom.h \
+ $$7ZIP_BASE/CPP/Common/MyException.h \
+ $$7ZIP_BASE/CPP/Common/MyGuidDef.h \
+ $$7ZIP_BASE/CPP/Common/MyInitGuid.h \
+ $$7ZIP_BASE/CPP/Common/MyString.h \
+ $$7ZIP_BASE/CPP/Common/MyTypes.h \
+ $$7ZIP_BASE/CPP/Common/MyUnknown.h \
+ $$7ZIP_BASE/CPP/Common/MyVector.h \
+ $$7ZIP_BASE/CPP/Common/MyWindows.h \
+ $$7ZIP_BASE/CPP/Common/NewHandler.h \
+ $$7ZIP_BASE/CPP/Common/StdOutStream.h \
+ $$7ZIP_BASE/CPP/Common/StringConvert.h \
+ $$7ZIP_BASE/CPP/Common/StringToInt.h \
+ $$7ZIP_BASE/CPP/Common/UTFConvert.h \
+ $$7ZIP_BASE/CPP/Common/Wildcard.h
+
+SOURCES += $$7ZIP_BASE/CPP/Common/CommandLineParser.cpp \
+ $$7ZIP_BASE/CPP/Common/IntToString.cpp \
+ $$7ZIP_BASE/CPP/Common/ListFileUtils.cpp \
+ $$7ZIP_BASE/CPP/Common/MyString.cpp \
+ $$7ZIP_BASE/CPP/Common/MyWindows.cpp \
+ $$7ZIP_BASE/CPP/Common/NewHandler.cpp \
+ $$7ZIP_BASE/CPP/Common/StdOutStream.cpp \
+ $$7ZIP_BASE/CPP/Common/StringConvert.cpp \
+ $$7ZIP_BASE/CPP/Common/StringToInt.cpp \
+ $$7ZIP_BASE/CPP/Common/UTFConvert.cpp \
+ $$7ZIP_BASE/CPP/Common/Wildcard.cpp
diff --git a/src/libs/7zip/unix/CPP/Common/DynamicBuffer.h b/src/libs/7zip/unix/CPP/Common/DynamicBuffer.h
deleted file mode 100644
index eaac123e1..000000000
--- a/src/libs/7zip/unix/CPP/Common/DynamicBuffer.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Common/DynamicBuffer.h
-
-#ifndef __COMMON_DYNAMIC_BUFFER_H
-#define __COMMON_DYNAMIC_BUFFER_H
-
-#include "Buffer.h"
-
-template <class T> class CDynamicBuffer: public CBuffer<T>
-{
- void GrowLength(size_t size)
- {
- size_t delta;
- if (this->_capacity > 64)
- delta = this->_capacity / 4;
- else if (this->_capacity > 8)
- delta = 16;
- else
- delta = 4;
- delta = MyMax(delta, size);
- size_t newCap = this->_capacity + delta;
- if (newCap < delta)
- newCap = this->_capacity + size;
- this->SetCapacity(newCap);
- }
-public:
- CDynamicBuffer(): CBuffer<T>() {};
- CDynamicBuffer(const CDynamicBuffer &buffer): CBuffer<T>(buffer) {};
- CDynamicBuffer(size_t size): CBuffer<T>(size) {};
- CDynamicBuffer& operator=(const CDynamicBuffer &buffer)
- {
- this->Free();
- if (buffer._capacity > 0)
- {
- this->SetCapacity(buffer._capacity);
- memmove(this->_items, buffer._items, buffer._capacity * sizeof(T));
- }
- return *this;
- }
- void EnsureCapacity(size_t capacity)
- {
- if (this->_capacity < capacity)
- GrowLength(capacity - this->_capacity);
- }
-};
-
-typedef CDynamicBuffer<char> CCharDynamicBuffer;
-typedef CDynamicBuffer<wchar_t> CWCharDynamicBuffer;
-typedef CDynamicBuffer<unsigned char> CByteDynamicBuffer;
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/Common/IntToString.cpp b/src/libs/7zip/unix/CPP/Common/IntToString.cpp
index 013fee527..ed217c72c 100644
--- a/src/libs/7zip/unix/CPP/Common/IntToString.cpp
+++ b/src/libs/7zip/unix/CPP/Common/IntToString.cpp
@@ -4,74 +4,143 @@
#include "IntToString.h"
-void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base)
+#define CONVERT_INT_TO_STR(charType, tempSize) \
+ unsigned char temp[tempSize]; unsigned i = 0; \
+ while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
+ *s++ = (charType)('0' + (unsigned)val); \
+ while (i != 0) { i--; *s++ = temp[i]; } \
+ *s = 0;
+
+void ConvertUInt32ToString(UInt32 val, char *s) throw()
{
- if (base < 2 || base > 36)
+ CONVERT_INT_TO_STR(char, 16);
+}
+
+void ConvertUInt64ToString(UInt64 val, char *s) throw()
+{
+ if (val <= (UInt32)0xFFFFFFFF)
{
- *s = '\0';
+ ConvertUInt32ToString((UInt32)val, s);
return;
}
- char temp[72];
- int pos = 0;
- do
+ CONVERT_INT_TO_STR(char, 24);
+}
+
+void ConvertUInt64ToOct(UInt64 val, char *s) throw()
+{
+ UInt64 v = val;
+ unsigned i;
+ for (i = 1;; i++)
{
- int delta = (int)(value % base);
- temp[pos++] = (char)((delta < 10) ? ('0' + delta) : ('a' + (delta - 10)));
- value /= base;
+ v >>= 3;
+ if (v == 0)
+ break;
}
- while (value != 0);
+ s[i] = 0;
do
- *s++ = temp[--pos];
- while (pos > 0);
- *s = '\0';
+ {
+ unsigned t = (unsigned)(val & 0x7);
+ val >>= 3;
+ s[--i] = (char)('0' + t);
+ }
+ while (i);
}
-void ConvertUInt64ToString(UInt64 value, wchar_t *s)
+void ConvertUInt32ToHex(UInt32 val, char *s) throw()
{
- wchar_t temp[32];
- int pos = 0;
+ UInt32 v = val;
+ unsigned i;
+ for (i = 1;; i++)
+ {
+ v >>= 4;
+ if (v == 0)
+ break;
+ }
+ s[i] = 0;
do
{
- temp[pos++] = (wchar_t)(L'0' + (int)(value % 10));
- value /= 10;
+ unsigned t = (unsigned)((val & 0xF));
+ val >>= 4;
+ s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
- while (value != 0);
+ while (i);
+}
+
+void ConvertUInt64ToHex(UInt64 val, char *s) throw()
+{
+ UInt64 v = val;
+ unsigned i;
+ for (i = 1;; i++)
+ {
+ v >>= 4;
+ if (v == 0)
+ break;
+ }
+ s[i] = 0;
do
- *s++ = temp[--pos];
- while (pos > 0);
- *s = L'\0';
+ {
+ unsigned t = (unsigned)((val & 0xF));
+ val >>= 4;
+ s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ }
+ while (i);
}
-void ConvertUInt32ToString(UInt32 value, char *s) { ConvertUInt64ToString(value, s); }
-void ConvertUInt32ToString(UInt32 value, wchar_t *s) { ConvertUInt64ToString(value, s); }
+void ConvertUInt32ToHex8Digits(UInt32 val, char *s) throw()
+{
+ s[8] = 0;
+ for (int i = 7; i >= 0; i--)
+ {
+ unsigned t = val & 0xF;
+ val >>= 4;
+ s[i] = (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10))));
+ }
+}
-void ConvertInt64ToString(Int64 value, char *s)
+/*
+void ConvertUInt32ToHex8Digits(UInt32 val, wchar_t *s)
{
- if (value < 0)
+ s[8] = 0;
+ for (int i = 7; i >= 0; i--)
{
- *s++ = '-';
- value = -value;
+ unsigned t = val & 0xF;
+ val >>= 4;
+ s[i] = (wchar_t)(((t < 10) ? ('0' + t) : ('A' + (t - 10))));
+ }
+}
+*/
+
+void ConvertUInt32ToString(UInt32 val, wchar_t *s) throw()
+{
+ CONVERT_INT_TO_STR(wchar_t, 16);
+}
+
+void ConvertUInt64ToString(UInt64 val, wchar_t *s) throw()
+{
+ if (val <= (UInt32)0xFFFFFFFF)
+ {
+ ConvertUInt32ToString((UInt32)val, s);
+ return;
}
- ConvertUInt64ToString(value, s);
+ CONVERT_INT_TO_STR(wchar_t, 24);
}
-void ConvertInt64ToString(Int64 value, wchar_t *s)
+void ConvertInt64ToString(Int64 val, char *s) throw()
{
- if (value < 0)
+ if (val < 0)
{
- *s++ = L'-';
- value = -value;
+ *s++ = '-';
+ val = -val;
}
- ConvertUInt64ToString(value, s);
+ ConvertUInt64ToString(val, s);
}
-void ConvertUInt32ToHexWithZeros(UInt32 value, char *s)
+void ConvertInt64ToString(Int64 val, wchar_t *s) throw()
{
- for (int i = 0; i < 8; i++)
+ if (val < 0)
{
- int t = value & 0xF;
- value >>= 4;
- s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ *s++ = L'-';
+ val = -val;
}
- s[8] = '\0';
+ ConvertUInt64ToString(val, s);
}
diff --git a/src/libs/7zip/unix/CPP/Common/IntToString.h b/src/libs/7zip/unix/CPP/Common/IntToString.h
index 782f930c5..69605ab76 100644
--- a/src/libs/7zip/unix/CPP/Common/IntToString.h
+++ b/src/libs/7zip/unix/CPP/Common/IntToString.h
@@ -3,17 +3,22 @@
#ifndef __COMMON_INT_TO_STRING_H
#define __COMMON_INT_TO_STRING_H
-#include <stddef.h>
-#include "Types.h"
+#include "MyTypes.h"
-void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base = 10);
-void ConvertUInt64ToString(UInt64 value, wchar_t *s);
-void ConvertInt64ToString(Int64 value, char *s);
-void ConvertInt64ToString(Int64 value, wchar_t *s);
+void ConvertUInt32ToString(UInt32 value, char *s) throw();
+void ConvertUInt64ToString(UInt64 value, char *s) throw();
-void ConvertUInt32ToString(UInt32 value, char *s);
-void ConvertUInt32ToString(UInt32 value, wchar_t *s);
+void ConvertUInt32ToString(UInt32 value, wchar_t *s) throw();
+void ConvertUInt64ToString(UInt64 value, wchar_t *s) throw();
-void ConvertUInt32ToHexWithZeros(UInt32 value, char *s);
+void ConvertUInt64ToOct(UInt64 value, char *s) throw();
+
+void ConvertUInt32ToHex(UInt32 value, char *s) throw();
+void ConvertUInt64ToHex(UInt64 value, char *s) throw();
+void ConvertUInt32ToHex8Digits(UInt32 value, char *s) throw();
+// void ConvertUInt32ToHex8Digits(UInt32 value, wchar_t *s) throw();
+
+void ConvertInt64ToString(Int64 value, char *s) throw();
+void ConvertInt64ToString(Int64 value, wchar_t *s) throw();
#endif
diff --git a/src/libs/7zip/unix/CPP/Common/ListFileUtils.cpp b/src/libs/7zip/unix/CPP/Common/ListFileUtils.cpp
index 8e409016e..cede1ae54 100644
--- a/src/libs/7zip/unix/CPP/Common/ListFileUtils.cpp
+++ b/src/libs/7zip/unix/CPP/Common/ListFileUtils.cpp
@@ -2,74 +2,116 @@
#include "StdAfx.h"
-#include "MyWindows.h"
+#include "../../C/CpuArch.h"
+
#include "../Windows/FileIO.h"
#include "ListFileUtils.h"
+#include "MyBuffer.h"
#include "StringConvert.h"
#include "UTFConvert.h"
-static const char kQuoteChar = '\"';
-static void RemoveQuote(UString &s)
+static const char kQuoteChar = '\"';
+
+static void AddName(UStringVector &strings, UString &s)
{
- if (s.Length() >= 2)
- if (s[0] == kQuoteChar && s[s.Length() - 1] == kQuoteChar)
- s = s.Mid(1, s.Length() - 2);
+ s.Trim();
+ if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar)
+ {
+ s.DeleteBack();
+ s.Delete(0);
+ }
+ if (!s.IsEmpty())
+ strings.Add(s);
}
-bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &resultStrings, UINT codePage)
+bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage)
{
NWindows::NFile::NIO::CInFile file;
- if (!file.Open(fileName,true)) /* follow the symbolic link */
- return false;
- UInt64 length;
- if (!file.GetLength(length))
+ if (!file.Open(fileName,true)) /* follow the symbolic link */
return false;
- if (length > ((UInt32)1 << 31))
+ UInt64 fileSize;
+ if (!file.GetLength(fileSize))
return false;
- AString s;
- char *p = s.GetBuffer((int)length + 1);
- UInt32 processed;
- if (!file.Read(p, (UInt32)length, processed))
+ if (fileSize >= ((UInt32)1 << 31) - 32)
return false;
- p[(UInt32)length] = 0;
- s.ReleaseBuffer();
- file.Close();
-
UString u;
- #ifdef CP_UTF8
- if (codePage == CP_UTF8)
+ if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE)
{
- if (!ConvertUTF8ToUnicode(s, u))
+ if ((fileSize & 1) != 0)
+ return false;
+ CByteArr buf((size_t)fileSize);
+ UInt32 processed;
+ if (!file.Read(buf, (UInt32)fileSize, processed))
return false;
+ if (processed != fileSize)
+ return false;
+ file.Close();
+ unsigned num = (unsigned)fileSize / 2;
+ wchar_t *p = u.GetBuffer(num);
+ if (codePage == MY__CP_UTF16)
+ for (unsigned i = 0; i < num; i++)
+ {
+ wchar_t c = GetUi16(buf + i * 2);
+ if (c == 0)
+ return false;
+ p[i] = c;
+ }
+ else
+ for (unsigned i = 0; i < num; i++)
+ {
+ wchar_t c = (wchar_t)GetBe16(buf + i * 2);
+ if (c == 0)
+ return false;
+ p[i] = c;
+ }
+ u.ReleaseBuffer(num);
}
else
- #endif
- u = MultiByteToUnicodeString(s, codePage);
- if (!u.IsEmpty())
{
- if (u[0] == 0xFEFF)
- u.Delete(0);
+ AString s;
+ char *p = s.GetBuffer((unsigned)fileSize);
+ UInt32 processed;
+ if (!file.Read(p, (UInt32)fileSize, processed))
+ return false;
+ if (processed != fileSize)
+ return false;
+ file.Close();
+ p[processed] = 0;
+ s.ReleaseBuffer();
+ if (s.Len() != processed)
+ return false;
+
+ // #ifdef CP_UTF8
+ if (codePage == CP_UTF8)
+ {
+ if (!ConvertUTF8ToUnicode(s, u))
+ return false;
+ }
+ else
+ // #endif
+ MultiByteToUnicodeString2(u, s, codePage);
}
- UString t;
- for (int i = 0; i < u.Length(); i++)
+ const wchar_t kGoodBOM = 0xFEFF;
+ const wchar_t kBadBOM = 0xFFFE;
+
+ UString s;
+ unsigned i = 0;
+ for (; i < u.Len() && u[i] == kGoodBOM; i++);
+ for (; i < u.Len(); i++)
{
wchar_t c = u[i];
+ if (c == kGoodBOM || c == kBadBOM)
+ return false;
if (c == L'\n' || c == 0xD)
{
- t.Trim();
- RemoveQuote(t);
- if (!t.IsEmpty())
- resultStrings.Add(t);
- t.Empty();
+ AddName(strings, s);
+ s.Empty();
}
else
- t += c;
+ s += c;
}
- t.Trim();
- RemoveQuote(t);
- if (!t.IsEmpty())
- resultStrings.Add(t);
+ AddName(strings, s);
return true;
}
diff --git a/src/libs/7zip/unix/CPP/Common/ListFileUtils.h b/src/libs/7zip/unix/CPP/Common/ListFileUtils.h
index c58a8bd42..e8d833fdb 100644
--- a/src/libs/7zip/unix/CPP/Common/ListFileUtils.h
+++ b/src/libs/7zip/unix/CPP/Common/ListFileUtils.h
@@ -1,11 +1,14 @@
// Common/ListFileUtils.h
-#ifndef __COMMON_LISTFILEUTILS_H
-#define __COMMON_LISTFILEUTILS_H
+#ifndef __COMMON_LIST_FILE_UTILS_H
+#define __COMMON_LIST_FILE_UTILS_H
#include "MyString.h"
-#include "Types.h"
+#include "MyTypes.h"
-bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP);
+#define MY__CP_UTF16 1200
+#define MY__CP_UTF16BE 1201
+
+bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP);
#endif
diff --git a/src/libs/7zip/unix/CPP/Common/MyBuffer.h b/src/libs/7zip/unix/CPP/Common/MyBuffer.h
new file mode 100644
index 000000000..7bd79f6f4
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/Common/MyBuffer.h
@@ -0,0 +1,237 @@
+// Common/MyBuffer.h
+
+#ifndef __COMMON_MY_BUFFER_H
+#define __COMMON_MY_BUFFER_H
+
+#include "Defs.h"
+
+template <class T> class CBuffer
+{
+ T *_items;
+ size_t _size;
+
+ void CopyToEmpty(const CBuffer &buffer)
+ {
+ if (buffer._size > 0)
+ {
+ _items = new T[buffer._size];
+ memcpy(_items, buffer._items, buffer._size * sizeof(T));
+ _size = buffer._size;
+ }
+ }
+public:
+ void Free()
+ {
+ if (_items)
+ {
+ delete []_items;
+ _items = 0;
+ }
+ _size = 0;
+ }
+
+ CBuffer(): _items(0), _size(0) {};
+ CBuffer(size_t size): _items(0), _size(0) { _items = new T[size]; _size = size; }
+ CBuffer(const CBuffer &buffer): _items(0), _size(0) { CopyToEmpty(buffer); }
+ ~CBuffer() { delete []_items; }
+
+ operator T *() { return _items; };
+ operator const T *() const { return _items; };
+ size_t Size() const { return _size; }
+
+ void Alloc(size_t size)
+ {
+ if (size != _size)
+ {
+ Free();
+ if (size != 0)
+ {
+ _items = new T[size];
+ _size = size;
+ }
+ }
+ }
+
+ void AllocAtLeast(size_t size)
+ {
+ if (size > _size)
+ {
+ Free();
+ _items = new T[size];
+ _size = size;
+ }
+ }
+
+ void CopyFrom(const T *data, size_t size)
+ {
+ Alloc(size);
+ memcpy(_items, data, size * sizeof(T));
+ }
+
+ void ChangeSize_KeepData(size_t newSize, size_t keepSize)
+ {
+ if (newSize == _size)
+ return;
+ T *newBuffer = NULL;
+ if (newSize > 0)
+ {
+ newBuffer = new T[newSize];
+ if (_size > 0)
+ memcpy(newBuffer, _items, MyMin(MyMin(_size, keepSize), newSize) * sizeof(T));
+ }
+ delete []_items;
+ _items = newBuffer;
+ _size = newSize;
+ }
+
+ CBuffer& operator=(const CBuffer &buffer)
+ {
+ Free();
+ CopyToEmpty(buffer);
+ return *this;
+ }
+};
+
+template <class T>
+bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ size_t size1 = b1.Size();
+ if (size1 != b2.Size())
+ return false;
+ return memcmp(b1, b2, size1 * sizeof(T)) == 0;
+}
+
+template <class T>
+bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ size_t size1 = b1.Size();
+ if (size1 == b2.Size())
+ return false;
+ return memcmp(b1, b2, size1 * sizeof(T)) != 0;
+}
+
+
+typedef CBuffer<char> CCharBuffer;
+typedef CBuffer<wchar_t> CWCharBuffer;
+typedef CBuffer<unsigned char> CByteBuffer;
+
+
+template <class T> class CObjArray
+{
+protected:
+ T *_items;
+private:
+ // we disable constructors
+ CObjArray(const CObjArray &buffer);
+ void operator=(const CObjArray &buffer);
+public:
+ void Free()
+ {
+ delete []_items;
+ _items = 0;
+ }
+ CObjArray(size_t size): _items(0) { if (size != 0) _items = new T[size]; }
+ CObjArray(): _items(0) {};
+ ~CObjArray() { delete []_items; }
+
+ operator T *() { return _items; };
+ operator const T *() const { return _items; };
+
+ void Alloc(size_t newSize)
+ {
+ delete []_items;
+ _items = 0;
+ _items = new T[newSize];
+ }
+};
+
+typedef CObjArray<unsigned char> CByteArr;
+typedef CObjArray<bool> CBoolArr;
+typedef CObjArray<int> CIntArr;
+
+// #define CRecArray CObjArray
+
+template <class T> class CObjArray2
+{
+// protected:
+ T *_items;
+ unsigned _size;
+
+ CObjArray2(const CObjArray2 &buffer);
+ void operator=(const CObjArray2 &buffer);
+public:
+
+ void Free()
+ {
+ delete []_items;
+ _items = 0;
+ _size = 0;
+ }
+ CObjArray2(): _items(0), _size(0) {};
+ /*
+ CObjArray2(const CObjArray2 &buffer): _items(0), _size(0)
+ {
+ size_t newSize = buffer._size;
+ if (newSize > 0)
+ {
+ T *newBuffer = new T[newSize];;
+ _items = newBuffer;
+ _size = newSize;
+ const T *src = buffer;
+ for (size_t i = 0; i < newSize; i++)
+ newBuffer[i] = src[i];
+ }
+ }
+ */
+ /*
+ CObjArray2(size_t size): _items(0), _size(0)
+ {
+ if (size != 0)
+ {
+ _items = new T[size];
+ _size = size;
+ }
+ }
+ */
+
+ ~CObjArray2() { delete []_items; }
+
+ operator T *() { return _items; };
+ operator const T *() const { return _items; };
+
+ unsigned Size() const { return (unsigned)_size; }
+ bool IsEmpty() const { return _size == 0; }
+
+ // SetSize doesn't keep old items. It allocates new array if size is not equal
+ void SetSize(unsigned size)
+ {
+ if (size == _size)
+ return;
+ T *newBuffer = NULL;
+ if (size > 0)
+ newBuffer = new T[size];
+ delete []_items;
+ _items = newBuffer;
+ _size = size;
+ }
+
+ /*
+ CObjArray2& operator=(const CObjArray2 &buffer)
+ {
+ Free();
+ size_t newSize = buffer._size;
+ if (newSize > 0)
+ {
+ T *newBuffer = new T[newSize];;
+ _items = newBuffer;
+ _size = newSize;
+ const T *src = buffer;
+ for (size_t i = 0; i < newSize; i++)
+ newBuffer[i] = src[i];
+ }
+ return *this;
+ }
+ */
+};
+
+#endif
diff --git a/src/libs/7zip/unix/CPP/Common/MyCom.h b/src/libs/7zip/unix/CPP/Common/MyCom.h
index 2f00c258f..466407cde 100644
--- a/src/libs/7zip/unix/CPP/Common/MyCom.h
+++ b/src/libs/7zip/unix/CPP/Common/MyCom.h
@@ -1,9 +1,10 @@
// MyCom.h
-#ifndef __MYCOM_H
-#define __MYCOM_H
+#ifndef __MY_COM_H
+#define __MY_COM_H
#include "MyWindows.h"
+#include "NewHandler.h"
#ifndef RINOK
#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; }
@@ -14,14 +15,9 @@ class CMyComPtr
{
T* _p;
public:
- // typedef T _PtrClass;
- CMyComPtr() { _p = NULL;}
- CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
- CMyComPtr(const CMyComPtr<T>& lp)
- {
- if ((_p = lp._p) != NULL)
- _p->AddRef();
- }
+ CMyComPtr(): _p(NULL) {}
+ CMyComPtr(T* p) throw() { if ((_p = p) != NULL) p->AddRef(); }
+ CMyComPtr(const CMyComPtr<T>& lp) throw() { if ((_p = lp._p) != NULL) _p->AddRef(); }
~CMyComPtr() { if (_p) _p->Release(); }
void Release() { if (_p) { _p->Release(); _p = NULL; } }
operator T*() const { return (T*)_p; }
@@ -30,7 +26,7 @@ public:
T* operator->() const { return _p; }
T* operator=(T* p)
{
- if (p != 0)
+ if (p)
p->AddRef();
if (_p)
_p->Release();
@@ -40,7 +36,6 @@ public:
T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
bool operator!() const { return (_p == NULL); }
// bool operator==(T* pT) const { return _p == pT; }
- // Compare two objects for equivalence
void Attach(T* p2)
{
Release();
@@ -70,7 +65,7 @@ public:
}
*/
template <class Q>
- HRESULT QueryInterface(REFGUID iid, Q** pp) const
+ HRESULT QueryInterface(REFGUID iid, Q** pp) const throw()
{
return _p->QueryInterface(iid, (void**)pp);
}
@@ -81,13 +76,14 @@ public:
inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr)
{
*bstr = ::SysAllocString(src);
- return (*bstr != 0) ? S_OK : E_OUTOFMEMORY;
+ return (*bstr != NULL) ? S_OK : E_OUTOFMEMORY;
}
class CMyComBSTR
{
-public:
BSTR m_str;
+public:
+
CMyComBSTR(): m_str(NULL) {}
CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); }
// CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
@@ -119,7 +115,7 @@ public:
m_str = ::SysAllocString(src);
return *this;
}
- unsigned int Length() const { return ::SysStringLen(m_str); }
+ // unsigned Len() const { return ::SysStringLen(m_str); }
operator BSTR() const { return m_str; }
BSTR* operator&() { return &m_str; }
BSTR MyCopy() const
@@ -143,7 +139,7 @@ public:
::SysFreeString(m_str);
m_str = NULL;
}
- bool operator!() const { return (m_str == NULL); }
+ bool operator!() const { return (m_str == NULL); }
};
//////////////////////////////////////////////////////////
@@ -156,22 +152,22 @@ public:
};
#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
- (REFGUID iid, void **outObject) {
+(REFGUID iid, void **outObject) throw() { *outObject = NULL;
-#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
- { *outObject = (void *)(i *)this; AddRef(); return S_OK; }
+#define MY_QUERYINTERFACE_ENTRY(i) else if (iid == IID_ ## i) \
+ { *outObject = (void *)(i *)this; }
#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \
- { *outObject = (void *)(IUnknown *)(i *)this; AddRef(); return S_OK; }
+ { *outObject = (void *)(IUnknown *)(i *)this; }
#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
MY_QUERYINTERFACE_ENTRY(i)
-#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
+#define MY_QUERYINTERFACE_END else return E_NOINTERFACE; AddRef(); return S_OK; }
#define MY_ADDREF_RELEASE \
-STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
+STDMETHOD_(ULONG, AddRef)() throw() { return ++__m_RefCount; } \
STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
return __m_RefCount; delete this; return 0; }
@@ -222,4 +218,25 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
MY_QUERYINTERFACE_ENTRY(i5) \
)
+#define MY_UNKNOWN_IMP6(i1, i2, i3, i4, i5, i6) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ MY_QUERYINTERFACE_ENTRY(i6) \
+ )
+
+#define MY_UNKNOWN_IMP7(i1, i2, i3, i4, i5, i6, i7) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ MY_QUERYINTERFACE_ENTRY(i6) \
+ MY_QUERYINTERFACE_ENTRY(i7) \
+ )
+
#endif
diff --git a/src/libs/7zip/unix/CPP/Common/MyGuidDef.h b/src/libs/7zip/unix/CPP/Common/MyGuidDef.h
index 3c52cc07d..68745870e 100644
--- a/src/libs/7zip/unix/CPP/Common/MyGuidDef.h
+++ b/src/libs/7zip/unix/CPP/Common/MyGuidDef.h
@@ -3,7 +3,7 @@
#ifndef GUID_DEFINED
#define GUID_DEFINED
-#include "Types.h"
+#include "MyTypes.h"
typedef struct {
UInt32 Data1;
diff --git a/src/libs/7zip/unix/CPP/Common/MyInitGuid.h b/src/libs/7zip/unix/CPP/Common/MyInitGuid.h
index d6a486980..279fba5d6 100644
--- a/src/libs/7zip/unix/CPP/Common/MyInitGuid.h
+++ b/src/libs/7zip/unix/CPP/Common/MyInitGuid.h
@@ -3,20 +3,43 @@
#ifndef __COMMON_MY_INITGUID_H
#define __COMMON_MY_INITGUID_H
+/*
+This file must be included only to one C++ file in project before
+declarations of COM interfaces with DEFINE_GUID macro.
+
+Each GUID must be initialized exactly once in project.
+There are two different versions of the DEFINE_GUID macro in guiddef.h (MyGuidDef.h):
+ - if INITGUID is not defined: DEFINE_GUID declares an external reference to the symbol name.
+ - if INITGUID is defined: DEFINE_GUID initializes the symbol name to the value of the GUID.
+
+Also we need IID_IUnknown that is initialized in some file for linking:
+ MSVC: by default the linker uses some lib file that contains IID_IUnknown
+ MinGW: add -luuid switch for linker
+ WinCE: we define IID_IUnknown in this file
+ Other: we define IID_IUnknown in this file
+*/
+
#ifdef _WIN32
+
#ifdef UNDER_CE
#include <basetyps.h>
#endif
+
#include <initguid.h>
+
#ifdef UNDER_CE
DEFINE_GUID(IID_IUnknown,
0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
#endif
+
#else
+
#define INITGUID
#include "MyGuidDef.h"
DEFINE_GUID(IID_IUnknown,
0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+
#endif
+
#endif
diff --git a/src/libs/7zip/unix/CPP/Common/MyString.cpp b/src/libs/7zip/unix/CPP/Common/MyString.cpp
index 1c145f36e..6fbfa334b 100644
--- a/src/libs/7zip/unix/CPP/Common/MyString.cpp
+++ b/src/libs/7zip/unix/CPP/Common/MyString.cpp
@@ -1,153 +1,298 @@
-// Common/String.cpp
+// Common/MyString.cpp
#include "StdAfx.h"
+#ifdef _WIN32
+#include <windows.h>
+#include <wchar.h>
+#else
#include <ctype.h>
-#ifdef ENV_HAVE_WCTYPE_H
-#include <wctype.h>
#endif
-#include "StringConvert.h" // FIXED
-#include "MyString.h" // FIXED to avoid confusion with <string.h> on some filesystems
+#if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING)
+#include "StringConvert.h"
+#endif
-#include <stdio.h>
-#include <stdlib.h>
+#include "MyString.h"
-#ifdef ENV_HAVE_WCHAR__H
-#include <wchar.h>
-#endif
+#define MY_STRING_NEW(_T_, _size_) new _T_[_size_]
+// #define MY_STRING_NEW(_T_, _size_) ((_T_ *)my_new((size_t)(_size_) * sizeof(_T_)))
-#include <limits.h>
-#ifndef MB_LEN_MAX
-#define MB_LEN_MAX 1024
-#endif
+/*
+inline const char* MyStringGetNextCharPointer(const char *p) throw()
+{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ return CharNextA(p);
+ #else
+ return p + 1;
+ #endif
+}
+*/
-#include "myPrivate.h"
+int FindCharPosInString(const char *s, char c) throw()
+{
+ for (const char *p = s;; p++)
+ {
+ if (*p == c)
+ return (int)(p - s);
+ if (*p == 0)
+ return -1;
+ // MyStringGetNextCharPointer(p);
+ }
+}
-LPSTR WINAPI CharPrevA( LPCSTR start, LPCSTR ptr ) { // OK for MBS
- while (*start && (start < ptr)) {
- LPCSTR next = CharNextA( start );
- if (next >= ptr)
- break;
- start = next;
+int FindCharPosInString(const wchar_t *s, wchar_t c) throw()
+{
+ for (const wchar_t *p = s;; p++)
+ {
+ if (*p == c)
+ return (int)(p - s);
+ if (*p == 0)
+ return -1;
}
- return (LPSTR)start;
}
-LPSTR WINAPI CharNextA( LPCSTR ptr ) {
- if (!*ptr)
- return (LPSTR)ptr;
-// #ifdef ENV_HAVE_MBRTOWC
-// if (global_use_utf16_conversion)
-// {
-// wchar_t wc;
-// size_t len = mbrtowc(&wc,ptr,MB_LEN_MAX,0); // mbrtowc stales on some configurations.
-// if (len >= 1) return (LPSTR)(ptr + len);
-// printf("INTERNAL ERROR - CharNextA\n");
-// exit(EXIT_FAILURE);
-// } else {
-// return (LPSTR)(ptr + 1);
-// }
-//#else
- return (LPSTR)(ptr + 1); // p7zip search only for ASCII characters like '/' so no need to worry about current locale
-//#endif
+/*
+void MyStringUpper_Ascii(wchar_t *s)
+{
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharUpper_Ascii(c);
+ }
}
+*/
-char MyCharLower(char c)
+void MyStringLower_Ascii(wchar_t *s) throw()
{
- int r = c & 0xFF;
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharLower_Ascii(c);
+ }
+}
+
+#ifdef _WIN32
+
+#ifdef _UNICODE
+
+// wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
+// wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
+// for WinCE - FString - char
+// const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p) { return p - 1; }
+
+#else
- return tolower(r);
+// const char * MyStringGetPrevCharPointer(const char *base, const char *p) throw() { return CharPrevA(base, p); }
+// char * MyStringUpper(char *s) { return CharUpperA(s); }
+// char * MyStringLower(char *s) { return CharLowerA(s); }
+
+wchar_t MyCharUpper_WIN(wchar_t c) throw()
+{
+ wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return (wchar_t)(unsigned)(UINT_PTR)res;
+ const int kBufSize = 4;
+ char s[kBufSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);
+ if (numChars == 0 || numChars > kBufSize)
+ return c;
+ s[numChars] = 0;
+ ::CharUpperA(s);
+ ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
+ return c;
}
-wchar_t MyCharLower(wchar_t c)
+/*
+wchar_t MyCharLower_WIN(wchar_t c)
{
-#ifdef ENV_HAVE_TOWUPPER
- return towlower(c);
-#else
- int ret = c;
- if ((ret >= 1) && (ret <256)) ret = tolower(ret);
- return (wchar_t)ret;
-#endif
+ wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return (wchar_t)(unsigned)(UINT_PTR)res;
+ const int kBufSize = 4;
+ char s[kBufSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);
+ if (numChars == 0 || numChars > kBufSize)
+ return c;
+ s[numChars] = 0;
+ ::CharLowerA(s);
+ ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
+ return c;
}
+*/
-char * MyStringLower(char *s)
+/*
+wchar_t * MyStringUpper(wchar_t *s)
{
if (s == 0)
return 0;
- char *ret = s;
- while (*s)
- {
- *s = MyCharLower(*s);
- s++;
- }
- return ret;
+ wchar_t *res = CharUpperW(s);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return res;
+ AString a = UnicodeStringToMultiByte(s);
+ a.MakeUpper();
+ MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+ return s;
}
+*/
+/*
wchar_t * MyStringLower(wchar_t *s)
{
if (s == 0)
return 0;
- wchar_t *ret = s;
- while (*s)
+ wchar_t *res = CharLowerW(s);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return res;
+ AString a = UnicodeStringToMultiByte(s);
+ a.MakeLower();
+ MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+ return s;
+}
+*/
+
+#endif
+
+#endif
+
+bool IsString1PrefixedByString2(const char *s1, const char *s2) throw()
+{
+ for (;;)
{
- *s = MyCharLower(*s);
- s++;
+ unsigned char c2 = (unsigned char)*s2++; if (c2 == 0) return true;
+ unsigned char c1 = (unsigned char)*s1++; if (c1 != c2) return false;
}
- return ret;
}
-wchar_t MyCharUpper(wchar_t c)
+bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw()
{
-#ifdef ENV_HAVE_TOWUPPER
- return towupper(c);
-#else
- int ret = c;
- if ((ret >= 1) && (ret <256)) ret = toupper(ret);
- return (wchar_t)ret;
-#endif
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false;
+ if (c1 == 0) return true;
+ }
}
-wchar_t * MyStringUpper(wchar_t *s)
+// ---------- ASCII ----------
+
+bool AString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw()
{
- if (s == 0)
- return 0;
- wchar_t *ret = s;
- while (*s)
+ const char *s1 = _chars;
+ for (;;)
{
- *s = MyCharUpper(*s);
- s++;
+ char c2 = *s++;
+ if (c2 == 0)
+ return true;
+ char c1 = *s1++;
+ if (MyCharLower_Ascii(c1) !=
+ MyCharLower_Ascii(c2))
+ return false;
}
- return ret;
}
-int MyStringCompare(const char *s1, const char *s2)
+bool UString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw()
{
- while (true)
+ const wchar_t *s1 = _chars;
+ for (;;)
{
- unsigned char c1 = (unsigned char)*s1++;
- unsigned char c2 = (unsigned char)*s2++;
- if (c1 < c2) return -1;
- if (c1 > c2) return 1;
- if (c1 == 0) return 0;
+ char c2 = *s++;
+ if (c2 == 0)
+ return true;
+ wchar_t c1 = *s1++;
+ if (MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))
+ return false;
}
}
-int MyStringCompare(const wchar_t *s1, const wchar_t *s2)
+bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw()
{
- while (true)
+ for (;;)
+ {
+ unsigned char c = *a;
+ if (c != *u)
+ return false;
+ if (c == 0)
+ return true;
+ a++;
+ u++;
+ }
+}
+
+bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw()
+{
+ for (;;)
+ {
+ char c1 = *s1++;
+ char c2 = *s2++;
+ if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
+ return false;
+ if (c1 == 0)
+ return true;
+ }
+}
+
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw()
+{
+ for (;;)
{
wchar_t c1 = *s1++;
wchar_t c2 = *s2++;
- if (c1 < c2) return -1;
- if (c1 > c2) return 1;
+ if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
+ return false;
+ if (c1 == 0)
+ return true;
+ }
+}
+
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw()
+{
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ char c2 = *s2++;
+ if (c1 != (unsigned char)c2 && (c1 > 0x7F || MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2)))
+ return false;
+ if (c1 == 0)
+ return true;
+ }
+}
+
+bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw()
+{
+ for (;;)
+ {
+ wchar_t c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++; if (c1 != c2) return false;
+ }
+}
+
+// NTFS order: uses upper case
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw()
+{
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 != c2)
+ {
+ wchar_t u1 = MyCharUpper(c1);
+ wchar_t u2 = MyCharUpper(c2);
+ if (u1 < u2) return -1;
+ if (u1 > u2) return 1;
+ }
if (c1 == 0) return 0;
}
}
-int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)
+int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw()
{
- while (true)
+ for (; num != 0; num--)
{
wchar_t c1 = *s1++;
wchar_t c2 = *s2++;
@@ -160,47 +305,911 @@ int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)
}
if (c1 == 0) return 0;
}
+ return 0;
+}
+
+
+// ---------- AString ----------
+
+void AString::InsertSpace(unsigned &index, unsigned size)
+{
+ Grow(size);
+ MoveItems(index + size, index);
+}
+
+void AString::ReAlloc(unsigned newLimit)
+{
+ if (newLimit < _len || newLimit >= 0x20000000) throw 20130220;
+ // MY_STRING_REALLOC(_chars, char, newLimit + 1, _len + 1);
+ char *newBuf = MY_STRING_NEW(char, newLimit + 1);
+ memcpy(newBuf, _chars, (size_t)(_len + 1)); \
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+
+ _limit = newLimit;
+}
+
+void AString::SetStartLen(unsigned len)
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(char, len + 1);
+ _len = len;
+ _limit = len;
+}
+
+void AString::Grow_1()
+{
+ unsigned next = _len;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+void AString::Grow(unsigned n)
+{
+ unsigned freeSize = _limit - _len;
+ if (n <= freeSize)
+ return;
+
+ unsigned next = _len + n;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+/*
+AString::AString(unsigned num, const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (num > len)
+ num = len;
+ SetStartLen(num);
+ memcpy(_chars, s, num);
+ _chars[num] = 0;
+}
+*/
+
+AString::AString(unsigned num, const AString &s)
+{
+ if (num > s._len)
+ num = s._len;
+ SetStartLen(num);
+ memcpy(_chars, s._chars, num);
+ _chars[num] = 0;
+}
+
+AString::AString(const AString &s, char c)
+{
+ SetStartLen(s.Len() + 1);
+ char *chars = _chars;
+ unsigned len = s.Len();
+ memcpy(chars, s, len);
+ chars[len] = c;
+ chars[len + 1] = 0;
+}
+
+AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2)
+{
+ SetStartLen(num1 + num2);
+ char *chars = _chars;
+ memcpy(chars, s1, num1);
+ memcpy(chars + num1, s2, num2 + 1);
+}
+
+AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); }
+AString operator+(const AString &s1, const char *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); }
+AString operator+(const char *s1, const AString &s2) { return AString(s1, MyStringLen(s1), s2, s2.Len()); }
+
+AString::AString()
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(char, 4);
+ _len = 0;
+ _limit = 4 - 1;
+ _chars[0] = 0;
+}
+
+AString::AString(char c)
+{
+ SetStartLen(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+}
+
+AString::AString(const char *s)
+{
+ SetStartLen(MyStringLen(s));
+ MyStringCopy(_chars, s);
+}
+
+AString::AString(const AString &s)
+{
+ SetStartLen(s._len);
+ MyStringCopy(_chars, s._chars);
+}
+
+AString &AString::operator=(char c)
+{
+ if (1 > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, 1 + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = 1;
+ }
+ _len = 1;
+ _chars[0] = c;
+ _chars[1] = 0;
+ return *this;
+}
+
+AString &AString::operator=(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ MyStringCopy(_chars, s);
+ return *this;
+}
+
+AString &AString::operator=(const AString &s)
+{
+ if (&s == this)
+ return *this;
+ unsigned len = s._len;
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ MyStringCopy(_chars, s._chars);
+ return *this;
+}
+
+AString &AString::operator+=(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ Grow(len);
+ MyStringCopy(_chars + _len, s);
+ _len += len;
+ return *this;
+}
+
+AString &AString::operator+=(const AString &s)
+{
+ Grow(s._len);
+ MyStringCopy(_chars + _len, s._chars);
+ _len += s._len;
+ return *this;
+}
+
+void AString::SetFrom(const char *s, unsigned len) // no check
+{
+ if (len > _limit)
+ {
+ char *newBuf = MY_STRING_NEW(char, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ memcpy(_chars, s, len);
+ _chars[len] = 0;
+ _len = len;
+}
+
+int AString::Find(const AString &s, unsigned startIndex) const throw()
+{
+ if (s.IsEmpty())
+ return startIndex;
+ for (; startIndex < _len; startIndex++)
+ {
+ unsigned j;
+ for (j = 0; j < s._len && startIndex + j < _len; j++)
+ if (_chars[startIndex + j] != s._chars[j])
+ break;
+ if (j == s._len)
+ return (int)startIndex;
+ }
+ return -1;
+}
+
+int AString::ReverseFind(char c) const throw()
+{
+ if (_len == 0)
+ return -1;
+ const char *p = _chars + _len - 1;
+ for (;;)
+ {
+ if (*p == c)
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p--; // p = GetPrevCharPointer(_chars, p);
+ }
+}
+
+void AString::TrimLeft() throw()
+{
+ const char *p = _chars;
+ for (;; p++)
+ {
+ char c = *p;
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ unsigned pos = (unsigned)(p - _chars);
+ if (pos != 0)
+ {
+ MoveItems(0, pos);
+ _len -= pos;
+ }
+}
+
+void AString::TrimRight() throw()
+{
+ const char *p = _chars;
+ int i;
+ for (i = _len - 1; i >= 0; i--)
+ {
+ char c = p[i];
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ i++;
+ if ((unsigned)i != _len)
+ {
+ _chars[i] = 0;
+ _len = i;
+ }
+}
+
+void AString::InsertAtFront(char c)
+{
+ if (_limit == _len)
+ Grow_1();
+ MoveItems(1, 0);
+ _chars[0] = c;
+ _len++;
+}
+
+/*
+void AString::Insert(unsigned index, char c)
+{
+ InsertSpace(index, 1);
+ _chars[index] = c;
+ _len++;
+}
+*/
+
+void AString::Insert(unsigned index, const char *s)
+{
+ unsigned num = MyStringLen(s);
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ memcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void AString::Insert(unsigned index, const AString &s)
+{
+ unsigned num = s.Len();
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ memcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void AString::RemoveChar(char ch) throw()
+{
+ int pos = Find(ch);
+ if (pos < 0)
+ return;
+ const char *src = _chars;
+ char *dest = _chars + pos;
+ pos++;
+ unsigned len = _len;
+ for (; (unsigned)pos < len; pos++)
+ {
+ char c = src[(unsigned)pos];
+ if (c != ch)
+ *dest++ = c;
+ }
+ *dest = 0;
+ _len = (unsigned)(dest - _chars);
+}
+
+// !!!!!!!!!!!!!!! test it if newChar = '\0'
+void AString::Replace(char oldChar, char newChar) throw()
+{
+ if (oldChar == newChar)
+ return; // 0;
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldChar, pos);
+ if (pos < 0)
+ break;
+ _chars[pos] = newChar;
+ pos++;
+ // number++;
+ }
+ return; // number;
+}
+
+void AString::Replace(const AString &oldString, const AString &newString)
+{
+ if (oldString.IsEmpty())
+ return; // 0;
+ if (oldString == newString)
+ return; // 0;
+ unsigned oldLen = oldString.Len();
+ unsigned newLen = newString.Len();
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldString, pos);
+ if (pos < 0)
+ break;
+ Delete(pos, oldLen);
+ Insert(pos, newString);
+ pos += newLen;
+ // number++;
+ }
+ // return number;
+}
+
+void AString::Delete(unsigned index) throw()
+{
+ MoveItems(index, index + 1);
+ _len--;
+}
+
+void AString::Delete(unsigned index, unsigned count) throw()
+{
+ if (index + count > _len)
+ count = _len - index;
+ if (count > 0)
+ {
+ MoveItems(index, index + count);
+ _len -= count;
+ }
+}
+
+void AString::DeleteFrontal(unsigned num) throw()
+{
+ if (num != 0)
+ {
+ MoveItems(0, num);
+ _len -= num;
+ }
+}
+
+/*
+AString operator+(const AString &s1, const AString &s2)
+{
+ AString result(s1);
+ result += s2;
+ return result;
+}
+
+AString operator+(const AString &s, const char *chars)
+{
+ AString result(s);
+ result += chars;
+ return result;
+}
+
+AString operator+(const char *chars, const AString &s)
+{
+ AString result(chars);
+ result += s;
+ return result;
+}
+
+AString operator+(const AString &s, char c)
+{
+ AString result(s);
+ result += c;
+ return result;
+}
+*/
+
+/*
+AString operator+(char c, const AString &s)
+{
+ AString result(c);
+ result += s;
+ return result;
}
+*/
+
+
+
+// ---------- UString ----------
+
+void UString::InsertSpace(unsigned index, unsigned size)
+{
+ Grow(size);
+ MoveItems(index + size, index);
+}
+
+void UString::ReAlloc(unsigned newLimit)
+{
+ if (newLimit < _len || newLimit >= 0x20000000) throw 20130221;
+ // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, _len + 1);
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, newLimit + 1);
+ wmemcpy(newBuf, _chars, _len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+
+ _limit = newLimit;
+}
+
+void UString::SetStartLen(unsigned len)
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(wchar_t, len + 1);
+ _len = len;
+ _limit = len;
+}
+
+void UString::Grow_1()
+{
+ unsigned next = _len;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+void UString::Grow(unsigned n)
+{
+ unsigned freeSize = _limit - _len;
+ if (n <= freeSize)
+ return;
+
+ unsigned next = _len + n;
+ next += next / 2;
+ next += 16;
+ next &= ~(unsigned)15;
+ ReAlloc(next - 1);
+}
+
+
+UString::UString(unsigned num, const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ if (num > len)
+ num = len;
+ SetStartLen(num);
+ wmemcpy(_chars, s, num);
+ _chars[num] = 0;
+}
+
+
+UString::UString(unsigned num, const UString &s)
+{
+ if (num > s._len)
+ num = s._len;
+ SetStartLen(num);
+ wmemcpy(_chars, s._chars, num);
+ _chars[num] = 0;
+}
+
+UString::UString(const UString &s, wchar_t c)
+{
+ SetStartLen(s.Len() + 1);
+ wchar_t *chars = _chars;
+ unsigned len = s.Len();
+ wmemcpy(chars, s, len);
+ chars[len] = c;
+ chars[len + 1] = 0;
+}
+
+UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2)
+{
+ SetStartLen(num1 + num2);
+ wchar_t *chars = _chars;
+ wmemcpy(chars, s1, num1);
+ wmemcpy(chars + num1, s2, num2 + 1);
+}
+
+UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); }
+UString operator+(const UString &s1, const wchar_t *s2) { return UString(s1, s1.Len(), s2, MyStringLen(s2)); }
+UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); }
+
+UString::UString()
+{
+ _chars = 0;
+ _chars = MY_STRING_NEW(wchar_t, 4);
+ _len = 0;
+ _limit = 4 - 1;
+ _chars[0] = 0;
+}
+
+UString::UString(wchar_t c)
+{
+ SetStartLen(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+}
+
+UString::UString(const wchar_t *s)
+{
+ SetStartLen(MyStringLen(s));
+ MyStringCopy(_chars, s);
+}
+
+UString::UString(const UString &s)
+{
+ SetStartLen(s._len);
+ MyStringCopy(_chars, s._chars);
+}
+
+UString &UString::operator=(wchar_t c)
+{
+ if (1 > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = 1;
+ }
+ _len = 1;
+ _chars[0] = c;
+ _chars[1] = 0;
+ return *this;
+}
+
+UString &UString::operator=(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ MyStringCopy(_chars, s);
+ return *this;
+}
+
+UString &UString::operator=(const UString &s)
+{
+ if (&s == this)
+ return *this;
+ unsigned len = s._len;
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ _len = len;
+ MyStringCopy(_chars, s._chars);
+ return *this;
+}
+
+UString &UString::operator+=(const wchar_t *s)
+{
+ unsigned len = MyStringLen(s);
+ Grow(len);
+ MyStringCopy(_chars + _len, s);
+ _len += len;
+ return *this;
+}
+
+UString &UString::operator+=(const UString &s)
+{
+ Grow(s._len);
+ MyStringCopy(_chars + _len, s._chars);
+ _len += s._len;
+ return *this;
+}
+
+void UString::SetFrom(const wchar_t *s, unsigned len) // no check
+{
+ if (len > _limit)
+ {
+ wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1);
+ MY_STRING_DELETE(_chars);
+ _chars = newBuf;
+ _limit = len;
+ }
+ 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] = s[i];
+ chars[len] = 0;
+ _len = len;
+}
+
+void UString::AddAsciiStr(const char *s)
+{
+ unsigned len = MyStringLen(s);
+ Grow(len);
+ wchar_t *chars = _chars + _len;
+ for (unsigned i = 0; i < len; i++)
+ chars[i] = s[i];
+ chars[len] = 0;
+ _len += len;
+}
+
+
+
+int UString::Find(const UString &s, unsigned startIndex) const throw()
+{
+ if (s.IsEmpty())
+ return startIndex;
+ for (; startIndex < _len; startIndex++)
+ {
+ unsigned j;
+ for (j = 0; j < s._len && startIndex + j < _len; j++)
+ if (_chars[startIndex + j] != s._chars[j])
+ break;
+ if (j == s._len)
+ return (int)startIndex;
+ }
+ return -1;
+}
+
+int UString::ReverseFind(wchar_t c) const throw()
+{
+ if (_len == 0)
+ return -1;
+ const wchar_t *p = _chars + _len - 1;
+ for (;;)
+ {
+ if (*p == c)
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p--;
+ }
+}
+
+void UString::TrimLeft() throw()
+{
+ const wchar_t *p = _chars;
+ for (;; p++)
+ {
+ wchar_t c = *p;
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ unsigned pos = (unsigned)(p - _chars);
+ if (pos != 0)
+ {
+ MoveItems(0, pos);
+ _len -= pos;
+ }
+}
+
+void UString::TrimRight() throw()
+{
+ const wchar_t *p = _chars;
+ int i;
+ for (i = _len - 1; i >= 0; i--)
+ {
+ wchar_t c = p[i];
+ if (c != ' ' && c != '\n' && c != '\t')
+ break;
+ }
+ i++;
+ if ((unsigned)i != _len)
+ {
+ _chars[i] = 0;
+ _len = i;
+ }
+}
+
+void UString::InsertAtFront(wchar_t c)
+{
+ if (_limit == _len)
+ Grow_1();
+ MoveItems(1, 0);
+ _chars[0] = c;
+ _len++;
+}
+
+/*
+void UString::Insert(unsigned index, wchar_t c)
+{
+ InsertSpace(index, 1);
+ _chars[index] = c;
+ _len++;
+}
+*/
+
+void UString::Insert(unsigned index, const wchar_t *s)
+{
+ unsigned num = MyStringLen(s);
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ wmemcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void UString::Insert(unsigned index, const UString &s)
+{
+ unsigned num = s.Len();
+ if (num != 0)
+ {
+ InsertSpace(index, num);
+ wmemcpy(_chars + index, s, num);
+ _len += num;
+ }
+}
+
+void UString::RemoveChar(wchar_t ch) throw()
+{
+ int pos = Find(ch);
+ if (pos < 0)
+ return;
+ const wchar_t *src = _chars;
+ wchar_t *dest = _chars + pos;
+ pos++;
+ unsigned len = _len;
+ for (; (unsigned)pos < len; pos++)
+ {
+ wchar_t c = src[(unsigned)pos];
+ if (c != ch)
+ *dest++ = c;
+ }
+ *dest = 0;
+ _len = (unsigned)(dest - _chars);
+}
+
+// !!!!!!!!!!!!!!! test it if newChar = '\0'
+void UString::Replace(wchar_t oldChar, wchar_t newChar) throw()
+{
+ if (oldChar == newChar)
+ return; // 0;
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldChar, pos);
+ if (pos < 0)
+ break;
+ _chars[pos] = newChar;
+ pos++;
+ // number++;
+ }
+ return; // number;
+}
+
+void UString::Replace(const UString &oldString, const UString &newString)
+{
+ if (oldString.IsEmpty())
+ return; // 0;
+ if (oldString == newString)
+ return; // 0;
+ unsigned oldLen = oldString.Len();
+ unsigned newLen = newString.Len();
+ // unsigned number = 0;
+ int pos = 0;
+ while ((unsigned)pos < _len)
+ {
+ pos = Find(oldString, pos);
+ if (pos < 0)
+ break;
+ Delete(pos, oldLen);
+ Insert(pos, newString);
+ pos += newLen;
+ // number++;
+ }
+ // return number;
+}
+
+void UString::Delete(unsigned index) throw()
+{
+ MoveItems(index, index + 1);
+ _len--;
+}
+
+void UString::Delete(unsigned index, unsigned count) throw()
+{
+ if (index + count > _len)
+ count = _len - index;
+ if (count > 0)
+ {
+ MoveItems(index, index + count);
+ _len -= count;
+ }
+}
+
+void UString::DeleteFrontal(unsigned num) throw()
+{
+ if (num != 0)
+ {
+ MoveItems(0, num);
+ _len -= num;
+ }
+}
+
+
+// ----------------------------------------
+
+/*
int MyStringCompareNoCase(const char *s1, const char *s2)
{
return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2));
}
+*/
+static inline UINT GetCurrentCodePage()
+{
+ #if defined(UNDER_CE) || !defined(_WIN32)
+ return CP_ACP;
+ #else
+ return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ #endif
+}
-#ifndef ENV_HAVE_WCHAR__H
+#ifdef USE_UNICODE_FSTRING
-EXTERN_C_BEGIN
+#ifndef _UNICODE
-size_t wcslen(const wchar_t *s)
+AString fs2fas(CFSTR s)
{
- register const wchar_t *p;
-
- for (p=s ; *p ; p++) {}
-
- return p - s;
+ return UnicodeStringToMultiByte(s, GetCurrentCodePage());
}
-wchar_t *wcscpy(wchar_t * s1, const wchar_t * s2)
+FString fas2fs(const AString &s)
{
- register wchar_t *s = s1;
-
- while ( (*s++ = *s2++) != 0 ) {}
-
- return s1;
+ return MultiByteToUnicodeString(s, GetCurrentCodePage());
}
-wchar_t *wcscat(wchar_t * s1, const wchar_t * s2)
+#endif
+
+#else
+
+UString fs2us(const FString &s)
{
- register wchar_t *s = s1;
-
- while (*s++) {}
- --s;
- while ((*s++ = *s2++) != 0) {}
-
- return s1;
+ return MultiByteToUnicodeString((AString)s, GetCurrentCodePage());
}
-EXTERN_C_END
+FString us2fs(const wchar_t *s)
+{
+ return UnicodeStringToMultiByte(s, GetCurrentCodePage());
+}
#endif
diff --git a/src/libs/7zip/unix/CPP/Common/MyString.h b/src/libs/7zip/unix/CPP/Common/MyString.h
index d79b1ce1f..638ceed9b 100644
--- a/src/libs/7zip/unix/CPP/Common/MyString.h
+++ b/src/libs/7zip/unix/CPP/Common/MyString.h
@@ -4,598 +4,522 @@
#define __COMMON_STRING_H
#include <string.h>
-// #include <wchar.h>
+#ifndef _WIN32
+#include <wctype.h>
+#include <wchar.h>
+#endif
+
+#include "MyTypes.h"
#include "MyVector.h"
-LPSTR WINAPI CharNextA( LPCSTR ptr );
-LPSTR WINAPI CharPrevA( LPCSTR start, LPCSTR ptr );
+inline unsigned MyStringLen(const char *s)
+{
+ unsigned i;
+ for (i = 0; s[i] != 0; i++);
+ return i;
+}
+
+inline void MyStringCopy(char *dest, const char *src)
+{
+ while ((*dest++ = *src++) != 0);
+}
+
+inline char *MyStpCpy(char *dest, const char *src)
+{
+ for (;;)
+ {
+ char c = *src;
+ *dest = c;
+ if (c == 0)
+ return dest;
+ src++;
+ dest++;
+ }
+}
-template <class T>
-inline int MyStringLen(const T *s)
+inline unsigned MyStringLen(const wchar_t *s)
{
- int i;
- for (i = 0; s[i] != '\0'; i++) {}
+ unsigned i;
+ for (i = 0; s[i] != 0; i++);
return i;
}
-template <class T>
-inline T * MyStringCopy(T *dest, const T *src)
+inline void MyStringCopy(wchar_t *dest, const wchar_t *src)
{
- T *destStart = dest;
- while ((*dest++ = *src++) != 0) {}
- return destStart;
+ while ((*dest++ = *src++) != 0);
}
-inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
- { return (p + 1); }
-inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
- { return (p + 1); }
-inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
- { return (p - 1); }
-inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
- { return (p - 1); }
-
-wchar_t MyCharUpper(wchar_t c);
-char * MyStringUpper(char *s);
-wchar_t * MyStringUpper(wchar_t *s);
-
-char MyCharLower(char c);
-char * MyStringLower(char *s);
-wchar_t MyCharLower(wchar_t c);
-wchar_t * MyStringLower(wchar_t *s);
-
-
-inline char* MyStringGetPrevCharPointer(char *base, char *p)
- { return CharPrevA(base, p); }
-inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)
- { return CharPrevA(base, p); }
-inline char* MyStringGetNextCharPointer(char *p)
- { return CharNextA(p); }
-inline const char* MyStringGetNextCharPointer(const char *p)
- { return CharNextA(p); }
-
-//////////////////////////////////////
-// Compare
+int FindCharPosInString(const char *s, char c) throw();
+int FindCharPosInString(const wchar_t *s, wchar_t c) throw();
-/*
-#ifndef _WIN32_WCE
-int MyStringCollate(const char *s1, const char *s2);
-int MyStringCollateNoCase(const char *s1, const char *s2);
+#ifdef _WIN32
+ #ifndef _UNICODE
+ #define STRING_UNICODE_THROW
+ #endif
+#endif
+
+#ifndef STRING_UNICODE_THROW
+ #define STRING_UNICODE_THROW throw()
#endif
-int MyStringCollate(const wchar_t *s1, const wchar_t *s2);
-int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);
+
+/*
+inline char MyCharUpper_Ascii(char c)
+{
+ if (c >= 'a' && c <= 'z')
+ return (char)(c - 0x20);
+ return c;
+}
+inline wchar_t MyCharUpper_Ascii(wchar_t c)
+{
+ if (c >= 'a' && c <= 'z')
+ return (wchar_t)(c - 0x20);
+ return c;
+}
*/
-int MyStringCompare(const char *s1, const char *s2);
-int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
+inline char MyCharLower_Ascii(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return (char)(c + 0x20);
+ return c;
+}
+
+inline wchar_t MyCharLower_Ascii(wchar_t c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return (wchar_t)(c + 0x20);
+ return c;
+}
-// int MyStringCompareNoCase(const char *s1, const char *s2);
-int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
+wchar_t MyCharUpper_WIN(wchar_t c) throw();
-template <class T>
-class CStringBase
+inline wchar_t MyCharUpper(wchar_t c) throw()
{
- void TrimLeftWithCharSet(const CStringBase &charSet)
- {
- const T *p = _chars;
- while (charSet.Find(*p) >= 0 && (*p != 0))
- p = GetNextCharPointer(p);
- Delete(0, (int)(p - _chars));
- }
- void TrimRightWithCharSet(const CStringBase &charSet)
- {
- const T *p = _chars;
- const T *pLast = NULL;
- while (*p != 0)
- {
- if (charSet.Find(*p) >= 0)
- {
- if (pLast == NULL)
- pLast = p;
- }
- else
- pLast = NULL;
- p = GetNextCharPointer(p);
- }
- if (pLast != NULL)
- {
- int i = (int)(pLast - _chars);
- Delete(i, _length - i);
- }
+ if (c < 'a') return c;
+ if (c <= 'z') return (wchar_t)(c - 0x20);
+ if (c <= 0x7F) return c;
+ #ifdef _WIN32
+ #ifdef _UNICODE
+ return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
+ #else
+ return (wchar_t)MyCharUpper_WIN(c);
+ #endif
+ #else
+ return (wchar_t)towupper(c);
+ #endif
+}
- }
- void MoveItems(int destIndex, int srcIndex)
- {
- memmove(_chars + destIndex, _chars + srcIndex,
- sizeof(T) * (_length - srcIndex + 1));
- }
-
- void InsertSpace(int &index, int size)
- {
- CorrectIndex(index);
- GrowLength(size);
- MoveItems(index + size, index);
- }
+/*
+wchar_t MyCharLower_WIN(wchar_t c) throw();
- static T *GetNextCharPointer(T *p)
- { return MyStringGetNextCharPointer(p); }
- static const T *GetNextCharPointer(const T *p)
- { return MyStringGetNextCharPointer(p); }
- static T *GetPrevCharPointer(T *base, T *p)
- { return MyStringGetPrevCharPointer(base, p); }
- static const T *GetPrevCharPointer(const T *base, const T *p)
- { return MyStringGetPrevCharPointer(base, p); }
-protected:
- T *_chars;
- int _length;
- int _capacity;
-
- void SetCapacity(int newCapacity)
- {
- int realCapacity = newCapacity + 1;
- if (realCapacity == _capacity)
- return;
- /*
- const int kMaxStringSize = 0x20000000;
- #ifndef _WIN32_WCE
- if (newCapacity > kMaxStringSize || newCapacity < _length)
- throw 1052337;
+inline wchar_t MyCharLower(wchar_t c) throw()
+{
+ if (c < 'A') return c;
+ if (c <= 'Z') return (wchar_t)(c + 0x20);
+ if (c <= 0x7F) return c;
+ #ifdef _WIN32
+ #ifdef _UNICODE
+ return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
+ #else
+ return (wchar_t)MyCharLower_WIN(c);
#endif
- */
- T *newBuffer = new T[realCapacity];
- if (_capacity > 0)
- {
- for (int i = 0; i < _length; i++)
- newBuffer[i] = _chars[i];
- delete []_chars;
- }
- _chars = newBuffer;
- _chars[_length] = 0;
- _capacity = realCapacity;
- }
+ #else
+ return (wchar_t)tolower(c);
+ #endif
+}
+*/
- void GrowLength(int n)
- {
- int freeSize = _capacity - _length - 1;
- if (n <= freeSize)
- return;
- int delta;
- if (_capacity > 64)
- delta = _capacity / 2;
- else if (_capacity > 8)
- delta = 16;
- else
- delta = 4;
- if (freeSize + delta < n)
- delta = n - freeSize;
- SetCapacity(_capacity + delta);
- }
+// char *MyStringUpper(char *s) throw();
+// char *MyStringLower(char *s) throw();
+
+// void MyStringUpper_Ascii(wchar_t *s) throw();
+void MyStringLower_Ascii(wchar_t *s) throw();
+// wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW;
+// wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW;
+
+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();
+
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw();
+int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw();
+
+// ---------- ASCII ----------
+// char values in ASCII strings must be less then 128
+bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw();
+bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw();
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw();
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw();
+
+#define MY_STRING_DELETE(_p_) delete []_p_;
+// #define MY_STRING_DELETE(_p_) my_delete(_p_);
- void CorrectIndex(int &index) const
+class AString
+{
+ char *_chars;
+ unsigned _len;
+ unsigned _limit;
+
+ void MoveItems(unsigned dest, unsigned src)
{
- if (index > _length)
- index = _length;
+ memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char));
}
+ void InsertSpace(unsigned &index, unsigned size);
+
+ void ReAlloc(unsigned newLimit);
+ void SetStartLen(unsigned len);
+ void Grow_1();
+ void Grow(unsigned n);
+
+ // AString(unsigned num, const char *s);
+ AString(unsigned num, const AString &s);
+ AString(const AString &s, char c); // it's for String + char
+ AString(const char *s1, unsigned num1, const char *s2, unsigned num2);
+
+ friend AString operator+(const AString &s, char c) { return AString(s, c); } ;
+ // friend AString operator+(char c, const AString &s); // is not supported
+
+ friend AString operator+(const AString &s1, const AString &s2);
+ friend AString operator+(const AString &s1, const char *s2);
+ friend AString operator+(const char *s1, const AString &s2);
+
public:
- CStringBase(): _chars(0), _length(0), _capacity(0) { SetCapacity(3); }
- CStringBase(T c): _chars(0), _length(0), _capacity(0)
- {
- SetCapacity(1);
- _chars[0] = c;
- _chars[1] = 0;
- _length = 1;
- }
- CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)
- {
- int length = MyStringLen(chars);
- SetCapacity(length);
- MyStringCopy(_chars, chars); // can be optimized by memove()
- _length = length;
- }
- CStringBase(const CStringBase &s): _chars(0), _length(0), _capacity(0)
- {
- SetCapacity(s._length);
- MyStringCopy(_chars, s._chars);
- _length = s._length;
- }
- ~CStringBase() { delete []_chars; }
+ AString();
+ AString(char c);
+ AString(const char *s);
+ AString(const AString &s);
+ ~AString() { MY_STRING_DELETE(_chars); }
+
+ unsigned Len() const { return _len; }
+ bool IsEmpty() const { return _len == 0; }
+ void Empty() { _len = 0; _chars[0] = 0; }
- operator const T*() const { return _chars;}
+ operator const char *() const { return _chars; }
+ const char *Ptr() const { return _chars; }
+ const char *Ptr(unsigned pos) const { return _chars + pos; }
+ const char *RightPtr(unsigned num) const { return _chars + _len - num; }
+ char Back() const { return _chars[_len - 1]; }
- T Back() const { return _chars[_length - 1]; }
+ void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; }
// The minimum size of the character buffer in characters.
// This value does not include space for a null terminator.
- T* GetBuffer(int minBufLength)
+ char *GetBuffer(unsigned minBufLen)
{
- if (minBufLength >= _capacity)
- SetCapacity(minBufLength);
+ if (minBufLen > _limit)
+ ReAlloc(minBufLen);
return _chars;
}
void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
- void ReleaseBuffer(int newLength)
- {
- /*
- #ifndef _WIN32_WCE
- if (newLength >= _capacity)
- throw 282217;
- #endif
- */
- _chars[newLength] = 0;
- _length = newLength;
- }
+ void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
- CStringBase& operator=(T c)
- {
- Empty();
- SetCapacity(1);
- _chars[0] = c;
- _chars[1] = 0;
- _length = 1;
- return *this;
- }
- CStringBase& operator=(const T *chars)
- {
- Empty();
- int length = MyStringLen(chars);
- SetCapacity(length);
- MyStringCopy(_chars, chars);
- _length = length;
- return *this;
- }
- CStringBase& operator=(const CStringBase& s)
- {
- if (&s == this)
- return *this;
- Empty();
- SetCapacity(s._length);
- MyStringCopy(_chars, s._chars);
- _length = s._length;
- return *this;
- }
-
- CStringBase& operator+=(T c)
- {
- GrowLength(1);
- _chars[_length] = c;
- _chars[++_length] = 0;
- return *this;
- }
- CStringBase& operator+=(const T *s)
- {
- int len = MyStringLen(s);
- GrowLength(len);
- MyStringCopy(_chars + _length, s);
- _length += len;
- return *this;
- }
- CStringBase& operator+=(const CStringBase &s)
- {
- GrowLength(s._length);
- MyStringCopy(_chars + _length, s._chars);
- _length += s._length;
- return *this;
- }
- void Empty()
- {
- _length = 0;
- _chars[0] = 0;
- }
- int Length() const { return _length; }
- bool IsEmpty() const { return (_length == 0); }
+ AString &operator=(char c);
+ AString &operator=(const char *s);
+ AString &operator=(const AString &s);
- CStringBase Mid(int startIndex) const
- { return Mid(startIndex, _length - startIndex); }
- CStringBase Mid(int startIndex, int count ) const
- {
- if (startIndex + count > _length)
- count = _length - startIndex;
-
- if (startIndex == 0 && startIndex + count == _length)
- return *this;
-
- CStringBase<T> result;
- result.SetCapacity(count);
- // MyStringNCopy(result._chars, _chars + startIndex, count);
- for (int i = 0; i < count; i++)
- result._chars[i] = _chars[startIndex + i];
- result._chars[count] = 0;
- result._length = count;
- return result;
- }
- CStringBase Left(int count) const
- { return Mid(0, count); }
- CStringBase Right(int count) const
+ AString &operator+=(char c)
{
- if (count > _length)
- count = _length;
- return Mid(_length - count, count);
+ if (_limit == _len)
+ Grow_1();
+ unsigned len = _len;
+ char *chars = _chars;
+ chars[len++] = c;
+ chars[len] = 0;
+ _len = len;
+ return *this;
}
- void MakeUpper()
- { MyStringUpper(_chars); }
- void MakeLower()
- { MyStringLower(_chars); }
-
- int Compare(const CStringBase& s) const
- { return MyStringCompare(_chars, s._chars); }
+ AString &operator+=(const char *s);
+ AString &operator+=(const AString &s);
- int Compare(const T *s) const
- { return MyStringCompare(_chars, s); }
+ void SetFrom(const char *s, unsigned len); // no check
+ // AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
+ AString Left(unsigned count) const { return AString(count, *this); }
- int CompareNoCase(const CStringBase& s) const
- { return MyStringCompareNoCase(_chars, s._chars); }
+ // void MakeUpper() { MyStringUpper(_chars); }
+ // void MakeLower() { MyStringLower(_chars); }
- int CompareNoCase(const T *s) const
- { return MyStringCompareNoCase(_chars, s); }
- /*
- int Collate(const CStringBase& s) const
- { return MyStringCollate(_chars, s._chars); }
- int CollateNoCase(const CStringBase& s) const
- { return MyStringCollateNoCase(_chars, s._chars); }
- */
+ // int Compare(const char *s) const { return MyStringCompare(_chars, s); }
+ // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); }
+ // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); }
+ // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
+ bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); }
+ bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
- int Find(T c) const { return Find(c, 0); }
- int Find(T c, int startIndex) const
+ int Find(char c) const { return FindCharPosInString(_chars, c); }
+ int Find(char c, unsigned startIndex) const
{
- T *p = _chars + startIndex;
- for (;;)
- {
- if (*p == c)
- return (int)(p - _chars);
- if (*p == 0)
- return -1;
- p = GetNextCharPointer(p);
- }
+ int pos = FindCharPosInString(_chars + startIndex, c);
+ return pos < 0 ? -1 : (int)startIndex + pos;
}
- int Find(const CStringBase &s) const { return Find(s, 0); }
- int Find(const CStringBase &s, int startIndex) const
+ int ReverseFind(char c) const throw();
+ int Find(const AString &s) const { return Find(s, 0); }
+ int Find(const AString &s, unsigned startIndex) const throw();
+
+ void TrimLeft() throw();
+ void TrimRight() throw();
+ void Trim()
{
- if (s.IsEmpty())
- return startIndex;
- for (; startIndex < _length; startIndex++)
- {
- int j;
- for (j = 0; j < s._length && startIndex + j < _length; j++)
- if (_chars[startIndex+j] != s._chars[j])
- break;
- if (j == s._length)
- return startIndex;
- }
- return -1;
+ TrimRight();
+ TrimLeft();
}
- int ReverseFind(T c) const
+
+ void InsertAtFront(char c);
+ // void Insert(unsigned index, char c);
+ void Insert(unsigned index, const char *s);
+ void Insert(unsigned index, const AString &s);
+
+ void RemoveChar(char ch) throw();
+ void Replace(char oldChar, char newChar) throw();
+ void Replace(const AString &oldString, const AString &newString);
+
+ void Delete(unsigned index) throw();
+ void Delete(unsigned index, unsigned count) throw();
+ void DeleteFrontal(unsigned num) throw();
+ void DeleteBack() { _chars[--_len] = 0; }
+ void DeleteFrom(unsigned index)
{
- if (_length == 0)
- return -1;
- T *p = _chars + _length - 1;
- for (;;)
+ if (index < _len)
{
- if (*p == c)
- return (int)(p - _chars);
- if (p == _chars)
- return -1;
- p = GetPrevCharPointer(_chars, p);
+ _len = index;
+ _chars[index] = 0;
}
}
- int FindOneOf(const CStringBase &s) const
- {
- for (int i = 0; i < _length; i++)
- if (s.Find(_chars[i]) >= 0)
- return i;
- return -1;
- }
+};
- void TrimLeft(T c)
- {
- const T *p = _chars;
- while (c == *p)
- p = GetNextCharPointer(p);
- Delete(0, p - _chars);
- }
- private:
- CStringBase GetTrimDefaultCharSet()
+bool operator<(const AString &s1, const AString &s2);
+bool operator>(const AString &s1, const AString &s2);
+
+/*
+bool operator==(const AString &s1, const AString &s2);
+bool operator==(const AString &s1, const char *s2);
+bool operator==(const char *s1, const AString &s2);
+
+bool operator!=(const AString &s1, const AString &s2);
+bool operator!=(const AString &s1, const char *s2);
+bool operator!=(const char *s1, const AString &s2);
+*/
+
+inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; }
+inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; }
+inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; }
+
+inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; }
+inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; }
+inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; }
+
+
+
+class UString
+{
+ wchar_t *_chars;
+ unsigned _len;
+ unsigned _limit;
+
+ void MoveItems(unsigned dest, unsigned src)
{
- CStringBase<T> charSet;
- charSet += (T)' ';
- charSet += (T)'\n';
- charSet += (T)'\t';
- return charSet;
+ memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t));
}
- public:
- void TrimLeft()
+ void InsertSpace(unsigned index, unsigned size);
+
+ void ReAlloc(unsigned newLimit);
+ void SetStartLen(unsigned len);
+ void Grow_1();
+ void Grow(unsigned n);
+
+ UString(unsigned num, const wchar_t *s); // for Mid
+ UString(unsigned num, const UString &s); // for Left
+ UString(const UString &s, wchar_t c); // it's for String + char
+ UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2);
+
+ friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ;
+ // friend UString operator+(wchar_t c, const UString &s); // is not supported
+
+ friend UString operator+(const UString &s1, const UString &s2);
+ friend UString operator+(const UString &s1, const wchar_t *s2);
+ friend UString operator+(const wchar_t *s1, const UString &s2);
+
+public:
+ UString();
+ UString(wchar_t c);
+ UString(const wchar_t *s);
+ UString(const UString &s);
+ ~UString() { MY_STRING_DELETE(_chars); }
+
+ unsigned Len() const { return _len; }
+ bool IsEmpty() const { return _len == 0; }
+ void Empty() { _len = 0; _chars[0] = 0; }
+
+ operator const wchar_t *() const { return _chars; }
+ const wchar_t *Ptr() const { return _chars; }
+ const wchar_t *Ptr(unsigned pos) const { return _chars + pos; }
+ const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; }
+ wchar_t Back() const { return _chars[_len - 1]; }
+
+ void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
+
+ // The minimum size of the character buffer in characters.
+ // This value does not include space for a null terminator.
+ wchar_t *GetBuffer(unsigned minBufLen)
{
- TrimLeftWithCharSet(GetTrimDefaultCharSet());
+ if (minBufLen > _limit)
+ ReAlloc(minBufLen);
+ return _chars;
}
- void TrimRight()
+ void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
+ void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
+
+ UString &operator=(wchar_t c);
+ UString &operator=(const wchar_t *s);
+ UString &operator=(const UString &s);
+
+ UString &operator+=(wchar_t c)
{
- TrimRightWithCharSet(GetTrimDefaultCharSet());
+ if (_limit == _len)
+ Grow_1();
+ unsigned len = _len;
+ wchar_t *chars = _chars;
+ chars[len++] = c;
+ chars[len] = 0;
+ _len = len;
+ return *this;
}
- void TrimRight(T c)
+
+ UString &operator+=(const wchar_t *s);
+ UString &operator+=(const UString &s);
+
+ void SetFrom(const wchar_t *s, unsigned len); // no check
+
+ void SetFromAscii(const char *s);
+ void AddAsciiStr(const char *s);
+
+ UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); }
+ UString Left(unsigned count) const { return UString(count, *this); }
+
+ // void MakeUpper() { MyStringUpper(_chars); }
+ // void MakeUpper() { MyStringUpper_Ascii(_chars); }
+ // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); }
+ void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
+
+ bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); }
+ bool IsEqualToNoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); }
+ int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
+ // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); }
+ // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); }
+ // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
+ bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); };
+ bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
+
+ int Find(wchar_t c) const { return FindCharPosInString(_chars, c); }
+ int Find(wchar_t c, unsigned startIndex) const
{
- const T *p = _chars;
- const T *pLast = NULL;
- while (*p != 0)
- {
- if (*p == c)
- {
- if (pLast == NULL)
- pLast = p;
- }
- else
- pLast = NULL;
- p = GetNextCharPointer(p);
- }
- if (pLast != NULL)
- {
- int i = pLast - _chars;
- Delete(i, _length - i);
- }
+ int pos = FindCharPosInString(_chars + startIndex, c);
+ return pos < 0 ? -1 : (int)startIndex + pos;
}
+ int Find(const UString &s) const { return Find(s, 0); }
+ int Find(const UString &s, unsigned startIndex) const throw();
+ int ReverseFind(wchar_t c) const throw();
+
+ void TrimLeft() throw();
+ void TrimRight() throw();
void Trim()
{
TrimRight();
TrimLeft();
}
- int Insert(int index, T c)
- {
- InsertSpace(index, 1);
- _chars[index] = c;
- _length++;
- return _length;
- }
- int Insert(int index, const CStringBase &s)
- {
- CorrectIndex(index);
- if (s.IsEmpty())
- return _length;
- int numInsertChars = s.Length();
- InsertSpace(index, numInsertChars);
- for (int i = 0; i < numInsertChars; i++)
- _chars[index + i] = s[i];
- _length += numInsertChars;
- return _length;
- }
+ void InsertAtFront(wchar_t c);
+ // void Insert(unsigned index, wchar_t c);
+ void Insert(unsigned index, const wchar_t *s);
+ void Insert(unsigned index, const UString &s);
- // !!!!!!!!!!!!!!! test it if newChar = '\0'
- int Replace(T oldChar, T newChar)
- {
- if (oldChar == newChar)
- return 0;
- int number = 0;
- int pos = 0;
- while (pos < Length())
- {
- pos = Find(oldChar, pos);
- if (pos < 0)
- break;
- _chars[pos] = newChar;
- pos++;
- number++;
- }
- return number;
- }
- int Replace(const CStringBase &oldString, const CStringBase &newString)
- {
- if (oldString.IsEmpty())
- return 0;
- if (oldString == newString)
- return 0;
- int oldStringLength = oldString.Length();
- int newStringLength = newString.Length();
- int number = 0;
- int pos = 0;
- while (pos < _length)
- {
- pos = Find(oldString, pos);
- if (pos < 0)
- break;
- Delete(pos, oldStringLength);
- Insert(pos, newString);
- pos += newStringLength;
- number++;
- }
- return number;
- }
- int Delete(int index, int count = 1 )
+ void RemoveChar(wchar_t ch) throw();
+ void Replace(wchar_t oldChar, wchar_t newChar) throw();
+ void Replace(const UString &oldString, const UString &newString);
+
+ void Delete(unsigned index) throw();
+ void Delete(unsigned index, unsigned count) throw();
+ void DeleteFrontal(unsigned num) throw();
+ void DeleteBack() { _chars[--_len] = 0; }
+ void DeleteFrom(unsigned index)
{
- if (index + count > _length)
- count = _length - index;
- if (count > 0)
+ if (index < _len)
{
- MoveItems(index, index + count);
- _length -= count;
+ _len = index;
+ _chars[index] = 0;
}
- return _length;
}
- void DeleteBack() { Delete(_length - 1); }
};
-template <class T>
-CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
-{
- CStringBase<T> result(s1);
- result += s2;
- return result;
-}
+bool operator<(const UString &s1, const UString &s2);
+bool operator>(const UString &s1, const UString &s2);
-template <class T>
-CStringBase<T> operator+(const CStringBase<T>& s, T c)
-{
- CStringBase<T> result(s);
- result += c;
- return result;
-}
+inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; }
+inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; }
+inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; }
-template <class T>
-CStringBase<T> operator+(T c, const CStringBase<T>& s)
-{
- CStringBase<T> result(c);
- result += s;
- return result;
-}
+inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; }
+inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; }
+inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; }
-template <class T>
-CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)
-{
- CStringBase<T> result(s);
- result += chars;
- return result;
-}
-template <class T>
-CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)
-{
- CStringBase<T> result(chars);
- result += s;
- return result;
-}
+typedef CObjectVector<AString> AStringVector;
+typedef CObjectVector<UString> UStringVector;
-template <class T>
-bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)
- { return (s1.Compare(s2) == 0); }
+#ifdef _UNICODE
+ typedef UString CSysString;
+#else
+ typedef AString CSysString;
+#endif
-template <class T>
-bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)
- { return (s1.Compare(s2) < 0); }
+typedef CObjectVector<CSysString> CSysStringVector;
-template <class T>
-bool operator==(const T *s1, const CStringBase<T>& s2)
- { return (s2.Compare(s1) == 0); }
-template <class T>
-bool operator==(const CStringBase<T>& s1, const T *s2)
- { return (s1.Compare(s2) == 0); }
+// ---------- FString ----------
-template <class T>
-bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)
- { return (s1.Compare(s2) != 0); }
+// #ifdef _WIN32
+ #define USE_UNICODE_FSTRING
+// #endif
-template <class T>
-bool operator!=(const T *s1, const CStringBase<T>& s2)
- { return (s2.Compare(s1) != 0); }
+#ifdef USE_UNICODE_FSTRING
-template <class T>
-bool operator!=(const CStringBase<T>& s1, const T *s2)
- { return (s1.Compare(s2) != 0); }
+ #define __FTEXT(quote) L##quote
-typedef CStringBase<char> AString;
-typedef CStringBase<wchar_t> UString;
+ typedef wchar_t FChar;
+ typedef UString FString;
-typedef CObjectVector<AString> AStringVector;
-typedef CObjectVector<UString> UStringVector;
+ #define fs2us(_x_) (_x_)
+ #define us2fs(_x_) (_x_)
+ FString fas2fs(const AString &s);
+ AString fs2fas(const FChar *s);
-#ifdef _UNICODE
- typedef UString CSysString;
#else
- typedef AString CSysString;
+
+ #define __FTEXT(quote) quote
+
+ typedef char FChar;
+ typedef AString FString;
+
+ UString fs2us(const FString &s);
+ FString us2fs(const wchar_t *s);
+ #define fas2fs(_x_) (_x_)
+ #define fs2fas(_x_) (_x_)
+
#endif
-typedef CObjectVector<CSysString> CSysStringVector;
+#define FTEXT(quote) __FTEXT(quote)
+
+#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("*")
+typedef const FChar *CFSTR;
+
+typedef CObjectVector<FString> FStringVector;
#endif
diff --git a/src/libs/7zip/unix/CPP/Common/MyTypes.h b/src/libs/7zip/unix/CPP/Common/MyTypes.h
new file mode 100644
index 000000000..fe41188db
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/Common/MyTypes.h
@@ -0,0 +1,32 @@
+// Common/MyTypes.h
+
+#ifndef __COMMON_MY_TYPES_H
+#define __COMMON_MY_TYPES_H
+
+#include "../../C/7zTypes.h"
+
+typedef int HRes;
+
+#ifdef __cplusplus
+struct CBoolPair
+{
+ bool Val;
+ bool Def;
+
+ CBoolPair(): Val(false), Def(false) {}
+
+ void Init()
+ {
+ Val = false;
+ Def = false;
+ }
+
+ void SetTrueTrue()
+ {
+ Val = true;
+ Def = true;
+ }
+};
+#endif
+
+#endif
diff --git a/src/libs/7zip/unix/CPP/Common/MyUnknown.h b/src/libs/7zip/unix/CPP/Common/MyUnknown.h
index e9e8666b9..8b95afd38 100644
--- a/src/libs/7zip/unix/CPP/Common/MyUnknown.h
+++ b/src/libs/7zip/unix/CPP/Common/MyUnknown.h
@@ -9,5 +9,5 @@
#else
#include "MyWindows.h"
#endif
-
+
#endif
diff --git a/src/libs/7zip/unix/CPP/Common/MyVector.cpp b/src/libs/7zip/unix/CPP/Common/MyVector.cpp
deleted file mode 100644
index 3b5317688..000000000
--- a/src/libs/7zip/unix/CPP/Common/MyVector.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-// Common/MyVector.cpp
-
-#include "StdAfx.h"
-
-#include <string.h>
-
-#include "MyVector.h"
-
-CBaseRecordVector::~CBaseRecordVector() { ClearAndFree(); }
-
-void CBaseRecordVector::ClearAndFree()
-{
- Clear();
- delete []((unsigned char *)_items);
- _capacity = 0;
- _size = 0;
- _items = 0;
-}
-
-void CBaseRecordVector::Clear() { DeleteFrom(0); }
-void CBaseRecordVector::DeleteBack() { Delete(_size - 1); }
-void CBaseRecordVector::DeleteFrom(int index) { Delete(index, _size - index); }
-
-void CBaseRecordVector::ReserveOnePosition()
-{
- if (_size != _capacity)
- return;
- unsigned delta = 1;
- if (_capacity >= 64)
- delta = (unsigned)_capacity / 4;
- else if (_capacity >= 8)
- delta = 8;
- Reserve(_capacity + (int)delta);
-}
-
-void CBaseRecordVector::Reserve(int newCapacity)
-{
- // if (newCapacity <= _capacity)
- if (newCapacity == _capacity)
- return;
- if ((unsigned)newCapacity >= ((unsigned)1 << (sizeof(unsigned) * 8 - 1)))
- throw 1052353;
- size_t newSize = (size_t)(unsigned)newCapacity * _itemSize;
- if (newSize / _itemSize != (size_t)(unsigned)newCapacity)
- throw 1052354;
- unsigned char *p = NULL;
- if (newSize > 0)
- {
- p = new unsigned char[newSize];
- if (p == 0)
- throw 1052355;
- int numRecordsToMove = (_size < newCapacity ? _size : newCapacity);
- memcpy(p, _items, _itemSize * numRecordsToMove);
- }
- delete [](unsigned char *)_items;
- _items = p;
- _capacity = newCapacity;
-}
-
-void CBaseRecordVector::ReserveDown()
-{
- Reserve(_size);
-}
-
-void CBaseRecordVector::MoveItems(int destIndex, int srcIndex)
-{
- memmove(((unsigned char *)_items) + destIndex * _itemSize,
- ((unsigned char *)_items) + srcIndex * _itemSize,
- _itemSize * (_size - srcIndex));
-}
-
-void CBaseRecordVector::InsertOneItem(int index)
-{
- ReserveOnePosition();
- MoveItems(index + 1, index);
- _size++;
-}
-
-void CBaseRecordVector::Delete(int index, int num)
-{
- TestIndexAndCorrectNum(index, num);
- if (num > 0)
- {
- MoveItems(index, index + num);
- _size -= num;
- }
-}
diff --git a/src/libs/7zip/unix/CPP/Common/MyVector.h b/src/libs/7zip/unix/CPP/Common/MyVector.h
index 781b648bc..7e61dec31 100644
--- a/src/libs/7zip/unix/CPP/Common/MyVector.h
+++ b/src/libs/7zip/unix/CPP/Common/MyVector.h
@@ -1,92 +1,247 @@
-// Common/Vector.h
+// Common/MyVector.h
-#ifndef __COMMON_VECTOR_H
-#define __COMMON_VECTOR_H
-
-#include "Defs.h"
-
-class CBaseRecordVector
-{
- void MoveItems(int destIndex, int srcIndex);
-protected:
- int _capacity;
- int _size;
- void *_items;
- size_t _itemSize;
-
- void ReserveOnePosition();
- void InsertOneItem(int index);
- void TestIndexAndCorrectNum(int index, int &num) const
- { if (index + num > _size) num = _size - index; }
-public:
- CBaseRecordVector(size_t itemSize): _capacity(0), _size(0), _items(0), _itemSize(itemSize) {}
- virtual ~CBaseRecordVector();
- void ClearAndFree();
- int Size() const { return _size; }
- bool IsEmpty() const { return (_size == 0); }
- void Reserve(int newCapacity);
- void ReserveDown();
- virtual void Delete(int index, int num = 1);
- void Clear();
- void DeleteFrom(int index);
- void DeleteBack();
-};
+#ifndef __COMMON_MY_VECTOR_H
+#define __COMMON_MY_VECTOR_H
template <class T>
-class CRecordVector: public CBaseRecordVector
+class CRecordVector
{
+ T *_items;
+ unsigned _size;
+ unsigned _capacity;
+
+ void MoveItems(unsigned destIndex, unsigned srcIndex)
+ {
+ memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * (size_t)sizeof(T));
+ }
+
+ void ReserveOnePosition()
+ {
+ if (_size == _capacity)
+ {
+ unsigned newCapacity = _capacity + (_capacity >> 2) + 1;
+ T *p = new T[newCapacity];
+ memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newCapacity;
+ }
+ }
+
public:
- CRecordVector(): CBaseRecordVector(sizeof(T)){};
- CRecordVector(const CRecordVector &v): CBaseRecordVector(sizeof(T)) { *this = v; }
- CRecordVector& operator=(const CRecordVector &v)
+
+ CRecordVector(): _items(0), _size(0), _capacity(0) {}
+
+ CRecordVector(const CRecordVector &v): _items(0), _size(0), _capacity(0)
+ {
+ unsigned size = v.Size();
+ if (size != 0)
+ {
+ _items = new T[size];
+ _size = size;
+ _capacity = size;
+ memcpy(_items, v._items, (size_t)size * (size_t)sizeof(T));
+ }
+ }
+
+ unsigned Size() const { return _size; }
+ bool IsEmpty() const { return _size == 0; }
+
+ void ConstructReserve(unsigned size)
+ {
+ if (size != 0)
+ {
+ _items = new T[size];
+ _capacity = size;
+ }
+ }
+
+ void Reserve(unsigned newCapacity)
+ {
+ if (newCapacity > _capacity)
+ {
+ T *p = new T[newCapacity];
+ memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newCapacity;
+ }
+ }
+
+ void ClearAndReserve(unsigned newCapacity)
{
Clear();
- return (*this += v);
+ if (newCapacity > _capacity)
+ {
+ delete []_items;
+ _items = NULL;
+ _capacity = 0;
+ _items = new T[newCapacity];
+ _capacity = newCapacity;
+ }
+ }
+
+ void ClearAndSetSize(unsigned newSize)
+ {
+ ClearAndReserve(newSize);
+ _size = newSize;
}
+
+ void ChangeSize_KeepData(unsigned newSize)
+ {
+ if (newSize > _capacity)
+ {
+ T *p = new T[newSize];
+ memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newSize;
+ }
+ _size = newSize;
+ }
+
+ void ReserveDown()
+ {
+ if (_size == _capacity)
+ return;
+ T *p = NULL;
+ if (_size != 0)
+ {
+ p = new T[_size];
+ memcpy(p, _items, (size_t)_size * (size_t)sizeof(T));
+ }
+ delete []_items;
+ _items = p;
+ _capacity = _size;
+ }
+
+ ~CRecordVector() { delete []_items; }
+
+ void ClearAndFree()
+ {
+ delete []_items;
+ _items = NULL;
+ _size = 0;
+ _capacity = 0;
+ }
+
+ void Clear() { _size = 0; }
+
+ void DeleteBack() { _size--; }
+
+ void DeleteFrom(unsigned index)
+ {
+ // if (index <= _size)
+ _size = index;
+ }
+
+ void DeleteFrontal(unsigned num)
+ {
+ if (num != 0)
+ {
+ MoveItems(0, num);
+ _size -= num;
+ }
+ }
+
+ void Delete(unsigned index)
+ {
+ MoveItems(index, index + 1);
+ _size -= 1;
+ }
+
+ /*
+ void Delete(unsigned index, unsigned num)
+ {
+ if (num > 0)
+ {
+ MoveItems(index, index + num);
+ _size -= num;
+ }
+ }
+ */
+
+ CRecordVector& operator=(const CRecordVector &v)
+ {
+ unsigned size = v.Size();
+ if (size > _capacity)
+ {
+ delete []_items;
+ _capacity = 0;
+ _size = 0;
+ _items = NULL;
+ _items = new T[size];
+ _capacity = size;
+ }
+ _size = size;
+ memcpy(_items, v._items, (size_t)size * (size_t)sizeof(T));
+ return *this;
+ }
+
CRecordVector& operator+=(const CRecordVector &v)
{
- int size = v.Size();
- Reserve(Size() + size);
- for (int i = 0; i < size; i++)
- Add(v[i]);
+ unsigned size = v.Size();
+ Reserve(_size + size);
+ memcpy(_items + _size, v._items, (size_t)size * (size_t)sizeof(T));
+ _size += size;
return *this;
}
- int Add(T item)
+
+ unsigned Add(const T item)
{
ReserveOnePosition();
- ((T *)_items)[_size] = item;
+ _items[_size] = item;
return _size++;
}
- void Insert(int index, T item)
+
+ void AddInReserved(const T item)
{
- InsertOneItem(index);
- ((T *)_items)[index] = item;
+ _items[_size++] = item;
}
- // T* GetPointer() const { return (T*)_items; }
- // operator const T *() const { return _items; };
- const T& operator[](int index) const { return ((T *)_items)[index]; }
- T& operator[](int index) { return ((T *)_items)[index]; }
- const T& Front() const { return operator[](0); }
- T& Front() { return operator[](0); }
- const T& Back() const { return operator[](_size - 1); }
- T& Back() { return operator[](_size - 1); }
- void Swap(int i, int j)
+ void Insert(unsigned index, const T item)
{
- T temp = operator[](i);
- operator[](i) = operator[](j);
- operator[](j) = temp;
+ ReserveOnePosition();
+ MoveItems(index + 1, index);
+ _items[index] = item;
+ _size++;
}
- int FindInSorted(const T& item, int left, int right) const
+ void MoveToFront(unsigned index)
+ {
+ if (index != 0)
+ {
+ T temp = _items[index];
+ memmove(_items + 1, _items, (size_t)index * (size_t)sizeof(T));
+ _items[0] = temp;
+ }
+ }
+
+ const T& operator[](unsigned index) const { return _items[index]; }
+ T& operator[](unsigned index) { return _items[index]; }
+ const T& Front() const { return _items[0]; }
+ T& Front() { return _items[0]; }
+ const T& Back() const { return _items[_size - 1]; }
+ T& Back() { return _items[_size - 1]; }
+
+ /*
+ void Swap(unsigned i, unsigned j)
+ {
+ T temp = _items[i];
+ _items[i] = _items[j];
+ _items[j] = temp;
+ }
+ */
+
+ int FindInSorted(const T item, unsigned left, unsigned right) const
{
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T midVal = (*this)[mid];
+ if (item == midVal)
return mid;
- if (item < midValue)
+ if (item < midVal)
right = mid;
else
left = mid + 1;
@@ -94,16 +249,16 @@ public:
return -1;
}
- int FindInSorted(const T& item) const
+ int FindInSorted2(const T &item, unsigned left, unsigned right) const
{
- int left = 0, right = Size();
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
return mid;
- if (item < midValue)
+ if (comp < 0)
right = mid;
else
left = mid + 1;
@@ -111,16 +266,26 @@ public:
return -1;
}
- int AddToUniqueSorted(const T& item)
+ int FindInSorted(const T item) const
+ {
+ return FindInSorted(item, 0, _size);
+ }
+
+ int FindInSorted2(const T &item) const
+ {
+ return FindInSorted2(item, 0, _size);
+ }
+
+ unsigned AddToUniqueSorted(const T item)
{
- int left = 0, right = Size();
+ unsigned left = 0, right = _size;
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T midVal = (*this)[mid];
+ if (item == midVal)
return mid;
- if (item < midValue)
+ if (item < midVal)
right = mid;
else
left = mid + 1;
@@ -129,12 +294,31 @@ public:
return right;
}
- static void SortRefDown(T* p, int k, int size, int (*compare)(const T*, const T*, void *), void *param)
+ unsigned AddToUniqueSorted2(const T &item)
+ {
+ unsigned left = 0, right = _size;
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
+ return mid;
+ if (comp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+
+ static void SortRefDown(T* p, unsigned k, unsigned size, int (*compare)(const T*, const T*, void *), void *param)
{
T temp = p[k];
for (;;)
{
- int s = (k << 1);
+ unsigned s = (k << 1);
if (s > size)
break;
if (s < size && compare(p + s + 1, p + s, param) > 0)
@@ -149,12 +333,12 @@ public:
void Sort(int (*compare)(const T*, const T*, void *), void *param)
{
- int size = _size;
+ unsigned size = _size;
if (size <= 1)
return;
T* p = (&Front()) - 1;
{
- int i = size / 2;
+ unsigned i = size >> 1;
do
SortRefDown(p, i, size, compare, param);
while (--i != 0);
@@ -168,6 +352,46 @@ public:
}
while (size > 1);
}
+
+ static void SortRefDown2(T* p, unsigned k, unsigned size)
+ {
+ T temp = p[k];
+ for (;;)
+ {
+ unsigned s = (k << 1);
+ if (s > size)
+ break;
+ if (s < size && p[s + 1].Compare(p[s]) > 0)
+ s++;
+ if (temp.Compare(p[s]) >= 0)
+ break;
+ p[k] = p[s];
+ k = s;
+ }
+ p[k] = temp;
+ }
+
+ void Sort2()
+ {
+ unsigned size = _size;
+ if (size <= 1)
+ return;
+ T* p = (&Front()) - 1;
+ {
+ unsigned i = size >> 1;
+ do
+ SortRefDown2(p, i, size);
+ while (--i != 0);
+ }
+ do
+ {
+ T temp = p[size];
+ p[size--] = p[1];
+ p[1] = temp;
+ SortRefDown2(p, 1, size);
+ }
+ while (size > 1);
+ }
};
typedef CRecordVector<int> CIntVector;
@@ -177,76 +401,197 @@ typedef CRecordVector<unsigned char> CByteVector;
typedef CRecordVector<void *> CPointerVector;
template <class T>
-class CObjectVector: public CPointerVector
+class CObjectVector
{
+ CPointerVector _v;
public:
+ unsigned Size() const { return _v.Size(); }
+ bool IsEmpty() const { return _v.IsEmpty(); }
+ void ReserveDown() { _v.ReserveDown(); }
+ // void Reserve(unsigned newCapacity) { _v.Reserve(newCapacity); }
+ void ClearAndReserve(unsigned newCapacity) { Clear(); _v.ClearAndReserve(newCapacity); }
+
CObjectVector() {};
- ~CObjectVector() { Clear(); };
- CObjectVector(const CObjectVector &v): CPointerVector() { *this = v; }
+ CObjectVector(const CObjectVector &v)
+ {
+ unsigned size = v.Size();
+ _v.ConstructReserve(size);
+ for (unsigned i = 0; i < size; i++)
+ _v.AddInReserved(new T(v[i]));
+ }
CObjectVector& operator=(const CObjectVector &v)
{
Clear();
- return (*this += v);
+ unsigned size = v.Size();
+ _v.Reserve(size);
+ for (unsigned i = 0; i < size; i++)
+ _v.AddInReserved(new T(v[i]));
+ return *this;
}
+
CObjectVector& operator+=(const CObjectVector &v)
{
- int size = v.Size();
- Reserve(Size() + size);
- for (int i = 0; i < size; i++)
- Add(v[i]);
+ unsigned size = v.Size();
+ _v.Reserve(Size() + size);
+ for (unsigned i = 0; i < size; i++)
+ _v.AddInReserved(new T(v[i]));
return *this;
}
- const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); }
- T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); }
- T& Front() { return operator[](0); }
+
+ const T& operator[](unsigned index) const { return *((T *)_v[index]); }
+ T& operator[](unsigned index) { return *((T *)_v[index]); }
const T& Front() const { return operator[](0); }
- T& Back() { return operator[](_size - 1); }
- const T& Back() const { return operator[](_size - 1); }
- int Add(const T& item) { return CPointerVector::Add(new T(item)); }
- void Insert(int index, const T& item) { CPointerVector::Insert(index, new T(item)); }
- virtual void Delete(int index, int num = 1)
+ T& Front() { return operator[](0); }
+ const T& Back() const { return operator[](_v.Size() - 1); }
+ T& Back() { return operator[](_v.Size() - 1); }
+
+ void MoveToFront(unsigned index) { _v.MoveToFront(index); }
+
+ unsigned Add(const T& item) { return _v.Add(new T(item)); }
+
+ void AddInReserved(const T& item) { _v.AddInReserved(new T(item)); }
+
+ T& AddNew()
+ {
+ T *p = new T;
+ _v.Add(p);
+ return *p;
+ }
+
+ T& AddNewInReserved()
+ {
+ T *p = new T;
+ _v.AddInReserved(p);
+ return *p;
+ }
+
+ void Insert(unsigned index, const T& item) { _v.Insert(index, new T(item)); }
+
+ T& InsertNew(unsigned index)
+ {
+ T *p = new T;
+ _v.Insert(index, p);
+ return *p;
+ }
+
+ ~CObjectVector()
+ {
+ for (unsigned i = _v.Size(); i != 0;)
+ delete (T *)_v[--i];
+ }
+
+ void ClearAndFree()
+ {
+ Clear();
+ _v.ClearAndFree();
+ }
+
+ void Clear()
+ {
+ for (unsigned i = _v.Size(); i != 0;)
+ delete (T *)_v[--i];
+ _v.Clear();
+ }
+
+ void DeleteFrom(unsigned index)
+ {
+ unsigned size = _v.Size();
+ for (unsigned i = index; i < size; i++)
+ delete (T *)_v[i];
+ _v.DeleteFrom(index);
+ }
+
+ void DeleteFrontal(unsigned num)
+ {
+ for (unsigned i = 0; i < num; i++)
+ delete (T *)_v[i];
+ _v.DeleteFrontal(num);
+ }
+
+ void DeleteBack()
{
- TestIndexAndCorrectNum(index, num);
- for (int i = 0; i < num; i++)
- delete (T *)(((void **)_items)[index + i]);
- CPointerVector::Delete(index, num);
+ delete (T *)_v[_v.Size() - 1];
+ _v.DeleteBack();
}
+
+ void Delete(unsigned index)
+ {
+ delete (T *)_v[index];
+ _v.Delete(index);
+ }
+
+ /*
+ void Delete(unsigned index, unsigned num)
+ {
+ for (unsigned i = 0; i < num; i++)
+ delete (T *)_v[index + i];
+ _v.Delete(index, num);
+ }
+ */
+
+ /*
int Find(const T& item) const
{
- for (int i = 0; i < Size(); i++)
+ unsigned size = Size();
+ for (unsigned i = 0; i < size; i++)
if (item == (*this)[i])
return i;
return -1;
}
+ */
+
int FindInSorted(const T& item) const
{
- int left = 0, right = Size();
+ unsigned left = 0, right = Size();
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
return mid;
- if (item < midValue)
+ if (comp < 0)
right = mid;
else
left = mid + 1;
}
return -1;
}
- int AddToSorted(const T& item)
+
+ unsigned AddToUniqueSorted(const T& item)
{
- int left = 0, right = Size();
+ unsigned left = 0, right = Size();
while (left != right)
{
- int mid = (left + right) / 2;
- const T& midValue = (*this)[mid];
- if (item == midValue)
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
+ return mid;
+ if (comp < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+
+ /*
+ unsigned AddToSorted(const T& item)
+ {
+ unsigned left = 0, right = Size();
+ while (left != right)
+ {
+ unsigned mid = (left + right) / 2;
+ const T& midVal = (*this)[mid];
+ int comp = item.Compare(midVal);
+ if (comp == 0)
{
right = mid + 1;
break;
}
- if (item < midValue)
+ if (comp < 0)
right = mid;
else
left = mid + 1;
@@ -254,13 +599,17 @@ public:
Insert(right, item);
return right;
}
+ */
void Sort(int (*compare)(void *const *, void *const *, void *), void *param)
- { CPointerVector::Sort(compare, param); }
+ { _v.Sort(compare, param); }
static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */)
- { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); }
- void Sort() { CPointerVector::Sort(CompareObjectItems, 0); }
+ { return (*(*((const T **)a1))).Compare(*(*((const T **)a2))); }
+
+ void Sort() { _v.Sort(CompareObjectItems, 0); }
};
+#define FOR_VECTOR(_i_, _v_) for (unsigned _i_ = 0; _i_ < (_v_).Size(); _i_++)
+
#endif
diff --git a/src/libs/7zip/unix/CPP/Common/MyWindows.cpp b/src/libs/7zip/unix/CPP/Common/MyWindows.cpp
index 4037d5ea3..9acddc974 100644
--- a/src/libs/7zip/unix/CPP/Common/MyWindows.cpp
+++ b/src/libs/7zip/unix/CPP/Common/MyWindows.cpp
@@ -5,16 +5,16 @@
#ifndef _WIN32
#include "MyWindows.h"
-#include "Types.h"
+#include "MyTypes.h"
#include <stdlib.h> /* FIXED <malloc.h> */
static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); }
static inline void FreeForBSTR(void *pv) { ::free(pv);}
static UINT MyStringLen(const wchar_t *s)
-{
+{
UINT i;
- for (i = 0; s[i] != '\0'; i++) {}
+ for (i = 0; s[i] != '\0'; i++);
return i;
}
@@ -35,6 +35,21 @@ BSTR SysAllocStringByteLen(LPCSTR psz, UINT len)
return (BSTR)bstr;
}
+BSTR WINAPI SysAllocStringLen(const OLECHAR *sz, unsigned int numChars) // FIXME - code
+{
+ UINT len = (numChars + 1) * sizeof(OLECHAR);
+ void *p = AllocateForBSTR(len + sizeof(UINT));
+ if (p == 0)
+ return 0;
+ memset(p,0,len + sizeof(UINT));
+ *(UINT *)p = numChars * sizeof(OLECHAR); // FIXED
+ void * bstr = (void *)((UINT *)p + 1);
+ if (sz) memmove(bstr, sz, numChars * sizeof(OLECHAR)); // sz does not always have "wchar_t" alignment.
+
+ return (BSTR)bstr;
+}
+
+
BSTR SysAllocString(const OLECHAR *sz)
{
if (sz == 0)
@@ -84,7 +99,7 @@ HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src)
return res;
if (src->vt == VT_BSTR)
{
- dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal,
+ dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal,
SysStringByteLen(src->bstrVal));
if (dest->bstrVal == 0)
return E_OUTOFMEMORY;
diff --git a/src/libs/7zip/unix/CPP/Common/MyWindows.h b/src/libs/7zip/unix/CPP/Common/MyWindows.h
index d91f10f1b..3376dd6aa 100644
--- a/src/libs/7zip/unix/CPP/Common/MyWindows.h
+++ b/src/libs/7zip/unix/CPP/Common/MyWindows.h
@@ -190,12 +190,20 @@ typedef PROPVARIANT tagVARIANT;
typedef tagVARIANT VARIANT;
typedef VARIANT VARIANTARG;
+#define MY_EXTERN_C extern "C"
+
MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
+#else
+
+#define MY_EXTERN_C extern
+
+
#endif
MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
+MY_EXTERN_C BSTR SysAllocStringLen(const OLECHAR*,UINT);
MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
MY_EXTERN_C void SysFreeString(BSTR bstr);
MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
diff --git a/src/libs/7zip/unix/CPP/Common/NewHandler.cpp b/src/libs/7zip/unix/CPP/Common/NewHandler.cpp
new file mode 100644
index 000000000..e53f1d14d
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/Common/NewHandler.cpp
@@ -0,0 +1,32 @@
+// NewHandler.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/Alloc.h"
+
+
+
+/* An overload function for the C++ new */
+void * operator new(size_t size)
+{
+ return MyAlloc(size);
+}
+
+/* An overload function for the C++ new[] */
+void * operator new[](size_t size)
+{
+ return MyAlloc(size);
+}
+
+/* An overload function for the C++ delete */
+void operator delete(void *pnt)
+{
+ MyFree(pnt);
+}
+
+/* An overload function for the C++ delete[] */
+void operator delete[](void *pnt)
+{
+ MyFree(pnt);
+}
+
diff --git a/src/libs/7zip/unix/CPP/Common/NewHandler.h b/src/libs/7zip/unix/CPP/Common/NewHandler.h
index 215ba05f1..e3e7422c8 100644
--- a/src/libs/7zip/unix/CPP/Common/NewHandler.h
+++ b/src/libs/7zip/unix/CPP/Common/NewHandler.h
@@ -1,16 +1,68 @@
// Common/NewHandler.h
-#ifndef __COMMON_NEWHANDLER_H
-#define __COMMON_NEWHANDLER_H
+#ifndef __COMMON_NEW_HANDLER_H
+#define __COMMON_NEW_HANDLER_H
+
+/*
+This file must be included before any code that uses operators "delete" or "new".
+Also you must compile and link "NewHandler.cpp", if you use MSVC 6.0.
+The operator "new" in MSVC 6.0 doesn't throw exception "bad_alloc".
+So we define another version of operator "new" that throws "CNewException" on failure.
+
+If you use compiler that throws exception in "new" operator (GCC or new version of MSVC),
+you can compile without "NewHandler.cpp". So standard exception "bad_alloc" will be used.
+
+It's still allowed to use redefined version of operator "new" from "NewHandler.cpp"
+with any compiler. 7-Zip's code can work with "bad_alloc" and "CNewException" exceptions.
+But if you use some additional code (outside of 7-Zip's code), you must check
+that redefined version of operator "new" (that throws CNewException) is not
+problem for your code.
+
+Also we declare delete(void *p) throw() that creates smaller code.
+*/
+
class CNewException {};
+#ifdef WIN32
+// We can compile my_new and my_delete with _fastcall
+/*
+void * my_new(size_t size);
+void my_delete(void *p) throw();
+// void * my_Realloc(void *p, size_t newSize, size_t oldSize);
+*/
+#endif
+
#ifdef _WIN32
+
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new(size_t size);
+
void
#ifdef _MSC_VER
__cdecl
#endif
operator delete(void *p) throw();
+
+#endif
+
+/*
+#ifdef _WIN32
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new[](size_t size);
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete[](void *p) throw();
#endif
+*/
#endif
diff --git a/src/libs/7zip/unix/CPP/Common/StdInStream.cpp b/src/libs/7zip/unix/CPP/Common/StdInStream.cpp
deleted file mode 100644
index 78897e5ef..000000000
--- a/src/libs/7zip/unix/CPP/Common/StdInStream.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-// Common/StdInStream.cpp
-
-#include "StdAfx.h"
-
-#include <tchar.h>
-#include "StdInStream.h"
-
-#ifdef _MSC_VER
-// "was declared deprecated" disabling
-#pragma warning(disable : 4996 )
-#endif
-
-#ifdef _UNICODE
-#include "Common/StringConvert.h"
-#define NEED_NAME_WINDOWS_TO_UNIX
-#include "myPrivate.h"
-#endif
-
-static const char kIllegalChar = '\0';
-static const char kNewLineChar = '\n';
-
-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 const char * kFileOpenMode = "r";
-
-CStdInStream g_StdIn(stdin);
-
-bool CStdInStream::Open(LPCTSTR fileName)
-{
- Close();
-#ifdef _UNICODE
- AString aStr = UnicodeStringToMultiByte(fileName, CP_ACP); // FIXME
- const char * name = nameWindowToUnix(aStr);
-#else
- const char * name = nameWindowToUnix(fileName);
-#endif
- _stream = fopen(name, kFileOpenMode);
- _streamIsOpen = (_stream != 0);
- return _streamIsOpen;
-}
-
-bool CStdInStream::Close()
-{
- if (!_streamIsOpen)
- return true;
- _streamIsOpen = (fclose(_stream) != 0);
- return !_streamIsOpen;
-}
-
-CStdInStream::~CStdInStream()
-{
- Close();
-}
-
-AString CStdInStream::ScanStringUntilNewLine(bool allowEOF)
-{
- AString s;
- for (;;)
- {
- int intChar = GetChar();
- if (intChar == EOF)
- {
- if (allowEOF)
- break;
- throw kEOFMessage;
- }
- char c = char(intChar);
- if (c == kIllegalChar)
- throw kIllegalCharMessage;
- if (c == kNewLineChar)
- break;
- s += c;
- }
- return s;
-}
-
-void CStdInStream::ReadToString(AString &resultString)
-{
- resultString.Empty();
- int c;
- while ((c = GetChar()) != EOF)
- resultString += char(c);
-}
-
-bool CStdInStream::Eof()
-{
- return (feof(_stream) != 0);
-}
-
-int CStdInStream::GetChar()
-{
- int c = fgetc(_stream); // getc() doesn't work in BeOS?
- if (c == EOF && !Eof())
- throw kReadErrorMessage;
- return c;
-}
-
-
diff --git a/src/libs/7zip/unix/CPP/Common/StdInStream.h b/src/libs/7zip/unix/CPP/Common/StdInStream.h
deleted file mode 100644
index 0d182cc3c..000000000
--- a/src/libs/7zip/unix/CPP/Common/StdInStream.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Common/StdInStream.h
-
-#ifndef __COMMON_STDINSTREAM_H
-#define __COMMON_STDINSTREAM_H
-
-#include <stdio.h>
-
-#include "MyString.h"
-#include "Types.h"
-
-class CStdInStream
-{
- bool _streamIsOpen;
- FILE *_stream;
-public:
- CStdInStream(): _streamIsOpen(false) {};
- CStdInStream(FILE *stream): _streamIsOpen(false), _stream(stream) {};
- ~CStdInStream();
- bool Open(LPCTSTR fileName);
- bool Close();
-
- AString ScanStringUntilNewLine(bool allowEOF = false);
- void ReadToString(AString &resultString);
- UString ScanUStringUntilNewLine();
-
- bool Eof();
- int GetChar();
-};
-
-extern CStdInStream g_StdIn;
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/Common/StdOutStream.cpp b/src/libs/7zip/unix/CPP/Common/StdOutStream.cpp
index b93e255f9..6aed31a31 100644
--- a/src/libs/7zip/unix/CPP/Common/StdOutStream.cpp
+++ b/src/libs/7zip/unix/CPP/Common/StdOutStream.cpp
@@ -4,23 +4,21 @@
#include <tchar.h>
-#include "StdOutStream.h"
#include "IntToString.h"
+#include "StdOutStream.h"
#include "StringConvert.h"
-
-#ifdef _MSC_VER
-// "was declared deprecated" disabling
-#pragma warning(disable : 4996 )
-#endif
+#include "UTFConvert.h"
static const char kNewLineChar = '\n';
static const char *kFileOpenMode = "wt";
-CStdOutStream g_StdOut(stdout);
-CStdOutStream g_StdErr(stderr);
+extern int g_CodePage;
+
+CStdOutStream g_StdOut(stdout);
+CStdOutStream g_StdErr(stderr);
-bool CStdOutStream::Open(const char *fileName)
+bool CStdOutStream::Open(const char *fileName) throw()
{
Close();
_stream = fopen(fileName, kFileOpenMode);
@@ -28,7 +26,7 @@ bool CStdOutStream::Open(const char *fileName)
return _streamIsOpen;
}
-bool CStdOutStream::Close()
+bool CStdOutStream::Close() throw()
{
if (!_streamIsOpen)
return true;
@@ -39,55 +37,70 @@ bool CStdOutStream::Close()
return true;
}
-bool CStdOutStream::Flush()
+bool CStdOutStream::Flush() throw()
{
return (fflush(_stream) == 0);
}
-CStdOutStream::~CStdOutStream ()
+CStdOutStream & endl(CStdOutStream & outStream) throw()
{
- Close();
+ return outStream << kNewLineChar;
}
-CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*aFunction)(CStdOutStream &))
+CStdOutStream & CStdOutStream::operator<<(const wchar_t *s)
{
- (*aFunction)(*this);
- return *this;
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ AString dest;
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8(s, dest);
+ else
+ UnicodeStringToMultiByte2(dest, s, (UINT)codePage);
+ return operator<<((const char *)dest);
}
-CStdOutStream & endl(CStdOutStream & outStream)
+void StdOut_Convert_UString_to_AString(const UString &s, AString &temp)
{
- return outStream << kNewLineChar;
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8(s, temp);
+ else
+ UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
}
-CStdOutStream & CStdOutStream::operator<<(const char *string)
+void CStdOutStream::PrintUString(const UString &s, AString &temp)
{
- fputs(string, _stream);
- return *this;
+ StdOut_Convert_UString_to_AString(s, temp);
+ *this << (const char *)temp;
}
-CStdOutStream & CStdOutStream::operator<<(const wchar_t *string)
+CStdOutStream & CStdOutStream::operator<<(Int32 number) throw()
{
- *this << (const char *)UnicodeStringToMultiByte(string, CP_OEMCP);
- return *this;
+ char s[32];
+ ConvertInt64ToString(number, s);
+ return operator<<(s);
}
-CStdOutStream & CStdOutStream::operator<<(char c)
+CStdOutStream & CStdOutStream::operator<<(Int64 number) throw()
{
- fputc(c, _stream);
- return *this;
+ char s[32];
+ ConvertInt64ToString(number, s);
+ return operator<<(s);
}
-CStdOutStream & CStdOutStream::operator<<(int number)
+CStdOutStream & CStdOutStream::operator<<(UInt32 number) throw()
{
- char textString[32];
- ConvertInt64ToString(number, textString);
- return operator<<(textString);
+ char s[16];
+ ConvertUInt32ToString(number, s);
+ return operator<<(s);
}
-CStdOutStream & CStdOutStream::operator<<(UInt64 number)
+CStdOutStream & CStdOutStream::operator<<(UInt64 number) throw()
{
- char textString[32];
- ConvertUInt64ToString(number, textString);
- return operator<<(textString);
+ char s[32];
+ ConvertUInt64ToString(number, s);
+ return operator<<(s);
}
diff --git a/src/libs/7zip/unix/CPP/Common/StdOutStream.h b/src/libs/7zip/unix/CPP/Common/StdOutStream.h
index b0b2c615c..0a8c0febb 100644
--- a/src/libs/7zip/unix/CPP/Common/StdOutStream.h
+++ b/src/libs/7zip/unix/CPP/Common/StdOutStream.h
@@ -1,35 +1,62 @@
// Common/StdOutStream.h
-#ifndef __COMMON_STDOUTSTREAM_H
-#define __COMMON_STDOUTSTREAM_H
+#ifndef __COMMON_STD_OUT_STREAM_H
+#define __COMMON_STD_OUT_STREAM_H
#include <stdio.h>
-#include "Types.h"
+#include "MyString.h"
+#include "MyTypes.h"
class CStdOutStream
{
- bool _streamIsOpen;
FILE *_stream;
+ bool _streamIsOpen;
public:
- CStdOutStream (): _streamIsOpen(false), _stream(0) {};
- CStdOutStream (FILE *stream): _streamIsOpen(false), _stream(stream) {};
- ~CStdOutStream ();
+ CStdOutStream(): _stream(0), _streamIsOpen(false) {};
+ CStdOutStream(FILE *stream): _stream(stream), _streamIsOpen(false) {};
+ ~CStdOutStream() { Close(); }
+
+ // void AttachStdStream(FILE *stream) { _stream = stream; _streamIsOpen = false; }
+ // bool IsDefined() const { return _stream != NULL; }
+
operator FILE *() { return _stream; }
- bool Open(const char *fileName);
- bool Close();
- bool Flush();
- CStdOutStream & operator<<(CStdOutStream & (* aFunction)(CStdOutStream &));
- CStdOutStream & operator<<(const char *string);
- CStdOutStream & operator<<(const wchar_t *string);
- CStdOutStream & operator<<(char c);
- CStdOutStream & operator<<(int number);
- CStdOutStream & operator<<(UInt64 number);
+ bool Open(const char *fileName) throw();
+ bool Close() throw();
+ bool Flush() throw();
+
+ CStdOutStream & operator<<(CStdOutStream & (* func)(CStdOutStream &))
+ {
+ (*func)(*this);
+ return *this;
+ }
+
+ CStdOutStream & operator<<(const char *s) throw()
+ {
+ fputs(s, _stream);
+ return *this;
+ }
+
+ CStdOutStream & operator<<(char c) throw()
+ {
+ fputc(c, _stream);
+ return *this;
+ }
+
+ CStdOutStream & operator<<(Int32 number) throw();
+ CStdOutStream & operator<<(Int64 number) throw();
+ CStdOutStream & operator<<(UInt32 number) throw();
+ CStdOutStream & operator<<(UInt64 number) throw();
+
+ CStdOutStream & operator<<(const wchar_t *s);
+ void PrintUString(const UString &s, AString &temp);
};
-CStdOutStream & endl(CStdOutStream & outStream);
+CStdOutStream & endl(CStdOutStream & outStream) throw();
extern CStdOutStream g_StdOut;
extern CStdOutStream g_StdErr;
+void StdOut_Convert_UString_to_AString(const UString &s, AString &temp);
+
#endif
diff --git a/src/libs/7zip/unix/CPP/Common/StringConvert.cpp b/src/libs/7zip/unix/CPP/Common/StringConvert.cpp
index dc7dc2669..78f3d90ef 100644
--- a/src/libs/7zip/unix/CPP/Common/StringConvert.cpp
+++ b/src/libs/7zip/unix/CPP/Common/StringConvert.cpp
@@ -1,7 +1,6 @@
// Common/StringConvert.cpp
#include "StdAfx.h"
-#include <stdlib.h>
#include "StringConvert.h"
extern "C"
@@ -9,7 +8,6 @@ extern "C"
int global_use_utf16_conversion = 0;
}
-
#ifdef LOCALE_IS_UTF8
#ifdef __APPLE_CC__
@@ -34,20 +32,20 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
CFMutableStringRef cfpath2 = CFStringCreateMutableCopy(NULL,0,cfpath);
CFRelease(cfpath);
CFStringNormalize(cfpath2,kCFStringNormalizationFormC);
-
+
size_t n = CFStringGetLength(cfpath2);
for(size_t i = 0 ; i< n ;i++) {
resultString += CFStringGetCharacterAtIndex(cfpath2,i);
}
- CFRelease(cfpath2);
+ CFRelease(cfpath2);
return resultString;
}
}
UString resultString;
- for (int i = 0; i < srcString.Length(); i++)
+ for (int i = 0; i < srcString.Len(); i++)
resultString += wchar_t(srcString[i] & 255);
return resultString;
@@ -72,16 +70,16 @@ AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
CFMutableStringRef cfpath2 = CFStringCreateMutableCopy(NULL,0,cfpath);
CFRelease(cfpath);
CFStringNormalize(cfpath2,kCFStringNormalizationFormD);
-
+
CFStringGetCString(cfpath2,(char *)utf8,4096,kCFStringEncodingUTF8);
- CFRelease(cfpath2);
+ CFRelease(cfpath2);
return AString(utf8);
}
AString resultString;
- for (int i = 0; i < srcString.Length(); i++)
+ for (int i = 0; i < srcString.Len(); i++)
{
if (srcString[i] >= 256) resultString += '?';
else resultString += char(srcString[i]);
@@ -104,7 +102,7 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
}
UString resultString;
- for (int i = 0; i < srcString.Length(); i++)
+ for (int i = 0; i < srcString.Len(); i++)
resultString += wchar_t(srcString[i] & 255);
return resultString;
@@ -120,7 +118,7 @@ AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
}
AString resultString;
- for (int i = 0; i < srcString.Length(); i++)
+ for (int i = 0; i < srcString.Len(); i++)
{
if (srcString[i] >= 256) resultString += '?';
else resultString += char(srcString[i]);
@@ -138,28 +136,55 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT /* codePage */ )
if ((global_use_utf16_conversion) && (!srcString.IsEmpty()))
{
UString resultString;
- int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()),srcString,srcString.Length()+1);
+ int numChars = mbstowcs(resultString.GetBuffer(srcString.Len()),srcString,srcString.Len()+1);
if (numChars >= 0) {
- resultString.ReleaseBuffer(numChars);
+ resultString.ReleaseBuffer(numChars);
+
+#if WCHAR_MAX > 0xffff
+ for (int i = numChars; i >= 0; i--) {
+ if (resultString[i] > 0xffff) {
+ wchar_t c = resultString[i] - 0x10000;
+ resultString.Delete(i);
+ resultString.Insert(i, ((c >> 10) & 0x3ff) + 0xd800);
+ resultString.Insert(i + 1, (c & 0x3ff) + 0xdc00);
+ numChars++;
+ }
+ }
+#endif
+
return resultString;
}
}
#endif
UString resultString;
- for (int i = 0; i < srcString.Length(); i++)
+ for (int i = 0; i < srcString.Len(); i++)
resultString += wchar_t(srcString[i] & 255);
return resultString;
}
-AString UnicodeStringToMultiByte(const UString &srcString, UINT /* codePage */ )
+AString UnicodeStringToMultiByte(const UString &src, UINT /* codePage */ )
{
#ifdef ENV_HAVE_WCSTOMBS
+#if WCHAR_MAX > 0xffff
+ UString srcString(src);
+ for (int i = 0; i < srcString.Len(); i++) {
+ if ((0xd800 <= srcString[i] && srcString[i] <= 0xdbff) && ((i + 1) < srcString.Len()) &&
+ (0xdc00 <= srcString[i + 1] && srcString[i + 1] <= 0xdf00)) {
+ wchar_t c = (((srcString[i] - 0xd800) << 10) | (srcString[i + 1] - 0xdc00)) + 0x10000;
+ srcString.Delete(i, 2);
+ srcString.Insert(i, c);
+ }
+ }
+#else
+ UString &srcString = src;
+#endif
+
if ((global_use_utf16_conversion) && (!srcString.IsEmpty()))
{
AString resultString;
- int numRequiredBytes = srcString.Length() * 6+1;
+ int numRequiredBytes = srcString.Len() * 6+1;
int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes),srcString,numRequiredBytes);
if (numChars >= 0) {
resultString.ReleaseBuffer(numChars);
@@ -169,7 +194,7 @@ AString UnicodeStringToMultiByte(const UString &srcString, UINT /* codePage */ )
#endif
AString resultString;
- for (int i = 0; i < srcString.Length(); i++)
+ for (int i = 0; i < srcString.Len(); i++)
{
if (srcString[i] >= 256) resultString += '?';
else resultString += char(srcString[i]);
@@ -179,3 +204,14 @@ AString UnicodeStringToMultiByte(const UString &srcString, UINT /* codePage */ )
#endif /* LOCALE_IS_UTF8 */
+
+void MultiByteToUnicodeString2(UString &dest, const AString &srcString, UINT codePage)
+{
+ dest = MultiByteToUnicodeString(srcString,codePage);
+}
+
+void UnicodeStringToMultiByte2(AString &dest, const UString &srcString, UINT codePage)
+{
+ dest = UnicodeStringToMultiByte(srcString,codePage);
+}
+
diff --git a/src/libs/7zip/unix/CPP/Common/StringConvert.h b/src/libs/7zip/unix/CPP/Common/StringConvert.h
index cd737becb..8eea72ef2 100644
--- a/src/libs/7zip/unix/CPP/Common/StringConvert.h
+++ b/src/libs/7zip/unix/CPP/Common/StringConvert.h
@@ -3,15 +3,19 @@
#ifndef __COMMON_STRING_CONVERT_H
#define __COMMON_STRING_CONVERT_H
-#include "MyWindows.h"
#include "MyString.h"
-#include "Types.h"
+#include "MyWindows.h"
UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP);
+
+// optimized versions that work faster for ASCII strings
+void MultiByteToUnicodeString2(UString &dest, const AString &srcString, UINT codePage = CP_ACP);
+void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
+void UnicodeStringToMultiByte2(AString &dest, const UString &srcString, UINT codePage);
+
AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage, char defaultChar, bool &defaultCharWasUsed);
AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP);
-
inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString)
{ return unicodeString; }
inline const UString& GetUnicodeString(const UString &unicodeString)
diff --git a/src/libs/7zip/unix/CPP/Common/StringToInt.cpp b/src/libs/7zip/unix/CPP/Common/StringToInt.cpp
index 9473766bc..2023fcc2c 100644
--- a/src/libs/7zip/unix/CPP/Common/StringToInt.cpp
+++ b/src/libs/7zip/unix/CPP/Common/StringToInt.cpp
@@ -4,87 +4,141 @@
#include "StringToInt.h"
-UInt64 ConvertStringToUInt64(const char *s, const char **end)
+static const UInt32 k_UInt32_max = 0xFFFFFFFF;
+static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF);
+// static const UInt64 k_UInt64_max = (UInt64)(Int64)-1;
+
+#define CONVERT_STRING_TO_UINT_FUNC(uintType, charType) \
+ uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \
+ if (end) *end = s; \
+ uintType res = 0; \
+ for (;; s++) { \
+ charType c = *s; \
+ if (c < '0' || c > '9') { if (end) *end = s; return res; } \
+ if (res > (k_ ## uintType ## _max) / 10) return 0; \
+ res *= 10; \
+ unsigned v = (c - '0'); \
+ if (res > (k_ ## uintType ## _max) - v) return 0; \
+ res += v; }}
+
+CONVERT_STRING_TO_UINT_FUNC(UInt32, char)
+CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t)
+CONVERT_STRING_TO_UINT_FUNC(UInt64, char)
+CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t)
+
+Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw()
+{
+ if (end)
+ *end = s;
+ const wchar_t *s2 = s;
+ if (*s == '-')
+ s2++;
+ if (*s2 == 0)
+ return 0;
+ const wchar_t *end2;
+ UInt32 res = ConvertStringToUInt32(s2, &end2);
+ if (*s == '-')
+ {
+ if (res > ((UInt32)1 << (32 - 1)))
+ return 0;
+ }
+ else if ((res & ((UInt32)1 << (32 - 1))) != 0)
+ return 0;
+ if (end)
+ *end = end2;
+ if (*s == '-')
+ return -(Int32)res;
+ return (Int32)res;
+}
+
+UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw()
{
- UInt64 result = 0;
- for (;;)
+ if (end)
+ *end = s;
+ UInt32 res = 0;
+ for (;; s++)
{
char c = *s;
- if (c < '0' || c > '9')
+ if (c < '0' || c > '7')
{
- if (end != NULL)
+ if (end)
*end = s;
- return result;
+ return res;
}
- result *= 10;
- result += (c - '0');
- s++;
+ if ((res & (UInt32)7 << (32 - 3)) != 0)
+ return 0;
+ res <<= 3;
+ res |= (unsigned)(c - '0');
}
}
-UInt64 ConvertOctStringToUInt64(const char *s, const char **end)
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw()
{
- UInt64 result = 0;
- for (;;)
+ if (end)
+ *end = s;
+ UInt64 res = 0;
+ for (;; s++)
{
char c = *s;
if (c < '0' || c > '7')
{
- if (end != NULL)
+ if (end)
*end = s;
- return result;
+ return res;
}
- result <<= 3;
- result += (c - '0');
- s++;
+ if ((res & (UInt64)7 << (64 - 3)) != 0)
+ return 0;
+ res <<= 3;
+ res |= (unsigned)(c - '0');
}
}
-UInt64 ConvertHexStringToUInt64(const char *s, const char **end)
+UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw()
{
- UInt64 result = 0;
- for (;;)
+ if (end)
+ *end = s;
+ UInt32 res = 0;
+ for (;; s++)
{
char c = *s;
- UInt32 v;
+ unsigned v;
if (c >= '0' && c <= '9') v = (c - '0');
else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
else
{
- if (end != NULL)
+ if (end)
*end = s;
- return result;
+ return res;
}
- result <<= 4;
- result |= v;
- s++;
+ if ((res & (UInt32)0xF << (32 - 4)) != 0)
+ return 0;
+ res <<= 4;
+ res |= v;
}
}
-
-UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end)
+UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw()
{
- UInt64 result = 0;
- for (;;)
+ if (end)
+ *end = s;
+ UInt64 res = 0;
+ for (;; s++)
{
- wchar_t c = *s;
- if (c < '0' || c > '9')
+ char c = *s;
+ unsigned v;
+ if (c >= '0' && c <= '9') v = (c - '0');
+ else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
+ else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
+ else
{
- if (end != NULL)
+ if (end)
*end = s;
- return result;
+ return res;
}
- result *= 10;
- result += (c - '0');
- s++;
+ if ((res & (UInt64)0xF << (64 - 4)) != 0)
+ return 0;
+ res <<= 4;
+ res |= v;
}
}
-
-
-Int64 ConvertStringToInt64(const char *s, const char **end)
-{
- if (*s == '-')
- return -(Int64)ConvertStringToUInt64(s + 1, end);
- return ConvertStringToUInt64(s, end);
-}
diff --git a/src/libs/7zip/unix/CPP/Common/StringToInt.h b/src/libs/7zip/unix/CPP/Common/StringToInt.h
index c0d860eff..5c5d7d7fe 100644
--- a/src/libs/7zip/unix/CPP/Common/StringToInt.h
+++ b/src/libs/7zip/unix/CPP/Common/StringToInt.h
@@ -1,18 +1,21 @@
// Common/StringToInt.h
-#ifndef __COMMON_STRINGTOINT_H
-#define __COMMON_STRINGTOINT_H
+#ifndef __COMMON_STRING_TO_INT_H
+#define __COMMON_STRING_TO_INT_H
-#include <string.h>
-#include "Types.h"
+#include "MyTypes.h"
-UInt64 ConvertStringToUInt64(const char *s, const char **end);
-UInt64 ConvertOctStringToUInt64(const char *s, const char **end);
-UInt64 ConvertHexStringToUInt64(const char *s, const char **end);
-UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end);
+UInt32 ConvertStringToUInt32(const char *s, const char **end) throw();
+UInt64 ConvertStringToUInt64(const char *s, const char **end) throw();
+UInt32 ConvertStringToUInt32(const wchar_t *s, const wchar_t **end) throw();
+UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) throw();
-Int64 ConvertStringToInt64(const char *s, const char **end);
+Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw();
-#endif
+UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw();
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw();
+UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw();
+UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw();
+#endif
diff --git a/src/libs/7zip/unix/CPP/Common/Types.h b/src/libs/7zip/unix/CPP/Common/Types.h
deleted file mode 100644
index 9365b327f..000000000
--- a/src/libs/7zip/unix/CPP/Common/Types.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Common/Types.h
-
-#ifndef __COMMON_TYPES_H
-#define __COMMON_TYPES_H
-
-#include "../../C/Types.h"
-
-typedef int HRes;
-
-#endif
-
diff --git a/src/libs/7zip/unix/CPP/Common/UTFConvert.cpp b/src/libs/7zip/unix/CPP/Common/UTFConvert.cpp
index 95362430a..38bac3331 100644
--- a/src/libs/7zip/unix/CPP/Common/UTFConvert.cpp
+++ b/src/libs/7zip/unix/CPP/Common/UTFConvert.cpp
@@ -2,18 +2,53 @@
#include "StdAfx.h"
+#include "MyTypes.h"
#include "UTFConvert.h"
-#include "Types.h"
static const Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
-static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_t srcLen)
+bool CheckUTF8(const char *src) throw()
+{
+ for (;;)
+ {
+ Byte c;
+ unsigned numAdds;
+ c = *src++;
+ if (c == 0)
+ return true;
+
+ if (c < 0x80)
+ continue;
+ if (c < 0xC0)
+ return false;
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (c < kUtf8Limits[numAdds])
+ break;
+ UInt32 value = (c - kUtf8Limits[numAdds - 1]);
+
+ do
+ {
+ Byte c2 = *src++;
+ if (c2 < 0x80 || c2 >= 0xC0)
+ return false;
+ value <<= 6;
+ value |= (c2 - 0x80);
+ }
+ while (--numAdds);
+
+ if (value >= 0x110000)
+ return false;
+ }
+}
+
+
+static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_t srcLen) throw()
{
size_t destPos = 0, srcPos = 0;
for (;;)
{
Byte c;
- int numAdds;
+ unsigned numAdds;
if (srcPos == srcLen)
{
*destLen = destPos;
@@ -46,8 +81,8 @@ static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_
value <<= 6;
value |= (c2 - 0x80);
}
- while (--numAdds != 0);
-
+ while (--numAdds);
+
if (value < 0x10000)
{
if (dest)
@@ -124,11 +159,9 @@ bool ConvertUTF8ToUnicode(const AString &src, UString &dest)
{
dest.Empty();
size_t destLen = 0;
- Utf8_To_Utf16(NULL, &destLen, src, src.Length());
- wchar_t *p = dest.GetBuffer((int)destLen);
- Bool res = Utf8_To_Utf16(p, &destLen, src, src.Length());
- p[destLen] = 0;
- dest.ReleaseBuffer();
+ Utf8_To_Utf16(NULL, &destLen, src, src.Len());
+ Bool res = Utf8_To_Utf16(dest.GetBuffer((unsigned)destLen), &destLen, src, src.Len());
+ dest.ReleaseBuffer((unsigned)destLen);
return res ? true : false;
}
@@ -136,10 +169,8 @@ bool ConvertUnicodeToUTF8(const UString &src, AString &dest)
{
dest.Empty();
size_t destLen = 0;
- Utf16_To_Utf8(NULL, &destLen, src, src.Length());
- char *p = dest.GetBuffer((int)destLen);
- Bool res = Utf16_To_Utf8(p, &destLen, src, src.Length());
- p[destLen] = 0;
- dest.ReleaseBuffer();
+ Utf16_To_Utf8(NULL, &destLen, src, src.Len());
+ Bool res = Utf16_To_Utf8(dest.GetBuffer((unsigned)destLen), &destLen, src, src.Len());
+ dest.ReleaseBuffer((unsigned)destLen);
return res ? true : false;
}
diff --git a/src/libs/7zip/unix/CPP/Common/UTFConvert.h b/src/libs/7zip/unix/CPP/Common/UTFConvert.h
index 2a14600d9..16b02fe45 100644
--- a/src/libs/7zip/unix/CPP/Common/UTFConvert.h
+++ b/src/libs/7zip/unix/CPP/Common/UTFConvert.h
@@ -1,10 +1,11 @@
// Common/UTFConvert.h
-#ifndef __COMMON_UTFCONVERT_H
-#define __COMMON_UTFCONVERT_H
+#ifndef __COMMON_UTF_CONVERT_H
+#define __COMMON_UTF_CONVERT_H
#include "MyString.h"
+bool CheckUTF8(const char *src) throw();
bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString);
bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
diff --git a/src/libs/7zip/unix/CPP/Common/Wildcard.cpp b/src/libs/7zip/unix/CPP/Common/Wildcard.cpp
index 476ddebde..e88a1cf1c 100644
--- a/src/libs/7zip/unix/CPP/Common/Wildcard.cpp
+++ b/src/libs/7zip/unix/CPP/Common/Wildcard.cpp
@@ -2,8 +2,6 @@
#include "StdAfx.h"
-#include "../../C/Types.h"
-
#include "Wildcard.h"
bool g_CaseSensitive =
@@ -13,37 +11,43 @@ bool g_CaseSensitive =
true;
#endif
-static const wchar_t kAnyCharsChar = L'*';
-static const wchar_t kAnyCharChar = L'?';
-
-#ifdef _WIN32
-static const wchar_t kDirDelimiter1 = L'\\';
-#endif
-static const wchar_t kDirDelimiter2 = L'/';
-
-static const UString kWildCardCharSet = L"?*";
-static const UString kIllegalWildCardFileNameChars=
- L"\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF"
- L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
- L"\"/:<>\\|";
+bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2)
+{
+ if (g_CaseSensitive)
+ {
+ for (;;)
+ {
+ wchar_t c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++;
+ if (MyCharUpper(c1) !=
+ MyCharUpper(c2))
+ return false;
+ }
+ }
+ for (;;)
+ {
+ wchar_t c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++; if (c1 != c2) return false;
+ }
+}
-static inline bool IsCharDirLimiter(wchar_t c)
+int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW
{
- return (
- #ifdef _WIN32
- c == kDirDelimiter1 ||
- #endif
- c == kDirDelimiter2);
+ if (g_CaseSensitive)
+ return wcscmp(s1, s2);
+ return MyStringCompareNoCase(s1, s2);
}
-int CompareFileNames(const UString &s1, const UString &s2)
+#ifndef USE_UNICODE_FSTRING
+int CompareFileNames(const char *s1, const char *s2)
{
if (g_CaseSensitive)
- return s1.Compare(s2);
- return s1.CompareNoCase(s2);
+ return wcscmp(fs2us(s1), fs2us(s2));
+ return MyStringCompareNoCase(fs2us(s1), fs2us(s2));
}
+#endif
// -----------------------------------------
// this function compares name with mask
@@ -58,7 +62,7 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
wchar_t c = *name;
if (m == 0)
return (c == 0);
- if (m == kAnyCharsChar)
+ if (m == '*')
{
if (EnhancedMaskTest(mask + 1, name))
return true;
@@ -67,7 +71,7 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
}
else
{
- if (m == kAnyCharChar)
+ if (m == '?')
{
if (c == 0)
return false;
@@ -87,61 +91,84 @@ static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
void SplitPathToParts(const UString &path, UStringVector &pathParts)
{
pathParts.Clear();
- UString name;
- int len = path.Length();
+ unsigned len = path.Len();
if (len == 0)
return;
- for (int i = 0; i < len; i++)
- {
- wchar_t c = path[i];
- if (IsCharDirLimiter(c))
+ UString name;
+ unsigned prev = 0;
+ for (unsigned i = 0; i < len; i++)
+ if (IsCharDirLimiter(path[i]))
{
+ name.SetFrom(path.Ptr(prev), i - prev);
pathParts.Add(name);
- name.Empty();
+ prev = i + 1;
}
- else
- name += c;
- }
+ name.SetFrom(path.Ptr(prev), len - prev);
pathParts.Add(name);
}
-void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name)
+void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name)
{
- int i;
- for (i = path.Length() - 1; i >= 0; i--)
- if (IsCharDirLimiter(path[i]))
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ for (; p != start; p--)
+ if (IsCharDirLimiter(*(p - 1)))
break;
- dirPrefix = path.Left(i + 1);
- name = path.Mid(i + 1);
+ dirPrefix.SetFrom(path, (unsigned)(p - start));
+ name = p;
+}
+
+void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name)
+{
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ if (p != start)
+ {
+ if (IsCharDirLimiter(*(p - 1)))
+ p--;
+ for (; p != start; p--)
+ if (IsCharDirLimiter(*(p - 1)))
+ break;
+ }
+ dirPrefix.SetFrom(path, (unsigned)(p - start));
+ name = p;
}
UString ExtractDirPrefixFromPath(const UString &path)
{
- int i;
- for (i = path.Length() - 1; i >= 0; i--)
- if (IsCharDirLimiter(path[i]))
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ for (; p != start; p--)
+ if (IsCharDirLimiter(*(p - 1)))
break;
- return path.Left(i + 1);
+ return path.Left((unsigned)(p - start));
}
UString ExtractFileNameFromPath(const UString &path)
{
- int i;
- for (i = path.Length() - 1; i >= 0; i--)
- if (IsCharDirLimiter(path[i]))
+ const wchar_t *start = path;
+ const wchar_t *p = start + path.Len();
+ for (; p != start; p--)
+ if (IsCharDirLimiter(*(p - 1)))
break;
- return path.Mid(i + 1);
+ return p;
}
-bool CompareWildCardWithName(const UString &mask, const UString &name)
+bool DoesWildcardMatchName(const UString &mask, const UString &name)
{
return EnhancedMaskTest(mask, name);
}
-bool DoesNameContainWildCard(const UString &path)
+bool DoesNameContainWildcard(const UString &path)
{
- return (path.FindOneOf(kWildCardCharSet) >= 0);
+ for (unsigned i = 0; i < path.Len(); i++)
+ {
+ wchar_t c = path[i];
+ if (c == '*' || c == '?')
+ return true;
+ }
+ return false;
}
@@ -151,22 +178,36 @@ bool DoesNameContainWildCard(const UString &path)
namespace NWildcard {
+#ifdef _WIN32
+bool IsDriveColonName(const wchar_t *s)
+{
+ wchar_t c = s[0];
+ return c != 0 && s[1] == ':' && s[2] == 0 && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
+}
+#endif
+
/*
+
M = MaskParts.Size();
N = TestNameParts.Size();
File Dir
-ForFile req M<=N [N-M, N) -
- nonreq M=N [0, M) -
-
-ForDir req M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File
- nonreq [0, M) same as ForBoth-File
+ForFile rec M<=N [N-M, N) -
+!ForDir nonrec M=N [0, M) -
-ForBoth req m<=N [0, M) ... [N-M, N) same as ForBoth-File
- nonreq [0, M) same as ForBoth-File
+ForDir rec M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File
+!ForFile nonrec [0, M) same as ForBoth-File
+
+ForFile rec m<=N [0, M) ... [N-M, N) same as ForBoth-File
+ForDir nonrec [0, M) same as ForBoth-File
*/
+bool CItem::AreAllAllowed() const
+{
+ return ForFile && ForDir && WildcardMatching && PathParts.Size() == 1 && PathParts.Front() == L"*";
+}
+
bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
{
if (!isFile && !ForDir)
@@ -176,36 +217,62 @@ bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
return false;
int start = 0;
int finish = 0;
+
if (isFile)
{
- if (!ForDir && !Recursive && delta !=0)
- return false;
+ if (!ForDir)
+ {
+ if (Recursive)
+ start = delta;
+ else if (delta !=0)
+ return false;
+ }
if (!ForFile && delta == 0)
return false;
- if (!ForDir && Recursive)
- start = delta;
}
+
if (Recursive)
{
finish = delta;
if (isFile && !ForFile)
finish = delta - 1;
}
+
for (int d = start; d <= finish; d++)
{
- int i;
+ unsigned i;
for (i = 0; i < PathParts.Size(); i++)
- if (!CompareWildCardWithName(PathParts[i], pathParts[i + d]))
- break;
+ {
+ if (WildcardMatching)
+ {
+ if (!DoesWildcardMatchName(PathParts[i], pathParts[i + d]))
+ break;
+ }
+ else
+ {
+ if (CompareFileNames(PathParts[i], pathParts[i + d]) != 0)
+ break;
+ }
+ }
if (i == PathParts.Size())
return true;
}
return false;
}
+bool CCensorNode::AreAllAllowed() const
+{
+ if (!Name.IsEmpty() ||
+ !SubNodes.IsEmpty() ||
+ !ExcludeItems.IsEmpty() ||
+ IncludeItems.Size() != 1)
+ return false;
+ return IncludeItems.Front().AreAllAllowed();
+}
+
int CCensorNode::FindSubNode(const UString &name) const
{
- for (int i = 0; i < SubNodes.Size(); i++)
+ FOR_VECTOR (i, SubNodes)
if (CompareFileNames(SubNodes[i].Name, name) == 0)
return i;
return -1;
@@ -223,11 +290,19 @@ void CCensorNode::AddItem(bool include, CItem &item)
{
if (item.PathParts.Size() <= 1)
{
+ if (item.PathParts.Size() != 0 && item.WildcardMatching)
+ {
+ if (!DoesNameContainWildcard(item.PathParts.Front()))
+ item.WildcardMatching = false;
+ }
AddItemSimple(include, item);
return;
}
const UString &front = item.PathParts.Front();
- if (DoesNameContainWildCard(front))
+
+ // We can't ignore wildcard, since we don't allow wildcard in SubNodes[].Name
+ // if (item.Wildcard)
+ if (DoesNameContainWildcard(front))
{
AddItemSimple(include, item);
return;
@@ -239,19 +314,20 @@ void CCensorNode::AddItem(bool include, CItem &item)
SubNodes[index].AddItem(include, item);
}
-void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir)
+void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching)
{
CItem item;
SplitPathToParts(path, item.PathParts);
item.Recursive = recursive;
item.ForFile = forFile;
item.ForDir = forDir;
+ item.WildcardMatching = wildcardMatching;
AddItem(include, item);
}
bool CCensorNode::NeedCheckSubDirs() const
{
- for (int i = 0; i < IncludeItems.Size(); i++)
+ FOR_VECTOR (i, IncludeItems)
{
const CItem &item = IncludeItems[i];
if (item.Recursive || item.PathParts.Size() > 1)
@@ -264,7 +340,7 @@ bool CCensorNode::AreThereIncludeItems() const
{
if (IncludeItems.Size() > 0)
return true;
- for (int i = 0; i < SubNodes.Size(); i++)
+ FOR_VECTOR (i, SubNodes)
if (SubNodes[i].AreThereIncludeItems())
return true;
return false;
@@ -273,13 +349,13 @@ bool CCensorNode::AreThereIncludeItems() const
bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const
{
const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems;
- for (int i = 0; i < items.Size(); i++)
+ FOR_VECTOR (i, items)
if (items[i].CheckPath(pathParts, isFile))
return true;
return false;
}
-bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const
+bool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const
{
if (CheckPathCurrent(false, pathParts, isFile))
{
@@ -288,30 +364,45 @@ bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include
}
include = true;
bool finded = CheckPathCurrent(true, pathParts, isFile);
- if (pathParts.Size() == 1)
+ if (pathParts.Size() <= 1)
return finded;
int index = FindSubNode(pathParts.Front());
if (index >= 0)
{
UStringVector pathParts2 = pathParts;
pathParts2.Delete(0);
- if (SubNodes[index].CheckPath(pathParts2, isFile, include))
+ if (SubNodes[index].CheckPathVect(pathParts2, isFile, include))
return true;
}
return finded;
}
-bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const
+bool CCensorNode::CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const
{
UStringVector pathParts;
SplitPathToParts(path, pathParts);
- return CheckPath(pathParts, isFile, include);
+ if (CheckPathVect(pathParts, isFile, include))
+ {
+ if (!include || !isAltStream)
+ return true;
+ }
+ if (isAltStream && !pathParts.IsEmpty())
+ {
+ UString &back = pathParts.Back();
+ int pos = back.Find(L':');
+ if (pos > 0)
+ {
+ back.DeleteFrom(pos);
+ return CheckPathVect(pathParts, isFile, include);
+ }
+ }
+ return false;
}
-bool CCensorNode::CheckPath(const UString &path, bool isFile) const
+bool CCensorNode::CheckPath(bool isAltStream, const UString &path, bool isFile) const
{
bool include;
- if (CheckPath(path, isFile, include))
+ if (CheckPath2(isAltStream, path, isFile, include))
return include;
return false;
}
@@ -335,25 +426,25 @@ bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile
}
*/
-void CCensorNode::AddItem2(bool include, const UString &path, bool recursive)
+void CCensorNode::AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching)
{
if (path.IsEmpty())
return;
bool forFile = true;
bool forFolder = true;
UString path2 = path;
- if (IsCharDirLimiter(path[path.Length() - 1]))
+ if (IsCharDirLimiter(path.Back()))
{
- path2.Delete(path.Length() - 1);
+ path2.DeleteBack();
forFile = false;
}
- AddItem(include, path2, recursive, forFile, forFolder);
+ AddItem(include, path2, recursive, forFile, forFolder, wildcardMatching);
}
void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
{
ExcludeItems += fromNodes.ExcludeItems;
- for (int i = 0; i < fromNodes.SubNodes.Size(); i++)
+ FOR_VECTOR (i, fromNodes.SubNodes)
{
const CCensorNode &node = fromNodes.SubNodes[i];
int subNodeIndex = FindSubNode(node.Name);
@@ -365,13 +456,13 @@ void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
int CCensor::FindPrefix(const UString &prefix) const
{
- for (int i = 0; i < Pairs.Size(); i++)
+ FOR_VECTOR (i, Pairs)
if (CompareFileNames(Pairs[i].Prefix, prefix) == 0)
return i;
return -1;
}
-void CCensor::AddItem(bool include, const UString &path, bool recursive)
+void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching)
{
UStringVector pathParts;
if (path.IsEmpty())
@@ -383,40 +474,82 @@ void CCensor::AddItem(bool include, const UString &path, bool recursive)
forFile = false;
pathParts.DeleteBack();
}
- const UString &front = pathParts.Front();
- bool isAbs = false;
- if (front.IsEmpty())
- isAbs = true;
- else if (front.Length() == 2 && front[1] == L':')
- isAbs = true;
- else
+
+ UString prefix;
+
+ if (pathMode != k_AbsPath)
{
- for (int i = 0; i < pathParts.Size(); i++)
+ const UString &front = pathParts.Front();
+ bool isAbs = false;
+
+ if (front.IsEmpty())
+ isAbs = true;
+ else
{
- const UString &part = pathParts[i];
- if (part == L".." || part == L".")
- {
+ #ifdef _WIN32
+
+ if (IsDriveColonName(front))
isAbs = true;
- break;
+ else
+
+ #endif
+
+ FOR_VECTOR (i, pathParts)
+ {
+ const UString &part = pathParts[i];
+ if (part == L".." || part == L".")
+ {
+ isAbs = true;
+ break;
+ }
+ }
+ }
+
+ unsigned numAbsParts = 0;
+ if (isAbs)
+ if (pathParts.Size() > 1)
+ numAbsParts = pathParts.Size() - 1;
+ else
+ numAbsParts = 1;
+
+ #ifdef _WIN32
+
+ // \\?\ case
+ if (numAbsParts >= 3)
+ {
+ if (pathParts[0].IsEmpty() &&
+ pathParts[1].IsEmpty() &&
+ pathParts[2] == L"?")
+ {
+ prefix =
+ WSTRING_PATH_SEPARATOR
+ WSTRING_PATH_SEPARATOR L"?"
+ WSTRING_PATH_SEPARATOR;
+ numAbsParts -= 3;
+ pathParts.DeleteFrontal(3);
}
}
- }
- int numAbsParts = 0;
- if (isAbs)
- if (pathParts.Size() > 1)
- numAbsParts = pathParts.Size() - 1;
- else
+
+ #endif
+
+ if (numAbsParts > 1 && pathMode == k_FullPath)
numAbsParts = 1;
- UString prefix;
- for (int i = 0; i < numAbsParts; i++)
- {
- const UString &front = pathParts.Front();
- if (DoesNameContainWildCard(front))
- break;
- prefix += front;
- prefix += WCHAR_PATH_SEPARATOR;
- pathParts.Delete(0);
+
+ // We can't ignore wildcard, since we don't allow wildcard in SubNodes[].Name
+ // if (wildcardMatching)
+ for (unsigned i = 0; i < numAbsParts; i++)
+ {
+ {
+ const UString &front = pathParts.Front();
+ if (DoesNameContainWildcard(front))
+ break;
+ prefix += front;
+ prefix += WCHAR_PATH_SEPARATOR;
+ }
+ pathParts.Delete(0);
+ }
}
+
int index = FindPrefix(prefix);
if (index < 0)
index = Pairs.Add(CPair(prefix));
@@ -426,16 +559,17 @@ void CCensor::AddItem(bool include, const UString &path, bool recursive)
item.ForDir = true;
item.ForFile = forFile;
item.Recursive = recursive;
+ item.WildcardMatching = wildcardMatching;
Pairs[index].Head.AddItem(include, item);
}
-bool CCensor::CheckPath(const UString &path, bool isFile) const
+bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) const
{
bool finded = false;
- for (int i = 0; i < Pairs.Size(); i++)
+ FOR_VECTOR (i, Pairs)
{
bool include;
- if (Pairs[i].Head.CheckPath(path, isFile, include))
+ if (Pairs[i].Head.CheckPath2(isAltStream, path, isFile, include))
{
if (!include)
return false;
@@ -447,16 +581,35 @@ bool CCensor::CheckPath(const UString &path, bool isFile) const
void CCensor::ExtendExclude()
{
- int i;
+ unsigned i;
for (i = 0; i < Pairs.Size(); i++)
if (Pairs[i].Prefix.IsEmpty())
break;
if (i == Pairs.Size())
return;
- int index = i;
+ unsigned index = i;
for (i = 0; i < Pairs.Size(); i++)
if (index != i)
Pairs[i].Head.ExtendExclude(Pairs[index].Head);
}
+void CCensor::AddPathsToCensor(ECensorPathMode censorPathMode)
+{
+ FOR_VECTOR(i, CensorPaths)
+ {
+ const CCensorPath &cp = CensorPaths[i];
+ AddItem(censorPathMode, cp.Include, cp.Path, cp.Recursive, cp.WildcardMatching);
+ }
+ CensorPaths.Clear();
+}
+
+void CCensor::AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching)
+{
+ CCensorPath &cp = CensorPaths.AddNew();
+ cp.Path = path;
+ cp.Include = include;
+ cp.Recursive = recursive;
+ cp.WildcardMatching = wildcardMatching;
+}
+
}
diff --git a/src/libs/7zip/unix/CPP/Common/Wildcard.h b/src/libs/7zip/unix/CPP/Common/Wildcard.h
index 2aa33c496..a645e28b5 100644
--- a/src/libs/7zip/unix/CPP/Common/Wildcard.h
+++ b/src/libs/7zip/unix/CPP/Common/Wildcard.h
@@ -5,51 +5,90 @@
#include "MyString.h"
-int CompareFileNames(const UString &s1, const UString &s2);
+int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW;
+#ifndef USE_UNICODE_FSTRING
+ int CompareFileNames(const char *s1, const char *s2);
+#endif
+
+bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2);
+
+inline bool IsCharDirLimiter(wchar_t c)
+{
+ return c == WCHAR_PATH_SEPARATOR
+ #ifdef _WIN32
+ || c == L'/'
+ #endif
+ ;
+}
void SplitPathToParts(const UString &path, UStringVector &pathParts);
-void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name);
+void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name);
+void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name); // ignores dir delimiter at the end of (path)
+
UString ExtractDirPrefixFromPath(const UString &path);
UString ExtractFileNameFromPath(const UString &path);
-bool DoesNameContainWildCard(const UString &path);
-bool CompareWildCardWithName(const UString &mask, const UString &name);
+
+bool DoesNameContainWildcard(const UString &path);
+bool DoesWildcardMatchName(const UString &mask, const UString &name);
namespace NWildcard {
+#ifdef _WIN32
+// returns true, if name is like "a:", "c:", ...
+bool IsDriveColonName(const wchar_t *s);
+#endif
+
+
struct CItem
{
UStringVector PathParts;
bool Recursive;
bool ForFile;
bool ForDir;
+ bool WildcardMatching;
+
+ #ifdef _WIN32
+ bool IsDriveItem() const
+ {
+ return PathParts.Size() == 1 && !ForFile && ForDir && IsDriveColonName(PathParts[0]);
+ }
+ #endif
+
+ // CItem(): WildcardMatching(true) {}
+
+ bool AreAllAllowed() const;
bool CheckPath(const UStringVector &pathParts, bool isFile) const;
};
class CCensorNode
{
CCensorNode *Parent;
+
bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const;
void AddItemSimple(bool include, CItem &item);
- bool CheckPath(UStringVector &pathParts, bool isFile, bool &include) const;
+ bool CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const;
public:
CCensorNode(): Parent(0) { };
CCensorNode(const UString &name, CCensorNode *parent): Parent(parent), Name(name) { };
- UString Name;
+
+ UString Name; // wildcard is not allowed here
CObjectVector<CCensorNode> SubNodes;
CObjectVector<CItem> IncludeItems;
CObjectVector<CItem> ExcludeItems;
+ bool AreAllAllowed() const;
+
int FindSubNode(const UString &path) const;
void AddItem(bool include, CItem &item);
- void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir);
- void AddItem2(bool include, const UString &path, bool recursive);
+ void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching);
+ void AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching);
bool NeedCheckSubDirs() const;
bool AreThereIncludeItems() const;
- bool CheckPath(const UString &path, bool isFile, bool &include) const;
- bool CheckPath(const UString &path, bool isFile) const;
+ bool CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const;
+ bool CheckPath(bool isAltStream, const UString &path, bool isFile) const;
bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const;
// bool CheckPathToRoot(const UString &path, bool isFile, bool include) const;
@@ -60,21 +99,59 @@ struct CPair
{
UString Prefix;
CCensorNode Head;
+
CPair(const UString &prefix): Prefix(prefix) { };
};
+enum ECensorPathMode
+{
+ k_RelatPath, // absolute prefix as Prefix, remain path in Tree
+ k_FullPath, // drive prefix as Prefix, remain path in Tree
+ k_AbsPath // full path in Tree
+};
+
+struct CCensorPath
+{
+ UString Path;
+ bool Include;
+ bool Recursive;
+ bool WildcardMatching;
+
+ CCensorPath():
+ Include(true),
+ Recursive(false),
+ WildcardMatching(true)
+ {}
+};
+
class CCensor
{
int FindPrefix(const UString &prefix) const;
public:
CObjectVector<CPair> Pairs;
+
+ CObjectVector<NWildcard::CCensorPath> CensorPaths;
+
bool AllAreRelative() const
{ return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); }
- void AddItem(bool include, const UString &path, bool recursive);
- bool CheckPath(const UString &path, bool isFile) const;
+
+ void AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching);
+ bool CheckPath(bool isAltStream, const UString &path, bool isFile) const;
void ExtendExclude();
+
+ void AddPathsToCensor(NWildcard::ECensorPathMode censorPathMode);
+ void AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching);
+ void AddPreItem(const UString &path)
+ {
+ AddPreItem(true, path, false, false);
+ }
+ void AddPreItem_Wildcard()
+ {
+ AddPreItem(true, L"*", false, true);
+ }
};
+
}
#endif
diff --git a/src/libs/7zip/unix/CPP/Windows/DLL.cpp b/src/libs/7zip/unix/CPP/Windows/DLL.cpp
index 5f76cc5e2..345153cb2 100644
--- a/src/libs/7zip/unix/CPP/Windows/DLL.cpp
+++ b/src/libs/7zip/unix/CPP/Windows/DLL.cpp
@@ -28,14 +28,9 @@
namespace NWindows {
namespace NDLL {
-CLibrary::~CLibrary()
-{
- Free();
-}
-
bool CLibrary::Free()
{
-TRACEN((printf("CLibrary::Free(%p)\n",(void *)_module)))
+TRACEN((printf("CLibrary::Free(this=%p,%p)\n",(void *)this,(void *)_module)))
if (_module == 0)
return true;
@@ -86,18 +81,11 @@ FARPROC CLibrary::GetProc(LPCSTR lpProcName) const
return local_GetProcAddress(_module,lpProcName);
}
-bool CLibrary::LoadOperations(HMODULE newModule)
+bool CLibrary::Load(LPCTSTR lpLibFileName)
{
- if (newModule == NULL)
- return false;
if(!Free())
return false;
- _module = newModule;
- return true;
-}
-bool CLibrary::Load(LPCTSTR lpLibFileName)
-{
void *handler = 0;
char name[MAX_PATHNAME_LEN+1];
#ifdef _UNICODE
@@ -106,14 +94,14 @@ bool CLibrary::Load(LPCTSTR lpLibFileName)
#else
strcpy(name,nameWindowToUnix(lpLibFileName));
#endif
-
+
// replace ".dll" with ".so"
size_t len = strlen(name);
if ((len >=4) && (strcmp(name+len-4,".dll") == 0)) {
strcpy(name+len-4,".so");
}
- TRACEN((printf("CLibrary::Load(%ls) => %s\n",lpLibFileName,name)))
+ TRACEN((printf("CLibrary::Load(this=%p,%ls) => %s\n",(void *)this,lpLibFileName,name)))
#ifdef __APPLE_CC__
NSObjectFileImage image;
@@ -184,10 +172,30 @@ TRACEN((printf("load_add_on(%s)=%d\n",p.Path(),(int)image)))
#else
printf("Can't load '%ls' (%s)\n", lpLibFileName,dlerror());
#endif
- }
+ }
+
+ _module = handler;
+ TRACEN((printf("CLibrary::Load(this=%p,%ls) => _module=%p\n",(void *)this,lpLibFileName,_module)))
- return LoadOperations(handler);
+ return true;
}
+#ifndef _SFX
+
+FString GetModuleDirPrefix()
+{
+ FString s;
+
+ const char *p7zip_home_dir = getenv("P7ZIP_HOME_DIR");
+ if (p7zip_home_dir) {
+ return MultiByteToUnicodeString(p7zip_home_dir,CP_ACP);
+ }
+
+ return FTEXT(".") FSTRING_PATH_SEPARATOR;
+}
+
+#endif
+
+
}}
diff --git a/src/libs/7zip/unix/CPP/Windows/DLL.h b/src/libs/7zip/unix/CPP/Windows/DLL.h
index 9b57bec8a..2e044ec59 100644
--- a/src/libs/7zip/unix/CPP/Windows/DLL.h
+++ b/src/libs/7zip/unix/CPP/Windows/DLL.h
@@ -6,7 +6,7 @@
#include "../Common/MyString.h"
typedef void * HMODULE;
-
+// #define LOAD_LIBRARY_AS_DATAFILE 0
typedef int (*FARPROC)();
namespace NWindows {
@@ -14,17 +14,14 @@ namespace NDLL {
class CLibrary
{
- bool LoadOperations(HMODULE newModule);
HMODULE _module;
public:
+ CLibrary(): _module(NULL) {};
+ ~CLibrary() { Free(); }
+
operator HMODULE() const { return _module; }
HMODULE* operator&() { return &_module; }
-
-
- CLibrary():_module(NULL) {};
- ~CLibrary();
-
- bool Free();
+ bool IsLoaded() const { return (_module != NULL); };
void Attach(HMODULE m)
{
@@ -38,11 +35,16 @@ public:
return m;
}
-
- bool Load(LPCTSTR fileName);
- FARPROC GetProc(LPCSTR procName) const;
+ bool Free();
+ // bool LoadEx(CFSTR path, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
+ bool Load(CFSTR path);
+ FARPROC GetProc(LPCSTR procName) const; // { return My_GetProcAddress(_module, procName); }
};
+bool MyGetModuleFileName(FString &path);
+
+FString GetModuleDirPrefix();
+
}}
#endif
diff --git a/src/libs/7zip/unix/CPP/Windows/Defs.h b/src/libs/7zip/unix/CPP/Windows/Defs.h
index bad4e3552..b88df748d 100644
--- a/src/libs/7zip/unix/CPP/Windows/Defs.h
+++ b/src/libs/7zip/unix/CPP/Windows/Defs.h
@@ -3,6 +3,7 @@
#ifndef __WINDOWS_DEFS_H
#define __WINDOWS_DEFS_H
+#include "../myWindows/StdAfx.h"
#include "../Common/MyWindows.h"
// #ifdef _WIN32
diff --git a/src/libs/7zip/unix/CPP/Windows/Error.cpp b/src/libs/7zip/unix/CPP/Windows/Error.cpp
deleted file mode 100644
index 88008d711..000000000
--- a/src/libs/7zip/unix/CPP/Windows/Error.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-// Windows/Error.h
-
-#include "StdAfx.h"
-
-#include "Windows/Error.h"
-#include "Common/StringConvert.h"
-
-namespace NWindows {
-namespace NError {
-
-bool MyFormatMessage(DWORD messageID, CSysString &message)
-{
- const char * txt = 0;
- AString msg;
-
- switch(messageID) {
- case ERROR_NO_MORE_FILES : txt = "No more files"; break ;
- case E_NOTIMPL : txt = "E_NOTIMPL"; break ;
- case E_NOINTERFACE : txt = "E_NOINTERFACE"; break ;
- case E_ABORT : txt = "E_ABORT"; break ;
- case E_FAIL : txt = "E_FAIL"; break ;
- case STG_E_INVALIDFUNCTION : txt = "STG_E_INVALIDFUNCTION"; break ;
- case E_OUTOFMEMORY : txt = "E_OUTOFMEMORY"; break ;
- case E_INVALIDARG : txt = "E_INVALIDARG"; break ;
- default:
- txt = strerror(messageID);
- }
- if (txt) {
- msg = txt;
- } else {
- char msgBuf[256];
- snprintf(msgBuf,sizeof(msgBuf),"error #%x",(unsigned)messageID);
- msgBuf[sizeof(msgBuf)-1] = 0;
- msg = msgBuf;
- }
-
- msg += " ";
-
-#ifdef _UNICODE
- message = MultiByteToUnicodeString(msg);
-#else
- message = msg;
-#endif
- return true;
-}
-
-#ifndef _UNICODE
-bool MyFormatMessage(DWORD messageID, UString &message)
-{
- CSysString messageSys;
- bool result = MyFormatMessage(messageID, messageSys);
- message = GetUnicodeString(messageSys);
- return result;
-}
-#endif
-
-}}
-
diff --git a/src/libs/7zip/unix/CPP/Windows/Error.h b/src/libs/7zip/unix/CPP/Windows/Error.h
deleted file mode 100644
index 05b5cd0ea..000000000
--- a/src/libs/7zip/unix/CPP/Windows/Error.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Windows/Error.h
-
-#ifndef __WINDOWS_ERROR_H
-#define __WINDOWS_ERROR_H
-
-#include "Common/MyString.h"
-
-namespace NWindows {
-namespace NError {
-
-bool MyFormatMessage(DWORD messageID, CSysString &message);
-inline CSysString MyFormatMessage(DWORD messageID)
-{
- CSysString message;
- MyFormatMessage(messageID, message);
- return message;
-}
-#ifdef _UNICODE
-inline UString MyFormatMessageW(DWORD messageID)
- { return MyFormatMessage(messageID); }
-#else
-bool MyFormatMessage(DWORD messageID, UString &message);
-inline UString MyFormatMessageW(DWORD messageID)
-{
- UString message;
- MyFormatMessage(messageID, message);
- return message;
-}
-#endif
-
-}}
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/Windows/FileDir.cpp b/src/libs/7zip/unix/CPP/Windows/FileDir.cpp
index 838f92d5b..9915bd8b8 100644
--- a/src/libs/7zip/unix/CPP/Windows/FileDir.cpp
+++ b/src/libs/7zip/unix/CPP/Windows/FileDir.cpp
@@ -2,10 +2,14 @@
#include "StdAfx.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
#include "FileDir.h"
-#include "FileName.h"
#include "FileFind.h"
-#include "Defs.h"
+#include "FileName.h"
+
#include "../Common/StringConvert.h"
#include "../Common/IntToString.h"
@@ -25,6 +29,10 @@
// #define TRACEN(u) u;
#define TRACEN(u) /* */
+int g_filedir = 1;
+
+static NWindows::NSynchronization::CCriticalSection g_CountCriticalSection;
+
class Umask
{
public:
@@ -34,10 +42,12 @@ class Umask
current_umask = umask (0); /* get and set the umask */
umask(current_umask); /* restore the umask */
mask = 0777 & (~current_umask);
- }
+ }
};
static Umask gbl_umask;
+extern BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, DWORD *Seconds );
+
#ifdef _UNICODE
AString nameWindowToUnix2(LPCWSTR name) // FIXME : optimization ?
@@ -47,10 +57,7 @@ AString nameWindowToUnix2(LPCWSTR name) // FIXME : optimization ?
}
#endif
-extern BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, DWORD *Seconds );
-
-#ifdef _UNICODE
-DWORD WINAPI GetFullPathName( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *lastpart ) { // FIXME
+DWORD WINAPI GetFullPathNameW( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *lastpart ) { // FIXME
if (name == 0) return 0;
DWORD name_len = lstrlen(name);
@@ -71,7 +78,7 @@ DWORD WINAPI GetFullPathName( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *la
*lastpart=ptr+1;
ptr++;
}
- TRACEN((printf("GetFullPathNameA(%s,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
+ TRACEN((printf("GetFullPathNameA(%ls,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
return ret;
}
if (isascii(name[0]) && (name[1] == ':')) { // FIXME isascii
@@ -89,14 +96,14 @@ DWORD WINAPI GetFullPathName( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *la
*lastpart=ptr+1;
ptr++;
}
- TRACEN((printf("GetFullPathNameA(%sl,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
+ TRACEN((printf("GetFullPathNameA(%ls,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
return ret;
}
// name is a relative pathname.
//
if (len < 2) {
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 2)\n",name, (int)len)))
+ TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 2)\n",name, (int)len)))
return 0;
}
@@ -110,13 +117,13 @@ DWORD WINAPI GetFullPathName( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *la
if (cret) {
begin_len = strlen(begin);
}
-
+
if (begin_len >= 1) {
// strlen(begin) + strlen("/") + strlen(name)
ret = begin_len + 1 + name_len;
if (ret >= len) {
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 4)\n",name, (int)len)))
+ TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 4)\n",name, (int)len)))
return 0;
}
UString wbegin = GetUnicodeString(begin);
@@ -131,136 +138,14 @@ DWORD WINAPI GetFullPathName( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *la
*lastpart=ptr+1;
ptr++;
}
- TRACEN((printf("GetFullPathNameA(%s,%d,%s,%s)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
+ TRACEN((printf("GetFullPathNameA(%ls,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
} else {
ret = 0;
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 5)\n",name, (int)len)))
+ TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 5)\n",name, (int)len)))
}
return ret;
}
-#endif
-
-#if 0
-DWORD WINAPI GetFullPathName( LPCSTR name, DWORD len, LPSTR buffer, LPSTR *lastpart ) {
- if (name == 0) return 0;
-
- DWORD name_len = strlen(name);
-
- if (name[0] == '/') {
- DWORD ret = name_len+2;
- if (ret >= len) {
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 0)\n",name, (int)len)))
- return 0;
- }
- strcpy(buffer,"c:");
- strcat(buffer,name);
-
- *lastpart=buffer;
- char *ptr=buffer;
- while (*ptr) {
- if (*ptr == '/')
- *lastpart=ptr+1;
- ptr++;
- }
- TRACEN((printf("GetFullPathNameA(%s,%d,%s,%s)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
- return ret;
- }
- if (isascii(name[0]) && (name[1] == ':')) {
- DWORD ret = name_len;
- if (ret >= len) {
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 1)\n",name, (int)len)))
- return 0;
- }
- strcpy(buffer,name);
-
- *lastpart=buffer;
- char *ptr=buffer;
- while (*ptr) {
- if (*ptr == '/')
- *lastpart=ptr+1;
- ptr++;
- }
- TRACEN((printf("GetFullPathNameA(%s,%d,%s,%s)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
- return ret;
- }
-
- // name is a relative pathname.
- //
- if (len < 2) {
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 2)\n",name, (int)len)))
- return 0;
- }
-
- DWORD ret = 0;
- char begin[MAX_PATHNAME_LEN];
- /* DWORD begin_len = GetCurrentDirectoryA(MAX_PATHNAME_LEN,begin); */
- DWORD begin_len = 0;
- begin[0]='c';
- begin[1]=':';
- char * cret = getcwd(begin+2, MAX_PATHNAME_LEN - 3);
- if (cret) {
- begin_len = strlen(begin);
- }
-
- if (begin_len >= 1) {
- // strlen(begin) + strlen("/") + strlen(name)
- ret = begin_len + 1 + name_len;
-
- if (ret >= len) {
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 4)\n",name, (int)len)))
- return 0;
- }
- strcpy(buffer,begin);
- strcat(buffer,"/");
- strcat(buffer,name);
-
- *lastpart=buffer + begin_len + 1;
- char *ptr=buffer;
- while (*ptr) {
- if (*ptr == '/')
- *lastpart=ptr+1;
- ptr++;
- }
- TRACEN((printf("GetFullPathNameA(%s,%d,%s,%s)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
- } else {
- ret = 0;
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 5)\n",name, (int)len)))
- }
- return ret;
-}
-
-static BOOL WINAPI RemoveDirectory(LPCSTR path) {
- if (!path || !*path) {
- SetLastError(ERROR_PATH_NOT_FOUND);
- return FALSE;
- }
- const char * name = nameWindowToUnix(path);
- TRACEN((printf("RemoveDirectoryA(%s)\n",name)))
-
- if (rmdir( name ) != 0) {
- return FALSE;
- }
- return TRUE;
-}
-#endif
-
-#ifdef _UNICODE
-static BOOL WINAPI RemoveDirectory(LPCWSTR path) {
- if (!path || !*path) {
- SetLastError(ERROR_PATH_NOT_FOUND);
- return FALSE;
- }
- AString name = nameWindowToUnix2(path);
- TRACEN((printf("RemoveDirectoryA(%s)\n",(const char *)name)))
-
- if (rmdir( (const char *)name ) != 0) {
- return FALSE;
- }
- return TRUE;
-}
-#endif
-
static int copy_fd(int fin,int fout)
{
char buffer[16384];
@@ -297,6 +182,7 @@ static BOOL CopyFile(const char *src,const char *dst)
flags |= O_LARGEFILE;
#endif
+ // printf("##DBG CopyFile(%s,%s)\n",src,dst);
int fout = open(dst,O_CREAT | O_WRONLY | O_EXCL | flags, 0600);
if (fout != -1)
{
@@ -314,102 +200,76 @@ static BOOL CopyFile(const char *src,const char *dst)
return FALSE;
}
-/*****************************************************************************************/
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
namespace NWindows {
namespace NFile {
-namespace NDirectory {
+// SetCurrentDirectory doesn't support \\?\ prefix
-bool MySetCurrentDirectory(LPCWSTR wpath)
-{
- AString path = UnicodeStringToMultiByte(wpath);
+#ifdef WIN_LONG_PATH
+bool GetLongPathBase(CFSTR fileName, UString &res);
+bool GetLongPath(CFSTR fileName, UString &res);
+#endif
- return chdir((const char*)path) == 0;
-}
+namespace NDir {
-#ifdef _UNICODE
-bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
-{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Mid(index);
- return true;
-}
-bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
-{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Left(index);
- return true;
-}
-#endif
+#ifdef _WIN32
+#ifndef UNDER_CE
-bool MyGetCurrentDirectory(CSysString &resultPath)
+bool MyGetWindowsDirectory(FString &path)
{
- char begin[MAX_PATHNAME_LEN];
- begin[0]='c';
- begin[1]=':';
- char * cret = getcwd(begin+2, MAX_PATHNAME_LEN - 3);
- if (cret)
+ UINT needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
-#ifdef _UNICODE
- resultPath = GetUnicodeString(begin);
-#else
- resultPath = begin;
-#endif
- return true;
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetWindowsDirectory(s, MAX_PATH + 1);
+ path = fas2fs(s);
}
- return false;
-}
-
-bool MyMoveFile( LPCTSTR fn1, LPCTSTR fn2 ) {
-#ifdef _UNICODE
- AString src = nameWindowToUnix2(fn1);
- AString dst = nameWindowToUnix2(fn2);
-#else
- const char * src = nameWindowToUnix(fn1);
- const char * dst = nameWindowToUnix(fn2);
-#endif
-
- TRACEN((printf("MoveFileW(%s,%s)\n",src,dst)))
-
- int ret = rename(src,dst);
- if (ret != 0)
+ else
+ #endif
{
- if (errno == EXDEV) // FIXED : bug #1112167 (Temporary directory must be on same partition as target)
- {
- BOOL bret = CopyFile(src,dst);
- if (bret == FALSE) return false;
-
- struct stat info_file;
- ret = stat(src,&info_file);
- if (ret == 0) {
- TRACEN((printf("##DBG chmod-1(%s,%o)\n",dst,(unsigned)info_file.st_mode & gbl_umask.mask)))
- ret = chmod(dst,info_file.st_mode & gbl_umask.mask);
- }
- if (ret == 0) {
- ret = unlink(src);
- }
- if (ret == 0) return true;
- }
- return false;
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetWindowsDirectoryW(s, MAX_PATH + 1);
+ path = us2fs(s);
}
- return true;
+ return (needLength > 0 && needLength <= MAX_PATH);
}
-bool MyRemoveDirectory(LPCTSTR pathName)
+
+bool MyGetSystemDirectory(FString &path)
{
- return BOOLToBool(::RemoveDirectory(pathName));
+ UINT needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetSystemDirectory(s, MAX_PATH + 1);
+ path = fas2fs(s);
+ }
+ else
+ #endif
+ {
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetSystemDirectoryW(s, MAX_PATH + 1);
+ path = us2fs(s);
+ }
+ return (needLength > 0 && needLength <= MAX_PATH);
}
+#endif
+#endif // _WIN32
-bool SetDirTime(LPCWSTR fileName, const FILETIME * /* creationTime */ ,
- const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime)
+bool SetDirTime(CFSTR fileName, const FILETIME * /* cTime */ , const FILETIME *aTime, const FILETIME *mTime)
{
AString cfilename = UnicodeStringToMultiByte(fileName);
const char * unix_filename = nameWindowToUnix((const char *)cfilename);
@@ -427,22 +287,22 @@ bool SetDirTime(LPCWSTR fileName, const FILETIME * /* creationTime */ ,
buf.modtime = current_time;
}
- if (lpLastAccessTime)
+ if (aTime)
{
LARGE_INTEGER ltime;
DWORD dw;
- ltime.QuadPart = lpLastAccessTime->dwHighDateTime;
- ltime.QuadPart = (ltime.QuadPart << 32) | lpLastAccessTime->dwLowDateTime;
+ ltime.QuadPart = aTime->dwHighDateTime;
+ ltime.QuadPart = (ltime.QuadPart << 32) | aTime->dwLowDateTime;
RtlTimeToSecondsSince1970( &ltime, &dw );
buf.actime = dw;
}
- if (lpLastWriteTime)
+ if (mTime)
{
LARGE_INTEGER ltime;
DWORD dw;
- ltime.QuadPart = lpLastWriteTime->dwHighDateTime;
- ltime.QuadPart = (ltime.QuadPart << 32) | lpLastWriteTime->dwLowDateTime;
+ ltime.QuadPart = mTime->dwHighDateTime;
+ ltime.QuadPart = (ltime.QuadPart << 32) | mTime->dwLowDateTime;
RtlTimeToSecondsSince1970( &ltime, &dw );
buf.modtime = dw;
}
@@ -452,25 +312,20 @@ bool SetDirTime(LPCWSTR fileName, const FILETIME * /* creationTime */ ,
return true;
}
-#ifndef _UNICODE
-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
-{
- return MySetFileAttributes(UnicodeStringToMultiByte(fileName, CP_ACP), fileAttributes);
-}
-
-bool MyRemoveDirectory(LPCWSTR pathName)
-{
- return MyRemoveDirectory(UnicodeStringToMultiByte(pathName, CP_ACP));
-}
-
-bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
-{
- UINT codePage = CP_ACP;
- return MyMoveFile(UnicodeStringToMultiByte(existFileName, codePage), UnicodeStringToMultiByte(newFileName, codePage));
+#ifdef WIN_LONG_PATH
+bool GetLongPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2)
+{
+ if (!GetLongPathBase(s1, d1) ||
+ !GetLongPathBase(s2, d2))
+ return false;
+ if (d1.IsEmpty() && d2.IsEmpty())
+ return false;
+ if (d1.IsEmpty()) d1 = fs2us(s1);
+ if (d2.IsEmpty()) d2 = fs2us(s2);
+ return true;
}
#endif
-
static int convert_to_symlink(const char * name) {
FILE *file = fopen(name,"rb");
if (file) {
@@ -482,17 +337,17 @@ static int convert_to_symlink(const char * name) {
if (ir == 0) {
ir = symlink(buf,name);
}
- return ir;
+ return ir;
}
}
return -1;
}
-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
+bool SetFileAttrib(CFSTR fileName, DWORD fileAttributes)
{
if (!fileName) {
SetLastError(ERROR_PATH_NOT_FOUND);
- TRACEN((printf("MySetFileAttributes(NULL,%d) : false-1\n",fileAttributes)))
+ TRACEN((printf("SetFileAttrib(NULL,%d) : false-1\n",fileAttributes)))
return false;
}
#ifdef _UNICODE
@@ -504,14 +359,14 @@ bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
#ifdef ENV_HAVE_LSTAT
if (global_use_lstat) {
if(lstat(name,&stat_info)!=0) {
- TRACEN((printf("MySetFileAttributes(%s,%d) : false-2-1\n",name,fileAttributes)))
+ TRACEN((printf("SetFileAttrib(%s,%d) : false-2-1\n",(const char *)name,fileAttributes)))
return false;
}
} else
#endif
{
if(stat(name,&stat_info)!=0) {
- TRACEN((printf("MySetFileAttributes(%s,%d) : false-2-2\n",name,fileAttributes)))
+ TRACEN((printf("SetFileAttrib(%s,%d) : false-2-2\n",(const char *)name,fileAttributes)))
return false;
}
}
@@ -521,18 +376,18 @@ bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
#ifdef ENV_HAVE_LSTAT
if (S_ISLNK(stat_info.st_mode)) {
if ( convert_to_symlink(name) != 0) {
- TRACEN((printf("MySetFileAttributes(%s,%d) : false-3\n",name,fileAttributes)))
+ TRACEN((printf("SetFileAttrib(%s,%d) : false-3\n",(const char *)name,fileAttributes)))
return false;
}
} else
#endif
if (S_ISREG(stat_info.st_mode)) {
- TRACEN((printf("##DBG chmod-2(%s,%o)\n",name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
+ TRACEN((printf("##DBG chmod-2(%s,%o)\n",(const char *)name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
chmod(name,stat_info.st_mode & gbl_umask.mask);
} else if (S_ISDIR(stat_info.st_mode)) {
// user/7za must be able to create files in this directory
stat_info.st_mode |= (S_IRUSR | S_IWUSR | S_IXUSR);
- TRACEN((printf("##DBG chmod-3(%s,%o)\n",name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
+ TRACEN((printf("##DBG chmod-3(%s,%o)\n",(const char *)name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
chmod(name,stat_info.st_mode & gbl_umask.mask);
}
#ifdef ENV_HAVE_LSTAT
@@ -545,121 +400,123 @@ bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
/* Only Windows Attributes */
if( S_ISDIR(stat_info.st_mode)) {
/* Remark : FILE_ATTRIBUTE_READONLY ignored for directory. */
- TRACEN((printf("##DBG chmod-4(%s,%o)\n",name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
+ TRACEN((printf("##DBG chmod-4(%s,%o)\n",(const char *)name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
chmod(name,stat_info.st_mode & gbl_umask.mask);
} else {
if (fileAttributes & FILE_ATTRIBUTE_READONLY) stat_info.st_mode &= ~0222; /* octal!, clear write permission bits */
- TRACEN((printf("##DBG chmod-5(%s,%o)\n",name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
+ TRACEN((printf("##DBG chmod-5(%s,%o)\n",(const char *)name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
chmod(name,stat_info.st_mode & gbl_umask.mask);
}
}
- TRACEN((printf("MySetFileAttributes(%s,%d) : true\n",name,fileAttributes)))
+ TRACEN((printf("SetFileAttrib(%s,%d) : true\n",(const char *)name,fileAttributes)))
return true;
}
-bool MyCreateDirectory(LPCTSTR pathName)
-{
- if (!pathName || !*pathName) {
+bool RemoveDir(CFSTR path)
+{
+ if (!path || !*path) {
SetLastError(ERROR_PATH_NOT_FOUND);
- return false;
+ return FALSE;
}
+ AString name = nameWindowToUnix2(path);
+ TRACEN((printf("RemoveDirectoryA(%s)\n",(const char *)name)))
+
+ if (rmdir( (const char *)name ) != 0) {
+ return FALSE;
+ }
+ return TRUE;
+}
+bool MyMoveFile(CFSTR existFileName, CFSTR newFileName)
+{
#ifdef _UNICODE
- AString name = nameWindowToUnix2(pathName);
+ AString src = nameWindowToUnix2(existFileName);
+ AString dst = nameWindowToUnix2(newFileName);
#else
- const char * name = nameWindowToUnix(pathName);
+ const char * src = nameWindowToUnix(existFileName);
+ const char * dst = nameWindowToUnix(newFileName);
#endif
- bool bret = false;
- if (mkdir( name, 0700 ) == 0) bret = true;
-
- TRACEN((printf("MyCreateDirectory(%s)=%d\n",name,(int)bret)))
- return bret;
-}
-#ifndef _UNICODE
-bool MyCreateDirectory(LPCWSTR pathName)
-{
- return MyCreateDirectory(UnicodeStringToMultiByte(pathName, CP_ACP));
-}
-#endif
+ TRACEN((printf("MyMoveFile(%s,%s)\n",(const char *)src,(const char *)dst)))
-bool CreateComplexDirectory(LPCTSTR _aPathName)
-{
- CSysString pathName = _aPathName;
- int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
- if (pos > 0 && pos == pathName.Length() - 1)
- {
- if (pathName.Length() == 3 && pathName[1] == ':')
- return true; // Disk folder;
- pathName.Delete(pos);
- }
- CSysString pathName2 = pathName;
- pos = pathName.Length();
- while(true)
+ int ret = rename(src,dst);
+ if (ret != 0)
{
- if(MyCreateDirectory(pathName))
- break;
- if(::GetLastError() == ERROR_ALREADY_EXISTS)
+ if (errno == EXDEV) // FIXED : bug #1112167 (Temporary directory must be on same partition as target)
{
-#ifdef _WIN32 // FIXED for supporting symbolic link instead of a directory
- NFind::CFileInfo fileInfo;
- if (!NFind::FindFile(pathName, fileInfo)) // For network folders
- return true;
- if (!fileInfo.IsDir())
- return false;
-#endif
- break;
+ BOOL bret = CopyFile(src,dst);
+ if (bret == FALSE) return false;
+
+ struct stat info_file;
+ ret = stat(src,&info_file);
+ if (ret == 0) {
+ TRACEN((printf("##DBG chmod-1(%s,%o)\n",(const char *)dst,(unsigned)info_file.st_mode & gbl_umask.mask)))
+ ret = chmod(dst,info_file.st_mode & gbl_umask.mask);
+ }
+ if (ret == 0) {
+ ret = unlink(src);
+ }
+ if (ret == 0) return true;
}
- pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
- if (pos < 0 || pos == 0)
- return false;
- if (pathName[pos - 1] == ':')
- return false;
- pathName = pathName.Left(pos);
- }
- pathName = pathName2;
- while(pos < pathName.Length())
- {
- pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1);
- if (pos < 0)
- pos = pathName.Length();
- if(!MyCreateDirectory(pathName.Left(pos)))
- return false;
+ return false;
}
return true;
}
-#ifndef _UNICODE
+bool CreateDir(CFSTR path)
+{
+ if (!path || !*path) {
+ SetLastError(ERROR_PATH_NOT_FOUND);
+ return false;
+ }
-bool CreateComplexDirectory(LPCWSTR _aPathName)
+#ifdef _UNICODE
+ AString name = nameWindowToUnix2(path);
+#else
+ const char * name = nameWindowToUnix(path);
+#endif
+ bool bret = false;
+ if (mkdir( name, 0700 ) == 0) bret = true;
+
+ TRACEN((printf("CreateDir(%s)=%d\n",(const char *)name,(int)bret)))
+ return bret;
+}
+
+bool CreateComplexDir(CFSTR _aPathName)
{
- UString pathName = _aPathName;
- int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
- if (pos > 0 && pos == pathName.Length() - 1)
+ AString name = nameWindowToUnix2(_aPathName);
+ TRACEN((printf("CreateComplexDir(%s)\n",(const char *)name)))
+
+
+ FString pathName = _aPathName;
+ int pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
+ if (pos > 0 && pos == pathName.Len() - 1)
{
- if (pathName.Length() == 3 && pathName[1] == L':')
+ if (pathName.Len() == 3 && pathName[1] == L':')
return true; // Disk folder;
pathName.Delete(pos);
}
- UString pathName2 = pathName;
- pos = pathName.Length();
- while(true)
+ FString pathName2 = pathName;
+ pos = pathName.Len();
+ TRACEN((printf("CreateComplexDir(%s) pathName2=%ls\n",(const char *)name,(CFSTR)pathName2)))
+ for (;;)
{
- if(MyCreateDirectory(pathName))
+ if (CreateDir(pathName))
break;
- if(::GetLastError() == ERROR_ALREADY_EXISTS)
+ TRACEN((printf("CreateComplexDir(%s) GetLastError=%d (ERROR_ALREADY_EXISTS=%d)\n",(const char *)name,::GetLastError(), ERROR_ALREADY_EXISTS)))
+ if (::GetLastError() == ERROR_ALREADY_EXISTS)
{
#ifdef _WIN32 // FIXED for supporting symbolic link instead of a directory
- NFind::CFileInfoW fileInfo;
- if (!NFind::FindFile(pathName, fileInfo)) // For network folders
+ NFind::CFileInfo fileInfo;
+ if (!fileInfo.Find(pathName)) // For network folders
return true;
if (!fileInfo.IsDir())
return false;
#endif
break;
}
- pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+ pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
if (pos < 0 || pos == 0)
return false;
if (pathName[pos - 1] == L':')
@@ -667,20 +524,18 @@ bool CreateComplexDirectory(LPCWSTR _aPathName)
pathName = pathName.Left(pos);
}
pathName = pathName2;
- while(pos < pathName.Length())
+ while (pos < pathName.Len())
{
- pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
+ pos = pathName.Find(FCHAR_PATH_SEPARATOR, pos + 1);
if (pos < 0)
- pos = pathName.Length();
- if(!MyCreateDirectory(pathName.Left(pos)))
+ pos = pathName.Len();
+ if (!CreateDir(pathName.Left(pos)))
return false;
}
return true;
}
-#endif
-
-bool DeleteFileAlways(LPCTSTR name)
+bool DeleteFileAlways(CFSTR name)
{
if (!name || !*name) {
SetLastError(ERROR_PATH_NOT_FOUND);
@@ -693,235 +548,344 @@ bool DeleteFileAlways(LPCTSTR name)
#endif
bool bret = false;
if (remove(unixname) == 0) bret = true;
- TRACEN((printf("DeleteFileAlways(%s)=%d\n",unixname,(int)bret)))
+ TRACEN((printf("DeleteFileAlways(%s)=%d\n",(const char *)unixname,(int)bret)))
return bret;
}
-#ifndef _UNICODE
-bool DeleteFileAlways(LPCWSTR name)
-{
- return DeleteFileAlways(UnicodeStringToMultiByte(name, CP_ACP));
+bool RemoveDirWithSubItems(const FString &path)
+{
+ bool needRemoveSubItems = true;
+ {
+ NFind::CFileInfo fi;
+ if (!fi.Find(path))
+ return false;
+ if (!fi.IsDir())
+ {
+ ::SetLastError(ERROR_DIRECTORY);
+ return false;
+ }
+ if (fi.HasReparsePoint())
+ needRemoveSubItems = false;
+ }
+
+ if (needRemoveSubItems)
+ {
+ FString s = path;
+ s += FCHAR_PATH_SEPARATOR;
+ unsigned prefixSize = s.Len();
+ s += FCHAR_ANY_MASK;
+ NFind::CEnumerator enumerator(s);
+ NFind::CFileInfo fi;
+ while (enumerator.Next(fi))
+ {
+ s.DeleteFrom(prefixSize);
+ s += fi.Name;
+ if (fi.IsDir())
+ {
+ if (!RemoveDirWithSubItems(s))
+ return false;
+ }
+ else if (!DeleteFileAlways(s))
+ return false;
+ }
+ }
+
+ if (!SetFileAttrib(path, 0))
+ return false;
+ return RemoveDir(path);
}
-#endif
-static bool RemoveDirectorySubItems2(const UString &pathPrefix, const NFind::CFileInfoW &fileInfo)
+bool RemoveDirectoryWithSubItems(const FString &path); // FIXME
+static bool RemoveDirectorySubItems2(const FString pathPrefix, const NFind::CFileInfo &fileInfo)
{
if (fileInfo.IsDir())
return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
return DeleteFileAlways(pathPrefix + fileInfo.Name);
}
-
-bool RemoveDirectoryWithSubItems(const UString &path)
+bool RemoveDirectoryWithSubItems(const FString &path)
{
- NFind::CFileInfoW fileInfo;
- UString pathPrefix = path + NName::kDirDelimiter;
+ NFind::CFileInfo fileInfo;
+ FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
{
- NFind::CEnumeratorW enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
+ NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK);
while (enumerator.Next(fileInfo))
if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
return false;
}
- if (!MySetFileAttributes(path, 0))
+ if (!SetFileAttrib(path, 0))
return false;
- return MyRemoveDirectory(path);
+ return RemoveDir(path);
}
-#ifndef _WIN32_WCE
+#ifdef UNDER_CE
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath,
- int &fileNamePartStartIndex)
+bool MyGetFullPathName(CFSTR fileName, FString &resFullPath)
{
- LPTSTR fileNamePointer = 0;
- LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
- DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1,
- buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength == 0 || needLength >= MAX_PATH)
- return false;
- if (fileNamePointer == 0)
- fileNamePartStartIndex = lstrlen(fileName);
- else
- fileNamePartStartIndex = fileNamePointer - buffer;
+ resFullPath = fileName;
return true;
}
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath,
- int &fileNamePartStartIndex)
-{
- const UINT currentPage = CP_ACP;
- CSysString sysPath;
- if (!MyGetFullPathName(UnicodeStringToMultiByte(fileName,
- currentPage), sysPath, fileNamePartStartIndex))
- return false;
- UString resultPath1 = MultiByteToUnicodeString(
- sysPath.Left(fileNamePartStartIndex), currentPage);
- UString resultPath2 = MultiByteToUnicodeString(
- sysPath.Mid(fileNamePartStartIndex), currentPage);
- fileNamePartStartIndex = resultPath1.Length();
- resultPath = resultPath1 + resultPath2;
- return true;
-}
-#endif
+#else
+#ifdef WIN_LONG_PATH
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
+static FString GetLastPart(CFSTR path)
{
- int index;
- return MyGetFullPathName(fileName, path, index);
+ int i = MyStringLen(path);
+ for (; i > 0; i--)
+ {
+ FChar c = path[i - 1];
+ if (c == FCHAR_PATH_SEPARATOR || c == '/')
+ break;
+ }
+ return path + i;
}
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &path)
+static void AddTrailingDots(CFSTR oldPath, FString &newPath)
{
- int index;
- return MyGetFullPathName(fileName, path, index);
+ int len = MyStringLen(oldPath);
+ int i;
+ for (i = len; i > 0 && oldPath[i - 1] == '.'; i--);
+ if (i == 0 || i == len)
+ return;
+ FString oldName = GetLastPart(oldPath);
+ FString newName = GetLastPart(newPath);
+ int nonDotsLen = oldName.Len() - (len - i);
+ if (nonDotsLen == 0 || newName.CompareNoCase(oldName.Left(nonDotsLen)) != 0)
+ return;
+ for (; i != len; i++)
+ newPath += '.';
}
-#endif
#endif
-/* needed to find .DLL/.so and SFX */
-bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath)
+
+bool MyGetFullPathName(CFSTR fileName, FString &resFullPath)
{
- if (path != 0) {
- printf("NOT EXPECTED : MySearchPath : path != NULL\n");
- exit(EXIT_FAILURE);
+ resFullPath.Empty();
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ LPTSTR fileNamePointer = 0;
+ DWORD needLength = ::GetFullPathName(fs2fas(fileName), MAX_PATH + 1, s, &fileNamePointer);
+ if (needLength == 0 || needLength > MAX_PATH)
+ return false;
+ resFullPath = fas2fs(s);
+ return true;
}
-
- if (extension != 0) {
- printf("NOT EXPECTED : MySearchPath : extension != NULL\n");
- exit(EXIT_FAILURE);
+ else
+ #endif
+ {
+ LPWSTR fileNamePointer = 0;
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ DWORD needLength = ::GetFullPathNameW(fs2us(fileName), MAX_PATH + 1, s, &fileNamePointer);
+ if (needLength == 0)
+ return false;
+ if (needLength <= MAX_PATH)
+ {
+ resFullPath = us2fs(s);
+ return true;
+ }
+ #ifdef WIN_LONG_PATH
+ needLength++;
+ UString temp;
+ LPWSTR buffer = temp.GetBuffer(needLength + 1);
+ buffer[0] = 0;
+ DWORD needLength2 = ::GetFullPathNameW(fs2us(fileName), needLength, buffer, &fileNamePointer);
+ temp.ReleaseBuffer();
+ if (needLength2 > 0 && needLength2 <= needLength)
+ {
+ resFullPath = us2fs(temp);
+ AddTrailingDots(fileName, resFullPath);
+ return true;
+ }
+ #endif
+ return false;
}
+}
- if (fileName == 0) {
- printf("NOT EXPECTED : MySearchPath : fileName == NULL\n");
- exit(EXIT_FAILURE);
- }
+bool SetCurrentDir(CFSTR path)
+{
+ AString apath = UnicodeStringToMultiByte(path);
- const char *p7zip_home_dir = getenv("P7ZIP_HOME_DIR");
- if (p7zip_home_dir) {
- AString file_path = p7zip_home_dir;
- file_path += UnicodeStringToMultiByte(fileName, CP_ACP);
+ return chdir((const char*)apath) == 0;
+}
- TRACEN((printf("MySearchPath() fopen(%s)\n",(const char *)file_path)))
- FILE *file = fopen((const char *)file_path,"r");
- if (file) {
- // file is found
- fclose(file);
- resultPath = MultiByteToUnicodeString(file_path, CP_ACP);
- return true;
- }
+bool GetCurrentDir(FString &path)
+{
+ char begin[MAX_PATHNAME_LEN];
+ begin[0]='c';
+ begin[1]=':';
+ char * cret = getcwd(begin+2, MAX_PATHNAME_LEN - 3);
+ if (cret)
+ {
+#ifdef _UNICODE
+ path = GetUnicodeString(begin);
+#else
+ path = begin;
+#endif
+ return true;
}
return false;
}
-#ifndef _UNICODE
-bool MyGetTempPath(CSysString &path)
-{
- path = "c:/tmp/"; // final '/' is needed
- return true;
-}
#endif
-bool MyGetTempPath(UString &path)
+bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName)
{
- path = L"c:/tmp/"; // final '/' is needed
- return true;
+ bool res = MyGetFullPathName(path, resDirPrefix);
+ if (!res)
+ resDirPrefix = path;
+ int pos = resDirPrefix.ReverseFind(FCHAR_PATH_SEPARATOR);
+ resFileName = resDirPrefix.Ptr(pos + 1);
+ resDirPrefix.DeleteFrom(pos + 1);
+ return res;
}
-static NSynchronization::CCriticalSection g_CountCriticalSection;
+bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix)
+{
+ FString resFileName;
+ return GetFullPathAndSplit(path, resDirPrefix, resFileName);
+}
-static CSysString CSysConvertUInt32ToString(UInt32 value)
+bool MyGetTempPath(FString &path)
{
- TCHAR buffer[32];
- ConvertUInt32ToString(value, buffer);
- return buffer;
+ path = L"c:/tmp/"; // final '/' is needed
+ return true;
}
-UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
+static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COutFile *outFile)
{
+#ifdef _WIN32
+ UInt32 d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
+#else
static UInt32 memo_count = 0;
UInt32 count;
g_CountCriticalSection.Enter();
count = memo_count++;
g_CountCriticalSection.Leave();
-
- Remove();
-/* UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH)); */
UINT number = (UINT)getpid();
- resultPath = dirPath;
- resultPath += prefix;
- resultPath += TEXT('#');
- resultPath += CSysConvertUInt32ToString(number);
- resultPath += TEXT('@');
- resultPath += CSysConvertUInt32ToString(count);
- resultPath += TEXT(".tmp");
-
- _fileName = resultPath;
+ UInt32 d = (GetTickCount() << 12) ^ (count << 14) ^ number;
+#endif
+ for (unsigned i = 0; i < 100; i++)
+ {
+ path = prefix;
+ if (addRandom)
+ {
+ FChar s[16];
+ UInt32 value = d;
+ unsigned k;
+ for (k = 0; k < 8; k++)
+ {
+ unsigned t = value & 0xF;
+ value >>= 4;
+ s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ }
+ s[k] = '\0';
+ if (outFile)
+ path += FChar('.');
+ path += s;
+ UInt32 step = GetTickCount() + 2;
+ if (step == 0)
+ step = 1;
+ d += step;
+ }
+ addRandom = true;
+ if (outFile)
+ path += FTEXT(".tmp");
+ if (NFind::DoesFileOrDirExist(path))
+ {
+ SetLastError(ERROR_ALREADY_EXISTS);
+ continue;
+ }
+ if (outFile)
+ {
+ if (outFile->Create(path, false))
+ return true;
+ }
+ else
+ {
+ if (CreateDir(path))
+ return true;
+ }
+ DWORD error = GetLastError();
+ if (error != ERROR_FILE_EXISTS &&
+ error != ERROR_ALREADY_EXISTS)
+ break;
+ }
+ path.Empty();
+ return false;
+}
+
+bool CTempFile::Create(CFSTR prefix, NIO::COutFile *outFile)
+{
+ if (!Remove())
+ return false;
+ if (!CreateTempFile(prefix, false, _path, outFile))
+ return false;
_mustBeDeleted = true;
-
- return number;
+ return true;
}
-bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
+bool CTempFile::CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile)
{
- CSysString tempPath;
+ if (!Remove())
+ return false;
+ FString tempPath;
if (!MyGetTempPath(tempPath))
return false;
- if (Create(tempPath, prefix, resultPath) != 0)
- return true;
- return false;
+ if (!CreateTempFile(tempPath + namePrefix, true, _path, outFile))
+ return false;
+ _mustBeDeleted = true;
+ return true;
}
-
bool CTempFile::Remove()
{
if (!_mustBeDeleted)
return true;
- _mustBeDeleted = !DeleteFileAlways(_fileName);
+ _mustBeDeleted = !DeleteFileAlways(_path);
return !_mustBeDeleted;
}
-bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
+bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore)
{
- /*
- CSysString prefix = tempPath + prefixChars;
- CRandom random;
- random.Init();
- */
- for (;;)
- {
- {
- CTempFileW tempFile;
- if (!tempFile.Create(prefix, dirName))
- return false;
- if (!tempFile.Remove())
+ if (deleteDestBefore)
+ if (NFind::DoesFileExist(name))
+ if (!DeleteFileAlways(name))
return false;
- }
- /*
- UINT32 randomNumber = random.Generate();
- TCHAR randomNumberString[32];
- _stprintf(randomNumberString, _T("%04X"), randomNumber);
- dirName = prefix + randomNumberString;
- */
- if (NFind::DoesFileOrDirExist(dirName))
- continue;
- if (MyCreateDirectory(dirName))
- return true;
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
- return false;
- }
+ DisableDeleting();
+ return MyMoveFile(_path, name);
}
-bool CTempDirectory::Create(LPCTSTR prefix)
+bool CTempDir::Create(CFSTR prefix)
{
- Remove();
- return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
+ if (!Remove())
+ return false;
+ FString tempPath;
+ if (!MyGetTempPath(tempPath))
+ return false;
+ if (!CreateTempFile(tempPath + prefix, true, _path, NULL))
+ return false;
+ _mustBeDeleted = true;
+ return true;
}
+bool CTempDir::Remove()
+{
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !RemoveDirectoryWithSubItems(_path);
+ return !_mustBeDeleted;
+}
}}}
+
+
+
diff --git a/src/libs/7zip/unix/CPP/Windows/FileDir.h b/src/libs/7zip/unix/CPP/Windows/FileDir.h
index a7cfbaf8d..02d3e5a57 100644
--- a/src/libs/7zip/unix/CPP/Windows/FileDir.h
+++ b/src/libs/7zip/unix/CPP/Windows/FileDir.h
@@ -1,114 +1,96 @@
// Windows/FileDir.h
-#ifndef __WINDOWS_FILEDIR_H
-#define __WINDOWS_FILEDIR_H
+#ifndef __WINDOWS_FILE_DIR_H
+#define __WINDOWS_FILE_DIR_H
#include "../Common/MyString.h"
-#include "Defs.h"
-/* GetFullPathName for 7zAES.cpp */
-DWORD WINAPI GetFullPathName( LPCSTR name, DWORD len, LPSTR buffer, LPSTR *lastpart );
+#include "FileIO.h"
namespace NWindows {
namespace NFile {
-namespace NDirectory {
+namespace NDir {
-bool SetDirTime(LPCWSTR fileName, const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
+bool GetWindowsDir(FString &path);
+bool GetSystemDir(FString &path);
-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes);
-#ifndef _UNICODE
-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes);
-#endif
+bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
+bool SetFileAttrib(CFSTR path, DWORD attrib);
+bool MyMoveFile(CFSTR existFileName, CFSTR newFileName);
-bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName);
-#ifndef _UNICODE
-bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName);
+#ifndef UNDER_CE
+bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName);
#endif
-bool MyRemoveDirectory(LPCTSTR pathName);
-#ifndef _UNICODE
-bool MyRemoveDirectory(LPCWSTR pathName);
-#endif
+bool RemoveDir(CFSTR path);
+bool CreateDir(CFSTR path);
+bool CreateComplexDir(CFSTR path);
+bool DeleteFileAlways(CFSTR name);
+bool RemoveDirWithSubItems(const FString &path);
-bool MyCreateDirectory(LPCTSTR pathName);
-bool CreateComplexDirectory(LPCTSTR pathName);
-#ifndef _UNICODE
-bool MyCreateDirectory(LPCWSTR pathName);
-bool CreateComplexDirectory(LPCWSTR pathName);
-#endif
+bool MyGetFullPathName(CFSTR path, FString &resFullPath);
+bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName);
+bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix);
-bool DeleteFileAlways(LPCTSTR name);
-#ifndef _UNICODE
-bool DeleteFileAlways(LPCWSTR name);
-#endif
-bool RemoveDirectoryWithSubItems(const UString &path);
-
-#ifndef _WIN32_WCE
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath,
- int &fileNamePartStartIndex);
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath);
-bool GetOnlyName(LPCTSTR fileName, CSysString &resultName);
-bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName);
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath,
- int &fileNamePartStartIndex);
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);
-#endif
-
-#endif
+#ifndef UNDER_CE
-bool MySetCurrentDirectory(LPCWSTR path);
-bool MyGetCurrentDirectory(CSysString &resultPath);
+bool SetCurrentDir(CFSTR path);
+bool GetCurrentDir(FString &resultPath);
-bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath);
-
-bool MyGetTempPath(CSysString &resultPath);
-#ifndef _UNICODE
-bool MyGetTempPath(UString &resultPath);
#endif
+bool MyGetTempPath(FString &resultPath);
+
class CTempFile
{
bool _mustBeDeleted;
- CSysString _fileName;
+ FString _path;
+ void DisableDeleting() { _mustBeDeleted = false; }
public:
CTempFile(): _mustBeDeleted(false) {}
~CTempFile() { Remove(); }
- void DisableDeleting() { _mustBeDeleted = false; }
- UINT Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
- bool Create(LPCTSTR prefix, CSysString &resultPath);
+ const FString &GetPath() const { return _path; }
+ bool Create(CFSTR pathPrefix, NIO::COutFile *outFile); // pathPrefix is not folder prefix
+ bool CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile);
bool Remove();
+ bool MoveTo(CFSTR name, bool deleteDestBefore);
};
-#ifdef _UNICODE
-typedef CTempFile CTempFileW;
-#endif
-
-bool CreateTempDirectory(LPCWSTR prefixChars, UString &dirName);
-
-class CTempDirectory
+class CTempDir
{
bool _mustBeDeleted;
- CSysString _tempDir;
+ FString _path;
public:
- const CSysString &GetPath() const { return _tempDir; }
- CTempDirectory(): _mustBeDeleted(false) {}
- ~CTempDirectory() { Remove(); }
- bool Create(LPCTSTR prefix) ;
- bool Remove()
- {
- if (!_mustBeDeleted)
- return true;
- _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
- return (!_mustBeDeleted);
- }
+ CTempDir(): _mustBeDeleted(false) {}
+ ~CTempDir() { Remove(); }
+ const FString &GetPath() const { return _path; }
void DisableDeleting() { _mustBeDeleted = false; }
+ bool Create(CFSTR namePrefix) ;
+ bool Remove();
};
-#ifdef _UNICODE
-typedef CTempDirectory CTempDirectoryW;
-#endif
+#if !defined(UNDER_CE)
+class CCurrentDirRestorer
+{
+ FString _path;
+public:
+ bool NeedRestore;
+ CCurrentDirRestorer(): NeedRestore(true)
+ {
+ GetCurrentDir(_path);
+ }
+ ~CCurrentDirRestorer()
+ {
+ if (!NeedRestore)
+ return;
+ FString s;
+ if (GetCurrentDir(s))
+ if (s != _path)
+ SetCurrentDir(_path);
+ }
+};
+#endif
}}}
diff --git a/src/libs/7zip/unix/CPP/Windows/FileFind.cpp b/src/libs/7zip/unix/CPP/Windows/FileFind.cpp
index 9e526a233..eb2f93835 100644
--- a/src/libs/7zip/unix/CPP/Windows/FileFind.cpp
+++ b/src/libs/7zip/unix/CPP/Windows/FileFind.cpp
@@ -3,8 +3,15 @@
#include "StdAfx.h"
#include "FileFind.h"
+#include "FileIO.h"
+
#include "../Common/StringConvert.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
@@ -32,9 +39,9 @@ void my_windows_split_path(const AString &p_path, AString &dir , AString &base)
base = ".";
else
base = p_path;
- } else if ((pos+1) < p_path.Length()) {
+ } else if ((pos+1) < p_path.Len()) {
// true separator
- base = p_path.Mid(pos+1);
+ base = p_path.Ptr(pos+1);
while ((pos >= 1) && (p_path[pos-1] == '/'))
pos--;
if (pos == 0)
@@ -69,9 +76,9 @@ static void my_windows_split_path(const UString &p_path, UString &dir , UString
base = L".";
else
base = p_path;
- } else if ((pos+1) < p_path.Length()) {
+ } else if ((pos+1) < p_path.Len()) {
// true separator
- base = p_path.Mid(pos+1);
+ base = p_path.Ptr(pos+1);
while ((pos >= 1) && (p_path[pos-1] == L'/'))
pos--;
if (pos == 0)
@@ -128,30 +135,71 @@ static int filter_pattern(const char *string , const char *pattern , int flags_n
return 0;
}
-
namespace NWindows {
namespace NFile {
-namespace NFind {
-static const TCHAR kDot = TEXT('.');
+#ifdef SUPPORT_DEVICE_FILE
+bool IsDeviceName(CFSTR n);
+#endif
+
+#if defined(WIN_LONG_PATH)
+bool GetLongPath(CFSTR fileName, UString &res);
+#endif
+
+namespace NFind {
bool CFileInfo::IsDots() const
-{
+{
if (!IsDir() || Name.IsEmpty())
return false;
- if (Name[0] != kDot)
+ if (Name[0] != FTEXT('.'))
return false;
- return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+ return Name.Len() == 1 || (Name.Len() == 2 && Name[1] == FTEXT('.'));
}
-bool CFileInfoW::IsDots() const
-{
- if (!IsDir() || Name.IsEmpty())
- return false;
- if (Name[0] != kDot)
- return false;
- return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+#define WIN_FD_TO_MY_FI(fi, fd) \
+ fi.Attrib = fd.dwFileAttributes; \
+ fi.CTime = fd.ftCreationTime; \
+ fi.ATime = fd.ftLastAccessTime; \
+ fi.MTime = fd.ftLastWriteTime; \
+ fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; \
+ fi.IsDevice = false;
+
+ /*
+ #ifdef UNDER_CE
+ fi.ObjectID = fd.dwOID;
+ #else
+ fi.ReparseTag = fd.dwReserved0;
+ #endif
+ */
+
+#ifndef _UNICODE
+
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
+{
+ WIN_FD_TO_MY_FI(fi, fd);
+ fi.Name = fas2fs(fd.cFileName);
}
+#endif
+
+////////////////////////////////
+// CFindFile
+
+bool CFindFile::Close()
+{
+ if(_dirp == 0)
+ return true;
+ int ret = closedir(_dirp);
+ if (ret == 0)
+ {
+ _dirp = 0;
+ return true;
+ }
+ return false;
+}
+
static bool originalFilename(const UString & src, AString & res)
{
@@ -170,15 +218,13 @@ static bool originalFilename(const UString & src, AString & res)
return true;
}
-
-
// Warning this function cannot update "fileInfo.Name"
-static int fillin_CFileInfo(CFileInfo &fileInfo,const char *filename) {
+static int fillin_CFileInfo(CFileInfo &fileInfo,const char *filename,bool ignoreLink) {
struct stat stat_info;
int ret;
#ifdef ENV_HAVE_LSTAT
- if (global_use_lstat) {
+ if ( (global_use_lstat) && (ignoreLink == false)) {
ret = lstat(filename,&stat_info);
} else
#endif
@@ -186,6 +232,9 @@ static int fillin_CFileInfo(CFileInfo &fileInfo,const char *filename) {
ret = stat(filename,&stat_info);
}
+ // printf("fillin_CFileInfo(%s,%d)=%d mode=%o\n",filename,(int)ignoreLink,ret,(unsigned)stat_info.st_mode);
+
+
if (ret != 0) return ret;
/* FIXME : FILE_ATTRIBUTE_HIDDEN ? */
@@ -214,7 +263,7 @@ static int fillin_CFileInfo(CFileInfo &fileInfo,const char *filename) {
return 0;
}
-static int fillin_CFileInfo(CFileInfo &fileInfo,const char *dir,const char *name) {
+static int fillin_CFileInfo(CFileInfo &fi,const char *dir,const char *name,bool ignoreLink) {
char filename[MAX_PATHNAME_LEN];
size_t dir_len = strlen(dir);
size_t name_len = strlen(name);
@@ -231,9 +280,13 @@ static int fillin_CFileInfo(CFileInfo &fileInfo,const char *dir,const char *name
filename[dir_len] = CHAR_PATH_SEPARATOR;
memcpy(filename+(dir_len+1),name,name_len+1); // copy also final '\0'
- fileInfo.Name = name;
+#ifdef _UNICODE
+ fi.Name = GetUnicodeString(name, CP_ACP);
+#else
+ fi.Name = name;
+#endif
- int ret = fillin_CFileInfo(fileInfo,filename);
+ int ret = fillin_CFileInfo(fi,filename,ignoreLink);
if (ret != 0) {
AString err_msg = "stat error for ";
err_msg += filename;
@@ -245,36 +298,22 @@ static int fillin_CFileInfo(CFileInfo &fileInfo,const char *dir,const char *name
return ret;
}
-////////////////////////////////
-// CFindFile
-
-bool CFindFile::Close()
-{
-
- if(_dirp == 0)
- return true;
- int ret = closedir(_dirp);
- if (ret == 0)
- {
- _dirp = 0;
- return true;
- }
- return false;
-}
-
-// bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo)
-bool CFindFile::FindFirst(LPCSTR wildcard, CFileInfo &fileInfo)
+bool CFindFile::FindFirst(CFSTR cfWildcard, CFileInfo &fi, bool ignoreLink)
{
if (!Close())
return false;
+ AString Awildcard = UnicodeStringToMultiByte(cfWildcard, CP_ACP);
+ const char * wildcard = (const char *)Awildcard;
+
+
if ((!wildcard) || (wildcard[0]==0)) {
SetLastError(ERROR_PATH_NOT_FOUND);
return false;
}
-
+
my_windows_split_path(nameWindowToUnix(wildcard),_directory,_pattern);
-
+
TRACEN((printf("CFindFile::FindFirst : %s (dirname=%s,pattern=%s)\n",wildcard,(const char *)_directory,(const char *)_pattern)))
_dirp = ::opendir((const char *)_directory);
@@ -296,7 +335,7 @@ bool CFindFile::FindFirst(LPCSTR wildcard, CFileInfo &fileInfo)
struct dirent *dp;
while ((dp = readdir(_dirp)) != NULL) {
if (filter_pattern(dp->d_name,(const char *)_pattern,0) == 1) {
- int retf = fillin_CFileInfo(fileInfo,(const char *)_directory,dp->d_name);
+ int retf = fillin_CFileInfo(fi,(const char *)_directory,dp->d_name,ignoreLink);
if (retf)
{
TRACEN((printf("CFindFile::FindFirst : closedir-1(dirp=%p)\n",_dirp)))
@@ -315,29 +354,10 @@ bool CFindFile::FindFirst(LPCSTR wildcard, CFileInfo &fileInfo)
_dirp = 0;
SetLastError( ERROR_NO_MORE_FILES );
return false;
-}
-bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo)
-{
- if (!Close())
- return false;
- CFileInfo fileInfo0;
- AString Awildcard = UnicodeStringToMultiByte(wildcard, CP_ACP);
- bool bret = FindFirst((LPCSTR)Awildcard, fileInfo0);
- if (bret)
- {
- fileInfo.Attrib = fileInfo0.Attrib;
- fileInfo.CTime = fileInfo0.CTime;
- fileInfo.ATime = fileInfo0.ATime;
- fileInfo.MTime = fileInfo0.MTime;
- fileInfo.Size = fileInfo0.Size;
- fileInfo.IsDevice = fileInfo0.IsDevice;
- fileInfo.Name = GetUnicodeString(fileInfo0.Name, CP_ACP);
- }
- return bret;
}
-bool CFindFile::FindNext(CFileInfo &fileInfo)
+bool CFindFile::FindNext(CFileInfo &fi)
{
if (_dirp == 0)
{
@@ -348,7 +368,7 @@ bool CFindFile::FindNext(CFileInfo &fileInfo)
struct dirent *dp;
while ((dp = readdir(_dirp)) != NULL) {
if (filter_pattern(dp->d_name,(const char *)_pattern,0) == 1) {
- int retf = fillin_CFileInfo(fileInfo,(const char *)_directory,dp->d_name);
+ int retf = fillin_CFileInfo(fi,(const char *)_directory,dp->d_name,false);
if (retf)
{
TRACEN((printf("FindNextFileA -%s- ret_handle=FALSE (errno=%d)\n",dp->d_name,errno)))
@@ -364,46 +384,18 @@ bool CFindFile::FindNext(CFileInfo &fileInfo)
return false;
}
-bool CFindFile::FindNext(CFileInfoW &fileInfo)
-{
- CFileInfo fileInfo0;
- bool bret = FindNext(fileInfo0);
- if (bret)
- {
- fileInfo.Attrib = fileInfo0.Attrib;
- fileInfo.CTime = fileInfo0.CTime;
- fileInfo.ATime = fileInfo0.ATime;
- fileInfo.MTime = fileInfo0.MTime;
- fileInfo.Size = fileInfo0.Size;
- fileInfo.IsDevice = fileInfo0.IsDevice;
- fileInfo.Name = GetUnicodeString(fileInfo0.Name, CP_ACP);
- }
- return bret;
-}
+#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0;
-bool CFileInfo::Find(LPCSTR wildcard)
+void CFileInfoBase::Clear()
{
- #ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceName(wildcard))
- {
- Clear();
- IsDevice = true;
- NIO::CInFile inFile;
- if (!inFile.Open(wildcard))
- return false;
- Name = wildcard + 4;
- if (inFile.LengthDefined)
- Size = inFile.Length;
- return true;
- }
- #endif
- CFindFile finder;
- return finder.FindFirst(wildcard, *this);
+ Size = 0;
+ MY_CLEAR_FILETIME(CTime);
+ MY_CLEAR_FILETIME(ATime);
+ MY_CLEAR_FILETIME(MTime);
+ Attrib = 0;
}
-
-// #ifndef _UNICODE
-bool CFileInfoW::Find(LPCWSTR wildcard)
+bool CFileInfo::Find(CFSTR wildcard, bool ignoreLink)
{
#ifdef SUPPORT_DEVICE_FILE
if (IsDeviceName(wildcard))
@@ -420,148 +412,88 @@ bool CFileInfoW::Find(LPCWSTR wildcard)
}
#endif
CFindFile finder;
- return finder.FindFirst(wildcard, *this);
-}
-// #endif
-
-bool FindFile(LPCSTR wildcard, CFileInfo &fileInfo)
-{
- // CFindFile finder;
- // return finder.FindFirst(wildcard, fileInfo);
- AString dir,base;
- my_windows_split_path(wildcard, dir , base);
- int ret = fillin_CFileInfo(fileInfo,nameWindowToUnix(wildcard));
- fileInfo.Name = base;
- TRACEN((printf("FindFile(%s,CFileInfo) ret=%d\n",wildcard,ret)))
- return (ret == 0);
-}
-
-bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo)
-{
- // CFindFile finder;
- // return finder.FindFirst(wildcard, fileInfo);
- AString name = UnicodeStringToMultiByte(wildcard, CP_ACP);
- CFileInfo fileInfo0;
- int ret = fillin_CFileInfo(fileInfo0,nameWindowToUnix((const char *)name));
- TRACEN((printf("FindFile-1(%s,CFileInfo) ret=%d\n",(const char *)name,ret)))
- if (ret != 0)
+ if (finder.FindFirst(wildcard, *this,ignoreLink))
+ return true;
+ #ifdef _WIN32
{
- // Try to recover the original filename
- AString resultString;
- bool is_good = originalFilename(wildcard, resultString);
- if (is_good) {
- ret = fillin_CFileInfo(fileInfo0,nameWindowToUnix((const char *)resultString));
- TRACEN((printf("FindFile-2(%s,CFileInfo) ret=%d\n",(const char *)resultString,ret)))
+ DWORD lastError = GetLastError();
+ if (lastError == ERROR_BAD_NETPATH || lastError == ERROR_FILE_NOT_FOUND)
+ {
+ int len = MyStringLen(wildcard);
+ if (len > 2 && wildcard[0] == '\\' && wildcard[1] == '\\')
+ {
+ int pos = FindCharPosInString(wildcard + 2, FTEXT('\\'));
+ if (pos >= 0)
+ {
+ pos += 2 + 1;
+ len -= pos;
+ CFSTR remString = wildcard + pos;
+ int pos2 = FindCharPosInString(remString, FTEXT('\\'));
+ FString s = wildcard;
+ if (pos2 < 0 || pos2 == len - 1)
+ {
+ FString s = wildcard;
+ if (pos2 < 0)
+ {
+ pos2 = len;
+ s += FTEXT('\\');
+ }
+ s += FCHAR_ANY_MASK;
+ if (finder.FindFirst(s, *this))
+ if (Name == FTEXT("."))
+ {
+ Name.SetFrom(s.Ptr(pos), pos2);
+ return true;
+ }
+ ::SetLastError(lastError);
+ }
+ }
+ }
}
}
- if (ret == 0)
- {
- UString dir,base;
- my_windows_split_path(wildcard, dir , base);
- fileInfo.Attrib = fileInfo0.Attrib;
- fileInfo.CTime = fileInfo0.CTime;
- fileInfo.ATime = fileInfo0.ATime;
- fileInfo.MTime = fileInfo0.MTime;
- fileInfo.Size = fileInfo0.Size;
- fileInfo.Name = base;
- }
- return (ret == 0);
+ #endif
+ return false;
}
-bool DoesFileExist(LPCSTR name) // FIXME
+bool DoesFileExist(CFSTR name)
{
CFileInfo fi;
- int ret = fillin_CFileInfo(fi,nameWindowToUnix(name));
- TRACEN((printf("DoesFileExist(%s) ret=%d\n",name,ret)))
- return (ret == 0) && !fi.IsDir();;
+ return fi.Find(name) && !fi.IsDir();
}
-bool DoesDirExist(LPCSTR name) // FIXME
+bool DoesDirExist(CFSTR name)
{
CFileInfo fi;
- int ret = fillin_CFileInfo(fi,nameWindowToUnix(name));
- TRACEN((printf("DoesDirExist(%s) ret=%d\n",name,ret)))
- return (ret == 0) && fi.IsDir();;
-}
-
-bool DoesFileOrDirExist(LPCSTR name)
-{
- CFileInfo fileInfo;
- int ret = fillin_CFileInfo(fileInfo,nameWindowToUnix(name));
- TRACEN((printf("DoesFileOrDirExist(%s) ret=%d\n",name,ret)))
- return (ret == 0);
-}
-
-bool DoesFileExist(LPCWSTR name)
-{
- AString Aname = UnicodeStringToMultiByte(name, CP_ACP);
- bool bret = DoesFileExist((LPCSTR)Aname);
- if (bret) return bret;
-
- // Try to recover the original filename
- AString resultString;
- bool is_good = originalFilename(name, resultString);
- if (is_good) {
- bret = DoesFileExist((const char *)resultString);
- }
- return bret;
-}
-
-bool DoesDirExist(LPCWSTR name)
-{
- AString Aname = UnicodeStringToMultiByte(name, CP_ACP);
- bool bret = DoesDirExist((LPCSTR)Aname);
- if (bret) return bret;
-
- // Try to recover the original filename
- AString resultString;
- bool is_good = originalFilename(name, resultString);
- if (is_good) {
- bret = DoesDirExist((const char *)resultString);
- }
- return bret;
+ return fi.Find(name) && fi.IsDir();
}
-
-bool DoesFileOrDirExist(LPCWSTR name)
+bool DoesFileOrDirExist(CFSTR name)
{
- AString Aname = UnicodeStringToMultiByte(name, CP_ACP);
- bool bret = DoesFileOrDirExist((LPCSTR)Aname);
- if (bret) return bret;
-
- // Try to recover the original filename
- AString resultString;
- bool is_good = originalFilename(name, resultString);
- if (is_good) {
- bret = DoesFileOrDirExist((const char *)resultString);
- }
- return bret;
+ CFileInfo fi;
+ return fi.Find(name);
}
-/////////////////////////////////////
-// CEnumerator
-
-bool CEnumerator::NextAny(CFileInfo &fileInfo)
+bool CEnumerator::NextAny(CFileInfo &fi)
{
- if(_findFile.IsHandleAllocated())
- return _findFile.FindNext(fileInfo);
+ if (_findFile.IsHandleAllocated())
+ return _findFile.FindNext(fi);
else
- return _findFile.FindFirst(_wildcard, fileInfo);
+ return _findFile.FindFirst(_wildcard, fi);
}
-bool CEnumerator::Next(CFileInfo &fileInfo)
+bool CEnumerator::Next(CFileInfo &fi)
{
- while(true)
+ for (;;)
{
- if(!NextAny(fileInfo))
+ if (!NextAny(fi))
return false;
- if(!fileInfo.IsDots())
+ if (!fi.IsDots())
return true;
}
}
-bool CEnumerator::Next(CFileInfo &fileInfo, bool &found)
+bool CEnumerator::Next(CFileInfo &fi, bool &found)
{
- if (Next(fileInfo))
+ if (Next(fi))
{
found = true;
return true;
@@ -570,35 +502,100 @@ bool CEnumerator::Next(CFileInfo &fileInfo, bool &found)
return (::GetLastError() == ERROR_NO_MORE_FILES);
}
-bool CEnumeratorW::NextAny(CFileInfoW &fileInfo)
+////////////////////////////////
+// CFindChangeNotification
+// FindFirstChangeNotification can return 0. MSDN doesn't tell about it.
+
+#ifdef _WIN32
+bool CFindChangeNotification::Close()
{
- if(_findFile.IsHandleAllocated())
- return _findFile.FindNext(fileInfo);
- else
- return _findFile.FindFirst(_wildcard, fileInfo);
+ if (!IsHandleAllocated())
+ return true;
+ if (!::FindCloseChangeNotification(_handle))
+ return false;
+ _handle = INVALID_HANDLE_VALUE;
+ return true;
}
-bool CEnumeratorW::Next(CFileInfoW &fileInfo)
+HANDLE CFindChangeNotification::FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter)
{
- while(true)
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ _handle = ::FindFirstChangeNotification(fs2fas(pathName), BoolToBOOL(watchSubtree), notifyFilter);
+ else
+ #endif
{
- if(!NextAny(fileInfo))
- return false;
- if(!fileInfo.IsDots())
- return true;
+ _handle = ::FindFirstChangeNotificationW(fs2us(pathName), BoolToBOOL(watchSubtree), notifyFilter);
+ #ifdef WIN_LONG_PATH
+ if (!IsHandleAllocated())
+ {
+ UString longPath;
+ if (GetLongPath(pathName, longPath))
+ _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ }
+ #endif
}
+ return _handle;
}
-bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found)
+#ifndef UNDER_CE
+
+bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings)
{
- if (Next(fileInfo))
+ driveStrings.Clear();
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- found = true;
- return true;
+ driveStrings.Clear();
+ UINT32 size = GetLogicalDriveStrings(0, NULL);
+ if (size == 0)
+ return false;
+ AString buf;
+ UINT32 newSize = GetLogicalDriveStrings(size, buf.GetBuffer(size));
+ if (newSize == 0 || newSize > size)
+ return false;
+ AString s;
+ for (UINT32 i = 0; i < newSize; i++)
+ {
+ char c = buf[i];
+ if (c == '\0')
+ {
+ driveStrings.Add(fas2fs(s));
+ s.Empty();
+ }
+ else
+ s += c;
+ }
+ return s.IsEmpty();
+ }
+ else
+ #endif
+ {
+ UINT32 size = GetLogicalDriveStringsW(0, NULL);
+ if (size == 0)
+ return false;
+ UString buf;
+ UINT32 newSize = GetLogicalDriveStringsW(size, buf.GetBuffer(size));
+ if (newSize == 0 || newSize > size)
+ return false;
+ UString s;
+ for (UINT32 i = 0; i < newSize; i++)
+ {
+ WCHAR c = buf[i];
+ if (c == L'\0')
+ {
+ driveStrings.Add(us2fs(s));
+ s.Empty();
+ }
+ else
+ s += c;
+ }
+ return s.IsEmpty();
}
- found = false;
- return (::GetLastError() == ERROR_NO_MORE_FILES);
}
+#endif
+
+#endif // _WIN32
}}}
diff --git a/src/libs/7zip/unix/CPP/Windows/FileFind.h b/src/libs/7zip/unix/CPP/Windows/FileFind.h
index a1fd0f072..06435bb3d 100644
--- a/src/libs/7zip/unix/CPP/Windows/FileFind.h
+++ b/src/libs/7zip/unix/CPP/Windows/FileFind.h
@@ -1,10 +1,10 @@
// Windows/FileFind.h
-#ifndef __WINDOWS_FILEFIND_H
-#define __WINDOWS_FILEFIND_H
+#ifndef __WINDOWS_FILE_FIND_H
+#define __WINDOWS_FILE_FIND_H
#include "../Common/MyString.h"
-#include "FileName.h"
+#include "../Common/MyTypes.h"
#include "Defs.h"
#include <sys/types.h> /* for DIR */
@@ -26,8 +26,10 @@ namespace NAttributes
}
class CFileInfoBase
-{
- bool MatchesMask(UINT32 mask) const { return ((Attrib & mask) != 0); }
+{
+ bool MatchesMask(UINT32 mask) const { return ((Attrib & mask) != 0); }
+protected:
+ void Clear();
public:
UInt64 Size;
FILETIME CTime;
@@ -35,92 +37,87 @@ public:
FILETIME MTime;
DWORD Attrib;
bool IsDevice;
-
+
+ /*
+ #ifdef UNDER_CE
+ DWORD ObjectID;
+ #else
+ UINT32 ReparseTag;
+ #endif
+ */
+
+ bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
+ bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
bool IsDir() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); }
+ bool IsEncrypted() const { return MatchesMask(FILE_ATTRIBUTE_ENCRYPTED); }
+ bool IsHidden() const { return MatchesMask(FILE_ATTRIBUTE_HIDDEN); }
+ bool IsNormal() const { return MatchesMask(FILE_ATTRIBUTE_NORMAL); }
+ bool IsOffline() const { return MatchesMask(FILE_ATTRIBUTE_OFFLINE); }
+ bool IsReadOnly() const { return MatchesMask(FILE_ATTRIBUTE_READONLY); }
+ bool HasReparsePoint() const { return MatchesMask(FILE_ATTRIBUTE_REPARSE_POINT); }
+ bool IsSparse() const { return MatchesMask(FILE_ATTRIBUTE_SPARSE_FILE); }
+ bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); }
+ bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); }
};
-class CFileInfo: public CFileInfoBase
-{
-public:
- AString Name; // FIXME CSysString Name;
- bool IsDots() const;
- bool Find(LPCSTR wildcard);
-};
+struct CFileInfo: public CFileInfoBase
+{
+ FString Name;
-// FIXME #ifdef _UNICODE
-// typedef CFileInfo CFileInfoW;
-// #else
-class CFileInfoW: public CFileInfoBase
-{
-public:
- UString Name;
bool IsDots() const;
- bool Find(LPCWSTR wildcard);
+ bool Find(CFSTR wildcard, bool ignoreLink = false);
};
-// #endif
class CFindFile
{
friend class CEnumerator;
DIR *_dirp;
AString _pattern;
- AString _directory;
+ AString _directory;
public:
- bool IsHandleAllocated() const { return (_dirp != 0); }
+ bool IsHandleAllocated() const { return (_dirp != 0); }
CFindFile(): _dirp(0) {}
- ~CFindFile() { Close(); }
- // bool FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo);
- bool FindFirst(LPCSTR wildcard, CFileInfo &fileInfo);
+ ~CFindFile() { Close(); }
+ bool FindFirst(CFSTR wildcard, CFileInfo &fileInfo, bool ignoreLink = false);
bool FindNext(CFileInfo &fileInfo);
- // FIXME #ifndef _UNICODE
- bool FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo);
- bool FindNext(CFileInfoW &fileInfo);
- // FIXME #endif
bool Close();
};
-bool FindFile(LPCSTR wildcard, CFileInfo &fileInfo);
-
-bool DoesFileExist(LPCSTR name);
-bool DoesDirExist(LPCTSTR name);
-bool DoesFileOrDirExist(LPCSTR name);
-// #ifndef _UNICODE
-bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo);
-bool DoesFileExist(LPCWSTR name);
-bool DoesDirExist(LPCWSTR name);
-bool DoesFileOrDirExist(LPCWSTR name);
-// #endif
+bool DoesFileExist(CFSTR name);
+bool DoesDirExist(CFSTR name);
+bool DoesFileOrDirExist(CFSTR name);
class CEnumerator
{
CFindFile _findFile;
- AString _wildcard; // FIXME CSysString _wildcard;
+ FString _wildcard;
+
bool NextAny(CFileInfo &fileInfo);
public:
- CEnumerator(): _wildcard(NName::kAnyStringWildcard) {}
- // FIXME CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {}
- CEnumerator(const AString &wildcard): _wildcard(wildcard) {}
+ CEnumerator(const FString &wildcard): _wildcard(wildcard) {}
bool Next(CFileInfo &fileInfo);
bool Next(CFileInfo &fileInfo, bool &found);
};
-// FIXME #ifdef _UNICODE
-// typedef CEnumerator CEnumeratorW;
-// #else
-class CEnumeratorW
+#ifdef _WIN32
+class CFindChangeNotification
{
- CFindFile _findFile;
- UString _wildcard;
- bool NextAny(CFileInfoW &fileInfo);
+ HANDLE _handle;
public:
- CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {}
- CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {}
- bool Next(CFileInfoW &fileInfo);
- bool Next(CFileInfoW &fileInfo, bool &found);
+ operator HANDLE () { return _handle; }
+ bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE && _handle != 0; }
+ CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {}
+ ~CFindChangeNotification() { Close(); }
+ bool Close();
+ HANDLE FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter);
+ bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); }
};
-// FIXME #endif
+#endif
+
+#ifndef UNDER_CE
+bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings);
+#endif
}}}
#endif
-
diff --git a/src/libs/7zip/unix/CPP/Windows/FileIO.cpp b/src/libs/7zip/unix/CPP/Windows/FileIO.cpp
index 5080579fe..5da074a0f 100644
--- a/src/libs/7zip/unix/CPP/Windows/FileIO.cpp
+++ b/src/libs/7zip/unix/CPP/Windows/FileIO.cpp
@@ -37,10 +37,10 @@ CFileBase::~CFileBase()
}
bool CFileBase::Create(LPCSTR filename, DWORD dwDesiredAccess,
- DWORD /*dwShareMode*/, DWORD dwCreationDisposition, DWORD /*dwFlagsAndAttributes*/,bool ignoreSymbolicLink)
+ DWORD dwShareMode, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,bool ignoreSymbolicLink)
{
Close();
-
+
int flags = 0;
const char * name = nameWindowToUnix(filename);
@@ -98,7 +98,7 @@ bool CFileBase::Create(LPCSTR filename, DWORD dwDesiredAccess,
UString ustr = MultiByteToUnicodeString(AString(name), 0);
AString resultString;
int is_good = 1;
- for (int i = 0; i < ustr.Length(); i++)
+ for (int i = 0; i < ustr.Len(); i++)
{
if (ustr[i] >= 256) {
is_good = 0;
@@ -126,7 +126,7 @@ bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess,
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes,bool ignoreSymbolicLink)
{
Close();
- return Create(UnicodeStringToMultiByte(fileName, CP_ACP),
+ return Create(UnicodeStringToMultiByte(fileName, CP_ACP),
desiredAccess, shareMode, creationDisposition, flagsAndAttributes,ignoreSymbolicLink);
}
@@ -180,7 +180,7 @@ bool CFileBase::GetLength(UINT64 &length) const
return false;
}
-#ifdef ENV_HAVE_LSTAT
+#ifdef ENV_HAVE_LSTAT
if (_fd == FD_LINK) {
length = _size;
return true;
@@ -254,24 +254,24 @@ bool CFileBase::Seek(UINT64 position, UINT64 &newPosition)
/////////////////////////
// CInFile
-bool CInFile::Open(LPCTSTR fileName, DWORD shareMode,
+bool CInFile::Open(LPCTSTR fileName, DWORD shareMode,
DWORD creationDisposition, DWORD flagsAndAttributes)
{
- return Create(fileName, GENERIC_READ, shareMode,
+ return Create(fileName, GENERIC_READ, shareMode,
creationDisposition, flagsAndAttributes);
}
bool CInFile::Open(LPCTSTR fileName,bool ignoreSymbolicLink)
{
- return Create(fileName, GENERIC_READ , FILE_SHARE_READ, OPEN_EXISTING,
+ return Create(fileName, GENERIC_READ , FILE_SHARE_READ, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,ignoreSymbolicLink);
}
#ifndef _UNICODE
-bool CInFile::Open(LPCWSTR fileName, DWORD shareMode,
+bool CInFile::Open(LPCWSTR fileName, DWORD shareMode,
DWORD creationDisposition, DWORD flagsAndAttributes)
{
- return Create(fileName, GENERIC_READ, shareMode,
+ return Create(fileName, GENERIC_READ, shareMode,
creationDisposition, flagsAndAttributes);
}
@@ -282,8 +282,8 @@ bool CInFile::Open(LPCWSTR fileName,bool ignoreSymbolicLink)
#endif
// ReadFile and WriteFile functions in Windows have BUG:
-// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
-// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
+// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
+// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
// (Insufficient system resources exist to complete the requested service).
// static UINT32 kChunkSizeMax = (1 << 24);
@@ -339,10 +339,10 @@ bool CInFile::Read(void *buffer, UINT32 bytesToRead, UINT32 &bytesRead)
/////////////////////////
// COutFile
-bool COutFile::Open(LPCTSTR fileName, DWORD shareMode,
+bool COutFile::Open(LPCTSTR fileName, DWORD shareMode,
DWORD creationDisposition, DWORD flagsAndAttributes)
{
- return CFileBase::Create(fileName, GENERIC_WRITE, shareMode,
+ return CFileBase::Create(fileName, GENERIC_WRITE, shareMode,
creationDisposition, flagsAndAttributes);
}
@@ -351,7 +351,7 @@ static inline DWORD GetCreationDisposition(bool createAlways)
bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition)
{
- return Open(fileName, FILE_SHARE_READ,
+ return Open(fileName, FILE_SHARE_READ,
creationDisposition, FILE_ATTRIBUTE_NORMAL);
}
@@ -360,18 +360,23 @@ bool COutFile::Create(LPCTSTR fileName, bool createAlways)
return Open(fileName, GetCreationDisposition(createAlways));
}
+bool COutFile::CreateAlways(LPCTSTR fileName, DWORD /* flagsAndAttributes */ )
+{
+ return Open(fileName, true); // FIXME
+}
+
#ifndef _UNICODE
-bool COutFile::Open(LPCWSTR fileName, DWORD shareMode,
+bool COutFile::Open(LPCWSTR fileName, DWORD shareMode,
DWORD creationDisposition, DWORD flagsAndAttributes)
{
- return CFileBase::Create(fileName, GENERIC_WRITE, shareMode,
+ return CFileBase::Create(fileName, GENERIC_WRITE, shareMode,
creationDisposition, flagsAndAttributes);
}
bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition)
{
- return Open(fileName, FILE_SHARE_READ,
+ return Open(fileName, FILE_SHARE_READ,
creationDisposition, FILE_ATTRIBUTE_NORMAL);
}
diff --git a/src/libs/7zip/unix/CPP/Windows/FileIO.h b/src/libs/7zip/unix/CPP/Windows/FileIO.h
index 4aa84c053..a262e5610 100644
--- a/src/libs/7zip/unix/CPP/Windows/FileIO.h
+++ b/src/libs/7zip/unix/CPP/Windows/FileIO.h
@@ -15,12 +15,6 @@
#define FILE_END SEEK_END
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
-#define CREATE_NEW 1
-#define CREATE_ALWAYS 2
-#define OPEN_EXISTING 3
-#define OPEN_ALWAYS 4
-/* #define TRUNCATE_EXISTING 5 */
-
#endif
namespace NWindows {
@@ -83,6 +77,7 @@ public:
bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
bool Open(LPCTSTR fileName, DWORD creationDisposition);
bool Create(LPCTSTR fileName, bool createAlways);
+ bool CreateAlways(LPCTSTR fileName, DWORD flagsAndAttributes);
#ifndef _UNICODE
bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
diff --git a/src/libs/7zip/unix/CPP/Windows/FileName.cpp b/src/libs/7zip/unix/CPP/Windows/FileName.cpp
index 8443a4af9..b726976fe 100644
--- a/src/libs/7zip/unix/CPP/Windows/FileName.cpp
+++ b/src/libs/7zip/unix/CPP/Windows/FileName.cpp
@@ -5,15 +5,25 @@
#include "Windows/FileName.h"
#include "Common/Wildcard.h"
+// FIXME
+namespace NWindows {
+namespace NFile {
+namespace NDir {
+bool MyGetFullPathName(CFSTR path, FString &resFullPath);
+}}}
+
namespace NWindows {
namespace NFile {
namespace NName {
+bool IsAbsolutePath(const wchar_t *s) { return s[0] == WCHAR_PATH_SEPARATOR; } // FIXME
+
+
void NormalizeDirPathPrefix(CSysString &dirPath)
{
if (dirPath.IsEmpty())
return;
- if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Length() - 1)
+ if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Len() - 1)
dirPath += kDirDelimiter;
}
@@ -22,29 +32,16 @@ void NormalizeDirPathPrefix(UString &dirPath)
{
if (dirPath.IsEmpty())
return;
- if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Length() - 1)
- dirPath += wchar_t(kDirDelimiter);
+ if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Len() - 1)
+ dirPath += wchar_t(kDirDelimiter);
}
#endif
-const wchar_t kExtensionDelimiter = L'.';
-
-void SplitNameToPureNameAndExtension(const UString &fullName,
- UString &pureName, UString &extensionDelimiter, UString &extension)
+bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
{
- int index = fullName.ReverseFind(kExtensionDelimiter);
- if (index < 0)
- {
- pureName = fullName;
- extensionDelimiter.Empty();
- extension.Empty();
- }
- else
- {
- pureName = fullName.Left(index);
- extensionDelimiter = kExtensionDelimiter;
- extension = fullName.Mid(index + 1);
- }
+ res = FString(dirPrefix) + FString(s);
+
+ return true;
}
}}}
diff --git a/src/libs/7zip/unix/CPP/Windows/FileName.h b/src/libs/7zip/unix/CPP/Windows/FileName.h
index d98079026..19c585fc9 100644
--- a/src/libs/7zip/unix/CPP/Windows/FileName.h
+++ b/src/libs/7zip/unix/CPP/Windows/FileName.h
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_FILENAME_H
#define __WINDOWS_FILENAME_H
-#include "../../C/Types.h"
+#include "../../C/7zTypes.h"
#include "../Common/MyString.h"
@@ -19,8 +19,10 @@ void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with
void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\'
#endif
-void SplitNameToPureNameAndExtension(const UString &fullName,
- UString &pureName, UString &extensionDelimiter, UString &extension);
+bool IsAbsolutePath(const wchar_t *s);
+
+bool GetFullPath(CFSTR dirPrefix, CFSTR path, FString &fullPath);
+// FIXME bool GetFullPath(CFSTR path, FString &fullPath);
}}}
diff --git a/src/libs/7zip/unix/CPP/Windows/Handle.h b/src/libs/7zip/unix/CPP/Windows/Handle.h
deleted file mode 100644
index 0791b4acd..000000000
--- a/src/libs/7zip/unix/CPP/Windows/Handle.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Windows/Handle.h
-
-#ifndef __WINDOWS_HANDLE_H
-#define __WINDOWS_HANDLE_H
-
-namespace NWindows {
-
-class CHandle
-{
-protected:
- HANDLE _handle;
-public:
- operator HANDLE() { return _handle; }
- CHandle(): _handle(NULL) {}
- ~CHandle() { Close(); }
- bool Close()
- {
- if (_handle == NULL)
- return true;
- if (!::CloseHandle(_handle))
- return false;
- _handle = NULL;
- return true;
- }
- void Attach(HANDLE handle)
- { _handle = handle; }
- HANDLE Detach()
- {
- HANDLE handle = _handle;
- _handle = NULL;
- return handle;
- }
-};
-
-}
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/Windows/NtCheck.h b/src/libs/7zip/unix/CPP/Windows/NtCheck.h
deleted file mode 100644
index e56318f00..000000000
--- a/src/libs/7zip/unix/CPP/Windows/NtCheck.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Windows/NtCheck.h
-
-#ifndef __WINDOWS_NT_CHECK_H
-#define __WINDOWS_NT_CHECK_H
-
-#ifdef _WIN32
-
-#if !defined(_WIN64) && !defined(UNDER_CE)
-static inline bool IsItWindowsNT()
-{
- OSVERSIONINFO vi;
- vi.dwOSVersionInfoSize = sizeof(vi);
- return (::GetVersionEx(&vi) && vi.dwPlatformId == VER_PLATFORM_WIN32_NT);
-}
-#endif
-
-#ifndef _UNICODE
- #if defined(_WIN64) || defined(UNDER_CE)
- bool g_IsNT = true;
- #define SET_IS_NT
- #else
- bool g_IsNT = false;
- #define SET_IS_NT g_IsNT = IsItWindowsNT();
- #endif
- #define NT_CHECK_ACTION
- // #define NT_CHECK_ACTION { NT_CHECK_FAIL_ACTION }
-#else
- #if !defined(_WIN64) && !defined(UNDER_CE)
- #define NT_CHECK_ACTION if (!IsItWindowsNT()) { NT_CHECK_FAIL_ACTION }
- #else
- #define NT_CHECK_ACTION
- #endif
- #define SET_IS_NT
-#endif
-
-#define NT_CHECK NT_CHECK_ACTION SET_IS_NT
-
-#else
-
-#define NT_CHECK
-
-#endif
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/Windows/PropVariant.cpp b/src/libs/7zip/unix/CPP/Windows/PropVariant.cpp
index 90212e08f..d16f576cc 100644
--- a/src/libs/7zip/unix/CPP/Windows/PropVariant.cpp
+++ b/src/libs/7zip/unix/CPP/Windows/PropVariant.cpp
@@ -2,13 +2,43 @@
#include "StdAfx.h"
-#include "PropVariant.h"
-
#include "../Common/Defs.h"
+#include "PropVariant.h"
+
namespace NWindows {
namespace NCOM {
+HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw()
+{
+ p->bstrVal = ::SysAllocStringLen(0, numChars);
+ if (!p->bstrVal)
+ {
+ p->vt = VT_ERROR;
+ p->scode = E_OUTOFMEMORY;
+ return E_OUTOFMEMORY;
+ }
+ p->vt = VT_BSTR;
+ return S_OK;
+}
+
+HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw()
+{
+ UINT len = (UINT)strlen(s);
+ p->bstrVal = ::SysAllocStringLen(0, len);
+ if (!p->bstrVal)
+ {
+ p->vt = VT_ERROR;
+ p->scode = E_OUTOFMEMORY;
+ return E_OUTOFMEMORY;
+ }
+ p->vt = VT_BSTR;
+ BSTR dest = p->bstrVal;
+ for (UINT i = 0; i <= len; i++)
+ dest[i] = s[i];
+ return S_OK;
+}
+
CPropVariant::CPropVariant(const PROPVARIANT &varSrc)
{
vt = VT_EMPTY;
@@ -58,7 +88,7 @@ CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
vt = VT_BSTR;
wReserved1 = 0;
bstrVal = ::SysAllocString(lpszSrc);
- if (bstrVal == NULL && lpszSrc != NULL)
+ if (!bstrVal && lpszSrc)
{
throw kMemException;
// vt = VT_ERROR;
@@ -67,15 +97,14 @@ CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
return *this;
}
-
CPropVariant& CPropVariant::operator=(const char *s)
{
InternalClear();
vt = VT_BSTR;
wReserved1 = 0;
UINT len = (UINT)strlen(s);
- bstrVal = ::SysAllocStringByteLen(0, (UINT)len * sizeof(OLECHAR));
- if (bstrVal == NULL)
+ bstrVal = ::SysAllocStringLen(0, len);
+ if (!bstrVal)
{
throw kMemException;
// vt = VT_ERROR;
@@ -89,7 +118,7 @@ CPropVariant& CPropVariant::operator=(const char *s)
return *this;
}
-CPropVariant& CPropVariant::operator=(bool bSrc)
+CPropVariant& CPropVariant::operator=(bool bSrc) throw()
{
if (vt != VT_BOOL)
{
@@ -100,22 +129,40 @@ CPropVariant& CPropVariant::operator=(bool bSrc)
return *this;
}
+BSTR CPropVariant::AllocBstr(unsigned numChars)
+{
+ if (vt != VT_EMPTY)
+ InternalClear();
+ vt = VT_BSTR;
+ wReserved1 = 0;
+ bstrVal = ::SysAllocStringLen(0, numChars);
+ if (!bstrVal)
+ {
+ throw kMemException;
+ // vt = VT_ERROR;
+ // scode = E_OUTOFMEMORY;
+ }
+ return bstrVal;
+}
+
#define SET_PROP_FUNC(type, id, dest) \
- CPropVariant& CPropVariant::operator=(type value) \
+ CPropVariant& CPropVariant::operator=(type value) throw() \
{ if (vt != id) { InternalClear(); vt = id; } \
dest = value; return *this; }
SET_PROP_FUNC(Byte, VT_UI1, bVal)
-SET_PROP_FUNC(Int16, VT_I2, iVal)
+// SET_PROP_FUNC(Int16, VT_I2, iVal)
SET_PROP_FUNC(Int32, VT_I4, lVal)
SET_PROP_FUNC(UInt32, VT_UI4, ulVal)
SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
+SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart)
SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
-static HRESULT MyPropVariantClear(PROPVARIANT *prop)
+HRESULT PropVariant_Clear(PROPVARIANT *prop) throw()
{
- switch(prop->vt)
+ switch (prop->vt)
{
+ case VT_EMPTY:
case VT_UI1:
case VT_I1:
case VT_I2:
@@ -134,17 +181,24 @@ static HRESULT MyPropVariantClear(PROPVARIANT *prop)
case VT_DATE:
prop->vt = VT_EMPTY;
prop->wReserved1 = 0;
+ prop->wReserved2 = 0;
+ prop->wReserved3 = 0;
+ prop->uhVal.QuadPart = 0;
return S_OK;
}
return ::VariantClear((VARIANTARG *)prop);
+ // return ::PropVariantClear(prop);
+ // PropVariantClear can clear VT_BLOB.
}
-HRESULT CPropVariant::Clear()
+HRESULT CPropVariant::Clear() throw()
{
- return MyPropVariantClear(this);
+ if (vt == VT_EMPTY)
+ return S_OK;
+ return PropVariant_Clear(this);
}
-HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
+HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
{
::VariantClear((tagVARIANT *)this);
switch(pSrc->vt)
@@ -172,7 +226,7 @@ HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
}
-HRESULT CPropVariant::Attach(PROPVARIANT *pSrc)
+HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw()
{
HRESULT hr = Clear();
if (FAILED(hr))
@@ -182,18 +236,23 @@ HRESULT CPropVariant::Attach(PROPVARIANT *pSrc)
return S_OK;
}
-HRESULT CPropVariant::Detach(PROPVARIANT *pDest)
+HRESULT CPropVariant::Detach(PROPVARIANT *pDest) throw()
{
- HRESULT hr = MyPropVariantClear(pDest);
- if (FAILED(hr))
- return hr;
+ if (pDest->vt != VT_EMPTY)
+ {
+ HRESULT hr = PropVariant_Clear(pDest);
+ if (FAILED(hr))
+ return hr;
+ }
memcpy(pDest, this, sizeof(PROPVARIANT));
vt = VT_EMPTY;
return S_OK;
}
-HRESULT CPropVariant::InternalClear()
+HRESULT CPropVariant::InternalClear() throw()
{
+ if (vt == VT_EMPTY)
+ return S_OK;
HRESULT hr = Clear();
if (FAILED(hr))
{
@@ -215,7 +274,7 @@ void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
}
}
-int CPropVariant::Compare(const CPropVariant &a)
+int CPropVariant::Compare(const CPropVariant &a) throw()
{
if (vt != a.vt)
return MyCompare(vt, a.vt);
@@ -233,9 +292,7 @@ int CPropVariant::Compare(const CPropVariant &a)
case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
case VT_BOOL: return -MyCompare(boolVal, a.boolVal);
case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime);
- case VT_BSTR:
- return 0; // Not implemented
- // return MyCompare(aPropVarint.cVal);
+ case VT_BSTR: return 0; // Not implemented
default: return 0;
}
}
diff --git a/src/libs/7zip/unix/CPP/Windows/PropVariant.h b/src/libs/7zip/unix/CPP/Windows/PropVariant.h
index d018034eb..d71b85e1d 100644
--- a/src/libs/7zip/unix/CPP/Windows/PropVariant.h
+++ b/src/libs/7zip/unix/CPP/Windows/PropVariant.h
@@ -1,29 +1,73 @@
// Windows/PropVariant.h
-#ifndef __WINDOWS_PROPVARIANT_H
-#define __WINDOWS_PROPVARIANT_H
+#ifndef __WINDOWS_PROP_VARIANT_H
+#define __WINDOWS_PROP_VARIANT_H
+#include "../Common/MyTypes.h"
#include "../Common/MyWindows.h"
-#include "../Common/Types.h"
namespace NWindows {
namespace NCOM {
+HRESULT PropVariant_Clear(PROPVARIANT *p) throw();
+
+HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw();
+HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw();
+
+inline void PropVarEm_Set_UInt32(PROPVARIANT *p, UInt32 v) throw()
+{
+ p->vt = VT_UI4;
+ p->ulVal = v;
+}
+
+inline void PropVarEm_Set_UInt64(PROPVARIANT *p, UInt64 v) throw()
+{
+ p->vt = VT_UI8;
+ p->uhVal.QuadPart = v;
+}
+
+inline void PropVarEm_Set_FileTime64(PROPVARIANT *p, UInt64 v) throw()
+{
+ p->vt = VT_FILETIME;
+ p->filetime.dwLowDateTime = (DWORD)v;
+ p->filetime.dwHighDateTime = (DWORD)(v >> 32);
+}
+
+inline void PropVarEm_Set_Bool(PROPVARIANT *p, bool b) throw()
+{
+ p->vt = VT_BOOL;
+ p->boolVal = (b ? VARIANT_TRUE : VARIANT_FALSE);
+}
+
+
class CPropVariant : public tagPROPVARIANT
{
public:
- CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; }
- ~CPropVariant() { Clear(); }
+ CPropVariant()
+ {
+ vt = VT_EMPTY;
+ wReserved1 = 0;
+ // wReserved2 = 0;
+ // wReserved3 = 0;
+ // uhVal.QuadPart = 0;
+ bstrVal = 0;
+ }
+ ~CPropVariant() throw() { Clear(); }
CPropVariant(const PROPVARIANT &varSrc);
CPropVariant(const CPropVariant &varSrc);
CPropVariant(BSTR bstrSrc);
CPropVariant(LPCOLESTR lpszSrc);
CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); };
CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; }
- CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; iVal = value; }
- CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; }
+
+private:
+ CPropVariant(Int16 value); // { vt = VT_I2; wReserved1 = 0; iVal = value; }
+ CPropVariant(Int32 value); // { vt = VT_I4; wReserved1 = 0; lVal = value; }
+
+public:
CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; }
CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal.QuadPart = value; }
+ CPropVariant(Int64 value) { vt = VT_I8; wReserved1 = 0; hVal.QuadPart = value; }
CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; }
CPropVariant& operator=(const CPropVariant &varSrc);
@@ -31,24 +75,31 @@ public:
CPropVariant& operator=(BSTR bstrSrc);
CPropVariant& operator=(LPCOLESTR lpszSrc);
CPropVariant& operator=(const char *s);
- CPropVariant& operator=(bool bSrc);
- CPropVariant& operator=(Byte value);
- CPropVariant& operator=(Int16 value);
- CPropVariant& operator=(Int32 value);
- CPropVariant& operator=(UInt32 value);
- CPropVariant& operator=(Int64 value);
- CPropVariant& operator=(UInt64 value);
- CPropVariant& operator=(const FILETIME &value);
-
- HRESULT Clear();
- HRESULT Copy(const PROPVARIANT *pSrc);
- HRESULT Attach(PROPVARIANT *pSrc);
- HRESULT Detach(PROPVARIANT *pDest);
-
- HRESULT InternalClear();
+
+ CPropVariant& operator=(bool bSrc) throw();
+ CPropVariant& operator=(Byte value) throw();
+
+private:
+ CPropVariant& operator=(Int16 value) throw();
+
+public:
+ CPropVariant& operator=(Int32 value) throw();
+ CPropVariant& operator=(UInt32 value) throw();
+ CPropVariant& operator=(UInt64 value) throw();
+ CPropVariant& operator=(Int64 value) throw();
+ CPropVariant& operator=(const FILETIME &value) throw();
+
+ BSTR AllocBstr(unsigned numChars);
+
+ HRESULT Clear() throw();
+ HRESULT Copy(const PROPVARIANT *pSrc) throw();
+ HRESULT Attach(PROPVARIANT *pSrc) throw();
+ HRESULT Detach(PROPVARIANT *pDest) throw();
+
+ HRESULT InternalClear() throw();
void InternalCopy(const PROPVARIANT *pSrc);
- int Compare(const CPropVariant &a1);
+ int Compare(const CPropVariant &a) throw();
};
}}
diff --git a/src/libs/7zip/unix/CPP/Windows/PropVariantConv.cpp b/src/libs/7zip/unix/CPP/Windows/PropVariantConv.cpp
new file mode 100644
index 000000000..dfb93d6d6
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/Windows/PropVariantConv.cpp
@@ -0,0 +1,99 @@
+// PropVariantConvert.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/IntToString.h"
+
+#include "Defs.h"
+#include "PropVariantConv.h"
+
+#define UINT_TO_STR_2(c, val) { s[0] = (c); s[1] = (char)('0' + (val) / 10); s[2] = (char)('0' + (val) % 10); s += 3; }
+
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds) throw()
+{
+ SYSTEMTIME st;
+ if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
+ {
+ *s = 0;
+ return false;
+ }
+ unsigned val = st.wYear;
+ if (val >= 10000)
+ {
+ *s++ = (char)('0' + val / 10000);
+ val %= 10000;
+ }
+ {
+ s[3] = (char)('0' + val % 10); val /= 10;
+ s[2] = (char)('0' + val % 10); val /= 10;
+ s[1] = (char)('0' + val % 10);
+ s[0] = (char)('0' + val / 10);
+ s += 4;
+ }
+ UINT_TO_STR_2('-', st.wMonth);
+ UINT_TO_STR_2('-', st.wDay);
+ if (includeTime)
+ {
+ UINT_TO_STR_2(' ', st.wHour);
+ UINT_TO_STR_2(':', st.wMinute);
+ if (includeSeconds)
+ UINT_TO_STR_2(':', st.wSecond);
+ }
+ *s = 0;
+ return true;
+}
+
+void ConvertFileTimeToString(const FILETIME &ft, wchar_t *dest, bool includeTime, bool includeSeconds) throw()
+{
+ char s[32];
+ ConvertFileTimeToString(ft, s, includeTime, includeSeconds);
+ for (unsigned i = 0;; i++)
+ {
+ unsigned char c = s[i];
+ dest[i] = c;
+ if (c == 0)
+ return;
+ }
+}
+
+void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw()
+{
+ *dest = 0;
+ switch (prop.vt)
+ {
+ case VT_EMPTY: return;
+ case VT_BSTR: dest[0] = '?'; dest[1] = 0; return;
+ case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return;
+ case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
+ case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
+ case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
+ case VT_FILETIME: ConvertFileTimeToString(prop.filetime, dest, true, true); return;
+ // case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
+ case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
+ case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
+ case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return;
+ case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? '+' : '-'; dest[1] = 0; return;
+ default: dest[0] = '?'; dest[1] = ':'; ConvertUInt64ToString(prop.vt, dest + 2);
+ }
+}
+
+void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw()
+{
+ *dest = 0;
+ switch (prop.vt)
+ {
+ case VT_EMPTY: return;
+ case VT_BSTR: dest[0] = '?'; dest[1] = 0; return;
+ case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return;
+ case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
+ case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
+ case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
+ case VT_FILETIME: ConvertFileTimeToString(prop.filetime, dest, true, true); return;
+ // case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
+ case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
+ case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
+ case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return;
+ case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? '+' : '-'; dest[1] = 0; return;
+ default: dest[0] = '?'; dest[1] = ':'; ConvertUInt32ToString(prop.vt, dest + 2);
+ }
+}
diff --git a/src/libs/7zip/unix/CPP/Windows/PropVariantConv.h b/src/libs/7zip/unix/CPP/Windows/PropVariantConv.h
new file mode 100644
index 000000000..5d26357f0
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/Windows/PropVariantConv.h
@@ -0,0 +1,30 @@
+// Windows/PropVariantConv.h
+
+#ifndef __PROP_VARIANT_CONV_H
+#define __PROP_VARIANT_CONV_H
+
+#include "../Common/MyTypes.h"
+
+// provide at least 32 bytes for buffer including zero-end
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true) throw();
+void ConvertFileTimeToString(const FILETIME &ft, wchar_t *s, bool includeTime = true, bool includeSeconds = true) throw();
+
+// provide at least 32 bytes for buffer including zero-end
+// don't send VT_BSTR to these functions
+void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw();
+void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw();
+
+inline bool ConvertPropVariantToUInt64(const PROPVARIANT &prop, UInt64 &value)
+{
+ switch (prop.vt)
+ {
+ case VT_UI8: value = (UInt64)prop.uhVal.QuadPart; return true;
+ case VT_UI4: value = prop.ulVal; return true;
+ case VT_UI2: value = prop.uiVal; return true;
+ case VT_UI1: value = prop.bVal; return true;
+ case VT_EMPTY: return false;
+ default: throw 151199;
+ }
+}
+
+#endif
diff --git a/src/libs/7zip/unix/CPP/Windows/PropVariantConversions.cpp b/src/libs/7zip/unix/CPP/Windows/PropVariantConversions.cpp
deleted file mode 100644
index abd5b46c4..000000000
--- a/src/libs/7zip/unix/CPP/Windows/PropVariantConversions.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-// PropVariantConversions.cpp
-
-#include "StdAfx.h"
-
-#include "Common/IntToString.h"
-#include "Common/StringConvert.h"
-
-#include "Windows/Defs.h"
-
-#include "PropVariantConversions.h"
-
-static UString ConvertUInt64ToString(UInt64 value)
-{
- wchar_t buffer[32];
- ConvertUInt64ToString(value, buffer);
- return buffer;
-}
-
-static UString ConvertInt64ToString(Int64 value)
-{
- wchar_t buffer[32];
- ConvertInt64ToString(value, buffer);
- return buffer;
-}
-
-#ifdef _WIN32
-static char *UIntToStringSpec(char c, UInt32 value, char *s, int numPos)
-{
- if (c != 0)
- *s++ = c;
- char temp[16];
- int pos = 0;
- do
- {
- temp[pos++] = (char)('0' + value % 10);
- value /= 10;
- }
- while (value != 0);
- int i;
- for (i = 0; i < numPos - pos; i++)
- *s++ = '0';
- do
- *s++ = temp[--pos];
- while (pos > 0);
- *s = '\0';
- return s;
-}
-#endif
-
-bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds)
-{
-#ifdef _WIN32
- s[0] = '\0';
- SYSTEMTIME st;
- if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
- return false;
- s = UIntToStringSpec(0, st.wYear, s, 4);
- s = UIntToStringSpec('-', st.wMonth, s, 2);
- s = UIntToStringSpec('-', st.wDay, s, 2);
- if (includeTime)
- {
- s = UIntToStringSpec(' ', st.wHour, s, 2);
- s = UIntToStringSpec(':', st.wMinute, s, 2);
- if (includeSeconds)
- UIntToStringSpec(':', st.wSecond, s, 2);
- }
- /*
- sprintf(s, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);
- if (includeTime)
- {
- sprintf(s + strlen(s), " %02d:%02d", st.wHour, st.wMinute);
- if (includeSeconds)
- sprintf(s + strlen(s), ":%02d", st.wSecond);
- }
- */
-#else
- BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, DWORD *Seconds );
-
- LARGE_INTEGER ltime;
-
- ltime.QuadPart = ft.dwHighDateTime;
- ltime.QuadPart = (ltime.QuadPart << 32) | ft.dwLowDateTime;
-
- DWORD dw;
- RtlTimeToSecondsSince1970(&ltime, &dw );
- time_t timep = (time_t)dw;
-
- struct tm * date = localtime(&timep);
-
- sprintf(s, "%04d-%02d-%02d", date->tm_year+1900, date->tm_mon+1,date->tm_mday);
- if (includeTime)
- {
- sprintf(s + strlen(s), " %02d:%02d", date->tm_hour,date->tm_min);
- if (includeSeconds)
- sprintf(s + strlen(s), ":%02d", date->tm_sec);
- }
-#endif
- return true;
-}
-
-UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime, bool includeSeconds)
-{
- char s[32];
- ConvertFileTimeToString(ft, s, includeTime, includeSeconds);
- return GetUnicodeString(s);
-}
-
-
-UString ConvertPropVariantToString(const PROPVARIANT &prop)
-{
- switch (prop.vt)
- {
- case VT_EMPTY: return UString();
- case VT_BSTR: return prop.bstrVal;
- case VT_UI1: return ConvertUInt64ToString(prop.bVal);
- case VT_UI2: return ConvertUInt64ToString(prop.uiVal);
- case VT_UI4: return ConvertUInt64ToString(prop.ulVal);
- case VT_UI8: return ConvertUInt64ToString(prop.uhVal.QuadPart);
- case VT_FILETIME: return ConvertFileTimeToString(prop.filetime, true, true);
- // case VT_I1: return ConvertInt64ToString(prop.cVal);
- case VT_I2: return ConvertInt64ToString(prop.iVal);
- case VT_I4: return ConvertInt64ToString(prop.lVal);
- case VT_I8: return ConvertInt64ToString(prop.hVal.QuadPart);
- case VT_BOOL: return VARIANT_BOOLToBool(prop.boolVal) ? L"+" : L"-";
- default: throw 150245;
- }
-}
-
-UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop)
-{
- switch (prop.vt)
- {
- case VT_UI1: return prop.bVal;
- case VT_UI2: return prop.uiVal;
- case VT_UI4: return prop.ulVal;
- case VT_UI8: return (UInt64)prop.uhVal.QuadPart;
- default: throw 151199;
- }
-}
diff --git a/src/libs/7zip/unix/CPP/Windows/PropVariantConversions.h b/src/libs/7zip/unix/CPP/Windows/PropVariantConversions.h
deleted file mode 100644
index 3de4dedb3..000000000
--- a/src/libs/7zip/unix/CPP/Windows/PropVariantConversions.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Windows/PropVariantConversions.h
-
-#ifndef __PROP_VARIANT_CONVERSIONS_H
-#define __PROP_VARIANT_CONVERSIONS_H
-
-#include "Common/MyString.h"
-#include "Common/Types.h"
-
-bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true);
-UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime = true, bool includeSeconds = true);
-UString ConvertPropVariantToString(const PROPVARIANT &prop);
-UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop);
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/Windows/Registry.cpp b/src/libs/7zip/unix/CPP/Windows/Registry.cpp
deleted file mode 100644
index 74e255df4..000000000
--- a/src/libs/7zip/unix/CPP/Windows/Registry.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-// Windows/Registry.cpp
-
-#include "StdAfx.h"
-
-#ifndef _UNICODE
-#include "Common/StringConvert.h"
-#endif
-#include "Windows/Registry.h"
-
-#include <wx/config.h>
-
-class HKEY_Impl
-{
- public:
- wxString path;
- HKEY_Impl(wxString a) : path(a) {}
-};
-
-namespace NWindows {
-namespace NRegistry {
-
-#define ERROR_SET_VALUE (E_INVALIDARG) // FIXME
-#define ERROR_GET_VALUE (E_INVALIDARG) // FIXME
-#define PROGRAM_NAME L"p7zip"
-
-static wxConfig * g_config = 0;
-static int g_config_ref = 0;
-
-static void configAddRef() {
- if (g_config == 0) {
- g_config = new wxConfig(PROGRAM_NAME);
- g_config->Flush(true);
- wxConfigBase::Set(g_config);
- }
- g_config_ref++;
-}
-
-static void configSubRef() {
- if (g_config_ref >= 1)
- {
- g_config_ref--;
- if (g_config_ref == 0) {
- delete g_config;
- g_config = 0;
- wxConfigBase::Set(NULL);
- } else {
- g_config->Flush(true);
- }
- }
-}
-
- LONG CKey::Close()
- {
- if (_object)
- {
- configSubRef();
- delete _object;
- }
- _object = 0;
- return ERROR_SUCCESS;
- }
-
- LONG CKey::Create(HKEY parentKey, LPCTSTR keyName)
- {
- Close();
-
- configAddRef();
-
- wxString path;
-
- if (parentKey == HKEY_CURRENT_USER) {
- path=L"/" + wxString(keyName);
- } else {
- path = parentKey->path + L"/" + wxString(keyName);
- }
- _object = new HKEY_Impl(path);
- return ERROR_SUCCESS;
- }
- LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask)
- {
- Close();
-
- configAddRef();
-
- wxString path;
-
- if (parentKey == HKEY_CURRENT_USER) {
- path=L"/" + wxString(keyName);
- } else {
- path = parentKey->path + L"/" + wxString(keyName);
- }
- _object = new HKEY_Impl(path);
- return ERROR_SUCCESS;
- }
-
- LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName)
- {
- g_config->SetPath(_object->path);
- bool ret = g_config->DeleteGroup(subKeyName);
- if (ret) return ERROR_SUCCESS;
- return ERROR_GET_VALUE;
- }
-
- LONG CKey::DeleteValue(LPCTSTR name)
- {
- g_config->SetPath(_object->path);
- bool ret = g_config->DeleteEntry(name);
- if (ret) return ERROR_SUCCESS;
- return ERROR_GET_VALUE;
- }
-
- LONG CKey::QueryValue(LPCTSTR name, UInt32 &value)
- {
- g_config->SetPath(_object->path);
- long val;
- bool ret = g_config->Read(name,&val);
- if (ret) {
- value = (UInt32)val;
- return ERROR_SUCCESS;
- }
- return ERROR_GET_VALUE;
- }
-
- LONG CKey::QueryValue(LPCTSTR name, bool &value)
- {
- g_config->SetPath(_object->path);
- bool ret = g_config->Read(name,&value);
- if (ret) return ERROR_SUCCESS;
- return ERROR_GET_VALUE;
- }
-
- LONG CKey::QueryValue(LPCTSTR name, CSysString &value)
- {
- g_config->SetPath(_object->path);
- wxString val;
- bool ret = g_config->Read(name,&val);
- if (ret) {
- value = val;
- return ERROR_SUCCESS;
- }
- return ERROR_GET_VALUE;
- }
-
-LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value)
-{
- UInt32 newVal;
- LONG res = QueryValue(name, newVal);
- if (res == ERROR_SUCCESS)
- value = newVal;
- return res;
-}
-
-LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value)
-{
- bool newVal;
- LONG res = QueryValue(name, newVal);
- if (res == ERROR_SUCCESS)
- value = newVal;
- return res;
-}
-
-
- LONG CKey::SetValue(LPCTSTR valueName, UInt32 value)
- {
- g_config->SetPath(_object->path);
- bool ret = g_config->Write(valueName,(long)value);
- if (ret == true) return ERROR_SUCCESS;
- return ERROR_SET_VALUE;
- }
- LONG CKey::SetValue(LPCTSTR valueName, bool value)
- {
- g_config->SetPath(_object->path);
- bool ret = g_config->Write(valueName,value);
- if (ret == true) return ERROR_SUCCESS;
- return ERROR_SET_VALUE;
- }
- LONG CKey::SetValue(LPCTSTR valueName, LPCTSTR value)
- {
- g_config->SetPath(_object->path);
- bool ret = g_config->Write(valueName,value);
- if (ret == true) return ERROR_SUCCESS;
- return ERROR_SET_VALUE;
- }
-
- LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size)
- {
- static char hexa[] = "0123456789ABCDEF";
- /* FIXME
- MYASSERT(value != NULL);
- MYASSERT(_object != NULL);
- return RegSetValueEx(_object, name, NULL, REG_BINARY, (const BYTE *)value, size);
- */
- BYTE *buf = (BYTE *)value;
- wxString str;
- for(UInt32 i=0;i<size;i++)
- {
- str += hexa[ (buf[i]>>4) & 0x0f];
- str += hexa[ buf[i] & 0x0f];
- }
- return SetValue(name,(LPCTSTR)str);
- }
-
- LONG CKey::EnumKeys(CSysStringVector &keyNames)
- {
- g_config->SetPath(_object->path);
- keyNames.Clear();
- // enumeration variables
- wxString str;
- long dummy;
- bool bCont = g_config->GetFirstEntry(str, dummy);
- while ( bCont ) {
- keyNames.Add((const TCHAR *)str);
- bCont = g_config->GetNextEntry(str, dummy);
- }
-
- // now all groups...
- bCont = g_config->GetFirstGroup(str, dummy);
- while ( bCont ) {
- keyNames.Add((const TCHAR *)str);
- bCont = g_config->GetNextGroup(str, dummy);
- }
- return ERROR_SUCCESS;
- }
-
- LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &dataSize)
- {
- g_config->SetPath(_object->path);
- wxString str;
- bool ret = g_config->Read(name,&str);
- if (ret == false) return ERROR_GET_VALUE;
-
- size_t l = str.Len() / 2;
- if (l > dataSize) l = dataSize;
- else dataSize=l;
-
- BYTE *buf = (BYTE *)value;
- for(UInt32 i=0;i<dataSize;i++)
- {
- char cval[3];
- cval[0] = (char)str[2*i];
- cval[1] = (char)str[2*i+1];
- cval[2] = 0;
- unsigned uval = 0;
- sscanf(cval,"%x",&uval);
- buf[i]=(BYTE)uval;
- }
-
- return ERROR_SUCCESS;
- }
-
-
- LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize)
- {
- g_config->SetPath(_object->path);
- wxString str;
- bool ret = g_config->Read(name,&str);
- if (ret == false) return ERROR_GET_VALUE;
-
- dataSize = str.Len() / 2;
- value.SetCapacity(dataSize);
- return QueryValue(name, (BYTE *)value, dataSize);
- }
-
-
-LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings)
-{
- UInt32 numChars = 0;
- int i;
- for (i = 0; i < strings.Size(); i++)
- numChars += strings[i].Length() + 1;
- CBuffer<wchar_t> buffer;
- buffer.SetCapacity(numChars);
- int pos = 0;
- for (i = 0; i < strings.Size(); i++)
- {
- const UString &s = strings[i];
- MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)s);
- pos += s.Length() + 1;
- }
- return SetValue(valueName, buffer, numChars * sizeof(wchar_t));
-}
-
-LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)
-{
- strings.Clear();
- CByteBuffer buffer;
- UInt32 dataSize;
- LONG res = QueryValue(valueName, buffer, dataSize);
- if (res != ERROR_SUCCESS)
- return res;
- if (dataSize % sizeof(wchar_t) != 0)
- return E_FAIL;
- const wchar_t *data = (const wchar_t *)(const Byte *)buffer;
- int numChars = dataSize / sizeof(wchar_t);
- UString s;
- for (int i = 0; i < numChars; i++)
- {
- wchar_t c = data[i];
- if (c == 0)
- {
- strings.Add(s);
- s.Empty();
- }
- else
- s += c;
- }
- return res;
-}
-
-
-}
-}
-
diff --git a/src/libs/7zip/unix/CPP/Windows/Registry.h b/src/libs/7zip/unix/CPP/Windows/Registry.h
deleted file mode 100644
index a9078751f..000000000
--- a/src/libs/7zip/unix/CPP/Windows/Registry.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Windows/Registry.h
-
-#ifndef __WINDOWS_REGISTRY_H
-#define __WINDOWS_REGISTRY_H
-
-#include "Common/Buffer.h"
-#include "Common/MyString.h"
-#include "Common/Types.h"
-
-#ifndef _WIN32
-class HKEY_Impl;
-
-typedef HKEY_Impl * HKEY;
-
-/*
-#define HKEY_CLASSES_ROOT ((HKEY) 0x80000000)
-#define HKEY_LOCAL_MACHINE ((HKEY) 0x80000002)
-#define HKEY_USERS ((HKEY) 0x80000003)
-#define HKEY_PERFORMANCE_DATA ((HKEY) 0x80000004)
-#define HKEY_CURRENT_CONFIG ((HKEY) 0x80000005)
-#define HKEY_DYN_DATA ((HKEY) 0x80000006)
-*/
-#define HKEY_CURRENT_USER ((HKEY) 0x80000001)
-
-
-typedef DWORD REGSAM;
-#define ERROR_SUCCESS (0)
-#define KEY_READ (0x1234) // FIXME
-#define KEY_ALL_ACCESS (~0) // FIXME
-
-/* ------------------------------ end registry ------------------------------ */
-
-#endif
-
-namespace NWindows {
-namespace NRegistry {
-
-const TCHAR kKeyNameDelimiter = TEXT(CHAR_PATH_SEPARATOR);
-
-// LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value);
-
-class CKey
-{
- HKEY _object;
-public:
- CKey(): _object(NULL) {}
- ~CKey() { Close(); }
-
- operator HKEY() const { return _object; }
-
- #if 0
- HKEY Detach();
- void Attach(HKEY key);
- LONG Create(HKEY parentKey, LPCTSTR keyName,
- LPTSTR keyClass = REG_NONE, DWORD options = REG_OPTION_NON_VOLATILE,
- REGSAM accessMask = KEY_ALL_ACCESS,
- LPSECURITY_ATTRIBUTES securityAttributes = NULL,
- LPDWORD disposition = NULL);
- LONG Open(HKEY parentKey, LPCTSTR keyName,
- REGSAM accessMask = KEY_ALL_ACCESS);
-#endif // #if 0
- LONG Create(HKEY parentKey, LPCTSTR keyName);
- LONG Open(HKEY parentKey, LPCTSTR keyName,
- REGSAM accessMask = KEY_ALL_ACCESS);
-
- LONG Close();
-
- LONG DeleteSubKey(LPCTSTR subKeyName);
- LONG RecurseDeleteKey(LPCTSTR subKeyName);
-
- LONG DeleteValue(LPCTSTR name);
- #ifndef _UNICODE
- LONG DeleteValue(LPCWSTR name);
- #endif
-
- LONG SetValue(LPCTSTR valueName, UInt32 value);
- LONG SetValue(LPCTSTR valueName, bool value);
- LONG SetValue(LPCTSTR valueName, LPCTSTR value);
- // LONG SetValue(LPCTSTR valueName, const CSysString &value);
- #ifndef _UNICODE
- LONG SetValue(LPCWSTR name, LPCWSTR value);
- // LONG SetValue(LPCWSTR name, const UString &value);
- #endif
-
- LONG SetValue(LPCTSTR name, const void *value, UInt32 size);
-
- LONG SetValue_Strings(LPCTSTR valueName, const UStringVector &strings);
- LONG GetValue_Strings(LPCTSTR valueName, UStringVector &strings);
-
- LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value);
-
- LONG QueryValue(LPCTSTR name, UInt32 &value);
- LONG QueryValue(LPCTSTR name, bool &value);
- LONG QueryValue(LPCTSTR name, LPTSTR value, UInt32 &dataSize);
- LONG QueryValue(LPCTSTR name, CSysString &value);
-
- LONG GetValue_IfOk(LPCTSTR name, UInt32 &value);
- LONG GetValue_IfOk(LPCTSTR name, bool &value);
-
- #ifndef _UNICODE
- LONG QueryValue(LPCWSTR name, LPWSTR value, UInt32 &dataSize);
- LONG QueryValue(LPCWSTR name, UString &value);
- #endif
-
- LONG QueryValue(LPCTSTR name, void *value, UInt32 &dataSize);
- LONG QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize);
-
- LONG EnumKeys(CSysStringVector &keyNames);
-};
-
-}}
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/Windows/Synchronization.cpp b/src/libs/7zip/unix/CPP/Windows/Synchronization.cpp
index 8130f9ac3..4be33e1e9 100644
--- a/src/libs/7zip/unix/CPP/Windows/Synchronization.cpp
+++ b/src/libs/7zip/unix/CPP/Windows/Synchronization.cpp
@@ -73,7 +73,7 @@ namespace NSynchronization {
}
_isValid = false;
}
- void CSynchro::Enter() {
+ void CSynchro::Enter() {
TRACEN((printf("\nT%d : E1-CSynchro::Enter(%p)\n",(int)pthread_self(),(void *)&_object)))
int ret = ::pthread_mutex_lock(&_object);
if (ret != 0) {
diff --git a/src/libs/7zip/unix/CPP/Windows/Synchronization.h b/src/libs/7zip/unix/CPP/Windows/Synchronization.h
index df3c693a7..1c45a1b78 100644
--- a/src/libs/7zip/unix/CPP/Windows/Synchronization.h
+++ b/src/libs/7zip/unix/CPP/Windows/Synchronization.h
@@ -5,8 +5,8 @@
#include "Defs.h"
-extern "C"
-{
+extern "C"
+{
#include "../../C/Threads.h"
}
@@ -18,7 +18,7 @@ namespace NWindows {
namespace NSynchronization {
class Uncopyable {
-protected:
+protected:
Uncopyable() {} // allow construction
~Uncopyable() {} // and destruction of derived objects...
private:
@@ -125,8 +125,8 @@ public:
return 0;
return ::GetLastError();
}
- WRes Release()
- {
+ WRes Release()
+ {
return ::ReleaseMutex(_handle) ? 0 : ::GetLastError();
}
};
@@ -134,7 +134,7 @@ class CMutexLock
{
CMutex *_object;
public:
- CMutexLock(CMutex &object): _object(&object) { _object->Lock(); }
+ CMutexLock(CMutex &object): _object(&object) { _object->Lock(); }
~CMutexLock() { _object->Release(); }
};
#endif
@@ -173,7 +173,7 @@ class CCriticalSectionLock : private Uncopyable
CCriticalSection *_object;
void Unlock() { _object->Leave(); }
public:
- CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); }
+ CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); }
~CCriticalSectionLock() { Unlock(); }
};
diff --git a/src/libs/7zip/unix/CPP/Windows/Synchronization2.h b/src/libs/7zip/unix/CPP/Windows/Synchronization2.h
index d86b49dee..ff8f7a752 100644
--- a/src/libs/7zip/unix/CPP/Windows/Synchronization2.h
+++ b/src/libs/7zip/unix/CPP/Windows/Synchronization2.h
@@ -29,7 +29,7 @@ public:
~CSynchro() {}
void Enter() { Lock(); }
void Leave() { Unlock(); }
- void WaitCond() {
+ void WaitCond() {
_waiting[index_waiting++] = find_thread(NULL); // _waiting.push_back(find_thread(NULL));
thread_id sender;
Unlock();
@@ -84,16 +84,16 @@ public:
::pthread_mutex_init(&_object,0);
::pthread_cond_init(&_cond,0);
}
- void Enter() {
+ void Enter() {
::pthread_mutex_lock(&_object);
}
void Leave() {
::pthread_mutex_unlock(&_object);
}
- void WaitCond() {
+ void WaitCond() {
::pthread_cond_wait(&_cond, &_object);
}
- void LeaveAndSignal() {
+ void LeaveAndSignal() {
::pthread_cond_broadcast(&_cond);
::pthread_mutex_unlock(&_object);
}
@@ -119,7 +119,7 @@ class CBaseEventWFMO : public CBaseHandleWFMO
public:
bool IsCreated() { return (this->_sync != 0); }
- CBaseEventWFMO() { this->_sync = 0; }
+ CBaseEventWFMO() { this->_sync = 0; }
~CBaseEventWFMO() { Close(); }
WRes Close() { this->_sync = 0; return S_OK; }
@@ -178,7 +178,7 @@ class CSemaphoreWFMO : public CBaseHandleWFMO
LONG _maxCount;
public:
- CSemaphoreWFMO() : _count(0), _maxCount(0) { this->_sync=0;}
+ CSemaphoreWFMO() : _count(0), _maxCount(0) { this->_sync=0;}
WRes Create(CSynchro *sync,LONG initiallyCount, LONG maxCount)
{
if ((initiallyCount < 0) || (initiallyCount > maxCount) || (maxCount < 1)) return S_FALSE;
diff --git a/src/libs/7zip/unix/CPP/Windows/System.cpp b/src/libs/7zip/unix/CPP/Windows/System.cpp
index b63ebec79..55e723c40 100644
--- a/src/libs/7zip/unix/CPP/Windows/System.cpp
+++ b/src/libs/7zip/unix/CPP/Windows/System.cpp
@@ -20,7 +20,7 @@
#endif
-#include "Common/Types.h"
+#include "Common/MyTypes.h"
namespace NWindows
{
diff --git a/src/libs/7zip/unix/CPP/Windows/System.h b/src/libs/7zip/unix/CPP/Windows/System.h
index e0067158f..4133a7b30 100644
--- a/src/libs/7zip/unix/CPP/Windows/System.h
+++ b/src/libs/7zip/unix/CPP/Windows/System.h
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_SYSTEM_H
#define __WINDOWS_SYSTEM_H
-#include "../Common/Types.h"
+#include "../Common/MyTypes.h"
namespace NWindows {
namespace NSystem {
diff --git a/src/libs/7zip/unix/CPP/Windows/Thread.h b/src/libs/7zip/unix/CPP/Windows/Thread.h
index ed72507f4..944f19744 100644
--- a/src/libs/7zip/unix/CPP/Windows/Thread.h
+++ b/src/libs/7zip/unix/CPP/Windows/Thread.h
@@ -23,7 +23,7 @@ public:
WRes Create(THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
{ return Thread_Create(&thread, startAddress, parameter); }
WRes Wait() { return Thread_Wait(&thread); }
-
+
#ifdef _WIN32
operator HANDLE() { return thread; }
void Attach(HANDLE handle) { thread = handle; }
diff --git a/src/libs/7zip/unix/CPP/Windows/Time.cpp b/src/libs/7zip/unix/CPP/Windows/Time.cpp
deleted file mode 100644
index b58de6fe1..000000000
--- a/src/libs/7zip/unix/CPP/Windows/Time.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-// Windows/Time.cpp
-
-#include "StdAfx.h"
-
-#include "Time.h"
-#include "Windows/Defs.h"
-
-namespace NWindows {
-namespace NTime {
-
-static const UInt32 kFileTimeStartYear = 1601;
-
-static const UInt32 kNumTimeQuantumsInSecond = 10000000;
-static const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) * 60 * 60 * 24 * 134774;
-
-void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime)
-{
- UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond;
- fileTime.dwLowDateTime = (DWORD)v;
- fileTime.dwHighDateTime = (DWORD)(v >> 32);
-}
-
-bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime)
-{
- UInt64 winTime = (((UInt64)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime;
- if (winTime < kUnixTimeStartValue)
- {
- unixTime = 0;
- return false;
- }
- winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;
- if (winTime > 0xFFFFFFFF)
- {
- unixTime = 0xFFFFFFFF;
- return false;
- }
- unixTime = (UInt32)winTime;
- return true;
-}
-
-bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
- unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds)
-{
- resSeconds = 0;
- if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 ||
- day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59)
- return false;
- UInt32 numYears = year - kFileTimeStartYear;
- UInt32 numDays = numYears * 365 + numYears / 4 - numYears / 100 + numYears / 400;
- Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
- if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
- ms[1] = 29;
- month--;
- for (unsigned i = 0; i < month; i++)
- numDays += ms[i];
- numDays += day - 1;
- resSeconds = ((UInt64)(numDays * 24 + hour) * 60 + min) * 60 + sec;
- return true;
-}
-
-void GetCurUtcFileTime(FILETIME &ft)
-{
- SYSTEMTIME st;
- GetSystemTime(&st);
- SystemTimeToFileTime(&st, &ft);
-}
-
-}}
diff --git a/src/libs/7zip/unix/CPP/Windows/Time.h b/src/libs/7zip/unix/CPP/Windows/Time.h
deleted file mode 100644
index 6f510b22b..000000000
--- a/src/libs/7zip/unix/CPP/Windows/Time.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Windows/Time.h
-
-#ifndef __WINDOWS_TIME_H
-#define __WINDOWS_TIME_H
-
-#include "Common/Types.h"
-
-namespace NWindows {
-namespace NTime {
-
-bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime);
-bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime);
-void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime);
-bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime);
-bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
- unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds);
-void GetCurUtcFileTime(FILETIME &ft);
-
-}}
-
-#endif
diff --git a/src/libs/7zip/unix/CPP/Windows/TimeUtils.cpp b/src/libs/7zip/unix/CPP/Windows/TimeUtils.cpp
new file mode 100644
index 000000000..7ef44d9cc
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/Windows/TimeUtils.cpp
@@ -0,0 +1,203 @@
+// Windows/TimeUtils.cpp
+
+#include "StdAfx.h"
+
+#include "Defs.h"
+#include "TimeUtils.h"
+
+namespace NWindows {
+namespace NTime {
+
+static const UInt32 kNumTimeQuantumsInSecond = 10000000;
+static const UInt32 kFileTimeStartYear = 1601;
+static const UInt32 kDosTimeStartYear = 1980;
+static const UInt32 kUnixTimeStartYear = 1970;
+static const UInt64 kUnixTimeOffset =
+ (UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));
+static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond;
+
+bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) throw()
+{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft));
+ #else
+ ft.dwLowDateTime = 0;
+ ft.dwHighDateTime = 0;
+ UInt64 res;
+ if (!GetSecondsSince1601(kDosTimeStartYear + (dosTime >> 25), (dosTime >> 21) & 0xF, (dosTime >> 16) & 0x1F,
+ (dosTime >> 11) & 0x1F, (dosTime >> 5) & 0x3F, (dosTime & 0x1F) * 2, res))
+ return false;
+ res *= kNumTimeQuantumsInSecond;
+ ft.dwLowDateTime = (UInt32)res;
+ ft.dwHighDateTime = (UInt32)(res >> 32);
+ return true;
+ #endif
+}
+
+static const UInt32 kHighDosTime = 0xFF9FBF7D;
+static const UInt32 kLowDosTime = 0x210000;
+
+#define PERIOD_4 (4 * 365 + 1)
+#define PERIOD_100 (PERIOD_4 * 25 - 1)
+#define PERIOD_400 (PERIOD_100 * 4 + 1)
+
+bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw()
+{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+
+ WORD datePart, timePart;
+ if (!::FileTimeToDosDateTime(&ft, &datePart, &timePart))
+ {
+ dosTime = (ft.dwHighDateTime >= 0x01C00000) ? kHighDosTime : kLowDosTime;
+ return false;
+ }
+ dosTime = (((UInt32)datePart) << 16) + timePart;
+
+ #else
+
+ unsigned year, mon, day, hour, min, sec;
+ UInt64 v64 = ft.dwLowDateTime | ((UInt64)ft.dwHighDateTime << 32);
+ Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ unsigned temp;
+ UInt32 v;
+ v64 += (kNumTimeQuantumsInSecond * 2 - 1);
+ v64 /= kNumTimeQuantumsInSecond;
+ sec = (unsigned)(v64 % 60);
+ v64 /= 60;
+ min = (unsigned)(v64 % 60);
+ v64 /= 60;
+ hour = (unsigned)(v64 % 24);
+ v64 /= 24;
+
+ v = (UInt32)v64;
+
+ year = (unsigned)(kFileTimeStartYear + v / PERIOD_400 * 400);
+ v %= PERIOD_400;
+
+ temp = (unsigned)(v / PERIOD_100);
+ if (temp == 4)
+ temp = 3;
+ year += temp * 100;
+ v -= temp * PERIOD_100;
+
+ temp = v / PERIOD_4;
+ if (temp == 25)
+ temp = 24;
+ year += temp * 4;
+ v -= temp * PERIOD_4;
+
+ temp = v / 365;
+ if (temp == 4)
+ temp = 3;
+ year += temp;
+ v -= temp * 365;
+
+ if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
+ ms[1] = 29;
+ for (mon = 1; mon <= 12; mon++)
+ {
+ unsigned s = ms[mon - 1];
+ if (v < s)
+ break;
+ v -= s;
+ }
+ day = (unsigned)v + 1;
+
+ dosTime = kLowDosTime;
+ if (year < kDosTimeStartYear)
+ return false;
+ year -= kDosTimeStartYear;
+ dosTime = kHighDosTime;
+ if (year >= 128)
+ return false;
+ dosTime = (year << 25) | (mon << 21) | (day << 16) | (hour << 11) | (min << 5) | (sec >> 1);
+ #endif
+ return true;
+}
+
+void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft) throw()
+{
+ UInt64 v = (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond;
+ ft.dwLowDateTime = (DWORD)v;
+ ft.dwHighDateTime = (DWORD)(v >> 32);
+}
+
+bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft) throw()
+{
+ if (unixTime > kNumSecondsInFileTime - kUnixTimeOffset)
+ {
+ ft.dwLowDateTime = ft.dwHighDateTime = (UInt32)(Int32)-1;
+ return false;
+ }
+ Int64 v = (Int64)kUnixTimeOffset + unixTime;
+ if (v < 0)
+ {
+ ft.dwLowDateTime = ft.dwHighDateTime = 0;
+ return false;
+ }
+ UInt64 v2 = (UInt64)v * kNumTimeQuantumsInSecond;
+ ft.dwLowDateTime = (DWORD)v2;
+ ft.dwHighDateTime = (DWORD)(v2 >> 32);
+ return true;
+}
+
+Int64 FileTimeToUnixTime64(const FILETIME &ft) throw()
+{
+ UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
+ return (Int64)(winTime / kNumTimeQuantumsInSecond) - kUnixTimeOffset;
+}
+
+bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw()
+{
+ UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
+ winTime /= kNumTimeQuantumsInSecond;
+ if (winTime < kUnixTimeOffset)
+ {
+ unixTime = 0;
+ return false;
+ }
+ winTime -= kUnixTimeOffset;
+ if (winTime > 0xFFFFFFFF)
+ {
+ unixTime = 0xFFFFFFFF;
+ return false;
+ }
+ unixTime = (UInt32)winTime;
+ return true;
+}
+
+bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
+ unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw()
+{
+ resSeconds = 0;
+ if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 ||
+ day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59)
+ return false;
+ UInt32 numYears = year - kFileTimeStartYear;
+ UInt32 numDays = numYears * 365 + numYears / 4 - numYears / 100 + numYears / 400;
+ Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
+ ms[1] = 29;
+ month--;
+ for (unsigned i = 0; i < month; i++)
+ numDays += ms[i];
+ numDays += day - 1;
+ resSeconds = ((UInt64)(numDays * 24 + hour) * 60 + min) * 60 + sec;
+ return true;
+}
+
+void GetCurUtcFileTime(FILETIME &ft) throw()
+{
+ // Both variants provide same low resolution on WinXP: about 15 ms.
+ // But GetSystemTimeAsFileTime is much faster.
+
+ #ifdef UNDER_CE
+ SYSTEMTIME st;
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &ft);
+ #else
+ GetSystemTimeAsFileTime(&ft);
+ #endif
+}
+
+}}
diff --git a/src/libs/7zip/unix/CPP/Windows/TimeUtils.h b/src/libs/7zip/unix/CPP/Windows/TimeUtils.h
new file mode 100644
index 000000000..2967214e6
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/Windows/TimeUtils.h
@@ -0,0 +1,23 @@
+// Windows/TimeUtils.h
+
+#ifndef __WINDOWS_TIME_UTILS_H
+#define __WINDOWS_TIME_UTILS_H
+
+#include "../Common/MyTypes.h"
+
+namespace NWindows {
+namespace NTime {
+
+bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime) throw();
+bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime) throw();
+void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime) throw();
+bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &fileTime) throw();
+bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime) throw();
+Int64 FileTimeToUnixTime64(const FILETIME &ft) throw();
+bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
+ unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw();
+void GetCurUtcFileTime(FILETIME &ft) throw();
+
+}}
+
+#endif
diff --git a/src/libs/7zip/unix/CPP/Windows/Windows.pri b/src/libs/7zip/unix/CPP/Windows/Windows.pri
new file mode 100644
index 000000000..117fb37b3
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/Windows/Windows.pri
@@ -0,0 +1,24 @@
+HEADERS += $$7ZIP_BASE/CPP/Windows/DLL.h \
+ $$7ZIP_BASE/CPP/Windows/Defs.h \
+ $$7ZIP_BASE/CPP/Windows/FileDir.h \
+ $$7ZIP_BASE/CPP/Windows/FileFind.h \
+ $$7ZIP_BASE/CPP/Windows/FileIO.h \
+ $$7ZIP_BASE/CPP/Windows/FileName.h \
+ $$7ZIP_BASE/CPP/Windows/PropVariant.h \
+ $$7ZIP_BASE/CPP/Windows/PropVariantConv.h \
+ $$7ZIP_BASE/CPP/Windows/Synchronization.h \
+ $$7ZIP_BASE/CPP/Windows/Synchronization2.h \
+ $$7ZIP_BASE/CPP/Windows/System.h \
+ $$7ZIP_BASE/CPP/Windows/Thread.h \
+ $$7ZIP_BASE/CPP/Windows/TimeUtils.h
+
+SOURCES += $$7ZIP_BASE/CPP/Windows/DLL.cpp \
+ $$7ZIP_BASE/CPP/Windows/FileDir.cpp \
+ $$7ZIP_BASE/CPP/Windows/FileFind.cpp \
+ $$7ZIP_BASE/CPP/Windows/FileIO.cpp \
+ $$7ZIP_BASE/CPP/Windows/FileName.cpp \
+ $$7ZIP_BASE/CPP/Windows/PropVariant.cpp \
+ $$7ZIP_BASE/CPP/Windows/PropVariantConv.cpp \
+ $$7ZIP_BASE/CPP/Windows/Synchronization.cpp \
+ $$7ZIP_BASE/CPP/Windows/System.cpp \
+ $$7ZIP_BASE/CPP/Windows/TimeUtils.cpp
diff --git a/src/libs/7zip/unix/CPP/include_windows/basetyps.h b/src/libs/7zip/unix/CPP/include_windows/basetyps.h
index d761e74b0..2200cb7c3 100644
--- a/src/libs/7zip/unix/CPP/include_windows/basetyps.h
+++ b/src/libs/7zip/unix/CPP/include_windows/basetyps.h
@@ -2,16 +2,16 @@
#define _BASETYPS_H
#ifdef ENV_HAVE_GCCVISIBILITYPATCH
- #define DLLEXPORT __attribute__ ((visibility("default")))
- #else
- #define DLLEXPORT
- #endif
+ #define DLLEXPORT __attribute__ ((visibility("default")))
+#else
+ #define DLLEXPORT
+#endif
#ifdef __cplusplus
#define STDAPI extern "C" DLLEXPORT HRESULT
#else
#define STDAPI extern DLLEXPORT HRESULT
-#endif /* __cplusplus */
+#endif /* __cplusplus */
typedef GUID IID;
typedef GUID CLSID;
diff --git a/src/libs/7zip/unix/CPP/include_windows/include_windows.pri b/src/libs/7zip/unix/CPP/include_windows/include_windows.pri
new file mode 100644
index 000000000..5ef72fddd
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/include_windows/include_windows.pri
@@ -0,0 +1,3 @@
+HEADERS += $$7ZIP_BASE/CPP/include_windows/basetyps.h \
+ $$7ZIP_BASE/CPP/include_windows/tchar.h \
+ $$7ZIP_BASE/CPP/include_windows/windows.h
diff --git a/src/libs/7zip/unix/CPP/include_windows/tchar.h b/src/libs/7zip/unix/CPP/include_windows/tchar.h
index 4aa1a4f8e..5e89145af 100644
--- a/src/libs/7zip/unix/CPP/include_windows/tchar.h
+++ b/src/libs/7zip/unix/CPP/include_windows/tchar.h
@@ -1,4 +1,4 @@
-/*
+/*
* tchar.h
*
* Unicode mapping layer for the standard C library. By including this
diff --git a/src/libs/7zip/unix/CPP/include_windows/windows.h b/src/libs/7zip/unix/CPP/include_windows/windows.h
index 5223e81ac..59541864c 100644
--- a/src/libs/7zip/unix/CPP/include_windows/windows.h
+++ b/src/libs/7zip/unix/CPP/include_windows/windows.h
@@ -33,11 +33,20 @@
#define TRUE 1
#endif
-#define WINAPI
+#define WINAPI
#undef BOOL
typedef int BOOL;
+
+#define CREATE_NEW 1
+#define CREATE_ALWAYS 2
+#define OPEN_EXISTING 3
+#define OPEN_ALWAYS 4
+/* #define TRUNCATE_EXISTING 5 */
+
+
+
/* BEGIN #include <winnt.h> */
/* BEGIN <winerror.h> */
#define NO_ERROR 0L
@@ -46,7 +55,11 @@ typedef int BOOL;
#define ERROR_INVALID_HANDLE EBADF
#define ERROR_PATH_NOT_FOUND ENOENT
#define ERROR_DISK_FULL ENOSPC
-#define ERROR_NO_MORE_FILES 0x100123 // FIXME
+#define ERROR_NO_MORE_FILES 0x100018 // FIXME
+#define ERROR_DIRECTORY 267 // FIXME
+
+// #define ERROR_NEGATIVE_SEEK 0x100131 // FIXME
+
/* see Common/WyWindows.h
#define S_OK ((HRESULT)0x00000000L)
@@ -86,7 +99,7 @@ typedef TCHAR *LPTSTR;
* The corresponding macros _TEXT() and _T() for mapping _UNICODE strings
* passed to C runtime functions are defined in mingw/tchar.h
*/
-#define TEXT(q) P7ZIP_TEXT(q)
+#define TEXT(q) P7ZIP_TEXT(q)
typedef BYTE BOOLEAN;
@@ -142,11 +155,14 @@ typedef struct _SYSTEMTIME {
extern "C" {
#endif
+BOOL WINAPI DosDateTimeToFileTime(WORD,WORD,FILETIME *);
+BOOL WINAPI FileTimeToDosDateTime(CONST FILETIME *,WORD *, WORD *);
BOOL WINAPI FileTimeToLocalFileTime(CONST FILETIME *,FILETIME *);
-//BOOL WINAPI LocalFileTimeToFileTime(CONST FILETIME *,FILETIME *);
BOOL WINAPI FileTimeToSystemTime(CONST FILETIME *,SYSTEMTIME *);
+BOOL WINAPI LocalFileTimeToFileTime(CONST FILETIME *,FILETIME *);
VOID WINAPI GetSystemTime(SYSTEMTIME *);
BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME*,FILETIME *);
+VOID WINAPI GetSystemTimeAsFileTime(FILETIME * time);
DWORD WINAPI GetTickCount(VOID);
@@ -162,11 +178,11 @@ DWORD WINAPI GetTickCount(VOID);
#define CP_UTF8 65001
/* #include <unknwn.h> */
-#include <basetyps.h>
+#include "basetyps.h"
struct IEnumSTATPROPSTG;
typedef struct tagSTATPROPSTG {
- LPOLESTR lpwstrName;
+ const OLECHAR * lpwstrName; /* to avoid some warnings : LPOLESTR lpwstrName; */
PROPID propid;
VARTYPE vt;
} STATPROPSTG;
diff --git a/src/libs/7zip/unix/CPP/myWindows/StdAfx.h b/src/libs/7zip/unix/CPP/myWindows/StdAfx.h
index 629529dcf..86ce117a9 100644
--- a/src/libs/7zip/unix/CPP/myWindows/StdAfx.h
+++ b/src/libs/7zip/unix/CPP/myWindows/StdAfx.h
@@ -6,6 +6,7 @@
#include "config.h"
+#define MAXIMUM_WAIT_OBJECTS 64
#define NO_INLINE /* FIXME */
@@ -13,15 +14,16 @@
#include <pthread.h>
#endif
+#include "Common/Common.h"
#include "Common/MyWindows.h"
-#include "Common/Types.h"
+#include "Common/MyTypes.h"
-#include <windows.h>
+#include "../include_windows/tchar.h"
+#include "../include_windows/windows.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
-#include <tchar.h>
#include <wchar.h>
#include <stddef.h>
#include <ctype.h>
@@ -36,6 +38,13 @@
#undef CS /* fix for Solaris 10 x86 */
+#ifdef __cplusplus
+# define EXTERN_C extern "C"
+#else
+# define EXTERN_C extern
+#endif
+
+
/***************************/
#ifndef ENV_HAVE_WCHAR__H
@@ -87,6 +96,23 @@ typedef wxWindow *HWND;
#define MessageBox MessageBoxW
int MessageBoxW(wxWindow * parent, const TCHAR * mes, const TCHAR * title,int flag);
+
+// FIXME
+#define IDCLOSE (5001) // wxID_CLOSE
+#define IDEXIT (5006) // wxID_EXIT
+#define IDOK (5100) // wxID_OK
+#define IDCANCEL (5101) // wxID_CANCEL
+#define IDABORT (5115) // wxID_ABORT
+#define IDYES (5103) // wxID_YES
+#define IDNO (5104) // wxID_NO
+#define IDHELP (5009) // wxID_HELP
+
+// Show
+#define SW_HIDE 0
+#define SW_SHOW 5
+
+
+
typedef void *HINSTANCE;
typedef int INT_PTR; // FIXME 64 bits ?
@@ -101,8 +127,63 @@ typedef UINT_PTR WPARAM;
typedef LONG_PTR LPARAM;
typedef LONG_PTR LRESULT;
+
+#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xFFFF))
+#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16))
+
+
#define CALLBACK /* */
+#define ERROR_NEGATIVE_SEEK 0x100131 // FIXME
+#define FACILITY_WIN32 7 // FIXME
+#define __HRESULT_FROM_WIN32(x) ((HRESULT)(x) > 0 ? ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)) : (HRESULT)(x) ) // FIXME
+
+/************ Windows2.h ***********/
+
+typedef void * WNDPROC;
+typedef void * CREATESTRUCT;
+typedef struct
+{
+ HWND hwndFrom;
+
+ UINT code;
+#define NM_DBLCLK 1
+#define LVN_ITEMCHANGED 2
+#define LVN_COLUMNCLICK 3
+#define CBEN_BEGINEDIT 10
+#define CBEN_ENDEDITW 11
+
+
+} NMHDR;
+typedef NMHDR * LPNMHDR;
+
+typedef struct tagNMLISTVIEW
+{
+ NMHDR hdr;
+ INT iItem;
+ INT iSubItem;
+ UINT uNewState;
+ UINT uOldState;
+ // UINT uChanged;
+ // POINT ptAction;
+ LPARAM lParam;
+} NMLISTVIEW, *LPNMLISTVIEW;
+
+typedef void * LPNMITEMACTIVATE;
+
+#define NM_RCLICK 1234 /* FIXME */
+
+// FIXME
+#define WM_CREATE 1
+#define WM_COMMAND 2
+#define WM_NOTIFY 3
+#define WM_DESTROY 4
+#define WM_CLOSE 5
+
+#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16))
+#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xFFFF))
+
+
/************ LANG ***********/
typedef WORD LANGID;
@@ -120,5 +201,5 @@ LANGID GetSystemDefaultLangID(void);
#endif
-#endif
+#endif
diff --git a/src/libs/7zip/unix/CPP/myWindows/config.h b/src/libs/7zip/unix/CPP/myWindows/config.h
index 54332aad0..ee7d11882 100644
--- a/src/libs/7zip/unix/CPP/myWindows/config.h
+++ b/src/libs/7zip/unix/CPP/myWindows/config.h
@@ -24,14 +24,14 @@
#endif /* !ENV_MACOSX && !ENV_BEOS */
- #if !defined(ENV_BEOS)
+ #if !defined(ENV_BEOS) && !defined(ANDROID_NDK)
+
#define ENV_HAVE_GETPASS
#if !defined(sun)
#define ENV_HAVE_TIMEGM
#endif
-
#endif
/* lstat, readlink and S_ISLNK */
@@ -52,7 +52,8 @@
#define ENV_HAVE_PTHREAD
#endif
-#if defined(ENV_MACOSX)
+/* ANDROID don't have wcstombs or mbstowcs ? */
+#if defined(ENV_MACOSX) || defined(ANDROID_NDK)
#define LOCALE_IS_UTF8
#endif
diff --git a/src/libs/7zip/unix/CPP/myWindows/myCommandLineParser.cpp b/src/libs/7zip/unix/CPP/myWindows/myCommandLineParser.cpp
new file mode 100644
index 000000000..b4b444392
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/myWindows/myCommandLineParser.cpp
@@ -0,0 +1,51 @@
+/**************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#include "../CPP/Common/MyString.h"
+
+#include <QStringList>
+
+namespace NCommandLineParser {
+
+void SplitCommandLine(const UString &s, UStringVector &parts)
+{
+ parts.Clear();
+
+ const QString cmdLine = QString::fromStdWString(static_cast<const wchar_t*>(s));
+ const QStringList args = cmdLine.simplified().split(QLatin1Char(' '), QString::SkipEmptyParts);
+ foreach (const QString &arg, args)
+ parts.Add(arg.toStdWString().c_str());
+}
+
+} // namespace NCommandLineParser
diff --git a/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp b/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp
index 96554c900..48cb17c9a 100644
--- a/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp
+++ b/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp
@@ -32,19 +32,20 @@
**
**************************************************************************/
-#include <QDebug>
-#include <QDateTime>
#include "windows.h"
+#include <QDateTime>
+
+#include <chrono>
+
void FileTimeToDateTime(const FILETIME *source, QDateTime *target)
{
ULARGE_INTEGER store;
- QDateTime tempDateTime(QDate(1601, 1, 1));
-
store.QuadPart = source->dwHighDateTime;
store.QuadPart = store.QuadPart << 32;
store.QuadPart += source->dwLowDateTime;
+ const QDateTime tempDateTime(QDate(1601, 1, 1), QTime(0, 0, 0, 0), Qt::UTC);
*target = tempDateTime.addMSecs(store.QuadPart / 10000);
}
@@ -60,6 +61,13 @@ void DateTimeToSystemTime(const QDateTime *source, SYSTEMTIME *target)
target->wMilliseconds = source->time().msec();
}
+void DateTimeToFileTime(const QDateTime &dateTime, FILETIME *target)
+{
+ const qint64 nsecs = QDateTime(QDate(1601, 1, 1), QTime(0, 0, 0, 0), Qt::UTC)
+ .msecsTo(dateTime) * 10000;
+ target->dwLowDateTime = nsecs;
+ target->dwHighDateTime = nsecs >> 32;
+}
BOOL WINAPI FileTimeToSystemTime(CONST FILETIME *source,SYSTEMTIME *target)
{
@@ -70,21 +78,6 @@ BOOL WINAPI FileTimeToSystemTime(CONST FILETIME *source,SYSTEMTIME *target)
return TRUE;
}
-BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME *source,FILETIME *target)
-{
- // TODO: Implementation!
- // This doesn't seem to be called at all
-
- qDebug() << "SystemTimeToFileTime";
-
- target->dwHighDateTime = 0;
- target->dwLowDateTime = 0;
-
- qWarning() << Q_FUNC_INFO;
-
- return TRUE;
-}
-
BOOL WINAPI FileTimeToLocalFileTime(CONST FILETIME *source,FILETIME *target)
{
target->dwHighDateTime = source->dwHighDateTime;
@@ -137,3 +130,14 @@ VOID WINAPI GetSystemTime(SYSTEMTIME *st)
QDateTime nowDateTime = QDateTime::currentDateTimeUtc();
DateTimeToSystemTime(&nowDateTime, st);
}
+
+VOID WINAPI GetSystemTimeAsFileTime(FILETIME *time)
+{
+ DateTimeToFileTime(QDateTime::currentDateTimeUtc(), time);
+}
+
+DWORD WINAPI GetTickCount()
+{
+ using namespace std::chrono;
+ return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
+}
diff --git a/src/libs/7zip/unix/CPP/myWindows/myWindows.pri b/src/libs/7zip/unix/CPP/myWindows/myWindows.pri
new file mode 100644
index 000000000..0875fdb1f
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/myWindows/myWindows.pri
@@ -0,0 +1,7 @@
+HEADERS += $$7ZIP_BASE/CPP/myWindows/StdAfx.h \
+ $$7ZIP_BASE/CPP/myWindows/config.h \
+ $$7ZIP_BASE/CPP/myWindows/initguid.h \
+ $$7ZIP_BASE/CPP/myWindows/myPrivate.h
+
+SOURCES += $$7ZIP_BASE/CPP/myWindows/myDateAndTime.cpp \
+ $$7ZIP_BASE/CPP/myWindows/myCommandLineParser.cpp
diff --git a/src/libs/7zip/unix/Methods.txt b/src/libs/7zip/unix/Methods.txt
deleted file mode 100644
index f52e7c315..000000000
--- a/src/libs/7zip/unix/Methods.txt
+++ /dev/null
@@ -1,152 +0,0 @@
-7-Zip method IDs (9.18)
------------------------
-
-Each compression or crypto method in 7z has unique binary value (ID).
-The length of ID in bytes is arbitrary but it can not exceed 63 bits (8 bytes).
-
-If you want to add some new ID, you have two ways:
-1) Write request for allocating IDs to 7-zip developers.
-2) Generate 8-bytes ID:
-
- 3F ZZ ZZ ZZ ZZ ZZ MM MM
-
- 3F - Prefix for random IDs (1 byte)
- ZZ ZZ ZZ ZZ ZZ - Developer ID (5 bytes). Use real random bytes.
-
- MM MM - Method ID (2 bytes)
-
- You can notify 7-Zip developers about your Developer ID / Method ID.
-
- Note: Use new ID only if old codec can not decode data encoded with new version.
-
-
-List of defined IDs
--------------------
-
-00 - Copy
-
-03 - Delta
-04 - x86 (BCJ)
-05 - PPC (Big Endian)
-06 - IA64
-07 - ARM (little endian)
-08 - ARM Thumb (little endian)
-09 - SPARC
-21 - LZMA2
-
-02.. - Common
- 03 Swap
- - 2 Swap2
- - 4 Swap4
-
-03.. - 7z
- 01 - LZMA
- 01 - Version
-
- 03 - Branch
- 01 - x86
- 03 - BCJ
- 1B - BCJ2
- 02 - PPC
- 05 - PPC (Big Endian)
- 03 - Alpha
- 01 - Alpha
- 04 - IA64
- 01 - IA64
- 05 - ARM
- 01 - ARM
- 06 - M68
- 05 - M68 (Big Endian)
- 07 - ARM Thumb
- 01 - ARMT
- 08 - SPARC
- 05 - SPARC
-
- 04 - PPMD
- 01 - Version
-
- 7F -
- 01 - experimental methods.
-
-
-04.. - Misc
- 00 - Reserved
- 01 - Zip
- 00 - Copy (not used). Use {00} instead
- 01 - Shrink
- 06 - Implode
- 08 - Deflate
- 09 - Deflate64
- 10 - Imploding
- 12 - BZip2 (not used). Use {04 02 02} instead
- 14 - LZMA
- 60 - Jpeg
- 61 - WavPack
- 62 - PPMd
- 63 - wzAES
- 02 - BZip
- 02 - BZip2
- 03 - Rar
- 01 - Rar15
- 02 - Rar20
- 03 - Rar29
- 04 - Arj
- 01 - Arj (1,2,3)
- 02 - Arj 4
- 05 - Z
- 06 - Lzh
- 07 - Reserved for 7z
- 08 - Cab
- 09 - NSIS
- 01 - DeflateNSIS
- 02 - BZip2NSIS
-
-
-06.. - Crypto
- 00 -
- 01 - AES
- 0x - AES-128
- 4x - AES-192
- 8x - AES-256
- Cx - AES
-
- x0 - ECB
- x1 - CBC
- x2 - CFB
- x3 - OFB
-
- 07 - Reserved
- 0F - Reserved
-
- F0 - Misc Ciphers (Real Ciphers without hashing algo)
-
- F1 - Misc Ciphers (Combine)
- 01 - Zip
- 01 - Main Zip crypto algo
- 03 - RAR
- 02 -
- 03 - Rar29 AES-128 + (modified SHA-1)
- 07 - 7z
- 01 - AES-256 + SHA-256
-
-07.. - Hash (subject to change)
- 00 -
- 01 - CRC
- 02 - SHA-1
- 03 - SHA-256
- 04 - SHA-384
- 05 - SHA-512
-
- F0 - Misc Hash
-
- F1 - Misc
- 03 - RAR
- 03 - Rar29 Password Hashing (modified SHA1)
- 07 - 7z
- 01 - SHA-256 Password Hashing
-
-
-
-
----
-End of document
diff --git a/src/libs/7zip/unix/history.txt b/src/libs/7zip/unix/history.txt
deleted file mode 100644
index 79abd9cea..000000000
--- a/src/libs/7zip/unix/history.txt
+++ /dev/null
@@ -1,271 +0,0 @@
-HISTORY of the LZMA SDK
------------------------
-
-9.18 beta 2010-11-02
--------------------------
-- New small SFX module for installers (SfxSetup).
-
-
-9.12 beta 2010-03-24
--------------------------
-- The BUG in LZMA SDK 9.* was fixed: LZMA2 codec didn't work,
- if more than 10 threads were used (or more than 20 threads in some modes).
-
-
-9.11 beta 2010-03-15
--------------------------
-- PPMd compression method support
-
-
-9.09 2009-12-12
--------------------------
-- The bug was fixed:
- Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c
- incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8.
-- Some bugs were fixed
-
-
-9.06 2009-08-17
--------------------------
-- Some changes in ANSI-C 7z Decoder interfaces.
-
-
-9.04 2009-05-30
--------------------------
-- LZMA2 compression method support
-- xz format support
-
-
-4.65 2009-02-03
--------------------------
-- Some minor fixes
-
-
-4.63 2008-12-31
--------------------------
-- Some minor fixes
-
-
-4.61 beta 2008-11-23
--------------------------
-- The bug in ANSI-C LZMA Decoder was fixed:
- If encoded stream was corrupted, decoder could access memory
- outside of allocated range.
-- Some changes in ANSI-C 7z Decoder interfaces.
-- LZMA SDK is placed in the public domain.
-
-
-4.60 beta 2008-08-19
--------------------------
-- Some minor fixes.
-
-
-4.59 beta 2008-08-13
--------------------------
-- The bug was fixed:
- LZMA Encoder in fast compression mode could access memory outside of
- allocated range in some rare cases.
-
-
-4.58 beta 2008-05-05
--------------------------
-- ANSI-C LZMA Decoder was rewritten for speed optimizations.
-- ANSI-C LZMA Encoder was included to LZMA SDK.
-- C++ LZMA code now is just wrapper over ANSI-C code.
-
-
-4.57 2007-12-12
--------------------------
-- Speed optimizations in Ñ++ LZMA Decoder.
-- Small changes for more compatibility with some C/C++ compilers.
-
-
-4.49 beta 2007-07-05
--------------------------
-- .7z ANSI-C Decoder:
- - now it supports BCJ and BCJ2 filters
- - now it supports files larger than 4 GB.
- - now it supports "Last Write Time" field for files.
-- C++ code for .7z archives compressing/decompressing from 7-zip
- was included to LZMA SDK.
-
-
-4.43 2006-06-04
--------------------------
-- Small changes for more compatibility with some C/C++ compilers.
-
-
-4.42 2006-05-15
--------------------------
-- Small changes in .h files in ANSI-C version.
-
-
-4.39 beta 2006-04-14
--------------------------
-- The bug in versions 4.33b:4.38b was fixed:
- C++ version of LZMA encoder could not correctly compress
- files larger than 2 GB with HC4 match finder (-mfhc4).
-
-
-4.37 beta 2005-04-06
--------------------------
-- Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined.
-
-
-4.35 beta 2005-03-02
--------------------------
-- The bug was fixed in C++ version of LZMA Decoder:
- If encoded stream was corrupted, decoder could access memory
- outside of allocated range.
-
-
-4.34 beta 2006-02-27
--------------------------
-- Compressing speed and memory requirements for compressing were increased
-- LZMA now can use only these match finders: HC4, BT2, BT3, BT4
-
-
-4.32 2005-12-09
--------------------------
-- Java version of LZMA SDK was included
-
-
-4.30 2005-11-20
--------------------------
-- Compression ratio was improved in -a2 mode
-- Speed optimizations for compressing in -a2 mode
-- -fb switch now supports values up to 273
-- The bug in 7z_C (7zIn.c) was fixed:
- It used Alloc/Free functions from different memory pools.
- So if program used two memory pools, it worked incorrectly.
-- 7z_C: .7z format supporting was improved
-- LZMA# SDK (C#.NET version) was included
-
-
-4.27 (Updated) 2005-09-21
--------------------------
-- Some GUIDs/interfaces in C++ were changed.
- IStream.h:
- ISequentialInStream::Read now works as old ReadPart
- ISequentialOutStream::Write now works as old WritePart
-
-
-4.27 2005-08-07
--------------------------
-- The bug in LzmaDecodeSize.c was fixed:
- if _LZMA_IN_CB and _LZMA_OUT_READ were defined,
- decompressing worked incorrectly.
-
-
-4.26 2005-08-05
--------------------------
-- Fixes in 7z_C code and LzmaTest.c:
- previous versions could work incorrectly,
- if malloc(0) returns 0
-
-
-4.23 2005-06-29
--------------------------
-- Small fixes in C++ code
-
-
-4.22 2005-06-10
--------------------------
-- Small fixes
-
-
-4.21 2005-06-08
--------------------------
-- Interfaces for ANSI-C LZMA Decoder (LzmaDecode.c) were changed
-- New additional version of ANSI-C LZMA Decoder with zlib-like interface:
- - LzmaStateDecode.h
- - LzmaStateDecode.c
- - LzmaStateTest.c
-- ANSI-C LZMA Decoder now can decompress files larger than 4 GB
-
-
-4.17 2005-04-18
--------------------------
-- New example for RAM->RAM compressing/decompressing:
- LZMA + BCJ (filter for x86 code):
- - LzmaRam.h
- - LzmaRam.cpp
- - LzmaRamDecode.h
- - LzmaRamDecode.c
- - -f86 switch for lzma.exe
-
-
-4.16 2005-03-29
--------------------------
-- The bug was fixed in LzmaDecode.c (ANSI-C LZMA Decoder):
- If _LZMA_OUT_READ was defined, and if encoded stream was corrupted,
- decoder could access memory outside of allocated range.
-- Speed optimization of ANSI-C LZMA Decoder (now it's about 20% faster).
- Old version of LZMA Decoder now is in file LzmaDecodeSize.c.
- LzmaDecodeSize.c can provide slightly smaller code than LzmaDecode.c
-- Small speed optimization in LZMA C++ code
-- filter for SPARC's code was added
-- Simplified version of .7z ANSI-C Decoder was included
-
-
-4.06 2004-09-05
--------------------------
-- The bug in v4.05 was fixed:
- LZMA-Encoder didn't release output stream in some cases.
-
-
-4.05 2004-08-25
--------------------------
-- Source code of filters for x86, IA-64, ARM, ARM-Thumb
- and PowerPC code was included to SDK
-- Some internal minor changes
-
-
-4.04 2004-07-28
--------------------------
-- More compatibility with some C++ compilers
-
-
-4.03 2004-06-18
--------------------------
-- "Benchmark" command was added. It measures compressing
- and decompressing speed and shows rating values.
- Also it checks hardware errors.
-
-
-4.02 2004-06-10
--------------------------
-- C++ LZMA Encoder/Decoder code now is more portable
- and it can be compiled by GCC on Linux.
-
-
-4.01 2004-02-15
--------------------------
-- Some detection of data corruption was enabled.
- LzmaDecode.c / RangeDecoderReadByte
- .....
- {
- rd->ExtraBytes = 1;
- return 0xFF;
- }
-
-
-4.00 2004-02-13
--------------------------
-- Original version of LZMA SDK
-
-
-
-HISTORY of the LZMA
--------------------
- 2001-2008: Improvements to LZMA compressing/decompressing code,
- keeping compatibility with original LZMA format
- 1996-2001: Development of LZMA compression format
-
- Some milestones:
-
- 2001-08-30: LZMA compression was added to 7-Zip
- 1999-01-02: First version of 7-Zip was released
-
-
-End of document
diff --git a/src/libs/7zip/unix/lzma.txt b/src/libs/7zip/unix/lzma.txt
deleted file mode 100644
index 659323237..000000000
--- a/src/libs/7zip/unix/lzma.txt
+++ /dev/null
@@ -1,598 +0,0 @@
-LZMA SDK 9.20
--------------
-
-LZMA SDK provides the documentation, samples, header files, libraries,
-and tools you need to develop applications that use LZMA compression.
-
-LZMA is default and general compression method of 7z format
-in 7-Zip compression program (www.7-zip.org). LZMA provides high
-compression ratio and very fast decompression.
-
-LZMA is an improved version of famous LZ77 compression algorithm.
-It was improved in way of maximum increasing of compression ratio,
-keeping high decompression speed and low memory requirements for
-decompressing.
-
-
-
-LICENSE
--------
-
-LZMA SDK is written and placed in the public domain by Igor Pavlov.
-
-Some code in LZMA SDK is based on public domain code from another developers:
- 1) PPMd var.H (2001): Dmitry Shkarin
- 2) SHA-256: Wei Dai (Crypto++ library)
-
-
-LZMA SDK Contents
------------------
-
-LZMA SDK includes:
-
- - ANSI-C/C++/C#/Java source code for LZMA compressing and decompressing
- - Compiled file->file LZMA compressing/decompressing program for Windows system
-
-
-UNIX/Linux version
-------------------
-To compile C++ version of file->file LZMA encoding, go to directory
-CPP/7zip/Bundles/LzmaCon
-and call make to recompile it:
- make -f makefile.gcc clean all
-
-In some UNIX/Linux versions you must compile LZMA with static libraries.
-To compile with static libraries, you can use
-LIB = -lm -static
-
-
-Files
----------------------
-lzma.txt - LZMA SDK description (this file)
-7zFormat.txt - 7z Format description
-7zC.txt - 7z ANSI-C Decoder description
-methods.txt - Compression method IDs for .7z
-lzma.exe - Compiled file->file LZMA encoder/decoder for Windows
-7zr.exe - 7-Zip with 7z/lzma/xz support.
-history.txt - history of the LZMA SDK
-
-
-Source code structure
----------------------
-
-C/ - C files
- 7zCrc*.* - CRC code
- Alloc.* - Memory allocation functions
- Bra*.* - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
- LzFind.* - Match finder for LZ (LZMA) encoders
- LzFindMt.* - Match finder for LZ (LZMA) encoders for multithreading encoding
- LzHash.h - Additional file for LZ match finder
- LzmaDec.* - LZMA decoding
- LzmaEnc.* - LZMA encoding
- LzmaLib.* - LZMA Library for DLL calling
- Types.h - Basic types for another .c files
- Threads.* - The code for multithreading.
-
- LzmaLib - LZMA Library (.DLL for Windows)
-
- LzmaUtil - LZMA Utility (file->file LZMA encoder/decoder).
-
- Archive - files related to archiving
- 7z - 7z ANSI-C Decoder
-
-CPP/ -- CPP files
-
- Common - common files for C++ projects
- Windows - common files for Windows related code
-
- 7zip - files related to 7-Zip Project
-
- Common - common files for 7-Zip
-
- Compress - files related to compression/decompression
-
- Archive - files related to archiving
-
- Common - common files for archive handling
- 7z - 7z C++ Encoder/Decoder
-
- Bundles - Modules that are bundles of other modules
-
- Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2
- LzmaCon - lzma.exe: LZMA compression/decompression
- Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2
- Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.
-
- UI - User Interface files
-
- Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll
- Common - Common UI files
- Console - Code for console archiver
-
-
-
-CS/ - C# files
- 7zip
- Common - some common files for 7-Zip
- Compress - files related to compression/decompression
- LZ - files related to LZ (Lempel-Ziv) compression algorithm
- LZMA - LZMA compression/decompression
- LzmaAlone - file->file LZMA compression/decompression
- RangeCoder - Range Coder (special code of compression/decompression)
-
-Java/ - Java files
- SevenZip
- Compression - files related to compression/decompression
- LZ - files related to LZ (Lempel-Ziv) compression algorithm
- LZMA - LZMA compression/decompression
- RangeCoder - Range Coder (special code of compression/decompression)
-
-
-C/C++ source code of LZMA SDK is part of 7-Zip project.
-7-Zip source code can be downloaded from 7-Zip's SourceForge page:
-
- http://sourceforge.net/projects/sevenzip/
-
-
-
-LZMA features
--------------
- - Variable dictionary size (up to 1 GB)
- - Estimated compressing speed: about 2 MB/s on 2 GHz CPU
- - Estimated decompressing speed:
- - 20-30 MB/s on 2 GHz Core 2 or AMD Athlon 64
- - 1-2 MB/s on 200 MHz ARM, MIPS, PowerPC or other simple RISC
- - Small memory requirements for decompressing (16 KB + DictionarySize)
- - Small code size for decompressing: 5-8 KB
-
-LZMA decoder uses only integer operations and can be
-implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
-
-Some critical operations that affect the speed of LZMA decompression:
- 1) 32*16 bit integer multiply
- 2) Misspredicted branches (penalty mostly depends from pipeline length)
- 3) 32-bit shift and arithmetic operations
-
-The speed of LZMA decompressing mostly depends from CPU speed.
-Memory speed has no big meaning. But if your CPU has small data cache,
-overall weight of memory speed will slightly increase.
-
-
-How To Use
-----------
-
-Using LZMA encoder/decoder executable
---------------------------------------
-
-Usage: LZMA <e|d> inputFile outputFile [<switches>...]
-
- e: encode file
-
- d: decode file
-
- b: Benchmark. There are two tests: compressing and decompressing
- with LZMA method. Benchmark shows rating in MIPS (million
- instructions per second). Rating value is calculated from
- measured speed and it is normalized with Intel's Core 2 results.
- Also Benchmark checks possible hardware errors (RAM
- errors in most cases). Benchmark uses these settings:
- (-a1, -d21, -fb32, -mfbt4). You can change only -d parameter.
- Also you can change the number of iterations. Example for 30 iterations:
- LZMA b 30
- Default number of iterations is 10.
-
-<Switches>
-
-
- -a{N}: set compression mode 0 = fast, 1 = normal
- default: 1 (normal)
-
- d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
- The maximum value for dictionary size is 1 GB = 2^30 bytes.
- Dictionary size is calculated as DictionarySize = 2^N bytes.
- For decompressing file compressed by LZMA method with dictionary
- size D = 2^N you need about D bytes of memory (RAM).
-
- -fb{N}: set number of fast bytes - [5, 273], default: 128
- Usually big number gives a little bit better compression ratio
- and slower compression process.
-
- -lc{N}: set number of literal context bits - [0, 8], default: 3
- Sometimes lc=4 gives gain for big files.
-
- -lp{N}: set number of literal pos bits - [0, 4], default: 0
- lp switch is intended for periodical data when period is
- equal 2^N. For example, for 32-bit (4 bytes)
- periodical data you can use lp=2. Often it's better to set lc0,
- if you change lp switch.
-
- -pb{N}: set number of pos bits - [0, 4], default: 2
- pb switch is intended for periodical data
- when period is equal 2^N.
-
- -mf{MF_ID}: set Match Finder. Default: bt4.
- Algorithms from hc* group doesn't provide good compression
- ratio, but they often works pretty fast in combination with
- fast mode (-a0).
-
- Memory requirements depend from dictionary size
- (parameter "d" in table below).
-
- MF_ID Memory Description
-
- bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
- bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
- bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
- hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
-
- -eos: write End Of Stream marker. By default LZMA doesn't write
- eos marker, since LZMA decoder knows uncompressed size
- stored in .lzma file header.
-
- -si: Read data from stdin (it will write End Of Stream marker).
- -so: Write data to stdout
-
-
-Examples:
-
-1) LZMA e file.bin file.lzma -d16 -lc0
-
-compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)
-and 0 literal context bits. -lc0 allows to reduce memory requirements
-for decompression.
-
-
-2) LZMA e file.bin file.lzma -lc0 -lp2
-
-compresses file.bin to file.lzma with settings suitable
-for 32-bit periodical data (for example, ARM or MIPS code).
-
-3) LZMA d file.lzma file.bin
-
-decompresses file.lzma to file.bin.
-
-
-Compression ratio hints
------------------------
-
-Recommendations
----------------
-
-To increase the compression ratio for LZMA compressing it's desirable
-to have aligned data (if it's possible) and also it's desirable to locate
-data in such order, where code is grouped in one place and data is
-grouped in other place (it's better than such mixing: code, data, code,
-data, ...).
-
-
-Filters
--------
-You can increase the compression ratio for some data types, using
-special filters before compressing. For example, it's possible to
-increase the compression ratio on 5-10% for code for those CPU ISAs:
-x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
-
-You can find C source code of such filters in C/Bra*.* files
-
-You can check the compression ratio gain of these filters with such
-7-Zip commands (example for ARM code):
-No filter:
- 7z a a1.7z a.bin -m0=lzma
-
-With filter for little-endian ARM code:
- 7z a a2.7z a.bin -m0=arm -m1=lzma
-
-It works in such manner:
-Compressing = Filter_encoding + LZMA_encoding
-Decompressing = LZMA_decoding + Filter_decoding
-
-Compressing and decompressing speed of such filters is very high,
-so it will not increase decompressing time too much.
-Moreover, it reduces decompression time for LZMA_decoding,
-since compression ratio with filtering is higher.
-
-These filters convert CALL (calling procedure) instructions
-from relative offsets to absolute addresses, so such data becomes more
-compressible.
-
-For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
-
-
-LZMA compressed file format
----------------------------
-Offset Size Description
- 0 1 Special LZMA properties (lc,lp, pb in encoded form)
- 1 4 Dictionary size (little endian)
- 5 8 Uncompressed size (little endian). -1 means unknown size
- 13 Compressed data
-
-
-ANSI-C LZMA Decoder
-~~~~~~~~~~~~~~~~~~~
-
-Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58.
-If you want to use old interfaces you can download previous version of LZMA SDK
-from sourceforge.net site.
-
-To use ANSI-C LZMA Decoder you need the following files:
-1) LzmaDec.h + LzmaDec.c + Types.h
-LzmaUtil/LzmaUtil.c is example application that uses these files.
-
-
-Memory requirements for LZMA decoding
--------------------------------------
-
-Stack usage of LZMA decoding function for local variables is not
-larger than 200-400 bytes.
-
-LZMA Decoder uses dictionary buffer and internal state structure.
-Internal state structure consumes
- state_size = (4 + (1.5 << (lc + lp))) KB
-by default (lc=3, lp=0), state_size = 16 KB.
-
-
-How To decompress data
-----------------------
-
-LZMA Decoder (ANSI-C version) now supports 2 interfaces:
-1) Single-call Decompressing
-2) Multi-call State Decompressing (zlib-like interface)
-
-You must use external allocator:
-Example:
-void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }
-void SzFree(void *p, void *address) { p = p; free(address); }
-ISzAlloc alloc = { SzAlloc, SzFree };
-
-You can use p = p; operator to disable compiler warnings.
-
-
-Single-call Decompressing
--------------------------
-When to use: RAM->RAM decompressing
-Compile files: LzmaDec.h + LzmaDec.c + Types.h
-Compile defines: no defines
-Memory Requirements:
- - Input buffer: compressed size
- - Output buffer: uncompressed size
- - LZMA Internal Structures: state_size (16 KB for default settings)
-
-Interface:
- int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
- const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
- ELzmaStatus *status, ISzAlloc *alloc);
- In:
- dest - output data
- destLen - output data size
- src - input data
- srcLen - input data size
- propData - LZMA properties (5 bytes)
- propSize - size of propData buffer (5 bytes)
- finishMode - It has meaning only if the decoding reaches output limit (*destLen).
- LZMA_FINISH_ANY - Decode just destLen bytes.
- LZMA_FINISH_END - Stream must be finished after (*destLen).
- You can use LZMA_FINISH_END, when you know that
- current output buffer covers last bytes of stream.
- alloc - Memory allocator.
-
- Out:
- destLen - processed output size
- srcLen - processed input size
-
- Output:
- SZ_OK
- status:
- LZMA_STATUS_FINISHED_WITH_MARK
- LZMA_STATUS_NOT_FINISHED
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
- SZ_ERROR_DATA - Data error
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_UNSUPPORTED - Unsupported properties
- SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
-
- If LZMA decoder sees end_marker before reaching output limit, it returns OK result,
- and output value of destLen will be less than output buffer size limit.
-
- You can use multiple checks to test data integrity after full decompression:
- 1) Check Result and "status" variable.
- 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
- 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
- You must use correct finish mode in that case. */
-
-
-Multi-call State Decompressing (zlib-like interface)
-----------------------------------------------------
-
-When to use: file->file decompressing
-Compile files: LzmaDec.h + LzmaDec.c + Types.h
-
-Memory Requirements:
- - Buffer for input stream: any size (for example, 16 KB)
- - Buffer for output stream: any size (for example, 16 KB)
- - LZMA Internal Structures: state_size (16 KB for default settings)
- - LZMA dictionary (dictionary size is encoded in LZMA properties header)
-
-1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header:
- unsigned char header[LZMA_PROPS_SIZE + 8];
- ReadFile(inFile, header, sizeof(header)
-
-2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties
-
- CLzmaDec state;
- LzmaDec_Constr(&state);
- res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);
- if (res != SZ_OK)
- return res;
-
-3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop
-
- LzmaDec_Init(&state);
- for (;;)
- {
- ...
- int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);
- ...
- }
-
-
-4) Free all allocated structures
- LzmaDec_Free(&state, &g_Alloc);
-
-For full code example, look at C/LzmaUtil/LzmaUtil.c code.
-
-
-How To compress data
---------------------
-
-Compile files: LzmaEnc.h + LzmaEnc.c + Types.h +
-LzFind.c + LzFind.h + LzFindMt.c + LzFindMt.h + LzHash.h
-
-Memory Requirements:
- - (dictSize * 11.5 + 6 MB) + state_size
-
-Lzma Encoder can use two memory allocators:
-1) alloc - for small arrays.
-2) allocBig - for big arrays.
-
-For example, you can use Large RAM Pages (2 MB) in allocBig allocator for
-better compression speed. Note that Windows has bad implementation for
-Large RAM Pages.
-It's OK to use same allocator for alloc and allocBig.
-
-
-Single-call Compression with callbacks
---------------------------------------
-
-Check C/LzmaUtil/LzmaUtil.c as example,
-
-When to use: file->file decompressing
-
-1) you must implement callback structures for interfaces:
-ISeqInStream
-ISeqOutStream
-ICompressProgress
-ISzAlloc
-
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
- CFileSeqInStream inStream;
- CFileSeqOutStream outStream;
-
- inStream.funcTable.Read = MyRead;
- inStream.file = inFile;
- outStream.funcTable.Write = MyWrite;
- outStream.file = outFile;
-
-
-2) Create CLzmaEncHandle object;
-
- CLzmaEncHandle enc;
-
- enc = LzmaEnc_Create(&g_Alloc);
- if (enc == 0)
- return SZ_ERROR_MEM;
-
-
-3) initialize CLzmaEncProps properties;
-
- LzmaEncProps_Init(&props);
-
- Then you can change some properties in that structure.
-
-4) Send LZMA properties to LZMA Encoder
-
- res = LzmaEnc_SetProps(enc, &props);
-
-5) Write encoded properties to header
-
- Byte header[LZMA_PROPS_SIZE + 8];
- size_t headerSize = LZMA_PROPS_SIZE;
- UInt64 fileSize;
- int i;
-
- res = LzmaEnc_WriteProperties(enc, header, &headerSize);
- fileSize = MyGetFileLength(inFile);
- for (i = 0; i < 8; i++)
- header[headerSize++] = (Byte)(fileSize >> (8 * i));
- MyWriteFileAndCheck(outFile, header, headerSize)
-
-6) Call encoding function:
- res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable,
- NULL, &g_Alloc, &g_Alloc);
-
-7) Destroy LZMA Encoder Object
- LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
-
-
-If callback function return some error code, LzmaEnc_Encode also returns that code
-or it can return the code like SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS.
-
-
-Single-call RAM->RAM Compression
---------------------------------
-
-Single-call RAM->RAM Compression is similar to Compression with callbacks,
-but you provide pointers to buffers instead of pointers to stream callbacks:
-
-HRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
- CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-
-Return code:
- SZ_OK - OK
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_PARAM - Incorrect paramater
- SZ_ERROR_OUTPUT_EOF - output buffer overflow
- SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
-
-
-
-Defines
--------
-
-_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code.
-
-_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for
- some structures will be doubled in that case.
-
-_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is 32-bit.
-
-_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type.
-
-
-_7ZIP_PPMD_SUPPPORT - Define it if you don't want to support PPMD method in AMSI-C .7z decoder.
-
-
-C++ LZMA Encoder/Decoder
-~~~~~~~~~~~~~~~~~~~~~~~~
-C++ LZMA code use COM-like interfaces. So if you want to use it,
-you can study basics of COM/OLE.
-C++ LZMA code is just wrapper over ANSI-C code.
-
-
-C++ Notes
-~~~~~~~~~~~~~~~~~~~~~~~~
-If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling),
-you must check that you correctly work with "new" operator.
-7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator.
-So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator:
-operator new(size_t size)
-{
- void *p = ::malloc(size);
- if (p == 0)
- throw CNewException();
- return p;
-}
-If you use MSCV that throws exception for "new" operator, you can compile without
-"NewHandler.cpp". So standard exception will be used. Actually some code of
-7-Zip catches any exception in internal code and converts it to HRESULT code.
-So you don't need to catch CNewException, if you call COM interfaces of 7-Zip.
-
----
-
-http://www.7-zip.org
-http://www.7-zip.org/sdk.html
-http://www.7-zip.org/support.html
diff --git a/src/libs/7zip/unix/unix.pri b/src/libs/7zip/unix/unix.pri
index f5c749e24..6071add8f 100644
--- a/src/libs/7zip/unix/unix.pri
+++ b/src/libs/7zip/unix/unix.pri
@@ -1,131 +1,13 @@
-#$(COMMON_OBJS): ../../../Common/$(*B).cpp
-SOURCES += $$7ZIP_BASE/CPP/Common/IntToString.cpp
-SOURCES += $$7ZIP_BASE/CPP/Common/MyString.cpp
-SOURCES += $$7ZIP_BASE/CPP/Common/StringConvert.cpp
-SOURCES += $$7ZIP_BASE/CPP/Common/StringToInt.cpp
-SOURCES += $$7ZIP_BASE/CPP/Common/MyVector.cpp
-SOURCES += $$7ZIP_BASE/CPP/Common/Wildcard.cpp
-SOURCES += $$7ZIP_BASE/CPP/Common/MyWindows.cpp
-
-#$(WIN_OBJS): ../../../Windows/$(*B).cpp
-SOURCES += $$7ZIP_BASE/CPP/Windows/FileDir.cpp
-SOURCES += $$7ZIP_BASE/CPP/Windows/FileFind.cpp
-SOURCES += $$7ZIP_BASE/CPP/Windows/FileName.cpp
-SOURCES += $$7ZIP_BASE/CPP/Windows/FileIO.cpp
-SOURCES += $$7ZIP_BASE/CPP/Windows/PropVariant.cpp
-SOURCES += $$7ZIP_BASE/CPP/Windows/PropVariantConversions.cpp
-SOURCES += $$7ZIP_BASE/CPP/Windows/Synchronization.cpp
-SOURCES += $$7ZIP_BASE/CPP/Windows/System.cpp
-SOURCES += $$7ZIP_BASE/CPP/Windows/Time.cpp
-
-#$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/CreateCoder.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/CWrappers.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/InBuffer.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/InOutTempBuffer.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/FileStreams.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/FilterCoder.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/LimitedStreams.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/LockedStream.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/MethodId.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/MethodProps.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/OutBuffer.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/ProgressUtils.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/StreamBinder.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/StreamObjects.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/StreamUtils.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Common/VirtThread.cpp
-
-#$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/DefaultName.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/EnumDirItems.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/LoadCodecs.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/OpenArchive.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/SetProperties.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/SortUtils.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/TempFiles.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/Update.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/UpdateAction.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/UpdateCallback.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/UpdatePair.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Common/UpdateProduce.cpp
-
-#$(AR_OBJS): ../../Archive/$(*B).cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/LzmaHandler.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/SplitHandler.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/XzHandler.cpp
-
-#$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/Common/CoderMixer2.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/Common/HandlerOut.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/Common/ItemNameUtils.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/Common/ParseProperties.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/Common/MultiStream.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/Common/DummyOutStream.cpp
-
-#$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zDecode.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zEncode.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zExtract.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zFolderInStream.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHandler.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHandlerOut.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zHeader.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zIn.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zOut.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zProperties.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zSpecStream.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zUpdate.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Archive/7z/7zRegister.cpp
-
-#$(COMPRESS_OBJS): ../../Compress/$(*B).cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/Bcj2Coder.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/Bcj2Register.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/BcjCoder.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/BcjRegister.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/BranchCoder.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/BranchMisc.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/BranchRegister.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/ByteSwap.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/CopyCoder.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/CopyRegister.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/DeltaFilter.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/Lzma2Decoder.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/Lzma2Encoder.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/Lzma2Register.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/LzmaDecoder.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/LzmaEncoder.cpp
-SOURCES += $$7ZIP_BASE/CPP/7zip/Compress/LzmaRegister.cpp
-
-#$(C_OBJS): ../../../../C/$(*B).c
-SOURCES += $$7ZIP_BASE/C/Alloc.c
-SOURCES += $$7ZIP_BASE/C/Bra.c
-SOURCES += $$7ZIP_BASE/C/Bra86.c
-SOURCES += $$7ZIP_BASE/C/BraIA64.c
-SOURCES += $$7ZIP_BASE/C/CpuArch.c
-SOURCES += $$7ZIP_BASE/C/Delta.c
-SOURCES += $$7ZIP_BASE/C/LzFind.c
-SOURCES += $$7ZIP_BASE/C/LzFindMt.c
-SOURCES += $$7ZIP_BASE/C/Lzma2Dec.c
-SOURCES += $$7ZIP_BASE/C/Lzma2Enc.c
-SOURCES += $$7ZIP_BASE/C/LzmaDec.c
-SOURCES += $$7ZIP_BASE/C/LzmaEnc.c
-SOURCES += $$7ZIP_BASE/C/MtCoder.c
-SOURCES += $$7ZIP_BASE/C/Threads.c
-SOURCES += $$7ZIP_BASE/C/7zCrc.c
-SOURCES += $$7ZIP_BASE/C/7zCrcOpt.c
-SOURCES += $$7ZIP_BASE/C/7zStream.c
-SOURCES += $$7ZIP_BASE/C/Xz.c
-SOURCES += $$7ZIP_BASE/C/XzIn.c
-SOURCES += $$7ZIP_BASE/C/XzCrc64.c
-SOURCES += $$7ZIP_BASE/C/XzDec.c
-SOURCES += $$7ZIP_BASE/C/XzEnc.c
-SOURCES += $$7ZIP_BASE/C/Sha256.c
-
-SOURCES += \
-$$7ZIP_BASE/CPP/myWindows/myDateAndTime.cpp
+include(C/C.pri)
+include(CPP/7zip/7zip.pri)
+include(CPP/7zip/Archive/7z/7z.pri)
+include(CPP/7zip/Archive/Archive.pri)
+include(CPP/7zip/Archive/Common/Common.pri)
+include(CPP/7zip/Common/Common.pri)
+include(CPP/7zip/Compress/Compress.pri)
+include(CPP/7zip/UI/Common/Common.pri)
+include(CPP/7zip/UI/Console/Console.pri)
+include(CPP/Common/Common.pri)
+include(CPP/include_windows/include_windows.pri)
+include(CPP/myWindows/myWindows.pri)
+include(CPP/Windows/Windows.pri)