summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libs/7zip/7zip.pri12
-rw-r--r--src/libs/7zip/7zip.pro14
-rw-r--r--src/libs/7zip/patches/0001-Adjust-7z-and-p7z.patch517
-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/win/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.h20
-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.cpp (renamed from src/libs/7zip/win/CPP/Windows/Time.cpp)63
-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.cpp176
-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
-rw-r--r--src/libs/7zip/win/7zC.txt194
-rw-r--r--src/libs/7zip/win/7zFormat.txt471
-rw-r--r--src/libs/7zip/win/C/7z.h203
-rw-r--r--src/libs/7zip/win/C/7zAlloc.c76
-rw-r--r--src/libs/7zip/win/C/7zAlloc.h15
-rw-r--r--src/libs/7zip/win/C/7zBuf.c36
-rw-r--r--src/libs/7zip/win/C/7zBuf.h39
-rw-r--r--src/libs/7zip/win/C/7zBuf2.c45
-rw-r--r--src/libs/7zip/win/C/7zCrc.c69
-rw-r--r--src/libs/7zip/win/C/7zCrc.h4
-rw-r--r--src/libs/7zip/win/C/7zCrcOpt.c40
-rw-r--r--src/libs/7zip/win/C/7zDec.c470
-rw-r--r--src/libs/7zip/win/C/7zFile.c284
-rw-r--r--src/libs/7zip/win/C/7zFile.h83
-rw-r--r--src/libs/7zip/win/C/7zIn.c1402
-rw-r--r--src/libs/7zip/win/C/7zStream.c6
-rw-r--r--src/libs/7zip/win/C/7zTypes.h (renamed from src/libs/7zip/unix/C/Types.h)14
-rw-r--r--src/libs/7zip/win/C/7zVersion.h11
-rw-r--r--src/libs/7zip/win/C/Alloc.c10
-rw-r--r--src/libs/7zip/win/C/Bcj2.c132
-rw-r--r--src/libs/7zip/win/C/Bcj2.h38
-rw-r--r--src/libs/7zip/win/C/Bra.c12
-rw-r--r--src/libs/7zip/win/C/Bra.h20
-rw-r--r--src/libs/7zip/win/C/Bra86.c99
-rw-r--r--src/libs/7zip/win/C/BraIA64.c14
-rw-r--r--src/libs/7zip/win/C/C.pri48
-rw-r--r--src/libs/7zip/win/C/Compiler.h28
-rw-r--r--src/libs/7zip/win/C/CpuArch.c28
-rw-r--r--src/libs/7zip/win/C/CpuArch.h16
-rw-r--r--src/libs/7zip/win/C/Delta.c2
-rw-r--r--src/libs/7zip/win/C/Delta.h12
-rw-r--r--src/libs/7zip/win/C/LzFind.c6
-rw-r--r--src/libs/7zip/win/C/LzFind.h12
-rw-r--r--src/libs/7zip/win/C/LzFindMt.c33
-rw-r--r--src/libs/7zip/win/C/LzFindMt.h14
-rw-r--r--src/libs/7zip/win/C/Lzma2Dec.c42
-rw-r--r--src/libs/7zip/win/C/Lzma2Dec.h10
-rw-r--r--src/libs/7zip/win/C/Lzma2Enc.c40
-rw-r--r--src/libs/7zip/win/C/Lzma2Enc.h10
-rw-r--r--src/libs/7zip/win/C/Lzma86.h111
-rw-r--r--src/libs/7zip/win/C/Lzma86Dec.c56
-rw-r--r--src/libs/7zip/win/C/Lzma86Enc.c108
-rw-r--r--src/libs/7zip/win/C/LzmaDec.c78
-rw-r--r--src/libs/7zip/win/C/LzmaDec.h16
-rw-r--r--src/libs/7zip/win/C/LzmaEnc.c80
-rw-r--r--src/libs/7zip/win/C/LzmaEnc.h14
-rw-r--r--src/libs/7zip/win/C/LzmaLib.c46
-rw-r--r--src/libs/7zip/win/C/LzmaLib.h135
-rw-r--r--src/libs/7zip/win/C/MtCoder.c6
-rw-r--r--src/libs/7zip/win/C/MtCoder.h4
-rw-r--r--src/libs/7zip/win/C/Precomp.h10
-rw-r--r--src/libs/7zip/win/C/RotateDefs.h8
-rw-r--r--src/libs/7zip/win/C/Sha256.c4
-rw-r--r--src/libs/7zip/win/C/Sha256.h4
-rw-r--r--src/libs/7zip/win/C/Threads.c27
-rw-r--r--src/libs/7zip/win/C/Threads.h26
-rw-r--r--src/libs/7zip/win/C/Xz.c2
-rw-r--r--src/libs/7zip/win/C/Xz.h47
-rw-r--r--src/libs/7zip/win/C/XzCrc64.c89
-rw-r--r--src/libs/7zip/win/C/XzCrc64.h4
-rw-r--r--src/libs/7zip/win/C/XzCrc64Opt.c69
-rw-r--r--src/libs/7zip/win/C/XzDec.c108
-rw-r--r--src/libs/7zip/win/C/XzEnc.c309
-rw-r--r--src/libs/7zip/win/C/XzEnc.h32
-rw-r--r--src/libs/7zip/win/C/XzIn.c55
-rw-r--r--src/libs/7zip/win/CPP/7zip/7zip.pri6
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7z.pri30
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.cpp3
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.h9
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.cpp153
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.h13
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.cpp136
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.h2
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zExtract.cpp58
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.cpp4
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.h2
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.cpp2
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.h6
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.cpp717
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.h84
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandlerOut.cpp708
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.cpp5
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.h14
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.cpp1459
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.h359
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zItem.h214
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.cpp481
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.h211
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zProperties.cpp56
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zRegister.cpp23
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zSpecStream.cpp10
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.cpp708
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.h44
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.cpp3
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.h3
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Archive.def6
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Archive.pri6
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Archive2.def9
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/ArchiveExports.cpp135
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.cpp74
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.h19
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2MT.cpp60
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2MT.h15
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/Common.pri19
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/CrossThreadProgress.cpp15
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/CrossThreadProgress.h37
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/DummyOutStream.cpp19
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/DummyOutStream.h7
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/HandlerOut.cpp618
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/HandlerOut.h80
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/InStreamWithCRC.cpp32
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/ItemNameUtils.cpp41
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/ItemNameUtils.h7
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/MultiStream.cpp57
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/MultiStream.h13
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/OutStreamWithCRC.h1
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/ParseProperties.cpp177
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/ParseProperties.h16
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Common/StdAfx.h3
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/DllExports2.cpp74
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/IArchive.h336
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/LzmaHandler.cpp348
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/SplitHandler.cpp267
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/StdAfx.h3
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/XzHandler.cpp752
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/CWrappers.cpp44
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/CWrappers.h37
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/Common.pri40
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/CreateCoder.cpp218
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/CreateCoder.h41
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/FilePathAutoRename.cpp28
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/FilePathAutoRename.h10
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/FileStreams.cpp231
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/FileStreams.h76
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/FilterCoder.cpp24
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/FilterCoder.h22
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/InBuffer.cpp122
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/InBuffer.h101
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/InOutTempBuffer.cpp15
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/InOutTempBuffer.h4
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/LimitedStreams.cpp255
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/LimitedStreams.h142
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/MethodId.cpp27
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/MethodId.h2
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/MethodProps.cpp484
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/MethodProps.h178
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/OffsetStream.cpp35
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/OffsetStream.h25
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/OutBuffer.cpp57
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/OutBuffer.h37
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/ProgressUtils.cpp2
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/PropId.cpp99
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/RegisterArc.h67
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/RegisterCodec.h48
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/StdAfx.h3
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/StreamBinder.cpp148
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/StreamBinder.h36
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/StreamObjects.cpp75
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/StreamObjects.h31
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/StreamUtils.cpp8
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/StreamUtils.h12
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/UniqBlocks.cpp56
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/UniqBlocks.h30
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/VirtThread.cpp14
-rw-r--r--src/libs/7zip/win/CPP/7zip/Common/VirtThread.h11
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/Bcj2Coder.cpp176
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/Bcj2Coder.h55
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/BranchMisc.cpp42
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/CodecExports.cpp160
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/Compress.pri30
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/CopyCoder.cpp21
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/CopyCoder.h1
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/DeltaFilter.cpp17
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/Lzma2Decoder.cpp4
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/Lzma2Encoder.cpp2
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/Lzma2Encoder.h2
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/LzmaDecoder.cpp18
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/LzmaDecoder.h8
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/LzmaEncoder.cpp34
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/LzmaEncoder.h4
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/RangeCoder.h30
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/RangeCoderBit.h16
-rw-r--r--src/libs/7zip/win/CPP/7zip/Compress/StdAfx.h2
-rw-r--r--src/libs/7zip/win/CPP/7zip/Guid.txt38
-rw-r--r--src/libs/7zip/win/CPP/7zip/ICoder.h29
-rw-r--r--src/libs/7zip/win/CPP/7zip/IPassword.h3
-rw-r--r--src/libs/7zip/win/CPP/7zip/IProgress.h2
-rw-r--r--src/libs/7zip/win/CPP/7zip/IStream.h89
-rw-r--r--src/libs/7zip/win/CPP/7zip/MyVersion.h8
-rw-r--r--src/libs/7zip/win/CPP/7zip/PropID.h66
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveCommandLine.cpp1139
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveCommandLine.h79
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp999
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveExtractCallback.h208
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveName.cpp54
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveName.h10
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp42
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveOpenCallback.h36
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/Bench.cpp1028
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/Bench.h42
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/Common.pri44
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/DefaultName.cpp6
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/DefaultName.h6
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/DirItem.h91
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/EnumDirItems.cpp676
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/EnumDirItems.h18
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ExitCode.h27
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/Extract.cpp368
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/Extract.h54
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ExtractMode.h42
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ExtractingFilePath.cpp114
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ExtractingFilePath.h12
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/HashCalc.cpp361
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/HashCalc.h107
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/IFileExtractCallback.h32
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/LoadCodecs.cpp769
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/LoadCodecs.h190
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/OpenArchive.cpp3169
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/OpenArchive.h351
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/PropIDUtils.cpp547
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/PropIDUtils.h13
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/Property.h6
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/SetProperties.cpp31
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/SortUtils.cpp17
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/SortUtils.h8
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/StdAfx.h5
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/TempFiles.cpp9
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/TempFiles.h8
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/Update.cpp1111
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/Update.h147
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/UpdateAction.cpp10
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/UpdateAction.h29
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/UpdateCallback.cpp453
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/UpdateCallback.h64
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.cpp207
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.h4
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/UpdateProduce.cpp27
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/UpdateProduce.h26
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/WorkDir.cpp59
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/WorkDir.h10
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/ZipRegistry.h105
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/BenchCon.cpp297
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/BenchCon.h16
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/Console.pri4
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/ConsoleClose.cpp73
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/ConsoleClose.h24
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp228
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/ExtractCallbackConsole.h73
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/List.cpp654
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/List.h20
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/Main.cpp598
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/MainAr.cpp125
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/OpenCallbackConsole.cpp58
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/OpenCallbackConsole.h24
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/PercentPrinter.cpp40
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/PercentPrinter.h11
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/StdAfx.cpp3
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/StdAfx.h3
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp261
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/UpdateCallbackConsole.h62
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/UserInputUtils.cpp87
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Console/UserInputUtils.h24
-rw-r--r--src/libs/7zip/win/CPP/Common/AutoPtr.h35
-rw-r--r--src/libs/7zip/win/CPP/Common/Buffer.h77
-rw-r--r--src/libs/7zip/win/CPP/Common/CRC.cpp7
-rw-r--r--src/libs/7zip/win/CPP/Common/C_FileIO.cpp88
-rw-r--r--src/libs/7zip/win/CPP/Common/C_FileIO.h47
-rw-r--r--src/libs/7zip/win/CPP/Common/ComTry.h2
-rw-r--r--src/libs/7zip/win/CPP/Common/CommandLineParser.cpp265
-rw-r--r--src/libs/7zip/win/CPP/Common/CommandLineParser.h51
-rw-r--r--src/libs/7zip/win/CPP/Common/Common.h13
-rw-r--r--src/libs/7zip/win/CPP/Common/Common.pri35
-rw-r--r--src/libs/7zip/win/CPP/Common/DynamicBuffer.h50
-rw-r--r--src/libs/7zip/win/CPP/Common/IntToString.cpp149
-rw-r--r--src/libs/7zip/win/CPP/Common/IntToString.h23
-rw-r--r--src/libs/7zip/win/CPP/Common/ListFileUtils.cpp120
-rw-r--r--src/libs/7zip/win/CPP/Common/ListFileUtils.h11
-rw-r--r--src/libs/7zip/win/CPP/Common/MyBuffer.h237
-rw-r--r--src/libs/7zip/win/CPP/Common/MyCom.h63
-rw-r--r--src/libs/7zip/win/CPP/Common/MyGuidDef.h2
-rw-r--r--src/libs/7zip/win/CPP/Common/MyInitGuid.h23
-rw-r--r--src/libs/7zip/win/CPP/Common/MyString.cpp1175
-rw-r--r--src/libs/7zip/win/CPP/Common/MyString.h922
-rw-r--r--src/libs/7zip/win/CPP/Common/MyTypes.h30
-rw-r--r--src/libs/7zip/win/CPP/Common/MyUnknown.h2
-rw-r--r--src/libs/7zip/win/CPP/Common/MyVector.cpp87
-rw-r--r--src/libs/7zip/win/CPP/Common/MyVector.h577
-rw-r--r--src/libs/7zip/win/CPP/Common/MyWindows.cpp145
-rw-r--r--src/libs/7zip/win/CPP/Common/MyWindows.h30
-rw-r--r--src/libs/7zip/win/CPP/Common/NewHandler.cpp66
-rw-r--r--src/libs/7zip/win/CPP/Common/NewHandler.h56
-rw-r--r--src/libs/7zip/win/CPP/Common/StdAfx.h3
-rw-r--r--src/libs/7zip/win/CPP/Common/StdInStream.cpp107
-rw-r--r--src/libs/7zip/win/CPP/Common/StdInStream.h32
-rw-r--r--src/libs/7zip/win/CPP/Common/StdOutStream.cpp86
-rw-r--r--src/libs/7zip/win/CPP/Common/StdOutStream.h61
-rw-r--r--src/libs/7zip/win/CPP/Common/StringConvert.cpp90
-rw-r--r--src/libs/7zip/win/CPP/Common/StringConvert.h10
-rw-r--r--src/libs/7zip/win/CPP/Common/StringToInt.cpp144
-rw-r--r--src/libs/7zip/win/CPP/Common/StringToInt.h23
-rw-r--r--src/libs/7zip/win/CPP/Common/Types.h11
-rw-r--r--src/libs/7zip/win/CPP/Common/UTFConvert.cpp61
-rw-r--r--src/libs/7zip/win/CPP/Common/UTFConvert.h5
-rw-r--r--src/libs/7zip/win/CPP/Common/Wildcard.cpp391
-rw-r--r--src/libs/7zip/win/CPP/Common/Wildcard.h101
-rw-r--r--src/libs/7zip/win/CPP/Windows/DLL.cpp130
-rw-r--r--src/libs/7zip/win/CPP/Windows/DLL.h25
-rw-r--r--src/libs/7zip/win/CPP/Windows/Error.cpp50
-rw-r--r--src/libs/7zip/win/CPP/Windows/Error.h33
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileDir.cpp1050
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileDir.h180
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileFind.cpp605
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileFind.h127
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileIO.cpp430
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileIO.h217
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileLink.cpp426
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileMapping.cpp12
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileMapping.h8
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileName.cpp675
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileName.h69
-rw-r--r--src/libs/7zip/win/CPP/Windows/MemoryLock.cpp82
-rw-r--r--src/libs/7zip/win/CPP/Windows/MemoryLock.h15
-rw-r--r--src/libs/7zip/win/CPP/Windows/NtCheck.h44
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariant.cpp105
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariant.h97
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariantConv.cpp99
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariantConv.h30
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariantConversions.cpp105
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariantConversions.h14
-rw-r--r--src/libs/7zip/win/CPP/Windows/Registry.cpp369
-rw-r--r--src/libs/7zip/win/CPP/Windows/Registry.h85
-rw-r--r--src/libs/7zip/win/CPP/Windows/SecurityUtils.cpp179
-rw-r--r--src/libs/7zip/win/CPP/Windows/SecurityUtils.h167
-rw-r--r--src/libs/7zip/win/CPP/Windows/StdAfx.h3
-rw-r--r--src/libs/7zip/win/CPP/Windows/System.h2
-rw-r--r--src/libs/7zip/win/CPP/Windows/Thread.h2
-rw-r--r--src/libs/7zip/win/CPP/Windows/Time.h21
-rw-r--r--src/libs/7zip/win/CPP/Windows/TimeUtils.cpp203
-rw-r--r--src/libs/7zip/win/CPP/Windows/TimeUtils.h23
-rw-r--r--src/libs/7zip/win/CPP/Windows/Windows.pri29
-rw-r--r--src/libs/7zip/win/Methods.txt152
-rw-r--r--src/libs/7zip/win/history.txt271
-rw-r--r--src/libs/7zip/win/lzma.txt598
-rw-r--r--src/libs/7zip/win/win.pri142
-rw-r--r--src/libs/installer/adminauthorization_win.cpp6
-rw-r--r--src/libs/installer/adminauthorization_x11.cpp17
-rw-r--r--src/libs/installer/binarycontent.cpp10
-rw-r--r--src/libs/installer/binaryformat.cpp4
-rw-r--r--src/libs/installer/component.cpp51
-rw-r--r--src/libs/installer/component.h7
-rw-r--r--src/libs/installer/componentchecker.cpp12
-rw-r--r--src/libs/installer/componentmodel.cpp10
-rw-r--r--src/libs/installer/constants.h9
-rw-r--r--src/libs/installer/consumeoutputoperation.cpp31
-rw-r--r--src/libs/installer/consumeoutputoperation.h3
-rw-r--r--src/libs/installer/copydirectoryoperation.cpp48
-rw-r--r--src/libs/installer/copydirectoryoperation.h3
-rw-r--r--src/libs/installer/copyfiletask.cpp13
-rw-r--r--src/libs/installer/createdesktopentryoperation.cpp29
-rw-r--r--src/libs/installer/createdesktopentryoperation.h3
-rw-r--r--src/libs/installer/createlinkoperation.cpp24
-rw-r--r--src/libs/installer/createlinkoperation.h3
-rw-r--r--src/libs/installer/createlocalrepositoryoperation.cpp70
-rw-r--r--src/libs/installer/createlocalrepositoryoperation.h3
-rw-r--r--src/libs/installer/createshortcutoperation.cpp125
-rw-r--r--src/libs/installer/createshortcutoperation.h12
-rw-r--r--src/libs/installer/downloadarchivesjob.cpp36
-rw-r--r--src/libs/installer/downloadarchivesjob.h4
-rw-r--r--src/libs/installer/downloadfiletask.cpp78
-rw-r--r--src/libs/installer/downloadfiletask.h2
-rw-r--r--src/libs/installer/downloadfiletask_p.h4
-rw-r--r--src/libs/installer/elevatedexecuteoperation.cpp34
-rw-r--r--src/libs/installer/elevatedexecuteoperation.h13
-rw-r--r--src/libs/installer/environmentvariablesoperation.cpp32
-rw-r--r--src/libs/installer/environmentvariablesoperation.h3
-rw-r--r--src/libs/installer/errors.h12
-rw-r--r--src/libs/installer/extractarchiveoperation.cpp74
-rw-r--r--src/libs/installer/extractarchiveoperation.h3
-rw-r--r--src/libs/installer/extractarchiveoperation_p.h144
-rw-r--r--src/libs/installer/fakestopprocessforupdateoperation.cpp17
-rw-r--r--src/libs/installer/fakestopprocessforupdateoperation.h3
-rw-r--r--src/libs/installer/fileio.cpp12
-rw-r--r--src/libs/installer/fileutils.cpp67
-rw-r--r--src/libs/installer/fileutils.h2
-rw-r--r--src/libs/installer/globalsettingsoperation.cpp20
-rw-r--r--src/libs/installer/globalsettingsoperation.h3
-rw-r--r--src/libs/installer/init.cpp64
-rw-r--r--src/libs/installer/installer.pro10
-rw-r--r--src/libs/installer/installercalculator.cpp14
-rw-r--r--src/libs/installer/installiconsoperation.cpp48
-rw-r--r--src/libs/installer/installiconsoperation.h3
-rw-r--r--src/libs/installer/lib7z_create.h82
-rw-r--r--src/libs/installer/lib7z_extract.h85
-rw-r--r--src/libs/installer/lib7z_facade.cpp1856
-rw-r--r--src/libs/installer/lib7z_facade.h261
-rw-r--r--src/libs/installer/lib7z_guid.h97
-rw-r--r--src/libs/installer/lib7z_list.h62
-rw-r--r--src/libs/installer/licenseoperation.cpp23
-rw-r--r--src/libs/installer/licenseoperation.h3
-rw-r--r--src/libs/installer/linereplaceoperation.cpp24
-rw-r--r--src/libs/installer/linereplaceoperation.h3
-rw-r--r--src/libs/installer/link.cpp26
-rw-r--r--src/libs/installer/messageboxhandler.cpp4
-rw-r--r--src/libs/installer/metadatajob.cpp52
-rw-r--r--src/libs/installer/metadatajob.h4
-rw-r--r--src/libs/installer/metadatajob_p.h12
-rw-r--r--src/libs/installer/minimumprogressoperation.cpp9
-rw-r--r--src/libs/installer/minimumprogressoperation.h3
-rw-r--r--src/libs/installer/packagemanagercore.cpp135
-rw-r--r--src/libs/installer/packagemanagercore.h6
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp316
-rw-r--r--src/libs/installer/packagemanagercore_p.h38
-rw-r--r--src/libs/installer/packagemanagercoredata.cpp82
-rw-r--r--src/libs/installer/packagemanagercoredata.h3
-rw-r--r--src/libs/installer/packagemanagergui.cpp280
-rw-r--r--src/libs/installer/packagemanagergui.h5
-rw-r--r--src/libs/installer/packagemanagerpagefactory.cpp5
-rw-r--r--src/libs/installer/packagemanagerpagefactory.h13
-rw-r--r--src/libs/installer/packagemanagerproxyfactory.cpp2
-rw-r--r--src/libs/installer/packagemanagerproxyfactory.h2
-rw-r--r--src/libs/installer/packagesource.cpp91
-rw-r--r--src/libs/installer/packagesource.h63
-rw-r--r--src/libs/installer/performinstallationform.cpp11
-rw-r--r--src/libs/installer/progresscoordinator.cpp2
-rw-r--r--src/libs/installer/proxycredentialsdialog.h2
-rw-r--r--src/libs/installer/qinstallerglobal.h9
-rw-r--r--src/libs/installer/qprocesswrapper.cpp24
-rw-r--r--src/libs/installer/qprocesswrapper.h1
-rw-r--r--src/libs/installer/qtpatch.cpp14
-rw-r--r--src/libs/installer/registerfiletypeoperation.cpp23
-rw-r--r--src/libs/installer/registerfiletypeoperation.h3
-rw-r--r--src/libs/installer/remoteclient.cpp13
-rw-r--r--src/libs/installer/remoteclient.h2
-rw-r--r--src/libs/installer/remoteclient_p.h8
-rw-r--r--src/libs/installer/remoteobject.h2
-rw-r--r--src/libs/installer/remoteserver.cpp8
-rw-r--r--src/libs/installer/remoteserver_p.h6
-rw-r--r--src/libs/installer/remoteserverconnection_p.h24
-rw-r--r--src/libs/installer/replaceoperation.cpp24
-rw-r--r--src/libs/installer/replaceoperation.h3
-rw-r--r--src/libs/installer/repository.cpp2
-rw-r--r--src/libs/installer/resources/install.pngbin0 -> 268 bytes
-rw-r--r--src/libs/installer/resources/installer.qrc4
-rw-r--r--src/libs/installer/resources/keepinstalled.pngbin0 -> 239 bytes
-rw-r--r--src/libs/installer/resources/keepuninstalled.pngbin0 -> 203 bytes
-rw-r--r--src/libs/installer/resources/uninstall.pngbin0 -> 240 bytes
-rw-r--r--src/libs/installer/scriptengine.cpp20
-rw-r--r--src/libs/installer/scriptengine_p.h4
-rw-r--r--src/libs/installer/selfrestartoperation.cpp24
-rw-r--r--src/libs/installer/selfrestartoperation.h3
-rw-r--r--src/libs/installer/settings.cpp48
-rw-r--r--src/libs/installer/settings.h2
-rw-r--r--src/libs/installer/settingsoperation.cpp19
-rw-r--r--src/libs/installer/settingsoperation.h3
-rw-r--r--src/libs/installer/simplemovefileoperation.cpp36
-rw-r--r--src/libs/installer/simplemovefileoperation.h3
-rw-r--r--src/libs/installer/sysinfo_win.cpp2
-rw-r--r--src/libs/installer/testrepository.cpp164
-rw-r--r--src/libs/installer/testrepository.h52
-rw-r--r--src/libs/installer/unziptask.cpp50
-rw-r--r--src/libs/kdtools/environment.h6
-rw-r--r--src/libs/kdtools/filedownloader.cpp (renamed from src/libs/kdtools/kdupdaterfiledownloader.cpp)48
-rw-r--r--src/libs/kdtools/filedownloader.h (renamed from src/libs/kdtools/kdupdaterfiledownloader.h)10
-rw-r--r--src/libs/kdtools/filedownloader_p.h (renamed from src/libs/kdtools/kdupdaterfiledownloader_p.h)8
-rw-r--r--src/libs/kdtools/filedownloaderfactory.cpp (renamed from src/libs/kdtools/kdupdaterfiledownloaderfactory.cpp)11
-rw-r--r--src/libs/kdtools/filedownloaderfactory.h (renamed from src/libs/kdtools/kdupdaterfiledownloaderfactory.h)13
-rw-r--r--src/libs/kdtools/genericfactory.cpp128
-rw-r--r--src/libs/kdtools/genericfactory.h91
-rw-r--r--src/libs/kdtools/job.cpp (renamed from src/libs/kdtools/kdjob.cpp)84
-rw-r--r--src/libs/kdtools/job.h (renamed from src/libs/kdtools/kdjob.h)22
-rw-r--r--src/libs/kdtools/kdgenericfactory.cpp180
-rw-r--r--src/libs/kdtools/kdgenericfactory.h105
-rw-r--r--src/libs/kdtools/kdsysinfo_win.cpp2
-rw-r--r--src/libs/kdtools/kdtools.pri95
-rw-r--r--src/libs/kdtools/kdtoolsglobal.h6
-rw-r--r--src/libs/kdtools/kdupdaterapplication.cpp311
-rw-r--r--src/libs/kdtools/kdupdaterapplication.h105
-rw-r--r--src/libs/kdtools/kdupdaterupdatesourcesinfo.cpp480
-rw-r--r--src/libs/kdtools/kdupdaterupdatesourcesinfo.h117
-rw-r--r--src/libs/kdtools/localpackagehub.cpp (renamed from src/libs/kdtools/kdupdaterpackagesinfo.cpp)301
-rw-r--r--src/libs/kdtools/localpackagehub.h (renamed from src/libs/kdtools/kdupdaterpackagesinfo.h)72
-rw-r--r--src/libs/kdtools/lockfile.cpp (renamed from src/libs/kdtools/kdlockfile.cpp)18
-rw-r--r--src/libs/kdtools/lockfile.h (renamed from src/libs/kdtools/kdlockfile.h)20
-rw-r--r--src/libs/kdtools/lockfile_p.h (renamed from src/libs/kdtools/kdlockfile_p.h)14
-rw-r--r--src/libs/kdtools/lockfile_unix.cpp (renamed from src/libs/kdtools/kdlockfile_unix.cpp)27
-rw-r--r--src/libs/kdtools/lockfile_win.cpp (renamed from src/libs/kdtools/kdlockfile_win.cpp)33
-rw-r--r--src/libs/kdtools/runoncechecker.cpp (renamed from src/libs/kdtools/kdrunoncechecker.cpp)16
-rw-r--r--src/libs/kdtools/runoncechecker.h (renamed from src/libs/kdtools/kdrunoncechecker.h)20
-rw-r--r--src/libs/kdtools/selfrestarter.cpp (renamed from src/libs/kdtools/kdselfrestarter.cpp)22
-rw-r--r--src/libs/kdtools/selfrestarter.h (renamed from src/libs/kdtools/kdselfrestarter.h)14
-rw-r--r--src/libs/kdtools/sysinfo.cpp (renamed from src/libs/kdtools/kdsysinfo.cpp)2
-rw-r--r--src/libs/kdtools/sysinfo.h (renamed from src/libs/kdtools/kdsysinfo.h)8
-rw-r--r--src/libs/kdtools/sysinfo_mac.cpp (renamed from src/libs/kdtools/kdsysinfo_mac.cpp)2
-rw-r--r--src/libs/kdtools/sysinfo_x11.cpp (renamed from src/libs/kdtools/kdsysinfo_x11.cpp)4
-rw-r--r--src/libs/kdtools/task.cpp (renamed from src/libs/kdtools/kdupdatertask.cpp)2
-rw-r--r--src/libs/kdtools/task.h (renamed from src/libs/kdtools/kdupdatertask.h)8
-rw-r--r--src/libs/kdtools/update.cpp (renamed from src/libs/kdtools/kdupdaterupdate.cpp)28
-rw-r--r--src/libs/kdtools/update.h (renamed from src/libs/kdtools/kdupdaterupdate.h)20
-rw-r--r--src/libs/kdtools/updatefinder.cpp (renamed from src/libs/kdtools/kdupdaterupdatefinder.cpp)138
-rw-r--r--src/libs/kdtools/updatefinder.h (renamed from src/libs/kdtools/kdupdaterupdatefinder.h)19
-rw-r--r--src/libs/kdtools/updateoperation.cpp (renamed from src/libs/kdtools/kdupdaterupdateoperation.cpp)124
-rw-r--r--src/libs/kdtools/updateoperation.h (renamed from src/libs/kdtools/kdupdaterupdateoperation.h)20
-rw-r--r--src/libs/kdtools/updateoperationfactory.cpp (renamed from src/libs/kdtools/kdupdaterupdateoperationfactory.cpp)9
-rw-r--r--src/libs/kdtools/updateoperationfactory.h (renamed from src/libs/kdtools/kdupdaterupdateoperationfactory.h)19
-rw-r--r--src/libs/kdtools/updateoperations.cpp (renamed from src/libs/kdtools/kdupdaterupdateoperations.cpp)214
-rw-r--r--src/libs/kdtools/updateoperations.h (renamed from src/libs/kdtools/kdupdaterupdateoperations.h)29
-rw-r--r--src/libs/kdtools/updater.h (renamed from src/libs/kdtools/kdupdater.h)6
-rw-r--r--src/libs/kdtools/updatesinfo.cpp (renamed from src/libs/kdtools/kdupdaterupdatesinfo.cpp)18
-rw-r--r--src/libs/kdtools/updatesinfo_p.h (renamed from src/libs/kdtools/kdupdaterupdatesinfo_p.h)10
-rw-r--r--src/libs/kdtools/updatesinfodata_p.h (renamed from src/libs/kdtools/kdupdaterupdatesinfodata_p.h)12
-rw-r--r--src/libs/libs.pro2
-rw-r--r--src/sdk/installerbase.cpp16
-rw-r--r--src/sdk/installerbase.qrc2
-rw-r--r--src/sdk/installerbasecommons.cpp28
-rw-r--r--src/sdk/installerbasecommons.h3
-rw-r--r--src/sdk/main.cpp12
-rw-r--r--src/sdk/sdk.pro4
-rw-r--r--src/sdk/settingsdialog.cpp67
-rw-r--r--src/sdk/settingsdialog.h2
-rw-r--r--src/sdk/tabcontroller.cpp15
-rw-r--r--src/sdk/translations/de.ts242
-rw-r--r--src/sdk/translations/en.ts250
-rw-r--r--src/sdk/translations/es.ts2688
-rw-r--r--src/sdk/translations/fr.ts242
-rw-r--r--src/sdk/translations/it.ts242
-rw-r--r--src/sdk/translations/ja.ts244
-rw-r--r--src/sdk/translations/pl.ts242
-rw-r--r--src/sdk/translations/ru.ts244
-rw-r--r--src/sdk/translations/zh_cn.ts242
-rw-r--r--src/sdk/updatechecker.cpp10
-rw-r--r--src/src.pro4
861 files changed, 56396 insertions, 44678 deletions
diff --git a/src/libs/7zip/7zip.pri b/src/libs/7zip/7zip.pri
index 823e3ab1d..26c052fc7 100644
--- a/src/libs/7zip/7zip.pri
+++ b/src/libs/7zip/7zip.pri
@@ -1,7 +1,10 @@
+DEFINES += _UNICODE _NO_CRYPTO
+
win32 {
7ZIP_BASE=$$PWD/win
INCLUDEPATH += $$7ZIP_BASE/C $$7ZIP_BASE/CPP
- DEFINES += WIN_LONG_PATH _UNICODE _NO_CRYPTO
+ DEFINES += WIN_LONG_PATH _CRT_SECURE_NO_WARNINGS
+
QMAKE_CXXFLAGS_RELEASE -= -Zc:strictStrings
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO -= -Zc:strictStrings
}
@@ -15,5 +18,10 @@ unix {
$$7ZIP_BASE/CPP/include_windows
macx:DEFINES += ENV_MACOSX
- DEFINES += _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE NDEBUG _REENTRANT ENV_UNIX UNICODE _UNICODE _NO_CRYPTO
+ DEFINES += _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE NDEBUG _REENTRANT ENV_UNIX UNICODE
+}
+
+unix|win32-g++* {
+ QMAKE_CFLAGS += -w
+ QMAKE_CXXFLAGS += -w
}
diff --git a/src/libs/7zip/7zip.pro b/src/libs/7zip/7zip.pro
index 01b69dad2..70a51c068 100644
--- a/src/libs/7zip/7zip.pro
+++ b/src/libs/7zip/7zip.pro
@@ -7,15 +7,5 @@ CONFIG += staticlib
DESTDIR = $$IFW_LIB_PATH
include(7zip.pri)
-win32 {
- DEFINES += _CRT_SECURE_NO_WARNINGS
- win32-g++*:QMAKE_CXXFLAGS += -w -fvisibility=hidden
- CONFIG += no_batch # this is needed because we have a same named *.c and *.cpp file -> 7in
- include($$7ZIP_BASE/win.pri) #this is 7zip
-}
-
-unix {
- QMAKE_CFLAGS += -w
- QMAKE_CXXFLAGS += -fvisibility=hidden -w
- include($$7ZIP_BASE/unix.pri) #this is p7zip
-}
+win32:include($$7ZIP_BASE/win.pri) #7zip
+unix:include($$7ZIP_BASE/unix.pri) #p7zip
diff --git a/src/libs/7zip/patches/0001-Adjust-7z-and-p7z.patch b/src/libs/7zip/patches/0001-Adjust-7z-and-p7z.patch
new file mode 100644
index 000000000..822deb07f
--- /dev/null
+++ b/src/libs/7zip/patches/0001-Adjust-7z-and-p7z.patch
@@ -0,0 +1,517 @@
+From f643c01e4e8534f26a5a2d260caa566d23cdcb13 Mon Sep 17 00:00:00 2001
+From: Karsten Heimrich <karsten.heimrich@theqtcompany.com>
+Date: Thu, 4 Jun 2015 15:41:51 +0200
+Subject: [PATCH 1/1] Adjust 7z and p7z.
+
+Change-Id: I3b96d2b02e5a0908fb4cf5b4262cb33516a10098
+---
+ src/libs/7zip/7zip.pri | 11 ++++-
+ src/libs/7zip/7zip.pro | 14 +-----
+ src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.cpp | 2 -
+ src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h | 32 ++++++++++---
+ src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h | 29 ++++++++---
+ src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.cpp | 2 -
+ .../unix/CPP/include_windows/include_windows.pri | 3 ++
+ .../unix/CPP/myWindows/myCommandLineParser.cpp | 56 ++++++++++++++++++++++
+ src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp | 42 ++++++++--------
+ src/libs/7zip/unix/CPP/myWindows/myWindows.pri | 7 +++
+ src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.cpp | 2 -
+ src/libs/7zip/win/CPP/7zip/Common/RegisterArc.h | 32 ++++++++++---
+ src/libs/7zip/win/CPP/7zip/Common/RegisterCodec.h | 29 ++++++++---
+ src/libs/7zip/win/CPP/7zip/UI/Common/Extract.cpp | 2 -
+ 14 files changed, 194 insertions(+), 69 deletions(-)
+ create mode 100644 src/libs/7zip/unix/CPP/include_windows/include_windows.pri
+ create mode 100644 src/libs/7zip/unix/CPP/myWindows/myCommandLineParser.cpp
+ create mode 100644 src/libs/7zip/unix/CPP/myWindows/myWindows.pri
+
+diff --git a/src/libs/7zip/7zip.pri b/src/libs/7zip/7zip.pri
+index 823e3ab..85574ce 100644
+--- a/src/libs/7zip/7zip.pri
++++ b/src/libs/7zip/7zip.pri
+@@ -1,7 +1,11 @@
++DEFINES += _UNICODE _NO_CRYPTO
++
+ win32 {
+ 7ZIP_BASE=$$PWD/win
+ INCLUDEPATH += $$7ZIP_BASE/C $$7ZIP_BASE/CPP
+- DEFINES += WIN_LONG_PATH _UNICODE _NO_CRYPTO
++ DEFINES += WIN_LONG_PATH _CRT_SECURE_NO_WARNINGS
++ win32-g++*:QMAKE_CXXFLAGS += -w -fvisibility=hidden
++
+ QMAKE_CXXFLAGS_RELEASE -= -Zc:strictStrings
+ QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO -= -Zc:strictStrings
+ }
+@@ -14,6 +18,9 @@ unix {
+ $$7ZIP_BASE/CPP/myWindows \
+ $$7ZIP_BASE/CPP/include_windows
+
++ QMAKE_CFLAGS += -w
++ QMAKE_CXXFLAGS += -fvisibility=hidden -w
++
+ macx:DEFINES += ENV_MACOSX
+- DEFINES += _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE NDEBUG _REENTRANT ENV_UNIX UNICODE _UNICODE _NO_CRYPTO
++ DEFINES += _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE NDEBUG _REENTRANT ENV_UNIX UNICODE
+ }
+diff --git a/src/libs/7zip/7zip.pro b/src/libs/7zip/7zip.pro
+index 01b69da..70a51c0 100644
+--- a/src/libs/7zip/7zip.pro
++++ b/src/libs/7zip/7zip.pro
+@@ -7,15 +7,5 @@ CONFIG += staticlib
+ DESTDIR = $$IFW_LIB_PATH
+
+ include(7zip.pri)
+-win32 {
+- DEFINES += _CRT_SECURE_NO_WARNINGS
+- win32-g++*:QMAKE_CXXFLAGS += -w -fvisibility=hidden
+- CONFIG += no_batch # this is needed because we have a same named *.c and *.cpp file -> 7in
+- include($$7ZIP_BASE/win.pri) #this is 7zip
+-}
+-
+-unix {
+- QMAKE_CFLAGS += -w
+- QMAKE_CXXFLAGS += -fvisibility=hidden -w
+- include($$7ZIP_BASE/unix.pri) #this is p7zip
+-}
++win32:include($$7ZIP_BASE/win.pri) #7zip
++unix:include($$7ZIP_BASE/unix.pri) #p7zip
+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 8af28b9..e20858e 100644
+--- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.cpp
++++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zOut.cpp
+@@ -4,8 +4,6 @@
+
+ #include "../../../../C/7zCrc.h"
+
+-#include "../../../Common/AutoPtr.h"
+-
+ #include "../../Common/StreamObjects.h"
+
+ #include "7zOut.h"
+diff --git a/src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h b/src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h
+index 1e9bf14..82bd096 100644
+--- a/src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h
++++ b/src/libs/7zip/unix/CPP/7zip/Common/RegisterArc.h
+@@ -5,6 +5,8 @@
+
+ #include "../Archive/IArchive.h"
+
++#include <mutex>
++
+ struct CArcInfo
+ {
+ const char *Name;
+@@ -24,19 +26,35 @@ struct CArcInfo
+ Func_IsArc IsArc;
+
+ bool IsMultiSignature() const { return (Flags & NArcInfoFlags::kMultiSignature) != 0; }
++
++ std::once_flag once;
+ };
+
+ 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); }}; \
+- static REGISTER_ARC_NAME(x) g_RegisterArc;
+-
+-#define REGISTER_ARC_DEC_SIG(x) struct REGISTER_ARC_NAME(x) { \
+- REGISTER_ARC_NAME(x)() { g_ArcInfo.Signature[0]--; RegisterArc(&g_ArcInfo); }}; \
+- static REGISTER_ARC_NAME(x) g_RegisterArc;
++#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) \
+diff --git a/src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h b/src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h
+index 4222a30..0c6662a 100644
+--- a/src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h
++++ b/src/libs/7zip/unix/CPP/7zip/Common/RegisterCodec.h
+@@ -6,6 +6,8 @@
+ #include "../Common/MethodId.h"
+ #include "../ICoder.h"
+
++#include <mutex>
++
+ typedef void * (*CreateCodecP)();
+ struct CCodecInfo
+ {
+@@ -15,21 +17,34 @@ struct CCodecInfo
+ const wchar_t *Name;
+ UInt32 NumInStreams;
+ bool IsFilter;
++ std::once_flag once;
+ };
+
+ 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); }}; \
+- static REGISTER_CODEC_NAME(x) g_RegisterCodec;
++#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 (unsigned i = 0; i < ARRAY_SIZE(g_CodecsInfo); i++) \
+- RegisterCodec(&g_CodecsInfo[i]); }}; \
+- static REGISTER_CODECS_NAME(x) g_RegisterCodecs;
++#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
+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 03f31fa..5f94254 100644
+--- a/src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.cpp
++++ b/src/libs/7zip/unix/CPP/7zip/UI/Common/Extract.cpp
+@@ -2,8 +2,6 @@
+
+ #include "StdAfx.h"
+
+-#include "../../../../C/Sort.h"
+-
+ #include "../../../Common/StringConvert.h"
+
+ #include "../../../Windows/FileDir.h"
+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 0000000..5ef72fd
+--- /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/myWindows/myCommandLineParser.cpp b/src/libs/7zip/unix/CPP/myWindows/myCommandLineParser.cpp
+new file mode 100644
+index 0000000..5d7f6fd
+--- /dev/null
++++ b/src/libs/7zip/unix/CPP/myWindows/myCommandLineParser.cpp
+@@ -0,0 +1,56 @@
++/**************************************************************************
++**
++** 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 (QString arg, args) {
++ if (arg.startsWith(QLatin1Char('\"')))
++ arg = arg.mid(1);
++ if (arg.endsWith(QLatin1Char('\"')))
++ arg = arg.mid(1);
++ 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 96554c9..9ebfe37 100644
+--- a/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp
++++ b/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp
+@@ -32,19 +32,18 @@
+ **
+ **************************************************************************/
+
+-#include <QDebug>
+-#include <QDateTime>
+ #include "windows.h"
+
++#include <QDateTime>
++
+ 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 +59,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 +76,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 +128,16 @@ VOID WINAPI GetSystemTime(SYSTEMTIME *st)
+ QDateTime nowDateTime = QDateTime::currentDateTimeUtc();
+ DateTimeToSystemTime(&nowDateTime, st);
+ }
++
++VOID WINAPI GetSystemTimeAsFileTime(FILETIME *time)
++{
++ DateTimeToFileTime(QDateTime::currentDateTimeUtc(), time);
++}
++
++DWORD WINAPI GetTickCount()
++{
++ struct timespec ts;
++ if (clock_gettime(CLOCK_MONOTONIC, &ts))
++ return DWORD(ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
++ return DWORD(QDateTime::currentMSecsSinceEpoch());
++}
+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 0000000..0875fdb
+--- /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/win/CPP/7zip/Archive/7z/7zOut.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.cpp
+index 8af28b9..e20858e 100644
+--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.cpp
++++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.cpp
+@@ -4,8 +4,6 @@
+
+ #include "../../../../C/7zCrc.h"
+
+-#include "../../../Common/AutoPtr.h"
+-
+ #include "../../Common/StreamObjects.h"
+
+ #include "7zOut.h"
+diff --git a/src/libs/7zip/win/CPP/7zip/Common/RegisterArc.h b/src/libs/7zip/win/CPP/7zip/Common/RegisterArc.h
+index 1e9bf14..82bd096 100644
+--- a/src/libs/7zip/win/CPP/7zip/Common/RegisterArc.h
++++ b/src/libs/7zip/win/CPP/7zip/Common/RegisterArc.h
+@@ -5,6 +5,8 @@
+
+ #include "../Archive/IArchive.h"
+
++#include <mutex>
++
+ struct CArcInfo
+ {
+ const char *Name;
+@@ -24,19 +26,35 @@ struct CArcInfo
+ Func_IsArc IsArc;
+
+ bool IsMultiSignature() const { return (Flags & NArcInfoFlags::kMultiSignature) != 0; }
++
++ std::once_flag once;
+ };
+
+ 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); }}; \
+- static REGISTER_ARC_NAME(x) g_RegisterArc;
+-
+-#define REGISTER_ARC_DEC_SIG(x) struct REGISTER_ARC_NAME(x) { \
+- REGISTER_ARC_NAME(x)() { g_ArcInfo.Signature[0]--; RegisterArc(&g_ArcInfo); }}; \
+- static REGISTER_ARC_NAME(x) g_RegisterArc;
++#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) \
+diff --git a/src/libs/7zip/win/CPP/7zip/Common/RegisterCodec.h b/src/libs/7zip/win/CPP/7zip/Common/RegisterCodec.h
+index 4222a30..0c6662a 100644
+--- a/src/libs/7zip/win/CPP/7zip/Common/RegisterCodec.h
++++ b/src/libs/7zip/win/CPP/7zip/Common/RegisterCodec.h
+@@ -6,6 +6,8 @@
+ #include "../Common/MethodId.h"
+ #include "../ICoder.h"
+
++#include <mutex>
++
+ typedef void * (*CreateCodecP)();
+ struct CCodecInfo
+ {
+@@ -15,21 +17,34 @@ struct CCodecInfo
+ const wchar_t *Name;
+ UInt32 NumInStreams;
+ bool IsFilter;
++ std::once_flag once;
+ };
+
+ 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); }}; \
+- static REGISTER_CODEC_NAME(x) g_RegisterCodec;
++#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 (unsigned i = 0; i < ARRAY_SIZE(g_CodecsInfo); i++) \
+- RegisterCodec(&g_CodecsInfo[i]); }}; \
+- static REGISTER_CODECS_NAME(x) g_RegisterCodecs;
++#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
+diff --git a/src/libs/7zip/win/CPP/7zip/UI/Common/Extract.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/Extract.cpp
+index df86620..13d2ad2 100644
+--- a/src/libs/7zip/win/CPP/7zip/UI/Common/Extract.cpp
++++ b/src/libs/7zip/win/CPP/7zip/UI/Common/Extract.cpp
+@@ -2,8 +2,6 @@
+
+ #include "StdAfx.h"
+
+-#include "../../../../C/Sort.h"
+-
+ #include "../../../Common/StringConvert.h"
+
+ #include "../../../Windows/FileDir.h"
+--
+2.3.7.windows.1
+
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/win/C/Types.h b/src/libs/7zip/unix/C/7zTypes.h
index 7732c240c..778413ef4 100644
--- a/src/libs/7zip/win/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..83a896283 100644
--- a/src/libs/7zip/unix/CPP/Common/MyWindows.h
+++ b/src/libs/7zip/unix/CPP/Common/MyWindows.h
@@ -40,7 +40,17 @@ typedef UINT32 DWORD;
typedef Int64 LONGLONG;
typedef UInt64 ULONGLONG;
-typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;
+typedef union _LARGE_INTEGER {
+ struct {
+ DWORD LowPart;
+ LONG HighPart;
+ };
+ struct {
+ DWORD LowPart;
+ LONG HighPart;
+ } u;
+ LONGLONG QuadPart;
+} LARGE_INTEGER;
typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;
typedef const CHAR *LPCSTR;
@@ -190,12 +200,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/win/CPP/Windows/Time.cpp b/src/libs/7zip/unix/CPP/Windows/TimeUtils.cpp
index ec9ca47d9..7ef44d9cc 100644
--- a/src/libs/7zip/win/CPP/Windows/Time.cpp
+++ b/src/libs/7zip/unix/CPP/Windows/TimeUtils.cpp
@@ -1,10 +1,9 @@
-// Windows/Time.cpp
+// Windows/TimeUtils.cpp
#include "StdAfx.h"
-#include "Windows/Defs.h"
-
-#include "Time.h"
+#include "Defs.h"
+#include "TimeUtils.h"
namespace NWindows {
namespace NTime {
@@ -13,10 +12,11 @@ static const UInt32 kNumTimeQuantumsInSecond = 10000000;
static const UInt32 kFileTimeStartYear = 1601;
static const UInt32 kDosTimeStartYear = 1980;
static const UInt32 kUnixTimeStartYear = 1970;
-static const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) *
- 60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));
+static const UInt64 kUnixTimeOffset =
+ (UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));
+static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond;
-bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft)
+bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) throw()
{
#if defined(_WIN32) && !defined(UNDER_CE)
return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft));
@@ -41,7 +41,7 @@ static const UInt32 kLowDosTime = 0x210000;
#define PERIOD_100 (PERIOD_4 * 25 - 1)
#define PERIOD_400 (PERIOD_100 * 4 + 1)
-bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime)
+bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw()
{
#if defined(_WIN32) && !defined(UNDER_CE)
@@ -115,22 +115,48 @@ bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime)
return true;
}
-void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft)
+void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft) throw()
{
- UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond;
+ UInt64 v = (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond;
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
}
-bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime)
+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;
- if (winTime < kUnixTimeStartValue)
+ 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 = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;
+ winTime -= kUnixTimeOffset;
if (winTime > 0xFFFFFFFF)
{
unixTime = 0xFFFFFFFF;
@@ -141,7 +167,7 @@ bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime)
}
bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
- unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds)
+ unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw()
{
resSeconds = 0;
if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 ||
@@ -160,11 +186,18 @@ bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
return true;
}
-void GetCurUtcFileTime(FILETIME &ft)
+void GetCurUtcFileTime(FILETIME &ft) throw()
{
+ // Both variants provide same low resolution on WinXP: about 15 ms.
+ // But GetSystemTimeAsFileTime is much faster.
+
+ #ifdef UNDER_CE
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &ft);
+ #else
+ GetSystemTimeAsFileTime(&ft);
+ #endif
}
}}
diff --git a/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 b5520e58f..3411bc964 100644
--- a/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp
+++ b/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp
@@ -31,108 +31,150 @@
**
**************************************************************************/
-#include <QDebug>
-#include <QDateTime>
#include "windows.h"
-void FileTimeToDateTime(const FILETIME *source, QDateTime *target)
-{
- ULARGE_INTEGER store;
- QDateTime tempDateTime(QDate(1601, 1, 1));
+#include <QDateTime>
- store.QuadPart = source->dwHighDateTime;
- store.QuadPart = store.QuadPart << 32;
- store.QuadPart += source->dwLowDateTime;
+#include <chrono>
- *target = tempDateTime.addMSecs(store.QuadPart / 10000);
-}
+/*
+ MSDN description about FILETIME structure:
-void DateTimeToSystemTime(const QDateTime *source, SYSTEMTIME *target)
-{
- target->wYear = source->date().year();
- target->wMonth = source->date().month();
- target->wDayOfWeek = source->date().dayOfWeek();
- target->wDay = source->date().day();
- target->wHour = source->time().hour();
- target->wMinute = source->time().minute();
- target->wSecond = source->time().second();
- target->wMilliseconds = source->time().msec();
-}
+ The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals
+ since January 1, 1601 (UTC).
+ The DeltaToEpochInMsec can be calculated like this:
-BOOL WINAPI FileTimeToSystemTime(CONST FILETIME *source,SYSTEMTIME *target)
+ \code
+ quint64 delta = quint64(QDateTime(QDate(1601, 1, 1)).msecsTo(QDateTime(QDate(1970, 1, 1))))
+ * 10000ULL;
+ \endcode
+
+ But since the value is static, we use a precalculated number here.
+*/
+static const ULONGLONG DeltaToEpochInMsec = 116444736000000000ULL;
+
+inline void LocalDateTimeToFileTime(const QDateTime &dt, ULONGLONG utcOffsetInMsec, FILETIME *ft)
{
- QDateTime tempDateTime;
- FileTimeToDateTime(source, &tempDateTime);
- DateTimeToSystemTime(&tempDateTime, target);
+ const ULONGLONG msec = dt.toMSecsSinceEpoch() + utcOffsetInMsec;
+ const ULONGLONG nano100 = (msec * 10000ULL) + DeltaToEpochInMsec;
+
+ ft->dwLowDateTime = nano100;
+ ft->dwHighDateTime = nano100 >> 32;
- return TRUE;
}
-BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME *source,FILETIME *target)
+inline void UTCDateTimeToSystemTime(const QDateTime &dt, SYSTEMTIME *st)
{
- // TODO: Implementation!
- // This doesn't seem to be called at all
-
- qDebug() << "SystemTimeToFileTime";
+ const QDate date = dt.date();
+ const QTime time = dt.time();
+
+ st->wYear = date.year();
+ st->wMonth = date.month();
+ st->wDayOfWeek = date.dayOfWeek();
+ st->wDay = date.day();
+ st->wHour = time.hour();
+ st->wMinute = time.minute();
+ st->wSecond = time.second();
+ st->wMilliseconds = time.msec();
+}
- target->dwHighDateTime = 0;
- target->dwLowDateTime = 0;
- qWarning() << Q_FUNC_INFO;
+// -- WINAPI
+BOOL WINAPI FileTimeToSystemTime(CONST FILETIME *source,SYSTEMTIME *target)
+{
+ const QDateTime dt = QDateTime(QDate(1601, 1, 1), QTime(0, 0, 0, 1), Qt::UTC).addMSecs
+ ((ULONGLONG(source->dwLowDateTime) + (ULONGLONG(source->dwHighDateTime) << 32)) / 10000ULL);
+ UTCDateTimeToSystemTime(dt.toUTC(), target);
return TRUE;
}
BOOL WINAPI FileTimeToLocalFileTime(CONST FILETIME *source,FILETIME *target)
{
- target->dwHighDateTime = source->dwHighDateTime;
- target->dwLowDateTime = source->dwLowDateTime;
-
- QDateTime tempDateTime;
- FileTimeToDateTime(source, &tempDateTime);
-
- tempDateTime = tempDateTime.toLocalTime();
+ const QDateTime dt = QDateTime(QDate(1601, 1, 1), QTime(0, 0, 0, 1), Qt::UTC).addMSecs
+ ((ULONGLONG(source->dwLowDateTime) + (ULONGLONG(source->dwHighDateTime) << 32)) / 10000ULL);
+ LocalDateTimeToFileTime(dt.toLocalTime(), ULONGLONG(QDateTime::currentDateTime()
+ .offsetFromUtc()) * 1000ULL, target);
return TRUE;
}
BOOLEAN WINAPI RtlTimeToSecondsSince1970(const LARGE_INTEGER *Time, DWORD *Seconds)
{
- SYSTEMTIME tempSystemTime;
- FILETIME fileTime;
-
- fileTime.dwLowDateTime = Time->QuadPart;
- fileTime.dwHighDateTime = Time->QuadPart >> 32;
-
- FileTimeToSystemTime(&fileTime, &tempSystemTime);
-
- QDate targetDate(tempSystemTime.wYear, tempSystemTime.wMonth, tempSystemTime.wDay);
- QTime targetTime(tempSystemTime.wHour, tempSystemTime.wMinute, tempSystemTime.wSecond, tempSystemTime.wMilliseconds);
- QDateTime targetDateTime(targetDate, targetTime, Qt::UTC);
-
- quint64 secsSince1970 = targetDateTime.toMSecsSinceEpoch() / 1000;
-
- *Seconds = secsSince1970;
+ /*
+ MSDN suggests to implement the function like this:
+
+ 1. Call SystemTimeToFileTime to copy the system time to a FILETIME structure. Call
+ GetSystemTime to get the current system time to pass to SystemTimeToFileTime.
+ 2. Copy the contents of the FILETIME structure to a ULARGE_INTEGER structure.
+ 3. Initialize a SYSTEMTIME structure with the date and time of the first second of
+ January 1, 1970.
+ 4. Call SystemTimeToFileTime, passing the SYSTEMTIME structure initialized in Step 3
+ to the call.
+ 5. Copy the contents of the FILETIME structure returned by SystemTimeToFileTime in Step 4
+ to a second ULARGE_INTEGER. The copied value should be less than or equal to the value
+ copied in Step 2.
+ 6. Subtract the 64-bit value in the ULARGE_INTEGER structure initialized in Step 5
+ (January 1, 1970) from the 64-bit value of the ULARGE_INTEGER structure initialized
+ in Step 2 (the current system time). This produces a value in 100-nanosecond intervals
+ since January 1, 1970. To convert this value to seconds, divide by 10,000,000.
+
+ We can omit step 1 and 2, cause we get the LARGE_INTEGER passed as function argument.
+ */
+ SYSTEMTIME stFirstSecondOf1979;
+ stFirstSecondOf1979.wSecond = 1;
+ stFirstSecondOf1979.wMinute = 0;
+ stFirstSecondOf1979.wHour = 0;
+ stFirstSecondOf1979.wDay = 1;
+ stFirstSecondOf1979.wMonth = 1;
+ stFirstSecondOf1979.wYear = 1970;
+ stFirstSecondOf1979.wDayOfWeek = 4;
+
+ FILETIME ftFirstSecondOf1979;
+ SystemTimeToFileTime(&stFirstSecondOf1979, &ftFirstSecondOf1979);
+
+ LARGE_INTEGER liFirstSecondOf1979;
+ liFirstSecondOf1979.LowPart = ftFirstSecondOf1979.dwLowDateTime;
+ liFirstSecondOf1979.HighPart = ftFirstSecondOf1979.dwHighDateTime;
+
+ const ULONGLONG diffNano100 = Time->QuadPart - liFirstSecondOf1979.QuadPart;
+ *Seconds = diffNano100 / 10000000ULL;
return TRUE;
}
void WINAPI RtlSecondsSince1970ToFileTime(DWORD Seconds, FILETIME *ft)
{
- QDateTime fileTimeStartDate(QDate(1601, 1, 1));
- quint64 hnseconds = Seconds;
- QDateTime sourceDateTime = QDateTime::fromMSecsSinceEpoch(hnseconds * 1000);
+ const ULONGLONG nano100 = (ULONGLONG(Seconds) * 10000000ULL) + DeltaToEpochInMsec;
+ ft->dwLowDateTime = nano100;
+ ft->dwHighDateTime = nano100 >> 32;
+}
+
+VOID WINAPI GetSystemTime(SYSTEMTIME *st)
+{
+ UTCDateTimeToSystemTime(QDateTime::currentDateTimeUtc(), st);
+}
- hnseconds = fileTimeStartDate.msecsTo(sourceDateTime);
- hnseconds *= 10000;
+VOID WINAPI GetSystemTimeAsFileTime(FILETIME *time)
+{
+ SYSTEMTIME st;
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, time);
+}
- ft->dwLowDateTime = hnseconds;
- ft->dwHighDateTime = hnseconds >> 32;
+DWORD WINAPI GetTickCount()
+{
+ using namespace std::chrono;
+ return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
}
-VOID WINAPI GetSystemTime(SYSTEMTIME *st)
+BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, FILETIME *lpFileTime)
{
- QDateTime nowDateTime = QDateTime::currentDateTimeUtc();
- DateTimeToSystemTime(&nowDateTime, st);
+ const QDateTime dt(QDate(lpSystemTime->wYear, lpSystemTime->wMonth, lpSystemTime->wDay),
+ QTime(lpSystemTime->wHour, lpSystemTime->wMinute, lpSystemTime->wSecond,
+ lpSystemTime->wMilliseconds), Qt::UTC);
+
+ LocalDateTimeToFileTime(dt.toLocalTime(), 0ULL, lpFileTime);
+ return TRUE;
}
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)
diff --git a/src/libs/7zip/win/7zC.txt b/src/libs/7zip/win/7zC.txt
deleted file mode 100644
index 5d5d06d7b..000000000
--- a/src/libs/7zip/win/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/win/7zFormat.txt b/src/libs/7zip/win/7zFormat.txt
deleted file mode 100644
index e1cf7380d..000000000
--- a/src/libs/7zip/win/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/win/C/7z.h b/src/libs/7zip/win/C/7z.h
deleted file mode 100644
index 01c4cac6a..000000000
--- a/src/libs/7zip/win/C/7z.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/* 7z.h -- 7z interface
-2010-03-11 : Igor Pavlov : Public domain */
-
-#ifndef __7Z_H
-#define __7Z_H
-
-#include "7zBuf.h"
-
-EXTERN_C_BEGIN
-
-#define k7zStartHeaderSize 0x20
-#define k7zSignatureSize 6
-extern Byte k7zSignature[k7zSignatureSize];
-#define k7zMajorVersion 0
-
-enum EIdEnum
-{
- k7zIdEnd,
- k7zIdHeader,
- k7zIdArchiveProperties,
- k7zIdAdditionalStreamsInfo,
- k7zIdMainStreamsInfo,
- k7zIdFilesInfo,
- k7zIdPackInfo,
- k7zIdUnpackInfo,
- k7zIdSubStreamsInfo,
- k7zIdSize,
- k7zIdCRC,
- k7zIdFolder,
- k7zIdCodersUnpackSize,
- k7zIdNumUnpackStream,
- k7zIdEmptyStream,
- k7zIdEmptyFile,
- k7zIdAnti,
- k7zIdName,
- k7zIdCTime,
- k7zIdATime,
- k7zIdMTime,
- k7zIdWinAttributes,
- k7zIdComment,
- k7zIdEncodedHeader,
- k7zIdStartPos,
- k7zIdDummy
-};
-
-typedef struct
-{
- UInt32 NumInStreams;
- UInt32 NumOutStreams;
- UInt64 MethodID;
- CBuf Props;
-} CSzCoderInfo;
-
-void SzCoderInfo_Init(CSzCoderInfo *p);
-void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
-
-typedef struct
-{
- UInt32 InIndex;
- UInt32 OutIndex;
-} CSzBindPair;
-
-typedef struct
-{
- CSzCoderInfo *Coders;
- CSzBindPair *BindPairs;
- UInt32 *PackStreams;
- UInt64 *UnpackSizes;
- UInt32 NumCoders;
- UInt32 NumBindPairs;
- UInt32 NumPackStreams;
- int UnpackCRCDefined;
- UInt32 UnpackCRC;
-
- UInt32 NumUnpackStreams;
-} CSzFolder;
-
-void SzFolder_Init(CSzFolder *p);
-UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
-int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
-UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
-UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
-
-SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
- ILookInStream *stream, UInt64 startPos,
- Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
-
-typedef struct
-{
- UInt32 Low;
- UInt32 High;
-} CNtfsFileTime;
-
-typedef struct
-{
- CNtfsFileTime MTime;
- UInt64 Size;
- UInt32 Crc;
- UInt32 Attrib;
- Byte HasStream;
- Byte IsDir;
- Byte IsAnti;
- Byte CrcDefined;
- Byte MTimeDefined;
- Byte AttribDefined;
-} CSzFileItem;
-
-void SzFile_Init(CSzFileItem *p);
-
-typedef struct
-{
- UInt64 *PackSizes;
- Byte *PackCRCsDefined;
- UInt32 *PackCRCs;
- CSzFolder *Folders;
- CSzFileItem *Files;
- UInt32 NumPackStreams;
- UInt32 NumFolders;
- UInt32 NumFiles;
-} CSzAr;
-
-void SzAr_Init(CSzAr *p);
-void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
-
-
-/*
- SzExtract extracts file from archive
-
- *outBuffer must be 0 before first call for each new archive.
-
- Extracting cache:
- If you need to decompress more than one file, you can send
- these values from previous call:
- *blockIndex,
- *outBuffer,
- *outBufferSize
- You can consider "*outBuffer" as cache of solid block. If your archive is solid,
- it will increase decompression speed.
-
- If you use external function, you can declare these 3 cache variables
- (blockIndex, outBuffer, outBufferSize) as static in that external function.
-
- Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
-*/
-
-typedef struct
-{
- CSzAr db;
-
- UInt64 startPosAfterHeader;
- UInt64 dataPos;
-
- UInt32 *FolderStartPackStreamIndex;
- UInt64 *PackStreamStartPositions;
- UInt32 *FolderStartFileIndex;
- UInt32 *FileIndexToFolderIndexMap;
-
- size_t *FileNameOffsets; /* in 2-byte steps */
- CBuf FileNames; /* UTF-16-LE */
-} CSzArEx;
-
-void SzArEx_Init(CSzArEx *p);
-void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
-UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
-int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
-
-/*
-if dest == NULL, the return value specifies the required size of the buffer,
- in 16-bit characters, including the null-terminating character.
-if dest != NULL, the return value specifies the number of 16-bit characters that
- are written to the dest, including the null-terminating character. */
-
-size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
-
-SRes SzArEx_Extract(
- const CSzArEx *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);
-
-
-/*
-SzArEx_Open Errors:
-SZ_ERROR_NO_ARCHIVE
-SZ_ERROR_ARCHIVE
-SZ_ERROR_UNSUPPORTED
-SZ_ERROR_MEM
-SZ_ERROR_CRC
-SZ_ERROR_INPUT_EOF
-SZ_ERROR_FAIL
-*/
-
-SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
-
-EXTERN_C_END
-
-#endif
diff --git a/src/libs/7zip/win/C/7zAlloc.c b/src/libs/7zip/win/C/7zAlloc.c
deleted file mode 100644
index 964b28db3..000000000
--- a/src/libs/7zip/win/C/7zAlloc.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* 7zAlloc.c -- Allocation functions
-2010-10-29 : Igor Pavlov : Public domain */
-
-#include "7zAlloc.h"
-
-/* #define _SZ_ALLOC_DEBUG */
-/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
-
-#ifdef _SZ_ALLOC_DEBUG
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-#include <stdio.h>
-int g_allocCount = 0;
-int g_allocCountTemp = 0;
-
-#endif
-
-void *SzAlloc(void *p, size_t size)
-{
- p = p;
- if (size == 0)
- return 0;
- #ifdef _SZ_ALLOC_DEBUG
- fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
- g_allocCount++;
- #endif
- return malloc(size);
-}
-
-void SzFree(void *p, void *address)
-{
- p = p;
- #ifdef _SZ_ALLOC_DEBUG
- if (address != 0)
- {
- g_allocCount--;
- fprintf(stderr, "\nFree; count = %10d", g_allocCount);
- }
- #endif
- free(address);
-}
-
-void *SzAllocTemp(void *p, size_t size)
-{
- p = p;
- if (size == 0)
- return 0;
- #ifdef _SZ_ALLOC_DEBUG
- fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
- g_allocCountTemp++;
- #ifdef _WIN32
- return HeapAlloc(GetProcessHeap(), 0, size);
- #endif
- #endif
- return malloc(size);
-}
-
-void SzFreeTemp(void *p, void *address)
-{
- p = p;
- #ifdef _SZ_ALLOC_DEBUG
- if (address != 0)
- {
- g_allocCountTemp--;
- fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
- }
- #ifdef _WIN32
- HeapFree(GetProcessHeap(), 0, address);
- return;
- #endif
- #endif
- free(address);
-}
diff --git a/src/libs/7zip/win/C/7zAlloc.h b/src/libs/7zip/win/C/7zAlloc.h
deleted file mode 100644
index 3344e9373..000000000
--- a/src/libs/7zip/win/C/7zAlloc.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* 7zAlloc.h -- Allocation functions
-2010-10-29 : Igor Pavlov : Public domain */
-
-#ifndef __7Z_ALLOC_H
-#define __7Z_ALLOC_H
-
-#include <stdlib.h>
-
-void *SzAlloc(void *p, size_t size);
-void SzFree(void *p, void *address);
-
-void *SzAllocTemp(void *p, size_t size);
-void SzFreeTemp(void *p, void *address);
-
-#endif
diff --git a/src/libs/7zip/win/C/7zBuf.c b/src/libs/7zip/win/C/7zBuf.c
deleted file mode 100644
index 14e7f4e2b..000000000
--- a/src/libs/7zip/win/C/7zBuf.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* 7zBuf.c -- Byte Buffer
-2008-03-28
-Igor Pavlov
-Public domain */
-
-#include "7zBuf.h"
-
-void Buf_Init(CBuf *p)
-{
- p->data = 0;
- p->size = 0;
-}
-
-int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
-{
- p->size = 0;
- if (size == 0)
- {
- p->data = 0;
- return 1;
- }
- p->data = (Byte *)alloc->Alloc(alloc, size);
- if (p->data != 0)
- {
- p->size = size;
- return 1;
- }
- return 0;
-}
-
-void Buf_Free(CBuf *p, ISzAlloc *alloc)
-{
- alloc->Free(alloc, p->data);
- p->data = 0;
- p->size = 0;
-}
diff --git a/src/libs/7zip/win/C/7zBuf.h b/src/libs/7zip/win/C/7zBuf.h
deleted file mode 100644
index e9f2f316d..000000000
--- a/src/libs/7zip/win/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/win/C/7zBuf2.c b/src/libs/7zip/win/C/7zBuf2.c
deleted file mode 100644
index 8d17e0dcf..000000000
--- a/src/libs/7zip/win/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/win/C/7zCrc.c b/src/libs/7zip/win/C/7zCrc.c
index a92084961..5f32380dd 100644
--- a/src/libs/7zip/win/C/7zCrc.c
+++ b/src/libs/7zip/win/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,18 +49,37 @@ 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;
- #ifdef MY_CPU_X86_OR_AMD64
+
+ #if CRC_NUM_TABLES == 8
if (!CPU_Is_InOrder())
g_CrcUpdate = CrcUpdateT8;
#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/win/C/7zCrc.h b/src/libs/7zip/win/C/7zCrc.h
index 38e3e5fbc..8fd579587 100644
--- a/src/libs/7zip/win/C/7zCrc.h
+++ b/src/libs/7zip/win/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/win/C/7zCrcOpt.c b/src/libs/7zip/win/C/7zCrcOpt.c
index 6c766a209..ce132b5d4 100644
--- a/src/libs/7zip/win/C/7zCrcOpt.c
+++ b/src/libs/7zip/win/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/win/C/7zDec.c b/src/libs/7zip/win/C/7zDec.c
deleted file mode 100644
index b6d809956..000000000
--- a/src/libs/7zip/win/C/7zDec.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/* 7zDec.c -- Decoding from 7z folder
-2010-11-02 : Igor Pavlov : Public domain */
-
-#include <string.h>
-
-/* #define _7ZIP_PPMD_SUPPPORT */
-
-#include "7z.h"
-
-#include "Bcj2.h"
-#include "Bra.h"
-#include "CpuArch.h"
-#include "LzmaDec.h"
-#include "Lzma2Dec.h"
-#ifdef _7ZIP_PPMD_SUPPPORT
-#include "Ppmd7.h"
-#endif
-
-#define k_Copy 0
-#define k_LZMA2 0x21
-#define k_LZMA 0x30101
-#define k_BCJ 0x03030103
-#define k_PPC 0x03030205
-#define k_ARM 0x03030501
-#define k_ARMT 0x03030701
-#define k_SPARC 0x03030805
-#define k_BCJ2 0x0303011B
-
-#ifdef _7ZIP_PPMD_SUPPPORT
-
-#define k_PPMD 0x30401
-
-typedef struct
-{
- IByteIn p;
- const Byte *cur;
- const Byte *end;
- const Byte *begin;
- UInt64 processed;
- Bool extra;
- SRes res;
- ILookInStream *inStream;
-} CByteInToLook;
-
-static Byte ReadByte(void *pp)
-{
- CByteInToLook *p = (CByteInToLook *)pp;
- if (p->cur != p->end)
- return *p->cur++;
- if (p->res == SZ_OK)
- {
- size_t size = p->cur - p->begin;
- p->processed += size;
- p->res = p->inStream->Skip(p->inStream, size);
- size = (1 << 25);
- p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
- p->cur = p->begin;
- p->end = p->begin + size;
- if (size != 0)
- return *p->cur++;;
- }
- p->extra = True;
- return 0;
-}
-
-static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
- Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
-{
- CPpmd7 ppmd;
- CByteInToLook s;
- SRes res = SZ_OK;
-
- s.p.Read = ReadByte;
- s.inStream = inStream;
- s.begin = s.end = s.cur = NULL;
- s.extra = False;
- s.res = SZ_OK;
- s.processed = 0;
-
- if (coder->Props.size != 5)
- return SZ_ERROR_UNSUPPORTED;
-
- {
- unsigned order = coder->Props.data[0];
- UInt32 memSize = GetUi32(coder->Props.data + 1);
- if (order < PPMD7_MIN_ORDER ||
- order > PPMD7_MAX_ORDER ||
- memSize < PPMD7_MIN_MEM_SIZE ||
- memSize > PPMD7_MAX_MEM_SIZE)
- return SZ_ERROR_UNSUPPORTED;
- Ppmd7_Construct(&ppmd);
- if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
- return SZ_ERROR_MEM;
- Ppmd7_Init(&ppmd, order);
- }
- {
- CPpmd7z_RangeDec rc;
- Ppmd7z_RangeDec_CreateVTable(&rc);
- rc.Stream = &s.p;
- if (!Ppmd7z_RangeDec_Init(&rc))
- res = SZ_ERROR_DATA;
- else if (s.extra)
- res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
- else
- {
- SizeT i;
- for (i = 0; i < outSize; i++)
- {
- int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
- if (s.extra || sym < 0)
- break;
- outBuffer[i] = (Byte)sym;
- }
- if (i != outSize)
- res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
- else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
- res = SZ_ERROR_DATA;
- }
- }
- Ppmd7_Free(&ppmd, allocMain);
- return res;
-}
-
-#endif
-
-
-static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
- Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
-{
- CLzmaDec state;
- SRes res = SZ_OK;
-
- LzmaDec_Construct(&state);
- RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
- state.dic = outBuffer;
- state.dicBufSize = outSize;
- LzmaDec_Init(&state);
-
- for (;;)
- {
- Byte *inBuf = NULL;
- size_t lookahead = (1 << 18);
- if (lookahead > inSize)
- lookahead = (size_t)inSize;
- res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
- if (res != SZ_OK)
- break;
-
- {
- SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
- ELzmaStatus status;
- res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
- lookahead -= inProcessed;
- inSize -= inProcessed;
- if (res != SZ_OK)
- break;
- if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
- {
- if (state.dicBufSize != outSize || lookahead != 0 ||
- (status != LZMA_STATUS_FINISHED_WITH_MARK &&
- status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
- res = SZ_ERROR_DATA;
- break;
- }
- res = inStream->Skip((void *)inStream, inProcessed);
- if (res != SZ_OK)
- break;
- }
- }
-
- LzmaDec_FreeProbs(&state, allocMain);
- return res;
-}
-
-static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
- Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
-{
- CLzma2Dec state;
- SRes res = SZ_OK;
-
- Lzma2Dec_Construct(&state);
- if (coder->Props.size != 1)
- return SZ_ERROR_DATA;
- RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));
- state.decoder.dic = outBuffer;
- state.decoder.dicBufSize = outSize;
- Lzma2Dec_Init(&state);
-
- for (;;)
- {
- Byte *inBuf = NULL;
- size_t lookahead = (1 << 18);
- if (lookahead > inSize)
- lookahead = (size_t)inSize;
- res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
- if (res != SZ_OK)
- break;
-
- {
- SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
- ELzmaStatus status;
- res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
- lookahead -= inProcessed;
- inSize -= inProcessed;
- if (res != SZ_OK)
- break;
- if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
- {
- if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
- (status != LZMA_STATUS_FINISHED_WITH_MARK))
- res = SZ_ERROR_DATA;
- break;
- }
- res = inStream->Skip((void *)inStream, inProcessed);
- if (res != SZ_OK)
- break;
- }
- }
-
- Lzma2Dec_FreeProbs(&state, allocMain);
- return res;
-}
-
-static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
-{
- while (inSize > 0)
- {
- void *inBuf;
- size_t curSize = (1 << 18);
- if (curSize > inSize)
- curSize = (size_t)inSize;
- RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
- if (curSize == 0)
- return SZ_ERROR_INPUT_EOF;
- memcpy(outBuffer, inBuf, curSize);
- outBuffer += curSize;
- inSize -= curSize;
- RINOK(inStream->Skip((void *)inStream, curSize));
- }
- return SZ_OK;
-}
-
-static Bool IS_MAIN_METHOD(UInt32 m)
-{
- switch(m)
- {
- case k_Copy:
- case k_LZMA:
- case k_LZMA2:
- #ifdef _7ZIP_PPMD_SUPPPORT
- case k_PPMD:
- #endif
- return True;
- }
- return False;
-}
-
-static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
-{
- return
- c->NumInStreams == 1 &&
- c->NumOutStreams == 1 &&
- c->MethodID <= (UInt32)0xFFFFFFFF &&
- IS_MAIN_METHOD((UInt32)c->MethodID);
-}
-
-#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
-
-static SRes CheckSupportedFolder(const CSzFolder *f)
-{
- if (f->NumCoders < 1 || f->NumCoders > 4)
- return SZ_ERROR_UNSUPPORTED;
- if (!IS_SUPPORTED_CODER(&f->Coders[0]))
- return SZ_ERROR_UNSUPPORTED;
- if (f->NumCoders == 1)
- {
- if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
- return SZ_ERROR_UNSUPPORTED;
- return SZ_OK;
- }
- if (f->NumCoders == 2)
- {
- CSzCoderInfo *c = &f->Coders[1];
- if (c->MethodID > (UInt32)0xFFFFFFFF ||
- c->NumInStreams != 1 ||
- c->NumOutStreams != 1 ||
- f->NumPackStreams != 1 ||
- f->PackStreams[0] != 0 ||
- f->NumBindPairs != 1 ||
- f->BindPairs[0].InIndex != 1 ||
- f->BindPairs[0].OutIndex != 0)
- return SZ_ERROR_UNSUPPORTED;
- switch ((UInt32)c->MethodID)
- {
- case k_BCJ:
- case k_ARM:
- break;
- default:
- return SZ_ERROR_UNSUPPORTED;
- }
- return SZ_OK;
- }
- if (f->NumCoders == 4)
- {
- if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
- !IS_SUPPORTED_CODER(&f->Coders[2]) ||
- !IS_BCJ2(&f->Coders[3]))
- return SZ_ERROR_UNSUPPORTED;
- if (f->NumPackStreams != 4 ||
- f->PackStreams[0] != 2 ||
- f->PackStreams[1] != 6 ||
- f->PackStreams[2] != 1 ||
- f->PackStreams[3] != 0 ||
- f->NumBindPairs != 3 ||
- f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
- f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
- f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
- return SZ_ERROR_UNSUPPORTED;
- return SZ_OK;
- }
- return SZ_ERROR_UNSUPPORTED;
-}
-
-static UInt64 GetSum(const UInt64 *values, UInt32 index)
-{
- UInt64 sum = 0;
- UInt32 i;
- for (i = 0; i < index; i++)
- sum += values[i];
- return sum;
-}
-
-#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
-
-static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
- ILookInStream *inStream, UInt64 startPos,
- Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
- Byte *tempBuf[])
-{
- UInt32 ci;
- SizeT tempSizes[3] = { 0, 0, 0};
- SizeT tempSize3 = 0;
- Byte *tempBuf3 = 0;
-
- RINOK(CheckSupportedFolder(folder));
-
- for (ci = 0; ci < folder->NumCoders; ci++)
- {
- CSzCoderInfo *coder = &folder->Coders[ci];
-
- if (IS_MAIN_METHOD((UInt32)coder->MethodID))
- {
- UInt32 si = 0;
- UInt64 offset;
- UInt64 inSize;
- Byte *outBufCur = outBuffer;
- SizeT outSizeCur = outSize;
- if (folder->NumCoders == 4)
- {
- UInt32 indices[] = { 3, 2, 0 };
- UInt64 unpackSize = folder->UnpackSizes[ci];
- si = indices[ci];
- if (ci < 2)
- {
- Byte *temp;
- outSizeCur = (SizeT)unpackSize;
- if (outSizeCur != unpackSize)
- return SZ_ERROR_MEM;
- temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
- if (temp == 0 && outSizeCur != 0)
- return SZ_ERROR_MEM;
- outBufCur = tempBuf[1 - ci] = temp;
- tempSizes[1 - ci] = outSizeCur;
- }
- else if (ci == 2)
- {
- if (unpackSize > outSize) /* check it */
- return SZ_ERROR_PARAM;
- tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
- tempSize3 = outSizeCur = (SizeT)unpackSize;
- }
- else
- return SZ_ERROR_UNSUPPORTED;
- }
- offset = GetSum(packSizes, si);
- inSize = packSizes[si];
- RINOK(LookInStream_SeekTo(inStream, startPos + offset));
-
- if (coder->MethodID == k_Copy)
- {
- if (inSize != outSizeCur) /* check it */
- return SZ_ERROR_DATA;
- RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
- }
- else if (coder->MethodID == k_LZMA)
- {
- RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
- }
- else if (coder->MethodID == k_LZMA2)
- {
- RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
- }
- else
- {
- #ifdef _7ZIP_PPMD_SUPPPORT
- RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
- #else
- return SZ_ERROR_UNSUPPORTED;
- #endif
- }
- }
- else if (coder->MethodID == k_BCJ2)
- {
- UInt64 offset = GetSum(packSizes, 1);
- UInt64 s3Size = packSizes[1];
- SRes res;
- if (ci != 3)
- return SZ_ERROR_UNSUPPORTED;
- RINOK(LookInStream_SeekTo(inStream, startPos + offset));
- tempSizes[2] = (SizeT)s3Size;
- if (tempSizes[2] != s3Size)
- return SZ_ERROR_MEM;
- tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
- if (tempBuf[2] == 0 && tempSizes[2] != 0)
- return SZ_ERROR_MEM;
- res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
- RINOK(res)
-
- res = Bcj2_Decode(
- tempBuf3, tempSize3,
- tempBuf[0], tempSizes[0],
- tempBuf[1], tempSizes[1],
- tempBuf[2], tempSizes[2],
- outBuffer, outSize);
- RINOK(res)
- }
- else
- {
- if (ci != 1)
- return SZ_ERROR_UNSUPPORTED;
- switch(coder->MethodID)
- {
- case k_BCJ:
- {
- UInt32 state;
- x86_Convert_Init(state);
- x86_Convert(outBuffer, outSize, 0, &state, 0);
- break;
- }
- CASE_BRA_CONV(ARM)
- default:
- return SZ_ERROR_UNSUPPORTED;
- }
- }
- }
- return SZ_OK;
-}
-
-SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
- ILookInStream *inStream, UInt64 startPos,
- Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
-{
- Byte *tempBuf[3] = { 0, 0, 0};
- int i;
- SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
- outBuffer, (SizeT)outSize, allocMain, tempBuf);
- for (i = 0; i < 3; i++)
- IAlloc_Free(allocMain, tempBuf[i]);
- return res;
-}
diff --git a/src/libs/7zip/win/C/7zFile.c b/src/libs/7zip/win/C/7zFile.c
deleted file mode 100644
index a66c9e9d0..000000000
--- a/src/libs/7zip/win/C/7zFile.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/* 7zFile.c -- File IO
-2009-11-24 : Igor Pavlov : Public domain */
-
-#include "7zFile.h"
-
-#ifndef USE_WINDOWS_FILE
-
-#ifndef UNDER_CE
-#include <errno.h>
-#endif
-
-#else
-
-/*
- 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
- (Insufficient system resources exist to complete the requested service).
- Probably in some version of Windows there are problems with other sizes:
- for 32 MB (maybe also for 16 MB).
- And message can be "Network connection was lost"
-*/
-
-#define kChunkSizeMax (1 << 22)
-
-#endif
-
-void File_Construct(CSzFile *p)
-{
- #ifdef USE_WINDOWS_FILE
- p->handle = INVALID_HANDLE_VALUE;
- #else
- p->file = NULL;
- #endif
-}
-
-#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
-static WRes File_Open(CSzFile *p, const char *name, int writeMode)
-{
- #ifdef USE_WINDOWS_FILE
- p->handle = CreateFileA(name,
- writeMode ? GENERIC_WRITE : GENERIC_READ,
- FILE_SHARE_READ, NULL,
- writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, NULL);
- return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
- #else
- p->file = fopen(name, writeMode ? "wb+" : "rb");
- return (p->file != 0) ? 0 :
- #ifdef UNDER_CE
- 2; /* ENOENT */
- #else
- errno;
- #endif
- #endif
-}
-
-WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
-WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
-#endif
-
-#ifdef USE_WINDOWS_FILE
-static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
-{
- p->handle = CreateFileW(name,
- writeMode ? GENERIC_WRITE : GENERIC_READ,
- FILE_SHARE_READ, NULL,
- writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, NULL);
- return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
-}
-WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
-WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
-#endif
-
-WRes File_Close(CSzFile *p)
-{
- #ifdef USE_WINDOWS_FILE
- if (p->handle != INVALID_HANDLE_VALUE)
- {
- if (!CloseHandle(p->handle))
- return GetLastError();
- p->handle = INVALID_HANDLE_VALUE;
- }
- #else
- if (p->file != NULL)
- {
- int res = fclose(p->file);
- if (res != 0)
- return res;
- p->file = NULL;
- }
- #endif
- return 0;
-}
-
-WRes File_Read(CSzFile *p, void *data, size_t *size)
-{
- size_t originalSize = *size;
- if (originalSize == 0)
- return 0;
-
- #ifdef USE_WINDOWS_FILE
-
- *size = 0;
- do
- {
- DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
- DWORD processed = 0;
- BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
- data = (void *)((Byte *)data + processed);
- originalSize -= processed;
- *size += processed;
- if (!res)
- return GetLastError();
- if (processed == 0)
- break;
- }
- while (originalSize > 0);
- return 0;
-
- #else
-
- *size = fread(data, 1, originalSize, p->file);
- if (*size == originalSize)
- return 0;
- return ferror(p->file);
-
- #endif
-}
-
-WRes File_Write(CSzFile *p, const void *data, size_t *size)
-{
- size_t originalSize = *size;
- if (originalSize == 0)
- return 0;
-
- #ifdef USE_WINDOWS_FILE
-
- *size = 0;
- do
- {
- DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
- DWORD processed = 0;
- BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
- data = (void *)((Byte *)data + processed);
- originalSize -= processed;
- *size += processed;
- if (!res)
- return GetLastError();
- if (processed == 0)
- break;
- }
- while (originalSize > 0);
- return 0;
-
- #else
-
- *size = fwrite(data, 1, originalSize, p->file);
- if (*size == originalSize)
- return 0;
- return ferror(p->file);
-
- #endif
-}
-
-WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
-{
- #ifdef USE_WINDOWS_FILE
-
- LARGE_INTEGER value;
- DWORD moveMethod;
- value.LowPart = (DWORD)*pos;
- value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
- switch (origin)
- {
- case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
- case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
- case SZ_SEEK_END: moveMethod = FILE_END; break;
- default: return ERROR_INVALID_PARAMETER;
- }
- value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
- if (value.LowPart == 0xFFFFFFFF)
- {
- WRes res = GetLastError();
- if (res != NO_ERROR)
- return res;
- }
- *pos = ((Int64)value.HighPart << 32) | value.LowPart;
- return 0;
-
- #else
-
- int moveMethod;
- int res;
- switch (origin)
- {
- case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
- case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
- case SZ_SEEK_END: moveMethod = SEEK_END; break;
- default: return 1;
- }
- res = fseek(p->file, (long)*pos, moveMethod);
- *pos = ftell(p->file);
- return res;
-
- #endif
-}
-
-WRes File_GetLength(CSzFile *p, UInt64 *length)
-{
- #ifdef USE_WINDOWS_FILE
-
- DWORD sizeHigh;
- DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
- if (sizeLow == 0xFFFFFFFF)
- {
- DWORD res = GetLastError();
- if (res != NO_ERROR)
- return res;
- }
- *length = (((UInt64)sizeHigh) << 32) + sizeLow;
- return 0;
-
- #else
-
- long pos = ftell(p->file);
- int res = fseek(p->file, 0, SEEK_END);
- *length = ftell(p->file);
- fseek(p->file, pos, SEEK_SET);
- return res;
-
- #endif
-}
-
-
-/* ---------- FileSeqInStream ---------- */
-
-static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
-{
- CFileSeqInStream *p = (CFileSeqInStream *)pp;
- return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
-}
-
-void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
-{
- p->s.Read = FileSeqInStream_Read;
-}
-
-
-/* ---------- FileInStream ---------- */
-
-static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
-{
- CFileInStream *p = (CFileInStream *)pp;
- return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
-}
-
-static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
-{
- CFileInStream *p = (CFileInStream *)pp;
- return File_Seek(&p->file, pos, origin);
-}
-
-void FileInStream_CreateVTable(CFileInStream *p)
-{
- p->s.Read = FileInStream_Read;
- p->s.Seek = FileInStream_Seek;
-}
-
-
-/* ---------- FileOutStream ---------- */
-
-static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
-{
- CFileOutStream *p = (CFileOutStream *)pp;
- File_Write(&p->file, data, &size);
- return size;
-}
-
-void FileOutStream_CreateVTable(CFileOutStream *p)
-{
- p->s.Write = FileOutStream_Write;
-}
diff --git a/src/libs/7zip/win/C/7zFile.h b/src/libs/7zip/win/C/7zFile.h
deleted file mode 100644
index 84538c03f..000000000
--- a/src/libs/7zip/win/C/7zFile.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* 7zFile.h -- File IO
-2009-11-24 : Igor Pavlov : Public domain */
-
-#ifndef __7Z_FILE_H
-#define __7Z_FILE_H
-
-#ifdef _WIN32
-#define USE_WINDOWS_FILE
-#endif
-
-#ifdef USE_WINDOWS_FILE
-#include <windows.h>
-#else
-#include <stdio.h>
-#endif
-
-#include "Types.h"
-
-EXTERN_C_BEGIN
-
-/* ---------- File ---------- */
-
-typedef struct
-{
- #ifdef USE_WINDOWS_FILE
- HANDLE handle;
- #else
- FILE *file;
- #endif
-} CSzFile;
-
-void File_Construct(CSzFile *p);
-#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
-WRes InFile_Open(CSzFile *p, const char *name);
-WRes OutFile_Open(CSzFile *p, const char *name);
-#endif
-#ifdef USE_WINDOWS_FILE
-WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
-WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
-#endif
-WRes File_Close(CSzFile *p);
-
-/* reads max(*size, remain file's size) bytes */
-WRes File_Read(CSzFile *p, void *data, size_t *size);
-
-/* writes *size bytes */
-WRes File_Write(CSzFile *p, const void *data, size_t *size);
-
-WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
-WRes File_GetLength(CSzFile *p, UInt64 *length);
-
-
-/* ---------- FileInStream ---------- */
-
-typedef struct
-{
- ISeqInStream s;
- CSzFile file;
-} CFileSeqInStream;
-
-void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
-
-
-typedef struct
-{
- ISeekInStream s;
- CSzFile file;
-} CFileInStream;
-
-void FileInStream_CreateVTable(CFileInStream *p);
-
-
-typedef struct
-{
- ISeqOutStream s;
- CSzFile file;
-} CFileOutStream;
-
-void FileOutStream_CreateVTable(CFileOutStream *p);
-
-EXTERN_C_END
-
-#endif
diff --git a/src/libs/7zip/win/C/7zIn.c b/src/libs/7zip/win/C/7zIn.c
deleted file mode 100644
index ec93a43ff..000000000
--- a/src/libs/7zip/win/C/7zIn.c
+++ /dev/null
@@ -1,1402 +0,0 @@
-/* 7zIn.c -- 7z Input functions
-2010-10-29 : Igor Pavlov : Public domain */
-
-#include <string.h>
-
-#include "7z.h"
-#include "7zCrc.h"
-#include "CpuArch.h"
-
-Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
-
-#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
-
-#define NUM_FOLDER_CODERS_MAX 32
-#define NUM_CODER_STREAMS_MAX 32
-
-void SzCoderInfo_Init(CSzCoderInfo *p)
-{
- Buf_Init(&p->Props);
-}
-
-void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
-{
- Buf_Free(&p->Props, alloc);
- SzCoderInfo_Init(p);
-}
-
-void SzFolder_Init(CSzFolder *p)
-{
- p->Coders = 0;
- p->BindPairs = 0;
- p->PackStreams = 0;
- p->UnpackSizes = 0;
- p->NumCoders = 0;
- p->NumBindPairs = 0;
- p->NumPackStreams = 0;
- p->UnpackCRCDefined = 0;
- p->UnpackCRC = 0;
- p->NumUnpackStreams = 0;
-}
-
-void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
-{
- UInt32 i;
- if (p->Coders)
- for (i = 0; i < p->NumCoders; i++)
- SzCoderInfo_Free(&p->Coders[i], alloc);
- IAlloc_Free(alloc, p->Coders);
- IAlloc_Free(alloc, p->BindPairs);
- IAlloc_Free(alloc, p->PackStreams);
- IAlloc_Free(alloc, p->UnpackSizes);
- SzFolder_Init(p);
-}
-
-UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
-{
- UInt32 result = 0;
- UInt32 i;
- for (i = 0; i < p->NumCoders; i++)
- result += p->Coders[i].NumOutStreams;
- return result;
-}
-
-int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
-{
- UInt32 i;
- for (i = 0; i < p->NumBindPairs; i++)
- if (p->BindPairs[i].InIndex == inStreamIndex)
- return i;
- return -1;
-}
-
-
-int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
-{
- UInt32 i;
- for (i = 0; i < p->NumBindPairs; i++)
- if (p->BindPairs[i].OutIndex == outStreamIndex)
- return i;
- return -1;
-}
-
-UInt64 SzFolder_GetUnpackSize(CSzFolder *p)
-{
- int i = (int)SzFolder_GetNumOutStreams(p);
- if (i == 0)
- return 0;
- for (i--; i >= 0; i--)
- if (SzFolder_FindBindPairForOutStream(p, i) < 0)
- return p->UnpackSizes[i];
- /* throw 1; */
- return 0;
-}
-
-void SzFile_Init(CSzFileItem *p)
-{
- p->HasStream = 1;
- p->IsDir = 0;
- p->IsAnti = 0;
- p->CrcDefined = 0;
- p->MTimeDefined = 0;
-}
-
-void SzAr_Init(CSzAr *p)
-{
- p->PackSizes = 0;
- p->PackCRCsDefined = 0;
- p->PackCRCs = 0;
- p->Folders = 0;
- p->Files = 0;
- p->NumPackStreams = 0;
- p->NumFolders = 0;
- p->NumFiles = 0;
-}
-
-void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
-{
- UInt32 i;
- if (p->Folders)
- for (i = 0; i < p->NumFolders; i++)
- SzFolder_Free(&p->Folders[i], alloc);
-
- IAlloc_Free(alloc, p->PackSizes);
- IAlloc_Free(alloc, p->PackCRCsDefined);
- IAlloc_Free(alloc, p->PackCRCs);
- IAlloc_Free(alloc, p->Folders);
- IAlloc_Free(alloc, p->Files);
- SzAr_Init(p);
-}
-
-
-void SzArEx_Init(CSzArEx *p)
-{
- SzAr_Init(&p->db);
- p->FolderStartPackStreamIndex = 0;
- p->PackStreamStartPositions = 0;
- p->FolderStartFileIndex = 0;
- p->FileIndexToFolderIndexMap = 0;
- p->FileNameOffsets = 0;
- Buf_Init(&p->FileNames);
-}
-
-void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
-{
- IAlloc_Free(alloc, p->FolderStartPackStreamIndex);
- IAlloc_Free(alloc, p->PackStreamStartPositions);
- IAlloc_Free(alloc, p->FolderStartFileIndex);
- IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
-
- IAlloc_Free(alloc, p->FileNameOffsets);
- Buf_Free(&p->FileNames, alloc);
-
- SzAr_Free(&p->db, alloc);
- SzArEx_Init(p);
-}
-
-/*
-UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
-{
- return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
-}
-
-UInt64 GetFilePackSize(int fileIndex) const
-{
- int folderIndex = FileIndexToFolderIndexMap[fileIndex];
- if (folderIndex >= 0)
- {
- const CSzFolder &folderInfo = Folders[folderIndex];
- if (FolderStartFileIndex[folderIndex] == fileIndex)
- return GetFolderFullPackSize(folderIndex);
- }
- return 0;
-}
-*/
-
-#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \
- if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }
-
-static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
-{
- UInt32 startPos = 0;
- UInt64 startPosSize = 0;
- UInt32 i;
- UInt32 folderIndex = 0;
- UInt32 indexInFolder = 0;
- MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc);
- for (i = 0; i < p->db.NumFolders; i++)
- {
- p->FolderStartPackStreamIndex[i] = startPos;
- startPos += p->db.Folders[i].NumPackStreams;
- }
-
- MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc);
-
- for (i = 0; i < p->db.NumPackStreams; i++)
- {
- p->PackStreamStartPositions[i] = startPosSize;
- startPosSize += p->db.PackSizes[i];
- }
-
- MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc);
- MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc);
-
- for (i = 0; i < p->db.NumFiles; i++)
- {
- CSzFileItem *file = p->db.Files + i;
- int emptyStream = !file->HasStream;
- if (emptyStream && indexInFolder == 0)
- {
- p->FileIndexToFolderIndexMap[i] = (UInt32)-1;
- continue;
- }
- if (indexInFolder == 0)
- {
- /*
- v3.13 incorrectly worked with empty folders
- v4.07: Loop for skipping empty folders
- */
- for (;;)
- {
- if (folderIndex >= p->db.NumFolders)
- return SZ_ERROR_ARCHIVE;
- p->FolderStartFileIndex[folderIndex] = i;
- if (p->db.Folders[folderIndex].NumUnpackStreams != 0)
- break;
- folderIndex++;
- }
- }
- p->FileIndexToFolderIndexMap[i] = folderIndex;
- if (emptyStream)
- continue;
- indexInFolder++;
- if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams)
- {
- folderIndex++;
- indexInFolder = 0;
- }
- }
- return SZ_OK;
-}
-
-
-UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)
-{
- return p->dataPos +
- p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
-}
-
-int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize)
-{
- UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex];
- CSzFolder *folder = p->db.Folders + folderIndex;
- UInt64 size = 0;
- UInt32 i;
- for (i = 0; i < folder->NumPackStreams; i++)
- {
- UInt64 t = size + p->db.PackSizes[packStreamIndex + i];
- if (t < size) /* check it */
- return SZ_ERROR_FAIL;
- size = t;
- }
- *resSize = size;
- return SZ_OK;
-}
-
-
-/*
-SRes SzReadTime(const CObjectVector<CBuf> &dataVector,
- CObjectVector<CSzFileItem> &files, UInt64 type)
-{
- CBoolVector boolVector;
- RINOK(ReadBoolVector2(files.Size(), boolVector))
-
- CStreamSwitch streamSwitch;
- RINOK(streamSwitch.Set(this, &dataVector));
-
- for (int i = 0; i < files.Size(); i++)
- {
- CSzFileItem &file = files[i];
- CArchiveFileTime fileTime;
- bool defined = boolVector[i];
- if (defined)
- {
- UInt32 low, high;
- RINOK(SzReadUInt32(low));
- RINOK(SzReadUInt32(high));
- fileTime.dwLowDateTime = low;
- fileTime.dwHighDateTime = high;
- }
- switch(type)
- {
- case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break;
- case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break;
- case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break;
- }
- }
- return SZ_OK;
-}
-*/
-
-static int TestSignatureCandidate(Byte *testBytes)
-{
- size_t i;
- for (i = 0; i < k7zSignatureSize; i++)
- if (testBytes[i] != k7zSignature[i])
- return 0;
- return 1;
-}
-
-typedef struct _CSzState
-{
- Byte *Data;
- size_t Size;
-}CSzData;
-
-static SRes SzReadByte(CSzData *sd, Byte *b)
-{
- if (sd->Size == 0)
- return SZ_ERROR_ARCHIVE;
- sd->Size--;
- *b = *sd->Data++;
- return SZ_OK;
-}
-
-static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size)
-{
- size_t i;
- for (i = 0; i < size; i++)
- {
- RINOK(SzReadByte(sd, data + i));
- }
- return SZ_OK;
-}
-
-static SRes SzReadUInt32(CSzData *sd, UInt32 *value)
-{
- int i;
- *value = 0;
- for (i = 0; i < 4; i++)
- {
- Byte b;
- RINOK(SzReadByte(sd, &b));
- *value |= ((UInt32)(b) << (8 * i));
- }
- return SZ_OK;
-}
-
-static SRes SzReadNumber(CSzData *sd, UInt64 *value)
-{
- Byte firstByte;
- Byte mask = 0x80;
- int i;
- RINOK(SzReadByte(sd, &firstByte));
- *value = 0;
- for (i = 0; i < 8; i++)
- {
- Byte b;
- if ((firstByte & mask) == 0)
- {
- UInt64 highPart = firstByte & (mask - 1);
- *value += (highPart << (8 * i));
- return SZ_OK;
- }
- RINOK(SzReadByte(sd, &b));
- *value |= ((UInt64)b << (8 * i));
- mask >>= 1;
- }
- return SZ_OK;
-}
-
-static SRes SzReadNumber32(CSzData *sd, UInt32 *value)
-{
- UInt64 value64;
- RINOK(SzReadNumber(sd, &value64));
- if (value64 >= 0x80000000)
- return SZ_ERROR_UNSUPPORTED;
- if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
- return SZ_ERROR_UNSUPPORTED;
- *value = (UInt32)value64;
- return SZ_OK;
-}
-
-static SRes SzReadID(CSzData *sd, UInt64 *value)
-{
- return SzReadNumber(sd, value);
-}
-
-static SRes SzSkeepDataSize(CSzData *sd, UInt64 size)
-{
- if (size > sd->Size)
- return SZ_ERROR_ARCHIVE;
- sd->Size -= (size_t)size;
- sd->Data += (size_t)size;
- return SZ_OK;
-}
-
-static SRes SzSkeepData(CSzData *sd)
-{
- UInt64 size;
- RINOK(SzReadNumber(sd, &size));
- return SzSkeepDataSize(sd, size);
-}
-
-static SRes SzReadArchiveProperties(CSzData *sd)
-{
- for (;;)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- break;
- SzSkeepData(sd);
- }
- return SZ_OK;
-}
-
-static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute)
-{
- for (;;)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == attribute)
- return SZ_OK;
- if (type == k7zIdEnd)
- return SZ_ERROR_ARCHIVE;
- RINOK(SzSkeepData(sd));
- }
-}
-
-static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
-{
- Byte b = 0;
- Byte mask = 0;
- size_t i;
- MY_ALLOC(Byte, *v, numItems, alloc);
- for (i = 0; i < numItems; i++)
- {
- if (mask == 0)
- {
- RINOK(SzReadByte(sd, &b));
- mask = 0x80;
- }
- (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
- mask >>= 1;
- }
- return SZ_OK;
-}
-
-static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
-{
- Byte allAreDefined;
- size_t i;
- RINOK(SzReadByte(sd, &allAreDefined));
- if (allAreDefined == 0)
- return SzReadBoolVector(sd, numItems, v, alloc);
- MY_ALLOC(Byte, *v, numItems, alloc);
- for (i = 0; i < numItems; i++)
- (*v)[i] = 1;
- return SZ_OK;
-}
-
-static SRes SzReadHashDigests(
- CSzData *sd,
- size_t numItems,
- Byte **digestsDefined,
- UInt32 **digests,
- ISzAlloc *alloc)
-{
- size_t i;
- RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc));
- MY_ALLOC(UInt32, *digests, numItems, alloc);
- for (i = 0; i < numItems; i++)
- if ((*digestsDefined)[i])
- {
- RINOK(SzReadUInt32(sd, (*digests) + i));
- }
- return SZ_OK;
-}
-
-static SRes SzReadPackInfo(
- CSzData *sd,
- UInt64 *dataOffset,
- UInt32 *numPackStreams,
- UInt64 **packSizes,
- Byte **packCRCsDefined,
- UInt32 **packCRCs,
- ISzAlloc *alloc)
-{
- UInt32 i;
- RINOK(SzReadNumber(sd, dataOffset));
- RINOK(SzReadNumber32(sd, numPackStreams));
-
- RINOK(SzWaitAttribute(sd, k7zIdSize));
-
- MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc);
-
- for (i = 0; i < *numPackStreams; i++)
- {
- RINOK(SzReadNumber(sd, (*packSizes) + i));
- }
-
- for (;;)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- break;
- if (type == k7zIdCRC)
- {
- RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));
- continue;
- }
- RINOK(SzSkeepData(sd));
- }
- if (*packCRCsDefined == 0)
- {
- MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc);
- MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc);
- for (i = 0; i < *numPackStreams; i++)
- {
- (*packCRCsDefined)[i] = 0;
- (*packCRCs)[i] = 0;
- }
- }
- return SZ_OK;
-}
-
-static SRes SzReadSwitch(CSzData *sd)
-{
- Byte external;
- RINOK(SzReadByte(sd, &external));
- return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
-}
-
-static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
-{
- UInt32 numCoders, numBindPairs, numPackStreams, i;
- UInt32 numInStreams = 0, numOutStreams = 0;
-
- RINOK(SzReadNumber32(sd, &numCoders));
- if (numCoders > NUM_FOLDER_CODERS_MAX)
- return SZ_ERROR_UNSUPPORTED;
- folder->NumCoders = numCoders;
-
- MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc);
-
- for (i = 0; i < numCoders; i++)
- SzCoderInfo_Init(folder->Coders + i);
-
- for (i = 0; i < numCoders; i++)
- {
- Byte mainByte;
- CSzCoderInfo *coder = folder->Coders + i;
- {
- unsigned idSize, j;
- Byte longID[15];
- RINOK(SzReadByte(sd, &mainByte));
- idSize = (unsigned)(mainByte & 0xF);
- RINOK(SzReadBytes(sd, longID, idSize));
- if (idSize > sizeof(coder->MethodID))
- return SZ_ERROR_UNSUPPORTED;
- coder->MethodID = 0;
- for (j = 0; j < idSize; j++)
- coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j);
-
- if ((mainByte & 0x10) != 0)
- {
- RINOK(SzReadNumber32(sd, &coder->NumInStreams));
- RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
- if (coder->NumInStreams > NUM_CODER_STREAMS_MAX ||
- coder->NumOutStreams > NUM_CODER_STREAMS_MAX)
- return SZ_ERROR_UNSUPPORTED;
- }
- else
- {
- coder->NumInStreams = 1;
- coder->NumOutStreams = 1;
- }
- if ((mainByte & 0x20) != 0)
- {
- UInt64 propertiesSize = 0;
- RINOK(SzReadNumber(sd, &propertiesSize));
- if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc))
- return SZ_ERROR_MEM;
- RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize));
- }
- }
- while ((mainByte & 0x80) != 0)
- {
- RINOK(SzReadByte(sd, &mainByte));
- RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
- if ((mainByte & 0x10) != 0)
- {
- UInt32 n;
- RINOK(SzReadNumber32(sd, &n));
- RINOK(SzReadNumber32(sd, &n));
- }
- if ((mainByte & 0x20) != 0)
- {
- UInt64 propertiesSize = 0;
- RINOK(SzReadNumber(sd, &propertiesSize));
- RINOK(SzSkeepDataSize(sd, propertiesSize));
- }
- }
- numInStreams += coder->NumInStreams;
- numOutStreams += coder->NumOutStreams;
- }
-
- if (numOutStreams == 0)
- return SZ_ERROR_UNSUPPORTED;
-
- folder->NumBindPairs = numBindPairs = numOutStreams - 1;
- MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);
-
- for (i = 0; i < numBindPairs; i++)
- {
- CSzBindPair *bp = folder->BindPairs + i;
- RINOK(SzReadNumber32(sd, &bp->InIndex));
- RINOK(SzReadNumber32(sd, &bp->OutIndex));
- }
-
- if (numInStreams < numBindPairs)
- return SZ_ERROR_UNSUPPORTED;
-
- folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
- MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc);
-
- if (numPackStreams == 1)
- {
- for (i = 0; i < numInStreams ; i++)
- if (SzFolder_FindBindPairForInStream(folder, i) < 0)
- break;
- if (i == numInStreams)
- return SZ_ERROR_UNSUPPORTED;
- folder->PackStreams[0] = i;
- }
- else
- for (i = 0; i < numPackStreams; i++)
- {
- RINOK(SzReadNumber32(sd, folder->PackStreams + i));
- }
- return SZ_OK;
-}
-
-static SRes SzReadUnpackInfo(
- CSzData *sd,
- UInt32 *numFolders,
- CSzFolder **folders, /* for alloc */
- ISzAlloc *alloc,
- ISzAlloc *allocTemp)
-{
- UInt32 i;
- RINOK(SzWaitAttribute(sd, k7zIdFolder));
- RINOK(SzReadNumber32(sd, numFolders));
- {
- RINOK(SzReadSwitch(sd));
-
- MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc);
-
- for (i = 0; i < *numFolders; i++)
- SzFolder_Init((*folders) + i);
-
- for (i = 0; i < *numFolders; i++)
- {
- RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc));
- }
- }
-
- RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));
-
- for (i = 0; i < *numFolders; i++)
- {
- UInt32 j;
- CSzFolder *folder = (*folders) + i;
- UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);
-
- MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc);
-
- for (j = 0; j < numOutStreams; j++)
- {
- RINOK(SzReadNumber(sd, folder->UnpackSizes + j));
- }
- }
-
- for (;;)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- return SZ_OK;
- if (type == k7zIdCRC)
- {
- SRes res;
- Byte *crcsDefined = 0;
- UInt32 *crcs = 0;
- res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);
- if (res == SZ_OK)
- {
- for (i = 0; i < *numFolders; i++)
- {
- CSzFolder *folder = (*folders) + i;
- folder->UnpackCRCDefined = crcsDefined[i];
- folder->UnpackCRC = crcs[i];
- }
- }
- IAlloc_Free(allocTemp, crcs);
- IAlloc_Free(allocTemp, crcsDefined);
- RINOK(res);
- continue;
- }
- RINOK(SzSkeepData(sd));
- }
-}
-
-static SRes SzReadSubStreamsInfo(
- CSzData *sd,
- UInt32 numFolders,
- CSzFolder *folders,
- UInt32 *numUnpackStreams,
- UInt64 **unpackSizes,
- Byte **digestsDefined,
- UInt32 **digests,
- ISzAlloc *allocTemp)
-{
- UInt64 type = 0;
- UInt32 i;
- UInt32 si = 0;
- UInt32 numDigests = 0;
-
- for (i = 0; i < numFolders; i++)
- folders[i].NumUnpackStreams = 1;
- *numUnpackStreams = numFolders;
-
- for (;;)
- {
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdNumUnpackStream)
- {
- *numUnpackStreams = 0;
- for (i = 0; i < numFolders; i++)
- {
- UInt32 numStreams;
- RINOK(SzReadNumber32(sd, &numStreams));
- folders[i].NumUnpackStreams = numStreams;
- *numUnpackStreams += numStreams;
- }
- continue;
- }
- if (type == k7zIdCRC || type == k7zIdSize)
- break;
- if (type == k7zIdEnd)
- break;
- RINOK(SzSkeepData(sd));
- }
-
- if (*numUnpackStreams == 0)
- {
- *unpackSizes = 0;
- *digestsDefined = 0;
- *digests = 0;
- }
- else
- {
- *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64));
- RINOM(*unpackSizes);
- *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte));
- RINOM(*digestsDefined);
- *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32));
- RINOM(*digests);
- }
-
- for (i = 0; i < numFolders; i++)
- {
- /*
- v3.13 incorrectly worked with empty folders
- v4.07: we check that folder is empty
- */
- UInt64 sum = 0;
- UInt32 j;
- UInt32 numSubstreams = folders[i].NumUnpackStreams;
- if (numSubstreams == 0)
- continue;
- if (type == k7zIdSize)
- for (j = 1; j < numSubstreams; j++)
- {
- UInt64 size;
- RINOK(SzReadNumber(sd, &size));
- (*unpackSizes)[si++] = size;
- sum += size;
- }
- (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
- }
- if (type == k7zIdSize)
- {
- RINOK(SzReadID(sd, &type));
- }
-
- for (i = 0; i < *numUnpackStreams; i++)
- {
- (*digestsDefined)[i] = 0;
- (*digests)[i] = 0;
- }
-
-
- for (i = 0; i < numFolders; i++)
- {
- UInt32 numSubstreams = folders[i].NumUnpackStreams;
- if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
- numDigests += numSubstreams;
- }
-
-
- si = 0;
- for (;;)
- {
- if (type == k7zIdCRC)
- {
- int digestIndex = 0;
- Byte *digestsDefined2 = 0;
- UInt32 *digests2 = 0;
- SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);
- if (res == SZ_OK)
- {
- for (i = 0; i < numFolders; i++)
- {
- CSzFolder *folder = folders + i;
- UInt32 numSubstreams = folder->NumUnpackStreams;
- if (numSubstreams == 1 && folder->UnpackCRCDefined)
- {
- (*digestsDefined)[si] = 1;
- (*digests)[si] = folder->UnpackCRC;
- si++;
- }
- else
- {
- UInt32 j;
- for (j = 0; j < numSubstreams; j++, digestIndex++)
- {
- (*digestsDefined)[si] = digestsDefined2[digestIndex];
- (*digests)[si] = digests2[digestIndex];
- si++;
- }
- }
- }
- }
- IAlloc_Free(allocTemp, digestsDefined2);
- IAlloc_Free(allocTemp, digests2);
- RINOK(res);
- }
- else if (type == k7zIdEnd)
- return SZ_OK;
- else
- {
- RINOK(SzSkeepData(sd));
- }
- RINOK(SzReadID(sd, &type));
- }
-}
-
-
-static SRes SzReadStreamsInfo(
- CSzData *sd,
- UInt64 *dataOffset,
- CSzAr *p,
- UInt32 *numUnpackStreams,
- UInt64 **unpackSizes, /* allocTemp */
- Byte **digestsDefined, /* allocTemp */
- UInt32 **digests, /* allocTemp */
- ISzAlloc *alloc,
- ISzAlloc *allocTemp)
-{
- for (;;)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if ((UInt64)(int)type != type)
- return SZ_ERROR_UNSUPPORTED;
- switch((int)type)
- {
- case k7zIdEnd:
- return SZ_OK;
- case k7zIdPackInfo:
- {
- RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams,
- &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc));
- break;
- }
- case k7zIdUnpackInfo:
- {
- RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp));
- break;
- }
- case k7zIdSubStreamsInfo:
- {
- RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,
- numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp));
- break;
- }
- default:
- return SZ_ERROR_UNSUPPORTED;
- }
- }
-}
-
-size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
-{
- size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
- if (dest != 0)
- {
- size_t i;
- const Byte *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2);
- for (i = 0; i < len; i++)
- dest[i] = GetUi16(src + i * 2);
- }
- return len;
-}
-
-static SRes SzReadFileNames(const Byte *p, size_t size, UInt32 numFiles, size_t *sizes)
-{
- UInt32 i;
- size_t pos = 0;
- for (i = 0; i < numFiles; i++)
- {
- sizes[i] = pos;
- for (;;)
- {
- if (pos >= size)
- return SZ_ERROR_ARCHIVE;
- if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0)
- break;
- pos++;
- }
- pos++;
- }
- sizes[i] = pos;
- return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
-}
-
-static SRes SzReadHeader2(
- CSzArEx *p, /* allocMain */
- CSzData *sd,
- UInt64 **unpackSizes, /* allocTemp */
- Byte **digestsDefined, /* allocTemp */
- UInt32 **digests, /* allocTemp */
- Byte **emptyStreamVector, /* allocTemp */
- Byte **emptyFileVector, /* allocTemp */
- Byte **lwtVector, /* allocTemp */
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- UInt64 type;
- UInt32 numUnpackStreams = 0;
- UInt32 numFiles = 0;
- CSzFileItem *files = 0;
- UInt32 numEmptyStreams = 0;
- UInt32 i;
-
- RINOK(SzReadID(sd, &type));
-
- if (type == k7zIdArchiveProperties)
- {
- RINOK(SzReadArchiveProperties(sd));
- RINOK(SzReadID(sd, &type));
- }
-
-
- if (type == k7zIdMainStreamsInfo)
- {
- RINOK(SzReadStreamsInfo(sd,
- &p->dataPos,
- &p->db,
- &numUnpackStreams,
- unpackSizes,
- digestsDefined,
- digests, allocMain, allocTemp));
- p->dataPos += p->startPosAfterHeader;
- RINOK(SzReadID(sd, &type));
- }
-
- if (type == k7zIdEnd)
- return SZ_OK;
- if (type != k7zIdFilesInfo)
- return SZ_ERROR_ARCHIVE;
-
- RINOK(SzReadNumber32(sd, &numFiles));
- p->db.NumFiles = numFiles;
-
- MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain);
-
- p->db.Files = files;
- for (i = 0; i < numFiles; i++)
- SzFile_Init(files + i);
-
- for (;;)
- {
- UInt64 type;
- UInt64 size;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- break;
- RINOK(SzReadNumber(sd, &size));
- if (size > sd->Size)
- return SZ_ERROR_ARCHIVE;
- if ((UInt64)(int)type != type)
- {
- RINOK(SzSkeepDataSize(sd, size));
- }
- else
- switch((int)type)
- {
- case k7zIdName:
- {
- size_t namesSize;
- RINOK(SzReadSwitch(sd));
- namesSize = (size_t)size - 1;
- if ((namesSize & 1) != 0)
- return SZ_ERROR_ARCHIVE;
- if (!Buf_Create(&p->FileNames, namesSize, allocMain))
- return SZ_ERROR_MEM;
- MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
- memcpy(p->FileNames.data, sd->Data, namesSize);
- RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets))
- RINOK(SzSkeepDataSize(sd, namesSize));
- break;
- }
- case k7zIdEmptyStream:
- {
- RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp));
- numEmptyStreams = 0;
- for (i = 0; i < numFiles; i++)
- if ((*emptyStreamVector)[i])
- numEmptyStreams++;
- break;
- }
- case k7zIdEmptyFile:
- {
- RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
- break;
- }
- case k7zIdWinAttributes:
- {
- RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
- RINOK(SzReadSwitch(sd));
- for (i = 0; i < numFiles; i++)
- {
- CSzFileItem *f = &files[i];
- Byte defined = (*lwtVector)[i];
- f->AttribDefined = defined;
- f->Attrib = 0;
- if (defined)
- {
- RINOK(SzReadUInt32(sd, &f->Attrib));
- }
- }
- IAlloc_Free(allocTemp, *lwtVector);
- *lwtVector = NULL;
- break;
- }
- case k7zIdMTime:
- {
- RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
- RINOK(SzReadSwitch(sd));
- for (i = 0; i < numFiles; i++)
- {
- CSzFileItem *f = &files[i];
- Byte defined = (*lwtVector)[i];
- f->MTimeDefined = defined;
- f->MTime.Low = f->MTime.High = 0;
- if (defined)
- {
- RINOK(SzReadUInt32(sd, &f->MTime.Low));
- RINOK(SzReadUInt32(sd, &f->MTime.High));
- }
- }
- IAlloc_Free(allocTemp, *lwtVector);
- *lwtVector = NULL;
- break;
- }
- default:
- {
- RINOK(SzSkeepDataSize(sd, size));
- }
- }
- }
-
- {
- UInt32 emptyFileIndex = 0;
- UInt32 sizeIndex = 0;
- for (i = 0; i < numFiles; i++)
- {
- CSzFileItem *file = files + i;
- file->IsAnti = 0;
- if (*emptyStreamVector == 0)
- file->HasStream = 1;
- else
- file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
- if (file->HasStream)
- {
- file->IsDir = 0;
- file->Size = (*unpackSizes)[sizeIndex];
- file->Crc = (*digests)[sizeIndex];
- file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex];
- sizeIndex++;
- }
- else
- {
- if (*emptyFileVector == 0)
- file->IsDir = 1;
- else
- file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
- emptyFileIndex++;
- file->Size = 0;
- file->Crc = 0;
- file->CrcDefined = 0;
- }
- }
- }
- return SzArEx_Fill(p, allocMain);
-}
-
-static SRes SzReadHeader(
- CSzArEx *p,
- CSzData *sd,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- UInt64 *unpackSizes = 0;
- Byte *digestsDefined = 0;
- UInt32 *digests = 0;
- Byte *emptyStreamVector = 0;
- Byte *emptyFileVector = 0;
- Byte *lwtVector = 0;
- SRes res = SzReadHeader2(p, sd,
- &unpackSizes, &digestsDefined, &digests,
- &emptyStreamVector, &emptyFileVector, &lwtVector,
- allocMain, allocTemp);
- IAlloc_Free(allocTemp, unpackSizes);
- IAlloc_Free(allocTemp, digestsDefined);
- IAlloc_Free(allocTemp, digests);
- IAlloc_Free(allocTemp, emptyStreamVector);
- IAlloc_Free(allocTemp, emptyFileVector);
- IAlloc_Free(allocTemp, lwtVector);
- return res;
-}
-
-static SRes SzReadAndDecodePackedStreams2(
- ILookInStream *inStream,
- CSzData *sd,
- CBuf *outBuffer,
- UInt64 baseOffset,
- CSzAr *p,
- UInt64 **unpackSizes,
- Byte **digestsDefined,
- UInt32 **digests,
- ISzAlloc *allocTemp)
-{
-
- UInt32 numUnpackStreams = 0;
- UInt64 dataStartPos;
- CSzFolder *folder;
- UInt64 unpackSize;
- SRes res;
-
- RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
- &numUnpackStreams, unpackSizes, digestsDefined, digests,
- allocTemp, allocTemp));
-
- dataStartPos += baseOffset;
- if (p->NumFolders != 1)
- return SZ_ERROR_ARCHIVE;
-
- folder = p->Folders;
- unpackSize = SzFolder_GetUnpackSize(folder);
-
- RINOK(LookInStream_SeekTo(inStream, dataStartPos));
-
- if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
- return SZ_ERROR_MEM;
-
- res = SzFolder_Decode(folder, p->PackSizes,
- inStream, dataStartPos,
- outBuffer->data, (size_t)unpackSize, allocTemp);
- RINOK(res);
- if (folder->UnpackCRCDefined)
- if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC)
- return SZ_ERROR_CRC;
- return SZ_OK;
-}
-
-static SRes SzReadAndDecodePackedStreams(
- ILookInStream *inStream,
- CSzData *sd,
- CBuf *outBuffer,
- UInt64 baseOffset,
- ISzAlloc *allocTemp)
-{
- CSzAr p;
- UInt64 *unpackSizes = 0;
- Byte *digestsDefined = 0;
- UInt32 *digests = 0;
- SRes res;
- SzAr_Init(&p);
- res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
- &p, &unpackSizes, &digestsDefined, &digests,
- allocTemp);
- SzAr_Free(&p, allocTemp);
- IAlloc_Free(allocTemp, unpackSizes);
- IAlloc_Free(allocTemp, digestsDefined);
- IAlloc_Free(allocTemp, digests);
- return res;
-}
-
-static SRes SzArEx_Open2(
- CSzArEx *p,
- ILookInStream *inStream,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- Byte header[k7zStartHeaderSize];
- Int64 startArcPos;
- UInt64 nextHeaderOffset, nextHeaderSize;
- size_t nextHeaderSizeT;
- UInt32 nextHeaderCRC;
- CBuf buffer;
- SRes res;
-
- startArcPos = 0;
- RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
-
- RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
-
- if (!TestSignatureCandidate(header))
- return SZ_ERROR_NO_ARCHIVE;
- if (header[6] != k7zMajorVersion)
- return SZ_ERROR_UNSUPPORTED;
-
- nextHeaderOffset = GetUi64(header + 12);
- nextHeaderSize = GetUi64(header + 20);
- nextHeaderCRC = GetUi32(header + 28);
-
- p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;
-
- if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
- return SZ_ERROR_CRC;
-
- nextHeaderSizeT = (size_t)nextHeaderSize;
- if (nextHeaderSizeT != nextHeaderSize)
- return SZ_ERROR_MEM;
- if (nextHeaderSizeT == 0)
- return SZ_OK;
- if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
- nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
- return SZ_ERROR_NO_ARCHIVE;
-
- {
- Int64 pos = 0;
- RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
- if ((UInt64)pos < startArcPos + nextHeaderOffset ||
- (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
- (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
- return SZ_ERROR_INPUT_EOF;
- }
-
- RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));
-
- if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
- return SZ_ERROR_MEM;
-
- res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT);
- if (res == SZ_OK)
- {
- res = SZ_ERROR_ARCHIVE;
- if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)
- {
- CSzData sd;
- UInt64 type;
- sd.Data = buffer.data;
- sd.Size = buffer.size;
- res = SzReadID(&sd, &type);
- if (res == SZ_OK)
- {
- if (type == k7zIdEncodedHeader)
- {
- CBuf outBuffer;
- Buf_Init(&outBuffer);
- res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp);
- if (res != SZ_OK)
- Buf_Free(&outBuffer, allocTemp);
- else
- {
- Buf_Free(&buffer, allocTemp);
- buffer.data = outBuffer.data;
- buffer.size = outBuffer.size;
- sd.Data = buffer.data;
- sd.Size = buffer.size;
- res = SzReadID(&sd, &type);
- }
- }
- }
- if (res == SZ_OK)
- {
- if (type == k7zIdHeader)
- res = SzReadHeader(p, &sd, allocMain, allocTemp);
- else
- res = SZ_ERROR_UNSUPPORTED;
- }
- }
- }
- Buf_Free(&buffer, allocTemp);
- return res;
-}
-
-SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp)
-{
- SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
- if (res != SZ_OK)
- SzArEx_Free(p, allocMain);
- return res;
-}
-
-SRes SzArEx_Extract(
- const CSzArEx *p,
- ILookInStream *inStream,
- UInt32 fileIndex,
- UInt32 *blockIndex,
- Byte **outBuffer,
- size_t *outBufferSize,
- size_t *offset,
- size_t *outSizeProcessed,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
- SRes res = SZ_OK;
- *offset = 0;
- *outSizeProcessed = 0;
- if (folderIndex == (UInt32)-1)
- {
- IAlloc_Free(allocMain, *outBuffer);
- *blockIndex = folderIndex;
- *outBuffer = 0;
- *outBufferSize = 0;
- return SZ_OK;
- }
-
- if (*outBuffer == 0 || *blockIndex != folderIndex)
- {
- CSzFolder *folder = p->db.Folders + folderIndex;
- UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
- size_t unpackSize = (size_t)unpackSizeSpec;
- UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
-
- if (unpackSize != unpackSizeSpec)
- return SZ_ERROR_MEM;
- *blockIndex = folderIndex;
- IAlloc_Free(allocMain, *outBuffer);
- *outBuffer = 0;
-
- RINOK(LookInStream_SeekTo(inStream, startOffset));
-
- if (res == SZ_OK)
- {
- *outBufferSize = unpackSize;
- if (unpackSize != 0)
- {
- *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
- if (*outBuffer == 0)
- res = SZ_ERROR_MEM;
- }
- if (res == SZ_OK)
- {
- res = SzFolder_Decode(folder,
- p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex],
- inStream, startOffset,
- *outBuffer, unpackSize, allocTemp);
- if (res == SZ_OK)
- {
- if (folder->UnpackCRCDefined)
- {
- if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
- res = SZ_ERROR_CRC;
- }
- }
- }
- }
- }
- if (res == SZ_OK)
- {
- UInt32 i;
- CSzFileItem *fileItem = p->db.Files + fileIndex;
- *offset = 0;
- for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
- *offset += (UInt32)p->db.Files[i].Size;
- *outSizeProcessed = (size_t)fileItem->Size;
- if (*offset + *outSizeProcessed > *outBufferSize)
- return SZ_ERROR_FAIL;
- if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc)
- res = SZ_ERROR_CRC;
- }
- return res;
-}
diff --git a/src/libs/7zip/win/C/7zStream.c b/src/libs/7zip/win/C/7zStream.c
index 0ebb7b5f9..88f9c42b1 100644
--- a/src/libs/7zip/win/C/7zStream.c
+++ b/src/libs/7zip/win/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/win/C/7zTypes.h
index 7732c240c..778413ef4 100644
--- a/src/libs/7zip/unix/C/Types.h
+++ b/src/libs/7zip/win/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/win/C/7zVersion.h b/src/libs/7zip/win/C/7zVersion.h
index 9d99c5dff..475918352 100644
--- a/src/libs/7zip/win/C/7zVersion.h
+++ b/src/libs/7zip/win/C/7zVersion.h
@@ -1,7 +1,10 @@
#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
diff --git a/src/libs/7zip/win/C/Alloc.c b/src/libs/7zip/win/C/Alloc.c
index 358a7b526..1f3f6c661 100644
--- a/src/libs/7zip/win/C/Alloc.c
+++ b/src/libs/7zip/win/C/Alloc.c
@@ -1,7 +1,7 @@
/* Alloc.c -- Memory allocation functions
-2008-09-24
-Igor Pavlov
-Public domain */
+2013-11-12 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#ifdef _WIN32
#include <windows.h>
@@ -99,7 +99,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))
{
@@ -118,7 +118,7 @@ void BigFree(void *address)
if (address != 0)
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
#endif
-
+
if (address == 0)
return;
VirtualFree(address, 0, MEM_RELEASE);
diff --git a/src/libs/7zip/win/C/Bcj2.c b/src/libs/7zip/win/C/Bcj2.c
deleted file mode 100644
index 20199ce56..000000000
--- a/src/libs/7zip/win/C/Bcj2.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Bcj2.c -- Converter for x86 code (BCJ2)
-2008-10-04 : Igor Pavlov : Public domain */
-
-#include "Bcj2.h"
-
-#ifdef _LZMA_PROB32
-#define CProb UInt32
-#else
-#define CProb UInt16
-#endif
-
-#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
-#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
-
-#define kNumTopBits 24
-#define kTopValue ((UInt32)1 << kNumTopBits)
-
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
-#define kNumMoveBits 5
-
-#define RC_READ_BYTE (*buffer++)
-#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
-#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
- { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
-
-#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
-
-#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
-#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
-#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
-
-int Bcj2_Decode(
- const Byte *buf0, SizeT size0,
- const Byte *buf1, SizeT size1,
- const Byte *buf2, SizeT size2,
- const Byte *buf3, SizeT size3,
- Byte *outBuf, SizeT outSize)
-{
- CProb p[256 + 2];
- SizeT inPos = 0, outPos = 0;
-
- const Byte *buffer, *bufferLim;
- UInt32 range, code;
- Byte prevByte = 0;
-
- unsigned int i;
- for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
- p[i] = kBitModelTotal >> 1;
-
- buffer = buf3;
- bufferLim = buffer + size3;
- RC_INIT2
-
- if (outSize == 0)
- return SZ_OK;
-
- for (;;)
- {
- Byte b;
- CProb *prob;
- UInt32 bound;
- UInt32 ttt;
-
- SizeT limit = size0 - inPos;
- if (outSize - outPos < limit)
- limit = outSize - outPos;
- while (limit != 0)
- {
- Byte b = buf0[inPos];
- outBuf[outPos++] = b;
- if (IsJ(prevByte, b))
- break;
- inPos++;
- prevByte = b;
- limit--;
- }
-
- if (limit == 0 || outPos == outSize)
- break;
-
- b = buf0[inPos++];
-
- if (b == 0xE8)
- prob = p + prevByte;
- else if (b == 0xE9)
- prob = p + 256;
- else
- prob = p + 257;
-
- IF_BIT_0(prob)
- {
- UPDATE_0(prob)
- prevByte = b;
- }
- else
- {
- UInt32 dest;
- const Byte *v;
- UPDATE_1(prob)
- if (b == 0xE8)
- {
- v = buf1;
- if (size1 < 4)
- return SZ_ERROR_DATA;
- buf1 += 4;
- size1 -= 4;
- }
- else
- {
- v = buf2;
- if (size2 < 4)
- return SZ_ERROR_DATA;
- buf2 += 4;
- size2 -= 4;
- }
- dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
- ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
- outBuf[outPos++] = (Byte)dest;
- if (outPos == outSize)
- break;
- outBuf[outPos++] = (Byte)(dest >> 8);
- if (outPos == outSize)
- break;
- outBuf[outPos++] = (Byte)(dest >> 16);
- if (outPos == outSize)
- break;
- outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
- }
- }
- return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
-}
diff --git a/src/libs/7zip/win/C/Bcj2.h b/src/libs/7zip/win/C/Bcj2.h
deleted file mode 100644
index dbc054148..000000000
--- a/src/libs/7zip/win/C/Bcj2.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Bcj2.h -- Converter for x86 code (BCJ2)
-2009-02-07 : Igor Pavlov : Public domain */
-
-#ifndef __BCJ2_H
-#define __BCJ2_H
-
-#include "Types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
-Conditions:
- outSize <= FullOutputSize,
- where FullOutputSize is full size of output stream of x86_2 filter.
-
-If buf0 overlaps outBuf, there are two required conditions:
- 1) (buf0 >= outBuf)
- 2) (buf0 + size0 >= outBuf + FullOutputSize).
-
-Returns:
- SZ_OK
- SZ_ERROR_DATA - Data error
-*/
-
-int Bcj2_Decode(
- const Byte *buf0, SizeT size0,
- const Byte *buf1, SizeT size1,
- const Byte *buf2, SizeT size2,
- const Byte *buf3, SizeT size3,
- Byte *outBuf, SizeT outSize);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/libs/7zip/win/C/Bra.c b/src/libs/7zip/win/C/Bra.c
index 2e47b1413..33f7a391c 100644
--- a/src/libs/7zip/win/C/Bra.c
+++ b/src/libs/7zip/win/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/win/C/Bra.h b/src/libs/7zip/win/C/Bra.h
index 5748c1c05..184c291a7 100644
--- a/src/libs/7zip/win/C/Bra.h
+++ b/src/libs/7zip/win/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/win/C/Bra86.c b/src/libs/7zip/win/C/Bra86.c
index 1ee0e709b..6db15e7ec 100644
--- a/src/libs/7zip/win/C/Bra86.c
+++ b/src/libs/7zip/win/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/win/C/BraIA64.c b/src/libs/7zip/win/C/BraIA64.c
index 0b4ee85bc..aa1a44e1e 100644
--- a/src/libs/7zip/win/C/BraIA64.c
+++ b/src/libs/7zip/win/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/win/C/C.pri b/src/libs/7zip/win/C/C.pri
new file mode 100644
index 000000000..23d688642
--- /dev/null
+++ b/src/libs/7zip/win/C/C.pri
@@ -0,0 +1,48 @@
+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/CpuArch.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/win/C/Compiler.h b/src/libs/7zip/win/C/Compiler.h
new file mode 100644
index 000000000..6e964897e
--- /dev/null
+++ b/src/libs/7zip/win/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/win/C/CpuArch.c b/src/libs/7zip/win/C/CpuArch.c
index 260cc1f45..4feb028a2 100644
--- a/src/libs/7zip/win/C/CpuArch.c
+++ b/src/libs/7zip/win/C/CpuArch.c
@@ -1,5 +1,7 @@
/* CpuArch.c -- CPU specific code
-2010-10-26: Igor Pavlov : Public domain */
+2012-05-29: Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include "CpuArch.h"
@@ -9,6 +11,10 @@
#define USE_ASM
#endif
+#if !defined(USE_ASM) && _MSC_VER >= 1500
+#include <intrin.h>
+#endif
+
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
static UInt32 CheckFlag(UInt32 flag)
{
@@ -73,15 +79,23 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#else
__asm__ __volatile__ (
+ #if defined(MY_CPU_X86) && defined(__PIC__)
+ "mov %%ebx, %%edi;"
+ "cpuid;"
+ "xchgl %%ebx, %%edi;"
+ : "=a" (*a) ,
+ "=D" (*b) ,
+ #else
"cpuid"
: "=a" (*a) ,
"=b" (*b) ,
+ #endif
"=c" (*c) ,
"=d" (*d)
: "0" (function)) ;
#endif
-
+
#else
int CPUInfo[4];
@@ -135,7 +149,14 @@ Bool CPU_Is_InOrder()
firm = x86cpuid_GetFirm(&p);
switch (firm)
{
- case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
+ case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
+ /* Atom CPU */
+ model == 0x100C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
+ || model == 0x2006 /* 45 nm, Z6xx */
+ || model == 0x2007 /* 32 nm, Z2460 */
+ || model == 0x3005 /* 32 nm, Z2760 */
+ || model == 0x3006 /* 32 nm, N2xxx, D2xxx */
+ )));
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
}
@@ -143,6 +164,7 @@ Bool CPU_Is_InOrder()
}
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
+#include <windows.h>
static Bool CPU_Sys_Is_SSE_Supported()
{
OSVERSIONINFO vi;
diff --git a/src/libs/7zip/win/C/CpuArch.h b/src/libs/7zip/win/C/CpuArch.h
index 01930c7e6..4fee00937 100644
--- a/src/libs/7zip/win/C/CpuArch.h
+++ b/src/libs/7zip/win/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
@@ -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,7 +118,7 @@ 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
diff --git a/src/libs/7zip/win/C/Delta.c b/src/libs/7zip/win/C/Delta.c
index 2b327f15f..e3edd21ed 100644
--- a/src/libs/7zip/win/C/Delta.c
+++ b/src/libs/7zip/win/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/win/C/Delta.h b/src/libs/7zip/win/C/Delta.h
index 0d4cd6274..2fa54ad67 100644
--- a/src/libs/7zip/win/C/Delta.h
+++ b/src/libs/7zip/win/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/win/C/LzFind.c b/src/libs/7zip/win/C/LzFind.c
index e3ecb0542..9a4d25b80 100644
--- a/src/libs/7zip/win/C/LzFind.c
+++ b/src/libs/7zip/win/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/win/C/LzFind.h b/src/libs/7zip/win/C/LzFind.h
index 010c4b92b..706143d25 100644
--- a/src/libs/7zip/win/C/LzFind.h
+++ b/src/libs/7zip/win/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/win/C/LzFindMt.c b/src/libs/7zip/win/C/LzFindMt.c
index aa41ed98a..8be0adaaf 100644
--- a/src/libs/7zip/win/C/LzFindMt.c
+++ b/src/libs/7zip/win/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/win/C/LzFindMt.h b/src/libs/7zip/win/C/LzFindMt.h
index b985af5fe..65cc12783 100644
--- a/src/libs/7zip/win/C/LzFindMt.h
+++ b/src/libs/7zip/win/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/win/C/Lzma2Dec.c b/src/libs/7zip/win/C/Lzma2Dec.c
index 7ea1cc953..e7dcc2725 100644
--- a/src/libs/7zip/win/C/Lzma2Dec.c
+++ b/src/libs/7zip/win/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/win/C/Lzma2Dec.h b/src/libs/7zip/win/C/Lzma2Dec.h
index 6bc07bbc1..367daf6b3 100644
--- a/src/libs/7zip/win/C/Lzma2Dec.h
+++ b/src/libs/7zip/win/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/win/C/Lzma2Enc.c b/src/libs/7zip/win/C/Lzma2Enc.c
index e97597f63..5d67cc344 100644
--- a/src/libs/7zip/win/C/Lzma2Enc.c
+++ b/src/libs/7zip/win/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/win/C/Lzma2Enc.h b/src/libs/7zip/win/C/Lzma2Enc.h
index 283525581..f409f184c 100644
--- a/src/libs/7zip/win/C/Lzma2Enc.h
+++ b/src/libs/7zip/win/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/win/C/Lzma86.h b/src/libs/7zip/win/C/Lzma86.h
deleted file mode 100644
index 6acbd888a..000000000
--- a/src/libs/7zip/win/C/Lzma86.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Lzma86.h -- LZMA + x86 (BCJ) Filter
-2009-08-14 : Igor Pavlov : Public domain */
-
-#ifndef __LZMA86_H
-#define __LZMA86_H
-
-#include "Types.h"
-
-EXTERN_C_BEGIN
-
-#define LZMA86_SIZE_OFFSET (1 + 5)
-#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
-
-/*
-It's an example for LZMA + x86 Filter use.
-You can use .lzma86 extension, if you write that stream to file.
-.lzma86 header adds one additional byte to standard .lzma header.
-.lzma86 header (14 bytes):
- Offset Size Description
- 0 1 = 0 - no filter, pure LZMA
- = 1 - x86 filter + LZMA
- 1 1 lc, lp and pb in encoded form
- 2 4 dictSize (little endian)
- 6 8 uncompressed size (little endian)
-
-
-Lzma86_Encode
--------------
-level - compression level: 0 <= level <= 9, the default value for "level" is 5.
-
-dictSize - The dictionary size in bytes. The maximum value is
- 128 MB = (1 << 27) bytes for 32-bit version
- 1 GB = (1 << 30) bytes for 64-bit version
- The default value is 16 MB = (1 << 24) bytes, for level = 5.
- It's recommended to use the dictionary that is larger than 4 KB and
- that can be calculated as (1 << N) or (3 << N) sizes.
- For better compression ratio dictSize must be >= inSize.
-
-filterMode:
- SZ_FILTER_NO - no Filter
- SZ_FILTER_YES - x86 Filter
- SZ_FILTER_AUTO - it tries both alternatives to select best.
- Encoder will use 2 or 3 passes:
- 2 passes when FILTER_NO provides better compression.
- 3 passes when FILTER_YES provides better compression.
-
-Lzma86Encode allocates Data with MyAlloc functions.
-RAM Requirements for compressing:
- RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize
- filterMode FilterBlockSize
- SZ_FILTER_NO 0
- SZ_FILTER_YES inSize
- SZ_FILTER_AUTO inSize
-
-
-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)
-*/
-
-enum ESzFilterMode
-{
- SZ_FILTER_NO,
- SZ_FILTER_YES,
- SZ_FILTER_AUTO
-};
-
-SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
- int level, UInt32 dictSize, int filterMode);
-
-
-/*
-Lzma86_GetUnpackSize:
- In:
- src - input data
- srcLen - input data size
- Out:
- unpackSize - size of uncompressed stream
- Return code:
- SZ_OK - OK
- SZ_ERROR_INPUT_EOF - Error in headers
-*/
-
-SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize);
-
-/*
-Lzma86_Decode:
- In:
- dest - output data
- destLen - output data size
- src - input data
- srcLen - input data size
- Out:
- destLen - processed output size
- srcLen - processed input size
- Return code:
- SZ_OK - OK
- SZ_ERROR_DATA - Data error
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_UNSUPPORTED - unsupported file
- SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer
-*/
-
-SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen);
-
-EXTERN_C_END
-
-#endif
diff --git a/src/libs/7zip/win/C/Lzma86Dec.c b/src/libs/7zip/win/C/Lzma86Dec.c
deleted file mode 100644
index fe7726097..000000000
--- a/src/libs/7zip/win/C/Lzma86Dec.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
-2009-08-14 : Igor Pavlov : Public domain */
-
-#include "Lzma86.h"
-
-#include "Alloc.h"
-#include "Bra.h"
-#include "LzmaDec.h"
-
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
-
-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)
-{
- ISzAlloc g_Alloc = { SzAlloc, SzFree };
- 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/win/C/Lzma86Enc.c b/src/libs/7zip/win/C/Lzma86Enc.c
deleted file mode 100644
index 2ea4ac2da..000000000
--- a/src/libs/7zip/win/C/Lzma86Enc.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
-2009-08-14 : Igor Pavlov : Public domain */
-
-#include <string.h>
-
-#include "Lzma86.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); }
-
-int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
- int level, UInt32 dictSize, int filterMode)
-{
- ISzAlloc g_Alloc = { SzAlloc, SzFree };
- 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/win/C/LzmaDec.c b/src/libs/7zip/win/C/LzmaDec.c
index 2036761bf..b1a2ad150 100644
--- a/src/libs/7zip/win/C/LzmaDec.c
+++ b/src/libs/7zip/win/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/win/C/LzmaDec.h b/src/libs/7zip/win/C/LzmaDec.h
index bf7f084ba..63efc351f 100644
--- a/src/libs/7zip/win/C/LzmaDec.h
+++ b/src/libs/7zip/win/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/win/C/LzmaEnc.c b/src/libs/7zip/win/C/LzmaEnc.c
index cf131388a..bf3cc2ddb 100644
--- a/src/libs/7zip/win/C/LzmaEnc.c
+++ b/src/libs/7zip/win/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/win/C/LzmaEnc.h b/src/libs/7zip/win/C/LzmaEnc.h
index 200d60eb8..cffe220bb 100644
--- a/src/libs/7zip/win/C/LzmaEnc.h
+++ b/src/libs/7zip/win/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/win/C/LzmaLib.c b/src/libs/7zip/win/C/LzmaLib.c
deleted file mode 100644
index 02a511857..000000000
--- a/src/libs/7zip/win/C/LzmaLib.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* LzmaLib.c -- LZMA library wrapper
-2008-08-05
-Igor Pavlov
-Public domain */
-
-#include "LzmaEnc.h"
-#include "LzmaDec.h"
-#include "Alloc.h"
-#include "LzmaLib.h"
-
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
-MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
- unsigned char *outProps, size_t *outPropsSize,
- int level, /* 0 <= level <= 9, default = 5 */
- unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
- int lc, /* 0 <= lc <= 8, default = 3 */
- int lp, /* 0 <= lp <= 4, default = 0 */
- int pb, /* 0 <= pb <= 4, default = 2 */
- int fb, /* 5 <= fb <= 273, default = 32 */
- int numThreads /* 1 or 2, default = 2 */
-)
-{
- CLzmaEncProps props;
- LzmaEncProps_Init(&props);
- props.level = level;
- props.dictSize = dictSize;
- props.lc = lc;
- props.lp = lp;
- props.pb = pb;
- props.fb = fb;
- props.numThreads = numThreads;
-
- return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0,
- NULL, &g_Alloc, &g_Alloc);
-}
-
-
-MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
- const unsigned char *props, size_t propsSize)
-{
- ELzmaStatus status;
- return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc);
-}
diff --git a/src/libs/7zip/win/C/LzmaLib.h b/src/libs/7zip/win/C/LzmaLib.h
deleted file mode 100644
index 76c99ce75..000000000
--- a/src/libs/7zip/win/C/LzmaLib.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/* LzmaLib.h -- LZMA library interface
-2009-04-07 : Igor Pavlov : Public domain */
-
-#ifndef __LZMA_LIB_H
-#define __LZMA_LIB_H
-
-#include "Types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MY_STDAPI int MY_STD_CALL
-
-#define LZMA_PROPS_SIZE 5
-
-/*
-RAM requirements for LZMA:
- for compression: (dictSize * 11.5 + 6 MB) + state_size
- for decompression: dictSize + state_size
- state_size = (4 + (1.5 << (lc + lp))) KB
- by default (lc=3, lp=0), state_size = 16 KB.
-
-LZMA properties (5 bytes) format
- Offset Size Description
- 0 1 lc, lp and pb in encoded form.
- 1 4 dictSize (little endian).
-*/
-
-/*
-LzmaCompress
-------------
-
-outPropsSize -
- In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
- Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
-
- LZMA Encoder will use defult values for any parameter, if it is
- -1 for any from: level, loc, lp, pb, fb, numThreads
- 0 for dictSize
-
-level - compression level: 0 <= level <= 9;
-
- level dictSize algo fb
- 0: 16 KB 0 32
- 1: 64 KB 0 32
- 2: 256 KB 0 32
- 3: 1 MB 0 32
- 4: 4 MB 0 32
- 5: 16 MB 1 32
- 6: 32 MB 1 32
- 7+: 64 MB 1 64
-
- The default value for "level" is 5.
-
- algo = 0 means fast method
- algo = 1 means normal method
-
-dictSize - The dictionary size in bytes. The maximum value is
- 128 MB = (1 << 27) bytes for 32-bit version
- 1 GB = (1 << 30) bytes for 64-bit version
- The default value is 16 MB = (1 << 24) bytes.
- It's recommended to use the dictionary that is larger than 4 KB and
- that can be calculated as (1 << N) or (3 << N) sizes.
-
-lc - The number of literal context bits (high bits of previous literal).
- It can be in the range from 0 to 8. The default value is 3.
- Sometimes lc=4 gives the gain for big files.
-
-lp - The number of literal pos bits (low bits of current position for literals).
- It can be in the range from 0 to 4. The default value is 0.
- The lp switch is intended for periodical data when the period is equal to 2^lp.
- For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's
- better to set lc=0, if you change lp switch.
-
-pb - The number of pos bits (low bits of current position).
- It can be in the range from 0 to 4. The default value is 2.
- The pb switch is intended for periodical data when the period is equal 2^pb.
-
-fb - Word size (the number of fast bytes).
- It can be in the range from 5 to 273. The default value is 32.
- Usually, a big number gives a little bit better compression ratio and
- slower compression process.
-
-numThreads - The number of thereads. 1 or 2. The default value is 2.
- Fast mode (algo = 0) can use only 1 thread.
-
-Out:
- destLen - processed output size
-Returns:
- 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)
-*/
-
-MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
- unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
- int level, /* 0 <= level <= 9, default = 5 */
- unsigned dictSize, /* default = (1 << 24) */
- int lc, /* 0 <= lc <= 8, default = 3 */
- int lp, /* 0 <= lp <= 4, default = 0 */
- int pb, /* 0 <= pb <= 4, default = 2 */
- int fb, /* 5 <= fb <= 273, default = 32 */
- int numThreads /* 1 or 2, default = 2 */
- );
-
-/*
-LzmaUncompress
---------------
-In:
- dest - output data
- destLen - output data size
- src - input data
- srcLen - input data size
-Out:
- destLen - processed output size
- srcLen - processed input size
-Returns:
- SZ_OK - OK
- SZ_ERROR_DATA - Data error
- SZ_ERROR_MEM - Memory allocation arror
- SZ_ERROR_UNSUPPORTED - Unsupported properties
- SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
-*/
-
-MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
- const unsigned char *props, size_t propsSize);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/libs/7zip/win/C/MtCoder.c b/src/libs/7zip/win/C/MtCoder.c
index 946fbbc70..3d4dd2d14 100644
--- a/src/libs/7zip/win/C/MtCoder.c
+++ b/src/libs/7zip/win/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/win/C/MtCoder.h b/src/libs/7zip/win/C/MtCoder.h
index f0f06da28..e2cbdc3ab 100644
--- a/src/libs/7zip/win/C/MtCoder.h
+++ b/src/libs/7zip/win/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/win/C/Precomp.h b/src/libs/7zip/win/C/Precomp.h
new file mode 100644
index 000000000..e8ff8b40e
--- /dev/null
+++ b/src/libs/7zip/win/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/win/C/RotateDefs.h b/src/libs/7zip/win/C/RotateDefs.h
index c3a1385ce..1b83e5ea1 100644
--- a/src/libs/7zip/win/C/RotateDefs.h
+++ b/src/libs/7zip/win/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/win/C/Sha256.c b/src/libs/7zip/win/C/Sha256.c
index eb4fc61fc..10df0874f 100644
--- a/src/libs/7zip/win/C/Sha256.c
+++ b/src/libs/7zip/win/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/win/C/Sha256.h b/src/libs/7zip/win/C/Sha256.h
index 530f513ec..3f455dbc0 100644
--- a/src/libs/7zip/win/C/Sha256.h
+++ b/src/libs/7zip/win/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/win/C/Threads.c b/src/libs/7zip/win/C/Threads.c
index 7af1da2e2..5c67a1e26 100644
--- a/src/libs/7zip/win/C/Threads.c
+++ b/src/libs/7zip/win/C/Threads.c
@@ -1,5 +1,7 @@
/* Threads.c -- multithreading library
-2009-09-20 : Igor Pavlov : Public domain */
+2013-11-12 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#ifndef _WIN32_WCE
#include <process.h>
@@ -29,14 +31,21 @@ WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE)
WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
{
- unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
- *p =
- #ifdef UNDER_CE
- CreateThread(0, 0, func, param, 0, &threadId);
- #else
- (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);
- #endif
- /* maybe we must use errno here, but probably GetLastError() is also OK. */
+ /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
+
+ #ifdef UNDER_CE
+
+ DWORD threadId;
+ *p = CreateThread(0, 0, func, param, 0, &threadId);
+
+ #else
+
+ unsigned threadId;
+ *p = (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);
+
+ #endif
+
+ /* maybe we must use errno here, but probably GetLastError() is also OK. */
return HandleToWRes(*p);
}
diff --git a/src/libs/7zip/win/C/Threads.h b/src/libs/7zip/win/C/Threads.h
index d0ddd80e2..9b3e1c556 100644
--- a/src/libs/7zip/win/C/Threads.h
+++ b/src/libs/7zip/win/C/Threads.h
@@ -1,15 +1,17 @@
/* Threads.h -- multithreading library
-2009-03-27 : Igor Pavlov : Public domain */
+2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_THREADS_H
#define __7Z_THREADS_H
-#include "Types.h"
-
-#ifdef __cplusplus
-extern "C" {
+#ifdef _WIN32
+#include <windows.h>
#endif
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
WRes HandlePtr_Close(HANDLE *h);
WRes Handle_WaitObject(HANDLE h);
@@ -18,7 +20,15 @@ typedef HANDLE CThread;
#define Thread_WasCreated(p) (*(p) != NULL)
#define Thread_Close(p) HandlePtr_Close(p)
#define Thread_Wait(p) Handle_WaitObject(*(p))
-typedef unsigned THREAD_FUNC_RET_TYPE;
+
+typedef
+#ifdef UNDER_CE
+ DWORD
+#else
+ unsigned
+#endif
+ THREAD_FUNC_RET_TYPE;
+
#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);
@@ -52,8 +62,6 @@ WRes CriticalSection_Init(CCriticalSection *p);
#define CriticalSection_Enter(p) EnterCriticalSection(p)
#define CriticalSection_Leave(p) LeaveCriticalSection(p)
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/src/libs/7zip/win/C/Xz.c b/src/libs/7zip/win/C/Xz.c
index 18caba2c1..fbc732a8a 100644
--- a/src/libs/7zip/win/C/Xz.c
+++ b/src/libs/7zip/win/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/win/C/Xz.h b/src/libs/7zip/win/C/Xz.h
index 2cfa1b789..9268d5bc6 100644
--- a/src/libs/7zip/win/C/Xz.h
+++ b/src/libs/7zip/win/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/win/C/XzCrc64.c b/src/libs/7zip/win/C/XzCrc64.c
index 0369554b7..2c04c0af4 100644
--- a/src/libs/7zip/win/C/XzCrc64.c
+++ b/src/libs/7zip/win/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/win/C/XzCrc64.h b/src/libs/7zip/win/C/XzCrc64.h
index 0e8efd7ea..08dbc330c 100644
--- a/src/libs/7zip/win/C/XzCrc64.h
+++ b/src/libs/7zip/win/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/win/C/XzCrc64Opt.c b/src/libs/7zip/win/C/XzCrc64Opt.c
new file mode 100644
index 000000000..dccae1c19
--- /dev/null
+++ b/src/libs/7zip/win/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/win/C/XzDec.c b/src/libs/7zip/win/C/XzDec.c
index 40f1a2a45..6eef587d3 100644
--- a/src/libs/7zip/win/C/XzDec.c
+++ b/src/libs/7zip/win/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/win/C/XzEnc.c b/src/libs/7zip/win/C/XzEnc.c
index 721b4e765..56680fcd8 100644
--- a/src/libs/7zip/win/C/XzEnc.c
+++ b/src/libs/7zip/win/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/win/C/XzEnc.h b/src/libs/7zip/win/C/XzEnc.h
index 13390df8b..c3c19eca0 100644
--- a/src/libs/7zip/win/C/XzEnc.h
+++ b/src/libs/7zip/win/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/win/C/XzIn.c b/src/libs/7zip/win/C/XzIn.c
index 7f0f6af8d..ed9eac31a 100644
--- a/src/libs/7zip/win/C/XzIn.c
+++ b/src/libs/7zip/win/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 >= 0; j--)
- 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/win/CPP/7zip/7zip.pri b/src/libs/7zip/win/CPP/7zip/7zip.pri
new file mode 100644
index 000000000..a2b70a1f2
--- /dev/null
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7z.pri b/src/libs/7zip/win/CPP/7zip/Archive/7z/7z.pri
new file mode 100644
index 000000000..7763cf705
--- /dev/null
+++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/7z.pri
@@ -0,0 +1,30 @@
+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 \
+ $$7ZIP_BASE/CPP/7zip/Archive/7z/StdAfx.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/win/CPP/7zip/Archive/7z/7zCompressionMode.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.cpp
deleted file mode 100644
index 6774fc482..000000000
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-// CompressionMethod.cpp
-
-#include "StdAfx.h"
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.h
index 55bbc68ee..5cde97c38 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zCompressionMode.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zDecode.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.cpp
index 425a34157..973966bd3 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zDecode.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.h
index d8a424a36..54e9d2b52 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zDecode.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zEncode.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.cpp
index 87996bc0e..5f1436fc7 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zEncode.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.h
index 4909a6e89..8e20bdb5f 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zEncode.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zExtract.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zExtract.cpp
index d55f38e13..bb350455c 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zExtract.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.cpp
index edd276bc1..3f420a513 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zFolderInStream.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.h
index 6df3672a1..4ed4b2dd2 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderInStream.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zFolderOutStream.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
index 22c4600ec..847f65bf2 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zFolderOutStream.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.h
index f9bb1af42..cc2d77343 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zFolderOutStream.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zHandler.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.cpp
index 4ab7afa87..ed65dc20c 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zHandler.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.h
index 56062d464..677a3e10a 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandler.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandlerOut.cpp
index a8ccab6df..7de5b8140 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHandlerOut.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zHeader.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.cpp
index 5b5f2fb37..acff2fdd8 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zHeader.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.h
index 30622b90e..61dad655d 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zHeader.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zIn.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.cpp
index 0feb81d2c..28ec5e083 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zIn.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.h
index 971f27b2a..98f61c81e 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zIn.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zItem.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zItem.h
index 34f10775c..c112f83fd 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zItem.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zOut.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.cpp
index 0c8aa7e8c..e20858ea7 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zOut.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.h
index 7b1b528e6..391ca9d02 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zOut.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zProperties.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zProperties.cpp
index fd4af49c7..a29f8abe9 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zProperties.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zRegister.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zRegister.cpp
index 6e9bf6b99..37ea29d30 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zRegister.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zSpecStream.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zSpecStream.cpp
index 06969636d..8e45d9875 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zSpecStream.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/7zUpdate.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.cpp
index ee7f55c04..26faf2a18 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.cpp
+++ b/src/libs/7zip/win/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"
@@ -24,15 +25,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
@@ -67,19 +59,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();
@@ -119,11 +112,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);
}
*/
@@ -134,15 +128,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(
@@ -156,25 +154,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 =
@@ -207,7 +211,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;
@@ -246,7 +250,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),
@@ -257,64 +263,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
@@ -322,124 +398,109 @@ struct CSolidGroup
CRecordVector<UInt32> Indices;
};
-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;
}
-#ifdef USE_86_FILTER
-static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult)
+static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &m)
{
- methodResult.Id = methodID;
- methodResult.NumInStreams = numInStreams;
- methodResult.NumOutStreams = 1;
+ m.Id = methodID;
+ m.NumInStreams = numInStreams;
+ m.NumOutStreams = 1;
}
-static void MakeExeMethod(const CCompressionMethodMode &method,
- bool bcj2Filter, CCompressionMethodMode &exeMethod)
+static void AddBcj2Methods(CCompressionMethodMode &mode)
{
- exeMethod = method;
+ 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(CCompressionMethodMode &mode,
+ bool useFilters, bool addFilter, bool bcj2Filter)
+{
+ 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:
@@ -448,11 +509,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;
@@ -462,14 +523,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; }
@@ -477,7 +538,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;
@@ -576,13 +637,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
@@ -601,6 +662,7 @@ public:
Fos = FosSpec;
Result = E_FAIL;
}
+ ~CThreadDecoder() { CVirtThread::WaitThreadFinish(); }
virtual void Execute();
};
@@ -609,21 +671,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
);
}
@@ -638,7 +699,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)
@@ -669,20 +730,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
@@ -694,6 +766,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));
@@ -701,23 +776,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++)
{
@@ -726,7 +801,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;
@@ -753,7 +828,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);
@@ -772,7 +848,7 @@ HRESULT Update(
}
UInt64 inSizeForReduce = 0;
- int i;
+ unsigned i;
for (i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &ui = updateItems[i];
@@ -789,32 +865,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;
@@ -830,7 +904,7 @@ HRESULT Update(
{
int dotPos = ui.Name.ReverseFind(L'.');
if (dotPos >= 0)
- filteredGroup = IsExeExt(ui.Name.Mid(dotPos + 1));
+ filteredGroup = IsExeExt(ui.Name.Ptr(dotPos + 1));
}
groups[GetGroupIndex(method.PasswordIsDefined, filteredGroup)].Indices.Add(i);
}
@@ -842,7 +916,7 @@ HRESULT Update(
if (needEncryptedRepack)
{
getPasswordSpec = new CCryptoGetTextPassword;
- threadDecoder.GetTextPassword = getPasswordSpec;
+ threadDecoder.getTextPassword = getPasswordSpec;
if (options.Method->PasswordIsDefined)
getPasswordSpec->Password = options.Method->Password;
@@ -852,31 +926,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))
{
@@ -903,36 +1065,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;
@@ -946,44 +1108,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++;
@@ -1002,30 +1172,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;
@@ -1038,7 +1218,7 @@ HRESULT Update(
newDatabase.Files.Add(file);
*/
}
-
+
for (i = 0; i < numFiles;)
{
UInt64 totalSize = 0;
@@ -1057,7 +1237,7 @@ HRESULT Update(
if (numSubFiles == 0)
prevExtension = ext;
else
- if (ext.CompareNoCase(prevExtension) != 0)
+ if (!ext.IsEqualToNoCase(prevExtension))
break;
}
}
@@ -1067,38 +1247,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];
@@ -1122,7 +1307,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.
@@ -1134,42 +1326,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/win/CPP/7zip/Archive/7z/7zUpdate.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.h
index 31e362246..aee2d5ed3 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/7zUpdate.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/7z/StdAfx.cpp b/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.cpp
deleted file mode 100644
index d0feea85c..000000000
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-// StdAfx.cpp
-
-#include "StdAfx.h"
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.h b/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.h
index 2e4be10b2..2854ff3e9 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.h
+++ b/src/libs/7zip/win/CPP/7zip/Archive/7z/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../../Common/MyWindows.h"
-#include "../../../Common/NewHandler.h"
+#include "../../../Common/Common.h"
#endif
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Archive.def b/src/libs/7zip/win/CPP/7zip/Archive/Archive.def
deleted file mode 100644
index 55b530b2d..000000000
--- a/src/libs/7zip/win/CPP/7zip/Archive/Archive.def
+++ /dev/null
@@ -1,6 +0,0 @@
-EXPORTS
- CreateObject PRIVATE
- GetHandlerProperty PRIVATE
- GetNumberOfFormats PRIVATE
- GetHandlerProperty2 PRIVATE
- CreateObject PRIVATE
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Archive.pri b/src/libs/7zip/win/CPP/7zip/Archive/Archive.pri
new file mode 100644
index 000000000..e8a1c7832
--- /dev/null
+++ b/src/libs/7zip/win/CPP/7zip/Archive/Archive.pri
@@ -0,0 +1,6 @@
+HEADERS += $$7ZIP_BASE/CPP/7zip/Archive/IArchive.h \
+ $$7ZIP_BASE/CPP/7zip/Archive/StdAfx.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/win/CPP/7zip/Archive/Archive2.def b/src/libs/7zip/win/CPP/7zip/Archive/Archive2.def
deleted file mode 100644
index 885d39d14..000000000
--- a/src/libs/7zip/win/CPP/7zip/Archive/Archive2.def
+++ /dev/null
@@ -1,9 +0,0 @@
-EXPORTS
- CreateObject PRIVATE
- GetHandlerProperty PRIVATE
- GetNumberOfFormats PRIVATE
- GetHandlerProperty2 PRIVATE
- CreateObject PRIVATE
- GetNumberOfMethods PRIVATE
- GetMethodProperty PRIVATE
- SetLargePageMode PRIVATE
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/ArchiveExports.cpp b/src/libs/7zip/win/CPP/7zip/Archive/ArchiveExports.cpp
deleted file mode 100644
index c7908b591..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/CoderMixer2.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.cpp
index 0b06a489f..e562fec58 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/CoderMixer2.h b/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.h
index a03722d61..50e7077ae 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
index d76450bd1..36b252600 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/CoderMixer2MT.h b/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2MT.h
index d1c7f4d07..2190cf867 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/CoderMixer2MT.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/Common.pri b/src/libs/7zip/win/CPP/7zip/Archive/Common/Common.pri
new file mode 100644
index 000000000..e808619d3
--- /dev/null
+++ b/src/libs/7zip/win/CPP/7zip/Archive/Common/Common.pri
@@ -0,0 +1,19 @@
+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 \
+ $$7ZIP_BASE/CPP/7zip/Archive/Common/StdAfx.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/win/CPP/7zip/Archive/Common/CrossThreadProgress.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
deleted file mode 100644
index a974b54c7..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/CrossThreadProgress.h b/src/libs/7zip/win/CPP/7zip/Archive/Common/CrossThreadProgress.h
deleted file mode 100644
index 7e0b10538..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/DummyOutStream.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/DummyOutStream.cpp
index 54bcfec11..7c4f54879 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/DummyOutStream.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/DummyOutStream.h b/src/libs/7zip/win/CPP/7zip/Archive/Common/DummyOutStream.h
index 13d5b62ca..b5a51fc07 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/DummyOutStream.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/HandlerOut.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/HandlerOut.cpp
index 70ad47aad..7b875fbd0 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/HandlerOut.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/HandlerOut.h b/src/libs/7zip/win/CPP/7zip/Archive/Common/HandlerOut.h
index 72ea40321..eba2a19e1 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/HandlerOut.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/InStreamWithCRC.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
index 569a56f3b..a2d688328 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/ItemNameUtils.cpp
index a5e0dc0be..7cd3037be 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/ItemNameUtils.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/ItemNameUtils.h b/src/libs/7zip/win/CPP/7zip/Archive/Common/ItemNameUtils.h
index 5eafacb12..d0dc76a41 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/ItemNameUtils.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/MultiStream.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/MultiStream.cpp
index 04d11cafb..17f749058 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/MultiStream.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/MultiStream.h b/src/libs/7zip/win/CPP/7zip/Archive/Common/MultiStream.h
index 3fceb7cce..93aff33bf 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/MultiStream.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/OutStreamWithCRC.h b/src/libs/7zip/win/CPP/7zip/Archive/Common/OutStreamWithCRC.h
index 115b442aa..09b899bbd 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/OutStreamWithCRC.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/ParseProperties.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Common/ParseProperties.cpp
deleted file mode 100644
index 5cd849e29..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/ParseProperties.h b/src/libs/7zip/win/CPP/7zip/Archive/Common/ParseProperties.h
index 6f80f6344..1038a8c02 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/ParseProperties.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/Common/StdAfx.h b/src/libs/7zip/win/CPP/7zip/Archive/Common/StdAfx.h
index 2e4be10b2..2854ff3e9 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/Common/StdAfx.h
+++ b/src/libs/7zip/win/CPP/7zip/Archive/Common/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../../Common/MyWindows.h"
-#include "../../../Common/NewHandler.h"
+#include "../../../Common/Common.h"
#endif
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/DllExports2.cpp b/src/libs/7zip/win/CPP/7zip/Archive/DllExports2.cpp
deleted file mode 100644
index ad14ff06a..000000000
--- a/src/libs/7zip/win/CPP/7zip/Archive/DllExports2.cpp
+++ /dev/null
@@ -1,74 +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;
-
-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;
-}
-
-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/win/CPP/7zip/Archive/IArchive.h b/src/libs/7zip/win/CPP/7zip/Archive/IArchive.h
index 853202767..a15a97f16 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/IArchive.h
+++ b/src/libs/7zip/win/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,32 @@ ARCHIVE_INTERFACE(ISetProperties, 0x03)
STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \
{ value->vt = VT_EMPTY; return S_OK; }
+
+
+#define k_IsArc_Res_NO 0
+#define k_IsArc_Res_YES 1
+#define k_IsArc_Res_NEED_MORE 2
+// #define k_IsArc_Res_YES_LOW_PROB 3
+
+#define API_FUNC_IsArc EXTERN_C UInt32 WINAPI
+#define API_FUNC_static_IsArc extern "C" { static UInt32 WINAPI
+
+extern "C"
+{
+ typedef HRESULT (WINAPI *Func_CreateObject)(const GUID *clsID, const GUID *iid, void **outObject);
+
+ typedef UInt32 (WINAPI *Func_IsArc)(const Byte *p, size_t size);
+ typedef HRESULT (WINAPI *Func_GetIsArc)(UInt32 formatIndex, Func_IsArc *isArc);
+
+ typedef HRESULT (WINAPI *Func_GetNumberOfFormats)(UInt32 *numFormats);
+ typedef HRESULT (WINAPI *Func_GetHandlerProperty)(PROPID propID, PROPVARIANT *value);
+ typedef HRESULT (WINAPI *Func_GetHandlerProperty2)(UInt32 index, PROPID propID, PROPVARIANT *value);
+
+ typedef HRESULT (WINAPI *Func_SetCaseSensitive)(Int32 caseSensitive);
+ typedef HRESULT (WINAPI *Func_SetLargePageMode)();
+
+ typedef IOutArchive * (*Func_CreateOutArchive)();
+ typedef IInArchive * (*Func_CreateInArchive)();
+}
+
#endif
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/LzmaHandler.cpp b/src/libs/7zip/win/CPP/7zip/Archive/LzmaHandler.cpp
index a83e6a1ad..279cdefb7 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/LzmaHandler.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/SplitHandler.cpp b/src/libs/7zip/win/CPP/7zip/Archive/SplitHandler.cpp
index 5d84de4ed..db9f49aa0 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/SplitHandler.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Archive/StdAfx.h b/src/libs/7zip/win/CPP/7zip/Archive/StdAfx.h
index ef555ec12..1cbd7feae 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/StdAfx.h
+++ b/src/libs/7zip/win/CPP/7zip/Archive/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../Common/MyWindows.h"
-#include "../../Common/NewHandler.h"
+#include "../../Common/Common.h"
#endif
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/XzHandler.cpp b/src/libs/7zip/win/CPP/7zip/Archive/XzHandler.cpp
index 64b7a5863..789f41a72 100644
--- a/src/libs/7zip/win/CPP/7zip/Archive/XzHandler.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/CWrappers.cpp b/src/libs/7zip/win/CPP/7zip/Common/CWrappers.cpp
index 358f0b503..a15794e2a 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/CWrappers.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/CWrappers.h b/src/libs/7zip/win/CPP/7zip/Common/CWrappers.h
index 80a8a1b61..4fe7dea3e 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/CWrappers.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/Common.pri b/src/libs/7zip/win/CPP/7zip/Common/Common.pri
new file mode 100644
index 000000000..e6b054a24
--- /dev/null
+++ b/src/libs/7zip/win/CPP/7zip/Common/Common.pri
@@ -0,0 +1,40 @@
+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/StdAfx.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/win/CPP/7zip/Common/CreateCoder.cpp b/src/libs/7zip/win/CPP/7zip/Common/CreateCoder.cpp
index cc82a0db5..01ccbe12a 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/CreateCoder.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/CreateCoder.h b/src/libs/7zip/win/CPP/7zip/Common/CreateCoder.h
index bf0e96a38..fe1f6ccfe 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/CreateCoder.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/FilePathAutoRename.cpp b/src/libs/7zip/win/CPP/7zip/Common/FilePathAutoRename.cpp
index 7d6e36f14..958360fac 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/FilePathAutoRename.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/FilePathAutoRename.h b/src/libs/7zip/win/CPP/7zip/Common/FilePathAutoRename.h
index 3ef87f482..7b576591c 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/FilePathAutoRename.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/FileStreams.cpp b/src/libs/7zip/win/CPP/7zip/Common/FileStreams.cpp
index 426a0d3d6..77e5463e6 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/FileStreams.cpp
+++ b/src/libs/7zip/win/CPP/7zip/Common/FileStreams.cpp
@@ -29,42 +29,15 @@ static inline HRESULT ConvertBoolToHRESULT(bool result)
#endif
}
-bool CInFileStream::Open(LPCTSTR fileName)
-{
- return File.Open(fileName);
-}
-
-#ifdef USE_WIN_FILE
-#ifndef _UNICODE
-bool CInFileStream::Open(LPCWSTR fileName)
-{
- return File.Open(fileName);
-}
-#endif
-#endif
-
-bool CInFileStream::OpenShared(LPCTSTR fileName, bool shareForWrite)
-{
- return File.OpenShared(fileName, shareForWrite);
-}
-
-#ifdef USE_WIN_FILE
-#ifndef _UNICODE
-bool CInFileStream::OpenShared(LPCWSTR fileName, bool shareForWrite)
-{
- return File.OpenShared(fileName, shareForWrite);
-}
-#endif
-#endif
-
#ifdef SUPPORT_DEVICE_FILE
static const UInt32 kClusterSize = 1 << 18;
CInFileStream::CInFileStream():
VirtPos(0),
PhyPos(0),
- Buffer(0),
- BufferSize(0)
+ Buf(0),
+ BufSize(0),
+ SupportHardLinks(false)
{
}
@@ -73,50 +46,50 @@ CInFileStream::CInFileStream():
CInFileStream::~CInFileStream()
{
#ifdef SUPPORT_DEVICE_FILE
- MidFree(Buffer);
+ MidFree(Buf);
#endif
}
STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
#ifdef USE_WIN_FILE
-
+
#ifdef SUPPORT_DEVICE_FILE
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
if (size == 0)
return S_OK;
if (File.IsDeviceFile)
{
- if (File.LengthDefined)
+ if (File.SizeDefined)
{
- if (VirtPos >= File.Length)
- return VirtPos == File.Length ? S_OK : E_FAIL;
- UInt64 rem = File.Length - VirtPos;
+ if (VirtPos >= File.Size)
+ return VirtPos == File.Size ? S_OK : E_FAIL;
+ UInt64 rem = File.Size - VirtPos;
if (size > rem)
size = (UInt32)rem;
}
for (;;)
{
const UInt32 mask = kClusterSize - 1;
- UInt64 mask2 = ~(UInt64)mask;
+ const UInt64 mask2 = ~(UInt64)mask;
UInt64 alignedPos = VirtPos & mask2;
- if (BufferSize > 0 && BufferStartPos == alignedPos)
+ if (BufSize > 0 && BufStartPos == alignedPos)
{
UInt32 pos = (UInt32)VirtPos & mask;
- if (pos >= BufferSize)
+ if (pos >= BufSize)
return S_OK;
- UInt32 rem = MyMin(BufferSize - pos, size);
- memcpy(data, Buffer + pos, rem);
+ UInt32 rem = MyMin(BufSize - pos, size);
+ memcpy(data, Buf + pos, rem);
VirtPos += rem;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize += rem;
return S_OK;
}
-
- bool useBuffer = false;
+
+ bool useBuf = false;
if ((VirtPos & mask) != 0 || ((ptrdiff_t)data & mask) != 0 )
- useBuffer = true;
+ useBuf = true;
else
{
UInt64 end = VirtPos + size;
@@ -124,12 +97,12 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
end &= mask2;
if (end <= VirtPos)
- useBuffer = true;
+ useBuf = true;
else
size = (UInt32)(end - VirtPos);
}
}
- if (!useBuffer)
+ if (!useBuf)
break;
if (alignedPos != PhyPos)
{
@@ -140,24 +113,24 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
PhyPos = realNewPosition;
}
- BufferStartPos = alignedPos;
+ BufStartPos = alignedPos;
UInt32 readSize = kClusterSize;
- if (File.LengthDefined)
- readSize = (UInt32)MyMin(File.Length - PhyPos, (UInt64)kClusterSize);
+ if (File.SizeDefined)
+ readSize = (UInt32)MyMin(File.Size - PhyPos, (UInt64)kClusterSize);
- if (Buffer == 0)
+ if (!Buf)
{
- Buffer = (Byte *)MidAlloc(kClusterSize);
- if (Buffer == 0)
+ Buf = (Byte *)MidAlloc(kClusterSize);
+ if (!Buf)
return E_OUTOFMEMORY;
}
- bool result = File.Read1(Buffer, readSize, BufferSize);
+ bool result = File.Read1(Buf, readSize, BufSize);
if (!result)
return ConvertBoolToHRESULT(result);
- if (BufferSize == 0)
+ if (BufSize == 0)
return S_OK;
- PhyPos += BufferSize;
+ PhyPos += BufSize;
}
if (VirtPos != PhyPos)
@@ -173,22 +146,22 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
UInt32 realProcessedSize;
bool result = File.ReadPart(data, size, realProcessedSize);
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
#ifdef SUPPORT_DEVICE_FILE
VirtPos += realProcessedSize;
PhyPos += realProcessedSize;
#endif
return ConvertBoolToHRESULT(result);
-
+
#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;
@@ -198,30 +171,33 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
#ifdef UNDER_CE
STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- size_t s2 = fread(data, 1, size, stdout);
- if (processedSize != 0)
+ size_t s2 = fread(data, 1, size, stdin);
+ int error = ferror(stdin);
+ if (processedSize)
*processedSize = s2;
- return (s2 = size) ? S_OK : E_FAIL;
+ if (s2 <= size && error == 0)
+ return S_OK;
+ return E_FAIL;
}
#else
STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
#ifdef _WIN32
-
+
DWORD realProcessedSize;
UInt32 sizeTemp = (1 << 20);
if (sizeTemp > size)
sizeTemp = size;
BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL);
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = realProcessedSize;
if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
return S_OK;
return ConvertBoolToHRESULT(res != FALSE);
-
+
#else
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
ssize_t res;
do
@@ -231,17 +207,16 @@ 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)
return STG_E_INVALIDFUNCTION;
@@ -249,43 +224,44 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
#ifdef USE_WIN_FILE
#ifdef SUPPORT_DEVICE_FILE
- if (File.IsDeviceFile)
+ if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END))
{
- UInt64 newVirtPos = offset;
- switch(seekOrigin)
+ switch (seekOrigin)
{
case STREAM_SEEK_SET: break;
- case STREAM_SEEK_CUR: newVirtPos += VirtPos; break;
- case STREAM_SEEK_END: newVirtPos += File.Length; break;
+ case STREAM_SEEK_CUR: offset += VirtPos; break;
+ case STREAM_SEEK_END: offset += File.Size; break;
default: return STG_E_INVALIDFUNCTION;
}
- VirtPos = newVirtPos;
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ VirtPos = offset;
if (newPosition)
- *newPosition = newVirtPos;
+ *newPosition = offset;
return S_OK;
}
#endif
-
+
UInt64 realNewPosition;
bool result = File.Seek(offset, seekOrigin, realNewPosition);
-
+
#ifdef SUPPORT_DEVICE_FILE
PhyPos = VirtPos = realNewPosition;
#endif
- 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
}
@@ -294,6 +270,43 @@ STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
return ConvertBoolToHRESULT(File.GetLength(*size));
}
+#ifdef USE_WIN_FILE
+
+STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ if (File.GetFileInformation(&info))
+ {
+ if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
+ if (cTime) *cTime = info.ftCreationTime;
+ if (aTime) *aTime = info.ftLastAccessTime;
+ if (mTime) *mTime = info.ftLastWriteTime;
+ if (attrib) *attrib = info.dwFileAttributes;
+ return S_OK;
+ }
+ return GetLastError();
+}
+
+STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ if (File.GetFileInformation(&info))
+ {
+ props->Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
+ props->VolID = info.dwVolumeSerialNumber;
+ props->FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
+ props->FileID_High = 0;
+ props->NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1;
+ props->Attrib = info.dwFileAttributes;
+ props->CTime = info.ftCreationTime;
+ props->ATime = info.ftLastAccessTime;
+ props->MTime = info.ftLastWriteTime;
+ return S_OK;
+ }
+ return GetLastError();
+}
+
+#endif
//////////////////////////
// COutFileStream
@@ -310,25 +323,25 @@ 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)
@@ -337,19 +350,19 @@ STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo
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
}
@@ -372,14 +385,14 @@ STDMETHODIMP COutFileStream::SetSize(UInt64 newSize)
STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
size_t s2 = fwrite(data, 1, size, stdout);
- if (processedSize != 0)
+ if (processedSize)
*processedSize = s2;
- return (s2 = size) ? S_OK : E_FAIL;
+ return (s2 == size) ? S_OK : E_FAIL;
}
#else
STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
#ifdef _WIN32
@@ -396,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
{
@@ -411,10 +424,10 @@ 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
}
diff --git a/src/libs/7zip/win/CPP/7zip/Common/FileStreams.h b/src/libs/7zip/win/CPP/7zip/Common/FileStreams.h
index 895745d36..cce71e582 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/FileStreams.h
+++ b/src/libs/7zip/win/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
#ifdef _WIN32
#define USE_WIN_FILE
#endif
+#include "../../Common/MyString.h"
+
#ifdef USE_WIN_FILE
#include "../../Windows/FileIO.h"
#else
@@ -20,47 +22,63 @@
class CInFileStream:
public IInStream,
public IStreamGetSize,
+ #ifdef USE_WIN_FILE
+ public IStreamGetProps,
+ public IStreamGetProps2,
+ #endif
public CMyUnknownImp
{
public:
#ifdef USE_WIN_FILE
NWindows::NFile::NIO::CInFile File;
+
#ifdef SUPPORT_DEVICE_FILE
UInt64 VirtPos;
UInt64 PhyPos;
- UInt64 BufferStartPos;
- Byte *Buffer;
- UInt32 BufferSize;
+ UInt64 BufStartPos;
+ Byte *Buf;
+ UInt32 BufSize;
#endif
+
#else
NC::NFile::NIO::CInFile File;
#endif
+
+ bool SupportHardLinks;
+
virtual ~CInFileStream();
#ifdef SUPPORT_DEVICE_FILE
CInFileStream();
#endif
-
- bool Open(LPCTSTR fileName);
- #ifdef USE_WIN_FILE
- #ifndef _UNICODE
- bool Open(LPCWSTR fileName);
- #endif
- #endif
- bool OpenShared(LPCTSTR fileName, bool shareForWrite);
+ bool Open(CFSTR fileName)
+ {
+ return File.Open(fileName);
+ }
+
+ bool OpenShared(CFSTR fileName, bool shareForWrite)
+ {
+ return File.OpenShared(fileName, shareForWrite);
+ }
+
+ MY_QUERYINTERFACE_BEGIN2(IInStream)
+ MY_QUERYINTERFACE_ENTRY(IStreamGetSize)
#ifdef USE_WIN_FILE
- #ifndef _UNICODE
- bool OpenShared(LPCWSTR fileName, bool shareForWrite);
- #endif
+ MY_QUERYINTERFACE_ENTRY(IStreamGetProps)
+ MY_QUERYINTERFACE_ENTRY(IStreamGetProps2)
#endif
-
- MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
STDMETHOD(GetSize)(UInt64 *size);
+ #ifdef USE_WIN_FILE
+ STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib);
+ STDMETHOD(GetProps2)(CStreamFileProps *props);
+ #endif
};
class CStdInFileStream:
@@ -78,40 +96,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/win/CPP/7zip/Common/FilterCoder.cpp b/src/libs/7zip/win/CPP/7zip/Common/FilterCoder.cpp
index 696735278..3a2023b35 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/FilterCoder.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/FilterCoder.h b/src/libs/7zip/win/CPP/7zip/Common/FilterCoder.h
index 8132a6dd7..2b8f142f5 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/FilterCoder.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/InBuffer.cpp b/src/libs/7zip/win/CPP/7zip/Common/InBuffer.cpp
index ad4f8825e..133d95b38 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/InBuffer.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/InBuffer.h b/src/libs/7zip/win/CPP/7zip/Common/InBuffer.h
index 75625bfd9..dd3c66808 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/InBuffer.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/InOutTempBuffer.cpp b/src/libs/7zip/win/CPP/7zip/Common/InOutTempBuffer.cpp
index dfe8b3d32..be65ba32f 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/InOutTempBuffer.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/InOutTempBuffer.h b/src/libs/7zip/win/CPP/7zip/Common/InOutTempBuffer.h
index 073f95acf..256d72420 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/InOutTempBuffer.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/LimitedStreams.cpp b/src/libs/7zip/win/CPP/7zip/Common/LimitedStreams.cpp
index 1837e3201..5f20dcda4 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/LimitedStreams.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/LimitedStreams.h b/src/libs/7zip/win/CPP/7zip/Common/LimitedStreams.h
index 2cbe18e48..b14616f3b 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/LimitedStreams.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/MethodId.cpp b/src/libs/7zip/win/CPP/7zip/Common/MethodId.cpp
deleted file mode 100644
index b797b6857..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/Common/MethodId.h b/src/libs/7zip/win/CPP/7zip/Common/MethodId.h
index 54ebc9f7d..28b615fcd 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/MethodId.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/MethodProps.cpp b/src/libs/7zip/win/CPP/7zip/Common/MethodProps.cpp
index 5836d0f84..ff61995b7 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/MethodProps.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/MethodProps.h b/src/libs/7zip/win/CPP/7zip/Common/MethodProps.h
index 8127e21ee..39e2ee937 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/MethodProps.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/OffsetStream.cpp b/src/libs/7zip/win/CPP/7zip/Common/OffsetStream.cpp
deleted file mode 100644
index c5e4e6da4..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/Common/OffsetStream.h b/src/libs/7zip/win/CPP/7zip/Common/OffsetStream.h
deleted file mode 100644
index de9d06dd0..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/Common/OutBuffer.cpp b/src/libs/7zip/win/CPP/7zip/Common/OutBuffer.cpp
index 2e5debd83..4ba34a053 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/OutBuffer.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/OutBuffer.h b/src/libs/7zip/win/CPP/7zip/Common/OutBuffer.h
index 62e77caae..0baad3636 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/OutBuffer.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/ProgressUtils.cpp b/src/libs/7zip/win/CPP/7zip/Common/ProgressUtils.cpp
index f24ff6b6f..bac45c1c2 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/ProgressUtils.cpp
+++ b/src/libs/7zip/win/CPP/7zip/Common/ProgressUtils.cpp
@@ -1,4 +1,4 @@
-// ProgressUtils.h
+// ProgressUtils.cpp
#include "StdAfx.h"
diff --git a/src/libs/7zip/win/CPP/7zip/Common/PropId.cpp b/src/libs/7zip/win/CPP/7zip/Common/PropId.cpp
new file mode 100644
index 000000000..10daef715
--- /dev/null
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/RegisterArc.h b/src/libs/7zip/win/CPP/7zip/Common/RegisterArc.h
index 9b8cbd39d..82bd09673 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/RegisterArc.h
+++ b/src/libs/7zip/win/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[16];
- 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/win/CPP/7zip/Common/RegisterCodec.h b/src/libs/7zip/win/CPP/7zip/Common/RegisterCodec.h
index d53c4344a..0c6662a6c 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/RegisterCodec.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/StdAfx.h b/src/libs/7zip/win/CPP/7zip/Common/StdAfx.h
index ef555ec12..1cbd7feae 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/StdAfx.h
+++ b/src/libs/7zip/win/CPP/7zip/Common/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../Common/MyWindows.h"
-#include "../../Common/NewHandler.h"
+#include "../../Common/Common.h"
#endif
diff --git a/src/libs/7zip/win/CPP/7zip/Common/StreamBinder.cpp b/src/libs/7zip/win/CPP/7zip/Common/StreamBinder.cpp
index 03f886258..7a4c0ed26 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/StreamBinder.cpp
+++ b/src/libs/7zip/win/CPP/7zip/Common/StreamBinder.cpp
@@ -2,149 +2,125 @@
#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()
{
- RINOK(_allBytesAreWritenEvent.Create(true));
- RINOK(_thereAreBytesToReadEvent.Create());
- return _readStreamIsClosedEvent.Create();
+ RINOK(_canWrite_Event.Create(true));
+ RINOK(_canRead_Event.Create());
+ return _readingWasClosed_Event.Create();
}
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/win/CPP/7zip/Common/StreamBinder.h b/src/libs/7zip/win/CPP/7zip/Common/StreamBinder.h
index 48f68e60f..f3fb53228 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/StreamBinder.h
+++ b/src/libs/7zip/win/CPP/7zip/Common/StreamBinder.h
@@ -1,32 +1,34 @@
// 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::CManualResetEvent _allBytesAreWritenEvent;
- NWindows::NSynchronization::CManualResetEvent _thereAreBytesToReadEvent;
- NWindows::NSynchronization::CManualResetEvent _readStreamIsClosedEvent;
- UInt32 _bufferSize;
- const void *_buffer;
+ NWindows::NSynchronization::CManualResetEvent _canWrite_Event;
+ NWindows::NSynchronization::CManualResetEvent _canRead_Event;
+ NWindows::NSynchronization::CManualResetEvent _readingWasClosed_Event;
+ bool _waitWrite;
+ UInt32 _bufSize;
+ const void *_buf;
public:
- // bool ReadingWasClosed;
UInt64 ProcessedSize;
- CStreamBinder() {}
- 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/win/CPP/7zip/Common/StreamObjects.cpp b/src/libs/7zip/win/CPP/7zip/Common/StreamObjects.cpp
index 3c86c3aeb..7721c3a7e 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/StreamObjects.cpp
+++ b/src/libs/7zip/win/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(dest, _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/win/CPP/7zip/Common/StreamObjects.h b/src/libs/7zip/win/CPP/7zip/Common/StreamObjects.h
index 5c8b5e51b..d0c86b566 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/StreamObjects.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/StreamUtils.cpp b/src/libs/7zip/win/CPP/7zip/Common/StreamUtils.cpp
index 049e4aa17..1402f4205 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/StreamUtils.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/StreamUtils.h b/src/libs/7zip/win/CPP/7zip/Common/StreamUtils.h
index f1cfd1848..ae914c004 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/StreamUtils.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/UniqBlocks.cpp b/src/libs/7zip/win/CPP/7zip/Common/UniqBlocks.cpp
new file mode 100644
index 000000000..7fcc88f5e
--- /dev/null
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/UniqBlocks.h b/src/libs/7zip/win/CPP/7zip/Common/UniqBlocks.h
new file mode 100644
index 000000000..9c08b09f4
--- /dev/null
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/VirtThread.cpp b/src/libs/7zip/win/CPP/7zip/Common/VirtThread.cpp
index cf39bd023..77e3c1acf 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/VirtThread.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Common/VirtThread.h b/src/libs/7zip/win/CPP/7zip/Common/VirtThread.h
index f14a1f223..ebee158ca 100644
--- a/src/libs/7zip/win/CPP/7zip/Common/VirtThread.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/Bcj2Coder.cpp b/src/libs/7zip/win/CPP/7zip/Compress/Bcj2Coder.cpp
index 684da5abf..9da6b9c28 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/Bcj2Coder.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/Bcj2Coder.h b/src/libs/7zip/win/CPP/7zip/Compress/Bcj2Coder.h
index 79a713f17..e7bd37951 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/Bcj2Coder.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/BranchMisc.cpp b/src/libs/7zip/win/CPP/7zip/Compress/BranchMisc.cpp
index 423b723ab..239f25138 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/BranchMisc.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/CodecExports.cpp b/src/libs/7zip/win/CPP/7zip/Compress/CodecExports.cpp
deleted file mode 100644
index 4ff1c0fcb..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/Compress/Compress.pri b/src/libs/7zip/win/CPP/7zip/Compress/Compress.pri
new file mode 100644
index 000000000..db923a868
--- /dev/null
+++ b/src/libs/7zip/win/CPP/7zip/Compress/Compress.pri
@@ -0,0 +1,30 @@
+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 \
+ $$7ZIP_BASE/CPP/7zip/Compress/StdAfx.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/win/CPP/7zip/Compress/CopyCoder.cpp b/src/libs/7zip/win/CPP/7zip/Compress/CopyCoder.cpp
index f71692a77..f0863202a 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/CopyCoder.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/CopyCoder.h b/src/libs/7zip/win/CPP/7zip/Compress/CopyCoder.h
index c5445ccf8..5e0bb6436 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/CopyCoder.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/DeltaFilter.cpp b/src/libs/7zip/win/CPP/7zip/Compress/DeltaFilter.cpp
index 2e421acf4..d8378a60e 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/DeltaFilter.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/Lzma2Decoder.cpp b/src/libs/7zip/win/CPP/7zip/Compress/Lzma2Decoder.cpp
index 322015e29..b20ae5f5e 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/Lzma2Decoder.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/Lzma2Encoder.cpp b/src/libs/7zip/win/CPP/7zip/Compress/Lzma2Encoder.cpp
index 5e4c71bea..f867881c0 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/Lzma2Encoder.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/Lzma2Encoder.h b/src/libs/7zip/win/CPP/7zip/Compress/Lzma2Encoder.h
index f0fb74d33..6a2318076 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/Lzma2Encoder.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/LzmaDecoder.cpp b/src/libs/7zip/win/CPP/7zip/Compress/LzmaDecoder.cpp
index b7c260bd9..d378ba668 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/LzmaDecoder.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/LzmaDecoder.h b/src/libs/7zip/win/CPP/7zip/Compress/LzmaDecoder.h
index d28a4634b..140c48b9c 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/LzmaDecoder.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/LzmaEncoder.cpp b/src/libs/7zip/win/CPP/7zip/Compress/LzmaEncoder.cpp
index 9bdedaeb6..484d04523 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/LzmaEncoder.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/LzmaEncoder.h b/src/libs/7zip/win/CPP/7zip/Compress/LzmaEncoder.h
index 904c0002c..7e15a132d 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/LzmaEncoder.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/RangeCoder.h b/src/libs/7zip/win/CPP/7zip/Compress/RangeCoder.h
index 1eb2a6d47..1555bd705 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/RangeCoder.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/RangeCoderBit.h b/src/libs/7zip/win/CPP/7zip/Compress/RangeCoderBit.h
index b5a1830d6..0eddd5586 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/RangeCoderBit.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/Compress/StdAfx.h b/src/libs/7zip/win/CPP/7zip/Compress/StdAfx.h
index 99a8aa46d..1cbd7feae 100644
--- a/src/libs/7zip/win/CPP/7zip/Compress/StdAfx.h
+++ b/src/libs/7zip/win/CPP/7zip/Compress/StdAfx.h
@@ -3,6 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../Common/MyWindows.h"
+#include "../../Common/Common.h"
#endif
diff --git a/src/libs/7zip/win/CPP/7zip/Guid.txt b/src/libs/7zip/win/CPP/7zip/Guid.txt
index 59a743b96..c1e7446be 100644
--- a/src/libs/7zip/win/CPP/7zip/Guid.txt
+++ b/src/libs/7zip/win/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/win/CPP/7zip/ICoder.h b/src/libs/7zip/win/CPP/7zip/ICoder.h
index a518de463..74ee0e453 100644
--- a/src/libs/7zip/win/CPP/7zip/ICoder.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/IPassword.h b/src/libs/7zip/win/CPP/7zip/IPassword.h
index 3ca7b090e..7ea45537e 100644
--- a/src/libs/7zip/win/CPP/7zip/IPassword.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/IProgress.h b/src/libs/7zip/win/CPP/7zip/IProgress.h
index d6093f173..a270e693b 100644
--- a/src/libs/7zip/win/CPP/7zip/IProgress.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/IStream.h b/src/libs/7zip/win/CPP/7zip/IStream.h
index 165e8baad..48643e7b3 100644
--- a/src/libs/7zip/win/CPP/7zip/IStream.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/MyVersion.h b/src/libs/7zip/win/CPP/7zip/MyVersion.h
deleted file mode 100644
index eda88db08..000000000
--- a/src/libs/7zip/win/CPP/7zip/MyVersion.h
+++ /dev/null
@@ -1,8 +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
diff --git a/src/libs/7zip/win/CPP/7zip/PropID.h b/src/libs/7zip/win/CPP/7zip/PropID.h
index 8f8885263..82a7462bb 100644
--- a/src/libs/7zip/win/CPP/7zip/PropID.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
index 8ae2e15e8..769d21604 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
+++ b/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -1,6 +1,8 @@
// ArchiveCommandLine.cpp
#include "StdAfx.h"
+#undef printf
+#undef sprintf
#ifdef _WIN32
#ifndef UNDER_CE
@@ -9,15 +11,15 @@
#endif
#include <stdio.h>
-#include "Common/ListFileUtils.h"
-#include "Common/StringConvert.h"
-#include "Common/StringToInt.h"
+#include "../../../Common/ListFileUtils.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/StringToInt.h"
-#include "Windows/FileDir.h"
-#include "Windows/FileName.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileName.h"
#ifdef _WIN32
-#include "Windows/FileMapping.h"
-#include "Windows/Synchronization.h"
+#include "../../../Windows/FileMapping.h"
+#include "../../../Windows/Synchronization.h"
#endif
#include "ArchiveCommandLine.h"
@@ -48,6 +50,30 @@ 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 {
@@ -86,19 +112,47 @@ enum Enum
kTechMode,
kShareForWrite,
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
};
}
@@ -110,135 +164,127 @@ 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"SCS", NSwitchType::kUnLimitedPostString, false, 0},
- { L"SCC", NSwitchType::kUnLimitedPostString, false, 0},
- { L"SLT", NSwitchType::kSimple, false },
- { L"SSW", NSwitchType::kSimple, false },
- { L"SSC", NSwitchType::kPostChar, false, 0, 0, L"-" },
- { L"SCRC", NSwitchType::kSimple, false }
- };
-
-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" },
+ { "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)
-{
- throw CArchiveCommandLineException(errorMessage);
-}
-
-static void ThrowUserErrorException()
-{
- ThrowException(kUserErrorMessage);
-}
-
-// ---------------------------
-
-bool CArchiveCommand::IsFromExtractGroup() const
+bool CArcCommand::IsFromExtractGroup() const
{
- switch(CommandType)
+ switch (CommandType)
{
case NCommandType::kTest:
case NCommandType::kExtract:
- case NCommandType::kFullExtract:
+ case NCommandType::kExtractFull:
return true;
- default:
- return false;
}
+ return false;
}
-NExtract::NPathMode::EEnum CArchiveCommand::GetPathMode() const
+NExtract::NPathMode::EEnum CArcCommand::GetPathMode() const
{
- switch(CommandType)
+ switch (CommandType)
{
case NCommandType::kTest:
- case NCommandType::kFullExtract:
- return NExtract::NPathMode::kFullPathnames;
- default:
- return NExtract::NPathMode::kNoPathnames;
+ case NCommandType::kExtractFull:
+ return NExtract::NPathMode::kFullPaths;
}
+ return NExtract::NPathMode::kNoPaths;
}
-bool CArchiveCommand::IsFromUpdateGroup() const
+bool CArcCommand::IsFromUpdateGroup() const
{
- return (CommandType == NCommandType::kAdd ||
- CommandType == NCommandType::kUpdate ||
- CommandType == NCommandType::kDelete);
+ switch (CommandType)
+ {
+ case NCommandType::kAdd:
+ case NCommandType::kUpdate:
+ case NCommandType::kDelete:
+ case NCommandType::kRename:
+ return true;
+ }
+ return false;
}
static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
{
switch (index)
{
- case NRecursedPostCharIndex::kWildCardRecursionOnly:
- return NRecursedType::kWildCardOnlyRecursed;
+ case NRecursedPostCharIndex::kWildcardRecursionOnly:
+ return NRecursedType::kWildcardOnlyRecursed;
case NRecursedPostCharIndex::kNoRecursion:
return NRecursedType::kNonRecursed;
default:
@@ -246,170 +292,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);
+ AddToCensorFromListFile(renamePairs, censor, s.Ptr(1), true, type, wildcardMatching, codePage);
+ else if (renamePairs)
+ {
+ if (oldIndex == -1)
+ oldIndex = startIndex;
+ else
+ {
+ // 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;
+ }
+ }
else
- AddNameToCensor(wildcardCensor, s, true, type);
+ AddNameToCensor(censor, s, true, type, wildcardMatching);
+ }
+
+ if (oldIndex != -1)
+ {
+ throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[oldIndex]);
}
}
#ifdef _WIN32
-static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor,
- const UString &switchParam, bool include,
- NRecursedType::EEnum commonRecursedType)
+
+struct CEventSetEnd
{
- 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
- {
- 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++)
- {
- wchar_t c = curData[i];
- if (c == L'\0')
- {
- AddNameToCensor(wildcardCensor, name, include, commonRecursedType);
- name.Empty();
- }
- else
- name += c;
- }
- if (!name.IsEmpty())
- ThrowException("data error");
- }
- catch(...)
- {
- UnmapViewOfFile(data);
- throw;
- }
- UnmapViewOfFile(data);
- }
-
+ 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
@@ -418,20 +575,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::CFileInfo fi;
+ const FString path = us2fs(prefix + name);
+ if (NFile::NName::IsDevicePath(path))
return;
- NFind::CFileInfoW fi;
- if (fi.Find(prefix + name))
- name = fi.Name;
+ if (fi.Find(path))
+ name = fs2us(fi.Name);
}
static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
{
- for (int i = 0; i < items.Size(); i++)
+ FOR_VECTOR (i, items)
{
NWildcard::CItem &item = items[i];
if (item.Recursive || item.PathParts.Size() != 1)
continue;
+ if (prefix.IsEmpty() && item.IsDriveItem())
+ continue;
ConvertToLongName(prefix, item.PathParts.Front());
}
}
@@ -440,17 +602,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;
@@ -463,13 +630,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);
@@ -478,9 +645,10 @@ static void ConvertToLongNames(NWildcard::CCensor &censor)
#endif
+/*
static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
{
- switch(i)
+ switch (i)
{
case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore;
case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy;
@@ -489,35 +657,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};
-
-const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress, Create Anti
+static const wchar_t *kUpdatePairStateIDSet = L"pqrxyzw";
+static const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
-const wchar_t *kUpdateIgnoreItselfPostStringID = L"-";
-const wchar_t kUpdateNewArchivePostCharID = '!';
+static const unsigned kNumUpdatePairActions = 4;
+static const char *kUpdateIgnoreItselfPostStringID = "-";
+static const wchar_t kUpdateNewArchivePostCharID = '!';
static bool ParseUpdateCommandString2(const UString &command,
NUpdateArchive::CActionSet &actionSet, UString &postString)
{
- for (int i = 0; i < command.Length();)
+ for (unsigned i = 0; i < command.Len();)
{
- wchar_t c = MyCharUpper(command[i]);
- int statePos = kUpdatePairStateIDSet.Find(c);
+ wchar_t c = MyCharLower_Ascii(command[i]);
+ int statePos = FindCharPosInString(kUpdatePairStateIDSet, c);
if (statePos < 0)
{
- postString = command.Mid(i);
+ postString = command.Ptr(i);
return true;
}
i++;
- if (i >= command.Length())
+ if (i >= command.Len())
return false;
- int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i]));
- if (actionPos < 0)
+ c = command[i];
+ if (c < '0' || c >= '0' + kNumUpdatePairActions)
return false;
- actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos);
+ int actionPos = c - '0';
+ actionSet.StateActions[statePos] = (NUpdateArchive::NPairAction::EEnum)(actionPos);
if (kUpdatePairStateNotSupportedActions[statePos] == actionPos)
return false;
i++;
@@ -530,10 +699,12 @@ static void ParseUpdateCommandString(CUpdateOptions &options,
const UStringVector &updatePostStrings,
const NUpdateArchive::CActionSet &defaultActionSet)
{
- for (int i = 0; i < updatePostStrings.Size(); i++)
+ const char *errorMessage = "incorrect update switch command";
+ unsigned i;
+ for (i = 0; i < updatePostStrings.Size(); i++)
{
const UString &updateString = updatePostStrings[i];
- if (updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0)
+ if (updateString.IsEqualTo(kUpdateIgnoreItselfPostStringID))
{
if (options.UpdateArchiveItself)
{
@@ -547,7 +718,7 @@ static void ParseUpdateCommandString(CUpdateOptions &options,
UString postString;
if (!ParseUpdateCommandString2(updateString, actionSet, postString))
- ThrowUserErrorException();
+ break;
if (postString.IsEmpty())
{
if (options.UpdateArchiveItself)
@@ -555,64 +726,23 @@ static void ParseUpdateCommandString(CUpdateOptions &options,
}
else
{
- if (MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID)
- ThrowUserErrorException();
+ if (postString[0] != kUpdateNewArchivePostCharID)
+ break;
CUpdateArchiveCommand uc;
- UString archivePath = postString.Mid(1);
+ UString archivePath = postString.Ptr(1);
if (archivePath.IsEmpty())
- ThrowUserErrorException();
+ break;
uc.UserArchivePath = archivePath;
uc.ActionSet = actionSet;
options.Commands.Add(uc);
}
}
}
+ if (i != updatePostStrings.Size())
+ throw CArcCmdLineException(errorMessage, updatePostStrings[i]);
}
-static const char kByteSymbol = 'B';
-static const char kKiloSymbol = 'K';
-static const char kMegaSymbol = 'M';
-static const char kGigaSymbol = 'G';
-
-static bool ParseComplexSize(const UString &src, UInt64 &result)
-{
- UString s = src;
- s.MakeUpper();
-
- const wchar_t *start = s;
- const wchar_t *end;
- UInt64 number = ConvertStringToUInt64(start, &end);
- int numDigits = (int)(end - start);
- if (numDigits == 0 || s.Length() > numDigits + 1)
- return false;
- if (s.Length() == numDigits)
- {
- result = number;
- return true;
- }
- int numBits;
- switch (s[numDigits])
- {
- case kByteSymbol:
- result = number;
- return true;
- case kKiloSymbol:
- numBits = 10;
- break;
- case kMegaSymbol:
- numBits = 20;
- break;
- case kGigaSymbol:
- numBits = 30;
- break;
- default:
- return false;
- }
- if (number >= ((UInt64)1 << (64 - numBits)))
- return false;
- result = number << numBits;
- return true;
-}
+bool ParseComplexSize(const wchar_t *s, UInt64 &result);
static void SetAddCommandOptions(
NCommandType::EEnum commandType,
@@ -620,20 +750,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;
@@ -645,22 +775,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);
}
}
@@ -670,38 +800,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);
@@ -711,62 +831,67 @@ 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 _WIN32
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
}
struct CCodePagePair
{
- const wchar_t *Name;
- UINT CodePage;
+ const char *Name;
+ Int32 CodePage;
};
+static const unsigned kNumByteOnlyCodePages = 3;
+
static CCodePagePair g_CodePagePairs[] =
{
- { L"UTF-8", CP_UTF8 },
- { L"WIN", CP_ACP },
- { L"DOS", CP_OEMCP }
+ { "utf-8", CP_UTF8 },
+ { "win", CP_ACP },
+ { "dos", CP_OEMCP },
+ { "utf-16le", MY__CP_UTF16 },
+ { "utf-16be", MY__CP_UTF16BE }
};
-static int FindCharset(const NCommandLineParser::CParser &parser, int keyIndex, int defaultVal)
+static Int32 FindCharset(const NCommandLineParser::CParser &parser, int keyIndex,
+ bool byteOnlyCodePages, Int32 defaultVal)
{
if (!parser[keyIndex].ThereIs)
return defaultVal;
UString name = parser[keyIndex].PostStrings.Back();
- name.MakeUpper();
- int i;
- for (i = 0; i < sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]); i++)
+ UInt32 v;
+ if (StringToUInt32(name, v))
+ if (v < ((UInt32)1 << 16))
+ return (Int32)v;
+ name.MakeLower_Ascii();
+ unsigned num = byteOnlyCodePages ? kNumByteOnlyCodePages : ARRAY_SIZE(g_CodePagePairs);
+ for (unsigned i = 0;; i++)
{
+ if (i == num) // to disable warnings from different compilers
+ throw CArcCmdLineException("Unsupported charset:", name);
const CCodePagePair &pair = g_CodePagePairs[i];
- if (name.Compare(pair.Name) == 0)
+ if (name.IsEqualTo(pair.Name))
return pair.CodePage;
}
- if (i == sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]))
- ThrowUserErrorException();
- return -1;
-}
-
-static bool ConvertStringToUInt32(const wchar_t *s, UInt32 &v)
-{
- const wchar_t *end;
- UInt64 number = ConvertStringToUInt64(s, &end);
- if (*end != 0)
- return false;
- if (number > (UInt32)0xFFFFFFFF)
- return false;
- v = (UInt32)number;
- return true;
}
-void EnumerateDirItemsAndSort(NWildcard::CCensor &wildcardCensor,
+void EnumerateDirItemsAndSort(
+ bool storeAltStreams,
+ NWildcard::CCensor &censor,
+ NWildcard::ECensorPathMode censorPathMode,
+ const UString &addPathPrefix,
UStringVector &sortedPaths,
UStringVector &sortedFullPaths)
{
@@ -774,59 +899,92 @@ void EnumerateDirItemsAndSort(NWildcard::CCensor &wildcardCensor,
{
CDirItems dirItems;
{
- UStringVector errorPaths;
- CRecordVector<DWORD> errorCodes;
- HRESULT res = EnumerateItems(wildcardCensor, dirItems, NULL, errorPaths, errorCodes);
- if (res != S_OK || errorPaths.Size() > 0)
- throw "cannot find archive";
+ 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 (int i = 0; i < dirItems.Items.Size(); i++)
+ FOR_VECTOR (i, dirItems.Items)
{
const CDirItem &dirItem = dirItems.Items[i];
if (!dirItem.IsDir())
paths.Add(dirItems.GetPhyPath(i));
}
}
-
+
if (paths.Size() == 0)
- throw "there is no such archive";
-
+ throw CArcCmdLineException(kCannotFindArchive);
+
UStringVector fullPaths;
-
- int i;
+
+ unsigned i;
for (i = 0; i < paths.Size(); i++)
{
- UString fullPath;
- NFile::NDirectory::MyGetFullPathName(paths[i], fullPath);
- fullPaths.Add(fullPath);
+ FString fullPath;
+ NFile::NDir::MyGetFullPathName(us2fs(paths[i]), fullPath);
+ fullPaths.Add(fs2us(fullPath));
}
- CIntVector indices;
+ CUIntVector indices;
SortFileNames(fullPaths, indices);
- sortedPaths.Reserve(indices.Size());
- sortedFullPaths.Reserve(indices.Size());
+ sortedPaths.ClearAndReserve(indices.Size());
+ sortedFullPaths.ClearAndReserve(indices.Size());
for (i = 0; i < indices.Size(); i++)
{
- int index = indices[i];
- sortedPaths.Add(paths[index]);
- sortedFullPaths.Add(fullPaths[index]);
+ unsigned index = indices[i];
+ sortedPaths.AddInReserved(paths[index]);
+ sortedFullPaths.AddInReserved(fullPaths[index]);
+ if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0)
+ throw CArcCmdLineException("Duplicate archive path:", sortedFullPaths[i]);
}
}
-void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
+static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp)
+{
+ bp.Def = parser[switchID].ThereIs;
+ if (bp.Def)
+ bp.Val = !parser[switchID].WithMinus;
+}
+
+void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
{
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
int numNonSwitchStrings = nonSwitchStrings.Size();
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)
@@ -834,43 +992,55 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
else
recursedType = NRecursedType::kNonRecursed;
- g_CodePage = FindCharset(parser, NKey::kConsoleCharSet, -1);
- UINT codePage = FindCharset(parser, NKey::kListfileCharSet, CP_UTF8);
+ bool wildcardMatching = true;
+ if (parser[NKey::kDisableWildcardParsing].ThereIs)
+ wildcardMatching = false;
+
+ g_CodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1);
+ Int32 codePage = FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8);
bool thereAreSwitchIncludes = false;
+
if (parser[NKey::kInclude].ThereIs)
{
thereAreSwitchIncludes = true;
- AddSwitchWildCardsToCensor(options.WildcardCensor,
- parser[NKey::kInclude].PostStrings, true, recursedType, codePage);
+ AddSwitchWildcardsToCensor(options.Censor,
+ parser[NKey::kInclude].PostStrings, true, recursedType, wildcardMatching, codePage);
}
+
if (parser[NKey::kExclude].ThereIs)
- AddSwitchWildCardsToCensor(options.WildcardCensor,
- parser[NKey::kExclude].PostStrings, false, recursedType, codePage);
-
+ AddSwitchWildcardsToCensor(options.Censor,
+ parser[NKey::kExclude].PostStrings, false, recursedType, wildcardMatching, codePage);
+
int curCommandIndex = kCommandIndex + 1;
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;
@@ -886,28 +1056,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;
+
+ 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();
- NWildcard::CCensor archiveWildcardCensor;
+ // 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);
+ AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, wildcardMatching, codePage);
if (thereIsArchiveName)
- AddNameToCensor(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);
+ AddNameToCensor(arcCensor, options.ArchiveName, true, NRecursedType::kNonRecursed, wildcardMatching);
+
+ arcCensor.AddPathsToCensor(NWildcard::k_RelatPath);
#ifdef _WIN32
- ConvertToLongNames(archiveWildcardCensor);
+ ConvertToLongNames(arcCensor);
#endif
- archiveWildcardCensor.ExtendExclude();
+ arcCensor.ExtendExclude();
if (options.StdInMode)
{
@@ -917,54 +1132,76 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
}
else
{
- EnumerateDirItemsAndSort(archiveWildcardCensor,
- options.ArchivePathsSorted,
- options.ArchivePathsFullSorted);
+ EnumerateDirItemsAndSort(
+ false, // scanAltStreams
+ arcCensor,
+ NWildcard::k_RelatPath,
+ UString(), // addPathPrefix
+ options.ArchivePathsSorted,
+ options.ArchivePathsFullSorted);
}
-
+
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);
+
+ updateOptions.MethodMode.Properties = options.Properties;
if (parser[NKey::kShareForWrite].ThereIs)
updateOptions.OpenShareForWrite = true;
- options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs;
+ updateOptions.PathMode = censorPathMode;
- if (options.EnablePercents)
- {
- if ((options.StdOutMode && !options.IsStdErrTerminal) ||
- (!options.StdOutMode && !options.IsStdOutTerminal))
- options.EnablePercents = false;
- }
+ updateOptions.AltStreams = options.AltStreams;
+ updateOptions.NtSecurity = options.NtSecurity;
+ updateOptions.HardLinks = options.HardLinks;
+ updateOptions.SymLinks = options.SymLinks;
updateOptions.EMailMode = parser[NKey::kEmail].ThereIs;
if (updateOptions.EMailMode)
{
updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front();
- if (updateOptions.EMailAddress.Length() > 0)
+ if (updateOptions.EMailAddress.Len() > 0)
if (updateOptions.EMailAddress[0] == L'.')
{
updateOptions.EMailRemoveAfter = true;
@@ -975,68 +1212,46 @@ 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;
+ if (parser[NKey::kShareForWrite].ThereIs)
+ hashOptions.OpenShareForWrite = true;
+ hashOptions.StdInMode = options.StdInMode;
+ hashOptions.AltStreamsMode = options.AltStreams.Val;
+ }
else if (options.Command.CommandType == NCommandType::kInfo)
{
}
else
- ThrowUserErrorException();
- options.WildcardCensor.ExtendExclude();
+ throw 9815676711;
}
diff --git a/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveCommandLine.h b/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveCommandLine.h
index e8f601df4..87e6619e6 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveCommandLine.h
+++ b/src/libs/7zip/win/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 _WIN32
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/win/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
index 4c0cc90b5..250f66797 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveExtractCallback.h
index 367e4b07d..fe7ef42bb 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveExtractCallback.h
+++ b/src/libs/7zip/win/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
+
+#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/win/CPP/7zip/UI/Common/ArchiveName.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveName.cpp
deleted file mode 100644
index c3684def8..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/ArchiveName.h b/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveName.h
deleted file mode 100644
index 9513fb2ba..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
index e7e617131..4157aa4f1 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
+++ b/src/libs/7zip/win/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,41 +60,32 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
COM_TRY_END
}
-int COpenCallbackImp::FindName(const UString &name)
-{
- for (int i = 0; i < FileNames.Size(); i++)
- if (name.CompareNoCase(FileNames[i]) == 0)
- return i;
- return -1;
-}
-
struct CInFileStreamVol: public CInFileStream
{
- UString Name;
+ int FileNameIndex;
COpenCallbackImp *OpenCallbackImp;
CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
+
~CInFileStreamVol()
{
if (OpenCallbackRef)
- {
- int index = OpenCallbackImp->FindName(Name);
- if (index >= 0)
- OpenCallbackImp->FileNames.Delete(index);
- }
+ OpenCallbackImp->FileNames_WasUsed[FileNameIndex] = false;
}
};
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;
+ FString fullPath;
+ if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name), fullPath))
+ return S_FALSE;
if (!_fileInfo.Find(fullPath))
return S_FALSE;
if (_fileInfo.IsDir())
@@ -103,12 +94,14 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre
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/win/CPP/7zip/UI/Common/ArchiveOpenCallback.h b/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveOpenCallback.h
index c6651e8f9..3352eadef 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/ArchiveOpenCallback.h
+++ b/src/libs/7zip/win/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;
+ 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/win/CPP/7zip/UI/Common/Bench.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/Bench.cpp
deleted file mode 100644
index 282f405f1..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/Bench.h b/src/libs/7zip/win/CPP/7zip/UI/Common/Bench.h
deleted file mode 100644
index a8d02a19b..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/Common.pri b/src/libs/7zip/win/CPP/7zip/UI/Common/Common.pri
new file mode 100644
index 000000000..9d829d2af
--- /dev/null
+++ b/src/libs/7zip/win/CPP/7zip/UI/Common/Common.pri
@@ -0,0 +1,44 @@
+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/StdAfx.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/win/CPP/7zip/UI/Common/DefaultName.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/DefaultName.cpp
index 4335e2731..ce0b327b5 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/DefaultName.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/DefaultName.h b/src/libs/7zip/win/CPP/7zip/UI/Common/DefaultName.h
index 9764ff871..df1645602 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/DefaultName.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/DirItem.h b/src/libs/7zip/win/CPP/7zip/UI/Common/DirItem.h
index 29cc60d93..82203c03a 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/DirItem.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/EnumDirItems.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/EnumDirItems.cpp
index ba03ea35c..1e9562a0e 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/EnumDirItems.cpp
+++ b/src/libs/7zip/win/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;
+ 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
{
- NFind::CEnumeratorW enumerator(phyPrefix + (wchar_t)kAnyStringWildcard);
+ #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, (PSECURITY_DESCRIPTOR)(Byte *)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, (PSECURITY_DESCRIPTOR)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize);
+ if (res)
+ {
+ if (secureSize != TempSecureBuf.Size())
+ errorCode = ERROR_INVALID_FUNCTION;;
+ }
+ else
+ errorCode = GetLastError();
+ }
+ }
+ }
+ if (res)
+ {
+ secureIndex = SecureBlocks.AddUniq(TempSecureBuf, secureSize);
+ return;
+ }
+ if (errorCode == 0)
+ errorCode = ERROR_INVALID_FUNCTION;
+ AddError(path, errorCode);
+}
+
+#endif
+
+void CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phyPrefix)
+{
+ 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;
}
+#ifndef UNDER_CE
+
+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)
+{
+ 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;
+ }
+
+ #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 UString &phyPrefix,
+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,
- UStringVector &errorPaths,
- CRecordVector<DWORD> &errorCodes)
+ 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);
+
+ #ifndef UNDER_CE
+ {
+ CDirItem &dirItem = dirItems.Items.Back();
+ dirItems.SetLinkInfo(dirItem, fi, phyPrefix);
+ if (dirItem.ReparseData.Size() != 0)
+ continue;
+ }
+ #endif
+
+ dirItems.TotalSize += fi.Size;
+
+ #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;
+ 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))
{
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/win/CPP/7zip/UI/Common/EnumDirItems.h b/src/libs/7zip/win/CPP/7zip/UI/Common/EnumDirItems.h
index d0ce950e3..803a64e7d 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/EnumDirItems.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/ExitCode.h b/src/libs/7zip/win/CPP/7zip/UI/Common/ExitCode.h
deleted file mode 100644
index b6d7d4dfc..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/Extract.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/Extract.cpp
index ca2c8c73d..13d2ad29a 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/Extract.cpp
+++ b/src/libs/7zip/win/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];
+ const FString &arcPath = us2fs(arcPaths[i]);
if (!fi.Find(arcPath))
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)) || 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/win/CPP/7zip/UI/Common/Extract.h b/src/libs/7zip/win/CPP/7zip/UI/Common/Extract.h
index 5a939ed23..052b2f7d3 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/Extract.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/ExtractMode.h b/src/libs/7zip/win/CPP/7zip/UI/Common/ExtractMode.h
index b448fb30a..a54376705 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/ExtractMode.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/ExtractingFilePath.cpp
index 8f31708b6..852fd5adb 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/ExtractingFilePath.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/ExtractingFilePath.h b/src/libs/7zip/win/CPP/7zip/UI/Common/ExtractingFilePath.h
index da28bfc23..751248a97 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/ExtractingFilePath.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/HashCalc.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/HashCalc.cpp
new file mode 100644
index 000000000..2d13a2af1
--- /dev/null
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/HashCalc.h b/src/libs/7zip/win/CPP/7zip/UI/Common/HashCalc.h
new file mode 100644
index 000000000..68e2404cc
--- /dev/null
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/IFileExtractCallback.h b/src/libs/7zip/win/CPP/7zip/UI/Common/IFileExtractCallback.h
index e8dcdce5f..7bb852795 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/IFileExtractCallback.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/LoadCodecs.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/LoadCodecs.cpp
index 856e47fbc..a1d801b04 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/LoadCodecs.cpp
+++ b/src/libs/7zip/win/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,84 +31,167 @@ static const UINT kIconTypesResId = 100;
#endif
#ifdef _WIN32
-#include "Windows/Registry.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/Registry.h"
#endif
-using namespace NWindows;
using namespace NFile;
#ifdef _WIN32
extern HINSTANCE g_hInstance;
#endif
-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
- return CSysString(); // FIX IT
- #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();
+ 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;
}
@@ -111,34 +203,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)
@@ -146,13 +252,14 @@ static HRESULT ReadProp(
return getProp(propID, &prop);
}
-static HRESULT ReadBoolProp(
- GetHandlerPropertyFunc getProp,
- GetHandlerPropertyFunc2 getProp2,
+static HRESULT GetProp_Bool(
+ Func_GetHandlerProperty getProp,
+ Func_GetHandlerProperty2 getProp2,
UInt32 index, PROPID propID, bool &res)
{
+ res = false;
NCOM::CPropVariant prop;
- RINOK(ReadProp(getProp, getProp2, index, propID, prop));
+ RINOK(GetProp(getProp, getProp2, index, propID, prop));
if (prop.vt == VT_BOOL)
res = VARIANT_BOOLToBool(prop.boolVal);
else if (prop.vt != VT_EMPTY)
@@ -160,132 +267,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(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;
@@ -294,25 +419,26 @@ HRESULT CCodecs::LoadFormats()
#ifdef NEW_FOLDER_INTERFACE
void CCodecIcons::LoadIcons(HMODULE m)
{
- 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;
}
}
@@ -324,10 +450,10 @@ void CCodecIcons::LoadIcons(HMODULE m)
bool CCodecIcons::FindIconIndex(const UString &ext, int &iconIndex) const
{
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;
@@ -335,7 +461,8 @@ bool CCodecIcons::FindIconIndex(const UString &ext, int &iconIndex) const
}
return false;
}
-#endif
+
+#endif // EXTERNAL_CODECS
#ifdef _7ZIP_LARGE_PAGES
extern "C"
@@ -344,7 +471,7 @@ extern "C"
}
#endif
-HRESULT CCodecs::LoadDll(const CSysString &dllPath, bool needCheckDll)
+HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll)
{
if (needCheckDll)
{
@@ -354,9 +481,7 @@ HRESULT CCodecs::LoadDll(const CSysString &dllPath, bool needCheckDll)
}
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))
@@ -368,23 +493,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)
+ {
+ 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)
{
- int startSize = Codecs.Size();
+ 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;
}
}
}
@@ -393,9 +526,9 @@ HRESULT CCodecs::LoadDll(const CSysString &dllPath, bool needCheckDll)
return res;
}
-HRESULT CCodecs::LoadDllsFromFolder(const CSysString &folderPrefix)
+HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPrefix)
{
- NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
+ NFile::NFind::CEnumerator enumerator(folderPrefix + FCHAR_ANY_MASK);
NFile::NFind::CFileInfo fi;
while (enumerator.Next(fi))
{
@@ -408,46 +541,63 @@ 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
- InternalIcons.LoadIcons(g_hInstance);
+ InternalIcons.LoadIcons(g_hInstance);
#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;
}
@@ -455,17 +605,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;
+ if (ext.IsEqualToNoCase(L"exe"))
return -1;
- UString ext = arcPath.Mid(dotPos + 1);
- for (int i = 0; i < Formats.Size(); i++)
+ FOR_VECTOR (i, Formats)
{
const CArcInfoEx &arc = Formats[i];
+ /*
if (!arc.UpdateEnabled)
continue;
+ */
if (arc.FindExtension(ext) >= 0)
return i;
}
@@ -476,7 +631,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;
@@ -484,8 +639,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;
}
@@ -493,12 +648,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"*")
{
@@ -511,24 +668,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;
}
@@ -539,27 +711,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)
+ if (propID == NMethodPropID::kDecoderIsAssigned ||
+ propID == NMethodPropID::kEncoderIsAssigned)
{
- NWindows::NCOM::CPropVariant propVariant;
- propVariant = ci.DecoderIsAssigned;
- propVariant.Detach(value);
- return S_OK;
- }
- if (propID == NMethodPropID::kEncoderIsAssigned)
- {
- NWindows::NCOM::CPropVariant propVariant;
- propVariant = ci.EncoderIsAssigned;
- propVariant.Detach(value);
+ NCOM::CPropVariant prop;
+ prop = (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)
@@ -568,14 +736,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)
@@ -584,35 +752,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)
@@ -622,11 +808,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;
@@ -638,7 +834,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;
@@ -646,11 +842,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;
@@ -659,8 +851,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;
@@ -671,11 +862,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/win/CPP/7zip/UI/Common/LoadCodecs.h b/src/libs/7zip/win/CPP/7zip/UI/Common/LoadCodecs.h
index a633dd2e1..d254ae659 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/LoadCodecs.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/OpenArchive.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/OpenArchive.cpp
index 56a630467..4efbc9cc7 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/src/libs/7zip/win/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;
}
- while (i != 0xFF);
+
+ 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;
+ }
+ 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;
+
+ // UInt32 maxSignatureEnd = 0;
- #ifdef EXTERNAL_CODECS
+ 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
{
- RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));
+ 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)
+ {
+ 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;
+ fileStreamSpec = new CInFileStream;
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,238 @@ 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;
+
+ op.types = &inc;
+ op.excludedFormats = &excl;
+ op.stdInMode = false;
+ op.stream = NULL;
+ if (Arcs.Size() == 0) // ???
+ return Open2(op, NULL);
CMyComPtr<IArchiveOpenCallback> openCallbackNew;
- SetCallback(filePath, NULL, callback, openCallbackNew);
+ SetCallback(us2fs(op.filePath), NULL, op.callback, openCallbackNew);
CInFileStream *fileStreamSpec = new CInFileStream;
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/win/CPP/7zip/UI/Common/OpenArchive.h b/src/libs/7zip/win/CPP/7zip/UI/Common/OpenArchive.h
index 4a003ee63..2ee743adc 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/OpenArchive.h
+++ b/src/libs/7zip/win/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),
+ EachPos(false),
+ CanReturnArc(true),
+ CanReturnParser(false),
+ // SkipSfxStub(true),
+ // ExeAsUnknown(true),
+ ZerosTailIsAllowed(false),
+ MaxStartOffset_Defined(false),
+ MaxStartOffset(0)
+ {
+ SpecForcedType.CanReturnFrontal = true;
+ SpecForcedType.CanReturnTail = true;
+ SpecForcedType.CanReturnMid = true;
+
+ SpecMainType.CanReturnFrontal = true;
+
+ SpecUnknownExt.CanReturnTail = true; // for sfx
+ SpecUnknownExt.CanReturnMid = true;
+ SpecUnknownExt.CanReturnFrontal = true; // for alt streams of sfx with pad
+
+ // ZerosTailIsAllowed = true;
+ }
+};
+
+struct COpenOptions
+{
+ CCodecs *codecs;
+ COpenType openType;
+ const CObjectVector<COpenType> *types;
+ const CIntVector *excludedFormats;
+
+ IInStream *stream;
+ ISequentialInStream *seqStream;
+ IArchiveOpenCallback *callback;
+ COpenCallbackImp *callbackSpec;
+ OPEN_PROPS_DECL
+ // bool openOnlySpecifiedByExtension,
+
+ bool stdInMode;
+ UString filePath;
+
+ COpenOptions():
+ codecs(NULL),
+ types(NULL),
+ excludedFormats(NULL),
+ stream(NULL),
+ seqStream(NULL),
+ callback(NULL),
+ callbackSpec(NULL),
+ stdInMode(false)
+ {}
+
+};
+
+UInt32 GetOpenArcErrorFlags(const NWindows::NCOM::CPropVariant &prop, bool *isDefinedProp = NULL);
+
+struct CArcErrorInfo
+{
+ bool ThereIsTail;
+ bool UnexpecedEnd;
+ bool IgnoreTail; // all are zeros
+ // bool NonZerosTail;
+ bool ErrorFlags_Defined;
+ UInt32 ErrorFlags;
+ UInt32 WarningFlags;
+ int ErrorFormatIndex; // - 1 means no Error.
+ // if FormatIndex == ErrorFormatIndex, the archive is open with offset
+ UInt64 TailSize;
+
+ /* if CArc is Open OK with some format:
+ - ErrorFormatIndex shows error format index, if extension is incorrect
+ - other variables show message and warnings of archive that is open */
+
+ UString ErrorMessage;
+ UString WarningMessage;
+
+ // call IsArc_After_NonOpen only if Open returns S_FALSE
+ bool IsArc_After_NonOpen() const
+ {
+ return (ErrorFlags_Defined && (ErrorFlags & kpv_ErrorFlags_IsNotArc) == 0);
+ }
+
+
+ CArcErrorInfo():
+ ThereIsTail(false),
+ UnexpecedEnd(false),
+ IgnoreTail(false),
+ // NonZerosTail(false),
+ ErrorFlags_Defined(false),
+ ErrorFlags(0),
+ WarningFlags(0),
+ ErrorFormatIndex(-1),
+ TailSize(0)
+ {}
+
+ void ClearErrors();
+
+ void ClearErrors_Full()
+ {
+ ErrorFormatIndex = -1;
+ ClearErrors();
+ }
+
+ bool IsThereErrorOrWarning() const
+ {
+ return ErrorFlags != 0
+ || WarningFlags != 0
+ || NeedTailWarning()
+ || UnexpecedEnd
+ || !ErrorMessage.IsEmpty()
+ || !WarningMessage.IsEmpty();
+ }
+
+ bool AreThereErrors() const { return ErrorFlags != 0 || UnexpecedEnd; }
+ bool AreThereWarnings() const { return WarningFlags != 0 || NeedTailWarning(); }
+
+ bool NeedTailWarning() const { return !IgnoreTail && ThereIsTail; }
+
+ UInt32 GetWarningFlags() const
+ {
+ UInt32 a = WarningFlags;
+ if (NeedTailWarning() && (ErrorFlags & kpv_ErrorFlags_DataAfterEnd) == 0)
+ a |= kpv_ErrorFlags_DataAfterEnd;
+ return a;
+ }
+
+ UInt32 GetErrorFlags() const
+ {
+ UInt32 a = ErrorFlags;
+ if (UnexpecedEnd)
+ a |= kpv_ErrorFlags_UnexpectedEnd;
+ return a;
+ }
+};
+
+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/win/CPP/7zip/UI/Common/PropIDUtils.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/PropIDUtils.cpp
index dacaca5f9..8f27cc0d1 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/PropIDUtils.cpp
+++ b/src/libs/7zip/win/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,467 @@ 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
+
+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
diff --git a/src/libs/7zip/win/CPP/7zip/UI/Common/PropIDUtils.h b/src/libs/7zip/win/CPP/7zip/UI/Common/PropIDUtils.h
index ca14d091d..3ee2981de 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/PropIDUtils.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/Property.h b/src/libs/7zip/win/CPP/7zip/UI/Common/Property.h
index 9fd340cbc..8b57a2a64 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/Property.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/SetProperties.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/SetProperties.cpp
index 4827f2a78..64b9d92a6 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/SetProperties.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/SortUtils.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/SortUtils.cpp
index 061e77730..b7e422a29 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/SortUtils.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/SortUtils.h b/src/libs/7zip/win/CPP/7zip/UI/Common/SortUtils.h
index e15224611..8e42e0682 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/SortUtils.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/StdAfx.h b/src/libs/7zip/win/CPP/7zip/UI/Common/StdAfx.h
index 9a8e7d21a..2854ff3e9 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/StdAfx.h
+++ b/src/libs/7zip/win/CPP/7zip/UI/Common/StdAfx.h
@@ -1,9 +1,8 @@
-// stdafx.h
+// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../../Common/MyWindows.h"
-#include "../../../Common/NewHandler.h"
+#include "../../../Common/Common.h"
#endif
diff --git a/src/libs/7zip/win/CPP/7zip/UI/Common/TempFiles.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/TempFiles.cpp
index eeaec1802..0c13ae158 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/TempFiles.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/TempFiles.h b/src/libs/7zip/win/CPP/7zip/UI/Common/TempFiles.h
index eb474a760..4099e6558 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/TempFiles.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/Update.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/Update.cpp
index a57ec2a6b..e3d538f10 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/Update.cpp
+++ b/src/libs/7zip/win/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,9 +36,33 @@ static const char *kUpdateIsNotSupoorted =
using namespace NWindows;
using namespace NCOM;
using namespace NFile;
+using namespace NDir;
using namespace NName;
-static const wchar_t *kTempFolderPrefix = L"7zE";
+static CFSTR kTempFolderPrefix = FTEXT("7zE");
+
+
+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;
@@ -48,24 +70,24 @@ 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()
@@ -76,6 +98,7 @@ public:
_length = 0;
}
+ bool SetMTime(const FILETIME *mTime);
HRESULT Close();
MY_UNKNOWN_IMP1(IOutStream)
@@ -90,12 +113,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;
}
@@ -103,40 +126,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];
@@ -147,29 +183,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;
@@ -185,17 +221,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)
@@ -208,24 +238,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();
}
@@ -235,7 +265,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";
@@ -243,40 +333,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;
}
@@ -286,7 +394,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);
@@ -298,36 +406,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
{
@@ -342,12 +512,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:
@@ -358,8 +528,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!!!
@@ -368,61 +599,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);
@@ -445,12 +696,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();
@@ -462,29 +717,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();
@@ -500,9 +755,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)
@@ -510,7 +817,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)
{
@@ -518,23 +827,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;
@@ -542,7 +849,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:
@@ -555,99 +862,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)
@@ -661,40 +971,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 = NDLL::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)
+ {
+ 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::CFileInfoW fi;
- if (fi.Find(arcPath))
+ 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)
{
@@ -702,21 +1068,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;
@@ -730,7 +1123,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)
@@ -738,12 +1132,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)
{
@@ -752,14 +1155,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);
@@ -773,8 +1208,6 @@ HRESULT UpdateArchive(
bool createTempFile = false;
- bool thereIsInArchive = arcLink.IsOpen;
-
if (!options.StdOutMode && options.UpdateArchiveItself)
{
CArchivePath &ap = options.Commands[0].ArchivePath;
@@ -785,27 +1218,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;
@@ -819,13 +1253,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)
{
@@ -839,21 +1324,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;
}
}
@@ -863,30 +1348,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";
@@ -895,16 +1392,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/win/CPP/7zip/UI/Common/Update.h b/src/libs/7zip/win/CPP/7zip/UI/Common/Update.h
index ade001303..ff53cd992 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/Update.h
+++ b/src/libs/7zip/win/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;
- bool Init(const CCodecs *codecs, const CIntVector &formatIndices, const UString &arcPath);
+ CBoolPair NtSecurity;
+ CBoolPair AltStreams;
+ CBoolPair HardLinks;
+ CBoolPair SymLinks;
+
+ bool DeleteAfterCompressing;
+
+ bool SetArcMTime;
+
+ CObjectVector<CRenamePair> RenamePairs;
+
+ bool InitFormatIndex(const CCodecs *codecs, const CObjectVector<COpenType> &types, const UString &arcPath);
+ bool SetArcPath(const CCodecs *codecs, const UString &arcPath);
CUpdateOptions():
UpdateArchiveItself(true),
SfxMode(false),
- OpenShareForWrite(false),
StdInMode(false),
StdOutMode(false),
EMailMode(false),
- EMailRemoveAfter(false)
+ EMailRemoveAfter(false),
+ OpenShareForWrite(false),
+ ArcNameMode(k_ArcNameMode_Smart),
+ PathMode(NWildcard::k_RelatPath),
+
+ DeleteAfterCompressing(false),
+ SetArcMTime(false)
+
{};
- void SetAddActionCommand()
+ void SetActionCommand_Add()
{
Commands.Clear();
CUpdateArchiveCommand c;
- c.ActionSet = NUpdateArchive::kAddActionSet;
+ c.ActionSet = NUpdateArchive::k_ActionSet_Add;
Commands.Add(c);
}
@@ -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/win/CPP/7zip/UI/Common/UpdateAction.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/UpdateAction.cpp
index 879a49c57..a80db7212 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/UpdateAction.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/UpdateAction.h b/src/libs/7zip/win/CPP/7zip/UI/Common/UpdateAction.h
index 0ac1c1080..8c7609fb4 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/UpdateAction.h
+++ b/src/libs/7zip/win/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];
+
+ const 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/win/CPP/7zip/UI/Common/UpdateCallback.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/UpdateCallback.cpp
index 0f229058c..e490cde24 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/UpdateCallback.cpp
+++ b/src/libs/7zip/win/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;
+ #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)
+ {
+ #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,59 @@ 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 (StoreHardLinks)
+ {
+ CStreamFileProps props;
+ if (inStreamSpec->GetProps2(&props) == S_OK)
+ {
+ if (props.NumLinks > 1)
+ {
+ CKeyKeyValPair pair;
+ pair.Key1 = props.VolID;
+ pair.Key2 = props.FileID_Low;
+ pair.Value = index;
+ unsigned numItems = _map.Size();
+ unsigned pairIndex = _map.AddToUniqueSorted2(pair);
+ if (numItems == _map.Size())
+ {
+ // const CKeyKeyValPair &pair2 = _map.Pairs[pairIndex];
+ _hardIndex_From = index;
+ _hardIndex_To = pairIndex;
+ // we could return NULL as stream, but it's better to return real stream
+ // return S_OK;
+ }
+ }
+ }
+ }
+
+ if (ProcessedItemsStatuses)
+ {
+ NSynchronization::CCriticalSectionLock lock(CS);
+ ProcessedItemsStatuses[up.DirIndex] = 1;
+ }
*inStream = inStreamLoc.Detach();
}
+
return S_OK;
COM_TRY_END
}
@@ -216,12 +541,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/win/CPP/7zip/UI/Common/UpdateCallback.h b/src/libs/7zip/win/CPP/7zip/UI/Common/UpdateCallback.h
index 9a20c3159..81982e61d 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/UpdateCallback.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/UpdatePair.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.cpp
index a43a9e770..95afdd694 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.cpp
+++ b/src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.cpp
@@ -4,10 +4,9 @@
#include <time.h>
-#include "Common/Defs.h"
-#include "Common/Wildcard.h"
+#include "../../../Common/Wildcard.h"
-#include "Windows/Time.h"
+#include "../../../Windows/TimeUtils.h"
#include "SortUtils.h"
#include "UpdatePair.h"
@@ -17,7 +16,7 @@ using namespace NTime;
static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time1, const FILETIME &time2)
{
- switch(fileTimeType)
+ switch (fileTimeType)
{
case NFileTimeType::kWindows:
return ::CompareFileTime(&time1, &time2);
@@ -39,24 +38,38 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time
throw 4191618;
}
-static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:";
-static const wchar_t *kNotCensoredCollisionMessaged = L"Internal file name collision (file on disk, file in archive):";
+static const char *k_Duplicate_inArc_Message = "Duplicate filename in archive:";
+static const char *k_Duplicate_inDir_Message = "Duplicate filename on disk:";
+static const char *k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):";
-static void ThrowError(const UString &message, const UString &s1, const UString &s2)
+static void ThrowError(const char *message, const UString &s1, const UString &s2)
{
- UString m = message;
- m += L'\n';
- m += s1;
- m += L'\n';
- m += s2;
+ UString m;
+ m.SetFromAscii(message);
+ m += 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(
@@ -65,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);
+ {
+ int *vals = &duplicatedArcItem[0];
+ for (unsigned i = 0; i < numArcItems; i++)
+ vals[i] = 0;
+ }
+
{
- UStringVector arcNames;
- arcNames.Reserve(numArcItems);
- for (int i = 0; i < numArcItems; i++)
- arcNames.Add(arcItems[i].Name);
- SortFileNames(arcNames, arcIndices);
- TestDuplicateString(arcNames, arcIndices);
+ 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;
@@ -114,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/win/CPP/7zip/UI/Common/UpdatePair.h b/src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.h
index 3a332649c..296d3b097 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/UpdatePair.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/UpdateProduce.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/UpdateProduce.cpp
index c21db3b2a..2c4c28583 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/UpdateProduce.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/UpdateProduce.h b/src/libs/7zip/win/CPP/7zip/UI/Common/UpdateProduce.h
index e18648cd9..ef7b0f7a3 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Common/UpdateProduce.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/WorkDir.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/WorkDir.cpp
deleted file mode 100644
index 164118e2c..000000000
--- a/src/libs/7zip/win/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;
- #ifndef UNDER_CE
- 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/win/CPP/7zip/UI/Common/WorkDir.h b/src/libs/7zip/win/CPP/7zip/UI/Common/WorkDir.h
deleted file mode 100644
index 0643d67a4..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Common/ZipRegistry.h b/src/libs/7zip/win/CPP/7zip/UI/Common/ZipRegistry.h
deleted file mode 100644
index 378353868..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Console/BenchCon.cpp b/src/libs/7zip/win/CPP/7zip/UI/Console/BenchCon.cpp
deleted file mode 100644
index 35e868c9b..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Console/BenchCon.h b/src/libs/7zip/win/CPP/7zip/UI/Console/BenchCon.h
deleted file mode 100644
index 966a83a6a..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Console/Console.pri b/src/libs/7zip/win/CPP/7zip/UI/Console/Console.pri
new file mode 100644
index 000000000..14668f8b3
--- /dev/null
+++ b/src/libs/7zip/win/CPP/7zip/UI/Console/Console.pri
@@ -0,0 +1,4 @@
+HEADERS += $$7ZIP_BASE/CPP/7zip/UI/Console/PercentPrinter.h \
+ $$7ZIP_BASE/CPP/7zip/UI/Common/StdAfx.h
+
+SOURCES += $$7ZIP_BASE/CPP/7zip/UI/Console/PercentPrinter.cpp
diff --git a/src/libs/7zip/win/CPP/7zip/UI/Console/ConsoleClose.cpp b/src/libs/7zip/win/CPP/7zip/UI/Console/ConsoleClose.cpp
deleted file mode 100644
index 5acae942d..000000000
--- a/src/libs/7zip/win/CPP/7zip/UI/Console/ConsoleClose.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// ConsoleClose.cpp
-
-#include "StdAfx.h"
-
-#include "ConsoleClose.h"
-
-static int g_BreakCounter = 0;
-static const int kBreakAbortThreshold = 2;
-
-namespace NConsoleClose {
-
-#if !defined(UNDER_CE) && defined(_WIN32)
-static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
-{
- if (ctrlType == CTRL_LOGOFF_EVENT)
- {
- // printf("\nCTRL_LOGOFF_EVENT\n");
- return TRUE;
- }
-
- g_BreakCounter++;
- if (g_BreakCounter < kBreakAbortThreshold)
- return TRUE;
- return FALSE;
- /*
- switch(ctrlType)
- {
- case CTRL_C_EVENT:
- case CTRL_BREAK_EVENT:
- if (g_BreakCounter < kBreakAbortThreshold)
- return TRUE;
- }
- return FALSE;
- */
-}
-#endif
-
-bool TestBreakSignal()
-{
- #ifdef UNDER_CE
- return false;
- #else
- /*
- if (g_BreakCounter > 0)
- return true;
- */
- return (g_BreakCounter > 0);
- #endif
-}
-
-void CheckCtrlBreak()
-{
- if (TestBreakSignal())
- throw CCtrlBreakException();
-}
-
-CCtrlHandlerSetter::CCtrlHandlerSetter()
-{
- #if !defined(UNDER_CE) && defined(_WIN32)
- if(!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
- throw "SetConsoleCtrlHandler fails";
- #endif
-}
-
-CCtrlHandlerSetter::~CCtrlHandlerSetter()
-{
- #if !defined(UNDER_CE) && defined(_WIN32)
- if(!SetConsoleCtrlHandler(HandlerRoutine, FALSE))
- throw "SetConsoleCtrlHandler fails";
- #endif
-}
-
-}
diff --git a/src/libs/7zip/win/CPP/7zip/UI/Console/ConsoleClose.h b/src/libs/7zip/win/CPP/7zip/UI/Console/ConsoleClose.h
deleted file mode 100644
index 9019c4ce2..000000000
--- a/src/libs/7zip/win/CPP/7zip/UI/Console/ConsoleClose.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// ConsoleCloseUtils.h
-
-#ifndef __CONSOLECLOSEUTILS_H
-#define __CONSOLECLOSEUTILS_H
-
-namespace NConsoleClose {
-
-bool TestBreakSignal();
-
-class CCtrlHandlerSetter
-{
-public:
- CCtrlHandlerSetter();
- virtual ~CCtrlHandlerSetter();
-};
-
-class CCtrlBreakException
-{};
-
-void CheckCtrlBreak();
-
-}
-
-#endif
diff --git a/src/libs/7zip/win/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/src/libs/7zip/win/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
deleted file mode 100644
index af65739c3..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Console/ExtractCallbackConsole.h b/src/libs/7zip/win/CPP/7zip/UI/Console/ExtractCallbackConsole.h
deleted file mode 100644
index e42ca6f40..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Console/List.cpp b/src/libs/7zip/win/CPP/7zip/UI/Console/List.cpp
deleted file mode 100644
index f747cfda8..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Console/List.h b/src/libs/7zip/win/CPP/7zip/UI/Console/List.h
deleted file mode 100644
index 97d9fb15a..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Console/Main.cpp b/src/libs/7zip/win/CPP/7zip/UI/Console/Main.cpp
deleted file mode 100644
index 9bd451f83..000000000
--- a/src/libs/7zip/win/CPP/7zip/UI/Console/Main.cpp
+++ /dev/null
@@ -1,598 +0,0 @@
-// Main.cpp
-
-#include "StdAfx.h"
-
-#if defined( _WIN32) && 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"
-
-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";
-
-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"
- " -ssw: compress shared files\n"
- " -t{Type}: Set type of archive\n"
- " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n"
- " -v{Size}[b|k|m|g]: Create volumes\n"
- " -w[{path}]: assign Work directory. Empty path means a temporary directory\n"
- " -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n"
- " -y: assume Yes on all queries\n";
-
-// ---------------------------
-// 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;
- // s << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << "\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);
- #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(_WIN32) && defined(_7ZIP_LARGE_PAGES)
- if (options.LargePages)
- {
- SetLargePageSize();
- NSecurity::EnableLockMemoryPrivilege();
- }
- #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);
-
- 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/win/CPP/7zip/UI/Console/MainAr.cpp b/src/libs/7zip/win/CPP/7zip/UI/Console/MainAr.cpp
deleted file mode 100644
index c54a3d098..000000000
--- a/src/libs/7zip/win/CPP/7zip/UI/Console/MainAr.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-// MainAr.cpp
-
-#include "StdAfx.h"
-
-#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/win/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/src/libs/7zip/win/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
deleted file mode 100644
index 7dba2ad5d..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Console/OpenCallbackConsole.h b/src/libs/7zip/win/CPP/7zip/UI/Console/OpenCallbackConsole.h
deleted file mode 100644
index c002e6a72..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Console/PercentPrinter.cpp b/src/libs/7zip/win/CPP/7zip/UI/Console/PercentPrinter.cpp
index 28452b177..f2889957a 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Console/PercentPrinter.cpp
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Console/PercentPrinter.h b/src/libs/7zip/win/CPP/7zip/UI/Console/PercentPrinter.h
index 97f2e6adb..509bab5fc 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Console/PercentPrinter.h
+++ b/src/libs/7zip/win/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/win/CPP/7zip/UI/Console/StdAfx.cpp b/src/libs/7zip/win/CPP/7zip/UI/Console/StdAfx.cpp
deleted file mode 100644
index d0feea85c..000000000
--- a/src/libs/7zip/win/CPP/7zip/UI/Console/StdAfx.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-// StdAfx.cpp
-
-#include "StdAfx.h"
diff --git a/src/libs/7zip/win/CPP/7zip/UI/Console/StdAfx.h b/src/libs/7zip/win/CPP/7zip/UI/Console/StdAfx.h
index 2e4be10b2..2854ff3e9 100644
--- a/src/libs/7zip/win/CPP/7zip/UI/Console/StdAfx.h
+++ b/src/libs/7zip/win/CPP/7zip/UI/Console/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../../../Common/MyWindows.h"
-#include "../../../Common/NewHandler.h"
+#include "../../../Common/Common.h"
#endif
diff --git a/src/libs/7zip/win/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/src/libs/7zip/win/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
deleted file mode 100644
index 7f3373197..000000000
--- a/src/libs/7zip/win/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);
- 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/win/CPP/7zip/UI/Console/UpdateCallbackConsole.h b/src/libs/7zip/win/CPP/7zip/UI/Console/UpdateCallbackConsole.h
deleted file mode 100644
index 5ffe3eb7a..000000000
--- a/src/libs/7zip/win/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/win/CPP/7zip/UI/Console/UserInputUtils.cpp b/src/libs/7zip/win/CPP/7zip/UI/Console/UserInputUtils.cpp
deleted file mode 100644
index 754680090..000000000
--- a/src/libs/7zip/win/CPP/7zip/UI/Console/UserInputUtils.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-// UserInputUtils.cpp
-
-#include "StdAfx.h"
-
-#include "Common/StdInStream.h"
-#include "Common/StringConvert.h"
-
-#include "UserInputUtils.h"
-
-static const char kYes = 'Y';
-static const char kNo = 'N';
-static const char kYesAll = 'A';
-static const char kNoAll = 'S';
-static const char kAutoRenameAll = 'U';
-static const char kQuit = 'Q';
-
-static const char *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;
- }
- }
-}
-
-#ifdef _WIN32
-#ifndef UNDER_CE
-#define MY_DISABLE_ECHO
-#endif
-#endif
-
-UString GetPassword(CStdOutStream *outStream)
-{
- (*outStream) << "\nEnter password"
- #ifdef MY_DISABLE_ECHO
- " (will not be echoed)"
- #endif
- ":";
- outStream->Flush();
-
- #ifdef MY_DISABLE_ECHO
- HANDLE console = GetStdHandle(STD_INPUT_HANDLE);
- bool wasChanged = false;
- DWORD mode = 0;
- if (console != INVALID_HANDLE_VALUE && console != 0)
- if (GetConsoleMode(console, &mode))
- wasChanged = (SetConsoleMode(console, mode & ~ENABLE_ECHO_INPUT) != 0);
- UString res = g_StdIn.ScanUStringUntilNewLine();
- if (wasChanged)
- SetConsoleMode(console, mode);
- (*outStream) << "\n";
- outStream->Flush();
- return res;
- #else
- return g_StdIn.ScanUStringUntilNewLine();
- #endif
-}
diff --git a/src/libs/7zip/win/CPP/7zip/UI/Console/UserInputUtils.h b/src/libs/7zip/win/CPP/7zip/UI/Console/UserInputUtils.h
deleted file mode 100644
index 8b5232b3f..000000000
--- a/src/libs/7zip/win/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);
-
-#endif
diff --git a/src/libs/7zip/win/CPP/Common/AutoPtr.h b/src/libs/7zip/win/CPP/Common/AutoPtr.h
deleted file mode 100644
index 006d31551..000000000
--- a/src/libs/7zip/win/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/win/CPP/Common/Buffer.h b/src/libs/7zip/win/CPP/Common/Buffer.h
deleted file mode 100644
index 118fe11fc..000000000
--- a/src/libs/7zip/win/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/win/CPP/Common/CRC.cpp b/src/libs/7zip/win/CPP/Common/CRC.cpp
deleted file mode 100644
index 9a9f81fb7..000000000
--- a/src/libs/7zip/win/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/win/CPP/Common/C_FileIO.cpp b/src/libs/7zip/win/CPP/Common/C_FileIO.cpp
deleted file mode 100644
index b4893d658..000000000
--- a/src/libs/7zip/win/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/win/CPP/Common/C_FileIO.h b/src/libs/7zip/win/CPP/Common/C_FileIO.h
deleted file mode 100644
index 27aa56869..000000000
--- a/src/libs/7zip/win/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/win/CPP/Common/ComTry.h b/src/libs/7zip/win/CPP/Common/ComTry.h
index fb4ef0459..c8aa4aedc 100644
--- a/src/libs/7zip/win/CPP/Common/ComTry.h
+++ b/src/libs/7zip/win/CPP/Common/ComTry.h
@@ -9,7 +9,7 @@
#define COM_TRY_BEGIN try {
#define COM_TRY_END } 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/win/CPP/Common/CommandLineParser.cpp b/src/libs/7zip/win/CPP/Common/CommandLineParser.cpp
index 80b467fcb..ac9ae1960 100644
--- a/src/libs/7zip/win/CPP/Common/CommandLineParser.cpp
+++ b/src/libs/7zip/win/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 {
bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
@@ -11,13 +25,13 @@ bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
dest1.Empty();
dest2.Empty();
bool quoteMode = false;
- int i;
- for (i = 0; i < src.Length(); i++)
+ unsigned i;
+ for (i = 0; i < src.Len(); i++)
{
wchar_t c = src[i];
- if (c == L' ' && !quoteMode)
+ if ((c == L' ' || c == L'\t') && !quoteMode)
{
- dest2 = src.Mid(i + 1);
+ dest2 = src.Ptr(i + 1);
return i != 0;
}
if (c == L'\"')
@@ -45,21 +59,18 @@ void SplitCommandLine(const UString &s, UStringVector &parts)
}
-static const wchar_t kSwitchID1 = '-';
-// static const wchar_t kSwitchID2 = '/';
-
-static const 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()
@@ -67,163 +78,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/win/CPP/Common/CommandLineParser.h b/src/libs/7zip/win/CPP/Common/CommandLineParser.h
index 3d0b41dd4..e3e6e6b14 100644
--- a/src/libs/7zip/win/CPP/Common/CommandLineParser.h
+++ b/src/libs/7zip/win/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/win/CPP/Common/Common.h b/src/libs/7zip/win/CPP/Common/Common.h
new file mode 100644
index 000000000..9dd30f4be
--- /dev/null
+++ b/src/libs/7zip/win/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/win/CPP/Common/Common.pri b/src/libs/7zip/win/CPP/Common/Common.pri
new file mode 100644
index 000000000..ecc997d89
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Common/Common.pri
@@ -0,0 +1,35 @@
+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/StdAfx.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/win/CPP/Common/DynamicBuffer.h b/src/libs/7zip/win/CPP/Common/DynamicBuffer.h
deleted file mode 100644
index eaac123e1..000000000
--- a/src/libs/7zip/win/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/win/CPP/Common/IntToString.cpp b/src/libs/7zip/win/CPP/Common/IntToString.cpp
index 013fee527..ed217c72c 100644
--- a/src/libs/7zip/win/CPP/Common/IntToString.cpp
+++ b/src/libs/7zip/win/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/win/CPP/Common/IntToString.h b/src/libs/7zip/win/CPP/Common/IntToString.h
index 782f930c5..69605ab76 100644
--- a/src/libs/7zip/win/CPP/Common/IntToString.h
+++ b/src/libs/7zip/win/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/win/CPP/Common/ListFileUtils.cpp b/src/libs/7zip/win/CPP/Common/ListFileUtils.cpp
index c1c682a2c..4d7faeca3 100644
--- a/src/libs/7zip/win/CPP/Common/ListFileUtils.cpp
+++ b/src/libs/7zip/win/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))
return false;
- UInt64 length;
- if (!file.GetLength(length))
- return false;
- if (length > ((UInt32)1 << 31))
+ UInt64 fileSize;
+ if (!file.GetLength(fileSize))
return false;
- AString s;
- char *p = s.GetBuffer((int)length + 1);
- UInt32 processed;
- if (!file.Read(p, (UInt32)length, processed))
+ if (fileSize >= ((UInt32)1 << 31) - 32)
return false;
- p[(UInt32)length] = 0;
- s.ReleaseBuffer();
- file.Close();
-
UString u;
- #ifdef CP_UTF8
- if (codePage == CP_UTF8)
+ if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE)
{
- if (!ConvertUTF8ToUnicode(s, u))
+ if ((fileSize & 1) != 0)
+ return false;
+ CByteArr buf((size_t)fileSize);
+ UInt32 processed;
+ if (!file.Read(buf, (UInt32)fileSize, processed))
return false;
+ if (processed != fileSize)
+ return false;
+ file.Close();
+ unsigned num = (unsigned)fileSize / 2;
+ wchar_t *p = u.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/win/CPP/Common/ListFileUtils.h b/src/libs/7zip/win/CPP/Common/ListFileUtils.h
index c58a8bd42..e8d833fdb 100644
--- a/src/libs/7zip/win/CPP/Common/ListFileUtils.h
+++ b/src/libs/7zip/win/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/win/CPP/Common/MyBuffer.h b/src/libs/7zip/win/CPP/Common/MyBuffer.h
new file mode 100644
index 000000000..7bd79f6f4
--- /dev/null
+++ b/src/libs/7zip/win/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/win/CPP/Common/MyCom.h b/src/libs/7zip/win/CPP/Common/MyCom.h
index 2f00c258f..466407cde 100644
--- a/src/libs/7zip/win/CPP/Common/MyCom.h
+++ b/src/libs/7zip/win/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/win/CPP/Common/MyGuidDef.h b/src/libs/7zip/win/CPP/Common/MyGuidDef.h
index 3c52cc07d..68745870e 100644
--- a/src/libs/7zip/win/CPP/Common/MyGuidDef.h
+++ b/src/libs/7zip/win/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/win/CPP/Common/MyInitGuid.h b/src/libs/7zip/win/CPP/Common/MyInitGuid.h
index d6a486980..279fba5d6 100644
--- a/src/libs/7zip/win/CPP/Common/MyInitGuid.h
+++ b/src/libs/7zip/win/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/win/CPP/Common/MyString.cpp b/src/libs/7zip/win/CPP/Common/MyString.cpp
index 3d1ce2b84..6fbfa334b 100644
--- a/src/libs/7zip/win/CPP/Common/MyString.cpp
+++ b/src/libs/7zip/win/CPP/Common/MyString.cpp
@@ -2,32 +2,104 @@
#include "StdAfx.h"
-#ifndef _WIN32
+#ifdef _WIN32
+#include <windows.h>
+#include <wchar.h>
+#else
#include <ctype.h>
#endif
-#ifndef _UNICODE
+#if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING)
#include "StringConvert.h"
#endif
#include "MyString.h"
+#define MY_STRING_NEW(_T_, _size_) new _T_[_size_]
+// #define MY_STRING_NEW(_T_, _size_) ((_T_ *)my_new((size_t)(_size_) * sizeof(_T_)))
+
+/*
+inline const char* MyStringGetNextCharPointer(const char *p) throw()
+{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ return CharNextA(p);
+ #else
+ return p + 1;
+ #endif
+}
+*/
+
+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);
+ }
+}
+
+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;
+ }
+}
+
+/*
+void MyStringUpper_Ascii(wchar_t *s)
+{
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharUpper_Ascii(c);
+ }
+}
+*/
+
+void MyStringLower_Ascii(wchar_t *s) throw()
+{
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c == 0)
+ return;
+ *s++ = MyCharLower_Ascii(c);
+ }
+}
#ifdef _WIN32
-#ifndef _UNICODE
+#ifdef _UNICODE
-wchar_t MyCharUpper(wchar_t c)
+// 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
+
+// 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()
{
- if (c == 0)
- return 0;
- wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c);
+ wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
- return (wchar_t)(unsigned int)(UINT_PTR)res;
- const int kBufferSize = 4;
- char s[kBufferSize + 1];
- int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
- if (numChars == 0 || numChars > kBufferSize)
+ return (wchar_t)(unsigned)(UINT_PTR)res;
+ const int kBufSize = 4;
+ char s[kBufSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);
+ if (numChars == 0 || numChars > kBufSize)
return c;
s[numChars] = 0;
::CharUpperA(s);
@@ -35,24 +107,25 @@ wchar_t MyCharUpper(wchar_t c)
return c;
}
-wchar_t MyCharLower(wchar_t c)
+/*
+wchar_t MyCharLower_WIN(wchar_t c)
{
- if (c == 0)
- return 0;
- wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c);
+ wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
- return (wchar_t)(unsigned int)(UINT_PTR)res;
- const int kBufferSize = 4;
- char s[kBufferSize + 1];
- int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
- if (numChars == 0 || numChars > kBufferSize)
+ return (wchar_t)(unsigned)(UINT_PTR)res;
+ const int kBufSize = 4;
+ char s[kBufSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);
+ if (numChars == 0 || numChars > kBufSize)
return c;
s[numChars] = 0;
::CharLowerA(s);
::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
return c;
}
+*/
+/*
wchar_t * MyStringUpper(wchar_t *s)
{
if (s == 0)
@@ -62,9 +135,12 @@ wchar_t * MyStringUpper(wchar_t *s)
return res;
AString a = UnicodeStringToMultiByte(s);
a.MakeUpper();
- return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+ MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+ return s;
}
+*/
+/*
wchar_t * MyStringLower(wchar_t *s)
{
if (s == 0)
@@ -74,110 +150,149 @@ wchar_t * MyStringLower(wchar_t *s)
return res;
AString a = UnicodeStringToMultiByte(s);
a.MakeLower();
- return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+ MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+ return s;
}
+*/
#endif
-/*
-inline int ConvertCompareResult(int r) { return r - 2; }
+#endif
-int MyStringCollate(const wchar_t *s1, const wchar_t *s2)
+bool IsString1PrefixedByString2(const char *s1, const char *s2) throw()
{
- int res = CompareStringW(
- LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1);
- #ifdef _UNICODE
- return ConvertCompareResult(res);
- #else
- if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
- return ConvertCompareResult(res);
- return MyStringCollate(UnicodeStringToMultiByte(s1),
- UnicodeStringToMultiByte(s2));
- #endif
+ for (;;)
+ {
+ unsigned char c2 = (unsigned char)*s2++; if (c2 == 0) return true;
+ unsigned char c1 = (unsigned char)*s1++; if (c1 != c2) return false;
+ }
}
-#ifndef UNDER_CE
-int MyStringCollate(const char *s1, const char *s2)
+bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw()
{
- return ConvertCompareResult(CompareStringA(
- LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1));
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false;
+ if (c1 == 0) return true;
+ }
}
-int MyStringCollateNoCase(const char *s1, const char *s2)
+// ---------- ASCII ----------
+
+bool AString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw()
{
- return ConvertCompareResult(CompareStringA(
- LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1));
+ const char *s1 = _chars;
+ for (;;)
+ {
+ char c2 = *s++;
+ if (c2 == 0)
+ return true;
+ char c1 = *s1++;
+ if (MyCharLower_Ascii(c1) !=
+ MyCharLower_Ascii(c2))
+ return false;
+ }
}
-#endif
-int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+bool UString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw()
{
- int res = CompareStringW(
- LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1);
- #ifdef _UNICODE
- return ConvertCompareResult(res);
- #else
- if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
- return ConvertCompareResult(res);
- return MyStringCollateNoCase(UnicodeStringToMultiByte(s1),
- UnicodeStringToMultiByte(s2));
- #endif
+ const wchar_t *s1 = _chars;
+ for (;;)
+ {
+ char c2 = *s++;
+ if (c2 == 0)
+ return true;
+ wchar_t c1 = *s1++;
+ if (MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))
+ return false;
+ }
}
-*/
-#else
+bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw()
+{
+ for (;;)
+ {
+ unsigned char c = *a;
+ if (c != *u)
+ return false;
+ if (c == 0)
+ return true;
+ a++;
+ u++;
+ }
+}
-wchar_t MyCharUpper(wchar_t c)
+bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw()
{
- return toupper(c);
+ for (;;)
+ {
+ char c1 = *s1++;
+ char c2 = *s2++;
+ if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
+ return false;
+ if (c1 == 0)
+ return true;
+ }
}
-/*
-int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
wchar_t c1 = *s1++;
wchar_t c2 = *s2++;
- wchar_t u1 = MyCharUpper(c1);
- wchar_t u2 = MyCharUpper(c2);
-
- if (u1 < u2) return -1;
- if (u1 > u2) return 1;
- if (u1 == 0) return 0;
+ if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
+ return false;
+ if (c1 == 0)
+ return true;
}
}
-*/
-#endif
+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;
+ }
+}
-int MyStringCompare(const char *s1, const char *s2)
+bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
- unsigned char c1 = (unsigned char)*s1++;
- unsigned char c2 = (unsigned char)*s2++;
- if (c1 < c2) return -1;
- if (c1 > c2) return 1;
- if (c1 == 0) return 0;
+ wchar_t c2 = *s2++; if (c2 == 0) return true;
+ wchar_t c1 = *s1++; if (c1 != c2) return false;
}
}
-int MyStringCompare(const wchar_t *s1, const wchar_t *s2)
+// NTFS order: uses upper case
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
wchar_t c1 = *s1++;
wchar_t c2 = *s2++;
- if (c1 < c2) return -1;
- if (c1 > c2) return 1;
+ if (c1 != c2)
+ {
+ wchar_t u1 = MyCharUpper(c1);
+ wchar_t u2 = MyCharUpper(c2);
+ if (u1 < u2) return -1;
+ if (u1 > u2) return 1;
+ }
if (c1 == 0) return 0;
}
}
-int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)
+int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw()
{
- for (;;)
+ for (; num != 0; num--)
{
wchar_t c1 = *s1++;
wchar_t c2 = *s2++;
@@ -190,11 +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
+}
+
+#ifdef USE_UNICODE_FSTRING
+
+#ifndef _UNICODE
+
+AString fs2fas(CFSTR s)
+{
+ return UnicodeStringToMultiByte(s, GetCurrentCodePage());
+}
+
+FString fas2fs(const AString &s)
+{
+ return MultiByteToUnicodeString(s, GetCurrentCodePage());
+}
+
+#endif
+
+#else
+
+UString fs2us(const FString &s)
+{
+ return MultiByteToUnicodeString((AString)s, GetCurrentCodePage());
+}
+
+FString us2fs(const wchar_t *s)
+{
+ return UnicodeStringToMultiByte(s, GetCurrentCodePage());
+}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Common/MyString.h b/src/libs/7zip/win/CPP/Common/MyString.h
index f483e39dc..8417815cf 100644
--- a/src/libs/7zip/win/CPP/Common/MyString.h
+++ b/src/libs/7zip/win/CPP/Common/MyString.h
@@ -5,623 +5,521 @@
#include <string.h>
-#include "MyVector.h"
+#ifndef _WIN32
+#include <wctype.h>
+#include <wchar.h>
+#endif
-#include <windows.h>
+#include "MyTypes.h"
+#include "MyVector.h"
-template <class T>
-inline int MyStringLen(const T *s)
+inline unsigned MyStringLen(const char *s)
{
- int i;
- for (i = 0; s[i] != '\0'; i++);
+ unsigned i;
+ for (i = 0; s[i] != 0; i++);
return i;
}
-template <class T>
-inline T * MyStringCopy(T *dest, const T *src)
+inline void MyStringCopy(char *dest, const char *src)
{
- T *destStart = dest;
while ((*dest++ = *src++) != 0);
- return destStart;
}
-inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
- { return (p + 1); }
-inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
- { return (p + 1); }
-inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
- { return (p - 1); }
-inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
- { return (p - 1); }
+inline char *MyStpCpy(char *dest, const char *src)
+{
+ for (;;)
+ {
+ char c = *src;
+ *dest = c;
+ if (c == 0)
+ return dest;
+ src++;
+ dest++;
+ }
+}
-#ifdef _WIN32
+inline unsigned MyStringLen(const wchar_t *s)
+{
+ unsigned i;
+ for (i = 0; s[i] != 0; i++);
+ return i;
+}
-inline const char* MyStringGetNextCharPointer(const char *p)
+inline void MyStringCopy(wchar_t *dest, const wchar_t *src)
{
- #ifdef UNDER_CE
- return p + 1;
- #else
- return CharNextA(p);
- #endif
+ while ((*dest++ = *src++) != 0);
}
-inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)
- { return CharPrevA(base, p); }
+int FindCharPosInString(const char *s, char c) throw();
+int FindCharPosInString(const wchar_t *s, wchar_t c) throw();
-inline char MyCharUpper(char c)
- { return (char)(unsigned int)(UINT_PTR)CharUpperA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
-#ifdef _UNICODE
-inline wchar_t MyCharUpper(wchar_t c)
- { return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); }
-#else
-wchar_t MyCharUpper(wchar_t c);
+#ifdef _WIN32
+ #ifndef _UNICODE
+ #define STRING_UNICODE_THROW
+ #endif
#endif
-#ifdef _UNICODE
-inline wchar_t MyCharLower(wchar_t c)
- { return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); }
-#else
-wchar_t MyCharLower(wchar_t c);
+#ifndef STRING_UNICODE_THROW
+ #define STRING_UNICODE_THROW throw()
#endif
-inline char MyCharLower(char c)
-#ifdef UNDER_CE
- { return (char)MyCharLower((wchar_t)c); }
-#else
- { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
-#endif
+/*
+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;
+}
+*/
-inline char * MyStringUpper(char *s) { return CharUpperA(s); }
-#ifdef _UNICODE
-inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
-#else
-wchar_t * MyStringUpper(wchar_t *s);
-#endif
+inline char MyCharLower_Ascii(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return (char)(c + 0x20);
+ return c;
+}
-inline char * MyStringLower(char *s) { return CharLowerA(s); }
-#ifdef _UNICODE
-inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
-#else
-wchar_t * MyStringLower(wchar_t *s);
-#endif
+inline wchar_t MyCharLower_Ascii(wchar_t c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return (wchar_t)(c + 0x20);
+ return c;
+}
-#else // Standard-C
-wchar_t MyCharUpper(wchar_t c);
-#endif
+wchar_t MyCharUpper_WIN(wchar_t c) throw();
-//////////////////////////////////////
-// Compare
+inline wchar_t MyCharUpper(wchar_t c) throw()
+{
+ if (c < 'a') return c;
+ if (c <= 'z') return (wchar_t)(c - 0x20);
+ if (c <= 0x7F) return c;
+ #ifdef _WIN32
+ #ifdef _UNICODE
+ return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
+ #else
+ return (wchar_t)MyCharUpper_WIN(c);
+ #endif
+ #else
+ return (wchar_t)towupper(c);
+ #endif
+}
/*
-#ifndef UNDER_CE
-int MyStringCollate(const char *s1, const char *s2);
-int MyStringCollateNoCase(const char *s1, const char *s2);
-#endif
-int MyStringCollate(const wchar_t *s1, const wchar_t *s2);
-int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);
+wchar_t MyCharLower_WIN(wchar_t c) throw();
+
+inline wchar_t MyCharLower(wchar_t c) throw()
+{
+ if (c < 'A') return c;
+ if (c <= 'Z') return (wchar_t)(c + 0x20);
+ if (c <= 0x7F) return c;
+ #ifdef _WIN32
+ #ifdef _UNICODE
+ return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
+ #else
+ return (wchar_t)MyCharLower_WIN(c);
+ #endif
+ #else
+ return (wchar_t)tolower(c);
+ #endif
+}
*/
-int MyStringCompare(const char *s1, const char *s2);
-int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
+// 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 char *s1, const char *s2);
-int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw();
+int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw();
-template <class T>
-class CStringBase
+// ---------- ASCII ----------
+// char values in ASCII strings must be less then 128
+bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw();
+bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw();
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw();
+bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw();
+
+#define MY_STRING_DELETE(_p_) delete []_p_;
+// #define MY_STRING_DELETE(_p_) my_delete(_p_);
+
+class AString
{
- 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);
- }
+ char *_chars;
+ unsigned _len;
+ unsigned _limit;
- }
- void MoveItems(int destIndex, int srcIndex)
+ void MoveItems(unsigned dest, unsigned src)
{
- memmove(_chars + destIndex, _chars + srcIndex,
- sizeof(T) * (_length - srcIndex + 1));
- }
-
- void InsertSpace(int &index, int size)
- {
- CorrectIndex(index);
- GrowLength(size);
- MoveItems(index + size, index);
+ memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char));
}
- static const T *GetNextCharPointer(const T *p)
- { return MyStringGetNextCharPointer(p); }
- static const T *GetPrevCharPointer(const T *base, const T *p)
- { return MyStringGetPrevCharPointer(base, p); }
-protected:
- T *_chars;
- int _length;
- int _capacity;
-
- void SetCapacity(int newCapacity)
- {
- int realCapacity = newCapacity + 1;
- if (realCapacity == _capacity)
- return;
- /*
- const int kMaxStringSize = 0x20000000;
- if (newCapacity > kMaxStringSize || newCapacity < _length)
- throw 1052337;
- */
- T *newBuffer = new T[realCapacity];
- if (_capacity > 0)
- {
- for (int i = 0; i < _length; i++)
- newBuffer[i] = _chars[i];
- delete []_chars;
- }
- _chars = newBuffer;
- _chars[_length] = 0;
- _capacity = realCapacity;
- }
+ void InsertSpace(unsigned &index, unsigned size);
- 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);
- }
+ void ReAlloc(unsigned newLimit);
+ void SetStartLen(unsigned len);
+ void Grow_1();
+ void Grow(unsigned n);
- void CorrectIndex(int &index) const
- {
- if (index > _length)
- index = _length;
- }
+ // 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); }
- operator const T*() const { return _chars;}
+ unsigned Len() const { return _len; }
+ bool IsEmpty() const { return _len == 0; }
+ void Empty() { _len = 0; _chars[0] = 0; }
- T Back() const { return _chars[_length - 1]; }
+ operator const char *() const { return _chars; }
+ const char *Ptr() const { return _chars; }
+ const char *Ptr(unsigned pos) const { return _chars + pos; }
+ const char *RightPtr(unsigned num) const { return _chars + _len - num; }
+ char Back() const { return _chars[_len - 1]; }
+
+ void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; }
// 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)
- {
- /*
- if (newLength >= _capacity)
- throw 282217;
- */
- _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); }
+ AString &operator+=(const char *s);
+ AString &operator+=(const AString &s);
- int Compare(const CStringBase& s) const
- { return MyStringCompare(_chars, s._chars); }
+ 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 Compare(const T *s) const
- { return MyStringCompare(_chars, s); }
+ // void MakeUpper() { MyStringUpper(_chars); }
+ // void MakeLower() { MyStringLower(_chars); }
- int CompareNoCase(const CStringBase& s) const
- { return MyStringCompareNoCase(_chars, s._chars); }
- int CompareNoCase(const T *s) const
- { return MyStringCompareNoCase(_chars, s); }
+ // int Compare(const char *s) const { return MyStringCompare(_chars, s); }
+ // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); }
+ // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); }
+ // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
+ bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); }
+ bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
- /*
- int Collate(const CStringBase& s) const
- { return MyStringCollate(_chars, s._chars); }
- int CollateNoCase(const CStringBase& s) const
- { return MyStringCollateNoCase(_chars, s._chars); }
- */
-
- 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
{
- 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;
- const 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/win/CPP/Common/MyTypes.h b/src/libs/7zip/win/CPP/Common/MyTypes.h
new file mode 100644
index 000000000..d81788816
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Common/MyTypes.h
@@ -0,0 +1,30 @@
+// Common/MyTypes.h
+
+#ifndef __COMMON_MY_TYPES_H
+#define __COMMON_MY_TYPES_H
+
+#include "../../C/7zTypes.h"
+
+typedef int HRes;
+
+struct CBoolPair
+{
+ bool Val;
+ bool Def;
+
+ CBoolPair(): Val(false), Def(false) {}
+
+ void Init()
+ {
+ Val = false;
+ Def = false;
+ }
+
+ void SetTrueTrue()
+ {
+ Val = true;
+ Def = true;
+ }
+};
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Common/MyUnknown.h b/src/libs/7zip/win/CPP/Common/MyUnknown.h
index e9e8666b9..8b95afd38 100644
--- a/src/libs/7zip/win/CPP/Common/MyUnknown.h
+++ b/src/libs/7zip/win/CPP/Common/MyUnknown.h
@@ -9,5 +9,5 @@
#else
#include "MyWindows.h"
#endif
-
+
#endif
diff --git a/src/libs/7zip/win/CPP/Common/MyVector.cpp b/src/libs/7zip/win/CPP/Common/MyVector.cpp
deleted file mode 100644
index 3b5317688..000000000
--- a/src/libs/7zip/win/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/win/CPP/Common/MyVector.h b/src/libs/7zip/win/CPP/Common/MyVector.h
index 781b648bc..7e61dec31 100644
--- a/src/libs/7zip/win/CPP/Common/MyVector.h
+++ b/src/libs/7zip/win/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/win/CPP/Common/MyWindows.cpp b/src/libs/7zip/win/CPP/Common/MyWindows.cpp
new file mode 100644
index 000000000..38c93fdb2
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Common/MyWindows.cpp
@@ -0,0 +1,145 @@
+// MyWindows.cpp
+
+#include "StdAfx.h"
+
+#ifndef _WIN32
+
+#include <stdlib.h>
+
+#include "MyWindows.h"
+
+static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); }
+static inline void FreeForBSTR(void *pv) { ::free(pv);}
+
+/* Win32 uses DWORD (32-bit) type to store size of string before (OLECHAR *) string.
+ We must select CBstrSizeType for another systems (not Win32):
+
+ if (CBstrSizeType is UINT32),
+ then we support only strings smaller than 4 GB.
+ Win32 version always has that limitation.
+
+ if (CBstrSizeType is UINT),
+ (UINT can be 16/32/64-bit)
+ We can support strings larger than 4 GB (if UINT is 64-bit),
+ but sizeof(UINT) can be different in parts compiled by
+ different compilers/settings,
+ and we can't send such BSTR strings between such parts.
+*/
+
+typedef UINT32 CBstrSizeType;
+// typedef UINT CBstrSizeType;
+
+#define k_BstrSize_Max 0xFFFFFFFF
+// #define k_BstrSize_Max UINT_MAX
+// #define k_BstrSize_Max ((UINT)(INT)-1)
+
+BSTR SysAllocStringByteLen(LPCSTR s, UINT len)
+{
+ /* Original SysAllocStringByteLen in Win32 maybe fills only unaligned null OLECHAR at the end.
+ We provide also aligned null OLECHAR at the end. */
+
+ if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(OLECHAR) - sizeof(CBstrSizeType)))
+ return NULL;
+
+ UINT size = (len + sizeof(OLECHAR) + sizeof(OLECHAR) - 1) & ~(sizeof(OLECHAR) - 1);
+ void *p = AllocateForBSTR(size + sizeof(CBstrSizeType));
+ if (!p)
+ return NULL;
+ *(CBstrSizeType *)p = (CBstrSizeType)len;
+ BSTR bstr = (BSTR)((CBstrSizeType *)p + 1);
+ if (s)
+ memcpy(bstr, s, len);
+ for (; len < size; len++)
+ ((Byte *)bstr)[len] = 0;
+ return bstr;
+}
+
+BSTR SysAllocStringLen(const OLECHAR *s, UINT len)
+{
+ if (len >= (k_BstrSize_Max - sizeof(OLECHAR) - sizeof(CBstrSizeType)) / sizeof(OLECHAR))
+ return NULL;
+
+ UINT size = len * sizeof(OLECHAR);
+ void *p = AllocateForBSTR(size + sizeof(CBstrSizeType) + sizeof(OLECHAR));
+ if (!p)
+ return NULL;
+ *(CBstrSizeType *)p = (CBstrSizeType)size;
+ BSTR bstr = (BSTR)((CBstrSizeType *)p + 1);
+ if (s)
+ memcpy(bstr, s, size);
+ bstr[len] = 0;
+ return bstr;
+}
+
+BSTR SysAllocString(const OLECHAR *s)
+{
+ if (!s)
+ return 0;
+ const OLECHAR *s2 = s;
+ while (*s2 != 0)
+ s2++;
+ return SysAllocStringLen(s, (UINT)(s2 - s));
+}
+
+void SysFreeString(BSTR bstr)
+{
+ if (bstr)
+ FreeForBSTR((CBstrSizeType *)bstr - 1);
+}
+
+UINT SysStringByteLen(BSTR bstr)
+{
+ if (!bstr)
+ return 0;
+ return *((CBstrSizeType *)bstr - 1);
+}
+
+UINT SysStringLen(BSTR bstr)
+{
+ if (!bstr)
+ return 0;
+ return *((CBstrSizeType *)bstr - 1) / sizeof(OLECHAR);
+}
+
+
+HRESULT VariantClear(VARIANTARG *prop)
+{
+ if (prop->vt == VT_BSTR)
+ SysFreeString(prop->bstrVal);
+ prop->vt = VT_EMPTY;
+ return S_OK;
+}
+
+HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src)
+{
+ HRESULT res = ::VariantClear(dest);
+ if (res != S_OK)
+ return res;
+ if (src->vt == VT_BSTR)
+ {
+ dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal,
+ SysStringByteLen(src->bstrVal));
+ if (!dest->bstrVal)
+ return E_OUTOFMEMORY;
+ dest->vt = VT_BSTR;
+ }
+ else
+ *dest = *src;
+ return S_OK;
+}
+
+LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2)
+{
+ if (ft1->dwHighDateTime < ft2->dwHighDateTime) return -1;
+ if (ft1->dwHighDateTime > ft2->dwHighDateTime) return 1;
+ if (ft1->dwLowDateTime < ft2->dwLowDateTime) return -1;
+ if (ft1->dwLowDateTime > ft2->dwLowDateTime) return 1;
+ return 0;
+}
+
+DWORD GetLastError()
+{
+ return 0;
+}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Common/MyWindows.h b/src/libs/7zip/win/CPP/Common/MyWindows.h
index 8b0e5c069..139a4e8b9 100644
--- a/src/libs/7zip/win/CPP/Common/MyWindows.h
+++ b/src/libs/7zip/win/CPP/Common/MyWindows.h
@@ -1,12 +1,17 @@
// MyWindows.h
-#ifndef __MYWINDOWS_H
-#define __MYWINDOWS_H
+#ifndef __MY_WINDOWS_H
+#define __MY_WINDOWS_H
#ifdef _WIN32
#include <windows.h>
+#ifdef UNDER_CE
+ #undef VARIANT_TRUE
+ #define VARIANT_TRUE ((VARIANT_BOOL)-1)
+#endif
+
#else
#include <stddef.h> // for wchar_t
@@ -14,6 +19,8 @@
#include "MyGuidDef.h"
+#define WINAPI
+
typedef char CHAR;
typedef unsigned char UCHAR;
@@ -40,8 +47,8 @@ typedef UINT32 DWORD;
typedef Int64 LONGLONG;
typedef UInt64 ULONGLONG;
-typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;
-typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;
+typedef struct _LARGE_INTEGER { LONGLONG QuadPart; } LARGE_INTEGER;
+typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart; } ULARGE_INTEGER;
typedef const CHAR *LPCSTR;
typedef CHAR TCHAR;
@@ -57,7 +64,7 @@ typedef struct _FILETIME
{
DWORD dwLowDateTime;
DWORD dwHighDateTime;
-}FILETIME;
+} FILETIME;
#define HRESULT LONG
#define FAILED(Status) ((HRESULT)(Status)<0)
@@ -145,8 +152,6 @@ typedef WORD PROPVAR_PAD1;
typedef WORD PROPVAR_PAD2;
typedef WORD PROPVAR_PAD3;
-#ifdef __cplusplus
-
typedef struct tagPROPVARIANT
{
VARTYPE vt;
@@ -177,11 +182,17 @@ typedef tagVARIANT VARIANT;
typedef VARIANT VARIANTARG;
MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
-MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
+MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src);
-#endif
+typedef struct tagSTATPROPSTG
+{
+ LPOLESTR lpwstrName;
+ PROPID propid;
+ VARTYPE vt;
+} STATPROPSTG;
MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
+MY_EXTERN_C BSTR SysAllocStringLen(const OLECHAR *sz, UINT len);
MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
MY_EXTERN_C void SysFreeString(BSTR bstr);
MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
@@ -192,6 +203,7 @@ MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
#define CP_ACP 0
#define CP_OEMCP 1
+#define CP_UTF8 65001
typedef enum tagSTREAM_SEEK
{
diff --git a/src/libs/7zip/win/CPP/Common/NewHandler.cpp b/src/libs/7zip/win/CPP/Common/NewHandler.cpp
index aad6e7d16..9072376df 100644
--- a/src/libs/7zip/win/CPP/Common/NewHandler.cpp
+++ b/src/libs/7zip/win/CPP/Common/NewHandler.cpp
@@ -1,5 +1,5 @@
// NewHandler.cpp
-
+
#include "StdAfx.h"
#include <stdlib.h>
@@ -11,6 +11,32 @@
#ifndef DEBUG_MEMORY_LEAK
#ifdef _WIN32
+
+/*
+void * my_new(size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
+ if (p == 0)
+ throw CNewException();
+ return p;
+}
+
+void my_delete(void *p) throw()
+{
+ // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
+ ::free(p);
+}
+
+void * my_Realloc(void *p, size_t newSize, size_t oldSize)
+{
+ void *newBuf = my_new(newSize);
+ memcpy(newBuf, p, oldSize);
+ my_delete(p);
+ return newBuf;
+}
+*/
+
void *
#ifdef _MSC_VER
__cdecl
@@ -30,18 +56,42 @@ __cdecl
#endif
operator delete(void *p) throw()
{
- /*
+ // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
+ ::free(p);
+}
+
+/*
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new[](size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
if (p == 0)
- return;
- ::HeapFree(::GetProcessHeap(), 0, p);
- */
+ throw CNewException();
+ return p;
+}
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete[](void *p) throw()
+{
+ // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p);
::free(p);
}
+*/
+
#endif
#else
-#pragma init_seg(lib)
+#include <stdio.h>
+
+// #pragma init_seg(lib)
const int kDebugSize = 1000000;
static void *a[kDebugSize];
static int index = 0;
@@ -51,10 +101,6 @@ void * __cdecl operator new(size_t size)
{
numAllocs++;
void *p = HeapAlloc(GetProcessHeap(), 0, size);
- if (index == 40)
- {
- int t = 1;
- }
if (index < kDebugSize)
{
a[index] = p;
diff --git a/src/libs/7zip/win/CPP/Common/NewHandler.h b/src/libs/7zip/win/CPP/Common/NewHandler.h
index 215ba05f1..e3e7422c8 100644
--- a/src/libs/7zip/win/CPP/Common/NewHandler.h
+++ b/src/libs/7zip/win/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/win/CPP/Common/StdAfx.h b/src/libs/7zip/win/CPP/Common/StdAfx.h
index b8ba1d5c4..420f5c326 100644
--- a/src/libs/7zip/win/CPP/Common/StdAfx.h
+++ b/src/libs/7zip/win/CPP/Common/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-// #include "MyWindows.h"
-#include "NewHandler.h"
+#include "Common.h"
#endif
diff --git a/src/libs/7zip/win/CPP/Common/StdInStream.cpp b/src/libs/7zip/win/CPP/Common/StdInStream.cpp
deleted file mode 100644
index f3dcb85f5..000000000
--- a/src/libs/7zip/win/CPP/Common/StdInStream.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-// Common/StdInStream.cpp
-
-#include "StdAfx.h"
-
-#include <tchar.h>
-
-#include "StdInStream.h"
-#include "StringConvert.h"
-#include "UTFConvert.h"
-
-#ifdef _MSC_VER
-// "was declared deprecated" disabling
-#pragma warning(disable : 4996 )
-#endif
-
-static const char kIllegalChar = '\0';
-static const char kNewLineChar = '\n';
-
-static const char *kEOFMessage = "Unexpected end of input stream";
-static const char *kReadErrorMessage ="Error reading input stream";
-static const char *kIllegalCharMessage = "Illegal character in input stream";
-
-static LPCTSTR kFileOpenMode = TEXT("r");
-
-extern int g_CodePage;
-
-CStdInStream g_StdIn(stdin);
-
-bool CStdInStream::Open(LPCTSTR fileName)
-{
- Close();
- _stream = _tfopen(fileName, 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;
-}
-
-UString CStdInStream::ScanUStringUntilNewLine()
-{
- AString s = ScanStringUntilNewLine(true);
- int codePage = g_CodePage;
- if (codePage == -1)
- codePage = CP_OEMCP;
- UString dest;
- if (codePage == CP_UTF8)
- ConvertUTF8ToUnicode(s, dest);
- else
- dest = MultiByteToUnicodeString(s, (UINT)codePage);
- return dest;
-}
-
-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/win/CPP/Common/StdInStream.h b/src/libs/7zip/win/CPP/Common/StdInStream.h
deleted file mode 100644
index 0d182cc3c..000000000
--- a/src/libs/7zip/win/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/win/CPP/Common/StdOutStream.cpp b/src/libs/7zip/win/CPP/Common/StdOutStream.cpp
index 061a76063..6aed31a31 100644
--- a/src/libs/7zip/win/CPP/Common/StdOutStream.cpp
+++ b/src/libs/7zip/win/CPP/Common/StdOutStream.cpp
@@ -9,21 +9,16 @@
#include "StringConvert.h"
#include "UTFConvert.h"
-#ifdef _MSC_VER
-// "was declared deprecated" disabling
-#pragma warning(disable : 4996 )
-#endif
-
static const char kNewLineChar = '\n';
static const char *kFileOpenMode = "wt";
extern int g_CodePage;
-CStdOutStream g_StdOut(stdout);
-CStdOutStream g_StdErr(stderr);
+CStdOutStream g_StdOut(stdout);
+CStdOutStream g_StdErr(stderr);
-bool CStdOutStream::Open(const char *fileName)
+bool CStdOutStream::Open(const char *fileName) throw()
{
Close();
_stream = fopen(fileName, kFileOpenMode);
@@ -31,7 +26,7 @@ bool CStdOutStream::Open(const char *fileName)
return _streamIsOpen;
}
-bool CStdOutStream::Close()
+bool CStdOutStream::Close() throw()
{
if (!_streamIsOpen)
return true;
@@ -42,33 +37,16 @@ bool CStdOutStream::Close()
return true;
}
-bool CStdOutStream::Flush()
+bool CStdOutStream::Flush() throw()
{
return (fflush(_stream) == 0);
}
-CStdOutStream::~CStdOutStream ()
-{
- Close();
-}
-
-CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*aFunction)(CStdOutStream &))
-{
- (*aFunction)(*this);
- return *this;
-}
-
-CStdOutStream & endl(CStdOutStream & outStream)
+CStdOutStream & endl(CStdOutStream & outStream) throw()
{
return outStream << kNewLineChar;
}
-CStdOutStream & CStdOutStream::operator<<(const char *s)
-{
- fputs(s, _stream);
- return *this;
-}
-
CStdOutStream & CStdOutStream::operator<<(const wchar_t *s)
{
int codePage = g_CodePage;
@@ -78,27 +56,51 @@ CStdOutStream & CStdOutStream::operator<<(const wchar_t *s)
if (codePage == CP_UTF8)
ConvertUnicodeToUTF8(s, dest);
else
- dest = UnicodeStringToMultiByte(s, (UINT)codePage);
- *this << (const char *)dest;
- return *this;
+ UnicodeStringToMultiByte2(dest, s, (UINT)codePage);
+ return operator<<((const char *)dest);
+}
+
+void StdOut_Convert_UString_to_AString(const UString &s, AString &temp)
+{
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8(s, temp);
+ else
+ UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
+}
+
+void CStdOutStream::PrintUString(const UString &s, AString &temp)
+{
+ StdOut_Convert_UString_to_AString(s, temp);
+ *this << (const char *)temp;
+}
+
+CStdOutStream & CStdOutStream::operator<<(Int32 number) throw()
+{
+ char s[32];
+ ConvertInt64ToString(number, s);
+ return operator<<(s);
}
-CStdOutStream & CStdOutStream::operator<<(char c)
+CStdOutStream & CStdOutStream::operator<<(Int64 number) throw()
{
- fputc(c, _stream);
- return *this;
+ char s[32];
+ ConvertInt64ToString(number, s);
+ return operator<<(s);
}
-CStdOutStream & CStdOutStream::operator<<(int number)
+CStdOutStream & CStdOutStream::operator<<(UInt32 number) throw()
{
- char textString[32];
- ConvertInt64ToString(number, textString);
- return operator<<(textString);
+ char s[16];
+ ConvertUInt32ToString(number, s);
+ return operator<<(s);
}
-CStdOutStream & CStdOutStream::operator<<(UInt64 number)
+CStdOutStream & CStdOutStream::operator<<(UInt64 number) throw()
{
- char textString[32];
- ConvertUInt64ToString(number, textString);
- return operator<<(textString);
+ char s[32];
+ ConvertUInt64ToString(number, s);
+ return operator<<(s);
}
diff --git a/src/libs/7zip/win/CPP/Common/StdOutStream.h b/src/libs/7zip/win/CPP/Common/StdOutStream.h
index b0b2c615c..0a8c0febb 100644
--- a/src/libs/7zip/win/CPP/Common/StdOutStream.h
+++ b/src/libs/7zip/win/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/win/CPP/Common/StringConvert.cpp b/src/libs/7zip/win/CPP/Common/StringConvert.cpp
index 681895b71..0443a06ca 100644
--- a/src/libs/7zip/win/CPP/Common/StringConvert.cpp
+++ b/src/libs/7zip/win/CPP/Common/StringConvert.cpp
@@ -15,8 +15,8 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
if (!srcString.IsEmpty())
{
int numChars = MultiByteToWideChar(codePage, 0, srcString,
- srcString.Length(), resultString.GetBuffer(srcString.Length()),
- srcString.Length() + 1);
+ srcString.Len(), resultString.GetBuffer(srcString.Len()),
+ srcString.Len() + 1);
if (numChars == 0)
throw 282228;
resultString.ReleaseBuffer(numChars);
@@ -24,15 +24,83 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
return resultString;
}
+void MultiByteToUnicodeString2(UString &dest, const AString &srcString, UINT codePage)
+{
+ dest.Empty();
+ if (!srcString.IsEmpty())
+ {
+ wchar_t *destBuf = dest.GetBuffer(srcString.Len());
+ const char *sp = (const char *)srcString;
+ unsigned i;
+ for (i = 0;;)
+ {
+ char c = sp[i];
+ if ((Byte)c >= 0x80 || c == 0)
+ break;
+ destBuf[i++] = (wchar_t)c;
+ }
+
+ if (i != srcString.Len())
+ {
+ unsigned numChars = MultiByteToWideChar(codePage, 0, sp + i,
+ srcString.Len() - i, destBuf + i,
+ srcString.Len() + 1 - i);
+ if (numChars == 0)
+ throw 282228;
+ i += numChars;
+ }
+ dest.ReleaseBuffer(i);
+ }
+}
+
+void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
+{
+ dest.Empty();
+ defaultCharWasUsed = false;
+ if (!s.IsEmpty())
+ {
+ unsigned numRequiredBytes = s.Len() * 2;
+ char *destBuf = dest.GetBuffer(numRequiredBytes);
+ unsigned i;
+ const wchar_t *sp = (const wchar_t *)s;
+ for (i = 0;;)
+ {
+ wchar_t c = sp[i];
+ if (c >= 0x80 || c == 0)
+ break;
+ destBuf[i++] = (char)c;
+ }
+ defaultCharWasUsed = false;
+ if (i != s.Len())
+ {
+ BOOL defUsed;
+ unsigned numChars = WideCharToMultiByte(codePage, 0, sp + i, s.Len() - i,
+ destBuf + i, numRequiredBytes + 1 - i,
+ &defaultChar, &defUsed);
+ defaultCharWasUsed = (defUsed != FALSE);
+ if (numChars == 0)
+ throw 282229;
+ i += numChars;
+ }
+ dest.ReleaseBuffer(i);
+ }
+}
+
+void UnicodeStringToMultiByte2(AString &dest, const UString &srcString, UINT codePage)
+{
+ bool defaultCharWasUsed;
+ UnicodeStringToMultiByte2(dest, srcString, codePage, '_', defaultCharWasUsed);
+}
+
AString UnicodeStringToMultiByte(const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed)
{
AString dest;
defaultCharWasUsed = false;
if (!s.IsEmpty())
{
- int numRequiredBytes = s.Length() * 2;
+ unsigned numRequiredBytes = s.Len() * 2;
BOOL defUsed;
- int numChars = WideCharToMultiByte(codePage, 0, s, s.Length(),
+ int numChars = WideCharToMultiByte(codePage, 0, s, s.Len(),
dest.GetBuffer(numRequiredBytes), numRequiredBytes + 1,
&defaultChar, &defUsed);
defaultCharWasUsed = (defUsed != FALSE);
@@ -53,7 +121,7 @@ AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
AString SystemStringToOemString(const CSysString &srcString)
{
AString result;
- CharToOem(srcString, result.GetBuffer(srcString.Length() * 2));
+ CharToOem(srcString, result.GetBuffer(srcString.Len() * 2));
result.ReleaseBuffer();
return result;
}
@@ -64,12 +132,12 @@ AString SystemStringToOemString(const CSysString &srcString)
UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
{
UString resultString;
- for (int i = 0; i < srcString.Length(); i++)
- resultString += wchar_t(srcString[i]);
+ for (unsigned i = 0; i < srcString.Len(); i++)
+ resultString += (wchar_t)srcString[i];
/*
if (!srcString.IsEmpty())
{
- 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) throw "Your environment does not support UNICODE";
resultString.ReleaseBuffer(numChars);
}
@@ -80,12 +148,12 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
{
AString resultString;
- for (int i = 0; i < srcString.Length(); i++)
- resultString += char(srcString[i]);
+ for (unsigned i = 0; i < srcString.Len(); i++)
+ resultString += (char)srcString[i];
/*
if (!srcString.IsEmpty())
{
- int numRequiredBytes = srcString.Length() * 6 + 1;
+ int numRequiredBytes = srcString.Len() * 6 + 1;
int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes);
if (numChars < 0) throw "Your environment does not support UNICODE";
resultString.ReleaseBuffer(numChars);
diff --git a/src/libs/7zip/win/CPP/Common/StringConvert.h b/src/libs/7zip/win/CPP/Common/StringConvert.h
index cd737becb..8eea72ef2 100644
--- a/src/libs/7zip/win/CPP/Common/StringConvert.h
+++ b/src/libs/7zip/win/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/win/CPP/Common/StringToInt.cpp b/src/libs/7zip/win/CPP/Common/StringToInt.cpp
index 9473766bc..2023fcc2c 100644
--- a/src/libs/7zip/win/CPP/Common/StringToInt.cpp
+++ b/src/libs/7zip/win/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/win/CPP/Common/StringToInt.h b/src/libs/7zip/win/CPP/Common/StringToInt.h
index c0d860eff..5c5d7d7fe 100644
--- a/src/libs/7zip/win/CPP/Common/StringToInt.h
+++ b/src/libs/7zip/win/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/win/CPP/Common/Types.h b/src/libs/7zip/win/CPP/Common/Types.h
deleted file mode 100644
index 9365b327f..000000000
--- a/src/libs/7zip/win/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/win/CPP/Common/UTFConvert.cpp b/src/libs/7zip/win/CPP/Common/UTFConvert.cpp
index 95362430a..38bac3331 100644
--- a/src/libs/7zip/win/CPP/Common/UTFConvert.cpp
+++ b/src/libs/7zip/win/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/win/CPP/Common/UTFConvert.h b/src/libs/7zip/win/CPP/Common/UTFConvert.h
index 2a14600d9..16b02fe45 100644
--- a/src/libs/7zip/win/CPP/Common/UTFConvert.h
+++ b/src/libs/7zip/win/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/win/CPP/Common/Wildcard.cpp b/src/libs/7zip/win/CPP/Common/Wildcard.cpp
index 476ddebde..e88a1cf1c 100644
--- a/src/libs/7zip/win/CPP/Common/Wildcard.cpp
+++ b/src/libs/7zip/win/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/win/CPP/Common/Wildcard.h b/src/libs/7zip/win/CPP/Common/Wildcard.h
index 6d4cbcece..137d71ced 100644
--- a/src/libs/7zip/win/CPP/Common/Wildcard.h
+++ b/src/libs/7zip/win/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): Name(name), Parent(parent) { };
- 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/win/CPP/Windows/DLL.cpp b/src/libs/7zip/win/CPP/Windows/DLL.cpp
index 5afd72d9d..cf3dd1ceb 100644
--- a/src/libs/7zip/win/CPP/Windows/DLL.cpp
+++ b/src/libs/7zip/win/CPP/Windows/DLL.cpp
@@ -2,109 +2,109 @@
#include "StdAfx.h"
-#ifndef _UNICODE
-#include "../Common/StringConvert.h"
-#endif
-
#include "DLL.h"
#ifndef _UNICODE
extern bool g_IsNT;
#endif
+extern HINSTANCE g_hInstance;
+
namespace NWindows {
namespace NDLL {
-bool CLibrary::Free()
+bool CLibrary::Free() throw()
{
if (_module == 0)
return true;
- // MessageBox(0, TEXT(""), TEXT("Free"), 0);
- // Sleep(5000);
if (!::FreeLibrary(_module))
return false;
_module = 0;
return true;
}
-bool CLibrary::LoadOperations(HMODULE newModule)
+bool CLibrary::LoadEx(CFSTR path, DWORD flags) throw()
{
- if (newModule == NULL)
- return false;
if (!Free())
return false;
- _module = newModule;
- return true;
-}
-
-bool CLibrary::LoadEx(LPCTSTR fileName, DWORD flags)
-{
- // MessageBox(0, fileName, TEXT("LoadEx"), 0);
- return LoadOperations(::LoadLibraryEx(fileName, NULL, flags));
-}
-
-bool CLibrary::Load(LPCTSTR fileName)
-{
- // MessageBox(0, fileName, TEXT("Load"), 0);
- // Sleep(5000);
- // OutputDebugString(fileName);
- // OutputDebugString(TEXT("\n"));
- return LoadOperations(::LoadLibrary(fileName));
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ _module = ::LoadLibraryEx(fs2fas(path), NULL, flags);
+ }
+ else
+ #endif
+ {
+ _module = ::LoadLibraryExW(fs2us(path), NULL, flags);
+ }
+ return (_module != NULL);
}
-#ifndef _UNICODE
-static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-CSysString GetSysPath(LPCWSTR sysPath)
- { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
-
-bool CLibrary::LoadEx(LPCWSTR fileName, DWORD flags)
+bool CLibrary::Load(CFSTR path) throw()
{
- if (g_IsNT)
- return LoadOperations(::LoadLibraryExW(fileName, NULL, flags));
- return LoadEx(GetSysPath(fileName), flags);
-}
-bool CLibrary::Load(LPCWSTR fileName)
-{
- if (g_IsNT)
- return LoadOperations(::LoadLibraryW(fileName));
- return Load(GetSysPath(fileName));
+ if (!Free())
+ return false;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ _module = ::LoadLibrary(fs2fas(path));
+ }
+ else
+ #endif
+ {
+ _module = ::LoadLibraryW(fs2us(path));
+ }
+ return (_module != NULL);
}
-#endif
-bool MyGetModuleFileName(HMODULE hModule, CSysString &result)
+bool MyGetModuleFileName(FString &path)
{
- result.Empty();
- TCHAR fullPath[MAX_PATH + 2];
- DWORD size = ::GetModuleFileName(hModule, fullPath, MAX_PATH + 1);
- if (size <= MAX_PATH && size != 0)
+ HMODULE hModule = g_hInstance;
+ path.Empty();
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- result = fullPath;
- return true;
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ DWORD size = ::GetModuleFileName(hModule, s, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ path = fas2fs(s);
+ return true;
+ }
+ }
+ else
+ #endif
+ {
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ DWORD size = ::GetModuleFileNameW(hModule, s, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ path = us2fs(s);
+ return true;
+ }
}
return false;
}
-#ifndef _UNICODE
-bool MyGetModuleFileName(HMODULE hModule, UString &result)
+#ifndef _SFX
+
+FString GetModuleDirPrefix()
{
- result.Empty();
- if (g_IsNT)
+ FString s;
+ if (MyGetModuleFileName(s))
{
- wchar_t fullPath[MAX_PATH + 2];
- DWORD size = ::GetModuleFileNameW(hModule, fullPath, MAX_PATH + 1);
- if (size <= MAX_PATH && size != 0)
+ int pos = s.ReverseFind(FCHAR_PATH_SEPARATOR);
+ if (pos >= 0)
{
- result = fullPath;
- return true;
+ s.DeleteFrom(pos + 1);
+ return s;
}
- return false;
}
- CSysString resultSys;
- if (!MyGetModuleFileName(hModule, resultSys))
- return false;
- result = MultiByteToUnicodeString(resultSys, GetCurrentCodePage());
- return true;
+ return FTEXT(".") FSTRING_PATH_SEPARATOR;
}
+
#endif
}}
diff --git a/src/libs/7zip/win/CPP/Windows/DLL.h b/src/libs/7zip/win/CPP/Windows/DLL.h
index 4a253b326..d8848ce95 100644
--- a/src/libs/7zip/win/CPP/Windows/DLL.h
+++ b/src/libs/7zip/win/CPP/Windows/DLL.h
@@ -9,15 +9,13 @@ namespace NWindows {
namespace NDLL {
#ifdef UNDER_CE
-#define My_GetProcAddress(module, proceName) GetProcAddressA(module, proceName)
+#define My_GetProcAddress(module, procName) ::GetProcAddressA(module, procName)
#else
-#define My_GetProcAddress(module, proceName) ::GetProcAddress(module, proceName)
+#define My_GetProcAddress(module, procName) ::GetProcAddress(module, procName)
#endif
-
+
class CLibrary
{
- bool LoadOperations(HMODULE newModule);
-protected:
HMODULE _module;
public:
CLibrary(): _module(NULL) {};
@@ -39,20 +37,15 @@ public:
return m;
}
- bool Free();
- bool LoadEx(LPCTSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
- bool Load(LPCTSTR fileName);
- #ifndef _UNICODE
- bool LoadEx(LPCWSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
- bool Load(LPCWSTR fileName);
- #endif
+ bool Free() throw();
+ bool LoadEx(CFSTR path, DWORD flags = LOAD_LIBRARY_AS_DATAFILE) throw();
+ bool Load(CFSTR path) throw();
FARPROC GetProc(LPCSTR procName) const { return My_GetProcAddress(_module, procName); }
};
-bool MyGetModuleFileName(HMODULE hModule, CSysString &result);
-#ifndef _UNICODE
-bool MyGetModuleFileName(HMODULE hModule, UString &result);
-#endif
+bool MyGetModuleFileName(FString &path);
+
+FString GetModuleDirPrefix();
}}
diff --git a/src/libs/7zip/win/CPP/Windows/Error.cpp b/src/libs/7zip/win/CPP/Windows/Error.cpp
deleted file mode 100644
index 7b18c29cc..000000000
--- a/src/libs/7zip/win/CPP/Windows/Error.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-// Windows/Error.h
-
-#include "StdAfx.h"
-
-#include "Windows/Error.h"
-#ifndef _UNICODE
-#include "Common/StringConvert.h"
-#endif
-
-#ifndef _UNICODE
-extern bool g_IsNT;
-#endif
-
-namespace NWindows {
-namespace NError {
-
-bool MyFormatMessage(DWORD messageID, CSysString &message)
-{
- LPVOID msgBuf;
- if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,messageID, 0, (LPTSTR) &msgBuf,0, NULL) == 0)
- return false;
- message = (LPCTSTR)msgBuf;
- ::LocalFree(msgBuf);
- return true;
-}
-
-#ifndef _UNICODE
-bool MyFormatMessage(DWORD messageID, UString &message)
-{
- if (g_IsNT)
- {
- LPVOID msgBuf;
- if (::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, messageID, 0, (LPWSTR) &msgBuf, 0, NULL) == 0)
- return false;
- message = (LPCWSTR)msgBuf;
- ::LocalFree(msgBuf);
- return true;
- }
- CSysString messageSys;
- bool result = MyFormatMessage(messageID, messageSys);
- message = GetUnicodeString(messageSys);
- return result;
-}
-#endif
-
-}}
diff --git a/src/libs/7zip/win/CPP/Windows/Error.h b/src/libs/7zip/win/CPP/Windows/Error.h
deleted file mode 100644
index 05b5cd0ea..000000000
--- a/src/libs/7zip/win/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/win/CPP/Windows/FileDir.cpp b/src/libs/7zip/win/CPP/Windows/FileDir.cpp
index 857946031..097f81efb 100644
--- a/src/libs/7zip/win/CPP/Windows/FileDir.cpp
+++ b/src/libs/7zip/win/CPP/Windows/FileDir.cpp
@@ -14,81 +14,62 @@
extern bool g_IsNT;
#endif
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
namespace NWindows {
namespace NFile {
-
-#if defined(WIN_LONG_PATH) && defined(_UNICODE)
-#define WIN_LONG_PATH2
-#endif
-
-// SetCurrentDirectory doesn't support \\?\ prefix
-
-#ifdef WIN_LONG_PATH
-bool GetLongPathBase(LPCWSTR fileName, UString &res);
-bool GetLongPath(LPCWSTR fileName, UString &res);
-#endif
-
-namespace NDirectory {
-
-#ifndef _UNICODE
-static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-static UString GetUnicodePath(const CSysString &sysPath)
- { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); }
-static CSysString GetSysPath(LPCWSTR sysPath)
- { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
-#endif
+namespace NDir {
#ifndef UNDER_CE
-bool MyGetWindowsDirectory(CSysString &path)
-{
- UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
-}
-
-bool MyGetSystemDirectory(CSysString &path)
+bool GetWindowsDir(FString &path)
{
- UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- path.ReleaseBuffer();
+ UINT needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetWindowsDirectory(s, MAX_PATH + 1);
+ path = fas2fs(s);
+ }
+ else
+ #endif
+ {
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetWindowsDirectoryW(s, MAX_PATH + 1);
+ path = us2fs(s);
+ }
return (needLength > 0 && needLength <= MAX_PATH);
}
-#endif
-
-#ifndef _UNICODE
-bool MyGetWindowsDirectory(UString &path)
+bool GetSystemDir(FString &path)
{
- if (g_IsNT)
+ UINT needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetSystemDirectory(s, MAX_PATH + 1);
+ path = fas2fs(s);
}
- CSysString sysPath;
- if (!MyGetWindowsDirectory(sysPath))
- return false;
- path = GetUnicodePath(sysPath);
- return true;
-}
-
-bool MyGetSystemDirectory(UString &path)
-{
- if (g_IsNT)
+ else
+ #endif
{
- UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetSystemDirectoryW(s, MAX_PATH + 1);
+ path = us2fs(s);
}
- CSysString sysPath;
- if (!MyGetSystemDirectory(sysPath))
- return false;
- path = GetUnicodePath(sysPath);
- return true;
+ return (needLength > 0 && needLength <= MAX_PATH);
}
#endif
-bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
+bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
{
#ifndef _UNICODE
if (!g_IsNT)
@@ -97,17 +78,18 @@ bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime,
return false;
}
#endif
- HANDLE hDir = ::CreateFileW(fileName, GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+ HANDLE hDir = INVALID_HANDLE_VALUE;
+ IF_USE_MAIN_PATH
+ hDir = ::CreateFileW(fs2us(path), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
#ifdef WIN_LONG_PATH
- if (hDir == INVALID_HANDLE_VALUE)
+ if (hDir == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
UString longPath;
- if (GetLongPath(fileName, longPath))
- hDir = ::CreateFileW(longPath, GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ hDir = ::CreateFileW(longPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
}
#endif
@@ -120,790 +102,482 @@ bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime,
return res;
}
-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
-{
- if (::SetFileAttributes(fileName, fileAttributes))
- return true;
- #ifdef WIN_LONG_PATH2
- UString longPath;
- if (GetLongPath(fileName, longPath))
- return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
- #endif
- return false;
-}
-
-bool MyRemoveDirectory(LPCTSTR pathName)
-{
- if (::RemoveDirectory(pathName))
- return true;
- #ifdef WIN_LONG_PATH2
- UString longPath;
- if (GetLongPath(pathName, longPath))
- return BOOLToBool(::RemoveDirectoryW(longPath));
- #endif
- return false;
-}
-
-#ifdef WIN_LONG_PATH
-bool GetLongPaths(LPCWSTR s1, LPCWSTR 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 = s1;
- if (d2.IsEmpty()) d2 = s2;
- return true;
-}
-#endif
-
-bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName)
-{
- if (::MoveFile(existFileName, newFileName))
- return true;
- #ifdef WIN_LONG_PATH2
- UString d1, d2;
- if (GetLongPaths(existFileName, newFileName, d1, d2))
- return BOOLToBool(::MoveFileW(d1, d2));
- #endif
- return false;
-}
-
-#ifndef _UNICODE
-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
+bool SetFileAttrib(CFSTR path, DWORD attrib)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return MySetFileAttributes(GetSysPath(fileName), fileAttributes);
- if (::SetFileAttributesW(fileName, fileAttributes))
- return true;
- #ifdef WIN_LONG_PATH
- UString longPath;
- if (GetLongPath(fileName, longPath))
- return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
+ {
+ if (::SetFileAttributes(fs2fas(path), attrib))
+ return true;
+ }
+ else
#endif
+ {
+ IF_USE_MAIN_PATH
+ if (::SetFileAttributesW(fs2us(path), attrib))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ return BOOLToBool(::SetFileAttributesW(longPath, attrib));
+ }
+ #endif
+ }
return false;
}
-
-bool MyRemoveDirectory(LPCWSTR pathName)
+bool RemoveDir(CFSTR path)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return MyRemoveDirectory(GetSysPath(pathName));
- if (::RemoveDirectoryW(pathName))
- return true;
- #ifdef WIN_LONG_PATH
- UString longPath;
- if (GetLongPath(pathName, longPath))
- return BOOLToBool(::RemoveDirectoryW(longPath));
+ {
+ if (::RemoveDirectory(fs2fas(path)))
+ return true;
+ }
+ else
#endif
+ {
+ IF_USE_MAIN_PATH
+ if (::RemoveDirectoryW(fs2us(path)))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ return BOOLToBool(::RemoveDirectoryW(longPath));
+ }
+ #endif
+ }
return false;
}
-bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
+bool MyMoveFile(CFSTR oldFile, CFSTR newFile)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName));
- if (::MoveFileW(existFileName, newFileName))
- return true;
- #ifdef WIN_LONG_PATH
- UString d1, d2;
- if (GetLongPaths(existFileName, newFileName, d1, d2))
- return BOOLToBool(::MoveFileW(d1, d2));
- #endif
- return false;
-}
-#endif
-
-bool MyCreateDirectory(LPCTSTR pathName)
-{
- if (::CreateDirectory(pathName, NULL))
- return true;
- #ifdef WIN_LONG_PATH2
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
{
- UString longPath;
- if (GetLongPath(pathName, longPath))
- return BOOLToBool(::CreateDirectoryW(longPath, NULL));
+ if (::MoveFile(fs2fas(oldFile), fs2fas(newFile)))
+ return true;
}
+ else
#endif
+ {
+ IF_USE_MAIN_PATH_2(oldFile, newFile)
+ if (::MoveFileW(fs2us(oldFile), fs2us(newFile)))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH_2)
+ {
+ UString d1, d2;
+ if (GetSuperPaths(oldFile, newFile, d1, d2, USE_MAIN_PATH_2))
+ return BOOLToBool(::MoveFileW(d1, d2));
+ }
+ #endif
+ }
return false;
}
-#ifndef _UNICODE
-bool MyCreateDirectory(LPCWSTR pathName)
+#ifndef UNDER_CE
+
+EXTERN_C_BEGIN
+typedef BOOL (WINAPI *Func_CreateHardLinkW)(
+ LPCWSTR lpFileName,
+ LPCWSTR lpExistingFileName,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes
+ );
+EXTERN_C_END
+
+bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return MyCreateDirectory(GetSysPath(pathName));
- if (::CreateDirectoryW(pathName, NULL))
- return true;
- #ifdef WIN_LONG_PATH
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
{
- UString longPath;
- if (GetLongPath(pathName, longPath))
- return BOOLToBool(::CreateDirectoryW(longPath, NULL));
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ /*
+ if (::CreateHardLink(fs2fas(newFileName), fs2fas(existFileName), NULL))
+ return true;
+ */
}
+ else
#endif
- return false;
-}
-#endif
-
-/*
-bool CreateComplexDirectory(LPCTSTR pathName)
-{
- NName::CParsedPath path;
- path.ParsePath(pathName);
- CSysString fullPath = path.Prefix;
- DWORD errorCode = ERROR_SUCCESS;
- for (int i = 0; i < path.PathParts.Size(); i++)
{
- const CSysString &string = path.PathParts[i];
- if (string.IsEmpty())
- {
- if (i != path.PathParts.Size() - 1)
- return false;
- return true;
- }
- fullPath += path.PathParts[i];
- if (!MyCreateDirectory(fullPath))
+ Func_CreateHardLinkW my_CreateHardLinkW = (Func_CreateHardLinkW)
+ ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "CreateHardLinkW");
+ if (!my_CreateHardLinkW)
+ return false;
+ IF_USE_MAIN_PATH_2(newFileName, existFileName)
+ if (my_CreateHardLinkW(fs2us(newFileName), fs2us(existFileName), NULL))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH_2)
{
- DWORD errorCode = GetLastError();
- if (errorCode != ERROR_ALREADY_EXISTS)
- return false;
+ UString d1, d2;
+ if (GetSuperPaths(newFileName, existFileName, d1, d2, USE_MAIN_PATH_2))
+ return BOOLToBool(my_CreateHardLinkW(d1, d2, NULL));
}
- fullPath += NName::kDirDelimiter;
+ #endif
}
- return true;
+ return false;
}
-*/
-bool CreateComplexDirectory(LPCTSTR _aPathName)
+#endif
+
+bool CreateDir(CFSTR path)
{
- CSysString pathName = _aPathName;
- int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
- if (pos > 0 && pos == pathName.Length() - 1)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- if (pathName.Length() == 3 && pathName[1] == ':')
- return true; // Disk folder;
- pathName.Delete(pos);
+ if (::CreateDirectory(fs2fas(path), NULL))
+ return true;
}
- CSysString pathName2 = pathName;
- pos = pathName.Length();
- for (;;)
+ else
+ #endif
{
- if (MyCreateDirectory(pathName))
- break;
- if (::GetLastError() == ERROR_ALREADY_EXISTS)
- {
- NFind::CFileInfo fileInfo;
- if (!fileInfo.Find(pathName)) // For network folders
+ IF_USE_MAIN_PATH
+ if (::CreateDirectoryW(fs2us(path), NULL))
return true;
- if (!fileInfo.IsDir())
- return false;
- break;
+ #ifdef WIN_LONG_PATH
+ if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH)
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ return BOOLToBool(::CreateDirectoryW(longPath, NULL));
}
- 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;
+ #endif
}
- return true;
+ return false;
}
-#ifndef _UNICODE
-
-bool CreateComplexDirectory(LPCWSTR _aPathName)
+bool CreateComplexDir(CFSTR _aPathName)
{
- UString pathName = _aPathName;
- int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
- if (pos > 0 && pos == pathName.Length() - 1)
+ FString pathName = _aPathName;
+ int pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
+ if (pos > 0 && (unsigned)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();
+ const FString pathName2 = pathName;
+ pos = pathName.Len();
+
for (;;)
{
- if (MyCreateDirectory(pathName))
+ if (CreateDir(pathName))
break;
if (::GetLastError() == ERROR_ALREADY_EXISTS)
{
- NFind::CFileInfoW fileInfo;
+ NFind::CFileInfo fileInfo;
if (!fileInfo.Find(pathName)) // For network folders
return true;
if (!fileInfo.IsDir())
return false;
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':')
return false;
- pathName = pathName.Left(pos);
+ pathName.DeleteFrom(pos);
}
- pathName = pathName2;
- while (pos < pathName.Length())
+
+ while (pos < (int)pathName2.Len())
{
- pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
+ pos = pathName2.Find(FCHAR_PATH_SEPARATOR, pos + 1);
if (pos < 0)
- pos = pathName.Length();
- if (!MyCreateDirectory(pathName.Left(pos)))
+ pos = pathName2.Len();
+ pathName.SetFrom(pathName2, pos);
+ if (!CreateDir(pathName))
return false;
}
+
return true;
}
-#endif
-
-bool DeleteFileAlways(LPCTSTR name)
+bool DeleteFileAlways(CFSTR path)
{
- if (!MySetFileAttributes(name, 0))
+ if (!SetFileAttrib(path, 0))
return false;
- if (::DeleteFile(name))
- return true;
- #ifdef WIN_LONG_PATH2
- UString longPath;
- if (GetLongPath(name, longPath))
- return BOOLToBool(::DeleteFileW(longPath));
- #endif
- return false;
-}
-
-#ifndef _UNICODE
-bool DeleteFileAlways(LPCWSTR name)
-{
+ #ifndef _UNICODE
if (!g_IsNT)
- return DeleteFileAlways(GetSysPath(name));
- if (!MySetFileAttributes(name, 0))
- return false;
- if (::DeleteFileW(name))
- return true;
- #ifdef WIN_LONG_PATH
- UString longPath;
- if (GetLongPath(name, longPath))
- return BOOLToBool(::DeleteFileW(longPath));
+ {
+ if (::DeleteFile(fs2fas(path)))
+ return true;
+ }
+ else
#endif
+ {
+ IF_USE_MAIN_PATH
+ if (::DeleteFileW(fs2us(path)))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ return BOOLToBool(::DeleteFileW(longPath));
+ }
+ #endif
+ }
return false;
}
-#endif
-
-static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)
-{
- if (fileInfo.IsDir())
- return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
- return DeleteFileAlways(pathPrefix + fileInfo.Name);
-}
-bool RemoveDirectoryWithSubItems(const CSysString &path)
+bool RemoveDirWithSubItems(const FString &path)
{
- NFind::CFileInfo fileInfo;
- CSysString pathPrefix = path + NName::kDirDelimiter;
+ bool needRemoveSubItems = true;
{
- NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
- while (enumerator.Next(fileInfo))
- if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
- return false;
+ NFind::CFileInfo fi;
+ if (!fi.Find(path))
+ return false;
+ if (!fi.IsDir())
+ {
+ ::SetLastError(ERROR_DIRECTORY);
+ return false;
+ }
+ if (fi.HasReparsePoint())
+ needRemoveSubItems = false;
}
- if (!MySetFileAttributes(path, 0))
- return false;
- return MyRemoveDirectory(path);
-}
-#ifndef _UNICODE
-static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)
-{
- if (fileInfo.IsDir())
- return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
- return DeleteFileAlways(pathPrefix + fileInfo.Name);
-}
-bool RemoveDirectoryWithSubItems(const UString &path)
-{
- NFind::CFileInfoW fileInfo;
- UString pathPrefix = path + UString(NName::kDirDelimiter);
+ if (needRemoveSubItems)
{
- NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
- while (enumerator.Next(fileInfo))
- if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+ 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 (!MySetFileAttributes(path, 0))
- return false;
- return MyRemoveDirectory(path);
-}
-#endif
-bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
-{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
+ if (!SetFileAttrib(path, 0))
return false;
- resultName = resultName.Left(index);
- return true;
-}
-
-bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
-{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Mid(index);
- return true;
+ return RemoveDir(path);
}
#ifdef UNDER_CE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath)
-{
- resultPath = fileName;
- return true;
-}
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
+bool MyGetFullPathName(CFSTR path, FString &resFullPath)
{
- resultPath = fileName;
- // change it
- fileNamePartStartIndex = resultPath.ReverseFind(WCHAR_PATH_SEPARATOR);
- fileNamePartStartIndex++;
+ resFullPath = path;
return true;
}
#else
-bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
+bool MyGetFullPathName(CFSTR path, FString &resFullPath)
{
- DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- shortPath.ReleaseBuffer();
- return (needLength > 0 && needLength < MAX_PATH);
+ return GetFullPath(path, resFullPath);
}
-#ifdef WIN_LONG_PATH
-
-static UString GetLastPart(LPCWSTR path)
+bool SetCurrentDir(CFSTR path)
{
- int i = (int)wcslen(path);
- for (; i > 0; i--)
- {
- WCHAR c = path[i - 1];
- if (c == WCHAR_PATH_SEPARATOR || c == '/')
- break;
- }
- return path + i;
-}
-
-static void AddTrailingDots(LPCWSTR oldPath, UString &newPath)
-{
- int len = (int)wcslen(oldPath);
- int i;
- for (i = len; i > 0 && oldPath[i - 1] == '.'; i--);
- if (i == 0 || i == len)
- return;
- UString oldName = GetLastPart(oldPath);
- UString newName = GetLastPart(newPath);
- int nonDotsLen = oldName.Length() - (len - i);
- if (nonDotsLen == 0 || newName.CompareNoCase(oldName.Left(nonDotsLen)) != 0)
- return;
- for (; i != len; i++)
- newPath += '.';
-}
-
-#endif
-
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)
-{
- resultPath.Empty();
- LPTSTR fileNamePointer = 0;
- LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
- DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength == 0)
- return false;
- if (needLength >= MAX_PATH)
+ // SetCurrentDirectory doesn't support \\?\ prefix
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- #ifdef WIN_LONG_PATH2
- needLength++;
- buffer = resultPath.GetBuffer(needLength + 1);
- DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength2 == 0 || needLength2 > needLength)
- #endif
- return false;
+ return BOOLToBool(::SetCurrentDirectory(fs2fas(path)));
}
- if (fileNamePointer == 0)
- fileNamePartStartIndex = lstrlen(fileName);
else
- fileNamePartStartIndex = (int)(fileNamePointer - buffer);
- #ifdef _UNICODE
- #ifdef WIN_LONG_PATH
- AddTrailingDots(fileName, resultPath);
#endif
- #endif
- return true;
+ {
+ return BOOLToBool(::SetCurrentDirectoryW(fs2us(path)));
+ }
}
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
+bool GetCurrentDir(FString &path)
{
- resultPath.Empty();
- if (g_IsNT)
+ path.Empty();
+ DWORD needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- LPWSTR fileNamePointer = 0;
- LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);
- DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength == 0)
- return false;
- if (needLength >= MAX_PATH)
- {
- #ifdef WIN_LONG_PATH
- needLength++;
- buffer = resultPath.GetBuffer(needLength + 1);
- DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength2 == 0 || needLength2 > needLength)
- #endif
- return false;
- }
- if (fileNamePointer == 0)
- fileNamePartStartIndex = MyStringLen(fileName);
- else
- fileNamePartStartIndex = (int)(fileNamePointer - buffer);
- #ifdef WIN_LONG_PATH
- AddTrailingDots(fileName, resultPath);
- #endif
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetCurrentDirectory(MAX_PATH + 1, s);
+ path = fas2fs(s);
}
else
+ #endif
{
- CSysString sysPath;
- if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex))
- return false;
- UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex));
- UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex));
- fileNamePartStartIndex = resultPath1.Length();
- resultPath = resultPath1 + resultPath2;
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, s);
+ path = us2fs(s);
}
- return true;
-}
-#endif
-
-
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
-{
- int index;
- return MyGetFullPathName(fileName, path, index);
+ return (needLength > 0 && needLength <= MAX_PATH);
}
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &path)
-{
- int index;
- return MyGetFullPathName(fileName, path, index);
-}
#endif
-#ifndef _UNICODE
-bool GetOnlyName(LPCWSTR fileName, UString &resultName)
+bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName)
{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Mid(index);
- return true;
-}
-#endif
-
-#ifndef _UNICODE
-bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)
-{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Left(index);
- 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;
}
-#endif
-bool MyGetCurrentDirectory(CSysString &path)
+bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix)
{
- DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
+ FString resFileName;
+ return GetFullPathAndSplit(path, resDirPrefix, resFileName);
}
-#ifndef _UNICODE
-bool MySetCurrentDirectory(LPCWSTR path)
+bool MyGetTempPath(FString &path)
{
- if (g_IsNT)
- return BOOLToBool(::SetCurrentDirectoryW(path));
- return MySetCurrentDirectory(GetSysPath(path));
-}
-bool MyGetCurrentDirectory(UString &path)
-{
- if (g_IsNT)
+ path.Empty();
+ DWORD needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetTempPath(MAX_PATH + 1, s);
+ path = fas2fs(s);
}
- CSysString sysPath;
- if (!MyGetCurrentDirectory(sysPath))
- return false;
- path = GetUnicodePath(sysPath);
- return true;
-}
-#endif
-
-bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
- CSysString &resultPath, UINT32 &filePart)
-{
- LPTSTR filePartPointer;
- DWORD value = ::SearchPath(path, fileName, extension,
- MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
- filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath);
- resultPath.ReleaseBuffer();
- return (value > 0 && value <= MAX_PATH);
-}
-#endif
-
-#ifndef _UNICODE
-bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
- UString &resultPath, UINT32 &filePart)
-{
- if (g_IsNT)
+ else
+ #endif
{
- LPWSTR filePartPointer = 0;
- DWORD value = ::SearchPathW(path, fileName, extension,
- MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
- filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath);
- resultPath.ReleaseBuffer();
- return (value > 0 && value <= MAX_PATH);
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetTempPathW(MAX_PATH + 1, s);;
+ path = us2fs(s);
}
-
- CSysString sysPath;
- if (!MySearchPath(
- path != 0 ? (LPCTSTR)GetSysPath(path): 0,
- fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0,
- extension != 0 ? (LPCTSTR)GetSysPath(extension): 0,
- sysPath, filePart))
- return false;
- UString resultPath1 = GetUnicodePath(sysPath.Left(filePart));
- UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart));
- filePart = resultPath1.Length();
- resultPath = resultPath1 + resultPath2;
- return true;
-}
-#endif
-
-bool MyGetTempPath(CSysString &path)
-{
- DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
return (needLength > 0 && needLength <= MAX_PATH);
}
-#ifndef _UNICODE
-bool MyGetTempPath(UString &path)
-{
- path.Empty();
- if (g_IsNT)
- {
- DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
- }
- CSysString sysPath;
- if (!MyGetTempPath(sysPath))
- return false;
- path = GetUnicodePath(sysPath);
- return true;
-}
-#endif
-
-UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)
-{
- UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
- return number;
-}
-
-#ifndef _UNICODE
-UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)
+static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COutFile *outFile)
{
- if (g_IsNT)
+ UInt32 d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
+ for (unsigned i = 0; i < 100; i++)
{
- UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));
- path.ReleaseBuffer();
- return number;
+ 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;
}
- CSysString sysPath;
- UINT number = MyGetTempFileName(
- dirPath ? (LPCTSTR)GetSysPath(dirPath): 0,
- prefix ? (LPCTSTR)GetSysPath(prefix): 0,
- sysPath);
- path = GetUnicodePath(sysPath);
- return number;
+ path.Empty();
+ return false;
}
-#endif
-UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
+bool CTempFile::Create(CFSTR prefix, NIO::COutFile *outFile)
{
- Remove();
- UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
- if (number != 0)
- {
- _fileName = resultPath;
- _mustBeDeleted = true;
- }
- return number;
+ if (!Remove())
+ return false;
+ if (!CreateTempFile(prefix, false, _path, outFile))
+ return false;
+ _mustBeDeleted = true;
+ 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;
- #ifdef UNDER_CE
- return false;
- #else
- if (!MyGetWindowsDirectory(tempPath))
+ if (!CreateTempFile(tempPath + namePrefix, true, _path, outFile))
return false;
- return (Create(tempPath, prefix, resultPath) != 0);
- #endif
+ _mustBeDeleted = true;
+ return true;
}
bool CTempFile::Remove()
{
if (!_mustBeDeleted)
return true;
- _mustBeDeleted = !DeleteFileAlways(_fileName);
+ _mustBeDeleted = !DeleteFileAlways(_path);
return !_mustBeDeleted;
}
-#ifndef _UNICODE
-
-UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
+bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore)
{
- Remove();
- UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
- if (number != 0)
- {
- _fileName = resultPath;
- _mustBeDeleted = true;
- }
- return number;
+ if (deleteDestBefore)
+ if (NFind::DoesFileExist(name))
+ if (!DeleteFileAlways(name))
+ return false;
+ DisableDeleting();
+ return MyMoveFile(_path, name);
}
-bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
+bool CTempDir::Create(CFSTR prefix)
{
- UString tempPath;
+ if (!Remove())
+ return false;
+ FString tempPath;
if (!MyGetTempPath(tempPath))
return false;
- if (Create(tempPath, prefix, resultPath) != 0)
- return true;
- if (!MyGetWindowsDirectory(tempPath))
+ if (!CreateTempFile(tempPath + prefix, true, _path, NULL))
return false;
- return (Create(tempPath, prefix, resultPath) != 0);
+ _mustBeDeleted = true;
+ return true;
}
-bool CTempFileW::Remove()
+bool CTempDir::Remove()
{
if (!_mustBeDeleted)
return true;
- _mustBeDeleted = !DeleteFileAlways(_fileName);
+ _mustBeDeleted = !RemoveDirWithSubItems(_path);
return !_mustBeDeleted;
}
-#endif
-
-bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)
-{
- /*
- CSysString prefix = tempPath + prefixChars;
- CRandom random;
- random.Init();
- */
- for (;;)
- {
- {
- CTempFile tempFile;
- if (!tempFile.Create(prefix, dirName))
- return false;
- if (!tempFile.Remove())
- 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;
- }
-}
-
-bool CTempDirectory::Create(LPCTSTR prefix)
-{
- Remove();
- return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
-}
-
-#ifndef _UNICODE
-
-bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
-{
- /*
- CSysString prefix = tempPath + prefixChars;
- CRandom random;
- random.Init();
- */
- for (;;)
- {
- {
- CTempFileW tempFile;
- if (!tempFile.Create(prefix, dirName))
- return false;
- if (!tempFile.Remove())
- 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;
- }
-}
-
-bool CTempDirectoryW::Create(LPCWSTR prefix)
-{
- Remove();
- return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
-}
-
-#endif
-
}}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileDir.h b/src/libs/7zip/win/CPP/Windows/FileDir.h
index 04542d872..02d3e5a57 100644
--- a/src/libs/7zip/win/CPP/Windows/FileDir.h
+++ b/src/libs/7zip/win/CPP/Windows/FileDir.h
@@ -1,174 +1,94 @@
// 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"
+
+#include "FileIO.h"
namespace NWindows {
namespace NFile {
-namespace NDirectory {
+namespace NDir {
-#ifdef WIN_LONG_PATH
-bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2);
-#endif
+bool GetWindowsDir(FString &path);
+bool GetSystemDir(FString &path);
-bool MyGetWindowsDirectory(CSysString &path);
-bool MyGetSystemDirectory(CSysString &path);
-#ifndef _UNICODE
-bool MyGetWindowsDirectory(UString &path);
-bool MyGetSystemDirectory(UString &path);
-#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 SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
-
-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes);
-bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName);
-bool MyRemoveDirectory(LPCTSTR pathName);
-bool MyCreateDirectory(LPCTSTR pathName);
-bool CreateComplexDirectory(LPCTSTR pathName);
-bool DeleteFileAlways(LPCTSTR name);
-bool RemoveDirectoryWithSubItems(const CSysString &path);
-
-#ifndef _UNICODE
-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes);
-bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName);
-bool MyRemoveDirectory(LPCWSTR pathName);
-bool MyCreateDirectory(LPCWSTR pathName);
-bool CreateComplexDirectory(LPCWSTR pathName);
-bool DeleteFileAlways(LPCWSTR name);
-bool RemoveDirectoryWithSubItems(const UString &path);
+#ifndef UNDER_CE
+bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName);
#endif
-bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName);
-bool GetOnlyName(LPCTSTR fileName, CSysString &resultName);
-#ifdef UNDER_CE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex);
-#else
-bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath);
-
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex);
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath);
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath,
- int &fileNamePartStartIndex);
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);
-bool GetOnlyName(LPCWSTR fileName, UString &resultName);
-bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName);
-#endif
+bool RemoveDir(CFSTR path);
+bool CreateDir(CFSTR path);
+bool CreateComplexDir(CFSTR path);
+bool DeleteFileAlways(CFSTR name);
+bool RemoveDirWithSubItems(const FString &path);
-inline bool MySetCurrentDirectory(LPCTSTR path)
- { return BOOLToBool(::SetCurrentDirectory(path)); }
-bool MyGetCurrentDirectory(CSysString &resultPath);
-#ifndef _UNICODE
-bool MySetCurrentDirectory(LPCWSTR path);
-bool MyGetCurrentDirectory(UString &resultPath);
-#endif
+bool MyGetFullPathName(CFSTR path, FString &resFullPath);
+bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName);
+bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix);
-bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, CSysString &resultPath, UINT32 &filePart);
-#ifndef _UNICODE
-bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath, UINT32 &filePart);
-#endif
+#ifndef UNDER_CE
-inline bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, CSysString &resultPath)
-{
- UINT32 value;
- return MySearchPath(path, fileName, extension, resultPath, value);
-}
-
-#ifndef _UNICODE
-inline bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath)
-{
- UINT32 value;
- return MySearchPath(path, fileName, extension, resultPath, value);
-}
-#endif
+bool SetCurrentDir(CFSTR path);
+bool GetCurrentDir(FString &resultPath);
#endif
-bool MyGetTempPath(CSysString &resultPath);
-#ifndef _UNICODE
-bool MyGetTempPath(UString &resultPath);
-#endif
-
-UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
-#ifndef _UNICODE
-UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, 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;
-#else
-class CTempFileW
+class CTempDir
{
bool _mustBeDeleted;
- UString _fileName;
+ FString _path;
public:
- CTempFileW(): _mustBeDeleted(false) {}
- ~CTempFileW() { Remove(); }
+ CTempDir(): _mustBeDeleted(false) {}
+ ~CTempDir() { Remove(); }
+ const FString &GetPath() const { return _path; }
void DisableDeleting() { _mustBeDeleted = false; }
- UINT Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
- bool Create(LPCWSTR prefix, UString &resultPath);
+ bool Create(CFSTR namePrefix) ;
bool Remove();
};
-#endif
-
-bool CreateTempDirectory(LPCTSTR prefixChars, CSysString &dirName);
-class CTempDirectory
+#if !defined(UNDER_CE)
+class CCurrentDirRestorer
{
- bool _mustBeDeleted;
- CSysString _tempDir;
+ FString _path;
public:
- const CSysString &GetPath() const { return _tempDir; }
- CTempDirectory(): _mustBeDeleted(false) {}
- ~CTempDirectory() { Remove(); }
- bool Create(LPCTSTR prefix) ;
- bool Remove()
+ bool NeedRestore;
+
+ CCurrentDirRestorer(): NeedRestore(true)
{
- if (!_mustBeDeleted)
- return true;
- _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
- return (!_mustBeDeleted);
+ GetCurrentDir(_path);
}
- void DisableDeleting() { _mustBeDeleted = false; }
-};
-
-#ifdef _UNICODE
-typedef CTempDirectory CTempDirectoryW;
-#else
-class CTempDirectoryW
-{
- bool _mustBeDeleted;
- UString _tempDir;
-public:
- const UString &GetPath() const { return _tempDir; }
- CTempDirectoryW(): _mustBeDeleted(false) {}
- ~CTempDirectoryW() { Remove(); }
- bool Create(LPCWSTR prefix) ;
- bool Remove()
+ ~CCurrentDirRestorer()
{
- if (!_mustBeDeleted)
- return true;
- _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
- return (!_mustBeDeleted);
+ if (!NeedRestore)
+ return;
+ FString s;
+ if (GetCurrentDir(s))
+ if (s != _path)
+ SetCurrentDir(_path);
}
- void DisableDeleting() { _mustBeDeleted = false; }
};
#endif
diff --git a/src/libs/7zip/win/CPP/Windows/FileFind.cpp b/src/libs/7zip/win/CPP/Windows/FileFind.cpp
index e3358f905..7f58288fe 100644
--- a/src/libs/7zip/win/CPP/Windows/FileFind.cpp
+++ b/src/libs/7zip/win/CPP/Windows/FileFind.cpp
@@ -4,6 +4,7 @@
#include "FileFind.h"
#include "FileIO.h"
+#include "FileName.h"
#ifndef _UNICODE
#include "../Common/StringConvert.h"
#endif
@@ -12,45 +13,55 @@
extern bool g_IsNT;
#endif
-namespace NWindows {
-namespace NFile {
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
-#ifdef SUPPORT_DEVICE_FILE
-bool IsDeviceName(LPCTSTR n);
-#ifndef _UNICODE
-bool IsDeviceName(LPCWSTR n);
-#endif
-#endif
+#if defined(_WIN32) && !defined(UNDER_CE)
-#if defined(WIN_LONG_PATH) && defined(_UNICODE)
-#define WIN_LONG_PATH2
-#endif
+EXTERN_C_BEGIN
+
+typedef enum
+{
+ My_FindStreamInfoStandard,
+ My_FindStreamInfoMaxInfoLevel
+} MY_STREAM_INFO_LEVELS;
+
+typedef struct
+{
+ LARGE_INTEGER StreamSize;
+ WCHAR cStreamName[MAX_PATH + 36];
+} MY_WIN32_FIND_STREAM_DATA, *MY_PWIN32_FIND_STREAM_DATA;
-bool GetLongPath(LPCWSTR fileName, UString &res);
+typedef WINBASEAPI HANDLE (WINAPI *FindFirstStreamW_Ptr)(LPCWSTR fileName, MY_STREAM_INFO_LEVELS infoLevel,
+ LPVOID findStreamData, DWORD flags);
-namespace NFind {
+typedef WINBASEAPI BOOL (APIENTRY *FindNextStreamW_Ptr)(HANDLE findStream, LPVOID findStreamData);
-static const TCHAR kDot = TEXT('.');
+EXTERN_C_END
-bool CFileInfo::IsDots() const
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#ifdef SUPPORT_DEVICE_FILE
+namespace NSystem
{
- if (!IsDir() || Name.IsEmpty())
- return false;
- if (Name[0] != kDot)
- return false;
- return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
}
+#endif
-#ifndef _UNICODE
-bool CFileInfoW::IsDots() const
+namespace NFind {
+
+bool CFileInfo::IsDots() const throw()
{
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('.'));
}
-#endif
#define WIN_FD_TO_MY_FI(fi, fd) \
fi.Attrib = fd.dwFileAttributes; \
@@ -58,6 +69,7 @@ bool CFileInfoW::IsDots() const
fi.ATime = fd.ftLastAccessTime; \
fi.MTime = fd.ftLastWriteTime; \
fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; \
+ fi.IsAltStream = false; \
fi.IsDevice = false;
/*
@@ -68,33 +80,31 @@ bool CFileInfoW::IsDots() const
#endif
*/
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
+static void Convert_WIN32_FIND_DATA_to_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfo &fi)
{
WIN_FD_TO_MY_FI(fi, fd);
- fi.Name = fd.cFileName;
+ fi.Name = us2fs(fd.cFileName);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // fi.ShortName = us2fs(fd.cAlternateFileName);
+ #endif
}
#ifndef _UNICODE
-static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfoW &fi)
-{
- WIN_FD_TO_MY_FI(fi, fd);
- fi.Name = fd.cFileName;
-}
-
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfoW &fi)
+static void Convert_WIN32_FIND_DATA_to_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
{
WIN_FD_TO_MY_FI(fi, fd);
- fi.Name = GetUnicodeString(fd.cFileName, GetCurrentCodePage());
+ fi.Name = fas2fs(fd.cFileName);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // fi.ShortName = fas2fs(fd.cAlternateFileName);
+ #endif
}
#endif
-
+
////////////////////////////////
// CFindFile
-bool CFindFile::Close()
+bool CFindFileBase::Close() throw()
{
if (_handle == INVALID_HANDLE_VALUE)
return true;
@@ -104,183 +114,344 @@ bool CFindFile::Close()
return true;
}
-
-bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fi)
+bool CFindFile::FindFirst(CFSTR path, CFileInfo &fi)
{
if (!Close())
return false;
- WIN32_FIND_DATA fd;
- _handle = ::FindFirstFile(wildcard, &fd);
- #ifdef WIN_LONG_PATH2
- if (_handle == INVALID_HANDLE_VALUE)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- UString longPath;
- if (GetLongPath(wildcard, longPath))
- _handle = ::FindFirstFileW(longPath, &fd);
+ WIN32_FIND_DATAA fd;
+ _handle = ::FindFirstFileA(fs2fas(path), &fd);
+ if (_handle == INVALID_HANDLE_VALUE)
+ return false;
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
+ else
#endif
- if (_handle == INVALID_HANDLE_VALUE)
- return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
- return true;
-}
-
-#ifndef _UNICODE
-bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fi)
-{
- if (!Close())
- return false;
- if (g_IsNT)
{
WIN32_FIND_DATAW fd;
- _handle = ::FindFirstFileW(wildcard, &fd);
+
+ IF_USE_MAIN_PATH
+ _handle = ::FindFirstFileW(fs2us(path), &fd);
#ifdef WIN_LONG_PATH
- if (_handle == INVALID_HANDLE_VALUE)
+ if (_handle == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
UString longPath;
- if (GetLongPath(wildcard, longPath))
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
_handle = ::FindFirstFileW(longPath, &fd);
}
#endif
- if (_handle != INVALID_HANDLE_VALUE)
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ if (_handle == INVALID_HANDLE_VALUE)
+ return false;
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
- else
+ return true;
+}
+
+bool CFindFile::FindNext(CFileInfo &fi)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
WIN32_FIND_DATAA fd;
- _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
- GetCurrentCodePage()), &fd);
- if (_handle != INVALID_HANDLE_VALUE)
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ if (!::FindNextFileA(_handle, &fd))
+ return false;
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
- return (_handle != INVALID_HANDLE_VALUE);
+ else
+ #endif
+ {
+ WIN32_FIND_DATAW fd;
+ if (!::FindNextFileW(_handle, &fd))
+ return false;
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
+ }
+ return true;
}
-#endif
-bool CFindFile::FindNext(CFileInfo &fi)
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+////////////////////////////////
+// AltStreams
+
+static FindFirstStreamW_Ptr g_FindFirstStreamW;
+static FindNextStreamW_Ptr g_FindNextStreamW;
+
+struct CFindStreamLoader
{
- WIN32_FIND_DATA fd;
- bool result = BOOLToBool(::FindNextFile(_handle, &fd));
- if (result)
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
- return result;
+ CFindStreamLoader()
+ {
+ g_FindFirstStreamW = (FindFirstStreamW_Ptr)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "FindFirstStreamW");
+ g_FindNextStreamW = (FindNextStreamW_Ptr)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "FindNextStreamW");
+ }
+} g_FindStreamLoader;
+
+bool CStreamInfo::IsMainStream() const throw()
+{
+ return Name == L"::$DATA";
+};
+
+UString CStreamInfo::GetReducedName() const
+{
+ UString s = Name;
+ if (s.Len() >= 6)
+ if (wcscmp(s.RightPtr(6), L":$DATA") == 0)
+ s.DeleteFrom(s.Len() - 6);
+ return s;
}
-#ifndef _UNICODE
-bool CFindFile::FindNext(CFileInfoW &fi)
+static void Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(const MY_WIN32_FIND_STREAM_DATA &sd, CStreamInfo &si)
+{
+ si.Size = sd.StreamSize.QuadPart;
+ si.Name = sd.cStreamName;
+}
+
+bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si)
{
- if (g_IsNT)
+ if (!Close())
+ return false;
+ if (!g_FindFirstStreamW)
{
- WIN32_FIND_DATAW fd;
- if (!::FindNextFileW(_handle, &fd))
+ ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ }
+ {
+ MY_WIN32_FIND_STREAM_DATA sd;
+ IF_USE_MAIN_PATH
+ _handle = g_FindFirstStreamW(fs2us(path), My_FindStreamInfoStandard, &sd, 0);
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ if (::GetLastError() == ERROR_HANDLE_EOF)
+ return false;
+ // long name can be tricky for path like ".\dirName".
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ _handle = g_FindFirstStreamW(longPath, My_FindStreamInfoStandard, &sd, 0);
+ }
+ #endif
+ }
+ if (_handle == INVALID_HANDLE_VALUE)
return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si);
}
- else
+ return true;
+}
+
+bool CFindStream::FindNext(CStreamInfo &si)
+{
+ if (!g_FindNextStreamW)
{
- WIN32_FIND_DATAA fd;
- if (!::FindNextFileA(_handle, &fd))
+ ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ }
+ {
+ MY_WIN32_FIND_STREAM_DATA sd;
+ if (!g_FindNextStreamW(_handle, &sd))
return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si);
}
return true;
}
+
+bool CStreamEnumerator::Next(CStreamInfo &si, bool &found)
+{
+ bool res;
+ if (_find.IsHandleAllocated())
+ res = _find.FindNext(si);
+ else
+ res = _find.FindFirst(_filePath, si);
+ if (res)
+ {
+ found = true;
+ return true;
+ }
+ found = false;
+ return (::GetLastError() == ERROR_HANDLE_EOF);
+}
+
#endif
+
#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0;
-void CFileInfoBase::Clear()
+void CFileInfoBase::Clear() throw()
{
Size = 0;
MY_CLEAR_FILETIME(CTime);
MY_CLEAR_FILETIME(ATime);
MY_CLEAR_FILETIME(MTime);
Attrib = 0;
+ IsAltStream = false;
+ IsDevice = false;
}
-
-bool CFileInfo::Find(LPCTSTR wildcard)
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+static int FindAltStreamColon(CFSTR path)
{
- #ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceName(wildcard))
+ for (int i = 0;; i++)
{
- Clear();
- IsDevice = true;
- NIO::CInFile inFile;
- if (!inFile.Open(wildcard))
- return false;
- Name = wildcard + 4;
- if (inFile.LengthDefined)
- Size = inFile.Length;
- return true;
+ FChar c = path[i];
+ if (c == 0)
+ return -1;
+ if (c == ':')
+ {
+ if (path[i + 1] == '\\')
+ if (i == 1 || (i > 1 && path[i - 2] == '\\'))
+ {
+ wchar_t c0 = path[i - 1];
+ if (c0 >= 'a' && c0 <= 'z' ||
+ c0 >= 'A' && c0 <= 'Z')
+ continue;
+ }
+ return i;
+ }
}
- #endif
- CFindFile finder;
- return finder.FindFirst(wildcard, *this);
}
+#endif
-#ifndef _UNICODE
-bool CFileInfoW::Find(LPCWSTR wildcard)
+bool CFileInfo::Find(CFSTR path)
{
#ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceName(wildcard))
+ if (IsDevicePath(path))
{
Clear();
+ Name = path + 4;
+
IsDevice = true;
+ if (/* path[0] == '\\' && path[1] == '\\' && path[2] == '.' && path[3] == '\\' && */
+ path[5] == ':' && path[6] == 0)
+ {
+ FChar drive[4] = { path[4], ':', '\\', 0 };
+ UInt64 clusterSize, totalSize, freeSize;
+ if (NSystem::MyGetDiskFreeSpace(drive, clusterSize, totalSize, freeSize))
+ {
+ Size = totalSize;
+ return true;
+ }
+ }
+
NIO::CInFile inFile;
- if (!inFile.Open(wildcard))
+ // ::OutputDebugStringW(path);
+ if (!inFile.Open(path))
return false;
- Name = wildcard + 4;
- if (inFile.LengthDefined)
- Size = inFile.Length;
+ // ::OutputDebugStringW(L"---");
+ if (inFile.SizeDefined)
+ Size = inFile.Size;
return true;
}
#endif
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+
+ int colonPos = FindAltStreamColon(path);
+ if (colonPos >= 0)
+ {
+ UString streamName = fs2us(path + (unsigned)colonPos);
+ FString filePath = path;
+ filePath.DeleteFrom(colonPos);
+ streamName += L":$DATA"; // change it!!!!
+ if (Find(filePath))
+ {
+ // if (IsDir())
+ Attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
+ Size = 0;
+ CStreamEnumerator enumerator(filePath);
+ for (;;)
+ {
+ CStreamInfo si;
+ bool found;
+ if (!enumerator.Next(si, found))
+ return false;
+ if (!found)
+ {
+ ::SetLastError(ERROR_FILE_NOT_FOUND);
+ return false;
+ }
+ if (si.Name.IsEqualToNoCase(streamName))
+ {
+ Name += us2fs(si.Name);
+ Name.DeleteFrom(Name.Len() - 6);
+ Size = si.Size;
+ IsAltStream = true;
+ return true;
+ }
+ }
+ }
+ }
+
+ #endif
+
CFindFile finder;
- return finder.FindFirst(wildcard, *this);
+ if (finder.FindFirst(path, *this))
+ return true;
+ #ifdef _WIN32
+ {
+ DWORD lastError = GetLastError();
+ if (lastError == ERROR_BAD_NETPATH ||
+ lastError == ERROR_FILE_NOT_FOUND ||
+ lastError == ERROR_INVALID_NAME // for "\\SERVER\shared" paths that are translated to "\\?\UNC\SERVER\shared"
+ )
+ {
+ unsigned len = MyStringLen(path);
+ if (len > 2 && path[0] == '\\' && path[1] == '\\')
+ {
+ int startPos = 2;
+ if (len > kSuperUncPathPrefixSize && IsSuperUncPath(path))
+ startPos = kSuperUncPathPrefixSize;
+ int pos = FindCharPosInString(path + startPos, FTEXT('\\'));
+ if (pos >= 0)
+ {
+ pos += startPos + 1;
+ len -= pos;
+ int pos2 = FindCharPosInString(path + pos, FTEXT('\\'));
+ if (pos2 < 0 || pos2 == (int)len - 1)
+ {
+ FString s = path;
+ 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);
+ }
+ }
+ }
+ }
+ }
+ #endif
+ return false;
}
-#endif
-bool DoesFileExist(LPCTSTR name)
+bool DoesFileExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name) && !fi.IsDir();
}
-bool DoesDirExist(LPCTSTR name)
+bool DoesDirExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name) && fi.IsDir();
}
-
-bool DoesFileOrDirExist(LPCTSTR name)
+bool DoesFileOrDirExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name);
}
-#ifndef _UNICODE
-bool DoesFileExist(LPCWSTR name)
-{
- CFileInfoW fi;
- return fi.Find(name) && !fi.IsDir();
-}
-
-bool DoesDirExist(LPCWSTR name)
-{
- CFileInfoW fi;
- return fi.Find(name) && fi.IsDir();
-}
-bool DoesFileOrDirExist(LPCWSTR name)
-{
- CFileInfoW fi;
- return fi.Find(name);
-}
-#endif
-
-/////////////////////////////////////
-// CEnumerator
-
bool CEnumerator::NextAny(CFileInfo &fi)
{
if (_findFile.IsHandleAllocated())
@@ -311,44 +482,11 @@ bool CEnumerator::Next(CFileInfo &fi, bool &found)
return (::GetLastError() == ERROR_NO_MORE_FILES);
}
-#ifndef _UNICODE
-bool CEnumeratorW::NextAny(CFileInfoW &fi)
-{
- if (_findFile.IsHandleAllocated())
- return _findFile.FindNext(fi);
- else
- return _findFile.FindFirst(_wildcard, fi);
-}
-
-bool CEnumeratorW::Next(CFileInfoW &fi)
-{
- for (;;)
- {
- if (!NextAny(fi))
- return false;
- if (!fi.IsDots())
- return true;
- }
-}
-
-bool CEnumeratorW::Next(CFileInfoW &fi, bool &found)
-{
- if (Next(fi))
- {
- found = true;
- return true;
- }
- found = false;
- return (::GetLastError() == ERROR_NO_MORE_FILES);
-}
-
-#endif
-
////////////////////////////////
// CFindChangeNotification
// FindFirstChangeNotification can return 0. MSDN doesn't tell about it.
-bool CFindChangeNotification::Close()
+bool CFindChangeNotification::Close() throw()
{
if (!IsHandleAllocated())
return true;
@@ -357,105 +495,84 @@ bool CFindChangeNotification::Close()
_handle = INVALID_HANDLE_VALUE;
return true;
}
-
-HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter)
-{
- _handle = ::FindFirstChangeNotification(pathName, BoolToBOOL(watchSubtree), notifyFilter);
- #ifdef WIN_LONG_PATH2
- if (!IsHandleAllocated())
- {
- UString longPath;
- if (GetLongPath(pathName, longPath))
- _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
- }
- #endif
- return _handle;
-}
-#ifndef _UNICODE
-HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter)
+HANDLE CFindChangeNotification::FindFirst(CFSTR path, bool watchSubtree, DWORD notifyFilter)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
- _handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter);
- #ifdef WIN_LONG_PATH
- if (!IsHandleAllocated())
+ _handle = ::FindFirstChangeNotification(fs2fas(path), BoolToBOOL(watchSubtree), notifyFilter);
+ else
+ #endif
{
- UString longPath;
- if (GetLongPath(pathName, longPath))
- _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ IF_USE_MAIN_PATH
+ _handle = ::FindFirstChangeNotificationW(fs2us(path), BoolToBOOL(watchSubtree), notifyFilter);
+ #ifdef WIN_LONG_PATH
+ if (!IsHandleAllocated())
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ }
+ #endif
}
- #endif
return _handle;
}
-#endif
#ifndef UNDER_CE
-bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings)
+
+bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings)
{
driveStrings.Clear();
- UINT32 size = GetLogicalDriveStrings(0, NULL);
- if (size == 0)
- return false;
- CSysString buffer;
- UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size));
- if (newSize == 0)
- return false;
- if (newSize > size)
- return false;
- CSysString string;
- for (UINT32 i = 0; i < newSize; i++)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- TCHAR c = buffer[i];
- if (c == TEXT('\0'))
+ 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++)
{
- driveStrings.Add(string);
- string.Empty();
+ char c = buf[i];
+ if (c == '\0')
+ {
+ driveStrings.Add(fas2fs(s));
+ s.Empty();
+ }
+ else
+ s += c;
}
- else
- string += c;
+ return s.IsEmpty();
}
- if (!string.IsEmpty())
- return false;
- return true;
-}
-
-#ifndef _UNICODE
-bool MyGetLogicalDriveStrings(UStringVector &driveStrings)
-{
- driveStrings.Clear();
- if (g_IsNT)
+ else
+ #endif
{
UINT32 size = GetLogicalDriveStringsW(0, NULL);
if (size == 0)
return false;
- UString buffer;
- UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size));
- if (newSize == 0)
- return false;
- if (newSize > size)
+ UString buf;
+ UINT32 newSize = GetLogicalDriveStringsW(size, buf.GetBuffer(size));
+ if (newSize == 0 || newSize > size)
return false;
- UString string;
+ UString s;
for (UINT32 i = 0; i < newSize; i++)
{
- WCHAR c = buffer[i];
+ WCHAR c = buf[i];
if (c == L'\0')
{
- driveStrings.Add(string);
- string.Empty();
+ driveStrings.Add(us2fs(s));
+ s.Empty();
}
else
- string += c;
+ s += c;
}
- return string.IsEmpty();
+ return s.IsEmpty();
}
- CSysStringVector driveStringsA;
- bool res = MyGetLogicalDriveStrings(driveStringsA);
- for (int i = 0; i < driveStringsA.Size(); i++)
- driveStrings.Add(GetUnicodeString(driveStringsA[i]));
- return res;
}
-#endif
#endif
diff --git a/src/libs/7zip/win/CPP/Windows/FileFind.h b/src/libs/7zip/win/CPP/Windows/FileFind.h
index 63631f66b..aaa7499bd 100644
--- a/src/libs/7zip/win/CPP/Windows/FileFind.h
+++ b/src/libs/7zip/win/CPP/Windows/FileFind.h
@@ -1,12 +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 "../Common/Types.h"
#include "Defs.h"
-#include "FileName.h"
namespace NWindows {
namespace NFile {
@@ -26,14 +24,13 @@ namespace NAttributes
class CFileInfoBase
{
bool MatchesMask(UINT32 mask) const { return ((Attrib & mask) != 0); }
-protected:
- void Clear();
public:
UInt64 Size;
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
DWORD Attrib;
+ bool IsAltStream;
bool IsDevice;
/*
@@ -44,6 +41,11 @@ public:
#endif
*/
+ CFileInfoBase() { Clear(); }
+ void Clear() throw();
+
+ void SetAsDir() { Attrib = FILE_ATTRIBUTE_DIRECTORY; }
+
bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
bool IsDir() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); }
@@ -60,78 +62,80 @@ public:
struct CFileInfo: public CFileInfoBase
{
- CSysString Name;
+ FString Name;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // FString ShortName;
+ #endif
+
+ bool IsDots() const throw();
+ bool Find(CFSTR wildcard);
+};
+
+class CFindFileBase
+{
+protected:
+ HANDLE _handle;
+public:
+ bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; }
+ CFindFileBase(): _handle(INVALID_HANDLE_VALUE) {}
+ ~CFindFileBase() { Close(); }
+ bool Close() throw();
+};
- bool IsDots() const;
- bool Find(LPCTSTR wildcard);
+class CFindFile: public CFindFileBase
+{
+public:
+ bool FindFirst(CFSTR wildcard, CFileInfo &fileInfo);
+ bool FindNext(CFileInfo &fileInfo);
};
-#ifdef _UNICODE
-typedef CFileInfo CFileInfoW;
-#else
-struct CFileInfoW: public CFileInfoBase
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+struct CStreamInfo
{
UString Name;
+ UInt64 Size;
- bool IsDots() const;
- bool Find(LPCWSTR wildcard);
+ UString GetReducedName() const;
+ bool IsMainStream() const throw();
};
-#endif
-class CFindFile
+class CFindStream: public CFindFileBase
{
- friend class CEnumerator;
- HANDLE _handle;
public:
- bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; }
- CFindFile(): _handle(INVALID_HANDLE_VALUE) {}
- ~CFindFile() { Close(); }
- bool FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo);
- bool FindNext(CFileInfo &fileInfo);
- #ifndef _UNICODE
- bool FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo);
- bool FindNext(CFileInfoW &fileInfo);
- #endif
- bool Close();
+ bool FindFirst(CFSTR filePath, CStreamInfo &streamInfo);
+ bool FindNext(CStreamInfo &streamInfo);
+};
+
+class CStreamEnumerator
+{
+ CFindStream _find;
+ FString _filePath;
+
+ bool NextAny(CFileInfo &fileInfo);
+public:
+ CStreamEnumerator(const FString &filePath): _filePath(filePath) {}
+ bool Next(CStreamInfo &streamInfo, bool &found);
};
-bool DoesFileExist(LPCTSTR name);
-bool DoesDirExist(LPCTSTR name);
-bool DoesFileOrDirExist(LPCTSTR name);
-#ifndef _UNICODE
-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;
- CSysString _wildcard;
+ FString _wildcard;
+
bool NextAny(CFileInfo &fileInfo);
public:
- CEnumerator(): _wildcard(NName::kAnyStringWildcard) {}
- CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {}
+ CEnumerator(const FString &wildcard): _wildcard(wildcard) {}
bool Next(CFileInfo &fileInfo);
bool Next(CFileInfo &fileInfo, bool &found);
};
-#ifdef _UNICODE
-typedef CEnumerator CEnumeratorW;
-#else
-class CEnumeratorW
-{
- CFindFile _findFile;
- UString _wildcard;
- bool NextAny(CFileInfoW &fileInfo);
-public:
- CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {}
- CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {}
- bool Next(CFileInfoW &fileInfo);
- bool Next(CFileInfoW &fileInfo, bool &found);
-};
-#endif
-
class CFindChangeNotification
{
HANDLE _handle;
@@ -140,22 +144,15 @@ public:
bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE && _handle != 0; }
CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {}
~CFindChangeNotification() { Close(); }
- bool Close();
- HANDLE FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter);
- #ifndef _UNICODE
- HANDLE FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter);
- #endif
+ bool Close() throw();
+ HANDLE FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter);
bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); }
};
#ifndef UNDER_CE
-bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings);
-#ifndef _UNICODE
-bool MyGetLogicalDriveStrings(UStringVector &driveStrings);
-#endif
+bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings);
#endif
}}}
#endif
-
diff --git a/src/libs/7zip/win/CPP/Windows/FileIO.cpp b/src/libs/7zip/win/CPP/Windows/FileIO.cpp
index 938e6c701..fec859ed3 100644
--- a/src/libs/7zip/win/CPP/Windows/FileIO.cpp
+++ b/src/libs/7zip/win/CPP/Windows/FileIO.cpp
@@ -2,161 +2,86 @@
#include "StdAfx.h"
-#include "FileIO.h"
-
-#if defined(WIN_LONG_PATH) || defined(SUPPORT_DEVICE_FILE)
-#include "../Common/MyString.h"
-#endif
-#ifndef _UNICODE
-#include "../Common/StringConvert.h"
+#ifdef SUPPORT_DEVICE_FILE
+#include "../../C/Alloc.h"
#endif
+#include "FileIO.h"
+#include "FileName.h"
+
#ifndef _UNICODE
extern bool g_IsNT;
#endif
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
namespace NWindows {
namespace NFile {
#ifdef SUPPORT_DEVICE_FILE
-bool IsDeviceName(LPCTSTR n)
-{
- #ifdef UNDER_CE
- int len = (int)MyStringLen(n);
- if (len < 5 || len > 5 || memcmp(n, TEXT("DSK"), 3 * sizeof(TCHAR)) != 0)
- return false;
- if (n[4] != ':')
- return false;
- // for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ));
- #else
- if (n[0] != '\\' || n[1] != '\\' || n[2] != '.' || n[3] != '\\')
- return false;
- int len = (int)MyStringLen(n);
- if (len == 6 && n[5] == ':')
- return true;
- if (len < 18 || len > 22 || memcmp(n + 4, TEXT("PhysicalDrive"), 13 * sizeof(TCHAR)) != 0)
- return false;
- for (int i = 17; i < len; i++)
- if (n[i] < '0' || n[i] > '9')
- return false;
- #endif
- return true;
-}
-#ifndef _UNICODE
-bool IsDeviceName(LPCWSTR n)
+namespace NSystem
{
- if (n[0] != '\\' || n[1] != '\\' || n[2] != '.' || n[3] != '\\')
- return false;
- int len = (int)wcslen(n);
- if (len == 6 && n[5] == ':')
- return true;
- if (len < 18 || len > 22 || wcsncmp(n + 4, L"PhysicalDrive", 13) != 0)
- return false;
- for (int i = 17; i < len; i++)
- if (n[i] < '0' || n[i] > '9')
- return false;
- return true;
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
}
#endif
-#endif
-#if defined(WIN_LONG_PATH) && defined(_UNICODE)
-#define WIN_LONG_PATH2
-#endif
-
-#ifdef WIN_LONG_PATH
-bool GetLongPathBase(LPCWSTR s, UString &res)
-{
- res.Empty();
- int len = MyStringLen(s);
- wchar_t c = s[0];
- if (len < 1 || c == L'\\' || c == L'.' && (len == 1 || len == 2 && s[1] == L'.'))
- return true;
- UString curDir;
- bool isAbs = false;
- if (len > 3)
- isAbs = (s[1] == L':' && s[2] == L'\\' && (c >= L'a' && c <= L'z' || c >= L'A' && c <= L'Z'));
+namespace NIO {
- if (!isAbs)
- {
- DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, curDir.GetBuffer(MAX_PATH + 1));
- curDir.ReleaseBuffer();
- if (needLength == 0 || needLength > MAX_PATH)
- return false;
- if (curDir[curDir.Length() - 1] != L'\\')
- curDir += L'\\';
- }
- res = UString(L"\\\\?\\") + curDir + s;
- return true;
-}
+/*
+WinXP-64 CreateFile():
+ "" - ERROR_PATH_NOT_FOUND
+ :stream - OK
+ .:stream - ERROR_PATH_NOT_FOUND
+ .\:stream - OK
-bool GetLongPath(LPCWSTR path, UString &longPath)
-{
- if (GetLongPathBase(path, longPath))
- return !longPath.IsEmpty();
- return false;
-}
-#endif
+ folder\:stream - ERROR_INVALID_NAME
+ folder:stream - OK
-namespace NIO {
+ c:\:stream - OK
-CFileBase::~CFileBase() { Close(); }
+ c::stream - ERROR_INVALID_NAME, if current dir is NOT ROOT ( c:\dir1 )
+ c::stream - OK, if current dir is ROOT ( c:\ )
+*/
-bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess,
+bool CFileBase::Create(CFSTR path, DWORD desiredAccess,
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
{
if (!Close())
return false;
- _handle = ::CreateFile(fileName, desiredAccess, shareMode,
- (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
- flagsAndAttributes, (HANDLE)NULL);
- #ifdef WIN_LONG_PATH2
- if (_handle == INVALID_HANDLE_VALUE)
- {
- UString longPath;
- if (GetLongPath(fileName, longPath))
- _handle = ::CreateFileW(longPath, desiredAccess, shareMode,
- (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
- flagsAndAttributes, (HANDLE)NULL);
- }
- #endif
+
#ifdef SUPPORT_DEVICE_FILE
IsDeviceFile = false;
#endif
- return (_handle != INVALID_HANDLE_VALUE);
-}
-#ifndef _UNICODE
-bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess,
- DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
-{
+ #ifndef _UNICODE
if (!g_IsNT)
- return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP),
- desiredAccess, shareMode, creationDisposition, flagsAndAttributes);
- if (!Close())
- return false;
- _handle = ::CreateFileW(fileName, desiredAccess, shareMode,
- (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
- flagsAndAttributes, (HANDLE)NULL);
- #ifdef WIN_LONG_PATH
- if (_handle == INVALID_HANDLE_VALUE)
{
- UString longPath;
- if (GetLongPath(fileName, longPath))
- _handle = ::CreateFileW(longPath, desiredAccess, shareMode,
- (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
- flagsAndAttributes, (HANDLE)NULL);
+ _handle = ::CreateFile(fs2fas(path), desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
}
+ else
#endif
- #ifdef SUPPORT_DEVICE_FILE
- IsDeviceFile = false;
- #endif
+ {
+ IF_USE_MAIN_PATH
+ _handle = ::CreateFileW(fs2us(path), desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
+ #ifdef WIN_LONG_PATH
+ if (_handle == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
+ {
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ _handle = ::CreateFileW(superPath, desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
+ }
+ #endif
+ }
return (_handle != INVALID_HANDLE_VALUE);
}
-#endif
-bool CFileBase::Close()
+bool CFileBase::Close() throw()
{
if (_handle == INVALID_HANDLE_VALUE)
return true;
@@ -166,17 +91,17 @@ bool CFileBase::Close()
return true;
}
-bool CFileBase::GetPosition(UInt64 &position) const
+bool CFileBase::GetPosition(UInt64 &position) const throw()
{
return Seek(0, FILE_CURRENT, position);
}
-bool CFileBase::GetLength(UInt64 &length) const
+bool CFileBase::GetLength(UInt64 &length) const throw()
{
#ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceFile && LengthDefined)
+ if (IsDeviceFile && SizeDefined)
{
- length = Length;
+ length = Size;
return true;
}
#endif
@@ -190,127 +115,211 @@ bool CFileBase::GetLength(UInt64 &length) const
return true;
}
-bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const
+bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const throw()
{
#ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceFile && LengthDefined && moveMethod == FILE_END)
+ if (IsDeviceFile && SizeDefined && moveMethod == FILE_END)
{
- distanceToMove += Length;
+ distanceToMove += Size;
moveMethod = FILE_BEGIN;
}
#endif
- LARGE_INTEGER value;
- value.QuadPart = distanceToMove;
- value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod);
- if (value.LowPart == 0xFFFFFFFF)
+ LONG high = (LONG)(distanceToMove >> 32);
+ DWORD low = ::SetFilePointer(_handle, (LONG)(distanceToMove & 0xFFFFFFFF), &high, moveMethod);
+ if (low == 0xFFFFFFFF)
if (::GetLastError() != NO_ERROR)
return false;
- newPosition = value.QuadPart;
+ newPosition = (((UInt64)high) << 32) + low;
return true;
}
-bool CFileBase::Seek(UInt64 position, UInt64 &newPosition)
+bool CFileBase::Seek(UInt64 position, UInt64 &newPosition) const throw()
{
return Seek(position, FILE_BEGIN, newPosition);
}
-bool CFileBase::SeekToBegin()
+bool CFileBase::SeekToBegin() const throw()
{
UInt64 newPosition;
return Seek(0, newPosition);
}
-bool CFileBase::SeekToEnd(UInt64 &newPosition)
+bool CFileBase::SeekToEnd(UInt64 &newPosition) const throw()
{
return Seek(0, FILE_END, newPosition);
}
-bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const
+// ---------- CInFile ---------
+
+#ifdef SUPPORT_DEVICE_FILE
+
+void CInFile::CorrectDeviceSize()
{
- BY_HANDLE_FILE_INFORMATION winFileInfo;
- if (!::GetFileInformationByHandle(_handle, &winFileInfo))
- return false;
- fileInfo.Attrib = winFileInfo.dwFileAttributes;
- fileInfo.CTime = winFileInfo.ftCreationTime;
- fileInfo.ATime = winFileInfo.ftLastAccessTime;
- fileInfo.MTime = winFileInfo.ftLastWriteTime;
- fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes;
- fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) + winFileInfo.nFileSizeLow;
- fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks;
- fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow;
- return true;
+ // maybe we must decrease kClusterSize to 1 << 12, if we want correct size at tail
+ static const UInt32 kClusterSize = 1 << 14;
+ UInt64 pos = Size & ~(UInt64)(kClusterSize - 1);
+ UInt64 realNewPosition;
+ if (!Seek(pos, realNewPosition))
+ return;
+ Byte *buf = (Byte *)MidAlloc(kClusterSize);
+
+ bool needbackward = true;
+
+ for (;;)
+ {
+ UInt32 processed = 0;
+ // up test is slow for "PhysicalDrive".
+ // processed size for latest block for "PhysicalDrive0" is 0.
+ if (!Read1(buf, kClusterSize, processed))
+ break;
+ if (processed == 0)
+ break;
+ needbackward = false;
+ Size = pos + processed;
+ if (processed != kClusterSize)
+ break;
+ pos += kClusterSize;
+ }
+
+ if (needbackward && pos != 0)
+ {
+ pos -= kClusterSize;
+ for (;;)
+ {
+ // break;
+ if (!Seek(pos, realNewPosition))
+ break;
+ if (!buf)
+ {
+ buf = (Byte *)MidAlloc(kClusterSize);
+ if (!buf)
+ break;
+ }
+ UInt32 processed = 0;
+ // that code doesn't work for "PhysicalDrive0"
+ if (!Read1(buf, kClusterSize, processed))
+ break;
+ if (processed != 0)
+ {
+ Size = pos + processed;
+ break;
+ }
+ if (pos == 0)
+ break;
+ pos -= kClusterSize;
+ }
+ }
+ MidFree(buf);
}
-/////////////////////////
-// CInFile
-#ifdef SUPPORT_DEVICE_FILE
-void CInFile::GetDeviceLength()
+void CInFile::CalcDeviceSize(CFSTR s)
{
- if (_handle != INVALID_HANDLE_VALUE && IsDeviceFile)
- {
- #ifdef UNDER_CE
- LengthDefined = true;
- Length = 128 << 20;
+ SizeDefined = false;
+ Size = 0;
+ if (_handle == INVALID_HANDLE_VALUE || !IsDeviceFile)
+ return;
+ #ifdef UNDER_CE
+
+ SizeDefined = true;
+ Size = 128 << 20;
+
+ #else
+
+ PARTITION_INFORMATION partInfo;
+ bool needCorrectSize = true;
- #else
- PARTITION_INFORMATION partInfo;
- LengthDefined = true;
- Length = 0;
+ /*
+ WinXP 64-bit:
+
+ HDD \\.\PhysicalDrive0 (MBR):
+ GetPartitionInfo == GeometryEx : corrrect size? (includes tail)
+ Geometry : smaller than GeometryEx (no tail, maybe correct too?)
+ MyGetDiskFreeSpace : FAIL
+ Size correction is slow and block size (kClusterSize) must be small?
+
+ HDD partition \\.\N: (NTFS):
+ MyGetDiskFreeSpace : Size of NTFS clusters. Same size can be calculated after correction
+ GetPartitionInfo : size of partition data: NTFS clusters + TAIL; TAIL contains extra empty sectors and copy of first sector of NTFS
+ Geometry / CdRomGeometry / GeometryEx : size of HDD (not that partition)
+
+ CD-ROM drive (ISO):
+ MyGetDiskFreeSpace : correct size. Same size can be calculated after correction
+ Geometry == CdRomGeometry : smaller than corrrect size
+ GetPartitionInfo == GeometryEx : larger than corrrect size
+
+ Floppy \\.\a: (FAT):
+ Geometry : correct size.
+ CdRomGeometry / GeometryEx / GetPartitionInfo / MyGetDiskFreeSpace - FAIL
+ correction works OK for FAT.
+ correction works OK for non-FAT, if kClusterSize = 512.
+ */
+
+ if (GetPartitionInfo(&partInfo))
+ {
+ Size = partInfo.PartitionLength.QuadPart;
+ SizeDefined = true;
+ needCorrectSize = false;
+ if ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '.' && (s)[3] == '\\' && (s)[5] == ':' && (s)[6] == 0)
+ {
+ FChar path[4] = { s[4], ':', '\\', 0 };
+ UInt64 clusterSize, totalSize, freeSize;
+ if (NSystem::MyGetDiskFreeSpace(path, clusterSize, totalSize, freeSize))
+ Size = totalSize;
+ else
+ needCorrectSize = true;
+ }
+ }
- if (GetPartitionInfo(&partInfo))
- Length = partInfo.PartitionLength.QuadPart;
+ if (!SizeDefined)
+ {
+ my_DISK_GEOMETRY_EX geomEx;
+ SizeDefined = GetGeometryEx(&geomEx);
+ if (SizeDefined)
+ Size = geomEx.DiskSize.QuadPart;
else
{
DISK_GEOMETRY geom;
- if (!GetGeometry(&geom))
- if (!GetCdRomGeometry(&geom))
- LengthDefined = false;
- if (LengthDefined)
- Length = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector;
+ SizeDefined = GetGeometry(&geom);
+ if (!SizeDefined)
+ SizeDefined = GetCdRomGeometry(&geom);
+ if (SizeDefined)
+ Size = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector;
}
- // SeekToBegin();
- #endif
}
+
+ if (needCorrectSize && SizeDefined && Size != 0)
+ {
+ CorrectDeviceSize();
+ SeekToBegin();
+ }
+
+ // SeekToBegin();
+ #endif
}
// ((desiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA | GENERIC_WRITE)) == 0 &&
#define MY_DEVICE_EXTRA_CODE \
- IsDeviceFile = IsDeviceName(fileName); \
- GetDeviceLength();
+ IsDeviceFile = IsDevicePath(fileName); \
+ CalcDeviceSize(fileName);
#else
#define MY_DEVICE_EXTRA_CODE
#endif
-bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
-{
- bool res = Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes);
- MY_DEVICE_EXTRA_CODE
- return res;
-}
-
-bool CInFile::OpenShared(LPCTSTR fileName, bool shareForWrite)
-{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
-
-bool CInFile::Open(LPCTSTR fileName)
- { return OpenShared(fileName, false); }
-
-#ifndef _UNICODE
-bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+bool CInFile::Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
{
bool res = Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes);
MY_DEVICE_EXTRA_CODE
return res;
}
-bool CInFile::OpenShared(LPCWSTR fileName, bool shareForWrite)
+bool CInFile::OpenShared(CFSTR fileName, bool shareForWrite)
{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
-bool CInFile::Open(LPCWSTR fileName)
+bool CInFile::Open(CFSTR fileName)
{ return OpenShared(fileName, false); }
-#endif
// ReadFile and WriteFile functions in Windows have BUG:
// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
@@ -323,7 +332,7 @@ bool CInFile::Open(LPCWSTR fileName)
static UInt32 kChunkSizeMax = (1 << 22);
-bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize)
+bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize) throw()
{
DWORD processedLoc = 0;
bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
@@ -331,14 +340,14 @@ bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize)
return res;
}
-bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize)
+bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw()
{
if (size > kChunkSizeMax)
size = kChunkSizeMax;
return Read1(data, size, processedSize);
}
-bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
+bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize) throw()
{
processedSize = 0;
do
@@ -357,40 +366,29 @@ bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
return true;
}
-/////////////////////////
-// COutFile
-
-bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
- { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
+// ---------- COutFile ---------
static inline DWORD GetCreationDisposition(bool createAlways)
{ return createAlways? CREATE_ALWAYS: CREATE_NEW; }
-bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition)
- { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
-
-bool COutFile::Create(LPCTSTR fileName, bool createAlways)
- { return Open(fileName, GetCreationDisposition(createAlways)); }
-
-#ifndef _UNICODE
-
-bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+bool COutFile::Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
{ return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
-bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition)
+bool COutFile::Open(CFSTR fileName, DWORD creationDisposition)
{ return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
-bool COutFile::Create(LPCWSTR fileName, bool createAlways)
+bool COutFile::Create(CFSTR fileName, bool createAlways)
{ return Open(fileName, GetCreationDisposition(createAlways)); }
-#endif
+bool COutFile::CreateAlways(CFSTR fileName, DWORD flagsAndAttributes)
+ { return Open(fileName, FILE_SHARE_READ, GetCreationDisposition(true), flagsAndAttributes); }
-bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
+bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw()
{ return BOOLToBool(::SetFileTime(_handle, cTime, aTime, mTime)); }
-bool COutFile::SetMTime(const FILETIME *mTime) { return SetTime(NULL, NULL, mTime); }
+bool COutFile::SetMTime(const FILETIME *mTime) throw() { return SetTime(NULL, NULL, mTime); }
-bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
+bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw()
{
if (size > kChunkSizeMax)
size = kChunkSizeMax;
@@ -400,7 +398,7 @@ bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
return res;
}
-bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
+bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize) throw()
{
processedSize = 0;
do
@@ -419,9 +417,9 @@ bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
return true;
}
-bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); }
+bool COutFile::SetEndOfFile() throw() { return BOOLToBool(::SetEndOfFile(_handle)); }
-bool COutFile::SetLength(UInt64 length)
+bool COutFile::SetLength(UInt64 length) throw()
{
UInt64 newPosition;
if (!Seek(length, newPosition))
diff --git a/src/libs/7zip/win/CPP/Windows/FileIO.h b/src/libs/7zip/win/CPP/Windows/FileIO.h
index dce692fed..f595121ef 100644
--- a/src/libs/7zip/win/CPP/Windows/FileIO.h
+++ b/src/libs/7zip/win/CPP/Windows/FileIO.h
@@ -1,134 +1,199 @@
// Windows/FileIO.h
-#ifndef __WINDOWS_FILEIO_H
-#define __WINDOWS_FILEIO_H
+#ifndef __WINDOWS_FILE_IO_H
+#define __WINDOWS_FILE_IO_H
-#include "../Common/Types.h"
+#if defined(_WIN32) && !defined(UNDER_CE)
+#include <winioctl.h>
+#endif
+
+#include "../Common/MyString.h"
+#include "../Common/MyBuffer.h"
#include "Defs.h"
+#define _my_IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
+#define _my_IO_REPARSE_TAG_SYMLINK (0xA000000CL)
+
+#define _my_SYMLINK_FLAG_RELATIVE 1
+
+#define my_FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // REPARSE_DATA_BUFFER
+#define my_FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) // REPARSE_DATA_BUFFER
+
namespace NWindows {
namespace NFile {
-namespace NIO {
-struct CByHandleFileInfo
+#if defined(_WIN32) && !defined(UNDER_CE)
+bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink);
+#endif
+
+struct CReparseShortInfo
+{
+ unsigned Offset;
+ unsigned Size;
+
+ bool Parse(const Byte *p, size_t size);
+};
+
+struct CReparseAttr
{
- DWORD Attrib;
- FILETIME CTime;
- FILETIME ATime;
- FILETIME MTime;
- DWORD VolumeSerialNumber;
- UInt64 Size;
- DWORD NumberOfLinks;
- UInt64 FileIndex;
+ UInt32 Tag;
+ UInt32 Flags;
+ UString SubsName;
+ UString PrintName;
+
+ CReparseAttr(): Tag(0), Flags(0) {}
+ bool Parse(const Byte *p, size_t size);
+
+ bool IsMountPoint() const { return Tag == _my_IO_REPARSE_TAG_MOUNT_POINT; } // it's Junction
+ bool IsSymLink() const { return Tag == _my_IO_REPARSE_TAG_SYMLINK; }
+ bool IsRelative() const { return Flags == _my_SYMLINK_FLAG_RELATIVE; }
+ // bool IsVolume() const;
+
+ bool IsOkNamePair() const;
+ UString GetPath() const;
};
+namespace NIO {
+
+bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo = NULL);
+bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size);
+
class CFileBase
{
protected:
HANDLE _handle;
-
- bool Create(LPCTSTR fileName, DWORD desiredAccess,
- DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- #ifndef _UNICODE
- bool Create(LPCWSTR fileName, DWORD desiredAccess,
+
+ bool Create(CFSTR path, DWORD desiredAccess,
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- #endif
+
+public:
+
+ bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inSize,
+ LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned, LPOVERLAPPED overlapped = NULL) const
+ {
+ return BOOLToBool(::DeviceIoControl(_handle, controlCode, inBuffer, inSize,
+ outBuffer, outSize, bytesReturned, overlapped));
+ }
+
+ bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned) const
+ {
+ return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize, bytesReturned);
+ }
+
+ bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize) const
+ {
+ DWORD bytesReturned;
+ return DeviceIoControlOut(controlCode, outBuffer, outSize, &bytesReturned);
+ }
public:
#ifdef SUPPORT_DEVICE_FILE
bool IsDeviceFile;
- bool LengthDefined;
- UInt64 Length;
+ bool SizeDefined;
+ UInt64 Size; // it can be larger than real available size
#endif
CFileBase(): _handle(INVALID_HANDLE_VALUE) {};
- ~CFileBase();
+ ~CFileBase() { Close(); }
+
+ bool Close() throw();
+
+ bool GetPosition(UInt64 &position) const throw();
+ bool GetLength(UInt64 &length) const throw();
- bool Close();
+ bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const throw();
+ bool Seek(UInt64 position, UInt64 &newPosition) const throw();
+ bool SeekToBegin() const throw();
+ bool SeekToEnd(UInt64 &newPosition) const throw();
- bool GetPosition(UInt64 &position) const;
- bool GetLength(UInt64 &length) const;
+ bool GetFileInformation(BY_HANDLE_FILE_INFORMATION *info) const
+ { return BOOLToBool(GetFileInformationByHandle(_handle, info)); }
- bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const;
- bool Seek(UInt64 position, UInt64 &newPosition);
- bool SeekToBegin();
- bool SeekToEnd(UInt64 &newPosition);
-
- bool GetFileInformation(CByHandleFileInfo &fileInfo) const;
+ static bool GetFileInformation(CFSTR path, BY_HANDLE_FILE_INFORMATION *info)
+ {
+ NIO::CFileBase file;
+ if (!file.Create(path, 0, FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS))
+ return false;
+ return file.GetFileInformation(info);
+ }
};
+#ifndef UNDER_CE
#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS)
-#define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
+// #define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
+
+// IOCTL_DISK_GET_DRIVE_GEOMETRY_EX works since WinXP
+#define my_IOCTL_DISK_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_DISK_BASE, 0x0028, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+struct my_DISK_GEOMETRY_EX
+{
+ DISK_GEOMETRY Geometry;
+ LARGE_INTEGER DiskSize;
+ BYTE Data[1];
+};
+#endif
class CInFile: public CFileBase
{
#ifdef SUPPORT_DEVICE_FILE
- bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inSize,
- LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned, LPOVERLAPPED overlapped) const
- {
- return BOOLToBool(::DeviceIoControl(_handle, controlCode, inBuffer, inSize,
- outBuffer, outSize, bytesReturned, overlapped));
- }
-
- bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer,
- DWORD inSize, LPVOID outBuffer, DWORD outSize) const
- {
- DWORD ret;
- return DeviceIoControl(controlCode, inBuffer, inSize, outBuffer, outSize, &ret, 0);
- }
-
- bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize) const
- { return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize); }
#ifndef UNDER_CE
+
bool GetGeometry(DISK_GEOMETRY *res) const
{ return DeviceIoControlOut(IOCTL_DISK_GET_DRIVE_GEOMETRY, res, sizeof(*res)); }
+ bool GetGeometryEx(my_DISK_GEOMETRY_EX *res) const
+ { return DeviceIoControlOut(my_IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, res, sizeof(*res)); }
+
bool GetCdRomGeometry(DISK_GEOMETRY *res) const
{ return DeviceIoControlOut(IOCTL_CDROM_GET_DRIVE_GEOMETRY, res, sizeof(*res)); }
-
+
bool GetPartitionInfo(PARTITION_INFORMATION *res)
{ return DeviceIoControlOut(IOCTL_DISK_GET_PARTITION_INFO, LPVOID(res), sizeof(*res)); }
+
#endif
- void GetDeviceLength();
+ void CorrectDeviceSize();
+ void CalcDeviceSize(CFSTR name);
+
#endif
public:
- bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- bool OpenShared(LPCTSTR fileName, bool shareForWrite);
- bool Open(LPCTSTR fileName);
- #ifndef _UNICODE
- bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- bool OpenShared(LPCWSTR fileName, bool shareForWrite);
- bool Open(LPCWSTR fileName);
+ bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool OpenShared(CFSTR fileName, bool shareForWrite);
+ bool Open(CFSTR fileName);
+
+ #ifndef UNDER_CE
+
+ bool OpenReparse(CFSTR fileName)
+ {
+ return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS);
+ }
+
#endif
- bool Read1(void *data, UInt32 size, UInt32 &processedSize);
- bool ReadPart(void *data, UInt32 size, UInt32 &processedSize);
- bool Read(void *data, UInt32 size, UInt32 &processedSize);
+
+ bool Read1(void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool Read(void *data, UInt32 size, UInt32 &processedSize) throw();
};
class COutFile: public CFileBase
{
public:
- bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- bool Open(LPCTSTR fileName, DWORD creationDisposition);
- bool Create(LPCTSTR fileName, bool createAlways);
-
- #ifndef _UNICODE
- bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- bool Open(LPCWSTR fileName, DWORD creationDisposition);
- bool Create(LPCWSTR fileName, bool createAlways);
- #endif
-
- bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
- bool SetMTime(const FILETIME *mTime);
- bool WritePart(const void *data, UInt32 size, UInt32 &processedSize);
- bool Write(const void *data, UInt32 size, UInt32 &processedSize);
- bool SetEndOfFile();
- bool SetLength(UInt64 length);
+ bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(CFSTR fileName, DWORD creationDisposition);
+ bool Create(CFSTR fileName, bool createAlways);
+ bool CreateAlways(CFSTR fileName, DWORD flagsAndAttributes);
+
+ bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw();
+ bool SetMTime(const FILETIME *mTime) throw();
+ bool WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool Write(const void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool SetEndOfFile() throw();
+ bool SetLength(UInt64 length) throw();
};
}}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileLink.cpp b/src/libs/7zip/win/CPP/Windows/FileLink.cpp
new file mode 100644
index 000000000..dc524700d
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileLink.cpp
@@ -0,0 +1,426 @@
+// Windows/FileLink.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/CpuArch.h"
+
+#ifdef SUPPORT_DEVICE_FILE
+#include "../../C/Alloc.h"
+#endif
+
+#include "FileDir.h"
+#include "FileFind.h"
+#include "FileIO.h"
+#include "FileName.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+using namespace NName;
+
+/*
+ Reparse Points (Junctions and Symbolic Links):
+ struct
+ {
+ UInt32 Tag;
+ UInt16 Size; // not including starting 8 bytes
+ UInt16 Reserved; // = 0
+
+ UInt16 SubstituteOffset; // offset in bytes from start of namesChars
+ UInt16 SubstituteLen; // size in bytes, it doesn't include tailed NUL
+ UInt16 PrintOffset; // offset in bytes from start of namesChars
+ UInt16 PrintLen; // size in bytes, it doesn't include tailed NUL
+
+ [UInt32] Flags; // for Symbolic Links only.
+
+ UInt16 namesChars[]
+ }
+
+ MOUNT_POINT (Junction point):
+ 1) there is NUL wchar after path
+ 2) Default Order in table:
+ Substitute Path
+ Print Path
+ 3) pathnames can not contain dot directory names
+
+ SYMLINK:
+ 1) there is no NUL wchar after path
+ 2) Default Order in table:
+ Print Path
+ Substitute Path
+*/
+
+/*
+static const UInt32 kReparseFlags_Alias = (1 << 29);
+static const UInt32 kReparseFlags_HighLatency = (1 << 30);
+static const UInt32 kReparseFlags_Microsoft = ((UInt32)1 << 31);
+
+#define _my_IO_REPARSE_TAG_HSM (0xC0000004L)
+#define _my_IO_REPARSE_TAG_HSM2 (0x80000006L)
+#define _my_IO_REPARSE_TAG_SIS (0x80000007L)
+#define _my_IO_REPARSE_TAG_WIM (0x80000008L)
+#define _my_IO_REPARSE_TAG_CSV (0x80000009L)
+#define _my_IO_REPARSE_TAG_DFS (0x8000000AL)
+#define _my_IO_REPARSE_TAG_DFSR (0x80000012L)
+*/
+
+#define Get16(p) GetUi16(p)
+#define Get32(p) GetUi32(p)
+
+#define Set16(p, v) SetUi16(p, v)
+#define Set32(p, v) SetUi32(p, v)
+
+static const wchar_t *k_LinkPrefix = L"\\??\\";
+static const unsigned k_LinkPrefix_Size = 4;
+
+static const bool IsLinkPrefix(const wchar_t *s)
+{
+ return IsString1PrefixedByString2(s, k_LinkPrefix);
+}
+
+/*
+static const wchar_t *k_VolumePrefix = L"Volume{";
+static const bool IsVolumeName(const wchar_t *s)
+{
+ return IsString1PrefixedByString2(s, k_VolumePrefix);
+}
+*/
+
+void WriteString(Byte *dest, const wchar_t *path)
+{
+ for (;;)
+ {
+ wchar_t c = *path++;
+ if (c == 0)
+ return;
+ Set16(dest, (UInt16)c);
+ dest += 2;
+ }
+}
+
+bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink)
+{
+ bool isAbs = IsAbsolutePath(path);
+ if (!isAbs && !isSymLink)
+ return false;
+
+ bool needPrintName = true;
+
+ if (IsSuperPath(path))
+ {
+ path += kSuperPathPrefixSize;
+ if (!IsDrivePath(path))
+ needPrintName = false;
+ }
+
+ const unsigned add_Prefix_Len = isAbs ? k_LinkPrefix_Size : 0;
+
+ unsigned len2 = MyStringLen(path) * 2;
+ const unsigned len1 = len2 + add_Prefix_Len * 2;
+ if (!needPrintName)
+ len2 = 0;
+
+ unsigned totalNamesSize = (len1 + len2);
+
+ /* some WIM imagex software uses old scheme for symbolic links.
+ so we can old scheme for byte to byte compatibility */
+
+ bool newOrderScheme = isSymLink;
+ // newOrderScheme = false;
+
+ if (!newOrderScheme)
+ totalNamesSize += 2 * 2;
+
+ const size_t size = 8 + 8 + (isSymLink ? 4 : 0) + totalNamesSize;
+ dest.Alloc(size);
+ memset(dest, 0, size);
+ const UInt32 tag = isSymLink ?
+ _my_IO_REPARSE_TAG_SYMLINK :
+ _my_IO_REPARSE_TAG_MOUNT_POINT;
+ Byte *p = dest;
+ Set32(p, tag);
+ Set16(p + 4, (UInt16)(size - 8));
+ Set16(p + 6, 0);
+ p += 8;
+
+ unsigned subOffs = 0;
+ unsigned printOffs = 0;
+ if (newOrderScheme)
+ subOffs = len2;
+ else
+ printOffs = len1 + 2;
+
+ Set16(p + 0, (UInt16)subOffs);
+ Set16(p + 2, (UInt16)len1);
+ Set16(p + 4, (UInt16)printOffs);
+ Set16(p + 6, (UInt16)len2);
+
+ p += 8;
+ if (isSymLink)
+ {
+ UInt32 flags = isAbs ? 0 : _my_SYMLINK_FLAG_RELATIVE;
+ Set32(p, flags);
+ p += 4;
+ }
+
+ if (add_Prefix_Len != 0)
+ WriteString(p + subOffs, k_LinkPrefix);
+ WriteString(p + subOffs + add_Prefix_Len * 2, path);
+ if (needPrintName)
+ WriteString(p + printOffs, path);
+ return true;
+}
+
+static void GetString(const Byte *p, unsigned len, UString &res)
+{
+ wchar_t *s = res.GetBuffer(len);
+ for (unsigned i = 0; i < len; i++)
+ s[i] = Get16(p + i * 2);
+ s[len] = 0;
+ res.ReleaseBuffer();
+}
+
+bool CReparseAttr::Parse(const Byte *p, size_t size)
+{
+ if (size < 8)
+ return false;
+ Tag = Get32(p);
+ UInt32 len = Get16(p + 4);
+ if (len + 8 > size)
+ return false;
+ /*
+ if ((type & kReparseFlags_Alias) == 0 ||
+ (type & kReparseFlags_Microsoft) == 0 ||
+ (type & 0xFFFF) != 3)
+ */
+ if (Tag != _my_IO_REPARSE_TAG_MOUNT_POINT &&
+ Tag != _my_IO_REPARSE_TAG_SYMLINK)
+ // return true;
+ return false;
+
+ if (Get16(p + 6) != 0) // padding
+ return false;
+
+ p += 8;
+ size -= 8;
+
+ if (len != size) // do we need that check?
+ return false;
+
+ if (len < 8)
+ return false;
+ unsigned subOffs = Get16(p);
+ unsigned subLen = Get16(p + 2);
+ unsigned printOffs = Get16(p + 4);
+ unsigned printLen = Get16(p + 6);
+ len -= 8;
+ p += 8;
+
+ Flags = 0;
+ if (Tag == _my_IO_REPARSE_TAG_SYMLINK)
+ {
+ if (len < 4)
+ return false;
+ Flags = Get32(p);
+ len -= 4;
+ p += 4;
+ }
+
+ if ((subOffs & 1) != 0 || subOffs > len || len - subOffs < subLen)
+ return false;
+ if ((printOffs & 1) != 0 || printOffs > len || len - printOffs < printLen)
+ return false;
+ GetString(p + subOffs, subLen >> 1, SubsName);
+ GetString(p + printOffs, printLen >> 1, PrintName);
+
+ return true;
+}
+
+bool CReparseShortInfo::Parse(const Byte *p, size_t size)
+{
+ const Byte *start = p;
+ Offset= 0;
+ Size = 0;
+ if (size < 8)
+ return false;
+ UInt32 Tag = Get32(p);
+ UInt32 len = Get16(p + 4);
+ if (len + 8 > size)
+ return false;
+ /*
+ if ((type & kReparseFlags_Alias) == 0 ||
+ (type & kReparseFlags_Microsoft) == 0 ||
+ (type & 0xFFFF) != 3)
+ */
+ if (Tag != _my_IO_REPARSE_TAG_MOUNT_POINT &&
+ Tag != _my_IO_REPARSE_TAG_SYMLINK)
+ // return true;
+ return false;
+
+ if (Get16(p + 6) != 0) // padding
+ return false;
+
+ p += 8;
+ size -= 8;
+
+ if (len != size) // do we need that check?
+ return false;
+
+ if (len < 8)
+ return false;
+ unsigned subOffs = Get16(p);
+ unsigned subLen = Get16(p + 2);
+ unsigned printOffs = Get16(p + 4);
+ unsigned printLen = Get16(p + 6);
+ len -= 8;
+ p += 8;
+
+ // UInt32 Flags = 0;
+ if (Tag == _my_IO_REPARSE_TAG_SYMLINK)
+ {
+ if (len < 4)
+ return false;
+ // Flags = Get32(p);
+ len -= 4;
+ p += 4;
+ }
+
+ if ((subOffs & 1) != 0 || subOffs > len || len - subOffs < subLen)
+ return false;
+ if ((printOffs & 1) != 0 || printOffs > len || len - printOffs < printLen)
+ return false;
+
+ Offset = (unsigned)(p - start) + subOffs;
+ Size = subLen;
+ return true;
+}
+
+bool CReparseAttr::IsOkNamePair() const
+{
+ if (IsLinkPrefix(SubsName))
+ {
+ if (!IsDrivePath(SubsName.Ptr(k_LinkPrefix_Size)))
+ return PrintName.IsEmpty();
+ if (wcscmp(SubsName.Ptr(k_LinkPrefix_Size), PrintName) == 0)
+ return true;
+ }
+ return wcscmp(SubsName, PrintName) == 0;
+}
+
+/*
+bool CReparseAttr::IsVolume() const
+{
+ if (!IsLinkPrefix(SubsName))
+ return false;
+ return IsVolumeName(SubsName.Ptr(k_LinkPrefix_Size));
+}
+*/
+
+UString CReparseAttr::GetPath() const
+{
+ UString s = SubsName;
+ if (IsLinkPrefix(s))
+ {
+ s.ReplaceOneCharAtPos(1, '\\');
+ if (IsDrivePath(s.Ptr(k_LinkPrefix_Size)))
+ s.DeleteFrontal(k_LinkPrefix_Size);
+ }
+ return s;
+}
+
+
+#ifdef SUPPORT_DEVICE_FILE
+
+namespace NSystem
+{
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
+}
+#endif
+
+#ifndef UNDER_CE
+
+namespace NIO {
+
+bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo)
+{
+ reparseData.Free();
+ CInFile file;
+ if (!file.OpenReparse(path))
+ return false;
+
+ if (fileInfo)
+ file.GetFileInformation(fileInfo);
+
+ const unsigned kBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
+ CByteArr buf(kBufSize);
+ DWORD returnedSize;
+ if (!file.DeviceIoControlOut(my_FSCTL_GET_REPARSE_POINT, buf, kBufSize, &returnedSize))
+ return false;
+ reparseData.CopyFrom(buf, returnedSize);
+ return true;
+}
+
+static bool CreatePrefixDirOfFile(CFSTR path)
+{
+ FString path2 = path;
+ int pos = path2.ReverseFind(FCHAR_PATH_SEPARATOR);
+ if (pos < 0)
+ return true;
+ #ifdef _WIN32
+ if (pos == 2 && path2[1] == L':')
+ return true; // we don't create Disk folder;
+ #endif
+ path2.DeleteFrom(pos);
+ return NDir::CreateComplexDir(path2);
+}
+
+// If there is Reprase data already, it still writes new Reparse data
+bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size)
+{
+ NFile::NFind::CFileInfo fi;
+ if (fi.Find(path))
+ {
+ if (fi.IsDir() != isDir)
+ {
+ ::SetLastError(ERROR_DIRECTORY);
+ return false;
+ }
+ }
+ else
+ {
+ if (isDir)
+ {
+ if (!NDir::CreateComplexDir(path))
+ return false;
+ }
+ else
+ {
+ CreatePrefixDirOfFile(path);
+ COutFile file;
+ if (!file.Create(path, CREATE_NEW))
+ return false;
+ }
+ }
+
+ COutFile file;
+ if (!file.Open(path,
+ FILE_SHARE_WRITE,
+ OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS))
+ return false;
+
+ DWORD returnedSize;
+ if (!file.DeviceIoControl(my_FSCTL_SET_REPARSE_POINT, (void *)data, size, NULL, 0, &returnedSize))
+ return false;
+ return true;
+}
+
+}
+
+#endif
+
+}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileMapping.cpp b/src/libs/7zip/win/CPP/Windows/FileMapping.cpp
deleted file mode 100644
index 55048fdb2..000000000
--- a/src/libs/7zip/win/CPP/Windows/FileMapping.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-// Windows/FileMapping.cpp
-
-#include "StdAfx.h"
-
-#include "Windows/FileMapping.h"
-
-namespace NWindows {
-namespace NFile {
-namespace NMapping {
-
-
-}}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileMapping.h b/src/libs/7zip/win/CPP/Windows/FileMapping.h
index 3f0ebd74c..f90c429f1 100644
--- a/src/libs/7zip/win/CPP/Windows/FileMapping.h
+++ b/src/libs/7zip/win/CPP/Windows/FileMapping.h
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_FILEMAPPING_H
#define __WINDOWS_FILEMAPPING_H
-#include "Common/Types.h"
+#include "../Common/MyTypes.h"
#include "Handle.h"
@@ -18,7 +18,11 @@ public:
return ::GetLastError();
}
- WRes Open(DWORD desiredAccess, LPCTSTR name)
+ WRes Open(DWORD
+ #ifndef UNDER_CE
+ desiredAccess
+ #endif
+ , LPCTSTR name)
{
#ifdef UNDER_CE
WRes res = Create(PAGE_READONLY, 0, name);
diff --git a/src/libs/7zip/win/CPP/Windows/FileName.cpp b/src/libs/7zip/win/CPP/Windows/FileName.cpp
index 8443a4af9..0a6aee100 100644
--- a/src/libs/7zip/win/CPP/Windows/FileName.cpp
+++ b/src/libs/7zip/win/CPP/Windows/FileName.cpp
@@ -2,49 +2,686 @@
#include "StdAfx.h"
-#include "Windows/FileName.h"
-#include "Common/Wildcard.h"
+#include "FileName.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
namespace NWindows {
namespace NFile {
namespace NName {
-void NormalizeDirPathPrefix(CSysString &dirPath)
+#ifndef USE_UNICODE_FSTRING
+void NormalizeDirPathPrefix(FString &dirPath)
{
if (dirPath.IsEmpty())
return;
- if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Length() - 1)
- dirPath += kDirDelimiter;
+ if (dirPath.Back() != FCHAR_PATH_SEPARATOR)
+ dirPath += FCHAR_PATH_SEPARATOR;
}
+#endif
-#ifndef _UNICODE
void NormalizeDirPathPrefix(UString &dirPath)
{
if (dirPath.IsEmpty())
return;
- if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Length() - 1)
- dirPath += wchar_t(kDirDelimiter);
+ if (dirPath.Back() != WCHAR_PATH_SEPARATOR)
+ dirPath += WCHAR_PATH_SEPARATOR;
+}
+
+
+#ifdef _WIN32
+
+const wchar_t *kSuperPathPrefix = L"\\\\?\\";
+static const wchar_t *kSuperUncPrefix = L"\\\\?\\UNC\\";
+
+#define IS_DEVICE_PATH(s) ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '.' && (s)[3] == '\\')
+#define IS_SUPER_PREFIX(s) ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '?' && (s)[3] == '\\')
+#define IS_SUPER_OR_DEVICE_PATH(s) ((s)[0] == '\\' && (s)[1] == '\\' && ((s)[2] == '?' || (s)[2] == '.') && (s)[3] == '\\')
+#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
+
+#define IS_UNC_WITH_SLASH(s) ( \
+ ((s)[0] == 'U' || (s)[0] == 'u') && \
+ ((s)[1] == 'N' || (s)[1] == 'n') && \
+ ((s)[2] == 'C' || (s)[2] == 'c') && \
+ (s)[3] == '\\')
+
+bool IsDevicePath(CFSTR s) throw()
+{
+ #ifdef UNDER_CE
+
+ s = s;
+ return false;
+ /*
+ // actually we don't know the way to open device file in WinCE.
+ unsigned len = MyStringLen(s);
+ if (len < 5 || len > 5 || memcmp(s, FTEXT("DSK"), 3 * sizeof(FChar)) != 0)
+ return false;
+ if (s[4] != ':')
+ return false;
+ // for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ));
+ */
+
+ #else
+
+ if (!IS_DEVICE_PATH(s))
+ return false;
+ unsigned len = MyStringLen(s);
+ if (len == 6 && s[5] == ':')
+ return true;
+ if (len < 18 || len > 22 || memcmp(s + kDevicePathPrefixSize, FTEXT("PhysicalDrive"), 13 * sizeof(FChar)) != 0)
+ return false;
+ for (unsigned i = 17; i < len; i++)
+ if (s[i] < '0' || s[i] > '9')
+ return false;
+ return true;
+
+ #endif
+}
+
+bool IsSuperUncPath(CFSTR s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
+
+bool IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; }
+bool IsSuperPath(const wchar_t *s) throw() { return IS_SUPER_PREFIX(s); }
+bool IsSuperOrDevicePath(const wchar_t *s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); }
+// bool IsSuperUncPath(const wchar_t *s) { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
+
+#ifndef USE_UNICODE_FSTRING
+bool IsDrivePath(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; }
+bool IsSuperPath(CFSTR s) throw() { return IS_SUPER_PREFIX(s); }
+bool IsSuperOrDevicePath(CFSTR s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); }
+#endif // USE_UNICODE_FSTRING
+
+bool IsAbsolutePath(const wchar_t *s) throw()
+{
+ return s[0] == WCHAR_PATH_SEPARATOR || IsDrivePath(s);
+}
+
+static const unsigned kDrivePrefixSize = 3; /* c:\ */
+
+#ifndef USE_UNICODE_FSTRING
+
+static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s) throw()
+{
+ // Network path: we look "server\path\" as root prefix
+ int pos = FindCharPosInString(s, '\\');
+ if (pos < 0)
+ return 0;
+ int pos2 = FindCharPosInString(s + pos + 1, '\\');
+ if (pos2 < 0)
+ return 0;
+ return pos + pos2 + 2;
+}
+
+static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s) throw()
+{
+ if (IsDrivePath(s))
+ return kDrivePrefixSize;
+ if (s[0] != '\\' || s[1] != '\\')
+ return 0;
+ unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
+ return (size == 0) ? 0 : 2 + size;
+}
+
+static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s) throw()
+{
+ if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
+ {
+ unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize);
+ return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
+ }
+ // we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
+ int pos = FindCharPosInString(s + kSuperPathPrefixSize, FCHAR_PATH_SEPARATOR);
+ if (pos < 0)
+ return 0;
+ return kSuperPathPrefixSize + pos + 1;
+}
+
+unsigned GetRootPrefixSize(CFSTR s) throw()
+{
+ if (IS_DEVICE_PATH(s))
+ return kDevicePathPrefixSize;
+ if (IsSuperPath(s))
+ return GetRootPrefixSize_Of_SuperPath(s);
+ return GetRootPrefixSize_Of_SimplePath(s);
+}
+
+#endif // USE_UNICODE_FSTRING
+
+static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s) throw()
+{
+ // Network path: we look "server\path\" as root prefix
+ int pos = FindCharPosInString(s, L'\\');
+ if (pos < 0)
+ return 0;
+ int pos2 = FindCharPosInString(s + pos + 1, L'\\');
+ if (pos2 < 0)
+ return 0;
+ return pos + pos2 + 2;
+}
+
+static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s) throw()
+{
+ if (IsDrivePath(s))
+ return kDrivePrefixSize;
+ if (s[0] != '\\' || s[1] != '\\')
+ return 0;
+ unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
+ return (size == 0) ? 0 : 2 + size;
+}
+
+static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s) throw()
+{
+ if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
+ {
+ unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize);
+ return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
+ }
+ // we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
+ int pos = FindCharPosInString(s + kSuperPathPrefixSize, L'\\');
+ if (pos < 0)
+ return 0;
+ return kSuperPathPrefixSize + pos + 1;
+}
+
+unsigned GetRootPrefixSize(const wchar_t *s) throw()
+{
+ if (IS_DEVICE_PATH(s))
+ return kDevicePathPrefixSize;
+ if (IsSuperPath(s))
+ return GetRootPrefixSize_Of_SuperPath(s);
+ return GetRootPrefixSize_Of_SimplePath(s);
+}
+
+#else // _WIN32
+
+bool IsAbsolutePath(const wchar_t *s) throw() { return s[0] == WCHAR_PATH_SEPARATOR }
+
+#ifndef USE_UNICODE_FSTRING
+unsigned GetRootPrefixSize(CFSTR s) throw() { return s[0] == CHAR_PATH_SEPRATOR ? 1 : 0; }
+#endif
+unsigned GetRootPrefixSize(const wchar_t *s) throw() { return s[0] == CHAR_PATH_SEPRATOR ? 1 : 0; }
+
+#endif // _WIN32
+
+
+#ifndef UNDER_CE
+
+static bool GetCurDir(UString &path)
+{
+ path.Empty();
+ DWORD needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetCurrentDirectory(MAX_PATH + 1, s);
+ path = fs2us(fas2fs(s));
+ }
+ else
+ #endif
+ {
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, s);
+ path = s;
+ }
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+static bool ResolveDotsFolders(UString &s)
+{
+ #ifdef _WIN32
+ s.Replace(L'/', WCHAR_PATH_SEPARATOR);
+ #endif
+ for (int i = 0;;)
+ {
+ wchar_t c = s[i];
+ if (c == 0)
+ return true;
+ if (c == '.' && (i == 0 || s[i - 1] == WCHAR_PATH_SEPARATOR))
+ {
+ wchar_t c1 = s[i + 1];
+ if (c1 == '.')
+ {
+ wchar_t c2 = s[i + 2];
+ if (c2 == WCHAR_PATH_SEPARATOR || c2 == 0)
+ {
+ if (i == 0)
+ return false;
+ int k = i - 2;
+ for (; k >= 0; k--)
+ if (s[k] == WCHAR_PATH_SEPARATOR)
+ break;
+ unsigned num;
+ if (k >= 0)
+ {
+ num = i + 2 - k;
+ i = k;
+ }
+ else
+ {
+ num = (c2 == 0 ? (i + 2) : (i + 3));
+ i = 0;
+ }
+ s.Delete(i, num);
+ continue;
+ }
+ }
+ else
+ {
+ if (c1 == WCHAR_PATH_SEPARATOR || c1 == 0)
+ {
+ unsigned num = 2;
+ if (i != 0)
+ i--;
+ else if (c1 == 0)
+ num = 1;
+ s.Delete(i, num);
+ continue;
+ }
+ }
+ }
+ i++;
+ }
+}
+
+#endif // UNDER_CE
+
+#define LONG_PATH_DOTS_FOLDERS_PARSING
+
+
+/*
+Windows (at least 64-bit XP) can't resolve "." or ".." in paths that start with SuperPrefix \\?\
+To solve that problem we check such path:
+ - super path contains "." or ".." - we use kSuperPathType_UseOnlySuper
+ - super path doesn't contain "." or ".." - we use kSuperPathType_UseOnlyMain
+*/
+#ifdef LONG_PATH_DOTS_FOLDERS_PARSING
+#ifndef UNDER_CE
+static bool AreThereDotsFolders(CFSTR s)
+{
+ for (unsigned i = 0;; i++)
+ {
+ FChar c = s[i];
+ if (c == 0)
+ return false;
+ if (c == '.' && (i == 0 || s[i - 1] == CHAR_PATH_SEPARATOR))
+ {
+ FChar c1 = s[i + 1];
+ if (c1 == 0 || c1 == CHAR_PATH_SEPARATOR ||
+ (c1 == '.' && (s[i + 2] == 0 || s[i + 2] == CHAR_PATH_SEPARATOR)))
+ return true;
+ }
+ }
}
#endif
+#endif // LONG_PATH_DOTS_FOLDERS_PARSING
+
+#ifdef WIN_LONG_PATH
+
+/*
+Most of Windows versions have problems, if some file or dir name
+contains '.' or ' ' at the end of name (Bad Path).
+To solve that problem, we always use Super Path ("\\?\" prefix and full path)
+in such cases. Note that "." and ".." are not bad names.
+
+There are 3 cases:
+ 1) If the path is already Super Path, we use that path
+ 2) If the path is not Super Path :
+ 2.1) Bad Path; we use only Super Path.
+ 2.2) Good Path; we use Main Path. If it fails, we use Super Path.
+
+ NeedToUseOriginalPath returns:
+ kSuperPathType_UseOnlyMain : Super already
+ kSuperPathType_UseOnlySuper : not Super, Bad Path
+ kSuperPathType_UseMainAndSuper : not Super, Good Path
+*/
+
+int GetUseSuperPathType(CFSTR s) throw()
+{
+ if (IsSuperOrDevicePath(s))
+ {
+ #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
+ if ((s)[2] != '.')
+ if (AreThereDotsFolders(s + kSuperPathPrefixSize))
+ return kSuperPathType_UseOnlySuper;
+ #endif
+ return kSuperPathType_UseOnlyMain;
+ }
+
+ for (unsigned i = 0;; i++)
+ {
+ FChar c = s[i];
+ if (c == 0)
+ return kSuperPathType_UseMainAndSuper;
+ if (c == '.' || c == ' ')
+ {
+ FChar c2 = s[i + 1];
+ if (c2 == 0 || c2 == CHAR_PATH_SEPARATOR)
+ {
+ // if it's "." or "..", it's not bad name.
+ if (c == '.')
+ {
+ if (i == 0 || s[i - 1] == CHAR_PATH_SEPARATOR)
+ continue;
+ if (s[i - 1] == '.')
+ {
+ if (i - 1 == 0 || s[i - 2] == CHAR_PATH_SEPARATOR)
+ continue;
+ }
+ }
+ return kSuperPathType_UseOnlySuper;
+ }
+ }
+ }
+}
+
+
+/*
+ returns false in two cases:
+ - if GetCurDir was used, and GetCurDir returned error.
+ - if we can't resolve ".." name.
+ if path is ".", "..", res is empty.
+ if it's Super Path already, res is empty.
+ for \**** , and if GetCurDir is not drive (c:\), res is empty
+ for absolute paths, returns true, res is Super path.
+*/
+
+
+static bool GetSuperPathBase(CFSTR s, UString &res)
+{
+ res.Empty();
+
+ FChar c = s[0];
+ if (c == 0)
+ return true;
+ if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
+ return true;
+
+ if (IsSuperOrDevicePath(s))
+ {
+ #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
+
+ if ((s)[2] == '.')
+ return true;
+
+ // we will return true here, so we will try to use these problem paths.
+
+ if (!AreThereDotsFolders(s + kSuperPathPrefixSize))
+ return true;
+
+ UString temp = fs2us(s);
+ unsigned fixedSize = GetRootPrefixSize_Of_SuperPath(temp);
+ if (fixedSize == 0)
+ return true;
+
+ UString rem = &temp[fixedSize];
+ if (!ResolveDotsFolders(rem))
+ return true;
+
+ temp.DeleteFrom(fixedSize);
+ res += temp;
+ res += rem;
+
+ #endif
+
+ return true;
+ }
+
+ if (c == CHAR_PATH_SEPARATOR)
+ {
+ if (s[1] == CHAR_PATH_SEPARATOR)
+ {
+ UString temp = fs2us(s + 2);
+ unsigned fixedSize = GetRootPrefixSize_Of_NetworkPath(temp);
+ if (fixedSize == 0) // maybe we must ignore that error to allow short network paths?
+ return false;
+ UString rem = &temp[fixedSize];
+ if (!ResolveDotsFolders(rem))
+ return false;
+ res += kSuperUncPrefix;
+ temp.DeleteFrom(fixedSize);
+ res += temp;
+ res += rem;
+ return true;
+ }
+ }
+ else
+ {
+ if (IsDrivePath(s))
+ {
+ UString temp = fs2us(s);
+ UString rem = &temp[kDrivePrefixSize];
+ if (!ResolveDotsFolders(rem))
+ return true;
+ res += kSuperPathPrefix;
+ temp.DeleteFrom(kDrivePrefixSize);
+ res += temp;
+ res += rem;
+ return true;
+ }
+ }
+
+ UString curDir;
+ if (!GetCurDir(curDir))
+ return false;
+ if (curDir.Back() != WCHAR_PATH_SEPARATOR)
+ curDir += WCHAR_PATH_SEPARATOR;
+
+ unsigned fixedSizeStart = 0;
+ unsigned fixedSize = 0;
+ const wchar_t *superMarker = NULL;
+ if (IsSuperPath(curDir))
+ {
+ fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
+ if (fixedSize == 0)
+ return false;
+ }
+ else
+ {
+ if (IsDrivePath(curDir))
+ {
+ superMarker = kSuperPathPrefix;
+ fixedSize = kDrivePrefixSize;
+ }
+ else
+ {
+ if (curDir[0] != CHAR_PATH_SEPARATOR || curDir[1] != CHAR_PATH_SEPARATOR)
+ return false;
+ fixedSizeStart = 2;
+ fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]);
+ if (fixedSize == 0)
+ return false;
+ superMarker = kSuperUncPrefix;
+ }
+ }
+
+ UString temp;
+ if (c == CHAR_PATH_SEPARATOR)
+ {
+ temp = fs2us(s + 1);
+ }
+ else
+ {
+ temp += &curDir[fixedSizeStart + fixedSize];
+ temp += fs2us(s);
+ }
+ if (!ResolveDotsFolders(temp))
+ return false;
+ if (superMarker)
+ res += superMarker;
+ res += curDir.Mid(fixedSizeStart, fixedSize);
+ res += temp;
+ return true;
+}
+
-const wchar_t kExtensionDelimiter = L'.';
+/*
+ In that case if GetSuperPathBase doesn't return new path, we don't need
+ to use same path that was used as main path
-void SplitNameToPureNameAndExtension(const UString &fullName,
- UString &pureName, UString &extensionDelimiter, UString &extension)
+ GetSuperPathBase superPath.IsEmpty() onlyIfNew
+ false * * GetCurDir Error
+ true false * use Super path
+ true true true don't use any path, we already used mainPath
+ true true false use main path as Super Path, we don't try mainMath
+ That case is possible now if GetCurDir returns unknow
+ type of path (not drive and not network)
+
+ We can change that code if we want to try mainPath, if GetSuperPathBase returns error,
+ and we didn't try mainPath still.
+ If we want to work that way, we don't need to use GetSuperPathBase return code.
+*/
+
+bool GetSuperPath(CFSTR path, UString &superPath, bool onlyIfNew)
+{
+ if (GetSuperPathBase(path, superPath))
+ {
+ if (superPath.IsEmpty())
+ {
+ // actually the only possible when onlyIfNew == true and superPath is empty
+ // is case when
+
+ if (onlyIfNew)
+ return false;
+ superPath = fs2us(path);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew)
+{
+ if (!GetSuperPathBase(s1, d1) ||
+ !GetSuperPathBase(s2, d2))
+ return false;
+ if (d1.IsEmpty() && d2.IsEmpty() && onlyIfNew)
+ return false;
+ if (d1.IsEmpty()) d1 = fs2us(s1);
+ if (d2.IsEmpty()) d2 = fs2us(s2);
+ return true;
+}
+
+
+/*
+// returns true, if we need additional use with New Super path.
+bool GetSuperPath(CFSTR path, UString &superPath)
+{
+ if (GetSuperPathBase(path, superPath))
+ return !superPath.IsEmpty();
+ return false;
+}
+*/
+#endif // WIN_LONG_PATH
+
+bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
{
- int index = fullName.ReverseFind(kExtensionDelimiter);
- if (index < 0)
+ res = s;
+
+ #ifdef UNDER_CE
+
+ if (s[0] != CHAR_PATH_SEPARATOR)
+ {
+ if (!dirPrefix)
+ return false;
+ res = dirPrefix;
+ res += s;
+ }
+
+ #else
+
+ unsigned prefixSize = GetRootPrefixSize(s);
+ if (prefixSize != 0)
+ {
+ if (!AreThereDotsFolders(s + prefixSize))
+ return true;
+
+ UString rem = fs2us(s + prefixSize);
+ if (!ResolveDotsFolders(rem))
+ return true; // maybe false;
+ res.DeleteFrom(prefixSize);
+ res += us2fs(rem);
+ return true;
+ }
+
+ /*
+ FChar c = s[0];
+ if (c == 0)
+ return true;
+ if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
+ return true;
+ if (c == CHAR_PATH_SEPARATOR && s[1] == CHAR_PATH_SEPARATOR)
+ return true;
+ if (IsDrivePath(s))
+ return true;
+ */
+
+ UString curDir;
+ if (dirPrefix)
+ curDir = fs2us(dirPrefix);
+ else
+ {
+ if (!GetCurDir(curDir))
+ return false;
+ }
+ if (!curDir.IsEmpty() && curDir.Back() != WCHAR_PATH_SEPARATOR)
+ curDir += WCHAR_PATH_SEPARATOR;
+
+ unsigned fixedSize = 0;
+
+ #ifdef _WIN32
+
+ if (IsSuperPath(curDir))
+ {
+ fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
+ if (fixedSize == 0)
+ return false;
+ }
+ else
+ {
+ if (IsDrivePath(curDir))
+ fixedSize = kDrivePrefixSize;
+ else
+ {
+ if (curDir[0] != WCHAR_PATH_SEPARATOR || curDir[1] != WCHAR_PATH_SEPARATOR)
+ return false;
+ fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]);
+ if (fixedSize == 0)
+ return false;
+ fixedSize += 2;
+ }
+ }
+
+ #endif // _WIN32
+
+ UString temp;
+ if (s[0] == CHAR_PATH_SEPARATOR)
{
- pureName = fullName;
- extensionDelimiter.Empty();
- extension.Empty();
+ temp = fs2us(s + 1);
}
else
{
- pureName = fullName.Left(index);
- extensionDelimiter = kExtensionDelimiter;
- extension = fullName.Mid(index + 1);
+ temp += curDir.Ptr(fixedSize);
+ temp += fs2us(s);
}
+ if (!ResolveDotsFolders(temp))
+ return false;
+ curDir.DeleteFrom(fixedSize);
+ res = us2fs(curDir);
+ res += us2fs(temp);
+
+ #endif // UNDER_CE
+
+ return true;
+}
+
+bool GetFullPath(CFSTR path, FString &fullPath)
+{
+ return GetFullPath(NULL, path, fullPath);
}
}}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileName.h b/src/libs/7zip/win/CPP/Windows/FileName.h
index d98079026..04fc79b2d 100644
--- a/src/libs/7zip/win/CPP/Windows/FileName.h
+++ b/src/libs/7zip/win/CPP/Windows/FileName.h
@@ -1,9 +1,7 @@
// Windows/FileName.h
-#ifndef __WINDOWS_FILENAME_H
-#define __WINDOWS_FILENAME_H
-
-#include "../../C/Types.h"
+#ifndef __WINDOWS_FILE_NAME_H
+#define __WINDOWS_FILE_NAME_H
#include "../Common/MyString.h"
@@ -11,16 +9,65 @@ namespace NWindows {
namespace NFile {
namespace NName {
-const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR;
-const TCHAR kAnyStringWildcard = '*';
+void NormalizeDirPathPrefix(FString &dirPath); // ensures that it ended with '\\', if dirPath is not epmty
+void NormalizeDirPathPrefix(UString &dirPath);
+
+#ifdef _WIN32
+
+extern const wchar_t *kSuperPathPrefix; /* \\?\ */
+const unsigned kDevicePathPrefixSize = 4;
+const unsigned kSuperPathPrefixSize = 4;
+const unsigned kSuperUncPathPrefixSize = kSuperPathPrefixSize + 4;
+
+bool IsDevicePath(CFSTR s) throw(); /* \\.\ */
+bool IsSuperUncPath(CFSTR s) throw();
-void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\'
-#ifndef _UNICODE
-void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\'
+bool IsDrivePath(const wchar_t *s) throw();
+bool IsSuperPath(const wchar_t *s) throw();
+bool IsSuperOrDevicePath(const wchar_t *s) throw();
+
+#ifndef USE_UNICODE_FSTRING
+bool IsDrivePath(CFSTR s) throw();
+bool IsSuperPath(CFSTR s) throw();
+bool IsSuperOrDevicePath(CFSTR s) throw();
#endif
-void SplitNameToPureNameAndExtension(const UString &fullName,
- UString &pureName, UString &extensionDelimiter, UString &extension);
+#endif // _WIN32
+
+bool IsAbsolutePath(const wchar_t *s) throw();
+unsigned GetRootPrefixSize(const wchar_t *s) throw();
+
+#ifdef WIN_LONG_PATH
+
+const int kSuperPathType_UseOnlyMain = 0;
+const int kSuperPathType_UseOnlySuper = 1;
+const int kSuperPathType_UseMainAndSuper = 2;
+
+int GetUseSuperPathType(CFSTR s) throw();
+bool GetSuperPath(CFSTR path, UString &longPath, bool onlyIfNew);
+bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew);
+
+#define USE_MAIN_PATH (__useSuperPathType != kSuperPathType_UseOnlySuper)
+#define USE_MAIN_PATH_2 (__useSuperPathType1 != kSuperPathType_UseOnlySuper && __useSuperPathType2 != kSuperPathType_UseOnlySuper)
+
+#define USE_SUPER_PATH (__useSuperPathType != kSuperPathType_UseOnlyMain)
+#define USE_SUPER_PATH_2 (__useSuperPathType1 != kSuperPathType_UseOnlyMain || __useSuperPathType2 != kSuperPathType_UseOnlyMain)
+
+#define IF_USE_MAIN_PATH int __useSuperPathType = GetUseSuperPathType(path); if (USE_MAIN_PATH)
+#define IF_USE_MAIN_PATH_2(x1, x2) \
+ int __useSuperPathType1 = GetUseSuperPathType(x1); \
+ int __useSuperPathType2 = GetUseSuperPathType(x2); \
+ if (USE_MAIN_PATH_2)
+
+#else
+
+#define IF_USE_MAIN_PATH
+#define IF_USE_MAIN_PATH_2(x1, x2)
+
+#endif // WIN_LONG_PATH
+
+bool GetFullPath(CFSTR dirPrefix, CFSTR path, FString &fullPath);
+bool GetFullPath(CFSTR path, FString &fullPath);
}}}
diff --git a/src/libs/7zip/win/CPP/Windows/MemoryLock.cpp b/src/libs/7zip/win/CPP/Windows/MemoryLock.cpp
deleted file mode 100644
index e0f430996..000000000
--- a/src/libs/7zip/win/CPP/Windows/MemoryLock.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-// Common/MemoryLock.cpp
-
-#include "StdAfx.h"
-
-namespace NWindows {
-namespace NSecurity {
-
-#ifndef UNDER_CE
-
-#ifndef _UNICODE
-typedef BOOL (WINAPI * OpenProcessTokenP)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
-typedef BOOL (WINAPI * LookupPrivilegeValueP)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid);
-typedef BOOL (WINAPI * AdjustTokenPrivilegesP)(HANDLE TokenHandle, BOOL DisableAllPrivileges,
- PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState,PDWORD ReturnLength);
-#endif
-
-#ifdef _UNICODE
-bool EnableLockMemoryPrivilege(
-#else
-static bool EnableLockMemoryPrivilege2(HMODULE hModule,
-#endif
-bool enable)
-{
- #ifndef _UNICODE
- if (hModule == NULL)
- return false;
- OpenProcessTokenP openProcessToken = (OpenProcessTokenP)GetProcAddress(hModule, "OpenProcessToken");
- LookupPrivilegeValueP lookupPrivilegeValue = (LookupPrivilegeValueP)GetProcAddress(hModule, "LookupPrivilegeValueA" );
- AdjustTokenPrivilegesP adjustTokenPrivileges = (AdjustTokenPrivilegesP)GetProcAddress(hModule, "AdjustTokenPrivileges");
- if (openProcessToken == NULL || adjustTokenPrivileges == NULL || lookupPrivilegeValue == NULL)
- return false;
- #endif
-
- HANDLE token;
- if (!
- #ifdef _UNICODE
- ::OpenProcessToken
- #else
- openProcessToken
- #endif
- (::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
- return false;
- TOKEN_PRIVILEGES tp;
- bool res = false;
- if (
- #ifdef _UNICODE
- ::LookupPrivilegeValue
- #else
- lookupPrivilegeValue
- #endif
- (NULL, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)))
- {
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED: 0;
- if (
- #ifdef _UNICODE
- ::AdjustTokenPrivileges
- #else
- adjustTokenPrivileges
- #endif
- (token, FALSE, &tp, 0, NULL, NULL))
- res = (GetLastError() == ERROR_SUCCESS);
- }
- ::CloseHandle(token);
- return res;
-}
-
-#ifndef _UNICODE
-bool EnableLockMemoryPrivilege(bool enable)
-{
- HMODULE hModule = LoadLibrary(TEXT("Advapi32.dll"));
- if (hModule == NULL)
- return false;
- bool res = EnableLockMemoryPrivilege2(hModule, enable);
- ::FreeLibrary(hModule);
- return res;
-}
-#endif
-
-#endif
-
-}}
diff --git a/src/libs/7zip/win/CPP/Windows/MemoryLock.h b/src/libs/7zip/win/CPP/Windows/MemoryLock.h
deleted file mode 100644
index 5fe619de0..000000000
--- a/src/libs/7zip/win/CPP/Windows/MemoryLock.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Windows/MemoryLock.h
-
-#ifndef __WINDOWS_MEMORYLOCK_H
-#define __WINDOWS_MEMORYLOCK_H
-
-namespace NWindows {
-namespace NSecurity {
-
-#ifndef UNDER_CE
-bool EnableLockMemoryPrivilege(bool enable = true);
-#endif
-
-}}
-
-#endif
diff --git a/src/libs/7zip/win/CPP/Windows/NtCheck.h b/src/libs/7zip/win/CPP/Windows/NtCheck.h
deleted file mode 100644
index e56318f00..000000000
--- a/src/libs/7zip/win/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/win/CPP/Windows/PropVariant.cpp b/src/libs/7zip/win/CPP/Windows/PropVariant.cpp
index 90212e08f..d16f576cc 100644
--- a/src/libs/7zip/win/CPP/Windows/PropVariant.cpp
+++ b/src/libs/7zip/win/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/win/CPP/Windows/PropVariant.h b/src/libs/7zip/win/CPP/Windows/PropVariant.h
index d018034eb..d71b85e1d 100644
--- a/src/libs/7zip/win/CPP/Windows/PropVariant.h
+++ b/src/libs/7zip/win/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/win/CPP/Windows/PropVariantConv.cpp b/src/libs/7zip/win/CPP/Windows/PropVariantConv.cpp
new file mode 100644
index 000000000..dfb93d6d6
--- /dev/null
+++ b/src/libs/7zip/win/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/win/CPP/Windows/PropVariantConv.h b/src/libs/7zip/win/CPP/Windows/PropVariantConv.h
new file mode 100644
index 000000000..5d26357f0
--- /dev/null
+++ b/src/libs/7zip/win/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/win/CPP/Windows/PropVariantConversions.cpp b/src/libs/7zip/win/CPP/Windows/PropVariantConversions.cpp
deleted file mode 100644
index 2d8456cd6..000000000
--- a/src/libs/7zip/win/CPP/Windows/PropVariantConversions.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-// PropVariantConversions.cpp
-
-#include "StdAfx.h"
-
-#include "Common/IntToString.h"
-#include "Common/StringConvert.h"
-
-#include "Windows/Defs.h"
-
-#include "PropVariantConversions.h"
-
-static UString ConvertUInt64ToString(UInt64 value)
-{
- wchar_t buffer[32];
- ConvertUInt64ToString(value, buffer);
- return buffer;
-}
-
-static UString ConvertInt64ToString(Int64 value)
-{
- wchar_t buffer[32];
- ConvertInt64ToString(value, buffer);
- return buffer;
-}
-
-static char *UIntToStringSpec(char c, UInt32 value, char *s, int numPos)
-{
- if (c != 0)
- *s++ = c;
- char temp[16];
- int pos = 0;
- do
- {
- temp[pos++] = (char)('0' + value % 10);
- value /= 10;
- }
- while (value != 0);
- int i;
- for (i = 0; i < numPos - pos; i++)
- *s++ = '0';
- do
- *s++ = temp[--pos];
- while (pos > 0);
- *s = '\0';
- return s;
-}
-
-bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds)
-{
- s[0] = '\0';
- SYSTEMTIME st;
- if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
- return false;
- s = UIntToStringSpec(0, st.wYear, s, 4);
- s = UIntToStringSpec('-', st.wMonth, s, 2);
- s = UIntToStringSpec('-', st.wDay, s, 2);
- if (includeTime)
- {
- s = UIntToStringSpec(' ', st.wHour, s, 2);
- s = UIntToStringSpec(':', st.wMinute, s, 2);
- if (includeSeconds)
- UIntToStringSpec(':', st.wSecond, s, 2);
- }
- return true;
-}
-
-UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime, bool includeSeconds)
-{
- char s[32];
- ConvertFileTimeToString(ft, s, includeTime, includeSeconds);
- return GetUnicodeString(s);
-}
-
-
-UString ConvertPropVariantToString(const PROPVARIANT &prop)
-{
- switch (prop.vt)
- {
- case VT_EMPTY: return UString();
- case VT_BSTR: return prop.bstrVal;
- case VT_UI1: return ConvertUInt64ToString(prop.bVal);
- case VT_UI2: return ConvertUInt64ToString(prop.uiVal);
- case VT_UI4: return ConvertUInt64ToString(prop.ulVal);
- case VT_UI8: return ConvertUInt64ToString(prop.uhVal.QuadPart);
- case VT_FILETIME: return ConvertFileTimeToString(prop.filetime, true, true);
- // case VT_I1: return ConvertInt64ToString(prop.cVal);
- case VT_I2: return ConvertInt64ToString(prop.iVal);
- case VT_I4: return ConvertInt64ToString(prop.lVal);
- case VT_I8: return ConvertInt64ToString(prop.hVal.QuadPart);
- case VT_BOOL: return VARIANT_BOOLToBool(prop.boolVal) ? L"+" : L"-";
- default: throw 150245;
- }
-}
-
-UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop)
-{
- switch (prop.vt)
- {
- case VT_UI1: return prop.bVal;
- case VT_UI2: return prop.uiVal;
- case VT_UI4: return prop.ulVal;
- case VT_UI8: return (UInt64)prop.uhVal.QuadPart;
- default: throw 151199;
- }
-}
diff --git a/src/libs/7zip/win/CPP/Windows/PropVariantConversions.h b/src/libs/7zip/win/CPP/Windows/PropVariantConversions.h
deleted file mode 100644
index 3de4dedb3..000000000
--- a/src/libs/7zip/win/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/win/CPP/Windows/Registry.cpp b/src/libs/7zip/win/CPP/Windows/Registry.cpp
deleted file mode 100644
index 8b25375d9..000000000
--- a/src/libs/7zip/win/CPP/Windows/Registry.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-// Windows/Registry.cpp
-
-#include "StdAfx.h"
-
-#ifndef _UNICODE
-#include "Common/StringConvert.h"
-#endif
-#include "Windows/Registry.h"
-
-#ifndef _UNICODE
-extern bool g_IsNT;
-#endif
-
-namespace NWindows {
-namespace NRegistry {
-
-#define MYASSERT(expr) // _ASSERTE(expr)
-
-LONG CKey::Create(HKEY parentKey, LPCTSTR keyName,
- LPTSTR keyClass, DWORD options, REGSAM accessMask,
- LPSECURITY_ATTRIBUTES securityAttributes, LPDWORD disposition)
-{
- MYASSERT(parentKey != NULL);
- DWORD dispositionReal;
- HKEY key = NULL;
- LONG res = RegCreateKeyEx(parentKey, keyName, 0, keyClass,
- options, accessMask, securityAttributes, &key, &dispositionReal);
- if (disposition != NULL)
- *disposition = dispositionReal;
- if (res == ERROR_SUCCESS)
- {
- res = Close();
- _object = key;
- }
- return res;
-}
-
-LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask)
-{
- MYASSERT(parentKey != NULL);
- HKEY key = NULL;
- LONG res = RegOpenKeyEx(parentKey, keyName, 0, accessMask, &key);
- if (res == ERROR_SUCCESS)
- {
- res = Close();
- MYASSERT(res == ERROR_SUCCESS);
- _object = key;
- }
- return res;
-}
-
-LONG CKey::Close()
-{
- LONG res = ERROR_SUCCESS;
- if (_object != NULL)
- {
- res = RegCloseKey(_object);
- _object = NULL;
- }
- return res;
-}
-
-// win95, win98: deletes sunkey and all its subkeys
-// winNT to be deleted must not have subkeys
-LONG CKey::DeleteSubKey(LPCTSTR subKeyName)
-{
- MYASSERT(_object != NULL);
- return RegDeleteKey(_object, subKeyName);
-}
-
-LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName)
-{
- CKey key;
- LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE);
- if (res != ERROR_SUCCESS)
- return res;
- FILETIME fileTime;
- const UInt32 kBufferSize = MAX_PATH + 1; // 256 in ATL
- DWORD size = kBufferSize;
- TCHAR buffer[kBufferSize];
- while (RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime) == ERROR_SUCCESS)
- {
- res = key.RecurseDeleteKey(buffer);
- if (res != ERROR_SUCCESS)
- return res;
- size = kBufferSize;
- }
- key.Close();
- return DeleteSubKey(subKeyName);
-}
-
-
-/////////////////////////
-// Value Functions
-
-static inline UInt32 BoolToUINT32(bool value) { return (value ? 1: 0); }
-static inline bool UINT32ToBool(UInt32 value) { return (value != 0); }
-
-
-LONG CKey::DeleteValue(LPCTSTR name)
-{
- MYASSERT(_object != NULL);
- return ::RegDeleteValue(_object, name);
-}
-
-#ifndef _UNICODE
-LONG CKey::DeleteValue(LPCWSTR name)
-{
- MYASSERT(_object != NULL);
- if (g_IsNT)
- return ::RegDeleteValueW(_object, name);
- return DeleteValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name));
-}
-#endif
-
-LONG CKey::SetValue(LPCTSTR name, UInt32 value)
-{
- MYASSERT(_object != NULL);
- return RegSetValueEx(_object, name, NULL, REG_DWORD,
- (BYTE * const)&value, sizeof(UInt32));
-}
-
-LONG CKey::SetValue(LPCTSTR name, bool value)
-{
- return SetValue(name, BoolToUINT32(value));
-}
-
-LONG CKey::SetValue(LPCTSTR name, LPCTSTR value)
-{
- MYASSERT(value != NULL);
- MYASSERT(_object != NULL);
- return RegSetValueEx(_object, name, NULL, REG_SZ,
- (const BYTE * )value, (lstrlen(value) + 1) * sizeof(TCHAR));
-}
-
-/*
-LONG CKey::SetValue(LPCTSTR name, const CSysString &value)
-{
- MYASSERT(value != NULL);
- MYASSERT(_object != NULL);
- return RegSetValueEx(_object, name, NULL, REG_SZ,
- (const BYTE *)(const TCHAR *)value, (value.Length() + 1) * sizeof(TCHAR));
-}
-*/
-
-#ifndef _UNICODE
-
-LONG CKey::SetValue(LPCWSTR name, LPCWSTR value)
-{
- MYASSERT(value != NULL);
- MYASSERT(_object != NULL);
- if (g_IsNT)
- return RegSetValueExW(_object, name, NULL, REG_SZ,
- (const BYTE * )value, (DWORD)((wcslen(value) + 1) * sizeof(wchar_t)));
- return SetValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name),
- value == 0 ? 0 : (LPCSTR)GetSystemString(value));
-}
-
-#endif
-
-
-LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size)
-{
- MYASSERT(value != NULL);
- MYASSERT(_object != NULL);
- return RegSetValueEx(_object, name, NULL, REG_BINARY,
- (const BYTE *)value, size);
-}
-
-LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value)
-{
- MYASSERT(value != NULL);
- CKey key;
- LONG res = key.Create(parentKey, keyName);
- if (res == ERROR_SUCCESS)
- res = key.SetValue(valueName, value);
- return res;
-}
-
-LONG CKey::SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value)
-{
- MYASSERT(value != NULL);
- CKey key;
- LONG res = key.Create(_object, keyName);
- if (res == ERROR_SUCCESS)
- res = key.SetValue(valueName, value);
- return res;
-}
-
-LONG CKey::QueryValue(LPCTSTR name, UInt32 &value)
-{
- DWORD type = NULL;
- DWORD count = sizeof(DWORD);
- LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type,
- (LPBYTE)&value, &count);
- MYASSERT((res!=ERROR_SUCCESS) || (type == REG_DWORD));
- MYASSERT((res!=ERROR_SUCCESS) || (count == sizeof(UInt32)));
- return res;
-}
-
-LONG CKey::QueryValue(LPCTSTR name, bool &value)
-{
- UInt32 uintValue = BoolToUINT32(value);
- LONG res = QueryValue(name, uintValue);
- value = UINT32ToBool(uintValue);
- return res;
-}
-
-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::QueryValue(LPCTSTR name, LPTSTR value, UInt32 &count)
-{
- MYASSERT(count != NULL);
- DWORD type = NULL;
- LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
- MYASSERT((res!=ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
- return res;
-}
-
-LONG CKey::QueryValue(LPCTSTR name, CSysString &value)
-{
- value.Empty();
- DWORD type = NULL;
- UInt32 currentSize = 0;
- LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&currentSize);
- if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
- return res;
- res = QueryValue(name, value.GetBuffer(currentSize), currentSize);
- value.ReleaseBuffer();
- return res;
-}
-
-#ifndef _UNICODE
-LONG CKey::QueryValue(LPCWSTR name, LPWSTR value, UInt32 &count)
-{
- MYASSERT(count != NULL);
- DWORD type = NULL;
- LONG res = RegQueryValueExW(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
- MYASSERT((res!=ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
- return res;
-}
-LONG CKey::QueryValue(LPCWSTR name, UString &value)
-{
- value.Empty();
- DWORD type = NULL;
- UInt32 currentSize = 0;
-
- LONG res;
- if (g_IsNT)
- {
- res = RegQueryValueExW(_object, name, NULL, &type, NULL, (DWORD *)&currentSize);
- if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
- return res;
- res = QueryValue(name, value.GetBuffer(currentSize), currentSize);
- value.ReleaseBuffer();
- }
- else
- {
- AString vTemp;
- res = QueryValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), vTemp);
- value = GetUnicodeString(vTemp);
- }
- return res;
-}
-#endif
-
-LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &count)
-{
- DWORD type = NULL;
- LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
- MYASSERT((res!=ERROR_SUCCESS) || (type == REG_BINARY));
- return res;
-}
-
-
-LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize)
-{
- DWORD type = NULL;
- dataSize = 0;
- LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&dataSize);
- if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
- return res;
- value.SetCapacity(dataSize);
- return QueryValue(name, (BYTE *)value, dataSize);
-}
-
-LONG CKey::EnumKeys(CSysStringVector &keyNames)
-{
- keyNames.Clear();
- CSysString keyName;
- for (UInt32 index = 0; ; index++)
- {
- const UInt32 kBufferSize = MAX_PATH + 1; // 256 in ATL
- FILETIME lastWriteTime;
- UInt32 nameSize = kBufferSize;
- LONG result = ::RegEnumKeyEx(_object, index, keyName.GetBuffer(kBufferSize),
- (DWORD *)&nameSize, NULL, NULL, NULL, &lastWriteTime);
- keyName.ReleaseBuffer();
- if (result == ERROR_NO_MORE_ITEMS)
- break;
- if (result != ERROR_SUCCESS)
- return result;
- keyNames.Add(keyName);
- }
- return ERROR_SUCCESS;
-}
-
-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/win/CPP/Windows/Registry.h b/src/libs/7zip/win/CPP/Windows/Registry.h
deleted file mode 100644
index f0561e688..000000000
--- a/src/libs/7zip/win/CPP/Windows/Registry.h
+++ /dev/null
@@ -1,85 +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"
-
-namespace NWindows {
-namespace NRegistry {
-
-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; }
- void Attach(HKEY key) { _object = key; }
- HKEY Detach()
- {
- HKEY key = _object;
- _object = NULL;
- return 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);
-
- 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/win/CPP/Windows/SecurityUtils.cpp b/src/libs/7zip/win/CPP/Windows/SecurityUtils.cpp
new file mode 100644
index 000000000..f997738ce
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/SecurityUtils.cpp
@@ -0,0 +1,179 @@
+// Windows/SecurityUtils.cpp
+
+#include "StdAfx.h"
+
+#include "SecurityUtils.h"
+
+namespace NWindows {
+namespace NSecurity {
+
+/*
+bool MyLookupAccountSid(LPCTSTR systemName, PSID sid,
+ CSysString &accountName, CSysString &domainName, PSID_NAME_USE sidNameUse)
+{
+ DWORD accountNameSize = 0, domainNameSize = 0;
+
+ if (!::LookupAccountSid(systemName, sid,
+ accountName.GetBuffer(0), &accountNameSize,
+ domainName.GetBuffer(0), &domainNameSize, sidNameUse))
+ {
+ if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ return false;
+ }
+ bool result = BOOLToBool(::LookupAccountSid(systemName, sid,
+ accountName.GetBuffer(accountNameSize), &accountNameSize,
+ domainName.GetBuffer(domainNameSize), &domainNameSize, sidNameUse));
+ accountName.ReleaseBuffer();
+ domainName.ReleaseBuffer();
+ return result;
+}
+*/
+
+static void SetLsaString(LPWSTR src, PLSA_UNICODE_STRING dest)
+{
+ int len = (int)wcslen(src);
+ dest->Length = (USHORT)(len * sizeof(WCHAR));
+ dest->MaximumLength = (USHORT)((len + 1) * sizeof(WCHAR));
+ dest->Buffer = src;
+}
+
+/*
+static void MyLookupSids(CPolicy &policy, PSID ps)
+{
+ LSA_REFERENCED_DOMAIN_LIST *referencedDomains = NULL;
+ LSA_TRANSLATED_NAME *names = NULL;
+ NTSTATUS nts = policy.LookupSids(1, &ps, &referencedDomains, &names);
+ int res = LsaNtStatusToWinError(nts);
+ LsaFreeMemory(referencedDomains);
+ LsaFreeMemory(names);
+}
+*/
+
+#ifndef _UNICODE
+typedef BOOL (WINAPI * LookupAccountNameWP)(
+ LPCWSTR lpSystemName,
+ LPCWSTR lpAccountName,
+ PSID Sid,
+ LPDWORD cbSid,
+ LPWSTR ReferencedDomainName,
+ LPDWORD cchReferencedDomainName,
+ PSID_NAME_USE peUse
+ );
+#endif
+
+static PSID GetSid(LPWSTR accountName)
+{
+ #ifndef _UNICODE
+ HMODULE hModule = GetModuleHandle(TEXT("Advapi32.dll"));
+ if (hModule == NULL)
+ return NULL;
+ LookupAccountNameWP lookupAccountNameW = (LookupAccountNameWP)GetProcAddress(hModule, "LookupAccountNameW");
+ if (lookupAccountNameW == NULL)
+ return NULL;
+ #endif
+
+ DWORD sidLen = 0, domainLen = 0;
+ SID_NAME_USE sidNameUse;
+ if (!
+ #ifdef _UNICODE
+ ::LookupAccountNameW
+ #else
+ lookupAccountNameW
+ #endif
+ (NULL, accountName, NULL, &sidLen, NULL, &domainLen, &sidNameUse))
+ {
+ if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+ {
+ PSID pSid = ::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sidLen);
+ LPWSTR domainName = (LPWSTR)::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (domainLen + 1) * sizeof(WCHAR));
+ BOOL res =
+ #ifdef _UNICODE
+ ::LookupAccountNameW
+ #else
+ lookupAccountNameW
+ #endif
+ (NULL, accountName, pSid, &sidLen, domainName, &domainLen, &sidNameUse);
+ ::HeapFree(GetProcessHeap(), 0, domainName);
+ if (res)
+ return pSid;
+ }
+ }
+ return NULL;
+}
+
+#define MY__SE_LOCK_MEMORY_NAME L"SeLockMemoryPrivilege"
+
+bool AddLockMemoryPrivilege()
+{
+ CPolicy policy;
+ LSA_OBJECT_ATTRIBUTES attr;
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = NULL;
+ attr.ObjectName = NULL;
+ attr.Attributes = 0;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+ if (policy.Open(NULL, &attr,
+ // GENERIC_WRITE)
+ POLICY_ALL_ACCESS)
+ // STANDARD_RIGHTS_REQUIRED,
+ // GENERIC_READ | GENERIC_EXECUTE | POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES)
+ != 0)
+ return false;
+ LSA_UNICODE_STRING userRights;
+ wchar_t s[128] = MY__SE_LOCK_MEMORY_NAME;
+ SetLsaString(s, &userRights);
+ WCHAR userName[256 + 2];
+ DWORD size = 256;
+ if (!GetUserNameW(userName, &size))
+ return false;
+ PSID psid = GetSid(userName);
+ if (psid == NULL)
+ return false;
+ bool res = false;
+
+ /*
+ PLSA_UNICODE_STRING userRightsArray;
+ ULONG countOfRights;
+ NTSTATUS status = policy.EnumerateAccountRights(psid, &userRightsArray, &countOfRights);
+ if (status != 0)
+ return false;
+ bool finded = false;
+ for (ULONG i = 0; i < countOfRights; i++)
+ {
+ LSA_UNICODE_STRING &ur = userRightsArray[i];
+ if (ur.Length != s.Length() * sizeof(WCHAR))
+ continue;
+ if (wcsncmp(ur.Buffer, s, s.Length()) != 0)
+ continue;
+ finded = true;
+ res = true;
+ break;
+ }
+ if (!finded)
+ */
+ {
+ /*
+ LSA_ENUMERATION_INFORMATION *enums;
+ ULONG countReturned;
+ NTSTATUS status = policy.EnumerateAccountsWithUserRight(&userRights, &enums, &countReturned);
+ if (status == 0)
+ {
+ for (ULONG i = 0; i < countReturned; i++)
+ MyLookupSids(policy, enums[i].Sid);
+ if (enums)
+ ::LsaFreeMemory(enums);
+ res = true;
+ }
+ */
+ NTSTATUS status = policy.AddAccountRights(psid, &userRights);
+ if (status == 0)
+ res = true;
+ // ULONG res = LsaNtStatusToWinError(status);
+ }
+ HeapFree(GetProcessHeap(), 0, psid);
+ return res;
+}
+
+}}
+
diff --git a/src/libs/7zip/win/CPP/Windows/SecurityUtils.h b/src/libs/7zip/win/CPP/Windows/SecurityUtils.h
new file mode 100644
index 000000000..715de2505
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/SecurityUtils.h
@@ -0,0 +1,167 @@
+// Windows/SecurityUtils.h
+
+#ifndef __WINDOWS_SECURITY_UTILS_H
+#define __WINDOWS_SECURITY_UTILS_H
+
+#include <NTSecAPI.h>
+
+#include "Defs.h"
+
+namespace NWindows {
+namespace NSecurity {
+
+class CAccessToken
+{
+ HANDLE _handle;
+public:
+ CAccessToken(): _handle(NULL) {};
+ ~CAccessToken() { Close(); }
+ bool Close()
+ {
+ if (_handle == NULL)
+ return true;
+ bool res = BOOLToBool(::CloseHandle(_handle));
+ if (res)
+ _handle = NULL;
+ return res;
+ }
+
+ bool OpenProcessToken(HANDLE processHandle, DWORD desiredAccess)
+ {
+ Close();
+ return BOOLToBool(::OpenProcessToken(processHandle, desiredAccess, &_handle));
+ }
+
+ /*
+ bool OpenThreadToken(HANDLE threadHandle, DWORD desiredAccess, bool openAsSelf)
+ {
+ Close();
+ return BOOLToBool(::OpenTreadToken(threadHandle, desiredAccess, BoolToBOOL(anOpenAsSelf), &_handle));
+ }
+ */
+
+ bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState,
+ DWORD bufferLength, PTOKEN_PRIVILEGES previousState, PDWORD returnLength)
+ { return BOOLToBool(::AdjustTokenPrivileges(_handle, BoolToBOOL(disableAllPrivileges),
+ newState, bufferLength, previousState, returnLength)); }
+
+ bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState)
+ { return AdjustPrivileges(disableAllPrivileges, newState, 0, NULL, NULL); }
+
+ bool AdjustPrivileges(PTOKEN_PRIVILEGES newState)
+ { return AdjustPrivileges(false, newState); }
+
+};
+
+#ifndef _UNICODE
+typedef NTSTATUS (NTAPI *LsaOpenPolicyP)(PLSA_UNICODE_STRING SystemName,
+ PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK DesiredAccess, PLSA_HANDLE PolicyHandle);
+typedef NTSTATUS (NTAPI *LsaCloseP)(LSA_HANDLE ObjectHandle);
+typedef NTSTATUS (NTAPI *LsaAddAccountRightsP)(LSA_HANDLE PolicyHandle,
+ PSID AccountSid, PLSA_UNICODE_STRING UserRights, ULONG CountOfRights );
+#define MY_STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L)
+#endif
+
+struct CPolicy
+{
+protected:
+ LSA_HANDLE _handle;
+ #ifndef _UNICODE
+ HMODULE hModule;
+ #endif
+public:
+ operator LSA_HANDLE() const { return _handle; }
+ CPolicy(): _handle(NULL)
+ {
+ #ifndef _UNICODE
+ hModule = GetModuleHandle(TEXT("Advapi32.dll"));
+ #endif
+ };
+ ~CPolicy() { Close(); }
+
+ NTSTATUS Open(PLSA_UNICODE_STRING systemName, PLSA_OBJECT_ATTRIBUTES objectAttributes,
+ ACCESS_MASK desiredAccess)
+ {
+ #ifndef _UNICODE
+ if (hModule == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ LsaOpenPolicyP lsaOpenPolicy = (LsaOpenPolicyP)GetProcAddress(hModule, "LsaOpenPolicy");
+ if (lsaOpenPolicy == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ #endif
+
+ Close();
+ return
+ #ifdef _UNICODE
+ ::LsaOpenPolicy
+ #else
+ lsaOpenPolicy
+ #endif
+ (systemName, objectAttributes, desiredAccess, &_handle);
+ }
+
+ NTSTATUS Close()
+ {
+ if (_handle == NULL)
+ return 0;
+
+ #ifndef _UNICODE
+ if (hModule == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ LsaCloseP lsaClose = (LsaCloseP)GetProcAddress(hModule, "LsaClose");
+ if (lsaClose == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ #endif
+
+ NTSTATUS res =
+ #ifdef _UNICODE
+ ::LsaClose
+ #else
+ lsaClose
+ #endif
+ (_handle);
+ _handle = NULL;
+ return res;
+ }
+
+ NTSTATUS EnumerateAccountsWithUserRight(PLSA_UNICODE_STRING userRights,
+ PLSA_ENUMERATION_INFORMATION *enumerationBuffer, PULONG countReturned)
+ { return LsaEnumerateAccountsWithUserRight(_handle, userRights, (void **)enumerationBuffer, countReturned); }
+
+ NTSTATUS EnumerateAccountRights(PSID sid, PLSA_UNICODE_STRING* userRights, PULONG countOfRights)
+ { return ::LsaEnumerateAccountRights(_handle, sid, userRights, countOfRights); }
+
+ NTSTATUS LookupSids(ULONG count, PSID* sids,
+ PLSA_REFERENCED_DOMAIN_LIST* referencedDomains, PLSA_TRANSLATED_NAME* names)
+ { return LsaLookupSids(_handle, count, sids, referencedDomains, names); }
+
+ NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights, ULONG countOfRights)
+ {
+ #ifndef _UNICODE
+ if (hModule == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ LsaAddAccountRightsP lsaAddAccountRights = (LsaAddAccountRightsP)GetProcAddress(hModule, "LsaAddAccountRights");
+ if (lsaAddAccountRights == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ #endif
+
+ return
+ #ifdef _UNICODE
+ ::LsaAddAccountRights
+ #else
+ lsaAddAccountRights
+ #endif
+ (_handle, accountSid, userRights, countOfRights);
+ }
+ NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights)
+ { return AddAccountRights(accountSid, userRights, 1); }
+
+ NTSTATUS RemoveAccountRights(PSID accountSid, bool allRights, PLSA_UNICODE_STRING userRights, ULONG countOfRights)
+ { return LsaRemoveAccountRights(_handle, accountSid, (BOOLEAN)(allRights ? TRUE : FALSE), userRights, countOfRights); }
+};
+
+bool AddLockMemoryPrivilege();
+
+}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/StdAfx.h b/src/libs/7zip/win/CPP/Windows/StdAfx.h
index 8b383c5ba..1766dfa86 100644
--- a/src/libs/7zip/win/CPP/Windows/StdAfx.h
+++ b/src/libs/7zip/win/CPP/Windows/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../Common/MyWindows.h"
-#include "../Common/NewHandler.h"
+#include "../Common/Common.h"
#endif
diff --git a/src/libs/7zip/win/CPP/Windows/System.h b/src/libs/7zip/win/CPP/Windows/System.h
index e0067158f..4133a7b30 100644
--- a/src/libs/7zip/win/CPP/Windows/System.h
+++ b/src/libs/7zip/win/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/win/CPP/Windows/Thread.h b/src/libs/7zip/win/CPP/Windows/Thread.h
index 16a509d47..f9ecaed85 100644
--- a/src/libs/7zip/win/CPP/Windows/Thread.h
+++ b/src/libs/7zip/win/CPP/Windows/Thread.h
@@ -20,7 +20,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/win/CPP/Windows/Time.h b/src/libs/7zip/win/CPP/Windows/Time.h
deleted file mode 100644
index 6f510b22b..000000000
--- a/src/libs/7zip/win/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/win/CPP/Windows/TimeUtils.cpp b/src/libs/7zip/win/CPP/Windows/TimeUtils.cpp
new file mode 100644
index 000000000..7ef44d9cc
--- /dev/null
+++ b/src/libs/7zip/win/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/win/CPP/Windows/TimeUtils.h b/src/libs/7zip/win/CPP/Windows/TimeUtils.h
new file mode 100644
index 000000000..2967214e6
--- /dev/null
+++ b/src/libs/7zip/win/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/win/CPP/Windows/Windows.pri b/src/libs/7zip/win/CPP/Windows/Windows.pri
new file mode 100644
index 000000000..a69279060
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Windows.pri
@@ -0,0 +1,29 @@
+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/FileMapping.h \
+ $$7ZIP_BASE/CPP/Windows/FileName.h \
+ $$7ZIP_BASE/CPP/Windows/Handle.h \
+ $$7ZIP_BASE/CPP/Windows/PropVariant.h \
+ $$7ZIP_BASE/CPP/Windows/PropVariantConv.h \
+ $$7ZIP_BASE/CPP/Windows/SecurityUtils.h \
+ $$7ZIP_BASE/CPP/Windows/StdAfx.h \
+ $$7ZIP_BASE/CPP/Windows/Synchronization.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/FileLink.cpp \
+ $$7ZIP_BASE/CPP/Windows/FileName.cpp \
+ $$7ZIP_BASE/CPP/Windows/PropVariant.cpp \
+ $$7ZIP_BASE/CPP/Windows/PropVariantConv.cpp \
+ $$7ZIP_BASE/CPP/Windows/SecurityUtils.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/win/Methods.txt b/src/libs/7zip/win/Methods.txt
deleted file mode 100644
index f52e7c315..000000000
--- a/src/libs/7zip/win/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/win/history.txt b/src/libs/7zip/win/history.txt
deleted file mode 100644
index 79abd9cea..000000000
--- a/src/libs/7zip/win/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/win/lzma.txt b/src/libs/7zip/win/lzma.txt
deleted file mode 100644
index 659323237..000000000
--- a/src/libs/7zip/win/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/win/win.pri b/src/libs/7zip/win/win.pri
index 932c567fa..d29553cbd 100644
--- a/src/libs/7zip/win/win.pri
+++ b/src/libs/7zip/win/win.pri
@@ -1,131 +1,11 @@
-#$(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
-
-#$(WIN_OBJS): ../../../Windows/$(*B).cpp
-SOURCES += $$7ZIP_BASE/CPP/Windows/DLL.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/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
-
-!static:DEF_FILE += $$7ZIP_BASE/CPP/7zip/Archive/Archive.def
-!static:DEF_FILE += $$7ZIP_BASE/CPP/7zip/Archive/Archive2.def
-
-#$(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/7zCompressionMode.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
+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/Windows/Windows.pri)
diff --git a/src/libs/installer/adminauthorization_win.cpp b/src/libs/installer/adminauthorization_win.cpp
index 85b9586ad..59ff3efdb 100644
--- a/src/libs/installer/adminauthorization_win.cpp
+++ b/src/libs/installer/adminauthorization_win.cpp
@@ -111,14 +111,14 @@ bool AdminAuthorization::execute(QWidget *, const QString &program, const QStrin
shellExecuteInfo.lpParameters = (wchar_t *)args.utf16();
shellExecuteInfo.fMask = SEE_MASK_NOASYNC;
- qDebug() << QString::fromLatin1("Starting elevated process %1 with arguments: %2.").arg(file, args);
+ qDebug() << "Starting elevated process" << file << "with arguments" << args;
if (ShellExecuteExW(&shellExecuteInfo)) {
qDebug() << "Finished starting elevated process.";
return true;
} else {
- qWarning() << QString::fromLatin1("Error while starting elevated process: %1, "
- "Error: %2").arg(program, QInstaller::windowsErrorString(GetLastError()));
+ qWarning() << "Error while starting elevated process" << program
+ << ":" << QInstaller::windowsErrorString(GetLastError());
}
return false;
}
diff --git a/src/libs/installer/adminauthorization_x11.cpp b/src/libs/installer/adminauthorization_x11.cpp
index 97c6093ae..20eacf1cc 100644
--- a/src/libs/installer/adminauthorization_x11.cpp
+++ b/src/libs/installer/adminauthorization_x11.cpp
@@ -55,6 +55,7 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <errno.h>
#include <iostream>
@@ -130,10 +131,14 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
if (pipe(pipedData) != 0)
return false;
- int flags = ::fcntl(pipedData[0], F_GETFD);
+ int flags = ::fcntl(pipedData[0], F_GETFL);
if (flags != -1)
::fcntl(pipedData[0], F_SETFL, flags | O_NONBLOCK);
+ flags = ::fcntl(masterFD, F_GETFL);
+ if (flags != -1)
+ ::fcntl(masterFD, F_SETFL, flags | O_NONBLOCK);
+
pid_t child = fork();
if (child < -1) {
@@ -151,8 +156,8 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
::close(pipedData[1]);
QRegExp re(QLatin1String("[Pp]assword.*:"));
+ QByteArray data;
QByteArray errData;
- flags = ::fcntl(masterFD, F_GETFD);
int bytes = 0;
int errBytes = 0;
char buf[1024];
@@ -162,14 +167,18 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
if (::waitpid(child, &state, WNOHANG) == -1)
break;
bytes = ::read(masterFD, buf, 1023);
+ if (bytes == -1 && errno == EAGAIN)
+ bytes = 0;
+ else if (bytes > 0)
+ data.append(buf, bytes);
errBytes = ::read(pipedData[0], errBuf, 1023);
if (errBytes > 0)
{
- errData.append(buf, errBytes);
+ errData.append(errBuf, errBytes);
errBytes=0;
}
if (bytes > 0) {
- const QString line = QString::fromLatin1(buf, bytes);
+ const QString line = QString::fromLatin1(data);
if (re.indexIn(line) != -1) {
const QString password = getPassword(parent);
if (password.isEmpty()) {
diff --git a/src/libs/installer/binarycontent.cpp b/src/libs/installer/binarycontent.cpp
index 4396c2964..8daeafda9 100644
--- a/src/libs/installer/binarycontent.cpp
+++ b/src/libs/installer/binarycontent.cpp
@@ -118,7 +118,7 @@ BinaryLayout BinaryContent::binaryLayout(QFile *file, quint64 magicCookie)
const qint64 posOfMetaDataCount = layout.endOfBinaryContent - (4 * sizeof(qint64));
if (!file->seek(posOfMetaDataCount)) {
throw QInstaller::Error(QCoreApplication::translate("BinaryLayout",
- "Could not seek to %1 to read the embedded meta data count.").arg(posOfMetaDataCount));
+ "Cannot seek to %1 to read the embedded meta data count.").arg(posOfMetaDataCount));
}
// read the meta resources count
@@ -129,7 +129,7 @@ BinaryLayout BinaryContent::binaryLayout(QFile *file, quint64 magicCookie)
+ (8 * sizeof(qint64))); // meta count, offset/length collection index, marker, cookie...
if (!file->seek(posOfResourceCollectionsSegment)) {
throw Error(QCoreApplication::translate("BinaryLayout",
- "Could not seek to %1 to read the resource collection segment.")
+ "Cannot seek to %1 to read the resource collection segment.")
.arg(posOfResourceCollectionsSegment));
}
@@ -204,7 +204,7 @@ void BinaryContent::readBinaryContent(QFile *file, QList<OperationBlob> *operati
const qint64 posOfOperationsBlock = layout.operationsSegment.start();
if (!file->seek(posOfOperationsBlock)) {
throw Error(QCoreApplication::translate("BinaryContent",
- "Could not seek to %1 to read the operation data.").arg(posOfOperationsBlock));
+ "Cannot seek to %1 to read the operation data.").arg(posOfOperationsBlock));
}
// read the operations count
qint64 operationsCount = QInstaller::retrieveInt64(file);
@@ -221,7 +221,7 @@ void BinaryContent::readBinaryContent(QFile *file, QList<OperationBlob> *operati
if (manager) { // read the collection index and data
const qint64 posOfResourceCollectionBlock = layout.resourceCollectionsSegment.start();
if (!file->seek(posOfResourceCollectionBlock)) {
- throw Error(QCoreApplication::translate("BinaryContent", "Could not seek to %1 to "
+ throw Error(QCoreApplication::translate("BinaryContent", "Cannot seek to %1 to "
"read the resource collection block.").arg(posOfResourceCollectionBlock));
}
manager->read(file, layout.endOfExectuable);
@@ -260,7 +260,7 @@ void BinaryContent::writeBinaryContent(QFile *out, const QList<OperationBlob> &o
const bool isOpen = resource->isOpen();
if ((!isOpen) && (!resource->open())) {
throw Error(QCoreApplication::translate("BinaryContent",
- "Could not open meta resource. Error: %1").arg(resource->errorString()));
+ "Cannot open meta resource %1.").arg(resource->errorString()));
}
resource->seek(0);
diff --git a/src/libs/installer/binaryformat.cpp b/src/libs/installer/binaryformat.cpp
index b38f9799d..c8bc38304 100644
--- a/src/libs/installer/binaryformat.cpp
+++ b/src/libs/installer/binaryformat.cpp
@@ -169,7 +169,7 @@ bool Resource::open()
}
if (!QIODevice::open(QIODevice::ReadOnly)) {
- setErrorString(tr("Could not open Resource '%1' read-only.").arg(QString::fromUtf8(m_name)));
+ setErrorString(tr("Cannot open resource %1 for reading.").arg(QString::fromUtf8(m_name)));
return false;
}
return true;
@@ -397,7 +397,7 @@ Range<qint64> ResourceCollectionManager::write(QFileDevice *out, qint64 offset)
foreach (const QSharedPointer<Resource> &resource, collection.resources()) {
if (!resource->open()) {
- throw QInstaller::Error(tr("Could not open resource %1: %2")
+ throw QInstaller::Error(tr("Cannot open resource %1: %2")
.arg(QString::fromUtf8(resource->name()), resource->errorString()));
}
resource->copyData(out);
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index 5346aac77..07f526a21 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -43,8 +43,7 @@
#include "settings.h"
#include "utils.h"
-#include <kdupdaterupdatesourcesinfo.h>
-#include <kdupdaterupdateoperationfactory.h>
+#include "updateoperationfactory.h"
#include <productkeycheck.h>
@@ -64,13 +63,13 @@
using namespace QInstaller;
static const QLatin1String scScriptTag("Script");
-static const QLatin1String scAutoDependOn("AutoDependOn");
static const QLatin1String scVirtual("Virtual");
static const QLatin1String scInstalled("Installed");
static const QLatin1String scUpdateText("UpdateText");
static const QLatin1String scUninstalled("Uninstalled");
static const QLatin1String scCurrentState("CurrentState");
static const QLatin1String scForcedInstallation("ForcedInstallation");
+static const QLatin1String scCheckable("Checkable");
/*!
\inmodule QtInstallerFramework
@@ -216,7 +215,7 @@ Component::Component(PackageManagerCore *core)
{
setPrivate(d);
- connect(this, SIGNAL(valueChanged(QString, QString)), this, SLOT(updateModelData(QString, QString)));
+ connect(this, &Component::valueChanged, this, &Component::updateModelData);
qRegisterMetaType<QList<QInstaller::Component*> >("QList<QInstaller::Component*>");
}
@@ -245,10 +244,9 @@ Component::~Component()
/*!
Sets variables according to the values set in the package.xml file of a local \a package.
*/
-void Component::loadDataFromPackage(const LocalPackage &package)
+void Component::loadDataFromPackage(const KDUpdater::LocalPackage &package)
{
setValue(scName, package.name);
- // pixmap ???
setValue(scDisplayName, package.title);
setValue(scDescription, package.description);
setValue(scVersion, package.version);
@@ -257,14 +255,8 @@ void Component::loadDataFromPackage(const LocalPackage &package)
setValue(QLatin1String("LastUpdateDate"), package.lastUpdateDate.toString());
setValue(QLatin1String("InstallDate"), package.installDate.toString());
setValue(scUncompressedSize, QString::number(package.uncompressedSize));
-
- QString dependstr;
- foreach (const QString &val, package.dependencies)
- dependstr += val + QLatin1String(",");
-
- if (package.dependencies.count() > 0)
- dependstr.chop(1);
- setValue(scDependencies, dependstr);
+ setValue(scDependencies, package.dependencies.join(QLatin1String(",")));
+ setValue(scAutoDependOn, package.autoDependencies.join(QLatin1String(",")));
setValue(scForcedInstallation, package.forcedInstallation ? scTrue : scFalse);
if (package.forcedInstallation & !PackageManagerCore::noForceInstallation()) {
@@ -273,6 +265,7 @@ void Component::loadDataFromPackage(const LocalPackage &package)
}
setValue(scVirtual, package.virtualComp ? scTrue : scFalse);
setValue(scCurrentState, scInstalled);
+ setValue(scCheckable, package.checkable ? scTrue : scFalse);
}
/*!
@@ -290,7 +283,7 @@ void Component::loadDataFromPackage(const Package &package)
setValue(scAutoDependOn, package.data(scAutoDependOn).toString());
setValue(scCompressedSize, package.data(scCompressedSize).toString());
setValue(scUncompressedSize, package.data(scUncompressedSize).toString());
- setValue(scRemoteVersion, package.data(scRemoteVersion).toString());
+ setValue(scVersion, package.data(scVersion).toString());
setValue(scInheritVersion, package.data(scInheritVersion).toString());
setValue(scDependencies, package.data(scDependencies).toString());
setValue(scDownloadableArchives, package.data(scDownloadableArchives).toString());
@@ -305,6 +298,7 @@ void Component::loadDataFromPackage(const Package &package)
setValue(scScriptTag, package.data(scScriptTag).toString());
setValue(scReplaces, package.data(scReplaces).toString());
setValue(scReleaseDate, package.data(scReleaseDate).toString());
+ setValue(scCheckable, package.data(scCheckable).toString());
QString forced = package.data(scForcedInstallation, scFalse).toString().toLower();
if (PackageManagerCore::noForceInstallation())
@@ -315,7 +309,7 @@ void Component::loadDataFromPackage(const Package &package)
setCheckState(Qt::Checked);
}
- setLocalTempPath(QInstaller::pathFromUrl(package.sourceInfoUrl()));
+ setLocalTempPath(QInstaller::pathFromUrl(package.packageSource().url));
const QStringList uis = package.data(QLatin1String("UserInterfaces")).toString()
.split(QInstaller::commaRegExp(), QString::SkipEmptyParts);
if (!uis.isEmpty())
@@ -396,6 +390,8 @@ void Component::setValue(const QString &key, const QString &value)
if (key == scName)
d->m_componentName = normalizedValue;
+ if (key == scCheckable)
+ this->setCheckable(normalizedValue.toLower() == scTrue);
d->m_vars[key] = normalizedValue;
emit valueChanged(key, normalizedValue);
@@ -578,8 +574,8 @@ void Component::loadUserInterfaces(const QDir &directory, const QStringList &uis
while (it.hasNext()) {
QFile file(it.next());
if (!file.open(QIODevice::ReadOnly)) {
- throw Error(tr("Could not open the requested UI file '%1'. Error: %2").arg(it.fileName(),
- file.errorString()));
+ throw Error(tr("Cannot open the requested UI file \"%1\": %2").arg(
+ it.fileName(), file.errorString()));
}
static QUiLoader loader;
@@ -587,8 +583,8 @@ void Component::loadUserInterfaces(const QDir &directory, const QStringList &uis
loader.setLanguageChangeEnabled(true);
QWidget *const widget = loader.load(&file, 0);
if (!widget) {
- throw Error(tr("Could not load the requested UI file '%1'. Error: %2").arg(it.fileName(),
- loader.errorString()));
+ throw Error(tr("Cannot load the requested UI file \"%1\": %2").arg(
+ it.fileName(), loader.errorString()));
}
d->scriptEngine()->newQObject(widget);
d->m_userInterfaces.insert(widget->objectName(), widget);
@@ -632,7 +628,7 @@ void Component::loadLicenses(const QString &directory, const QHash<QString, QVar
QFile file(fileInfo.filePath());
if (!file.open(QIODevice::ReadOnly)) {
- throw Error(tr("Could not open the requested license file '%1'. Error: %2").arg(
+ throw Error(tr("Cannot open the requested license file \"%1\": %2").arg(
file.fileName(), file.errorString()));
}
QTextStream stream(&file);
@@ -831,7 +827,7 @@ void Component::addDownloadableArchive(const QString &path)
Q_ASSERT(isFromOnlineRepository());
qDebug() << "addDownloadable" << path;
- d->m_downloadableArchives.append(d->m_vars.value(scRemoteVersion) + path);
+ d->m_downloadableArchives.append(d->m_vars.value(scVersion) + path);
}
/*!
@@ -910,15 +906,14 @@ OperationList Component::operations() const
if (!d->m_minimumProgressOperation) {
d->m_minimumProgressOperation = KDUpdater::UpdateOperationFactory::instance()
- .create(QLatin1String("MinimumProgress"));
+ .create(QLatin1String("MinimumProgress"), d->m_core);
d->m_minimumProgressOperation->setValue(QLatin1String("component"), name());
d->m_operations.append(d->m_minimumProgressOperation);
}
if (!d->m_licenses.isEmpty()) {
d->m_licenseOperation = KDUpdater::UpdateOperationFactory::instance()
- .create(QLatin1String("License"));
- d->m_licenseOperation->setValue(QLatin1String("installer"), QVariant::fromValue(d->m_core));
+ .create(QLatin1String("License"), d->m_core);
d->m_licenseOperation->setValue(QLatin1String("component"), name());
QVariantMap licenses;
@@ -992,11 +987,12 @@ Operation *Component::createOperation(const QString &operationName, const QStrin
Operation *Component::createOperation(const QString &operationName, const QStringList &parameters)
{
- Operation *operation = KDUpdater::UpdateOperationFactory::instance().create(operationName);
+ Operation *operation = KDUpdater::UpdateOperationFactory::instance().create(operationName,
+ d->m_core);
if (operation == 0) {
const QMessageBox::StandardButton button =
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
- QLatin1String("OperationDoesNotExistError"), tr("Error"), tr("Error: Operation %1 does not exist")
+ QLatin1String("OperationDoesNotExistError"), tr("Error"), tr("Error: Operation %1 does not exist.")
.arg(operationName), QMessageBox::Abort | QMessageBox::Ignore);
if (button == QMessageBox::Abort)
d->m_operationsCreatedSuccessfully = false;
@@ -1005,7 +1001,6 @@ Operation *Component::createOperation(const QString &operationName, const QStrin
if (operation->name() == QLatin1String("Delete"))
operation->setValue(QLatin1String("performUndo"), false);
- operation->setValue(QLatin1String("installer"), qVariantFromValue(d->m_core));
operation->setArguments(d->m_core->replaceVariables(parameters));
operation->setValue(QLatin1String("component"), name());
diff --git a/src/libs/installer/component.h b/src/libs/installer/component.h
index a075a0145..395bf90dd 100644
--- a/src/libs/installer/component.h
+++ b/src/libs/installer/component.h
@@ -46,11 +46,6 @@
QT_FORWARD_DECLARE_CLASS(QDebug)
QT_FORWARD_DECLARE_CLASS(QQmlV4Function)
-namespace KDUpdater {
- class Update;
- struct PackageInfo;
-}
-
namespace QInstaller {
class PackageManagerCore;
@@ -94,7 +89,7 @@ public:
};
void loadDataFromPackage(const Package &package);
- void loadDataFromPackage(const LocalPackage &package);
+ void loadDataFromPackage(const KDUpdater::LocalPackage &package);
QHash<QString, QString> variables() const;
Q_INVOKABLE void setValue(const QString &key, const QString &value);
diff --git a/src/libs/installer/componentchecker.cpp b/src/libs/installer/componentchecker.cpp
index 8dbcab42b..f95d856a8 100644
--- a/src/libs/installer/componentchecker.cpp
+++ b/src/libs/installer/componentchecker.cpp
@@ -50,6 +50,12 @@ QStringList ComponentChecker::checkComponent(Component *component)
if (!core)
return checkResult;
+ if (component->childCount() && !component->archives().isEmpty()) {
+ checkResult << QString::fromLatin1("Component %1 contains data to be installed "
+ "while having child components. This may not work properly.")
+ .arg(component->name());
+ }
+
const bool defaultPropertyScriptValue = component->variables().value(scDefault).compare(scScript, Qt::CaseInsensitive) == 0;
const bool defaultPropertyValue = component->variables().value(scDefault).compare(scTrue, Qt::CaseInsensitive) == 0;
const QStringList autoDependencies = component->autoDependencies();
@@ -127,13 +133,13 @@ QStringList ComponentChecker::checkComponent(Component *component)
Moreover, the "Next" button will be disabled.
*/
checkResult << QString::fromLatin1("Component %1 auto depends on other components "
- "while having children components. This will not work properly.")
+ "while having child components. This will not work properly.")
.arg(component->name());
}
if (!component->dependencies().isEmpty()) {
checkResult << QString::fromLatin1("Component %1 depends on other components "
- "while having children components. This will not work properly.")
+ "while having child components. This will not work properly.")
.arg(component->name());
}
@@ -153,7 +159,7 @@ QStringList ComponentChecker::checkComponent(Component *component)
Moreover, the "Next" button will be disabled.
*/
checkResult << QString::fromLatin1("Other components depend on component %1 "
- "which has children components. This will not work properly.")
+ "which has child components. This will not work properly.")
.arg(component->name());
}
}
diff --git a/src/libs/installer/componentmodel.cpp b/src/libs/installer/componentmodel.cpp
index 65d907d00..adcda4db5 100644
--- a/src/libs/installer/componentmodel.cpp
+++ b/src/libs/installer/componentmodel.cpp
@@ -82,6 +82,10 @@ class IconCache
{
public:
IconCache() {
+ m_icons.insert(ComponentModelHelper::Install, QIcon(QLatin1String(":/install.png")));
+ m_icons.insert(ComponentModelHelper::Uninstall, QIcon(QLatin1String(":/uninstall.png")));
+ m_icons.insert(ComponentModelHelper::KeepInstalled, QIcon(QLatin1String(":/keepinstalled.png")));
+ m_icons.insert(ComponentModelHelper::KeepUninstalled, QIcon(QLatin1String(":/keepuninstalled.png")));
}
QIcon icon(ComponentModelHelper::InstallAction action) const {
@@ -102,7 +106,7 @@ ComponentModel::ComponentModel(int columns, PackageManagerCore *core)
, m_modelState(DefaultChecked)
{
m_headerData.insert(0, columns, QVariant());
- connect(this, SIGNAL(modelReset()), this, SLOT(slotModelReset()));
+ connect(this, &QAbstractItemModel::modelReset, this, &ComponentModel::slotModelReset);
}
/*!
@@ -408,7 +412,7 @@ void ComponentModel::setRootComponents(QList<QInstaller::Component*> rootCompone
// show virtual components only in case we run as updater or if the core engine is set to show them
const bool showVirtuals = m_core->isUpdater() || m_core->virtualComponentsVisible();
foreach (Component *const component, rootComponents) {
- connect(component, SIGNAL(virtualStateChanged()), this, SLOT(onVirtualStateChanged()));
+ connect(component, &Component::virtualStateChanged, this, &ComponentModel::onVirtualStateChanged);
if ((!showVirtuals) && component->isVirtual())
continue;
m_rootComponentList.append(component);
@@ -468,7 +472,7 @@ void ComponentModel::slotModelReset()
foreach (Component *const component, components) {
if (component->checkState() == Qt::Checked)
checked.insert(component);
- connect(component, SIGNAL(virtualStateChanged()), this, SLOT(onVirtualStateChanged()));
+ connect(component, &Component::virtualStateChanged, this, &ComponentModel::onVirtualStateChanged);
}
updateCheckedState(checked, Qt::Checked);
diff --git a/src/libs/installer/constants.h b/src/libs/installer/constants.h
index e48a22c02..1cba6d572 100644
--- a/src/libs/installer/constants.h
+++ b/src/libs/installer/constants.h
@@ -46,7 +46,6 @@ static const QLatin1String scScript("script");
static const QLatin1String scName("Name");
static const QLatin1String scVersion("Version");
static const QLatin1String scDefault("Default");
-static const QLatin1String scRemoteVersion("Version");
static const QLatin1String scDisplayVersion("DisplayVersion");
static const QLatin1String scRemoteDisplayVersion("RemoteDisplayVersion");
static const QLatin1String scInheritVersion("inheritVersionFrom");
@@ -58,6 +57,7 @@ static const QLatin1String scReleaseDate("ReleaseDate");
static const QLatin1String scDescription("Description");
static const QLatin1String scDisplayName("DisplayName");
static const QLatin1String scDependencies("Dependencies");
+static const QLatin1String scAutoDependOn("AutoDependOn");
static const QLatin1String scNewComponent("NewComponent");
static const QLatin1String scRepositories("Repositories");
static const QLatin1String scCompressedSize("CompressedSize");
@@ -69,6 +69,7 @@ static const QLatin1String scRequiresAdminRights("RequiresAdminRights");
// constants used throughout the components class
static const QLatin1String scVirtual("Virtual");
static const QLatin1String scSortingPriority("SortingPriority");
+static const QLatin1String scCheckable("Checkable");
// constants used throughout the settings and package manager core class
static const QLatin1String scTitle("Title");
@@ -83,10 +84,16 @@ static const QLatin1String scAllowNonAsciiCharacters("AllowNonAsciiCharacters");
static const QLatin1String scRepositorySettingsPageVisible("RepositorySettingsPageVisible");
static const QLatin1String scAllowSpaceInPath("AllowSpaceInPath");
static const QLatin1String scWizardStyle("WizardStyle");
+static const QLatin1String scStyleSheet("StyleSheet");
static const QLatin1String scTitleColor("TitleColor");
static const QLatin1String scWizardDefaultWidth("WizardDefaultWidth");
static const QLatin1String scWizardDefaultHeight("WizardDefaultHeight");
+static const QLatin1String scUrlQueryString("UrlQueryString");
static const QLatin1String scProductUUID("ProductUUID");
+static const QLatin1String scAllUsers("AllUsers");
+
+const char scRelocatable[] = "@RELOCATABLE_PATH@";
+
}
#endif // CONSTANTS_H
diff --git a/src/libs/installer/consumeoutputoperation.cpp b/src/libs/installer/consumeoutputoperation.cpp
index 497af969a..d7aa6b49f 100644
--- a/src/libs/installer/consumeoutputoperation.cpp
+++ b/src/libs/installer/consumeoutputoperation.cpp
@@ -42,7 +42,8 @@
using namespace QInstaller;
-ConsumeOutputOperation::ConsumeOutputOperation()
+ConsumeOutputOperation::ConsumeOutputOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("ConsumeOutput"));
}
@@ -58,15 +59,12 @@ bool ConsumeOutputOperation::performOperation()
// 2. executable path
// 3. argument for the executable
// 4. more arguments possible ...
- if (arguments().count() < 3) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.").arg(name()).arg(
- arguments().count()).arg(tr("at least 2"), QLatin1String("(<to be saved installer key name>, "
- "<executable>, [argument1], [argument2], ...)")));
+
+ if (!checkArgumentCount(2, INT_MAX, tr("<to be saved installer key name> "
+ "<executable> [argument1] [argument2] [...]")))
return false;
- }
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ PackageManagerCore *const core = packageManager();
if (!core) {
setError(UserDefinedError);
setErrorString(tr("Needed installer object in %1 operation is empty.").arg(name()));
@@ -76,8 +74,8 @@ bool ConsumeOutputOperation::performOperation()
const QString installerKeyName = arguments().at(0);
if (installerKeyName.isEmpty()) {
setError(UserDefinedError);
- setErrorString(tr("Can not save the output of %1 to an empty installer key value.").arg(
- arguments().at(1)));
+ setErrorString(tr("Cannot save the output of \"%1\" to an empty installer key value.").arg(
+ QDir::toNativeSeparators(arguments().at(1))));
return false;
}
@@ -90,7 +88,7 @@ bool ConsumeOutputOperation::performOperation()
if (!executable.exists() || !executable.isExecutable()) {
setError(UserDefinedError);
- setErrorString(tr("File '%1' does not exist or is not an executable binary.").arg(
+ setErrorString(tr("File \"%1\" does not exist or is not an executable binary.").arg(
QDir::toNativeSeparators(executable.absoluteFilePath())));
return false;
}
@@ -111,7 +109,7 @@ bool ConsumeOutputOperation::performOperation()
<< "standard output: " << process.readAllStandardOutput()
<< "error output: " << process.readAllStandardError();
setError(UserDefinedError);
- setErrorString(tr("Running '%1' resulted in a crash.").arg(
+ setErrorString(tr("Running \"%1\" resulted in a crash.").arg(
QDir::toNativeSeparators(executable.absoluteFilePath())));
return false;
}
@@ -129,8 +127,7 @@ bool ConsumeOutputOperation::performOperation()
}
if (executableOutput.isEmpty()) {
- qWarning() << QString::fromLatin1("Cannot get any query output from executable: '%1'").arg(
- executable.absoluteFilePath());
+ qWarning() << "Cannot get any query output from executable" << executable.absoluteFilePath();
}
core->setValue(installerKeyName, QString::fromLocal8Bit(executableOutput));
return true;
@@ -145,9 +142,3 @@ bool ConsumeOutputOperation::testOperation()
{
return true;
}
-
-Operation *ConsumeOutputOperation::clone() const
-{
- return new ConsumeOutputOperation();
-}
-
diff --git a/src/libs/installer/consumeoutputoperation.h b/src/libs/installer/consumeoutputoperation.h
index f9f59dd58..067d79d65 100644
--- a/src/libs/installer/consumeoutputoperation.h
+++ b/src/libs/installer/consumeoutputoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT ConsumeOutputOperation : public Operation
{
public:
- ConsumeOutputOperation();
+ explicit ConsumeOutputOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
private:
};
diff --git a/src/libs/installer/copydirectoryoperation.cpp b/src/libs/installer/copydirectoryoperation.cpp
index 0a1fe6dca..afe85ca28 100644
--- a/src/libs/installer/copydirectoryoperation.cpp
+++ b/src/libs/installer/copydirectoryoperation.cpp
@@ -51,7 +51,8 @@ public:
};
-CopyDirectoryOperation::CopyDirectoryOperation()
+CopyDirectoryOperation::CopyDirectoryOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("CopyDirectory"));
}
@@ -62,13 +63,10 @@ void CopyDirectoryOperation::backup()
bool CopyDirectoryOperation::performOperation()
{
- const QStringList args = arguments();
- if (args.count() < 2 || args.count() > 3) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("2 or 3"), tr(" (<source> <target> [forceOverwrite])")));
+ if (!checkArgumentCount(2, 3, tr("<source> <target> [\"forceOverwrite\"]")))
return false;
- }
+
+ const QStringList args = arguments();
const QString sourcePath = args.at(0);
const QString targetPath = args.at(1);
bool overwrite = false;
@@ -79,19 +77,22 @@ bool CopyDirectoryOperation::performOperation()
overwrite = true;
} else {
setError(InvalidArguments);
- setErrorString(tr("Invalid argument in %0: Third argument needs to be forceOverwrite, "
- "if specified").arg(name()));
+ setErrorString(tr("Invalid argument in %1: Third argument needs to be forceOverwrite, "
+ "if specified.").arg(name()));
return false;
}
}
const QFileInfo sourceInfo(sourcePath);
const QFileInfo targetInfo(targetPath);
- if (!sourceInfo.exists() || !sourceInfo.isDir() || !targetInfo.exists() || !targetInfo.isDir()) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: Directories are invalid: %1 %2").arg(name())
- .arg(sourcePath).arg(targetPath));
- return false;
+
+ foreach (const QFileInfo &dir, QList<QFileInfo>() << sourceInfo << targetInfo) {
+ if (!dir.exists() || !dir.isDir()) {
+ setError(InvalidArguments);
+ setErrorString(tr("Invalid argument in %1: Directory \"%2\" is invalid.").arg(name())
+ .arg(QDir::toNativeSeparators(sourcePath)));
+ return false;
+ }
}
const QDir sourceDir = sourceInfo.absoluteDir();
@@ -122,22 +123,24 @@ bool CopyDirectoryOperation::performOperation()
} else if (itemInfo.isDir()) {
if (!targetDir.mkpath(targetDir.absoluteFilePath(relativePath))) {
setError(InvalidArguments);
- setErrorString(tr("Could not create %0").arg(targetDir.absoluteFilePath(relativePath)));
+ setErrorString(tr("Cannot create directory \"%1\".").arg(
+ QDir::toNativeSeparators(targetDir.absoluteFilePath(relativePath))));
return false;
}
} else {
const QString absolutePath = targetDir.absoluteFilePath(relativePath);
if (overwrite && QFile::exists(absolutePath) && !deleteFileNowOrLater(absolutePath)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to overwrite %1").arg(absolutePath));
+ setErrorString(tr("Failed to overwrite \"%1\".").arg(QDir::toNativeSeparators(absolutePath)));
return false;
}
QFile file(sourceDir.absoluteFilePath(itemName));
if (!file.copy(absolutePath)) {
setError(UserDefinedError);
- setErrorString(tr("Could not copy %0 to %1, error was: %3").arg(sourceDir.absoluteFilePath(itemName),
- targetDir.absoluteFilePath(relativePath),
- file.errorString()));
+ setErrorString(tr("Cannot copy file \"%1\" to \"%2\": %3").arg(
+ QDir::toNativeSeparators(sourceDir.absoluteFilePath(itemName)),
+ QDir::toNativeSeparators(targetDir.absoluteFilePath(relativePath)),
+ file.errorString()));
return false;
}
autoPush.m_files.prepend(targetDir.absoluteFilePath(relativePath));
@@ -156,7 +159,7 @@ bool CopyDirectoryOperation::undoOperation()
foreach (const QString &file, files) {
if (!QFile::remove(file)) {
setError(InvalidArguments);
- setErrorString(tr("Could not remove %0").arg(file));
+ setErrorString(tr("Cannot remove file \"%1\".").arg(QDir::toNativeSeparators(file)));
return false;
}
dir.rmpath(QFileInfo(file).absolutePath());
@@ -171,8 +174,3 @@ bool CopyDirectoryOperation::testOperation()
{
return true;
}
-
-Operation *CopyDirectoryOperation::clone() const
-{
- return new CopyDirectoryOperation();
-}
diff --git a/src/libs/installer/copydirectoryoperation.h b/src/libs/installer/copydirectoryoperation.h
index 18467b21a..7df3a4b60 100644
--- a/src/libs/installer/copydirectoryoperation.h
+++ b/src/libs/installer/copydirectoryoperation.h
@@ -45,13 +45,12 @@ class INSTALLER_EXPORT CopyDirectoryOperation : public QObject, public Operation
Q_OBJECT
public:
- CopyDirectoryOperation();
+ explicit CopyDirectoryOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
Q_SIGNALS:
void outputTextChanged(const QString &progress);
diff --git a/src/libs/installer/copyfiletask.cpp b/src/libs/installer/copyfiletask.cpp
index 327162637..a189a77bb 100644
--- a/src/libs/installer/copyfiletask.cpp
+++ b/src/libs/installer/copyfiletask.cpp
@@ -33,6 +33,7 @@
#include "copyfiletask.h"
#include "observer.h"
+#include <QDir>
#include <QFileInfo>
#include <QTemporaryFile>
@@ -68,8 +69,8 @@ void CopyFileTask::doTask(QFutureInterface<FileTaskResult> &fi)
QFile source(item.source());
if (!source.open(QIODevice::ReadOnly)) {
- fi.reportException(TaskException(tr("Could not open source '%1' for read. Error: %2.")
- .arg(source.fileName(), source.errorString())));
+ fi.reportException(TaskException(tr("Cannot open file \"%1\" for reading: %2")
+ .arg(QDir::toNativeSeparators(source.fileName()), source.errorString())));
fi.reportFinished(); return; // error
}
observer.setBytesToTransfer(source.size());
@@ -84,8 +85,8 @@ void CopyFileTask::doTask(QFutureInterface<FileTaskResult> &fi)
file.reset(new QFile(target));
}
if (!file->open(QIODevice::WriteOnly | QIODevice::Truncate)) {
- fi.reportException(TaskException(tr("Could not open target '%1' for write. Error: %2.")
- .arg(file->fileName(), file->errorString())));
+ fi.reportException(TaskException(tr("Cannot open file \"%1\" for writing: %2")
+ .arg(QDir::toNativeSeparators(file->fileName()), file->errorString())));
fi.reportFinished(); return; // error
}
@@ -101,8 +102,8 @@ void CopyFileTask::doTask(QFutureInterface<FileTaskResult> &fi)
while (written < read) {
const qint64 toWrite = file->write(buffer.constData() + written, read - written);
if (toWrite < 0) {
- fi.reportException(TaskException(tr("Writing to target '%1' failed. Error: %2.")
- .arg(file->fileName(), file->errorString())));
+ fi.reportException(TaskException(tr("Writing to file \"%1\" failed: %2")
+ .arg(QDir::toNativeSeparators(file->fileName()), file->errorString())));
}
written += toWrite;
}
diff --git a/src/libs/installer/createdesktopentryoperation.cpp b/src/libs/installer/createdesktopentryoperation.cpp
index 956060e61..ebe7f7ab3 100644
--- a/src/libs/installer/createdesktopentryoperation.cpp
+++ b/src/libs/installer/createdesktopentryoperation.cpp
@@ -96,7 +96,8 @@ QString CreateDesktopEntryOperation::absoluteFileName()
return QDir(directory).absoluteFilePath(filename);
}
-CreateDesktopEntryOperation::CreateDesktopEntryOperation()
+CreateDesktopEntryOperation::CreateDesktopEntryOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("CreateDesktopEntry"));
}
@@ -121,32 +122,27 @@ void CreateDesktopEntryOperation::backup()
}
if (!file.copy(value(QLatin1String("backupOfExistingDesktopEntry")).toString()))
- setErrorString(tr("Could not backup file %1: %2").arg(filename, file.errorString()));
+ setErrorString(tr("Cannot backup file \"%1\": %2").arg(QDir::toNativeSeparators(filename), file.errorString()));
}
bool CreateDesktopEntryOperation::performOperation()
{
- const QStringList args = arguments();
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 2"), QLatin1String("")));
+ if (!checkArgumentCount(2))
return false;
- }
const QString filename = absoluteFileName();
- const QString &values = args[1];
+ const QString &values = arguments().at(1);
QFile file(filename);
if (file.exists() && !file.remove()) {
setError(UserDefinedError);
- setErrorString(tr("Failed to overwrite %1").arg(filename));
+ setErrorString(tr("Failed to overwrite file \"%1\".").arg(QDir::toNativeSeparators(filename)));
return false;
}
if(!file.open(QIODevice::WriteOnly)) {
setError(UserDefinedError);
- setErrorString(tr("Could not write Desktop Entry at %1").arg(filename));
+ setErrorString(tr("Cannot write desktop entry to \"%1\".").arg(QDir::toNativeSeparators(filename)));
return false;
}
@@ -172,7 +168,7 @@ bool CreateDesktopEntryOperation::undoOperation()
// first remove the link
QFile file(filename);
if (file.exists() && !file.remove()) {
- qWarning() << "Could not delete file" << filename << file.errorString();
+ qWarning() << "Cannot delete file" << filename << ":" << file.errorString();
return true;
}
@@ -182,13 +178,13 @@ bool CreateDesktopEntryOperation::undoOperation()
QFile backupFile(value(QLatin1String("backupOfExistingDesktopEntry")).toString());
if (!backupFile.exists()) {
// do not treat this as a real error: The backup file might have been just nuked by the user.
- qWarning() << "Could not restore original desktop entry at" << filename
+ qWarning() << "Cannot restore original desktop entry at" << filename
<< ": Backup file" << backupFile.fileName() << "does not exist anymore.";
return true;
}
if (!backupFile.rename(filename))
- qWarning() << "Could not restore the file" << filename << ":" << backupFile.errorString();
+ qWarning() << "Cannot restore the file" << filename << ":" << backupFile.errorString();
return true;
}
@@ -197,8 +193,3 @@ bool CreateDesktopEntryOperation::testOperation()
{
return true;
}
-
-Operation *CreateDesktopEntryOperation::clone() const
-{
- return new CreateDesktopEntryOperation();
-}
diff --git a/src/libs/installer/createdesktopentryoperation.h b/src/libs/installer/createdesktopentryoperation.h
index 74f942739..c70fe0968 100644
--- a/src/libs/installer/createdesktopentryoperation.h
+++ b/src/libs/installer/createdesktopentryoperation.h
@@ -41,14 +41,13 @@ namespace QInstaller {
class INSTALLER_EXPORT CreateDesktopEntryOperation : public Operation
{
public:
- CreateDesktopEntryOperation();
+ explicit CreateDesktopEntryOperation(PackageManagerCore *core);
~CreateDesktopEntryOperation();
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation* clone() const;
QString absoluteFileName();
};
diff --git a/src/libs/installer/createlinkoperation.cpp b/src/libs/installer/createlinkoperation.cpp
index dac579a1b..0f329693d 100644
--- a/src/libs/installer/createlinkoperation.cpp
+++ b/src/libs/installer/createlinkoperation.cpp
@@ -34,11 +34,13 @@
#include "link.h"
+#include <QDir>
#include <QFileInfo>
using namespace QInstaller;
-CreateLinkOperation::CreateLinkOperation()
+CreateLinkOperation::CreateLinkOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("CreateLink"));
}
@@ -49,22 +51,18 @@ void CreateLinkOperation::backup()
bool CreateLinkOperation::performOperation()
{
- QStringList args = arguments();
-
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 2"), QLatin1String("")));
+ if (!checkArgumentCount(2))
return false;
- }
+ const QStringList args = arguments();
const QString& linkPath = args.at(0);
const QString& targetPath = args.at(1);
Link link = Link::create(linkPath, targetPath);
if (!link.exists()) {
setError(UserDefinedError);
- setErrorString(tr("Could not create link from %1 to %2.").arg(linkPath, targetPath));
+ setErrorString(tr("Cannot create link from \"%1\" to \"%2\".").arg(
+ QDir::toNativeSeparators(linkPath), QDir::toNativeSeparators(targetPath)));
return false;
}
@@ -84,7 +82,8 @@ bool CreateLinkOperation::undoOperation()
}
if (!link.remove()) {
setError(UserDefinedError);
- setErrorString(tr("Could not remove link from %1 to %2.").arg(linkPath, targetPath));
+ setErrorString(tr("Cannot remove link from \"%1\" to \"%2\".").arg(
+ QDir::toNativeSeparators(linkPath), QDir::toNativeSeparators(targetPath)));
return false;
}
@@ -95,8 +94,3 @@ bool CreateLinkOperation::testOperation()
{
return true;
}
-
-Operation *CreateLinkOperation::clone() const
-{
- return new CreateLinkOperation();
-}
diff --git a/src/libs/installer/createlinkoperation.h b/src/libs/installer/createlinkoperation.h
index 2095638ca..15787c5ab 100644
--- a/src/libs/installer/createlinkoperation.h
+++ b/src/libs/installer/createlinkoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT CreateLinkOperation : public Operation
{
public:
- CreateLinkOperation();
+ explicit CreateLinkOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
}
diff --git a/src/libs/installer/createlocalrepositoryoperation.cpp b/src/libs/installer/createlocalrepositoryoperation.cpp
index 5068e26dd..6bcac3cb6 100644
--- a/src/libs/installer/createlocalrepositoryoperation.cpp
+++ b/src/libs/installer/createlocalrepositoryoperation.cpp
@@ -39,11 +39,12 @@
#include "fileio.h"
#include "fileutils.h"
#include "copydirectoryoperation.h"
+#include "lib7z_create.h"
#include "lib7z_facade.h"
#include "packagemanagercore.h"
#include "productkeycheck.h"
-#include "kdupdaterupdateoperations.h"
+#include "updateoperations.h"
#include <QtCore/QDir>
#include <QtCore/QDirIterator>
@@ -87,8 +88,8 @@ static void fixPermissions(const QString &repoPath)
if (!QFile::setPermissions(it.filePath(), QFile::ReadOwner | QFile::WriteOwner
| QFile::ReadUser | QFile::WriteUser | QFile::ReadGroup | QFile::ReadOther)) {
- throw Error(CreateLocalRepositoryOperation::tr("Could not set file permissions %1!")
- .arg(it.filePath()));
+ throw Error(CreateLocalRepositoryOperation::tr("Cannot set permissions for file \"%1\".")
+ .arg(QDir::toNativeSeparators(it.filePath())));
}
}
}
@@ -108,8 +109,8 @@ static void removeFiles(const QString &path, AutoHelper *const helper)
if (fi.isSymLink() || fi.isFile()) {
QFile f(fi.filePath());
if (!f.remove()) {
- throw Error(CreateLocalRepositoryOperation::tr("Could not remove file %1: %2")
- .arg(f.fileName(), f.errorString()));
+ throw Error(CreateLocalRepositoryOperation::tr("Cannot remove file \"%1\": %2")
+ .arg(QDir::toNativeSeparators(f.fileName()), f.errorString()));
}
helper->m_files.removeAll(f.fileName());
}
@@ -126,8 +127,9 @@ static QString createArchive(const QString repoPath, const QString &sourceDir, c
Lib7z::createArchive(&archive, QStringList() << sourceDir);
removeFiles(sourceDir, helper); // cleanup the files we compressed
if (!archive.rename(sourceDir + fileName)) {
- throw Error(CreateLocalRepositoryOperation::tr("Could not move file %1 to %2. Error: %3")
- .arg(archive.fileName(), sourceDir + fileName, archive.errorString()));
+ throw Error(CreateLocalRepositoryOperation::tr("Cannot move file \"%1\" to \"%2\": %3")
+ .arg(QDir::toNativeSeparators(archive.fileName()),
+ QDir::toNativeSeparators(sourceDir + fileName), archive.errorString()));
}
return archive.fileName();
}
@@ -137,7 +139,8 @@ static QString createArchive(const QString repoPath, const QString &sourceDir, c
// -- CreateLocalRepositoryOperation
-CreateLocalRepositoryOperation::CreateLocalRepositoryOperation()
+CreateLocalRepositoryOperation::CreateLocalRepositoryOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("CreateLocalRepository"));
}
@@ -151,24 +154,20 @@ bool CreateLocalRepositoryOperation::performOperation()
AutoHelper helper(this);
emit progressChanged(0.0);
- const QStringList args = arguments();
-
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 2"), QLatin1String("")));
+ if (!checkArgumentCount(2))
return false;
- }
try {
+ const QStringList args = arguments();
+
const QString binaryPath = QFileInfo(args.at(0)).absoluteFilePath();
// Note the "/" at the end, important to make copy directory operation behave well
const QString repoPath = QFileInfo(args.at(1)).absoluteFilePath() + QLatin1Char('/');
// check if this is an offline version, otherwise there will be no binary data
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ PackageManagerCore *const core = packageManager();
if (core && !core->isOfflineOnly()) {
- throw QInstaller::Error(tr("Installer needs to be an offline version: %1.")
+ throw QInstaller::Error(tr("Installer at \"%1\" needs to be an offline one.")
.arg(QDir::toNativeSeparators(binaryPath)));
}
@@ -190,9 +189,10 @@ bool CreateLocalRepositoryOperation::performOperation()
setValue(QLatin1String("createddir"), mkDirOp.value(QLatin1String("createddir")));
// copy the whole meta data into local repository
- CopyDirectoryOperation copyDirOp;
+ CopyDirectoryOperation copyDirOp(core);
copyDirOp.setArguments(QStringList() << QLatin1String(":/metadata/") << repoPath);
- connect(&copyDirOp, SIGNAL(outputTextChanged(QString)), this, SIGNAL(outputTextChanged(QString)));
+ connect(&copyDirOp, &CopyDirectoryOperation::outputTextChanged,
+ this, &CreateLocalRepositoryOperation::outputTextChanged);
const bool success = copyDirOp.performOperation();
helper.m_files = copyDirOp.value(QLatin1String("files")).toStringList();
@@ -211,13 +211,15 @@ bool CreateLocalRepositoryOperation::performOperation()
// open the updates xml file we previously copied
QFile updatesXml(repoPath + QLatin1String("Updates.xml"));
if (!updatesXml.exists() || !updatesXml.open(QIODevice::ReadOnly))
- throw QInstaller::Error(tr("Could not open file: %1").arg(updatesXml.fileName()));
+ throw QInstaller::Error(tr("Cannot open file \"%1\" for reading.").arg(
+ QDir::toNativeSeparators(updatesXml.fileName())));
// read the content of the updates xml
QString error;
QDomDocument doc;
if (!doc.setContent(&updatesXml, &error))
- throw QInstaller::Error(tr("Could not read: %1. Error: %2").arg(updatesXml.fileName(), error));
+ throw QInstaller::Error(tr("Cannot read file \"%1\": %2").arg(
+ QDir::toNativeSeparators(updatesXml.fileName()), error));
// build for each available package a name - version mapping
QHash<QString, QString> nameVersionHash;
@@ -247,8 +249,9 @@ bool CreateLocalRepositoryOperation::performOperation()
QFile file(binaryPath);
if (!file.open(QIODevice::ReadOnly)) {
- throw QInstaller::Error(tr("Could not open file: %1. Error: %2").arg(file.fileName(),
- file.errorString()));
+ throw QInstaller::Error(tr("Cannot open file \"%1\" for reading: %2").arg(
+ QDir::toNativeSeparators(file.fileName()),
+ file.errorString()));
}
// start to read the binary layout
@@ -265,8 +268,8 @@ bool CreateLocalRepositoryOperation::performOperation()
for (int i = 0; i < names.count(); ++i) {
const QString name = names.at(i);
if (!repo.mkpath(name)) {
- throw QInstaller::Error(tr("Could not create target dir: %1.")
- .arg(repo.filePath(name)));
+ throw QInstaller::Error(tr("Cannot create target directory: \"%1\".")
+ .arg(QDir::toNativeSeparators(repo.filePath(name))));
}
// zip the meta files that come with the offline installer
helper.m_files.prepend(Static::createArchive(repoPath,
@@ -334,10 +337,10 @@ bool CreateLocalRepositoryOperation::undoOperation()
QDir dir;
const QStringList files = value(QLatin1String("files")).toStringList();
foreach (const QString &file, files) {
- emit outputTextChanged(tr("Removing file: %0").arg(file));
+ emit outputTextChanged(tr("Removing file \"%1\".").arg(QDir::toNativeSeparators(file)));
if (!QFile::remove(file)) {
setError(InvalidArguments);
- setErrorString(tr("Could not remove %0.").arg(file));
+ setErrorString(tr("Cannot remove file \"%1\".").arg(QDir::toNativeSeparators(file)));
return false;
}
dir.rmpath(QFileInfo(file).absolutePath());
@@ -356,12 +359,12 @@ bool CreateLocalRepositoryOperation::undoOperation()
#if defined(Q_OS_WIN) && !defined(Q_CC_MINGW)
char msg[128];
if (strerror_s(msg, sizeof msg, errno) != 0) {
- setError(UserDefinedError, tr("Cannot remove directory %1: %2").arg(createdDir.path(),
- QString::fromLocal8Bit(msg)));
+ setError(UserDefinedError, tr("Cannot remove directory \"%1\": %2").arg(
+ QDir::toNativeSeparators(createdDir.path()), QString::fromLocal8Bit(msg)));
}
#else
- setError(UserDefinedError, tr("Cannot remove directory %1: %2").arg(createdDir.path(),
- QString::fromLocal8Bit(strerror(errno))));
+ setError(UserDefinedError, tr("Cannot remove directory \"%1\": %2").arg(
+ QDir::toNativeSeparators(createdDir.path()), QString::fromLocal8Bit(strerror(errno))));
#endif
}
setValue(QLatin1String("files"), QStringList());
@@ -374,11 +377,6 @@ bool CreateLocalRepositoryOperation::testOperation()
return true;
}
-Operation *CreateLocalRepositoryOperation::clone() const
-{
- return new CreateLocalRepositoryOperation();
-}
-
void CreateLocalRepositoryOperation::emitFullProgress()
{
emit progressChanged(1.0);
diff --git a/src/libs/installer/createlocalrepositoryoperation.h b/src/libs/installer/createlocalrepositoryoperation.h
index 5216077ed..a982930a9 100644
--- a/src/libs/installer/createlocalrepositoryoperation.h
+++ b/src/libs/installer/createlocalrepositoryoperation.h
@@ -46,13 +46,12 @@ class INSTALLER_EXPORT CreateLocalRepositoryOperation : public QObject, public O
friend struct AutoHelper;
public:
- CreateLocalRepositoryOperation();
+ explicit CreateLocalRepositoryOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
signals:
void progressChanged(double progress);
diff --git a/src/libs/installer/createshortcutoperation.cpp b/src/libs/installer/createshortcutoperation.cpp
index 89838ddcb..99da0f531 100644
--- a/src/libs/installer/createshortcutoperation.cpp
+++ b/src/libs/installer/createshortcutoperation.cpp
@@ -46,6 +46,7 @@ using namespace QInstaller;
#ifdef Q_OS_WIN
#include <qt_windows.h>
#include <shlobj.h>
+#include <Intshcut.h>
#ifndef PIDLIST_ABSOLUTE
typedef ITEMIDLIST *PIDLIST_ABSOLUTE;
@@ -98,39 +99,62 @@ static QString takeArgument(const QString argument, QStringList *arguments)
static bool createLink(const QString &fileName, const QString &linkName, QString workingDir,
const QString &arguments = QString(), const QString &iconPath = QString(),
- const QString &iconId = QString())
+ const QString &iconId = QString(), const QString &description = QString())
{
#ifdef Q_OS_WIN
- bool success = QFile::link(fileName, linkName);
+ // CoInitialize cleanup object
+ DeCoInitializer _;
- if (!success)
- return success;
+ IUnknown *iunkn = NULL;
- if (workingDir.isEmpty())
- workingDir = QFileInfo(fileName).absolutePath();
- workingDir = QDir::toNativeSeparators(workingDir);
+ if (fileName.toLower().startsWith(QLatin1String("http:"))
+ || fileName.toLower().startsWith(QLatin1String("ftp:"))) {
+ IUniformResourceLocator *iurl = NULL;
+ if (FAILED(CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER,
+ IID_IUniformResourceLocator, (LPVOID*)&iurl))) {
+ return false;
+ }
- // CoInitialize cleanup object
- DeCoInitializer _;
+ if (FAILED(iurl->SetURL((wchar_t *)fileName.utf16(), IURL_SETURL_FL_GUESS_PROTOCOL))) {
+ iurl->Release();
+ return false;
+ }
+ iunkn = iurl;
+ } else {
+ bool success = QFile::link(fileName, linkName);
+
+ if (!success) {
+ return success;
+ }
+
+ if (workingDir.isEmpty())
+ workingDir = QFileInfo(fileName).absolutePath();
+ workingDir = QDir::toNativeSeparators(workingDir);
- IShellLink *psl = NULL;
- if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl)))
- return success;
+ IShellLink *psl = NULL;
+ if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ IID_IShellLink, (LPVOID*)&psl))) {
+ return success;
+ }
- // TODO: implement this server side, since there's not Qt equivalent to set working dir and arguments
- psl->SetPath((wchar_t *)QDir::toNativeSeparators(fileName).utf16());
- psl->SetWorkingDirectory((wchar_t *)workingDir.utf16());
- if (!arguments.isNull())
- psl->SetArguments((wchar_t*)arguments.utf16());
- if (!iconPath.isNull())
- psl->SetIconLocation((wchar_t*)(iconPath.utf16()), iconId.toInt());
+ // TODO: implement this server side, since there's not Qt equivalent to set working dir and arguments
+ psl->SetPath((wchar_t *)QDir::toNativeSeparators(fileName).utf16());
+ psl->SetWorkingDirectory((wchar_t *)workingDir.utf16());
+ if (!arguments.isNull())
+ psl->SetArguments((wchar_t*)arguments.utf16());
+ if (!iconPath.isNull())
+ psl->SetIconLocation((wchar_t*)(iconPath.utf16()), iconId.toInt());
+ if (!description.isNull())
+ psl->SetDescription((wchar_t*)(description.utf16()));
+ iunkn = psl;
+ }
IPersistFile *ppf = NULL;
- if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (void **)&ppf))) {
+ if (SUCCEEDED(iunkn->QueryInterface(IID_IPersistFile, (void **)&ppf))) {
ppf->Save((wchar_t*)QDir::toNativeSeparators(linkName).utf16(), true);
ppf->Release();
}
- psl->Release();
+ iunkn->Release();
PIDLIST_ABSOLUTE pidl; // Force start menu cache update
if (SUCCEEDED(SHGetFolderLocation(0, CSIDL_STARTMENU, 0, 0, &pidl))) {
@@ -142,7 +166,7 @@ static bool createLink(const QString &fileName, const QString &linkName, QString
CoTaskMemFree(pidl);
}
- return success;
+ return true;
#else
Q_UNUSED(arguments)
Q_UNUSED(workingDir)
@@ -157,13 +181,17 @@ static bool createLink(const QString &fileName, const QString &linkName, QString
// -- CreateShortcutOperation
-CreateShortcutOperation::CreateShortcutOperation()
+CreateShortcutOperation::CreateShortcutOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
+ , m_optionalArgumentsRead(false)
{
setName(QLatin1String("CreateShortcut"));
}
void CreateShortcutOperation::backup()
{
+ ensureOptionalArgumentsRead();
+
QDir linkPath(QFileInfo(arguments().at(1)).absolutePath());
QStringList directoriesToCreate;
@@ -176,25 +204,38 @@ void CreateShortcutOperation::backup()
setValue(QLatin1String("createddirs"), directoriesToCreate);
}
-bool CreateShortcutOperation::performOperation()
+void CreateShortcutOperation::ensureOptionalArgumentsRead()
{
+ if (m_optionalArgumentsRead)
+ return;
+
+ m_optionalArgumentsRead = true;
+
QStringList args = arguments();
- const QString iconId = takeArgument(QString::fromLatin1("iconId="), &args);
- const QString iconPath = takeArgument(QString::fromLatin1("iconPath="), &args);
- const QString workingDir = takeArgument(QString::fromLatin1("workingDirectory="), &args);
+ m_iconId = takeArgument(QString::fromLatin1("iconId="), &args);
+ m_iconPath = takeArgument(QString::fromLatin1("iconPath="), &args);
+ m_workingDir = takeArgument(QString::fromLatin1("workingDirectory="), &args);
+ m_description = takeArgument(QString::fromLatin1("description="), &args);
+
+ setArguments(args);
+}
+
+bool CreateShortcutOperation::performOperation()
+{
+ ensureOptionalArgumentsRead();
- if (args.count() != 2 && args.count() != 3) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("2 or 3"),
- tr(" (optional: 'workingDirectory=...', 'iconPath=...', 'iconId=...')")));
+ if (!checkArgumentCount(2, 3, tr("<target> <link location> [target arguments] "
+ "[\"workingDirectory=...\"] [\"iconPath=...\"] [\"iconId=...\"] "
+ "[\"description=...\"]"))) {
return false;
}
+ QStringList args = arguments();
+
const QString linkTarget = args.at(0);
const QString linkLocation = args.at(1);
- const QString targetArguments = args.value(2); //used value because it could be not existing
+ const QString targetArguments = args.value(2); // value() used since it's optional
const QString linkPath = QFileInfo(linkLocation).absolutePath().trimmed();
const bool created = QDir(linkPath).exists() || QDir::root().mkpath(linkPath);
@@ -204,11 +245,11 @@ bool CreateShortcutOperation::performOperation()
#if defined(Q_OS_WIN) && !defined(Q_CC_MINGW)
char msg[128];
if (strerror_s(msg, sizeof msg, errno) != 0) {
- setErrorString(tr("Could not create folder %1: %2.").arg(QDir::toNativeSeparators(linkPath),
+ setErrorString(tr("Cannot create directory \"%1\": %2").arg(QDir::toNativeSeparators(linkPath),
QString::fromLocal8Bit(msg)));
}
#else
- setErrorString(tr("Could not create folder %1: %2.").arg(QDir::toNativeSeparators(linkPath),
+ setErrorString(tr("Cannot create directory \"%1\": %2").arg(QDir::toNativeSeparators(linkPath),
QString::fromLocal8Bit(strerror(errno))));
#endif
return false;
@@ -218,15 +259,16 @@ bool CreateShortcutOperation::performOperation()
QString errorString;
if (QFile::exists(linkLocation) && !deleteFileNowOrLater(linkLocation, &errorString)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to overwrite %1: %2").arg(QDir::toNativeSeparators(linkLocation),
+ setErrorString(tr("Failed to overwrite \"%1\": %2").arg(QDir::toNativeSeparators(linkLocation),
errorString));
return false;
}
- const bool linked = createLink(linkTarget, linkLocation, workingDir, targetArguments, iconPath, iconId);
+ const bool linked = createLink(linkTarget, linkLocation, m_workingDir, targetArguments, m_iconPath, m_iconId,
+ m_description);
if (!linked) {
setError(UserDefinedError);
- setErrorString(tr("Could not create link %1: %2").arg(QDir::toNativeSeparators(linkLocation),
+ setErrorString(tr("Cannot create link \"%1\": %2").arg(QDir::toNativeSeparators(linkLocation),
qt_error_string()));
return false;
}
@@ -235,6 +277,8 @@ bool CreateShortcutOperation::performOperation()
bool CreateShortcutOperation::undoOperation()
{
+ ensureOptionalArgumentsRead();
+
const QString &linkLocation = arguments().at(1);
if (!deleteFileNowOrLater(linkLocation) )
qDebug() << "Cannot delete:" << linkLocation;
@@ -276,8 +320,3 @@ bool CreateShortcutOperation::testOperation()
{
return true;
}
-
-Operation *CreateShortcutOperation::clone() const
-{
- return new CreateShortcutOperation();
-}
diff --git a/src/libs/installer/createshortcutoperation.h b/src/libs/installer/createshortcutoperation.h
index 832ecbc7e..b39c0a340 100644
--- a/src/libs/installer/createshortcutoperation.h
+++ b/src/libs/installer/createshortcutoperation.h
@@ -41,13 +41,21 @@ namespace QInstaller {
class INSTALLER_EXPORT CreateShortcutOperation : public Operation
{
public:
- CreateShortcutOperation();
+ explicit CreateShortcutOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
+
+private:
+ void ensureOptionalArgumentsRead();
+
+ bool m_optionalArgumentsRead;
+ QString m_iconId;
+ QString m_iconPath;
+ QString m_workingDir;
+ QString m_description;
};
}
diff --git a/src/libs/installer/downloadarchivesjob.cpp b/src/libs/installer/downloadarchivesjob.cpp
index e7f60f9cf..52031121d 100644
--- a/src/libs/installer/downloadarchivesjob.cpp
+++ b/src/libs/installer/downloadarchivesjob.cpp
@@ -38,8 +38,8 @@
#include "packagemanagercore.h"
#include "utils.h"
-#include "kdupdaterfiledownloader.h"
-#include "kdupdaterfiledownloaderfactory.h"
+#include "filedownloader.h"
+#include "filedownloaderfactory.h"
#include <QtCore/QFile>
#include <QtCore/QTimerEvent>
@@ -52,7 +52,7 @@ using namespace KDUpdater;
Creates a new DownloadArchivesJob with \a parent.
*/
DownloadArchivesJob::DownloadArchivesJob(PackageManagerCore *core)
- : KDJob(core)
+ : Job(core)
, m_core(core)
, m_downloader(0)
, m_archivesDownloaded(0)
@@ -125,8 +125,8 @@ void DownloadArchivesJob::fetchNextArchiveHash()
return;
}
- connect(m_downloader, SIGNAL(downloadCompleted()), this, SLOT(finishedHashDownload()),
- Qt::QueuedConnection);
+ connect(m_downloader, &FileDownloader::downloadCompleted,
+ this, &DownloadArchivesJob::finishedHashDownload, Qt::QueuedConnection);
m_downloader->download();
} else {
QMetaObject::invokeMethod(this, "fetchNextArchive", Qt::QueuedConnection);
@@ -164,7 +164,7 @@ void DownloadArchivesJob::fetchNextArchive()
if (m_downloader != 0)
m_downloader->deleteLater();
- m_downloader = setupDownloader(QString(), m_core->value(QLatin1String("UrlQueryString")));
+ m_downloader = setupDownloader(QString(), m_core->value(scUrlQueryString));
if (!m_downloader) {
m_archivesToDownload.removeFirst();
QMetaObject::invokeMethod(this, "fetchNextArchiveHash", Qt::QueuedConnection);
@@ -173,7 +173,8 @@ void DownloadArchivesJob::fetchNextArchive()
emit progressChanged(double(m_archivesDownloaded) / m_archivesToDownloadCount);
connect(m_downloader, SIGNAL(downloadProgress(double)), this, SLOT(emitDownloadProgress(double)));
- connect(m_downloader, SIGNAL(downloadCompleted()), this, SLOT(registerFile()), Qt::QueuedConnection);
+ connect(m_downloader, &FileDownloader::downloadCompleted,
+ this, &DownloadArchivesJob::registerFile, Qt::QueuedConnection);
m_downloader->download();
}
@@ -220,7 +221,7 @@ void DownloadArchivesJob::registerFile()
QMessageBox::Retry | QMessageBox::Cancel, QMessageBox::Cancel);
if (res == QMessageBox::Cancel) {
- finishWithError(tr("Could not verify Hash"));
+ finishWithError(tr("Cannot verify Hash"));
return;
}
} else {
@@ -240,7 +241,7 @@ void DownloadArchivesJob::registerFile()
void DownloadArchivesJob::downloadCanceled()
{
- emitFinishedWithError(KDJob::Canceled, m_downloader->errorString());
+ emitFinishedWithError(Job::Canceled, m_downloader->errorString());
}
void DownloadArchivesJob::downloadFailed(const QString &error)
@@ -250,7 +251,7 @@ void DownloadArchivesJob::downloadFailed(const QString &error)
const QMessageBox::StandardButton b =
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
- QLatin1String("archiveDownloadError"), tr("Download Error"), tr("Could not download archive: %1 : %2")
+ QLatin1String("archiveDownloadError"), tr("Download Error"), tr("Cannot download archive %1: %2")
.arg(m_archivesToDownload.first().second, error), QMessageBox::Retry | QMessageBox::Cancel);
if (b == QMessageBox::Retry)
@@ -262,7 +263,7 @@ void DownloadArchivesJob::downloadFailed(const QString &error)
void DownloadArchivesJob::finishWithError(const QString &error)
{
const FileDownloader *const dl = qobject_cast<const FileDownloader*> (sender());
- const QString msg = tr("Could not fetch archives: %1\nError while loading %2");
+ const QString msg = tr("Cannot fetch archives: %1\nError while loading %2");
if (dl != 0)
emitFinishedWithError(QInstaller::DownloadError, msg.arg(error, dl->url().toString()));
else
@@ -291,24 +292,23 @@ KDUpdater::FileDownloader *DownloadArchivesJob::setupDownloader(const QString &s
auth.setPassword(component->value(QLatin1String("password")));
downloader->setAuthenticator(auth);
- connect(downloader, SIGNAL(downloadCanceled()), this, SLOT(downloadCanceled()));
- connect(downloader, SIGNAL(downloadAborted(QString)), this, SLOT(downloadFailed(QString)),
+ connect(downloader, &FileDownloader::downloadCanceled, this, &DownloadArchivesJob::downloadCanceled);
+ connect(downloader, &FileDownloader::downloadAborted, this, &DownloadArchivesJob::downloadFailed,
Qt::QueuedConnection);
- connect(downloader, SIGNAL(downloadStatus(QString)), this, SIGNAL(downloadStatusChanged(QString)));
+ connect(downloader, &FileDownloader::downloadStatus, this, &DownloadArchivesJob::downloadStatusChanged);
if (FileDownloaderFactory::isSupportedScheme(scheme)) {
downloader->setDownloadedFileName(component->localTempPath() + QLatin1Char('/')
+ component->name() + QLatin1Char('/') + fi.fileName() + suffix);
}
- emit outputTextChanged(tr("Downloading archive '%1' for component: %2")
+ emit outputTextChanged(tr("Downloading archive \"%1\" for component %2.")
.arg(fi.fileName() + suffix, component->displayName()));
} else {
- emit outputTextChanged(tr("Scheme not supported: %1 (%2)").arg(scheme, url.toString()));
+ emit outputTextChanged(tr("Scheme %1 not supported (URL: %2).").arg(scheme, url.toString()));
}
} else {
- emit outputTextChanged(tr("Could not find component for: %1.").arg(QFileInfo(fi.path())
- .fileName()));
+ emit outputTextChanged(tr("Cannot find component for %1.").arg(QFileInfo(fi.path()).fileName()));
}
return downloader;
}
diff --git a/src/libs/installer/downloadarchivesjob.h b/src/libs/installer/downloadarchivesjob.h
index ddc1cc7d0..2fcc01131 100644
--- a/src/libs/installer/downloadarchivesjob.h
+++ b/src/libs/installer/downloadarchivesjob.h
@@ -34,7 +34,7 @@
#ifndef DOWNLOADARCHIVESJOB_H
#define DOWNLOADARCHIVESJOB_H
-#include <kdjob.h>
+#include "job.h"
#include <QtCore/QPair>
@@ -51,7 +51,7 @@ namespace QInstaller {
class MessageBoxHandler;
class PackageManagerCore;
-class DownloadArchivesJob : public KDJob
+class DownloadArchivesJob : public Job
{
Q_OBJECT
diff --git a/src/libs/installer/downloadfiletask.cpp b/src/libs/installer/downloadfiletask.cpp
index e1e4d9ffb..19cb217d6 100644
--- a/src/libs/installer/downloadfiletask.cpp
+++ b/src/libs/installer/downloadfiletask.cpp
@@ -36,12 +36,12 @@
#include "downloadfiletask_p.h"
#include <QCoreApplication>
+#include <QDir>
#include <QEventLoop>
#include <QFileInfo>
#include <QNetworkProxyFactory>
#include <QSslError>
#include <QTemporaryFile>
-#include <QTimer>
namespace QInstaller {
@@ -54,7 +54,8 @@ AuthenticationRequiredException::AuthenticationRequiredException(Type type, cons
Downloader::Downloader()
: m_finished(0)
{
- connect(&m_nam, SIGNAL(finished(QNetworkReply*)), SLOT(onFinished(QNetworkReply*)));
+ connect(&m_timer, &QTimer::timeout, this, &Downloader::onTimeout);
+ connect(&m_nam, &QNetworkAccessManager::finished, this, &Downloader::onFinished);
}
Downloader::~Downloader()
@@ -77,15 +78,17 @@ void Downloader::download(QFutureInterface<FileTaskResult> &fi, const QList<File
fi.setExpectedResultCount(items.count());
m_nam.setProxyFactory(networkProxyFactory);
- connect(&m_nam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this,
- SLOT(onAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
- connect(&m_nam, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this,
- SLOT(onProxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
- QTimer::singleShot(0, this, SLOT(doDownload()));
+ connect(&m_nam, &QNetworkAccessManager::authenticationRequired, this,
+ &Downloader::onAuthenticationRequired);
+ connect(&m_nam, &QNetworkAccessManager::proxyAuthenticationRequired, this,
+ &Downloader::onProxyAuthenticationRequired);
+ QTimer::singleShot(0, this, &Downloader::doDownload);
}
void Downloader::doDownload()
{
+ m_timer.start(1000); // Use a timer to check for canceled downloads.
+
foreach (const FileTaskItem &item, m_items) {
if (!startDownload(item))
break;
@@ -125,15 +128,17 @@ void Downloader::onReadyRead()
}
if (file->exists() && (!QFileInfo(file->fileName()).isFile())) {
- m_futureInterface->reportException(TaskException(tr("Target file '%1' already exists "
+ m_futureInterface->reportException(TaskException(tr("Target file \"%1\" already exists "
"but is not a file.").arg(file->fileName())));
return;
}
if (!file->open(QIODevice::WriteOnly | QIODevice::Truncate)) {
//: %2 is a sentence describing the error
- m_futureInterface->reportException(TaskException(tr("Could not open target '%1' for "
- "write. Error: %2.").arg(file->fileName(), file->errorString())));
+ m_futureInterface->reportException(
+ TaskException(tr("Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(file->fileName()),
+ file->errorString())));
return;
}
data.file = std::move(file);
@@ -142,8 +147,9 @@ void Downloader::onReadyRead()
if (!data.file->isOpen()) {
//: %2 is a sentence describing the error.
m_futureInterface->reportException(
- TaskException(tr("Target '%1' not open for write. Error: %2.").arg(
- data.file->fileName(), data.file->errorString())));
+ TaskException(tr("File \"%1\" not open for writing: %2").arg(
+ QDir::toNativeSeparators(data.file->fileName()),
+ data.file->errorString())));
return;
}
@@ -161,8 +167,9 @@ void Downloader::onReadyRead()
if (toWrite < 0) {
//: %2 is a sentence describing the error.
m_futureInterface->reportException(
- TaskException(tr("Writing to target '%1' failed. Error: %2.").arg(
- data.file->fileName(), data.file->errorString())));
+ TaskException(tr("Writing to file \"%1\" failed: %2").arg(
+ QDir::toNativeSeparators(data.file->fileName()),
+ data.file->errorString())));
return;
}
written += toWrite;
@@ -208,7 +215,7 @@ void Downloader::onFinished(QNetworkReply *reply)
reply->deleteLater();
return;
} else {
- m_futureInterface->reportException(TaskException(tr("Redirect loop detected '%1'.")
+ m_futureInterface->reportException(TaskException(tr("Redirect loop detected for \"%1\".")
.arg(url.toString())));
return;
}
@@ -225,7 +232,7 @@ void Downloader::onFinished(QNetworkReply *reply)
const QByteArray expectedCheckSum = data.taskItem.value(TaskRole::Checksum).toByteArray();
if (!expectedCheckSum.isEmpty()) {
if (expectedCheckSum != data.observer->checkSum().toHex()) {
- m_futureInterface->reportException(TaskException(tr("Checksum mismatch detected '%1'.")
+ m_futureInterface->reportException(TaskException(tr("Checksum mismatch detected for \"%1\".")
.arg(reply->url().toString())));
}
}
@@ -255,12 +262,12 @@ void Downloader::onError(QNetworkReply::NetworkError error)
const Data &data = *m_downloads[reply];
//: %2 is a sentence describing the error
m_futureInterface->reportException(
- TaskException(tr("Network error while downloading '%1': %2.").arg(
+ TaskException(tr("Network error while downloading \"%1\": %2").arg(
data.taskItem.source(), reply->errorString())));
} else {
//: %1 is a sentence describing the error
m_futureInterface->reportException(
- TaskException(tr("Unknown network error while downloading: %1.").arg(error)));
+ TaskException(tr("Unknown network error while downloading \"%1\".").arg(error)));
}
}
@@ -270,7 +277,7 @@ void Downloader::onSslErrors(const QList<QSslError> &sslErrors)
Q_UNUSED(sslErrors);
#else
foreach (const QSslError &error, sslErrors)
- qDebug() << QString::fromLatin1("SSL error: %s").arg(error.errorString());
+ qDebug() << "SSL error:" << error.errorString();
#endif
}
@@ -317,6 +324,28 @@ void Downloader::onProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuth
}
+/*!
+ \internal
+
+ Canceling from the outside will not get noticed if we are waiting on a connection that
+ does not create any events. QNam will drop after 45 seconds, though the user might have
+ canceled the download before. In that case we block until the QNam timeout is reached,
+ worst case resulting in deadlock while the application is shutting down at the same time.
+*/
+void Downloader::onTimeout()
+{
+ if (testCanceled()) {
+ // Inject exception, we can't use QFuturInterface::reportException() as the exception
+ // store is "frozen" once cancel was called. On the other hand, client code could use
+ // QFutureWatcherBase::isCanceled() or QFuture::isCanceled() to check for canceled futures.
+ m_futureInterface->exceptionStore()
+ .setException(TaskException(tr("Network transfers canceled.")));
+ m_futureInterface->reportFinished();
+ emit finished();
+ }
+}
+
+
// -- private
bool Downloader::testCanceled()
@@ -335,7 +364,7 @@ QNetworkReply *Downloader::startDownload(const FileTaskItem &item)
QUrl const source = item.source();
if (!source.isValid()) {
//: %2 is a sentence describing the error
- m_futureInterface->reportException(TaskException(tr("Invalid source '%1'. Error: %2.")
+ m_futureInterface->reportException(TaskException(tr("Invalid source URL \"%1\": %2")
.arg(source.toString(), source.errorString())));
return 0;
}
@@ -344,14 +373,13 @@ QNetworkReply *Downloader::startDownload(const FileTaskItem &item)
std::unique_ptr<Data> data(new Data(item));
m_downloads[reply] = std::move(data);
- connect(reply, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
+ connect(reply, &QIODevice::readyRead, this, &Downloader::onReadyRead);
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this,
SLOT(onError(QNetworkReply::NetworkError)));
#ifndef QT_NO_SSL
- connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(onSslErrors(QList<QSslError>)));
+ connect(reply, &QNetworkReply::sslErrors, this, &Downloader::onSslErrors);
#endif
- connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(onDownloadProgress(qint64,
- qint64)));
+ connect(reply, &QNetworkReply::downloadProgress, this, &Downloader::onDownloadProgress);
return reply;
}
@@ -398,7 +426,7 @@ void DownloadFileTask::doTask(QFutureInterface<FileTaskResult> &fi)
{
QEventLoop el;
Downloader downloader;
- connect(&downloader, SIGNAL(finished()), &el, SLOT(quit()));
+ connect(&downloader, &Downloader::finished, &el, &QEventLoop::quit);
QList<FileTaskItem> items = taskItems();
if (!m_authenticator.isNull()) {
diff --git a/src/libs/installer/downloadfiletask.h b/src/libs/installer/downloadfiletask.h
index a61527135..425b2d021 100644
--- a/src/libs/installer/downloadfiletask.h
+++ b/src/libs/installer/downloadfiletask.h
@@ -35,7 +35,7 @@
#define DOWNLOADFILETASK_H
#include "abstractfiletask.h"
-#include "kdupdaterfiledownloaderfactory.h"
+#include "filedownloaderfactory.h"
#include <QAuthenticator>
Q_DECLARE_METATYPE(QAuthenticator)
diff --git a/src/libs/installer/downloadfiletask_p.h b/src/libs/installer/downloadfiletask_p.h
index f71ba06fd..5583779b4 100644
--- a/src/libs/installer/downloadfiletask_p.h
+++ b/src/libs/installer/downloadfiletask_p.h
@@ -41,6 +41,7 @@
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
+#include <QTimer>
#include <memory>
#include <unordered_map>
@@ -95,7 +96,7 @@ private slots:
void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void onAuthenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator);
void onProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
-
+ void onTimeout();
private:
bool testCanceled();
@@ -104,6 +105,7 @@ private:
private:
QFutureInterface<FileTaskResult> *m_futureInterface;
+ QTimer m_timer;
int m_finished;
QNetworkAccessManager m_nam;
QList<FileTaskItem> m_items;
diff --git a/src/libs/installer/elevatedexecuteoperation.cpp b/src/libs/installer/elevatedexecuteoperation.cpp
index 5de3c0203..3f3cdbb2a 100644
--- a/src/libs/installer/elevatedexecuteoperation.cpp
+++ b/src/libs/installer/elevatedexecuteoperation.cpp
@@ -63,8 +63,9 @@ public:
bool showStandardError;
};
-ElevatedExecuteOperation::ElevatedExecuteOperation()
- : d(new Private(this))
+ElevatedExecuteOperation::ElevatedExecuteOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
+ , d(new Private(this))
{
// this operation has to "overwrite" the Execute operation from KDUpdater
setName(QLatin1String("Execute"));
@@ -79,12 +80,9 @@ bool ElevatedExecuteOperation::performOperation()
{
// This operation receives only one argument. It is the complete
// command line of the external program to execute.
- if (arguments().isEmpty()) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("at least 1"), QLatin1String("")));
+ if (!checkArgumentCount(1, INT_MAX))
return false;
- }
+
QStringList args;
foreach (const QString &argument, arguments()) {
if (argument!=QLatin1String("UNDOEXECUTE"))
@@ -144,7 +142,7 @@ bool ElevatedExecuteOperation::Private::run(const QStringList &arguments)
const bool success = QProcessWrapper::startDetached(args.front(), args.mid(1));
if (!success) {
q->setError(UserDefinedError);
- q->setErrorString(tr("Execution failed: Could not start detached: \"%1\"").arg(callstr));
+ q->setErrorString(tr("Cannot start detached: \"%1\"").arg(callstr));
}
return success;
}
@@ -163,12 +161,12 @@ bool ElevatedExecuteOperation::Private::run(const QStringList &arguments)
if (showStandardError)
process->setProcessChannelMode(QProcessWrapper::MergedChannels);
- connect(q, SIGNAL(cancelProcess()), process, SLOT(cancel()));
+ connect(q, &ElevatedExecuteOperation::cancelProcess, process, &QProcessWrapper::cancel);
//we still like the none blocking possibility to perform this operation without threads
QEventLoop loop;
if (QThread::currentThread() == qApp->thread()) {
- QObject::connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit()));
+ QObject::connect(process, &QProcessWrapper::finished, &loop, &QEventLoop::quit);
}
//readProcessOutput should only called from this current Thread -> Qt::DirectConnection
QObject::connect(process, SIGNAL(readyRead()), q, SLOT(readProcessOutput()), Qt::DirectConnection);
@@ -196,7 +194,7 @@ bool ElevatedExecuteOperation::Private::run(const QStringList &arguments)
if (!success) {
q->setError(UserDefinedError);
//TODO: pass errorString() through the wrapper */
- q->setErrorString(tr("Execution failed: Could not start: \"%1\"(%2)").arg(callstr,
+ q->setErrorString(tr("Cannot start: \"%1\": %2").arg(callstr,
process->errorString()));
returnValue = false;
}
@@ -212,14 +210,14 @@ bool ElevatedExecuteOperation::Private::run(const QStringList &arguments)
if (process->exitStatus() == QProcessWrapper::CrashExit) {
q->setError(UserDefinedError);
- q->setErrorString(tr("Execution failed(Crash): \"%1\"").arg(callstr));
+ q->setErrorString(tr("Program crashed: \"%1\"").arg(callstr));
returnValue = false;
}
if (!allowedExitCodes.contains(process->exitCode())) {
q->setError(UserDefinedError);
if (customErrorMessage.isEmpty()) {
- q->setErrorString(tr("Execution failed(Unexpected exit code: %1): \"%2\"")
+ q->setErrorString(tr("Execution failed (Unexpected exit code: %1): \"%2\"")
.arg(QString::number(process->exitCode()), callstr));
} else {
q->setErrorString(customErrorMessage);
@@ -228,13 +226,14 @@ bool ElevatedExecuteOperation::Private::run(const QStringList &arguments)
QByteArray standardErrorOutput = process->readAllStandardError();
// in error case it would be useful to see something in verbose output
if (!standardErrorOutput.isEmpty())
- qWarning() << standardErrorOutput;
+ qWarning().noquote() << standardErrorOutput;
returnValue = false;
}
Q_ASSERT(process);
- process->deleteLater();
+ Q_ASSERT(process->state() == QProcessWrapper::NotRunning);
+ delete process;
process = 0;
return returnValue;
@@ -289,11 +288,6 @@ bool ElevatedExecuteOperation::testOperation()
return true;
}
-Operation *ElevatedExecuteOperation::clone() const
-{
- return new ElevatedExecuteOperation;
-}
-
void ElevatedExecuteOperation::backup()
{
}
diff --git a/src/libs/installer/elevatedexecuteoperation.h b/src/libs/installer/elevatedexecuteoperation.h
index c218e6aaa..88c3f22d2 100644
--- a/src/libs/installer/elevatedexecuteoperation.h
+++ b/src/libs/installer/elevatedexecuteoperation.h
@@ -43,14 +43,13 @@ class INSTALLER_EXPORT ElevatedExecuteOperation : public QObject, public Operati
Q_OBJECT
public:
- ElevatedExecuteOperation();
+ explicit ElevatedExecuteOperation(PackageManagerCore *core);
~ElevatedExecuteOperation();
-
- virtual void backup();
- virtual bool performOperation();
- virtual bool undoOperation();
- virtual bool testOperation();
- virtual Operation *clone() const;
+
+ void backup() Q_DECL_OVERRIDE;
+ bool performOperation() Q_DECL_OVERRIDE;
+ bool undoOperation() Q_DECL_OVERRIDE;
+ bool testOperation() Q_DECL_OVERRIDE;
Q_SIGNALS:
void cancelProcess();
diff --git a/src/libs/installer/environmentvariablesoperation.cpp b/src/libs/installer/environmentvariablesoperation.cpp
index 24016569b..1b869fb11 100644
--- a/src/libs/installer/environmentvariablesoperation.cpp
+++ b/src/libs/installer/environmentvariablesoperation.cpp
@@ -45,7 +45,8 @@
using namespace QInstaller;
using namespace KDUpdater;
-EnvironmentVariableOperation::EnvironmentVariableOperation()
+EnvironmentVariableOperation::EnvironmentVariableOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("EnvironmentVariable"));
}
@@ -79,7 +80,7 @@ UpdateOperation::Error writeSetting(const QString &regPath,
oldValue->clear();
SettingsType registry(regPath, QSettingsWrapper::NativeFormat);
if (!registry.isWritable()) {
- *errorString = UpdateOperation::tr("Registry path %1 is not writable").arg(regPath);
+ *errorString = UpdateOperation::tr("Registry path %1 is not writable.").arg(regPath);
return UpdateOperation::UserDefinedError;
}
@@ -91,7 +92,7 @@ UpdateOperation::Error writeSetting(const QString &regPath,
registry.sync();
if (registry.status() != QSettingsWrapper::NoError) {
- *errorString = UpdateOperation::tr("Could not write to registry path %1").arg(regPath);
+ *errorString = UpdateOperation::tr("Cannot write to registry path %1.").arg(regPath);
return UpdateOperation::UserDefinedError;
}
@@ -120,21 +121,16 @@ UpdateOperation::Error undoSetting(const QString &regPath,
bool EnvironmentVariableOperation::performOperation()
{
- QStringList args = arguments();
- if (args.count() < 2 || args.count() > 4) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("2 to 4"), QLatin1String("")));
+ if (!checkArgumentCount(2, 4))
return false;
- }
- const QString name = arguments().at(0);
- const QString value = arguments().at(1);
- bool isPersistent = false;
+ const QStringList args = arguments();
+ const QString name = args.at(0);
+ const QString value = args.at(1);
#ifdef Q_OS_WIN
- isPersistent = arguments().count() >= 3 ? arguments().at(2) == QLatin1String("true") : true;
- const bool isSystemWide = arguments().count() >= 4 ? arguments().at(3) == QLatin1String("true") : false;
+ const bool isPersistent = arguments().count() > 2 ? arguments().at(2) == QLatin1String("true") : true;
+ const bool isSystemWide = arguments().count() > 3 ? arguments().at(3) == QLatin1String("true") : false;
QString oldvalue;
if (isPersistent) {
const QString regPath = isSystemWide ? QLatin1String("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet"
@@ -157,9 +153,8 @@ bool EnvironmentVariableOperation::performOperation()
setValue(QLatin1String("oldvalue"), oldvalue);
return true;
}
-#endif
Q_ASSERT(!isPersistent);
- Q_UNUSED(isPersistent)
+#endif
setValue(QLatin1String("oldvalue"), Environment::instance().value(name));
Environment::instance().setTemporaryValue(name, value);
@@ -214,8 +209,3 @@ bool EnvironmentVariableOperation::testOperation()
{
return true;
}
-
-Operation *EnvironmentVariableOperation::clone() const
-{
- return new EnvironmentVariableOperation();
-}
diff --git a/src/libs/installer/environmentvariablesoperation.h b/src/libs/installer/environmentvariablesoperation.h
index 2fa3bc289..507b4aff6 100644
--- a/src/libs/installer/environmentvariablesoperation.h
+++ b/src/libs/installer/environmentvariablesoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT EnvironmentVariableOperation : public Operation
{
public:
- EnvironmentVariableOperation();
+ explicit EnvironmentVariableOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
}
diff --git a/src/libs/installer/errors.h b/src/libs/installer/errors.h
index 0c9502cbb..40bdefcf4 100644
--- a/src/libs/installer/errors.h
+++ b/src/libs/installer/errors.h
@@ -44,13 +44,15 @@ namespace QInstaller {
class Error : public std::exception
{
public:
- Error() {}
+ Error()
+ {}
+
explicit Error(const QString &message)
: m_message(message)
- {
- qDebug() << "create Error-Exception:" << message;
- }
- virtual ~Error() throw() {}
+ {}
+
+ virtual ~Error() throw()
+ {}
QString message() const { return m_message; }
diff --git a/src/libs/installer/extractarchiveoperation.cpp b/src/libs/installer/extractarchiveoperation.cpp
index dba9fd93d..f91068e40 100644
--- a/src/libs/installer/extractarchiveoperation.cpp
+++ b/src/libs/installer/extractarchiveoperation.cpp
@@ -31,17 +31,15 @@
**
**************************************************************************/
-#include "extractarchiveoperation.h"
#include "extractarchiveoperation_p.h"
-#include <QtCore/QEventLoop>
-#include <QtCore/QThread>
-#include <QtCore/QThreadPool>
+#include <QEventLoop>
+#include <QThreadPool>
-using namespace QInstaller;
+namespace QInstaller {
-
-ExtractArchiveOperation::ExtractArchiveOperation()
+ExtractArchiveOperation::ExtractArchiveOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Extract"));
}
@@ -53,55 +51,46 @@ void ExtractArchiveOperation::backup()
bool ExtractArchiveOperation::performOperation()
{
- const QStringList args = arguments();
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 2"), QLatin1String("")));
+ if (!checkArgumentCount(2))
return false;
- }
- const QString archivePath = args.first();
+ const QStringList args = arguments();
+ const QString archivePath = args.at(0);
const QString targetDir = args.at(1);
Receiver receiver;
Callback callback;
- connect(&callback, SIGNAL(currentFileChanged(QString)), this, SLOT(fileFinished(QString)));
- connect(&callback, SIGNAL(progressChanged(double)), this, SIGNAL(progressChanged(double)));
+ connect(&callback, &Callback::currentFileChanged, this, &ExtractArchiveOperation::fileFinished);
+ connect(&callback, &Callback::progressChanged, this, &ExtractArchiveOperation::progressChanged);
- if (PackageManagerCore *core = this->value(QLatin1String("installer")).value<PackageManagerCore*>()) {
- connect(core, SIGNAL(statusChanged(QInstaller::PackageManagerCore::Status)), &callback,
- SLOT(statusChanged(QInstaller::PackageManagerCore::Status)));
+ if (PackageManagerCore *core = packageManager()) {
+ connect(core, &PackageManagerCore::statusChanged, &callback, &Callback::statusChanged);
}
- //Runnable is derived from QRunable which will be deleted by the ThreadPool -> no parent is needed
Runnable *runnable = new Runnable(archivePath, targetDir, &callback);
- connect(runnable, SIGNAL(finished(bool,QString)), &receiver, SLOT(runnableFinished(bool,QString)),
+ connect(runnable, &Runnable::finished, &receiver, &Receiver::runnableFinished,
Qt::QueuedConnection);
QEventLoop loop;
- connect(&receiver, SIGNAL(finished()), &loop, SLOT(quit()));
+ connect(&receiver, &Receiver::finished, &loop, &QEventLoop::quit);
if (QThreadPool::globalInstance()->tryStart(runnable)) {
loop.exec();
} else {
- // in case there is no availabe thread we should call it directly this is more a hack
+ // HACK: In case there is no availabe thread we should call it directly.
runnable->run();
receiver.runnableFinished(true, QString());
}
- typedef QPair<QString, QString> StringPair;
- QVector<StringPair> backupFiles = callback.backupFiles;
-
- //TODO use backups for rollback, too? doesn't work for uninstallation though
+ // TODO: Use backups for rollback, too? Doesn't work for uninstallation though.
- //delete all backups we can delete right now, remember the rest
- foreach (const StringPair &i, backupFiles)
+ // delete all backups we can delete right now, remember the rest
+ foreach (const Backup &i, callback.backupFiles())
deleteFileNowOrLater(i.second);
- if (!receiver.success) {
+ if (!receiver.success()) {
setError(UserDefinedError);
- setErrorString(receiver.errorString);
+ setErrorString(receiver.errorString());
return false;
}
return true;
@@ -110,17 +99,16 @@ bool ExtractArchiveOperation::performOperation()
bool ExtractArchiveOperation::undoOperation()
{
Q_ASSERT(arguments().count() == 2);
- //const QString archivePath = arguments().first();
- //const QString targetDir = arguments().last();
-
const QStringList files = value(QLatin1String("files")).toStringList();
WorkerThread *const thread = new WorkerThread(this, files);
- connect(thread, SIGNAL(currentFileChanged(QString)), this, SIGNAL(outputTextChanged(QString)));
- connect(thread, SIGNAL(progressChanged(double)), this, SIGNAL(progressChanged(double)));
+ connect(thread, &WorkerThread::currentFileChanged, this,
+ &ExtractArchiveOperation::outputTextChanged);
+ connect(thread, &WorkerThread::progressChanged, this,
+ &ExtractArchiveOperation::progressChanged);
QEventLoop loop;
- connect(thread, SIGNAL(finished()), &loop, SLOT(quit()), Qt::QueuedConnection);
+ connect(thread, &QThread::finished, &loop, &QEventLoop::quit, Qt::QueuedConnection);
thread->start();
loop.exec();
thread->deleteLater();
@@ -132,18 +120,16 @@ bool ExtractArchiveOperation::testOperation()
return true;
}
-Operation *ExtractArchiveOperation::clone() const
-{
- return new ExtractArchiveOperation();
-}
-
/*!
- This slot is direct connected to the caller so please don't call it from another thread in the same time.
+ This slot is direct connected to the caller so please don't call it from another thread in the
+ same time.
*/
void ExtractArchiveOperation::fileFinished(const QString &filename)
{
QStringList files = value(QLatin1String("files")).toStringList();
files.prepend(filename);
setValue(QLatin1String("files"), files);
- emit outputTextChanged(filename);
+ emit outputTextChanged(QDir::toNativeSeparators(filename));
}
+
+} // namespace QInstaller
diff --git a/src/libs/installer/extractarchiveoperation.h b/src/libs/installer/extractarchiveoperation.h
index 51ade8ca9..50a544c80 100644
--- a/src/libs/installer/extractarchiveoperation.h
+++ b/src/libs/installer/extractarchiveoperation.h
@@ -46,13 +46,12 @@ class INSTALLER_EXPORT ExtractArchiveOperation : public QObject, public Operatio
friend class WorkerThread;
public:
- ExtractArchiveOperation();
+ explicit ExtractArchiveOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
Q_SIGNALS:
void outputTextChanged(const QString &progress);
diff --git a/src/libs/installer/extractarchiveoperation_p.h b/src/libs/installer/extractarchiveoperation_p.h
index 66529d934..3e2b1ce74 100644
--- a/src/libs/installer/extractarchiveoperation_p.h
+++ b/src/libs/installer/extractarchiveoperation_p.h
@@ -36,24 +36,23 @@
#include "extractarchiveoperation.h"
#include "fileutils.h"
+#include "lib7z_extract.h"
#include "lib7z_facade.h"
#include "packagemanagercore.h"
-#include <QtCore/QDir>
-#include <QtCore/QFile>
-#include <QtCore/QPair>
-#include <QtCore/QThread>
-#include <QtCore/QVector>
+#include <QRunnable>
+#include <QThread>
namespace QInstaller {
class WorkerThread : public QThread
{
Q_OBJECT
+ Q_DISABLE_COPY(WorkerThread)
+
public:
- WorkerThread(ExtractArchiveOperation *op, const QStringList &files, QObject *parent = 0)
- : QThread(parent)
- , m_files(files)
+ WorkerThread(ExtractArchiveOperation *op, const QStringList &files)
+ : m_files(files)
, m_op(op)
{
setObjectName(QLatin1String("ExtractArchive"));
@@ -61,26 +60,25 @@ public:
void run()
{
- ExtractArchiveOperation *const op = m_op;//dynamic_cast< ExtractArchiveOperation* >(parent());
- Q_ASSERT(op != 0);
+ Q_ASSERT(m_op != 0);
int removedCounter = 0;
foreach (const QString &file, m_files) {
removedCounter++;
+
const QFileInfo fi(file);
- emit currentFileChanged(file);
+ emit currentFileChanged(QDir::toNativeSeparators(file));
emit progressChanged(double(removedCounter) / m_files.count());
if (fi.isFile() || fi.isSymLink()) {
- op->deleteFileNowOrLater(fi.absoluteFilePath());
+ m_op->deleteFileNowOrLater(fi.absoluteFilePath());
} else if (fi.isDir()) {
- const QDir d = fi.dir();
removeSystemGeneratedFiles(file);
- d.rmdir(file); // directory may not exist
+ fi.dir().rmdir(file); // directory may not exist
}
}
}
-Q_SIGNALS:
+signals:
void currentFileChanged(const QString &filename);
void progressChanged(double);
@@ -89,44 +87,42 @@ private:
ExtractArchiveOperation *m_op;
};
+typedef QPair<QString, QString> Backup;
+typedef QVector<Backup> BackupFiles;
class ExtractArchiveOperation::Callback : public QObject, public Lib7z::ExtractCallback
{
Q_OBJECT
+ Q_DISABLE_COPY(Callback)
public:
- HRESULT state;
- bool createBackups;
- QVector<QPair<QString, QString> > backupFiles;
-
- Callback() : state(S_OK), createBackups(true) {}
+ Callback() = default;
-Q_SIGNALS:
- void currentFileChanged(const QString &filename);
- void progressChanged(double progress);
+ BackupFiles backupFiles() const {
+ return m_backupFiles;
+ }
-public Q_SLOTS:
+public slots:
void statusChanged(QInstaller::PackageManagerCore::Status status)
{
switch(status) {
case PackageManagerCore::Canceled:
- state = E_ABORT;
+ m_state = E_ABORT;
break;
case PackageManagerCore::Failure:
- state = E_FAIL;
+ m_state = E_FAIL;
break;
- default: // fall through
- // PackageManagerCore::Unfinished, PackageManagerCore::Success, PackageManagerCore::Running
- // PackageManagerCore::ForceUpdate
-
- // already set
- //state = S_OK;
+ default: // ignore all other status values
break;
}
}
-protected:
- void setCurrentFile(const QString &filename)
+signals:
+ void currentFileChanged(const QString &filename);
+ void progressChanged(double progress);
+
+private:
+ void setCurrentFile(const QString &filename) Q_DECL_OVERRIDE
{
emit currentFileChanged(QDir::toNativeSeparators(filename));
}
@@ -141,94 +137,106 @@ protected:
return res;
}
- bool prepareForFile(const QString &filename)
+ bool prepareForFile(const QString &filename) Q_DECL_OVERRIDE
{
- if (!createBackups)
- return true;
if (!QFile::exists(filename))
return true;
const QString backup = generateBackupName(filename);
QFile f(filename);
const bool renamed = f.rename(backup);
if (f.exists() && !renamed) {
- qCritical("Could not rename %s to %s: %s", qPrintable(filename), qPrintable(backup),
+ qCritical("Cannot rename %s to %s: %s", qPrintable(filename), qPrintable(backup),
qPrintable(f.errorString()));
return false;
}
- backupFiles.push_back(qMakePair(filename, backup));
+ m_backupFiles.append(qMakePair(filename, backup));
return true;
}
- HRESULT setCompleted(quint64 completed, quint64 total)
+ HRESULT setCompleted(quint64 completed, quint64 total) Q_DECL_OVERRIDE
{
emit progressChanged(double(completed) / total);
- return state;
+ return m_state;
}
+
+private:
+ HRESULT m_state = S_OK;
+ BackupFiles m_backupFiles;
};
class ExtractArchiveOperation::Runnable : public QObject, public QRunnable
{
Q_OBJECT
+ Q_DISABLE_COPY(Runnable)
public:
- Runnable(const QString &archivePath_, const QString &targetDir_, ExtractArchiveOperation::Callback *callback_)
- : QObject()
- , QRunnable()
- , archivePath(archivePath_)
- , targetDir(targetDir_)
- , callback(callback_) {}
+ Runnable(const QString &archivePath, const QString &targetDir,
+ ExtractArchiveOperation::Callback *callback)
+ : m_archivePath(archivePath)
+ , m_targetDir(targetDir)
+ , m_callback(callback)
+ {}
void run()
{
- QFile archive(archivePath);
+ QFile archive(m_archivePath);
if (!archive.open(QIODevice::ReadOnly)) {
-
- emit finished(false, tr("Could not open %1 for reading: %2.").arg(archivePath, archive.errorString()));
+ emit finished(false, tr("Cannot open archive \"%1\" for reading: %2").arg(m_archivePath,
+ archive.errorString()));
return;
}
try {
- Lib7z::extractArchive(&archive, targetDir, callback);
+ Lib7z::extractArchive(&archive, m_targetDir, m_callback);
emit finished(true, QString());
} catch (const Lib7z::SevenZipException& e) {
- emit finished(false, tr("Error while extracting '%1': %2").arg(archivePath, e.message()));
+ emit finished(false, tr("Error while extracting archive \"%1\": %2").arg(m_archivePath,
+ e.message()));
} catch (...) {
- emit finished(false, tr("Unknown exception caught while extracting %1.").arg(archivePath));
+ emit finished(false, tr("Unknown exception caught while extracting \"%1\".")
+ .arg(m_archivePath));
}
}
-Q_SIGNALS:
+signals:
void finished(bool success, const QString &errorString);
private:
- const QString archivePath;
- const QString targetDir;
- ExtractArchiveOperation::Callback *const callback;
+ QString m_archivePath;
+ QString m_targetDir;
+ ExtractArchiveOperation::Callback *m_callback;
};
-
class ExtractArchiveOperation::Receiver : public QObject
{
Q_OBJECT
+ Q_DISABLE_COPY(Receiver)
+
public:
- explicit Receiver(QObject *parent = 0)
- : QObject(parent)
- , success(false) {}
+ Receiver() = default;
-public Q_SLOTS:
+ bool success() const {
+ return m_success;
+ }
+
+ QString errorString() const {
+ return m_errorString;
+ }
+
+public slots:
void runnableFinished(bool ok, const QString &msg)
{
- success = ok;
- errorString = msg;
+ m_success = ok;
+ m_errorString = msg;
emit finished();
}
-Q_SIGNALS:
+signals:
void finished();
-public:
- bool success;
- QString errorString;
+private:
+ bool m_success = false;
+ QString m_errorString;
};
}
diff --git a/src/libs/installer/fakestopprocessforupdateoperation.cpp b/src/libs/installer/fakestopprocessforupdateoperation.cpp
index 2d49d0f46..d03319491 100644
--- a/src/libs/installer/fakestopprocessforupdateoperation.cpp
+++ b/src/libs/installer/fakestopprocessforupdateoperation.cpp
@@ -39,7 +39,8 @@
using namespace KDUpdater;
using namespace QInstaller;
-FakeStopProcessForUpdateOperation::FakeStopProcessForUpdateOperation()
+FakeStopProcessForUpdateOperation::FakeStopProcessForUpdateOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("FakeStopProcessForUpdate"));
}
@@ -56,15 +57,12 @@ bool FakeStopProcessForUpdateOperation::performOperation()
bool FakeStopProcessForUpdateOperation::undoOperation()
{
setError(KDUpdater::UpdateOperation::NoError);
- if (arguments().size() != 1) {
- setError(KDUpdater::UpdateOperation::InvalidArguments, tr("Number of arguments does not "
- "match: one is required"));
+ if (!checkArgumentCount(1))
return false;
- }
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ PackageManagerCore *const core = packageManager();
if (!core) {
- setError(KDUpdater::UpdateOperation::UserDefinedError, tr("Could not get package manager "
+ setError(KDUpdater::UpdateOperation::UserDefinedError, tr("Cannot get package manager "
"core."));
return false;
}
@@ -93,8 +91,3 @@ bool FakeStopProcessForUpdateOperation::testOperation()
{
return true;
}
-
-Operation *FakeStopProcessForUpdateOperation::clone() const
-{
- return new FakeStopProcessForUpdateOperation();
-}
diff --git a/src/libs/installer/fakestopprocessforupdateoperation.h b/src/libs/installer/fakestopprocessforupdateoperation.h
index 702a81b5e..8eb0ed38a 100644
--- a/src/libs/installer/fakestopprocessforupdateoperation.h
+++ b/src/libs/installer/fakestopprocessforupdateoperation.h
@@ -43,13 +43,12 @@ class INSTALLER_EXPORT FakeStopProcessForUpdateOperation : public QObject, publi
Q_OBJECT
public:
- FakeStopProcessForUpdateOperation();
+ explicit FakeStopProcessForUpdateOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
}
diff --git a/src/libs/installer/fileio.cpp b/src/libs/installer/fileio.cpp
index 5817d148c..8921f7257 100644
--- a/src/libs/installer/fileio.cpp
+++ b/src/libs/installer/fileio.cpp
@@ -38,6 +38,7 @@
#include <QCoreApplication>
#include <QByteArray>
+#include <QDir>
#include <QFileDevice>
#include <QString>
@@ -107,7 +108,8 @@ void QInstaller::openForRead(QFileDevice *dev)
Q_ASSERT(dev);
if (!dev->open(QIODevice::ReadOnly)) {
throw Error(QCoreApplication::translate("QInstaller",
- "Cannot open file %1 for reading: %2").arg(dev->fileName(), dev->errorString()));
+ "Cannot open file \"%1\" for reading: %2").arg(
+ QDir::toNativeSeparators(dev->fileName()), dev->errorString()));
}
}
@@ -116,7 +118,8 @@ void QInstaller::openForWrite(QFileDevice *dev)
Q_ASSERT(dev);
if (!dev->open(QIODevice::WriteOnly)) {
throw Error(QCoreApplication::translate("QInstaller",
- "Cannot open file %1 for writing: %2").arg(dev->fileName(), dev->errorString()));
+ "Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(dev->fileName()), dev->errorString()));
}
}
@@ -125,7 +128,8 @@ void QInstaller::openForAppend(QFileDevice *dev)
Q_ASSERT(dev);
if (!dev->open(QIODevice::WriteOnly | QIODevice::Append)) {
throw Error(QCoreApplication::translate("QInstaller",
- "Cannot open file %1 for writing: %2").arg(dev->fileName(), dev->errorString()));
+ "Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(dev->fileName()), dev->errorString()));
}
}
@@ -159,7 +163,7 @@ qint64 QInstaller::blockingCopy(QFileDevice *in, QFileDevice *out, qint64 size)
size -= actual;
actual = qMin(blockSize, size);
} catch (const Error &error) {
- throw Error(QCoreApplication::translate("QInstaller", "Copy failed. Error: %1")
+ throw Error(QCoreApplication::translate("QInstaller", "Copy failed: %1")
.arg(error.message()));
}
}
diff --git a/src/libs/installer/fileutils.cpp b/src/libs/installer/fileutils.cpp
index 79dc4273e..04a24ad8e 100644
--- a/src/libs/installer/fileutils.cpp
+++ b/src/libs/installer/fileutils.cpp
@@ -181,10 +181,11 @@ void QInstaller::removeFiles(const QString &path, bool ignoreErrors)
QFile f(fi.filePath());
if (!f.remove()) {
const QString errorMessage = QCoreApplication::translate("QInstaller",
- "Could not remove file %1: %2").arg(f.fileName(), f.errorString());
+ "Cannot remove file \"%1\": %2").arg(
+ QDir::toNativeSeparators(f.fileName()), f.errorString());
if (!ignoreErrors)
throw Error(errorMessage);
- qWarning() << errorMessage;
+ qWarning().noquote() << errorMessage;
}
}
}
@@ -222,10 +223,11 @@ void QInstaller::removeDirectory(const QString &path, bool ignoreErrors)
errno = 0;
if (d.exists(path) && !d.rmdir(dir)) {
const QString errorMessage = QCoreApplication::translate("QInstaller",
- "Could not remove folder %1: %2").arg(dir, errnoToQString(errno));
+ "Cannot remove directory \"%1\": %2").arg(QDir::toNativeSeparators(dir),
+ errnoToQString(errno));
if (!ignoreErrors)
throw Error(errorMessage);
- qWarning() << errorMessage;
+ qWarning().noquote() << errorMessage;
}
}
}
@@ -269,7 +271,7 @@ void QInstaller::removeDirectoryThreaded(const QString &path, bool ignoreErrors)
{
RemoveDirectoryThread thread(path, ignoreErrors);
QEventLoop loop;
- QObject::connect(&thread, SIGNAL(finished()), &loop, SLOT(quit()));
+ QObject::connect(&thread, &RemoveDirectoryThread::finished, &loop, &QEventLoop::quit);
thread.start();
loop.exec();
if (!thread.error().isEmpty())
@@ -292,8 +294,8 @@ void QInstaller::copyDirectoryContents(const QString &sourceDir, const QString &
Q_ASSERT(QFileInfo(sourceDir).isDir());
Q_ASSERT(!QFileInfo(targetDir).exists() || QFileInfo(targetDir).isDir());
if (!QDir().mkpath(targetDir)) {
- throw Error(QCoreApplication::translate("QInstaller", "Could not create folder %1")
- .arg(targetDir));
+ throw Error(QCoreApplication::translate("QInstaller", "Cannot create directory \"%1\".")
+ .arg(QDir::toNativeSeparators(targetDir)));
}
QDirIterator it(sourceDir, QDir::NoDotAndDotDot | QDir::AllEntries);
while (it.hasNext()) {
@@ -306,8 +308,10 @@ void QInstaller::copyDirectoryContents(const QString &sourceDir, const QString &
const QString target = QDir(targetDir).absoluteFilePath(i.fileName());
if (!f.copy(target)) {
throw Error(QCoreApplication::translate("QInstaller",
- "Could not copy file from %1 to %2: %3").arg(f.fileName(), target,
- f.errorString()));
+ "Cannot copy file from \"%1\" to \"%2\": %3").arg(
+ QDir::toNativeSeparators(f.fileName()),
+ QDir::toNativeSeparators(target),
+ f.errorString()));
}
}
}
@@ -318,8 +322,8 @@ void QInstaller::moveDirectoryContents(const QString &sourceDir, const QString &
Q_ASSERT(QFileInfo(sourceDir).isDir());
Q_ASSERT(!QFileInfo(targetDir).exists() || QFileInfo(targetDir).isDir());
if (!QDir().mkpath(targetDir)) {
- throw Error(QCoreApplication::translate("QInstaller", "Could not create folder %1")
- .arg(targetDir));
+ throw Error(QCoreApplication::translate("QInstaller", "Cannot create directory \"%1\".")
+ .arg(QDir::toNativeSeparators(targetDir)));
}
QDirIterator it(sourceDir, QDir::NoDotAndDotDot | QDir::AllEntries);
while (it.hasNext()) {
@@ -335,8 +339,10 @@ void QInstaller::moveDirectoryContents(const QString &sourceDir, const QString &
const QString target = QDir(targetDir).absoluteFilePath(i.fileName());
if (!f.rename(target)) {
throw Error(QCoreApplication::translate("QInstaller",
- "Could not move file from %1 to %2: %3").arg(f.fileName(), target,
- f.errorString()));
+ "Cannot move file from \"%1\" to \"%2\": %3").arg(
+ QDir::toNativeSeparators(f.fileName()),
+ QDir::toNativeSeparators(target),
+ f.errorString()));
}
}
}
@@ -346,8 +352,8 @@ void QInstaller::mkdir(const QString &path)
{
errno = 0;
if (!QDir().mkdir(QFileInfo(path).absoluteFilePath())) {
- throw Error(QCoreApplication::translate("QInstaller", "Could not create folder %1: %2")
- .arg(path, errnoToQString(errno)));
+ throw Error(QCoreApplication::translate("QInstaller", "Cannot create directory \"%1\": %2")
+ .arg(QDir::toNativeSeparators(path), errnoToQString(errno)));
}
}
@@ -355,8 +361,8 @@ void QInstaller::mkpath(const QString &path)
{
errno = 0;
if (!QDir().mkpath(QFileInfo(path).absoluteFilePath())) {
- throw Error(QCoreApplication::translate("QInstaller", "Could not create folder %1: %2")
- .arg(path, errnoToQString(errno)));
+ throw Error(QCoreApplication::translate("QInstaller", "Cannot create directory \"%1\": %2")
+ .arg(QDir::toNativeSeparators(path), errnoToQString(errno)));
}
}
@@ -366,7 +372,7 @@ QString QInstaller::generateTemporaryFileName(const QString &templ)
QTemporaryFile f;
if (!f.open()) {
throw Error(QCoreApplication::translate("QInstaller",
- "Could not open temporary file: %1").arg(f.errorString()));
+ "Cannot open temporary file: %1").arg(f.errorString()));
}
return f.fileName();
}
@@ -385,7 +391,7 @@ QString QInstaller::generateTemporaryFileName(const QString &templ)
QFile f(tmp.arg(templ, suffix).arg(count));
if (!f.open(QIODevice::WriteOnly)) {
throw Error(QCoreApplication::translate("QInstaller",
- "Could not open temporary file for template %1: %2").arg(templ, f.errorString()));
+ "Cannot open temporary file for template %1: %2").arg(templ, f.errorString()));
}
f.remove();
return f.fileName();
@@ -486,14 +492,13 @@ void QInstaller::setApplicationIcon(const QString &application, const QString &i
{
QFile iconFile(icon);
if (!iconFile.open(QIODevice::ReadOnly)) {
- qWarning() << QString::fromLatin1("Could not use '%1' as application icon: %2.")
- .arg(icon, iconFile.errorString());
+ qWarning() << "Cannot use" << icon << "as an application icon:" << iconFile.errorString();
return;
}
if (QImageReader::imageFormat(icon) != "ico") {
- qWarning() << QString::fromLatin1("Could not use '%1' as application icon, unsupported format %2.")
- .arg(icon, QLatin1String(QImageReader::imageFormat(icon)));
+ qWarning() << "Cannot use" << icon << "as an application icon, unsupported format"
+ << QImageReader::imageFormat(icon).constData();
return;
}
@@ -579,3 +584,19 @@ bool QInstaller::isInBundle(const QString &path, QString *bundlePath)
#endif
return false;
}
+
+/*!
+ Replaces the path \a before with the path \a after at the beginning of \a path and returns
+ the replaced path. If \a before cannot be found in \a path, the original value is returned.
+*/
+QString QInstaller::replacePath(const QString &path, const QString &before, const QString &after)
+{
+ if (path.isEmpty() || before.isEmpty())
+ return path;
+
+ QString pathToPatch = QDir::cleanPath(path);
+ const QString pathToReplace = QDir::cleanPath(before);
+ if (pathToPatch.startsWith(pathToReplace))
+ return QDir::cleanPath(after) + pathToPatch.mid(pathToReplace.size());
+ return path;
+}
diff --git a/src/libs/installer/fileutils.h b/src/libs/installer/fileutils.h
index 45f3a9acf..a9235df67 100644
--- a/src/libs/installer/fileutils.h
+++ b/src/libs/installer/fileutils.h
@@ -99,6 +99,8 @@ private:
quint64 INSTALLER_EXPORT fileSize(const QFileInfo &info);
bool INSTALLER_EXPORT isInBundle(const QString &path, QString *bundlePath = 0);
+ QString replacePath(const QString &path, const QString &pathBefore, const QString &pathAfter);
+
#ifdef Q_OS_WIN
QString INSTALLER_EXPORT getLongPathName(const QString &name);
QString INSTALLER_EXPORT getShortPathName(const QString &name);
diff --git a/src/libs/installer/globalsettingsoperation.cpp b/src/libs/installer/globalsettingsoperation.cpp
index 0dcc990e8..c266d5c57 100644
--- a/src/libs/installer/globalsettingsoperation.cpp
+++ b/src/libs/installer/globalsettingsoperation.cpp
@@ -36,7 +36,8 @@
using namespace QInstaller;
-GlobalSettingsOperation::GlobalSettingsOperation()
+GlobalSettingsOperation::GlobalSettingsOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("GlobalConfig"));
}
@@ -54,7 +55,7 @@ bool GlobalSettingsOperation::performOperation()
if (!settings->isWritable()) {
setError(UserDefinedError);
- setErrorString(tr("Settings are not writable"));
+ setErrorString(tr("Settings are not writable."));
return false;
}
@@ -64,7 +65,7 @@ bool GlobalSettingsOperation::performOperation()
if (settings->status() != QSettingsWrapper::NoError) {
setError(UserDefinedError);
- setErrorString(tr("Failed to write settings"));
+ setErrorString(tr("Failed to write settings."));
return false;
}
@@ -97,24 +98,15 @@ bool GlobalSettingsOperation::testOperation()
return true;
}
-Operation *GlobalSettingsOperation::clone() const
-{
- return new GlobalSettingsOperation();
-}
-
QSettingsWrapper *GlobalSettingsOperation::setup(QString *key, QString *value, const QStringList &arguments)
{
- if (arguments.count() != 3 && arguments.count() != 4 && arguments.count() != 5) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments.count()).arg(tr("3, 4 or 5"), QLatin1String("")));
+ if (!checkArgumentCount(3, 5))
return 0;
- }
if (arguments.count() == 5) {
QSettingsWrapper::Scope scope = QSettingsWrapper::UserScope;
if (arguments.at(0) == QLatin1String("SystemScope"))
- scope = QSettingsWrapper::SystemScope;
+ scope = QSettingsWrapper::SystemScope;
const QString &company = arguments.at(1);
const QString &application = arguments.at(2);
*key = arguments.at(3);
diff --git a/src/libs/installer/globalsettingsoperation.h b/src/libs/installer/globalsettingsoperation.h
index dab8866db..d64b13ce4 100644
--- a/src/libs/installer/globalsettingsoperation.h
+++ b/src/libs/installer/globalsettingsoperation.h
@@ -42,13 +42,12 @@ class QSettingsWrapper;
class INSTALLER_EXPORT GlobalSettingsOperation : public Operation
{
public:
- GlobalSettingsOperation();
+ explicit GlobalSettingsOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
private:
QSettingsWrapper *setup(QString *key, QString *value, const QStringList &args);
diff --git a/src/libs/installer/init.cpp b/src/libs/installer/init.cpp
index 9eb49669a..fffd21320 100644
--- a/src/libs/installer/init.cpp
+++ b/src/libs/installer/init.cpp
@@ -53,75 +53,20 @@
#include "settingsoperation.h"
#include "consumeoutputoperation.h"
-
+#include "lib7z_facade.h"
#include "utils.h"
-#include "kdupdaterupdateoperationfactory.h"
-#include "kdupdaterfiledownloaderfactory.h"
-
-#include "7zCrc.h"
+#include "updateoperationfactory.h"
+#include "filedownloaderfactory.h"
#include <QtPlugin>
#include <QElapsedTimer>
#include <iostream>
-namespace NArchive {
- namespace NXz {
- void registerArcxz();
- }
- namespace NSplit {
- void registerArcSplit();
- }
- namespace NLzma {
- namespace NLzmaAr {
- void registerArcLzma();
- }
- namespace NLzma86Ar {
- void registerArcLzma86();
- }
- }
-}
-
-void registerArc7z();
-
-void registerCodecBCJ();
-void registerCodecBCJ2();
-
-void registerCodecCopy();
-void registerCodecLZMA();
-void registerCodecLZMA2();
-
-void registerCodecDelta();
-void registerCodecBranch();
-void registerCodecByteSwap();
-
using namespace KDUpdater;
using namespace QInstaller;
-static void initArchives()
-{
- CrcGenerateTable();
-
- registerArc7z();
-
- registerCodecBCJ();
- registerCodecBCJ2();
-
- registerCodecCopy();
- registerCodecLZMA();
- registerCodecLZMA2();
-
- registerCodecDelta();
- registerCodecBranch();
- registerCodecByteSwap();
-
- NArchive::NXz::registerArcxz();
- NArchive::NSplit::registerArcSplit();
- NArchive::NLzma::NLzmaAr::registerArcLzma();
- NArchive::NLzma::NLzma86Ar::registerArcLzma86();
-}
-
#if defined(QT_STATIC)
static void initResources()
{
@@ -198,7 +143,8 @@ void messageHandler(QtMsgType type, const QMessageLogContext &context, const QSt
void QInstaller::init()
{
- ::initArchives();
+ Lib7z::initSevenZ();
+
#if defined(QT_STATIC)
::initResources();
#endif
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index cfa83d08d..ed27d61d6 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -125,7 +125,12 @@ HEADERS += packagemanagercore.h \
serverauthenticationdialog.h \
keepaliveobject.h \
systeminfo.h \
- localsocket.h
+ localsocket.h \
+ packagesource.h \
+ lib7z_guid.h \
+ lib7z_create.h \
+ lib7z_extract.h \
+ lib7z_list.h
SOURCES += packagemanagercore.cpp \
packagemanagercore_p.cpp \
@@ -199,7 +204,8 @@ SOURCES += packagemanagercore.cpp \
proxycredentialsdialog.cpp \
serverauthenticationdialog.cpp \
keepaliveobject.cpp \
- systeminfo.cpp
+ systeminfo.cpp \
+ packagesource.cpp
FORMS += proxycredentialsdialog.ui \
serverauthenticationdialog.ui
diff --git a/src/libs/installer/installercalculator.cpp b/src/libs/installer/installercalculator.cpp
index 0f92ecb3a..353335215 100644
--- a/src/libs/installer/installercalculator.cpp
+++ b/src/libs/installer/installercalculator.cpp
@@ -76,7 +76,7 @@ QString InstallerCalculator::installReason(Component *component) const
"Components added as automatic dependencies:");
case Dependent:
return QCoreApplication::translate("InstallerCalculator", "Components added as "
- "dependency for '%1':").arg(installReasonReferencedComponent(component));
+ "dependency for \"%1\":").arg(installReasonReferencedComponent(component));
case Resolved:
return QCoreApplication::translate("InstallerCalculator",
"Components that have resolved dependencies:");
@@ -107,8 +107,8 @@ void InstallerCalculator::realAppendToInstallComponents(Component *component)
QString InstallerCalculator::recursionError(Component *component)
{
- return QCoreApplication::translate("InstallerCalculator", "Recursion detected, component '%1' "
- "already added with reason: '%2'").arg(component->name(), installReason(component));
+ return QCoreApplication::translate("InstallerCalculator", "Recursion detected, component \"%1\" "
+ "already added with reason: \"%2\"").arg(component->name(), installReason(component));
}
bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &components)
@@ -120,7 +120,7 @@ bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &co
foreach (Component *component, components){
if (m_toInstallComponentIds.contains(component->name())) {
const QString errorMessage = recursionError(component);
- qWarning() << errorMessage;
+ qWarning().noquote() << errorMessage;
m_componentsToInstallError.append(errorMessage);
Q_ASSERT_X(!m_toInstallComponentIds.contains(component->name()), Q_FUNC_INFO,
qPrintable(errorMessage));
@@ -170,9 +170,9 @@ bool InstallerCalculator::appendComponentToInstall(Component *component)
PackageManagerCore::componentByName(dependencyComponentName, m_allComponents);
if (!dependencyComponent) {
const QString errorMessage = QCoreApplication::translate("InstallerCalculator",
- "Cannot find missing dependency '%1' for '%2'.").arg(dependencyComponentName,
+ "Cannot find missing dependency \"%1\" for \"%2\".").arg(dependencyComponentName,
component->name());
- qWarning() << errorMessage;
+ qWarning().noquote() << errorMessage;
m_componentsToInstallError.append(errorMessage);
return false;
}
@@ -181,7 +181,7 @@ bool InstallerCalculator::appendComponentToInstall(Component *component)
&& !m_toInstallComponentIds.contains(dependencyComponent->name())) {
if (m_visitedComponents.value(component).contains(dependencyComponent)) {
const QString errorMessage = recursionError(component);
- qWarning() << errorMessage;
+ qWarning().noquote() << errorMessage;
m_componentsToInstallError = errorMessage;
Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent),
Q_FUNC_INFO, qPrintable(errorMessage));
diff --git a/src/libs/installer/installiconsoperation.cpp b/src/libs/installer/installiconsoperation.cpp
index e5622dc2e..a91b644b8 100644
--- a/src/libs/installer/installiconsoperation.cpp
+++ b/src/libs/installer/installiconsoperation.cpp
@@ -91,7 +91,8 @@ QString InstallIconsOperation::targetDirectory()
return directory;
}
-InstallIconsOperation::InstallIconsOperation()
+InstallIconsOperation::InstallIconsOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("InstallIcons"));
}
@@ -108,20 +109,16 @@ void InstallIconsOperation::backup()
bool InstallIconsOperation::performOperation()
{
- const QStringList args = arguments();
- if ((args.count() != 1) && (args.count() != 2)) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("1 or 2"), tr(" (Sourcepath, [Vendorprefix])")));
+ if (!checkArgumentCount(1, 2, tr("<source path> [vendor prefix]")))
return false;
- }
+ const QStringList args = arguments();
const QString source = args.at(0);
- const QString vendor = args.value(1);
+ const QString vendor = args.value(1); // value() used since it's optional
if (source.isEmpty()) {
setError(InvalidArguments);
- setErrorString(tr("Invalid Argument: source folder must not be empty."));
+ setErrorString(tr("Invalid Argument: source directory must not be empty."));
return false;
}
@@ -132,7 +129,7 @@ bool InstallIconsOperation::performOperation()
QStringList backupFiles;
QStringList createdDirectories;
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ PackageManagerCore *const core = packageManager();
// iterate a second time to get the actual work done
QDirIterator it(sourceDir.path(), QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot,
@@ -170,7 +167,8 @@ bool InstallIconsOperation::performOperation()
QFile bf(target);
if (!bf.copy(backup)) {
setError(UserDefinedError);
- setErrorString(tr("Could not backup file %1: %2").arg(target, bf.errorString()));
+ setErrorString(tr("Cannot backup file \"%1\": %2").arg(
+ QDir::toNativeSeparators(target), bf.errorString()));
undoOperation();
return false;
}
@@ -183,7 +181,8 @@ bool InstallIconsOperation::performOperation()
QString errStr;
if (!deleteFileNowOrLater(target, &errStr)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to overwrite %1: %2").arg(target, errStr));
+ setErrorString(tr("Failed to overwrite \"%1\": %2").arg(
+ QDir::toNativeSeparators(target), errStr));
undoOperation();
return false;
}
@@ -194,7 +193,8 @@ bool InstallIconsOperation::performOperation()
QFile cf(source);
if (!cf.copy(target)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to copy file %1: %2").arg(target, cf.errorString()));
+ setErrorString(tr("Failed to copy file \"%1\": %2").arg(
+ QDir::toNativeSeparators(target), cf.errorString()));
undoOperation();
return false;
}
@@ -204,7 +204,8 @@ bool InstallIconsOperation::performOperation()
setValue(QLatin1String("files"), files);
} else if (fi.isDir() && !QDir(target).exists()) {
if (!QDir().mkpath(target)) {
- setErrorString(tr("Could not create folder at %1: %2").arg(target, qt_error_string()));
+ setErrorString(tr("Cannot create directory \"%1\": %2").arg(
+ QDir::toNativeSeparators(target), qt_error_string()));
undoOperation();
return false;
}
@@ -236,7 +237,7 @@ bool InstallIconsOperation::undoOperation()
QFile installedTarget(target);
if (installedTarget.exists() && !(installedTarget.copy(source) && installedTarget.remove())) {
- warningMessages << QString::fromLatin1("Could not move file from '%1' to '%2', error: %3)").arg(
+ warningMessages << QString::fromLatin1("Cannot move file from \"%1\" to \"%2\": %3)").arg(
target, source, installedTarget.errorString());
}
}
@@ -252,13 +253,13 @@ bool InstallIconsOperation::undoOperation()
deleteFileNowOrLater(target);
// then copy the backup onto the target
if (!QFile::copy(backup, target)) {
- warningMessages << QString::fromLatin1("Could not restore the backup '%1' to '%2'").arg(
+ warningMessages << QString::fromLatin1("Cannot restore the backup \"%1\" to \"%2\".").arg(
backup, target);
}
// finally remove the backp
if (!deleteFileNowOrLater(backup))
- warningMessages << QString::fromLatin1("Could not remove the backup '%1'").arg(backup);
+ warningMessages << QString::fromLatin1("Cannot remove the backup \"%1\".").arg(backup);
}
@@ -268,14 +269,14 @@ bool InstallIconsOperation::undoOperation()
const QDir dir(*it);
removeSystemGeneratedFiles(dir.absolutePath());
if (dir.exists() && !QDir::root().rmdir(dir.path()))
- warningMessages << QString::fromLatin1("Could not remove directory '%1'").arg(dir.path());
+ warningMessages << QString::fromLatin1("Cannot remove directory \"%1\".").arg(dir.path());
}
if (!warningMessages.isEmpty()) {
- qWarning() << QString::fromLatin1("Undo of operation '%1' with arguments '%2' had some problems.").arg(
- name(), arguments().join(QLatin1String(", ")));
+ qWarning() << "Undo of operation" << name() << "with arguments"
+ << arguments().join(QLatin1String(", ")) << "had some problems.";
foreach (const QString &message, warningMessages) {
- qWarning() << message;
+ qWarning().noquote() << message;
}
}
@@ -286,8 +287,3 @@ bool InstallIconsOperation::testOperation()
{
return true;
}
-
-Operation *InstallIconsOperation::clone() const
-{
- return new InstallIconsOperation();
-}
diff --git a/src/libs/installer/installiconsoperation.h b/src/libs/installer/installiconsoperation.h
index 534317d2b..ad3362098 100644
--- a/src/libs/installer/installiconsoperation.h
+++ b/src/libs/installer/installiconsoperation.h
@@ -44,14 +44,13 @@ class INSTALLER_EXPORT InstallIconsOperation : public QObject, public Operation
{
Q_OBJECT
public:
- InstallIconsOperation();
+ explicit InstallIconsOperation(PackageManagerCore *core);
~InstallIconsOperation();
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
Q_SIGNALS:
void outputTextChanged(const QString &progress);
diff --git a/src/libs/installer/lib7z_create.h b/src/libs/installer/lib7z_create.h
new file mode 100644
index 000000000..73cf1299c
--- /dev/null
+++ b/src/libs/installer/lib7z_create.h
@@ -0,0 +1,82 @@
+/**************************************************************************
+**
+** 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$
+**
+**************************************************************************/
+#ifndef LIB7Z_CREATE_H
+#define LIB7Z_CREATE_H
+
+#include "installer_global.h"
+
+#include <Common/MyCom.h>
+#include <7zip/UI/Common/Update.h>
+
+QT_BEGIN_NAMESPACE
+class QFileDevice;
+class QStringList;
+QT_END_NAMESPACE
+
+namespace Lib7z
+{
+ enum struct QTmpFile {
+ No,
+ Yes
+ };
+
+ enum struct Compression {
+ Non = 0,
+ Fastest = 1,
+ Fast = 3,
+ Normal = 5,
+ Maximum = 7,
+ Ultra = 9
+ };
+
+ class INSTALLER_EXPORT UpdateCallback : public IUpdateCallbackUI2, public CMyUnknownImp
+ {
+ Q_DISABLE_COPY(UpdateCallback)
+
+ public:
+ UpdateCallback() = default;
+ virtual ~UpdateCallback() {}
+
+ MY_UNKNOWN_IMP
+ INTERFACE_IUpdateCallbackUI2(;)
+ };
+
+ void INSTALLER_EXPORT createArchive(QFileDevice *archive, const QStringList &sources,
+ Compression level = Compression::Normal, UpdateCallback *callback = 0);
+ void INSTALLER_EXPORT createArchive(const QString &archive, const QStringList &sources,
+ QTmpFile mode, Compression level = Compression::Normal, UpdateCallback *callback = 0);
+
+} // namespace Lib7z
+
+#endif // LIB7Z_CREATE_H
diff --git a/src/libs/installer/lib7z_extract.h b/src/libs/installer/lib7z_extract.h
new file mode 100644
index 000000000..f6182c727
--- /dev/null
+++ b/src/libs/installer/lib7z_extract.h
@@ -0,0 +1,85 @@
+/**************************************************************************
+**
+** 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$
+**
+**************************************************************************/
+#ifndef LIB7Z_EXTRACT_H
+#define LIB7Z_EXTRACT_H
+
+#include "installer_global.h"
+
+#include <Common/MyCom.h>
+#include <7zip/Archive/IArchive.h>
+
+#include <QString>
+
+class CArc;
+
+QT_BEGIN_NAMESPACE
+class QFileDevice;
+QT_END_NAMESPACE
+
+namespace Lib7z
+{
+ class INSTALLER_EXPORT ExtractCallback : public IArchiveExtractCallback, public CMyUnknownImp
+ {
+ Q_DISABLE_COPY(ExtractCallback)
+
+ public:
+ ExtractCallback() = default;
+ virtual ~ExtractCallback() = default;
+
+ void setArchive(CArc *carc) { arc = carc; }
+ void setTarget(const QString &dir) { targetDir = dir; }
+
+ MY_UNKNOWN_IMP
+ INTERFACE_IArchiveExtractCallback(;)
+
+ protected:
+ virtual bool prepareForFile(const QString & /*filename*/) { return true; }
+ virtual void setCurrentFile(const QString &filename) { Q_UNUSED(filename) }
+ virtual HRESULT setCompleted(quint64 /*completed*/, quint64 /*total*/) { return S_OK; }
+
+ private:
+ CArc *arc = 0;
+
+ QString targetDir;
+ quint64 total = 0;
+ quint64 completed = 0;
+ quint32 currentIndex = 0;
+ };
+
+ void INSTALLER_EXPORT extractArchive(QFileDevice *archive, const QString &targetDirectory,
+ ExtractCallback *callback = 0);
+
+} // namespace Lib7z
+
+#endif // LIB7Z_EXTRACT_H
diff --git a/src/libs/installer/lib7z_facade.cpp b/src/libs/installer/lib7z_facade.cpp
index 8f21343db..86dc86e7a 100644
--- a/src/libs/installer/lib7z_facade.cpp
+++ b/src/libs/installer/lib7z_facade.cpp
@@ -30,106 +30,199 @@
** $QT_END_LICENSE$
**
**************************************************************************/
+
#include "lib7z_facade.h"
#include "errors.h"
#include "fileio.h"
+#include "lib7z_create.h"
+#include "lib7z_extract.h"
+#include "lib7z_list.h"
+#include "lib7z_guid.h"
+
#ifndef Q_OS_WIN
# include "StdAfx.h"
#endif
-#include "Common/MyInitGuid.h"
+#include <7zCrc.h>
+
+#include <7zip/Archive/IArchive.h>
-#include "7zip/Archive/IArchive.h"
-#include "7zip/UI/Common/OpenArchive.h"
-#include "7zip/UI/Common/Update.h"
+#include <7zip/UI/Common/ArchiveCommandLine.h>
+#include <7zip/UI/Common/OpenArchive.h>
-#include "Windows/FileIO.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
+#include <Windows/FileDir.h>
+#include <Windows/FileIO.h>
+#include <Windows/PropVariant.h>
+#include <Windows/PropVariantConv.h>
+#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QIODevice>
-#include <QtCore/QMutexLocker>
#include <QPointer>
-#include <QTemporaryFile>
#include <QReadWriteLock>
+#include <QTemporaryFile>
-#ifdef _MSC_VER
-#pragma warning(disable:4297)
-#endif
+#include <mutex>
+#include <memory>
#ifdef Q_OS_WIN
+HINSTANCE g_hInstance = 0;
+
+# define S_IFMT 00170000
+# define S_IFLNK 0120000
+# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+# define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 /* trick for Unix */
+# if !defined(Q_CC_MINGW)
+# include <time.h> // for localtime_s
+# endif
+#else
+extern "C" int global_use_utf16_conversion;
+
+#include <myWindows/config.h>
+#include <sys/stat.h>
+#endif
+
+namespace NArchive {
+ namespace N7z {
+ void registerArcDec7z();
+ }
+ namespace NXz {
+ void registerArcxz();
+ }
+ namespace NSplit {
+ void registerArcSplit();
+ }
+ namespace NLzma {
+ namespace NLzmaAr {
+ void registerArcLzma();
+ }
+ namespace NLzma86Ar {
+ void registerArcLzma86();
+ }
+ }
+}
+using namespace NWindows;
+
+void registerCodecBCJ();
+void registerCodecBCJ2();
+
+void registerCodecLZMA();
+void registerCodecLZMA2();
+
+void registerCodecCopy();
+void registerCodecDelta();
+void registerCodecBranch();
+void registerCodecByteSwap();
+
+namespace Lib7z {
+
-#include <time.h>
-#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 /* trick for Unix */
-#define S_IFMT 00170000
-#define S_IFLNK 0120000
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+// -- 7z init codecs, archives
-typedef BOOL (WINAPI *CREATEHARDLINK)(LPCSTR dst, LPCSTR str, LPSECURITY_ATTRIBUTES sa);
+std::once_flag gOnceFlag;
-bool CreateHardLinkWrapper(const QString &dest, const QString &file)
+void initSevenZ()
{
- static HMODULE module = 0;
- static CREATEHARDLINK proc = 0;
+ std::call_once(gOnceFlag, [] {
+ CrcGenerateTable();
- if (module == 0)
- module = LoadLibrary(L"kernel32.dll");
- if (module == 0)
- return false;
- if (proc == 0)
- proc = (CREATEHARDLINK) GetProcAddress(module, "CreateHardLinkA");
- if (proc == 0)
- return false;
- QString target = file;
- if (!QFileInfo(file).isAbsolute())
- {
- target = QFileInfo(dest).dir().absoluteFilePath(file);
- }
- const QString link = QDir::toNativeSeparators(dest);
- const QString existingFile = QDir::toNativeSeparators(target);
- return proc(link.toLocal8Bit(), existingFile.toLocal8Bit(), 0);
-}
+ registerCodecBCJ();
+ registerCodecBCJ2();
-#else
-#include <sys/stat.h>
+ registerCodecLZMA();
+ registerCodecLZMA2();
+
+ registerCodecCopy();
+ registerCodecDelta();
+ registerCodecBranch();
+ registerCodecByteSwap();
+
+ NArchive::N7z::registerArcDec7z();
+ NArchive::NXz::registerArcxz();
+ NArchive::NSplit::registerArcSplit();
+ NArchive::NLzma::NLzmaAr::registerArcLzma();
+ NArchive::NLzma::NLzma86Ar::registerArcLzma86();
+
+#ifndef Q_OS_WIN
+# ifdef ENV_HAVE_LOCALE
+ const QByteArray locale = qgetenv("LC_ALL").toUpper();
+ if (!locale.isEmpty() && (locale != "C") && (locale != "POSIX"))
+ global_use_utf16_conversion = 1;
+# elif defined(LOCALE_IS_UTF8)
+ global_use_utf16_conversion = 1;
+# else
+ global_use_utf16_conversion = 0;
+# endif
#endif
+ });
+}
-#include <memory>
-#include <cassert>
+// -- error handling
-using namespace Lib7z;
-using namespace NWindows;
+Q_GLOBAL_STATIC(QString, getLastErrorString)
+Q_GLOBAL_STATIC(QReadWriteLock, lastErrorReadWriteLock)
+QString lastError()
+{
+ QReadLocker locker(lastErrorReadWriteLock());
+ Q_UNUSED(locker)
+ return *getLastErrorString();
+}
-namespace Lib7z {
- Q_GLOBAL_STATIC(QReadWriteLock, lastErrorReadWriteLock)
- Q_GLOBAL_STATIC(QString, getLastErrorString)
+void setLastError(const QString &errorString)
+{
+ QWriteLocker locker(lastErrorReadWriteLock());
+ Q_UNUSED(locker)
+ *getLastErrorString() = errorString;
+}
- QString lastError()
- {
- QReadLocker locker(lastErrorReadWriteLock());
- Q_UNUSED(locker)
- return *getLastErrorString();
- }
+QString errorMessageFrom7zResult(const LONG &extractResult)
+{
+ if (!lastError().isEmpty())
+ return lastError();
- void setLastError(const QString &errorString)
- {
- QWriteLocker locker(lastErrorReadWriteLock());
- Q_UNUSED(locker)
- *getLastErrorString() = errorString;
+ QString errorMessage = QCoreApplication::translate("Lib7z", "internal code: %1");
+ switch (extractResult) {
+ case S_OK:
+ qFatal("S_OK value is not a valid error code.");
+ break;
+ case E_NOTIMPL:
+ errorMessage = errorMessage.arg(QLatin1String("E_NOTIMPL"));
+ break;
+ case E_NOINTERFACE:
+ errorMessage = errorMessage.arg(QLatin1String("E_NOINTERFACE"));
+ break;
+ case E_ABORT:
+ errorMessage = errorMessage.arg(QLatin1String("E_ABORT"));
+ break;
+ case E_FAIL:
+ errorMessage = errorMessage.arg(QLatin1String("E_FAIL"));
+ break;
+ case STG_E_INVALIDFUNCTION:
+ errorMessage = errorMessage.arg(QLatin1String("STG_E_INVALIDFUNCTION"));
+ break;
+ case E_OUTOFMEMORY:
+ errorMessage = QCoreApplication::translate("Lib7z", "not enough memory");
+ break;
+ case E_INVALIDARG:
+ errorMessage = errorMessage.arg(QLatin1String("E_INVALIDARG"));
+ break;
+ default:
+ errorMessage = QCoreApplication::translate("Lib7z", "Error: %1").arg(extractResult);
+ break;
}
+ return errorMessage;
}
-namespace {
-/**
-* RAII class to create a directory (tryCreate()) and delete it on destruction unless released.
+/*!
+ RAII class to create a directory (tryCreate()) and delete it on destruction unless released.
*/
-struct DirectoryGuard {
+struct DirectoryGuard
+{
explicit DirectoryGuard(const QString &path)
: m_path(path)
, m_created(false)
@@ -144,14 +237,15 @@ struct DirectoryGuard {
return;
QDir dir(m_path);
if (!dir.rmdir(m_path))
- qWarning() << "Could not delete directory " << m_path;
+ qWarning() << "Cannot delete directory " << m_path;
}
- /**
- * Tries to create the directorie structure.
- * Returns a list of every directory created.
+ /*!
+ Tries to create the directory structure.
+ Returns a list of every directory created.
*/
- QStringList tryCreate() {
+ QStringList tryCreate()
+ {
if (m_path.isEmpty())
return QStringList();
@@ -160,13 +254,12 @@ struct DirectoryGuard {
return QStringList();
if (fi.exists() && !fi.isDir()) {
throw SevenZipException(QCoreApplication::translate("DirectoryGuard",
- "Path exists but is not a folder: %1").arg(m_path));
+ "Path \"%1\" exists but is not a directory.").arg(QDir::toNativeSeparators(m_path)));
}
QStringList created;
QDir toCreate(m_path);
- while (!toCreate.exists())
- {
+ while (!toCreate.exists()) {
QString p = toCreate.absolutePath();
created.push_front(p);
p = p.section(QLatin1Char('/'), 0, -2);
@@ -177,12 +270,13 @@ struct DirectoryGuard {
m_created = dir.mkpath(m_path);
if (!m_created) {
throw SevenZipException(QCoreApplication::translate("DirectoryGuard",
- "Could not create folder: %1").arg(m_path));
+ "Cannot create directory \"%1\".").arg(QDir::toNativeSeparators(m_path)));
}
return created;
}
- void release() {
+ void release()
+ {
m_released = true;
}
@@ -190,7 +284,6 @@ struct DirectoryGuard {
bool m_created;
bool m_released;
};
-}
static UString QString2UString(const QString &str)
{
@@ -202,32 +295,12 @@ static QString UString2QString(const UString& str)
return QString::fromStdWString(static_cast<const wchar_t*>(str));
}
-static QString generateTempFileName()
-{
- QTemporaryFile tmp;
- if (!tmp.open()) {
- throw SevenZipException(QCoreApplication::translate("QInstaller",
- "Could not create temporary file"));
- }
- return QDir::toNativeSeparators(tmp.fileName());
-}
-
-/*
-static QStringList UStringVector2QStringList(const UStringVector& vec)
-{
-QStringList res;
-for (int i = 0; i < vec.Size(); ++i)
-res += UString2QString(vec[i]);
-return res;
-}
-*/
-
-static NCOM::CPropVariant readProperty(IInArchive* archive, int index, int propId)
+static NCOM::CPropVariant readProperty(IInArchive *archive, int index, int propId)
{
NCOM::CPropVariant prop;
if (archive->GetProperty(index, propId, &prop) != S_OK) {
- throw SevenZipException(QCoreApplication::translate("QInstaller",
- "Could not retrieve property %1 for item %2").arg(QString::number(propId),
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Cannot retrieve property %1 for item %2.").arg(QString::number(propId),
QString::number(index)));
}
return prop;
@@ -238,193 +311,134 @@ static bool IsFileTimeZero(const FILETIME *lpFileTime)
return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0);
}
-static bool IsDST(const QDateTime& datetime = QDateTime())
-{
- const time_t seconds = static_cast< time_t >(datetime.isValid() ? datetime.toTime_t()
- : QDateTime::currentDateTime().toTime_t());
-#if defined(Q_OS_WIN) && !defined(Q_CC_MINGW)
- struct tm t;
- localtime_s(&t, &seconds);
-#else
- const struct tm &t = *localtime(&seconds);
-#endif
- return t.tm_isdst;
-}
-
-static bool getFileTimeFromProperty(IInArchive* archive, int index, int propId, FILETIME *fileTime)
+static bool getFileTimeFromProperty(IInArchive* archive, int index, int propId, FILETIME *ft)
{
const NCOM::CPropVariant prop = readProperty(archive, index, propId);
if (prop.vt != VT_FILETIME) {
- throw SevenZipException(QCoreApplication::translate("QInstaller",
- "Property %1 for item %2 not of type VT_FILETIME but %3").arg(QString::number(propId),
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Property %1 for item %2 not of type VT_FILETIME but %3.").arg(QString::number(propId),
QString::number(index), QString::number(prop.vt)));
}
- *fileTime = prop.filetime;
-
- if (IsFileTimeZero(fileTime))
- return false;
- return true;
+ *ft = prop.filetime;
+ return !IsFileTimeZero(ft);
}
-static
-QDateTime getDateTimeProperty(IInArchive* archive, int index, int propId, const QDateTime& defaultValue)
+static bool getDateTimeProperty(IInArchive *arc, int index, int id, QDateTime *value)
{
- FILETIME fileTime;
- if (!getFileTimeFromProperty(archive, index, propId, &fileTime))
- return defaultValue;
+ FILETIME ft7z;
+ if (!getFileTimeFromProperty(arc, index, id, &ft7z))
+ return false;
- FILETIME localFileTime;
- if (!FileTimeToLocalFileTime(&fileTime, &localFileTime)) {
- throw SevenZipException(QCoreApplication::translate("QInstaller",
- "Could not convert file time to local time"));
- }
SYSTEMTIME st;
- if (!BOOLToBool(FileTimeToSystemTime(&localFileTime, &st))) {
- throw SevenZipException(QCoreApplication::translate("QInstaller",
- "Could not convert local file time to system time"));
+ if (!BOOLToBool(FileTimeToSystemTime(&ft7z, &st))) {
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Cannot convert UTC file time to system time."));
}
- const QDate date(st.wYear, st.wMonth, st.wDay);
- const QTime time(st.wHour, st.wMinute, st.wSecond);
- QDateTime result(date, time);
-
- // fix daylight saving time
- const bool dst = IsDST();
- if (dst != IsDST(result))
- result = result.addSecs(dst ? -3600 : 3600);
-
- return result;
+ *value = QDateTime(QDate(st.wYear, st.wMonth, st.wDay), QTime(st.wHour, st.wMinute,
+ st.wSecond), Qt::UTC);
+ return value->isValid();
}
-static quint64 getUInt64Property(IInArchive* archive, int index, int propId, quint64 defaultValue=0)
+static quint64 getUInt64Property(IInArchive *archive, int index, int propId, quint64 defaultValue)
{
- const NCOM::CPropVariant prop = readProperty(archive, index, propId);
- if (prop.vt == VT_EMPTY)
- return defaultValue;
- return static_cast<quint64>(ConvertPropVariantToUInt64(prop));
+ UInt64 value;
+ if (ConvertPropVariantToUInt64(readProperty(archive, index, propId), value))
+ return value;
+ return defaultValue;
}
-static quint32 getUInt32Property(IInArchive* archive, int index, int propId, quint32 defaultValue=0)
+static quint32 getUInt32Property(IInArchive *archive, int index, int propId, quint32 defaultValue)
{
const NCOM::CPropVariant prop = readProperty(archive, index, propId);
if (prop.vt == VT_EMPTY)
return defaultValue;
- return static_cast< quint32 >(prop.ulVal);
+ return static_cast<quint32>(prop.ulVal);
}
-static QFile::Permissions getPermissions(IInArchive* archive, int index, bool* hasPermissions = 0)
+static QFile::Permissions getPermissions(IInArchive *archive, int index, bool *hasPermissions)
{
quint32 attributes = getUInt32Property(archive, index, kpidAttrib, 0);
QFile::Permissions permissions = 0;
if (attributes & FILE_ATTRIBUTE_UNIX_EXTENSION) {
if (hasPermissions != 0)
*hasPermissions = true;
- // filter the unix permissions
+ // filter the Unix permissions
attributes = (attributes >> 16) & 0777;
- permissions |= static_cast< QFile::Permissions >((attributes & 0700) << 2); // owner rights
- permissions |= static_cast< QFile::Permissions >((attributes & 0070) << 1); // group
- permissions |= static_cast< QFile::Permissions >((attributes & 0007) << 0); // and world rights
+ permissions |= static_cast<QFile::Permissions>((attributes & 0700) << 2); // owner rights
+ permissions |= static_cast<QFile::Permissions>((attributes & 0070) << 1); // group
+ permissions |= static_cast<QFile::Permissions>((attributes & 0007) << 0); // and world rights
} else if (hasPermissions != 0) {
*hasPermissions = false;
}
return permissions;
}
-namespace Lib7z {
+#define LIB7Z_ASSERTS(X, MODE) \
+ Q_ASSERT(X); \
+ Q_ASSERT(X->isOpen()); \
+ Q_ASSERT(X->is ## MODE()); \
+ Q_ASSERT(!X->isSequential());
+
class QIODeviceSequentialOutStream : public ISequentialOutStream, public CMyUnknownImp
{
-public:
- enum Behavior {
- KeepDeviceUntouched,
- CloseAndDeleteDevice
- };
+ Q_DISABLE_COPY(QIODeviceSequentialOutStream)
+public:
MY_UNKNOWN_IMP
- explicit QIODeviceSequentialOutStream(QIODevice* device, Behavior behavior);
- ~QIODeviceSequentialOutStream();
- QString errorString() const;
- /* reimp */ STDMETHOD(Write)(const void* data, UInt32 size, UInt32* processedSize);
-
-private:
- Behavior m_behavior;
- QString m_errorString;
- QPointer<QIODevice> m_device;
-};
-
-QIODeviceSequentialOutStream::QIODeviceSequentialOutStream(QIODevice* device, Behavior behavior)
- : ISequentialOutStream()
- , CMyUnknownImp()
- , m_behavior(behavior)
- , m_device(device)
-{
- Q_ASSERT(m_device);
-
- if (!device->isOpen() && !m_device->open(QIODevice::WriteOnly))
- m_errorString = m_device->errorString();
-}
-
-QIODeviceSequentialOutStream::~QIODeviceSequentialOutStream()
-{
- if (m_behavior == CloseAndDeleteDevice) {
- m_device->close();
- delete m_device;
- m_device = 0;
+ explicit QIODeviceSequentialOutStream(std::unique_ptr<QIODevice> device)
+ : ISequentialOutStream()
+ , m_device(std::move(device))
+ {
+ LIB7Z_ASSERTS(m_device, Writable)
}
-}
-QString QIODeviceSequentialOutStream::errorString() const
-{
- return m_errorString;
-}
+ QString errorString() const {
+ return m_errorString;
+ }
-HRESULT QIODeviceSequentialOutStream::Write(const void* data, UInt32 size, UInt32* processedSize)
-{
- if (!m_device) {
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize)
+ {
if (processedSize)
*processedSize = 0;
- m_errorString = QCoreApplication::translate("QIODeviceSequentialOutStream",
- "No device set for output stream");
- return E_FAIL;
- }
- if (!m_device->isOpen()) {
- const bool opened = m_device->open(QIODevice::WriteOnly);
- if (!opened) {
- if (processedSize)
- *processedSize = 0;
+
+ const qint64 written = m_device->write(reinterpret_cast<const char*>(data), size);
+ if (written == -1) {
m_errorString = m_device->errorString();
return E_FAIL;
}
- }
- const qint64 written = m_device->write(reinterpret_cast<const char*>(data), size);
- if (written == -1) {
if (processedSize)
- *processedSize = 0;
- m_errorString = m_device->errorString();
- return E_FAIL;
+ *processedSize = written;
+ m_errorString.clear();
+ return S_OK;
}
- if (processedSize)
- *processedSize = written;
- m_errorString = QString();
- return S_OK;
-}
+private:
+ QString m_errorString;
+ std::unique_ptr<QIODevice> m_device;
+};
class QIODeviceInStream : public IInStream, public CMyUnknownImp
{
+ Q_DISABLE_COPY(QIODeviceInStream)
+
public:
MY_UNKNOWN_IMP
- explicit QIODeviceInStream(QIODevice* device) : IInStream(), CMyUnknownImp(), m_device(device)
+ explicit QIODeviceInStream(QIODevice *device)
+ : IInStream()
+ , CMyUnknownImp()
+ , m_device(device)
{
- assert(m_device);
- assert(!m_device->isSequential());
+ LIB7Z_ASSERTS(m_device, Readable)
}
- /* reimp */ STDMETHOD(Read)(void* data, UInt32 size, UInt32* processedSize)
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize)
{
- assert(m_device);
- assert(m_device->isReadable());
+ if (m_device.isNull())
+ return E_FAIL;
+
const qint64 actual = m_device->read(reinterpret_cast<char*>(data), size);
Q_ASSERT(actual != 0 || m_device->atEnd());
if (processedSize)
@@ -432,29 +446,28 @@ public:
return actual >= 0 ? S_OK : E_FAIL;
}
- /* reimp */ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64* newPosition)
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- assert(m_device);
- assert(!m_device->isSequential());
- assert(m_device->isReadable());
+ if (m_device.isNull())
+ return E_FAIL;
if (seekOrigin > STREAM_SEEK_END)
return STG_E_INVALIDFUNCTION;
UInt64 np = 0;
- switch(seekOrigin) {
- case STREAM_SEEK_SET:
- np = offset;
- break;
- case STREAM_SEEK_CUR:
- np = m_device->pos() + offset;
- break;
- case STREAM_SEEK_END:
- np = m_device->size() + offset;
- break;
- default:
- return STG_E_INVALIDFUNCTION;
+ switch (seekOrigin) {
+ case STREAM_SEEK_SET:
+ np = offset;
+ break;
+ case STREAM_SEEK_CUR:
+ np = m_device->pos() + offset;
+ break;
+ case STREAM_SEEK_END:
+ np = m_device->size() + offset;
+ break;
+ default:
+ return STG_E_INVALIDFUNCTION;
}
- np = qBound(static_cast<UInt64>(0), np, static_cast<UInt64>(m_device->size() - 1));
+ np = qBound(static_cast<UInt64>(0), np, static_cast<UInt64>(m_device->size()));
const bool ok = m_device->seek(np);
if (newPosition)
*newPosition = np;
@@ -464,1129 +477,646 @@ public:
private:
QPointer<QIODevice> m_device;
};
-}
-
-File::File()
- : permissions(0)
- , uncompressedSize(0)
- , compressedSize(0)
- , isDirectory(false)
-{
-}
-
-QVector<File> File::subtreeInPreorder() const
-{
- QVector<File> res;
- res += *this;
- Q_FOREACH (const File& child, children)
- res += child.subtreeInPreorder();
- return res;
-}
-
-bool File::operator<(const File& other) const
-{
- if (path != other.path)
- return path < other.path;
- if (mtime != other.mtime)
- return mtime < other.mtime;
- if (uncompressedSize != other.uncompressedSize)
- return uncompressedSize < other.uncompressedSize;
- if (compressedSize != other.compressedSize)
- return compressedSize < other.compressedSize;
- if (isDirectory != other.isDirectory)
- return !isDirectory;
- if (permissions != other.permissions)
- return permissions < other.permissions;
- return false;
-}
-
-bool File::operator==(const File& other) const
-{
- return mtime == other.mtime
- && path == other.path
- && uncompressedSize == other.uncompressedSize
- && compressedSize == other.compressedSize
- && isDirectory == other.isDirectory
- && children == other.children
- && (permissions == other.permissions
- || permissions == static_cast< QFile::Permissions >(-1)
- || other.permissions == static_cast< QFile::Permissions >(-1));
-}
-
-QByteArray Lib7z::formatKeyValuePairs(const QVariantList& l)
-{
- assert(l.size() % 2 == 0);
- QByteArray res;
- for (QVariantList::ConstIterator it = l.constBegin(); it != l.constEnd(); ++it) {
- if (!res.isEmpty())
- res += ", ";
- res += qPrintable(it->toString()) + QByteArray(" = ");
- ++it;
- res += qPrintable(it->toString());
- }
- return res;
-}
-
-class Job::Private
-{
-public:
- Private()
- : error(Lib7z::NoError)
- {}
-
- int error;
- QString errorString;
-};
-
-Job::Job(QObject* parent)
- : QObject(parent)
- , QRunnable()
- , d(new Private)
-{
-}
-
-Job::~Job()
-{
- delete d;
-}
-
-void Job::emitResult()
-{
- emit finished(this);
-}
-
-void Job::setError(int code)
-{
- d->error = code;
-}
-void Job::setErrorString(const QString &str)
+bool operator==(const File &lhs, const File &rhs)
{
- d->errorString = str;
+ return lhs.path == rhs.path
+ && lhs.utcTime == rhs.utcTime
+ && lhs.isDirectory == rhs.isDirectory
+ && lhs.compressedSize == rhs.compressedSize
+ && lhs.uncompressedSize == rhs.uncompressedSize
+ && (lhs.permissions == rhs.permissions
+ || lhs.permissions == static_cast<QFile::Permissions>(-1)
+ || rhs.permissions == static_cast<QFile::Permissions>(-1));
}
-void Job::emitProgress(qint64 completed, qint64 total)
+QVector<File> listArchive(QFileDevice *archive)
{
- emit progress(completed, total);
-}
-
-int Job::error() const
-{
- return d->error;
-}
+ LIB7Z_ASSERTS(archive, Readable)
-bool Job::hasError() const
-{
- return d->error != NoError;
-}
-
-void Job::run()
-{
- doStart();
-}
-
-QString Job::errorString() const
-{
- return d->errorString;
-}
+ const qint64 initialPos = archive->pos();
+ try {
+ CCodecs codecs;
+ if (codecs.Load() != S_OK)
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot load codecs."));
-void Job::start()
-{
- QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection);
-}
+ COpenOptions op;
+ op.codecs = &codecs;
-class ListArchiveJob::Private
-{
-public:
- QPointer<QFileDevice> archive;
- QVector<File> files;
-};
+ CObjectVector<COpenType> types;
+ op.types = &types; // Empty, because we use a stream.
-ListArchiveJob::ListArchiveJob(QObject* parent)
- : Job(parent)
- , d(new Private)
-{
-}
+ CIntVector excluded;
+ op.excludedFormats = &excluded;
-ListArchiveJob::~ListArchiveJob()
-{
- delete d;
-}
-
-QFileDevice* ListArchiveJob::archive() const
-{
- return d->archive;
-}
-
-void ListArchiveJob::setArchive(QFileDevice* device)
-{
- d->archive = device;
-}
+ const CMyComPtr<IInStream> stream = new QIODeviceInStream(archive);
+ op.stream = stream; // CMyComPtr is needed, otherwise it crashes in OpenStream().
-QVector<File> ListArchiveJob::index() const
-{
- return d->files;
-}
+ CObjectVector<CProperty> properties;
+ op.props = &properties;
-class OpenArchiveInfo
-{
-private:
- OpenArchiveInfo(QFileDevice* device)
- : codecs(new CCodecs)
- {
- if (codecs->Load() != S_OK) {
- throw SevenZipException(QCoreApplication::translate("OpenArchiveInfo",
- "Could not load codecs"));
- }
- if (!codecs->FindFormatForArchiveType(L"", formatIndices)) {
- throw SevenZipException(QCoreApplication::translate("OpenArchiveInfo",
- "Could not retrieve default format"));
- }
- stream = new QIODeviceInStream(device);
- if (archiveLink.Open2(codecs.data(), formatIndices, false, stream, UString(), 0) != S_OK) {
- throw SevenZipException(QCoreApplication::translate("OpenArchiveInfo",
- "Could not open archive"));
+ CArchiveLink archiveLink;
+ if (archiveLink.Open2(op, nullptr) != S_OK) {
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Cannot open archive \"%1\".").arg(archive->fileName()));
}
- if (archiveLink.Arcs.Size() == 0)
- throw SevenZipException(QCoreApplication::translate("OpenArchiveInfo", "No CArc found"));
-
- m_cleaner = new OpenArchiveInfoCleaner();
- m_cleaner->moveToThread(device->thread());
- QObject::connect(device, SIGNAL(destroyed(QObject*)), m_cleaner, SLOT(deviceDestroyed(QObject*)));
- }
-
-public:
- ~OpenArchiveInfo()
- {
- m_cleaner->deleteLater();
- }
-
- static OpenArchiveInfo* value(QFileDevice* device)
- {
- QMutexLocker _(&m_mutex);
- if (!instances.contains(device))
- instances.insert(device, new OpenArchiveInfo(device));
- return instances.value(device);
- }
-
- static OpenArchiveInfo* take(QFileDevice *device)
- {
- QMutexLocker _(&m_mutex);
- if (instances.contains(device))
- return instances.take(device);
- return 0;
- }
-
- CArchiveLink archiveLink;
-
-private:
- CIntVector formatIndices;
- CMyComPtr<IInStream> stream;
- QScopedPointer<CCodecs> codecs;
- OpenArchiveInfoCleaner *m_cleaner;
-
- static QMutex m_mutex;
- static QHash< QIODevice*, OpenArchiveInfo* > instances;
-};
-
-QMutex OpenArchiveInfo::m_mutex;
-QHash< QIODevice*, OpenArchiveInfo* > OpenArchiveInfo::instances;
-
-void OpenArchiveInfoCleaner::deviceDestroyed(QObject* dev)
-{
- QFileDevice* device = static_cast<QFileDevice*>(dev);
- Q_ASSERT(device);
- delete OpenArchiveInfo::take(device);
-}
-
-QVector<File> Lib7z::listArchive(QFileDevice* archive)
-{
- assert(archive);
- try {
- const OpenArchiveInfo* const openArchive = OpenArchiveInfo::value(archive);
QVector<File> flat;
-
- for (int i = 0; i < openArchive->archiveLink.Arcs.Size(); ++i) {
- const CArc& arc = openArchive->archiveLink.Arcs[i];
- IInArchive* const arch = arc.Archive;
-
+ for (unsigned i = 0; i < archiveLink.Arcs.Size(); ++i) {
+ IInArchive *const arch = archiveLink.Arcs[i].Archive;
UInt32 numItems = 0;
if (arch->GetNumberOfItems(&numItems) != S_OK) {
throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not retrieve number of items in archive"));
+ "Cannot retrieve number of items in archive."));
}
flat.reserve(flat.size() + numItems);
for (uint item = 0; item < numItems; ++item) {
UString s;
- if (arc.GetItemPath(item, s) != S_OK) {
+ if (archiveLink.Arcs[i].GetItemPath(item, s) != S_OK) {
throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not retrieve path of archive item %1").arg(item));
+ "Cannot retrieve path of archive item \"%1\".").arg(item));
}
File f;
f.archiveIndex.setX(i);
f.archiveIndex.setY(item);
f.path = UString2QString(s).replace(QLatin1Char('\\'), QLatin1Char('/'));
- IsArchiveItemFolder(arch, item, f.isDirectory);
- f.permissions = getPermissions(arch, item);
- f.mtime = getDateTimeProperty(arch, item, kpidMTime, QDateTime());
+ Archive_IsItem_Folder(arch, item, f.isDirectory);
+ f.permissions = getPermissions(arch, item, 0);
+ getDateTimeProperty(arch, item, kpidMTime, &(f.utcTime));
f.uncompressedSize = getUInt64Property(arch, item, kpidSize, 0);
f.compressedSize = getUInt64Property(arch, item, kpidPackSize, 0);
- flat.push_back(f);
- qApp->processEvents();
+ flat.append(f);
}
}
return flat;
- } catch (const SevenZipException& e) {
- throw e;
} catch (const char *err) {
+ archive->seek(initialPos);
throw SevenZipException(err);
+ } catch (const SevenZipException &e) {
+ archive->seek(initialPos);
+ throw e; // re-throw unmodified
} catch (...) {
+ archive->seek(initialPos);
throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Unknown exception caught (%1)").arg(QString::fromLatin1(Q_FUNC_INFO)));
+ "Unknown exception caught (%1).").arg(QString::fromLatin1(Q_FUNC_INFO)));
}
return QVector<File>(); // never reached
}
-void ListArchiveJob::doStart()
+
+// -- ExtractCallback
+
+STDMETHODIMP ExtractCallback::SetTotal(UInt64 t)
{
- try {
- if (!d->archive)
- throw SevenZipException(tr("Could not list archive: QIODevice already destroyed."));
- d->files = listArchive(d->archive);
- } catch (const SevenZipException& e) {
- setError(Failed);
- setErrorString(e.message());
- } catch (...) {
- setError(Failed);
- setErrorString(tr("Unknown exception caught (%1)").arg(tr("Failed")));
- }
- emitResult();
+ total = t;
+ return S_OK;
}
-class Lib7z::ExtractCallbackImpl : public IArchiveExtractCallback, public CMyUnknownImp
+STDMETHODIMP ExtractCallback::SetCompleted(const UInt64 *c)
{
-public:
- MY_UNKNOWN_IMP
- explicit ExtractCallbackImpl(ExtractCallback* qq)
- : q(qq)
- , currentIndex(0)
- , arc(0)
- , total(0)
- , completed(0)
- , device(0)
- {
- }
+ completed = *c;
+ if (total > 0)
+ return setCompleted(completed, total);
+ return S_OK;
+}
- void setTarget(QIODevice* dev)
- {
- device = dev;
- }
+// this method will be called by CFolderOutStream::OpenFile to stream via
+// CDecoder::CodeSpec extracted content to an output stream.
+STDMETHODIMP ExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 /*askExtractMode*/)
+{
+ *outStream = 0;
+ if (targetDir.isEmpty())
+ return E_FAIL;
- void setTarget(const QString &targetDirectory)
- {
- targetDir = targetDirectory;
- }
+ Q_ASSERT(arc);
+ currentIndex = index;
- // this method will be called by CFolderOutStream::OpenFile to stream via
- // CDecoder::CodeSpec extracted content to an output stream.
- /* reimp */ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream** outStream, Int32 askExtractMode)
- {
- Q_UNUSED(askExtractMode)
- *outStream = 0;
- if (device != 0) {
- QIODeviceSequentialOutStream *qOutStream = new QIODeviceSequentialOutStream(device,
- QIODeviceSequentialOutStream::KeepDeviceUntouched);
- if (!qOutStream->errorString().isEmpty()) {
- Lib7z::setLastError(qOutStream->errorString());
- return E_FAIL;
- }
- CMyComPtr<ISequentialOutStream> stream = qOutStream;
- *outStream = stream.Detach();
- return S_OK;
- } else if (!targetDir.isEmpty()) {
- assert(arc);
-
- currentIndex = index;
-
- UString s;
- if (arc->GetItemPath(index, s) != S_OK) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not retrieve path of archive item %1").arg(index));
- return E_FAIL;
- }
+ UString s;
+ if (arc->GetItemPath(index, s) != S_OK) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot retrieve path of archive item %1.").arg(index));
+ return E_FAIL;
+ }
- const QString path = UString2QString(s).replace(QLatin1Char('\\'), QLatin1Char('/'));
- const QFileInfo fi(QString::fromLatin1("%1/%2").arg(targetDir, path));
+ const QFileInfo fi(QString::fromLatin1("%1/%2").arg(targetDir, UString2QString(s)));
- DirectoryGuard guard(fi.absolutePath());
- const QStringList directories = guard.tryCreate();
+ DirectoryGuard guard(fi.absolutePath());
+ const QStringList directories = guard.tryCreate();
- bool isDir = false;
- IsArchiveItemFolder(arc->Archive, index, isDir);
- if (isDir)
- QDir(fi.absolutePath()).mkdir(fi.fileName());
+ bool isDir = false;
+ Archive_IsItem_Folder(arc->Archive, index, isDir);
+ if (isDir)
+ QDir(fi.absolutePath()).mkdir(fi.fileName());
- // this makes sure that all directories created get removed as well
- foreach (const QString &directory, directories)
- q->setCurrentFile(directory);
+ // this makes sure that all directories created get removed as well
+ foreach (const QString &directory, directories)
+ setCurrentFile(directory);
- if (!isDir && !q->prepareForFile(fi.absoluteFilePath()))
- return E_FAIL;
+ if (!isDir && !prepareForFile(fi.absoluteFilePath()))
+ return E_FAIL;
- q->setCurrentFile(fi.absoluteFilePath());
+ setCurrentFile(fi.absoluteFilePath());
- if (!isDir) {
+ if (!isDir) {
#ifndef Q_OS_WIN
- // do not follow symlinks, so we need to remove an existing one
- if (fi.isSymLink() && (!QFile::remove(fi.absoluteFilePath()))) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not remove already existing symlink. %1").arg(fi.absoluteFilePath()));
- return E_FAIL;
- }
+ // do not follow symlinks, so we need to remove an existing one
+ if (fi.isSymLink() && (!QFile::remove(fi.absoluteFilePath()))) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot remove already existing symlink %1.").arg(fi.absoluteFilePath()));
+ return E_FAIL;
+ }
#endif
- QIODeviceSequentialOutStream *qOutStream = new QIODeviceSequentialOutStream(
- new QFile(fi.absoluteFilePath()), QIODeviceSequentialOutStream::CloseAndDeleteDevice);
- if (!qOutStream->errorString().isEmpty()) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not open file: %1 (%2)").arg(fi.absoluteFilePath(),
- qOutStream->errorString()));
- return E_FAIL;
- }
- CMyComPtr<ISequentialOutStream> stream = qOutStream;
- *outStream = stream;
- stream.Detach();
- }
-
- guard.release();
- return S_OK;
+ std::unique_ptr<QFile> file(new QFile(fi.absoluteFilePath()));
+ if (!file->open(QIODevice::WriteOnly)) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(fi.absoluteFilePath()), file->errorString()));
+ return E_FAIL;
}
- return E_FAIL;
+ CMyComPtr<ISequentialOutStream> stream =
+ new QIODeviceSequentialOutStream(std::move(file));
+ *outStream = stream.Detach(); // CMyComPtr is needed, otherwise it crashes in Write().
}
- /* reimp */ STDMETHOD(PrepareOperation)(Int32 askExtractMode)
- {
- Q_UNUSED(askExtractMode)
+ guard.release();
+ return S_OK;
+}
+
+STDMETHODIMP ExtractCallback::PrepareOperation(Int32 /*askExtractMode*/)
+{
+ return S_OK;
+}
+
+STDMETHODIMP ExtractCallback::SetOperationResult(Int32 /*resultEOperationResult*/)
+{
+ if (targetDir.isEmpty())
return S_OK;
- }
- /* reimp */ STDMETHOD(SetOperationResult)(Int32 resultEOperationResult)
- {
- Q_UNUSED(resultEOperationResult)
+ UString s;
+ if (arc->GetItemPath(currentIndex, s) != S_OK) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot retrieve path of archive item %1.").arg(currentIndex));
+ return E_FAIL;
+ }
- if (!targetDir.isEmpty()) {
- bool hasPerm = false;
- const QFile::Permissions permissions = getPermissions(arc->Archive, currentIndex, &hasPerm);
+ const QString absFilePath = QFileInfo(QString::fromLatin1("%1/%2").arg(targetDir,
+ UString2QString(s).replace(QLatin1Char('\\'), QLatin1Char('/')))).absoluteFilePath();
- UString s;
- if (arc->GetItemPath(currentIndex, s) != S_OK) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not retrieve path of archive item %1").arg(currentIndex));
- return E_FAIL;
- }
- const QString path = UString2QString(s).replace(QLatin1Char('\\'), QLatin1Char('/'));
- const QString absFilePath = QFileInfo(QString::fromLatin1("%1/%2").arg(targetDir, path))
- .absoluteFilePath();
-
- // do we have a symlink?
- const quint32 attributes = getUInt32Property(arc->Archive, currentIndex, kpidAttrib, 0);
- struct stat stat_info;
- stat_info.st_mode = attributes >> 16;
- if (S_ISLNK(stat_info.st_mode)) {
+ // do we have a symlink?
+ const quint32 attributes = getUInt32Property(arc->Archive, currentIndex, kpidAttrib, 0);
+ struct stat stat_info;
+ stat_info.st_mode = attributes >> 16;
+ if (S_ISLNK(stat_info.st_mode)) {
#ifdef Q_OS_WIN
- qFatal(QString::fromLatin1("Creating a link from archive is not implemented for windows. "
- "Link filename: %1").arg(absFilePath).toLatin1());
- // TODO
-// if (!CreateHardLinkWrapper(absFilePath, QLatin1String(symlinkTarget))) {
-// return S_FALSE;
-// }
+ qFatal(QString::fromLatin1("Creating a link from archive is not implemented for "
+ "windows. Link filename: %1").arg(absFilePath).toLatin1());
+ // TODO
+ //if (!NFile::NDir::MyCreateHardLink(CFSTR(QDir::toNativeSeparators(absFilePath).utf16()),
+ // CFSTR(QDir::toNativeSeparators(symlinkTarget).utf16())) {
+ // return S_FALSE;
+ //}
#else
- QFileInfo symlinkPlaceHolderFileInfo(absFilePath);
- if (symlinkPlaceHolderFileInfo.isSymLink()) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not create symlink at '%1'. Another one is already existing.")
- .arg(absFilePath));
- return E_FAIL;
- }
- QFile symlinkPlaceHolderFile(absFilePath);
- if (!symlinkPlaceHolderFile.open(QIODevice::ReadOnly)) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not read symlink target from file '%1'.").arg(absFilePath));
- return E_FAIL;
- }
+ QFileInfo symlinkPlaceHolderFileInfo(absFilePath);
+ if (symlinkPlaceHolderFileInfo.isSymLink()) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot create symlink at \"%1\". Another one is already existing.")
+ .arg(absFilePath));
+ return E_FAIL;
+ }
+ QFile symlinkPlaceHolderFile(absFilePath);
+ if (!symlinkPlaceHolderFile.open(QIODevice::ReadOnly)) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot read symlink target from file \"%1\".").arg(absFilePath));
+ return E_FAIL;
+ }
- const QByteArray symlinkTarget = symlinkPlaceHolderFile.readAll();
- symlinkPlaceHolderFile.close();
- symlinkPlaceHolderFile.remove();
- QFile targetFile(QString::fromLatin1(symlinkTarget));
- if (!targetFile.link(absFilePath)) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not create symlink at %1. %2").arg(absFilePath,
- targetFile.errorString()));
- return E_FAIL;
- }
- return S_OK;
+ const QByteArray symlinkTarget = symlinkPlaceHolderFile.readAll();
+ symlinkPlaceHolderFile.close();
+ symlinkPlaceHolderFile.remove();
+ QFile targetFile(QString::fromLatin1(symlinkTarget));
+ if (!targetFile.link(absFilePath)) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot create symlink at %1: %2").arg(absFilePath,
+ targetFile.errorString()));
+ return E_FAIL;
+ }
+ return S_OK;
#endif
- }
+ }
- try {
- if (!absFilePath.isEmpty()) {
- // This might fail for archives without all properties, we can only be sure about
- // modification time, as it's always stored by default in 7z archives. Also note that
- // we restore modification time on Unix only, as access time and change time are
- // supposed to be set to the time of installation.
- FILETIME mTime;
- if (getFileTimeFromProperty(arc->Archive, currentIndex, kpidMTime, &mTime)) {
- NWindows::NFile::NIO::COutFile file;
- if (file.Open(QString2UString(absFilePath), 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL))
- file.SetTime(&mTime, &mTime, &mTime);
- }
+ try { // Note: This part might also fail while running a elevated installation.
+ if (!absFilePath.isEmpty()) {
+ // This might fail for archives without all properties, we can only be sure
+ // about modification time, as it's always stored by default in 7z archives.
+ // Also note that we restore modification time on Unix only, as access time
+ // and change time are supposed to be set to the time of installation.
+ FILETIME mTime;
+ const UString fileName = QString2UString(absFilePath);
+ if (getFileTimeFromProperty(arc->Archive, currentIndex, kpidMTime, &mTime)) {
+ NWindows::NFile::NIO::COutFile file;
+ if (file.Open(fileName, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL))
+ file.SetTime(&mTime, &mTime, &mTime);
+ }
#ifdef Q_OS_WIN
- FILETIME cTime, aTime;
- bool success = getFileTimeFromProperty(arc->Archive, currentIndex, kpidCTime, &cTime);
- if (success && getFileTimeFromProperty(arc->Archive, currentIndex, kpidATime, &aTime)) {
- NWindows::NFile::NIO::COutFile file;
- if (file.Open(QString2UString(absFilePath), 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL))
- file.SetTime(&cTime, &aTime, &mTime);
- }
+ FILETIME cTime, aTime;
+ if (getFileTimeFromProperty(arc->Archive, currentIndex, kpidCTime, &cTime)
+ && getFileTimeFromProperty(arc->Archive, currentIndex, kpidATime, &aTime)) {
+ NWindows::NFile::NIO::COutFile file;
+ if (file.Open(fileName, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL))
+ file.SetTime(&cTime, &aTime, &mTime);
+ }
#endif
- }
- } catch (...) {}
-
- if (hasPerm)
- QFile::setPermissions(absFilePath, permissions);
}
+ } catch (...) {}
- return S_OK;
- }
-
- /* reimp */ STDMETHOD(SetTotal)(UInt64 t)
- {
- total = t;
- return S_OK;
- }
-
- /* reimp */ STDMETHOD(SetCompleted)(const UInt64* c)
- {
- completed = *c;
- if (total > 0)
- return q->setCompleted(completed, total);
- return S_OK;
- }
-
- void setArchive(const CArc* archive)
- {
- arc = archive;
- }
-
-private:
- ExtractCallback* const q;
- UInt32 currentIndex;
- const CArc* arc;
- UInt64 total;
- UInt64 completed;
- QPointer<QIODevice> device;
- QString targetDir;
-};
+ bool hasPerm = false;
+ const QFile::Permissions permissions = getPermissions(arc->Archive, currentIndex, &hasPerm);
+ if (hasPerm)
+ QFile::setPermissions(absFilePath, permissions);
+ return S_OK;
+}
+/*!
+ \fn bool ExtractCallback::prepareForFile(const QString &filename)
-class Lib7z::ExtractCallbackPrivate
-{
-public:
- explicit ExtractCallbackPrivate(ExtractCallback* qq)
- {
- impl = new ExtractCallbackImpl(qq);
- }
+ Implement to prepare for file \a filename to be extracted, e.g. by renaming existing files.
+ Return \c true if the preparation was successful and extraction can be continued. If \c false
+ is returned, the extraction will be aborted. The default implementation returns \c true.
+*/
- CMyComPtr<ExtractCallbackImpl> impl;
-};
-ExtractCallback::ExtractCallback()
- : d(new ExtractCallbackPrivate(this))
-{
-}
+// -- UpdateCallback
-ExtractCallback::~ExtractCallback()
+HRESULT UpdateCallback::SetTotal(UInt64)
{
- delete d;
+ return S_OK;
}
-ExtractCallbackImpl* ExtractCallback::impl()
+HRESULT UpdateCallback::SetCompleted(const UInt64*)
{
- return d->impl;
+ return S_OK;
}
-const ExtractCallbackImpl* ExtractCallback::impl() const
+HRESULT UpdateCallback::SetRatioInfo(const UInt64*, const UInt64*)
{
- return d->impl;
+ return S_OK;
}
-void ExtractCallback::setTarget(QFileDevice* dev)
+HRESULT UpdateCallback::CheckBreak()
{
- d->impl->setTarget(dev);
+ return S_OK;
}
-void ExtractCallback::setTarget(const QString &dir)
+HRESULT UpdateCallback::Finilize()
{
- d->impl->setTarget(dir);
+ return S_OK;
}
-HRESULT ExtractCallback::setCompleted(quint64, quint64)
+HRESULT UpdateCallback::SetNumFiles(UInt64)
{
return S_OK;
}
-void ExtractCallback::setCurrentFile(const QString&)
+HRESULT UpdateCallback::GetStream(const wchar_t*, bool)
{
+ return S_OK;
}
-bool ExtractCallback::prepareForFile(const QString&)
+HRESULT UpdateCallback::OpenFileError(const wchar_t*, DWORD)
{
- return true;
+ return S_OK;
}
-class Lib7z::ExtractCallbackJobImpl : public ExtractCallback
-{
-public:
- explicit ExtractCallbackJobImpl(ExtractItemJob* j)
- : ExtractCallback()
- , job(j)
- {}
-
-private:
- /* reimp */ HRESULT setCompleted(quint64 c, quint64 t)
- {
- emit job->progress(c, t);
- return S_OK;
- }
-
- ExtractItemJob* const job;
-};
-
-class Lib7z::UpdateCallbackImpl : public IUpdateCallbackUI2, public CMyUnknownImp
-{
-public:
- MY_UNKNOWN_IMP
- UpdateCallbackImpl()
- {
- }
- virtual ~UpdateCallbackImpl()
- {
- }
- /**
- * \reimp
- */
- HRESULT SetTotal(UInt64)
- {
- return S_OK;
- }
- /**
- * \reimp
- */
- HRESULT SetCompleted(const UInt64*)
- {
- return S_OK;
- }
- HRESULT SetRatioInfo(const UInt64*, const UInt64*)
- {
- return S_OK;
- }
- HRESULT CheckBreak()
- {
- return S_OK;
- }
- HRESULT Finilize()
- {
- return S_OK;
- }
- HRESULT SetNumFiles(UInt64)
- {
- return S_OK;
- }
- HRESULT GetStream(const wchar_t*, bool)
- {
- return S_OK;
- }
- HRESULT OpenFileError(const wchar_t*, DWORD)
- {
- return S_OK;
- }
- HRESULT CryptoGetTextPassword2(Int32* passwordIsDefined, OLECHAR** password)
- {
- *password = 0;
- *passwordIsDefined = false;
- return S_OK;
- }
- HRESULT CryptoGetTextPassword(OLECHAR**)
- {
- return E_NOTIMPL;
- }
- HRESULT OpenResult(const wchar_t*, LONG)
- {
- return S_OK;
- }
- HRESULT StartScanning()
- {
- return S_OK;
- }
- HRESULT ScanProgress(UInt64, UInt64, const wchar_t*)
- {
- return S_OK;
- }
- HRESULT CanNotFindError(const wchar_t*, DWORD)
- {
- return S_OK;
- }
- HRESULT FinishScanning()
- {
- return S_OK;
- }
- HRESULT StartArchive(const wchar_t*, bool)
- {
- return S_OK;
- }
- HRESULT FinishArchive()
- {
- return S_OK;
- }
-
- /**
- * \reimp
- */
- HRESULT SetOperationResult(Int32)
- {
- // TODO!
- return S_OK;
- }
- void setSourcePaths(const QStringList &paths)
- {
- sourcePaths = paths;
- }
- void setTarget(QIODevice* archive)
- {
- target = archive;
- }
-
-private:
- QIODevice* target;
- QStringList sourcePaths;
-};
-
-class Lib7z::UpdateCallbackPrivate
-{
-public:
- UpdateCallbackPrivate()
- {
- m_impl = new UpdateCallbackImpl;
- }
-
- UpdateCallbackImpl* impl()
- {
- return m_impl;
- }
-
-private:
- CMyComPtr< UpdateCallbackImpl > m_impl;
-};
-
-UpdateCallback::UpdateCallback()
- : d(new UpdateCallbackPrivate)
+HRESULT UpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
{
+ *password = 0;
+ *passwordIsDefined = false;
+ return S_OK;
}
-UpdateCallback::~UpdateCallback()
+HRESULT UpdateCallback::CryptoGetTextPassword(BSTR *password)
{
- delete d;
+ *password = 0;
+ return E_NOTIMPL;
}
-UpdateCallbackImpl* UpdateCallback::impl()
+HRESULT UpdateCallback::OpenResult(const wchar_t*, HRESULT, const wchar_t*)
{
- return d->impl();
+ return S_OK;
}
-void UpdateCallback::setSourcePaths(const QStringList &paths)
+HRESULT UpdateCallback::StartScanning()
{
- d->impl()->setSourcePaths(paths);
+ return S_OK;
}
-void UpdateCallback::setTarget(QFileDevice* target)
+HRESULT UpdateCallback::ScanProgress(UInt64, UInt64, UInt64, const wchar_t*, bool)
{
- d->impl()->setTarget(target);
+ return S_OK;
}
-class ExtractItemJob::Private
-{
-public:
- Private(ExtractItemJob* qq)
- : q(qq)
- , target(0)
- , callback(new ExtractCallbackJobImpl(q))
- {
- }
-
- ExtractItemJob* q;
- File item;
- QPointer<QFileDevice> archive;
- QString targetDirectory;
- QFileDevice* target;
- ExtractCallback* callback;
-};
-
-ExtractItemJob::ExtractItemJob(QObject* parent)
- : Job(parent)
- , d(new Private(this))
+HRESULT UpdateCallback::CanNotFindError(const wchar_t*, DWORD)
{
+ return S_OK;
}
-ExtractItemJob::~ExtractItemJob()
+HRESULT UpdateCallback::FinishScanning()
{
- delete d;
+ return S_OK;
}
-File ExtractItemJob::item() const
+HRESULT UpdateCallback::StartArchive(const wchar_t*, bool)
{
- return d->item;
+ return S_OK;
}
-void ExtractItemJob::setItem(const File& item)
+HRESULT UpdateCallback::FinishArchive()
{
- d->item = item;
+ return S_OK;
}
-QFileDevice* ExtractItemJob::archive() const
+HRESULT UpdateCallback::SetOperationResult(Int32)
{
- return d->archive;
+ return S_OK;
}
-void ExtractItemJob::setArchive(QFileDevice* archive)
+/*!
+ Function to create an empty 7z container. Using a temporary file only is not working, since
+ 7z checks the output file for a valid signature, otherwise it rejects overwriting the file.
+*/
+static QString createTmp7z()
{
- d->archive = archive;
-}
+ QTemporaryFile file;
+ if (!file.open()) {
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot create "
+ "temporary file: %1").arg(file.errorString()));
+ }
-QString ExtractItemJob::targetDirectory() const
-{
- return d->targetDirectory;
+ file.write(QByteArray::fromHex("377A.BCAF.271C" // Signature.
+ ".0003.8D9B.D50F.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000" // Crc + Data.
+ ));
+ file.setAutoRemove(false);
+ return file.fileName();
}
-void ExtractItemJob::setTargetDirectory(const QString &dir)
-{
- d->targetDirectory = dir;
- d->target = 0;
-}
+/*!
+ Creates an archive using the given file device \a archive. \a sourcePaths can contain one or
+ more files, one or more directories or a combination of files and folders. The \c * wildcard
+ is supported also. The value of \a level specifies the compression ratio, the default is set
+ to \c 5 (Normal compression). The \a callback can be used to get information about the archive
+ creation process. If no \a callback is given, an empty implementation is used.
-void ExtractItemJob::setTarget(QFileDevice* dev)
+ \note Throws SevenZipException on error.
+ \note Filenames are stored case-sensitive with UTF-8 encoding.
+ \note The ownership of \a callback is transferred to the function and gets delete on exit.
+*/
+void INSTALLER_EXPORT createArchive(QFileDevice *archive, const QStringList &sources,
+ Compression level, UpdateCallback *callback)
{
- d->target = dev;
-}
+ LIB7Z_ASSERTS(archive, Writable)
-namespace{
- QString errorMessageFrom7zResult(const LONG & extractResult)
- {
- if (!Lib7z::lastError().isEmpty())
- return Lib7z::lastError();
-
- QString errorMessage = QCoreApplication::translate("Lib7z", "internal code: %1");
- switch (extractResult) {
- case S_OK:
- qFatal("S_OK value is not a valid error code.");
- break;
- case E_NOTIMPL:
- errorMessage = errorMessage.arg(QLatin1String("E_NOTIMPL"));
- break;
- case E_NOINTERFACE:
- errorMessage = errorMessage.arg(QLatin1String("E_NOINTERFACE"));
- break;
- case E_ABORT:
- errorMessage = errorMessage.arg(QLatin1String("E_ABORT"));
- break;
- case E_FAIL:
- errorMessage = errorMessage.arg(QLatin1String("E_FAIL"));
- break;
- case STG_E_INVALIDFUNCTION:
- errorMessage = errorMessage.arg(QLatin1String("STG_E_INVALIDFUNCTION"));
- break;
- case E_OUTOFMEMORY:
- errorMessage = QCoreApplication::translate("Lib7z", "not enough memory");
- break;
- case E_INVALIDARG:
- errorMessage = errorMessage.arg(QLatin1String("E_INVALIDARG"));
- break;
- default:
- errorMessage = QCoreApplication::translate("Lib7z", "Error: %1").arg(extractResult);
- break;
- }
- return errorMessage;
- }
-}
+ const QString tmpArchive = createTmp7z();
+ Lib7z::createArchive(tmpArchive, sources, QTmpFile::No, level, callback);
-void Lib7z::createArchive(QFileDevice* archive, const QStringList &sourcePaths, UpdateCallback* callback)
+ try {
+ QFile source(tmpArchive);
+ QInstaller::openForRead(&source);
+ QInstaller::blockingCopy(&source, archive, source.size());
+ } catch (const QInstaller::Error &error) {
+ throw SevenZipException(error.message());
+ }
+}
+
+/*!
+ Creates an archive with the given filename \a archive. \a sourcePaths can contain one or more
+ files, one or more directories or a combination of files and folders. Also the \c * wildcard
+ is supported. To be able to use the function during an elevated installation, set \a mode to
+ \c QTmpFile::Yes. The value of \a level specifies the compression ratio, the default is set
+ to \c 5 (Normal compression). The \a callback can be used to get information about the archive
+ creation process. If no \a callback is given, an empty implementation is used.
+
+ \note Throws SevenZipException on error.
+ \note If \a archive exists, it will be overwritten.
+ \note Filenames are stored case-sensitive with UTF-8 encoding.
+ \note The ownership of \a callback is transferred to the function and gets delete on exit.
+*/
+void createArchive(const QString &archive, const QStringList &sources, QTmpFile mode,
+ Compression level, UpdateCallback *callback)
{
- assert(archive);
-
- QScopedPointer<UpdateCallback> dummyCallback(callback ? 0 : new UpdateCallback);
- if (!callback)
- callback = dummyCallback.data();
-
try {
- callback->setTarget(archive);
-
- QScopedPointer<CCodecs> codecs(new CCodecs);
- if (codecs->Load() != S_OK)
- throw SevenZipException(QCoreApplication::translate("Lib7z", "Could not load codecs"));
-
- CIntVector formatIndices;
-
- if (!codecs.data()->FindFormatForArchiveType(L"", formatIndices)) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not retrieve default format"));
- }
-
- // yes this is crap, but there seems to be no streaming solution to this...
-
- const QString tempFile = generateTempFileName();
-
- NWildcard::CCensor censor;
- foreach (const QString &path, sourcePaths) {
- const QString cleanPath = QDir::toNativeSeparators(QDir::cleanPath(path));
- const UString nativePath = QString2UString(cleanPath);
- if (UString2QString(nativePath) != cleanPath) {
- throw SevenZipException(QCoreApplication::translate("Lib7z", "Could not convert"
- "path: %1.").arg(path));
- }
- censor.AddItem(true /* always include item */, nativePath, false /* never recurse*/);
+ QString target = archive;
+ if (mode == QTmpFile::Yes)
+ target = createTmp7z();
+
+ CArcCmdLineOptions options;
+ try {
+ UStringVector commandStrings;
+ commandStrings.Add(L"a"); // mode: add
+ commandStrings.Add(L"-t7z"); // type: 7z
+ commandStrings.Add(L"-mtm=on"); // time: modeifier|creation|access
+ commandStrings.Add(L"-mtc=on");
+ commandStrings.Add(L"-mta=on");
+ commandStrings.Add(L"-mmt=on"); // threads: multi-threaded
+#ifdef Q_OS_WIN
+ commandStrings.Add(L"-sccUTF-8"); // files: case-sensitive|UTF8
+#endif
+ commandStrings.Add(QString2UString(QString::fromLatin1("-mx=%1").arg(int(level)))); // compression: level
+ commandStrings.Add(QString2UString(QDir::toNativeSeparators(target)));
+ foreach (const QString &source, sources)
+ commandStrings.Add(QString2UString(source));
+
+ CArcCmdLineParser parser;
+ parser.Parse1(commandStrings, options);
+ parser.Parse2(options);
+ } catch (const CArcCmdLineException &e) {
+ throw SevenZipException(UString2QString(e));
}
- callback->setSourcePaths(sourcePaths);
-
- CArchivePath archivePath;
- archivePath.ParseFromPath(QString2UString(tempFile));
- CUpdateArchiveCommand command;
- command.ArchivePath = archivePath;
- command.ActionSet = NUpdateArchive::kAddActionSet;
+ CCodecs codecs;
+ if (codecs.Load() != S_OK)
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot load codecs."));
- CUpdateOptions options;
- options.Commands.Add(command);
- options.ArchivePath = archivePath;
- options.MethodMode.FormatIndex = codecs->FindFormatForArchiveType(L"7z");
-
- // preserve creation time
- CProperty tc;
- tc.Name = UString(L"TC");
- tc.Value = UString(L"ON");
- options.MethodMode.Properties.Add(tc);
-
- // preserve access time
- CProperty ta;
- ta.Name = UString(L"TA");
- ta.Value = UString(L"ON");
- options.MethodMode.Properties.Add(ta);
+ CObjectVector<COpenType> types;
+ if (!ParseOpenTypes(codecs, options.ArcType, types))
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Unsupported archive type."));
CUpdateErrorInfo errorInfo;
- const HRESULT res = UpdateArchive(codecs.data(), censor, options, errorInfo, 0, callback->impl());
- if (res != S_OK || !QFile::exists(tempFile)) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not create archive %1. %2").arg(tempFile, errorMessageFrom7zResult(res)));
+ CMyComPtr<UpdateCallback> comCallback = callback == 0 ? new UpdateCallback : callback;
+ const HRESULT res = UpdateArchive(&codecs, types, options.ArchiveName, options.Censor,
+ options.UpdateOptions, errorInfo, nullptr, comCallback, true);
+
+ const QFile tempFile(UString2QString(options.ArchiveName));
+ if (res != S_OK || !tempFile.exists()) {
+ QString errorMsg;
+ if (res == S_OK) {
+ errorMsg = QCoreApplication::translate("Lib7z", "Cannot create archive \"%1\"")
+ .arg(QDir::toNativeSeparators(tempFile.fileName()));
+ } else {
+ errorMsg = QCoreApplication::translate("Lib7z", "Cannot create archive \"%1\": %2")
+ .arg(QDir::toNativeSeparators(tempFile.fileName()), errorMessageFrom7zResult(res));
+ }
+ throw SevenZipException(errorMsg);
}
- {
- //TODO remove temp file even if one the following throws
- QFile file(tempFile);
- QInstaller::openForRead(&file);
- QInstaller::blockingCopy(&file, archive, file.size());
- }
+ if (mode == QTmpFile::Yes) {
+ QFile org(archive);
+ if (org.exists() && !org.remove()) {
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot remove "
+ "old archive \"%1\": %2").arg(QDir::toNativeSeparators(org.fileName()),
+ org.errorString()));
+ }
- QFile file(tempFile);
- if (!file.remove()) {
- qWarning("%s: Could not remove temporary file %s: %s", Q_FUNC_INFO, qPrintable(tempFile),
- qPrintable(file.errorString()));
+ QFile arc(UString2QString(options.ArchiveName));
+ if(!arc.rename(archive)) {
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot rename "
+ "temporary archive \"%1\" to \"%2\": %3").arg(
+ QDir::toNativeSeparators(arc.fileName()),
+ QDir::toNativeSeparators(archive),
+ arc.errorString()));
+ }
}
} catch (const char *err) {
- qDebug() << err;
throw SevenZipException(err);
+ } catch (SevenZipException &e) {
+ throw e; // re-throw unmodified
} catch (const QInstaller::Error &err) {
throw SevenZipException(err.message());
} catch (...) {
- throw SevenZipException(QCoreApplication::translate("Lib7z", "Unknown exception caught (%1)")
- .arg(QString::fromLatin1(Q_FUNC_INFO)));
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Unknown exception caught (%1)").arg(QString::fromLatin1(Q_FUNC_INFO)));
}
}
-void Lib7z::extractFileFromArchive(QFileDevice* archive, const File& item, QFileDevice* target,
- ExtractCallback* callback)
+/*!
+ Extracts the given \a archive content into target directory \a directory using the provided
+ extract callback \a callback. The output filenames are deduced from the \a archive content.
+
+ \note Throws SevenZipException on error.
+ \note The ownership of \a callback is not transferred to the function.
+*/
+void extractArchive(QFileDevice *archive, const QString &directory, ExtractCallback *callback)
{
- assert(archive);
- assert(target);
+ LIB7Z_ASSERTS(archive, Readable)
- std::auto_ptr<ExtractCallback> dummyCallback(callback ? 0 : new ExtractCallback);
- if (!callback)
- callback = dummyCallback.get();
+ // Guard a given object against unwanted delete.
+ CMyComPtr<ExtractCallback> externCallback = callback;
+
+ CMyComPtr<ExtractCallback> localCallback;
+ if (!externCallback) {
+ callback = new ExtractCallback;
+ localCallback = callback;
+ }
+ DirectoryGuard outDir(QFileInfo(directory).absolutePath());
try {
- const OpenArchiveInfo* const openArchive = OpenArchiveInfo::value(archive);
+ outDir.tryCreate();
- const int arcIdx = item.archiveIndex.x();
- if (arcIdx < 0 || arcIdx >= openArchive->archiveLink.Arcs.Size()) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "CArc index %1 out of bounds [0, %2]").arg(openArchive->archiveLink.Arcs.Size() - 1));
- }
- const CArc& arc = openArchive->archiveLink.Arcs[arcIdx];
- IInArchive* const parchive = arc.Archive;
+ CCodecs codecs;
+ if (codecs.Load() != S_OK)
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot load codecs."));
- const UInt32 itemIdx = item.archiveIndex.y();
- UInt32 numItems = 0;
- if (parchive->GetNumberOfItems(&numItems) != S_OK) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not retrieve number of items in archive"));
- }
+ COpenOptions op;
+ op.codecs = &codecs;
- if (itemIdx >= numItems) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Item index %1 out of bounds [0, %2]").arg(itemIdx).arg(numItems - 1));
- }
+ CObjectVector<COpenType> types;
+ op.types = &types; // Empty, because we use a stream.
- UString s;
- if (arc.GetItemPath(itemIdx, s) != S_OK) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not retrieve path of archive item %1").arg(itemIdx));
- }
- assert(item.path == UString2QString(s).replace(QLatin1Char('\\'), QLatin1Char('/')));
+ CIntVector excluded;
+ op.excludedFormats = &excluded;
- callback->setTarget(target);
- const LONG extractResult = parchive->Extract(&itemIdx, 1, /*testmode=*/0, callback->impl());
+ const CMyComPtr<IInStream> stream = new QIODeviceInStream(archive);
+ op.stream = stream; // CMyComPtr is needed, otherwise it crashes in OpenStream().
- if (extractResult != S_OK)
- throw SevenZipException(errorMessageFrom7zResult(extractResult));
+ CObjectVector<CProperty> properties;
+ op.props = &properties;
- } catch (const char *err) {
- throw SevenZipException(err);
- } catch (const Lib7z::SevenZipException& e) {
- throw e;
- } catch (...) {
- throw SevenZipException(QCoreApplication::translate("Lib7z", "Unknown exception caught (%1)")
- .arg(QString::fromLatin1(Q_FUNC_INFO)));
- }
-}
-
-void Lib7z::extractFileFromArchive(QFileDevice* archive, const File& item,
- const QString &targetDirectory, ExtractCallback* callback)
-{
- assert(archive);
+ CArchiveLink archiveLink;
+ if (archiveLink.Open2(op, nullptr) != S_OK) {
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Cannot open archive \"%1\".").arg(archive->fileName()));
+ }
- QScopedPointer<ExtractCallback> dummyCallback(callback ? 0 : new ExtractCallback);
- if (!callback)
- callback = dummyCallback.data();
+ callback->setTarget(directory);
+ for (unsigned a = 0; a < archiveLink.Arcs.Size(); ++a) {
+ callback->setArchive(&archiveLink.Arcs[a]);
+ IInArchive *const arch = archiveLink.Arcs[a].Archive;
- QFileInfo fi(targetDirectory + QLatin1String("/") + item.path);
- DirectoryGuard outDir(fi.absolutePath());
- outDir.tryCreate();
- QFile out(fi.absoluteFilePath());
- if (!out.open(QIODevice::WriteOnly)) { //TODO use tmp file
+ const LONG result = arch->Extract(0, static_cast<UInt32>(-1), false, callback);
+ if (result != S_OK)
+ throw SevenZipException(errorMessageFrom7zResult(result));
+ }
+ } catch (const SevenZipException &e) {
+ externCallback.Detach();
+ throw e; // re-throw unmodified
+ } catch (...) {
+ externCallback.Detach();
throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not create output file for writing: %1").arg(fi.absoluteFilePath()));
+ "Unknown exception caught (%1).").arg(QString::fromLatin1(Q_FUNC_INFO)));
}
- callback->setTarget(&out);
- extractFileFromArchive(archive, item, &out, callback);
- if (item.permissions)
- out.setPermissions(item.permissions);
outDir.release();
+ externCallback.Detach();
}
-void Lib7z::extractArchive(QFileDevice* archive, const QString &targetDirectory,
- ExtractCallback* callback)
-{
- assert(archive);
-
- QScopedPointer<ExtractCallback> dummyCallback(callback ? 0 : new ExtractCallback);
- if (!callback)
- callback = dummyCallback.data();
-
- callback->setTarget(targetDirectory);
-
- const QFileInfo fi(targetDirectory);
- DirectoryGuard outDir(fi.absolutePath());
- outDir.tryCreate();
-
- const OpenArchiveInfo* const openArchive = OpenArchiveInfo::value(archive);
-
- for (int a = 0; a < openArchive->archiveLink.Arcs.Size(); ++a)
- {
- const CArc& arc = openArchive->archiveLink.Arcs[a];
- IInArchive* const arch = arc.Archive;
- callback->impl()->setArchive(&arc);
- const LONG extractResult = arch->Extract(0, static_cast< UInt32 >(-1), false, callback->impl());
-
- if (extractResult != S_OK)
- throw SevenZipException(errorMessageFrom7zResult(extractResult));
- }
-
- outDir.release();
-}
+/*!
+ Returns \c true if the given \a archive is supported; otherwise returns \c false.
-bool Lib7z::isSupportedArchive(const QString &archive)
+ \note Throws SevenZipException on error.
+*/
+bool isSupportedArchive(QFileDevice *archive)
{
- QFile file(archive);
- if (!file.open(QIODevice::ReadOnly))
- return false;
+ LIB7Z_ASSERTS(archive, Readable)
- return isSupportedArchive(&file);
-}
-
-bool Lib7z::isSupportedArchive(QFileDevice* archive)
-{
- assert(archive);
- assert(!archive->isSequential());
const qint64 initialPos = archive->pos();
try {
- QScopedPointer<CCodecs> codecs(new CCodecs);
- if (codecs->Load() != S_OK)
- throw SevenZipException(QCoreApplication::translate("Lib7z", "Could not load codecs"));
+ CCodecs codecs;
+ if (codecs.Load() != S_OK)
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot load codecs."));
- CIntVector formatIndices;
+ COpenOptions op;
+ op.codecs = &codecs;
+
+ CObjectVector<COpenType> types;
+ op.types = &types; // Empty, because we use a stream.
+
+ CIntVector excluded;
+ op.excludedFormats = &excluded;
- if (!codecs->FindFormatForArchiveType(L"", formatIndices)) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not retrieve default format"));
- }
- CArchiveLink archiveLink;
- //CMyComPtr is needed, otherwise it crashes in OpenStream()
const CMyComPtr<IInStream> stream = new QIODeviceInStream(archive);
+ op.stream = stream; // CMyComPtr is needed, otherwise it crashes in OpenStream().
+
+ CObjectVector<CProperty> properties;
+ op.props = &properties;
- const HRESULT result = archiveLink.Open2(codecs.data(), formatIndices, /*stdInMode*/false, stream,
- UString(), 0);
+ CArchiveLink archiveLink;
+ const HRESULT result = archiveLink.Open2(op, nullptr);
archive->seek(initialPos);
return result == S_OK;
- } catch (const SevenZipException& e) {
- archive->seek(initialPos);
- throw e;
} catch (const char *err) {
archive->seek(initialPos);
throw SevenZipException(err);
+ } catch (const SevenZipException &e) {
+ archive->seek(initialPos);
+ throw e; // re-throw unmodified
} catch (...) {
archive->seek(initialPos);
- throw SevenZipException(QCoreApplication::translate("Lib7z", "Unknown exception caught (%1)")
- .arg(QString::fromLatin1(Q_FUNC_INFO)));
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Unknown exception caught (%1).").arg(QString::fromLatin1(Q_FUNC_INFO)));
}
return false; // never reached
}
-void ExtractItemJob::doStart()
+/*!
+ Returns \c true if the given \a archive is supported; otherwise returns \c false.
+
+ \note Throws SevenZipException on error.
+*/
+bool isSupportedArchive(const QString &archive)
{
- try {
- if (!d->archive)
- throw SevenZipException(tr("Could not list archive: QIODevice not set or already destroyed."));
- if (d->target)
- extractFileFromArchive(d->archive, d->item, d->target, d->callback);
- else if (!d->item.path.isEmpty())
- extractFileFromArchive(d->archive, d->item, d->targetDirectory, d->callback);
- else
- extractArchive(d->archive, d->targetDirectory, d->callback);
- } catch (const SevenZipException& e) {
- setError(Failed);
- setErrorString(tr("Error while extracting '%1': %2").arg(d->item.path, e.message()));
- } catch (...) {
- setError(Failed);
- setErrorString(tr("Unknown exception caught (%1)").arg(tr("Failed")));
- }
- emitResult();
+ QFile file(archive);
+ if (!file.open(QIODevice::ReadOnly))
+ return false;
+ return isSupportedArchive(&file);
}
+
+} // namespace Lib7z
diff --git a/src/libs/installer/lib7z_facade.h b/src/libs/installer/lib7z_facade.h
index 1af879614..44c5f6cac 100644
--- a/src/libs/installer/lib7z_facade.h
+++ b/src/libs/installer/lib7z_facade.h
@@ -34,253 +34,48 @@
#define LIB7Z_FACADE_H
#include "installer_global.h"
+#include "errors.h"
-#include <QCoreApplication>
-#include <QDateTime>
-#include <QFile>
-#include <QPoint>
-#include <QRunnable>
-#include <QString>
-#include <QVariant>
-#include <QVector>
-
-#include "Common/MyWindows.h"
-
-#include <stdexcept>
-#include <string>
+#include <Common/MyWindows.h>
+#include <7zip/UI/Console/PercentPrinter.h>
QT_BEGIN_NAMESPACE
-class QStringList;
-template <typename T> class QVector;
+class QFileDevice;
QT_END_NAMESPACE
-namespace Lib7z {
- class INSTALLER_EXPORT SevenZipException : public std::runtime_error {
- public:
- explicit SevenZipException( const QString& msg ) : std::runtime_error( msg.toStdString() ), m_message( msg ) {}
- explicit SevenZipException( const char* msg ) : std::runtime_error( msg ), m_message( QString::fromLocal8Bit( msg ) ) {}
- explicit SevenZipException( const std::string& msg ) : std::runtime_error( msg ), m_message( QString::fromLocal8Bit( msg.c_str() ) ) {}
-
- ~SevenZipException() throw() {}
- QString message() const { return m_message; }
- private:
- QString m_message;
- };
-
- class INSTALLER_EXPORT File {
- public:
- File();
- QVector<File> subtreeInPreorder() const;
-
- bool operator<( const File& other ) const;
- bool operator==( const File& other ) const;
-
- QFile::Permissions permissions;
- QString path;
- QDateTime mtime;
- quint64 uncompressedSize;
- quint64 compressedSize;
- bool isDirectory;
- QVector<File> children;
- QPoint archiveIndex;
- };
-
- class ExtractCallbackPrivate;
- class ExtractCallbackImpl;
-
- class ExtractCallback {
- friend class ::Lib7z::ExtractCallbackImpl;
- public:
- ExtractCallback();
- virtual ~ExtractCallback();
-
- void setTarget(QFileDevice* archive);
- void setTarget(const QString& dir );
-
- protected:
- /**
- * Reimplement to prepare for file @p filename to be extracted, e.g. by renaming existing files.
- * @return @p true if the preparation was successful and extraction can be continued.
- * If @p false is returned, the extraction will be aborted. Default implementation returns @p true.
- */
- virtual bool prepareForFile( const QString& filename );
- virtual void setCurrentFile( const QString& filename );
- virtual HRESULT setCompleted( quint64 completed, quint64 total );
+namespace Lib7z
+{
+ void INSTALLER_EXPORT initSevenZ();
+ bool INSTALLER_EXPORT isSupportedArchive(QFileDevice *archive);
+ bool INSTALLER_EXPORT isSupportedArchive(const QString &archive);
- public: //for internal use
- const ExtractCallbackImpl* impl() const;
- ExtractCallbackImpl* impl();
-
- private:
- ExtractCallbackPrivate* const d;
- };
-
- class UpdateCallbackPrivate;
- class UpdateCallbackImpl;
-
- class UpdateCallback
+ class INSTALLER_EXPORT SevenZipException : public QInstaller::Error
{
- friend class ::Lib7z::UpdateCallbackImpl;
public:
- UpdateCallback();
- virtual ~UpdateCallback();
-
- void setTarget(QFileDevice* archive);
- void setSourcePaths(const QStringList& paths);
-
- virtual UpdateCallbackImpl* impl();
-
- private:
- UpdateCallbackPrivate* const d;
- };
-
- class OpenArchiveInfoCleaner : public QObject {
- Q_OBJECT
- public:
- OpenArchiveInfoCleaner() {}
- private Q_SLOTS:
- void deviceDestroyed(QObject*);
- };
-
- /*!
- Extracts the given File \a file from \a archive into output device \a out using the
- provided extract callback \a callback.
-
- Throws Lib7z::SevenZipException on error.
- */
- void INSTALLER_EXPORT extractFileFromArchive(QFileDevice* archive, const File& item,
- QFileDevice* out, ExtractCallback* callback=0 );
-
- /*!
- Extracts the given File \a file from \a archive into target directory \a targetDirectory
- using the provided extract callback \a callback. The output filename is deduced from the
- \a file path name.
-
- Throws Lib7z::SevenZipException on error.
- */
- void INSTALLER_EXPORT extractFileFromArchive(QFileDevice* archive, const File& item,
- const QString& targetDirectory, ExtractCallback* callback = 0);
-
- /*!
- Extracts the given \a archive content into target directory \a targetDirectory using the
- provided extract callback \a callback. The output filenames are deduced from the \a archive
- content.
+ explicit SevenZipException(const QString &msg)
+ : QInstaller::Error(msg)
+ {}
- Throws Lib7z::SevenZipException on error.
- */
- void INSTALLER_EXPORT extractArchive(QFileDevice* archive, const QString& targetDirectory,
- ExtractCallback* callback = 0);
-
- /*
- * @thows Lib7z::SevenZipException
- */
- void INSTALLER_EXPORT createArchive(QFileDevice* archive, const QStringList& sourcePaths,
- UpdateCallback* callback = 0 );
-
- /*
- * @throws Lib7z::SevenZipException
- */
- QVector<File> INSTALLER_EXPORT listArchive(QFileDevice* archive);
-
- /*
- * @throws Lib7z::SevenZipException
- */
- bool INSTALLER_EXPORT isSupportedArchive(QFileDevice* archive);
-
- /*
- * @throws Lib7z::SevenZipException
- */
- bool INSTALLER_EXPORT isSupportedArchive(const QString& archive);
-
- enum Error {
- NoError=0,
- Failed=1,
- UserDefinedError=128
+ explicit SevenZipException(const char *msg)
+ : QInstaller::Error(QString::fromLocal8Bit(msg))
+ {}
};
- class ExtractCallbackJobImpl;
-
- class INSTALLER_EXPORT Job : public QObject, public QRunnable
+ class INSTALLER_EXPORT PercentPrinter : public CPercentPrinter
{
- friend class ::Lib7z::ExtractCallbackJobImpl;
- Q_OBJECT
- public:
-
- explicit Job( QObject* parent=0 );
- ~Job();
- void start();
- int error() const;
- bool hasError() const;
- QString errorString() const;
-
- /* reimp */ void run();
-
- protected:
- void emitResult();
- void setError( int code );
- void setErrorString( const QString& err );
- void emitProgress( qint64 completed, qint64 total );
-
- Q_SIGNALS:
- void finished( Lib7z::Job* job );
- void progress( qint64 completed, qint64 total );
-
- private Q_SLOTS:
- virtual void doStart() = 0;
-
- private:
- class Private;
- Private* const d;
- };
-
- class INSTALLER_EXPORT ListArchiveJob : public Job {
- Q_OBJECT
public:
-
- explicit ListArchiveJob( QObject* parent=0 );
- ~ListArchiveJob();
-
- QFileDevice* archive() const;
- void setArchive(QFileDevice* archive);
-
- QVector<File> index() const;
-
- private:
- /* reimp */ void doStart();
-
- private:
- class Private;
- Private* const d;
- };
-
- class INSTALLER_EXPORT ExtractItemJob : public Job {
- Q_OBJECT
- friend class ::Lib7z::ExtractCallback;
- public:
-
- explicit ExtractItemJob( QObject* parent=0 );
- ~ExtractItemJob();
-
- File item() const;
- void setItem( const File& item );
-
- QFileDevice* archive() const;
- void setArchive(QFileDevice* archive);
-
- QString targetDirectory() const;
- void setTargetDirectory( const QString& dir );
-
- void setTarget(QFileDevice* dev);
-
- private:
- /* reimp */ void doStart();
-
- private:
- class Private;
- Private* const d;
+ PercentPrinter() : CPercentPrinter(1 << 16) {
+ OutStream = &g_StdOut;
+ }
+
+ void PrintRatio() { CPercentPrinter::PrintRatio(); }
+ void ClosePrint() { CPercentPrinter::ClosePrint(); }
+ void RePrintRatio() { CPercentPrinter::RePrintRatio(); }
+ void PrintNewLine() { CPercentPrinter::PrintNewLine(); }
+ void PrintString(const char *s) { CPercentPrinter::PrintString(s); }
+ void PrintString(const wchar_t *s) { CPercentPrinter::PrintString(s); }
};
- QByteArray INSTALLER_EXPORT formatKeyValuePairs( const QVariantList& l );
-}
+} // namespace Lib7z
#endif // LIB7Z_FACADE_H
diff --git a/src/libs/installer/lib7z_guid.h b/src/libs/installer/lib7z_guid.h
new file mode 100644
index 000000000..16434558c
--- /dev/null
+++ b/src/libs/installer/lib7z_guid.h
@@ -0,0 +1,97 @@
+/**************************************************************************
+**
+** 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$
+**
+**************************************************************************/
+#ifndef LIB7Z_GUID_H
+#define LIB7Z_GUID_H
+
+#include <Common/MyInitGuid.h>
+
+#ifdef __cplusplus
+#define DEFINE_7Z_GUID(name, b4, b5, b6) extern "C" const GUID IID_ ## name = { 0x23170F69, \
+ 0x40C1, 0x278A, { 0x00, 0x00, 0x00, b4, b5, b6, 0x00, 0x00 } }
+#else
+#define DEFINE_7Z_GUID(name, b4, b5, b6) extern const GUID IID_ ## name = { 0x23170F69, \
+ 0x40C1, 0x278A, { 0x00, 0x00, 0x00, b4, b5, b6, 0x00, 0x00 } }
+#endif
+
+DEFINE_7Z_GUID(IInArchiveGetStream, 0x06, 0x00, 0x40);
+DEFINE_7Z_GUID(IInArchive, 0x06, 0x00, 0x60);
+
+DEFINE_7Z_GUID(IOutStream, 0x03, 0x00, 0x04);
+DEFINE_7Z_GUID(IOutStreamFlush, 0x03, 0x00, 0x07);
+DEFINE_7Z_GUID(IOutArchive, 0x06, 0x00, 0xA0);
+
+DEFINE_7Z_GUID(IInStream, 0x03, 0x00, 0x03);
+
+DEFINE_7Z_GUID(ISetProperties, 0x06, 0x00, 0x03);
+
+DEFINE_7Z_GUID(ISequentialInStream, 0x03, 0x00, 0x01);
+DEFINE_7Z_GUID(ISequentialOutStream, 0x03, 0x00, 0x02);
+
+DEFINE_7Z_GUID(IStreamGetSize, 0x03, 0x00, 0x06);
+DEFINE_7Z_GUID(IStreamGetProps, 0x03, 0x00, 0x08);
+DEFINE_7Z_GUID(IStreamGetProps2, 0x03, 0x00, 0x09);
+
+DEFINE_7Z_GUID(IArchiveKeepModeForNextOpen, 0x06, 0x00, 0x04);
+DEFINE_7Z_GUID(IArchiveAllowTail, 0x06, 0x00, 0x05);
+DEFINE_7Z_GUID(IArchiveOpenCallback, 0x06, 0x00, 0x10);
+DEFINE_7Z_GUID(IArchiveExtractCallback, 0x06, 0x00, 0x20);
+DEFINE_7Z_GUID(IArchiveOpenVolumeCallback, 0x06, 0x00, 0x30);
+DEFINE_7Z_GUID(IArchiveOpenSetSubArchiveName, 0x06, 0x00, 0x50);
+DEFINE_7Z_GUID(IArchiveOpenSeq, 0x06, 0x00, 0x61);
+DEFINE_7Z_GUID(IArchiveGetRawProps, 0x06, 0x00, 0x70);
+DEFINE_7Z_GUID(IArchiveGetRootProps, 0x06, 0x00, 0x71);
+DEFINE_7Z_GUID(IArchiveUpdateCallback, 0x06, 0x00, 0x80);
+DEFINE_7Z_GUID(IArchiveUpdateCallback2, 0x06, 0x00, 0x82);
+
+DEFINE_7Z_GUID(ICompressProgressInfo, 0x04, 0x00, 0x04);
+DEFINE_7Z_GUID(ICompressCoder, 0x04, 0x00, 0x05);
+DEFINE_7Z_GUID(ICompressSetCoderProperties, 0x04, 0x00, 0x20);
+DEFINE_7Z_GUID(ICompressSetDecoderProperties2, 0x04, 0x00, 0x22);
+DEFINE_7Z_GUID(ICompressWriteCoderProperties, 0x04, 0x00, 0x23);
+DEFINE_7Z_GUID(ICompressGetInStreamProcessedSize, 0x04, 0x00, 0x24);
+DEFINE_7Z_GUID(ICompressSetCoderMt, 0x04, 0x00, 0x25);
+DEFINE_7Z_GUID(ICompressSetOutStream, 0x04, 0x00, 0x32);
+DEFINE_7Z_GUID(ICompressSetInStream, 0x04, 0x00, 0x31);
+DEFINE_7Z_GUID(ICompressSetOutStreamSize, 0x04, 0x00, 0x34);
+DEFINE_7Z_GUID(ICompressSetBufSize, 0x04, 0x00, 0x35);
+DEFINE_7Z_GUID(ICompressGetSubStreamSize, 0x04, 0x00, 0x30);
+DEFINE_7Z_GUID(ICryptoResetInitVector, 0x04, 0x00, 0x8C);
+DEFINE_7Z_GUID(ICryptoSetPassword, 0x04, 0x00, 0x90);
+
+DEFINE_7Z_GUID(ICryptoGetTextPassword, 0x05, 0x00, 0x10);
+DEFINE_7Z_GUID(ICryptoGetTextPassword2, 0x05, 0x00, 0x11);
+
+#undef DEFINE_7Z_GUID
+
+#endif // LIB7Z_GUID_H
diff --git a/src/libs/installer/lib7z_list.h b/src/libs/installer/lib7z_list.h
new file mode 100644
index 000000000..6e2646025
--- /dev/null
+++ b/src/libs/installer/lib7z_list.h
@@ -0,0 +1,62 @@
+/**************************************************************************
+**
+** 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$
+**
+**************************************************************************/
+#ifndef LIB7Z_LIST_H
+#define LIB7Z_LIST_H
+
+#include "installer_global.h"
+
+#include <QDateTime>
+#include <QFile>
+#include <QPoint>
+
+namespace Lib7z
+{
+ struct INSTALLER_EXPORT File
+ {
+ public:
+ QString path;
+ QDateTime utcTime;
+ QPoint archiveIndex;
+ bool isDirectory = false;
+ quint64 compressedSize = 0;
+ quint64 uncompressedSize = 0;
+ QFile::Permissions permissions = 0;
+ };
+ INSTALLER_EXPORT bool operator==(const File &lhs, const File &rhs);
+
+ QVector<File> INSTALLER_EXPORT listArchive(QFileDevice *archive);
+
+} // namespace Lib7z
+
+#endif // LIB7Z_LIST_H
diff --git a/src/libs/installer/licenseoperation.cpp b/src/libs/installer/licenseoperation.cpp
index 2faf8d4a7..0f4797ac0 100644
--- a/src/libs/installer/licenseoperation.cpp
+++ b/src/libs/installer/licenseoperation.cpp
@@ -42,7 +42,8 @@
using namespace QInstaller;
-LicenseOperation::LicenseOperation()
+LicenseOperation::LicenseOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("License"));
}
@@ -60,26 +61,25 @@ bool LicenseOperation::performOperation()
return false;
}
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ PackageManagerCore *const core = packageManager();
if (!core) {
setError( UserDefinedError );
setErrorString(tr("Needed installer object in %1 operation is empty.").arg(name()));
return false;
}
- QString targetDir = QString::fromLatin1("%1/%2").arg(core->value(scTargetDir),
- QLatin1String("Licenses"));
+ QString targetDir = QString::fromLatin1("%1%2%3").arg(core->value(scTargetDir),
+ QDir::separator(), QLatin1String("Licenses"));
QDir dir;
dir.mkpath(targetDir);
setArguments(QStringList(targetDir));
- for (QVariantMap::const_iterator it = licenses.begin(); it != licenses.end(); ++it) {
- QFile file(targetDir + QDir::separator() + it.key());
+ for (QVariantMap::const_iterator it = licenses.constBegin(); it != licenses.constEnd(); ++it) {
+ QFile file(targetDir + QLatin1Char('/') + it.key());
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
setError(UserDefinedError);
- setErrorString(tr("Can not write license file: %1.").arg(targetDir + QDir::separator()
- + it.key()));
+ setErrorString(tr("Can not write license file \"%1\".").arg(QDir::toNativeSeparators(file.fileName())));
return false;
}
@@ -92,7 +92,7 @@ bool LicenseOperation::performOperation()
bool LicenseOperation::undoOperation()
{
- QVariantMap licenses = value(QLatin1String("licenses")).toMap();
+ const QVariantMap licenses = value(QLatin1String("licenses")).toMap();
if (licenses.isEmpty()) {
setError(UserDefinedError);
setErrorString(tr("No license files found to delete."));
@@ -113,8 +113,3 @@ bool LicenseOperation::testOperation()
{
return true;
}
-
-Operation *LicenseOperation::clone() const
-{
- return new LicenseOperation();
-}
diff --git a/src/libs/installer/licenseoperation.h b/src/libs/installer/licenseoperation.h
index 4cb75590b..88d7857a1 100644
--- a/src/libs/installer/licenseoperation.h
+++ b/src/libs/installer/licenseoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT LicenseOperation : public Operation
{
public:
- LicenseOperation();
+ explicit LicenseOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation* clone() const;
};
} // namespace QInstaller
diff --git a/src/libs/installer/linereplaceoperation.cpp b/src/libs/installer/linereplaceoperation.cpp
index 670ebbd63..1a3d2c670 100644
--- a/src/libs/installer/linereplaceoperation.cpp
+++ b/src/libs/installer/linereplaceoperation.cpp
@@ -39,7 +39,8 @@
using namespace QInstaller;
-LineReplaceOperation::LineReplaceOperation()
+LineReplaceOperation::LineReplaceOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("LineReplace"));
}
@@ -50,18 +51,14 @@ void LineReplaceOperation::backup()
bool LineReplaceOperation::performOperation()
{
- const QStringList args = arguments();
-
// Arguments:
// 1. filename
// 2. startsWith Search-String
// 3. Replace-Line-String
- if (args.count() != 3) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 3"), QLatin1String("")));
+ if (!checkArgumentCount(3))
return false;
- }
+
+ const QStringList args = arguments();
const QString fileName = args.at(0);
const QString searchString = args.at(1);
const QString replaceString = args.at(2);
@@ -69,7 +66,8 @@ bool LineReplaceOperation::performOperation()
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to open '%1' for reading.").arg(fileName));
+ setErrorString(tr("Cannot open file \"%1\" for reading: %2").arg(
+ QDir::toNativeSeparators(fileName), file.errorString()));
return false;
}
@@ -86,7 +84,8 @@ bool LineReplaceOperation::performOperation()
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to open '%1' for writing.").arg(fileName));
+ setErrorString(tr("Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(fileName), file.errorString()));
return false;
}
@@ -106,8 +105,3 @@ bool LineReplaceOperation::testOperation()
{
return true;
}
-
-Operation *LineReplaceOperation::clone() const
-{
- return new LineReplaceOperation();
-}
diff --git a/src/libs/installer/linereplaceoperation.h b/src/libs/installer/linereplaceoperation.h
index b28cf661c..c80325ade 100644
--- a/src/libs/installer/linereplaceoperation.h
+++ b/src/libs/installer/linereplaceoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT LineReplaceOperation : public Operation
{
public:
- LineReplaceOperation();
+ explicit LineReplaceOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
} // namespace
diff --git a/src/libs/installer/link.cpp b/src/libs/installer/link.cpp
index a8c640a50..ead52e513 100644
--- a/src/libs/installer/link.cpp
+++ b/src/libs/installer/link.cpp
@@ -93,8 +93,7 @@ public:
OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0);
if (m_dirHandle == INVALID_HANDLE_VALUE) {
- qWarning() << QString::fromLatin1("Could not open: '%1'; error: %2\n").arg(path)
- .arg(QInstaller::windowsErrorString(GetLastError()));
+ qWarning() << "Cannot open" << path << ":" << QInstaller::windowsErrorString(GetLastError());
}
}
@@ -143,14 +142,12 @@ QString readWindowsSymLink(const QString &path)
Link createJunction(const QString &linkPath, const QString &targetPath)
{
if (!QDir().mkpath(linkPath)) {
- qWarning() << QString::fromLatin1("Could not create the mount directory: %1").arg(
- linkPath);
+ qWarning() << "Cannot create the mount directory" << linkPath;
return Link(linkPath);
}
FileHandleWrapper dirHandle(linkPath);
if (dirHandle.handle() == INVALID_HANDLE_VALUE) {
- qWarning() << QString::fromLatin1("Could not open: '%1'; error: %2\n").arg(linkPath)
- .arg(QInstaller::windowsErrorString(GetLastError()));
+ qWarning() << "Cannot open" << linkPath << ":" << QInstaller::windowsErrorString(GetLastError());
return Link(linkPath);
}
@@ -180,8 +177,8 @@ Link createJunction(const QString &linkPath, const QString &targetPath)
if (!::DeviceIoControl(dirHandle.handle(), FSCTL_SET_REPARSE_POINT, reparseStructData,
reparseStructData->ReparseDataLength + REPARSE_DATA_BUFFER_HEADER_SIZE, 0, 0,
&bytesReturned, 0)) {
- qWarning() << QString::fromLatin1("Could not set the reparse point: for '%1' to %2; error: %3"
- ).arg(linkPath, targetPath).arg(QInstaller::windowsErrorString(GetLastError()));
+ qWarning() << "Cannot set the reparse point for" << linkPath << "to" << targetPath
+ << ":" << QInstaller::windowsErrorString(GetLastError());
}
return Link(linkPath);
}
@@ -202,8 +199,7 @@ bool removeJunction(const QString &path)
REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, 0, 0,
&bytesReturned, 0)) {
- qWarning() << QString::fromLatin1("Could not remove the reparse point: '%1'; error: %3"
- ).arg(path).arg(QInstaller::windowsErrorString(GetLastError()));
+ qWarning() << "Cannot remove the reparse point" << path << ":" << QInstaller::windowsErrorString(GetLastError());
return false;
}
}
@@ -216,8 +212,7 @@ Link createLnSymlink(const QString &linkPath, const QString &targetPath)
int linkedError = symlink(QFileInfo(targetPath).absoluteFilePath().toUtf8(),
QFileInfo(linkPath).absoluteFilePath().toUtf8());
if (linkedError != 0) {
- qWarning() << QString::fromLatin1("Could not create a symlink: from '%1' to %2; error: %3"
- ).arg(linkPath, targetPath).arg(linkedError);
+ qWarning() << "Cannot create a symlink from" << linkPath << "to" << targetPath << ":" << linkedError;
}
@@ -244,8 +239,7 @@ Link Link::create(const QString &link, const QString &targetPath)
if (!linkPathExists)
linkPathExists = QDir().mkpath(linkPath);
if (!linkPathExists) {
- qWarning() << QString::fromLatin1("Could not create the needed directories: %1").arg(
- link);
+ qWarning() << "Cannot create the needed directories" << link;
return Link(link);
}
@@ -253,8 +247,8 @@ Link Link::create(const QString &link, const QString &targetPath)
if (QFileInfo(targetPath).isDir())
return createJunction(link, targetPath);
- qWarning() << QString::fromLatin1("At the moment the %1 can not create anything else as "\
- "junctions for directories under windows").arg(QLatin1String(Q_FUNC_INFO));
+ qWarning() << "At the moment the" << Q_FUNC_INFO << "can not create anything else as "
+ << "junctions for directories under windows";
return Link(link);
#else
return createLnSymlink(link, targetPath);
diff --git a/src/libs/installer/messageboxhandler.cpp b/src/libs/installer/messageboxhandler.cpp
index 0c61424b5..66ccc23e0 100644
--- a/src/libs/installer/messageboxhandler.cpp
+++ b/src/libs/installer/messageboxhandler.cpp
@@ -406,8 +406,8 @@ QMessageBox::StandardButton MessageBoxHandler::showMessageBox(MessageType messag
messageTypeHash.insert(warningType, QLatin1String("warning"));
};
- qDebug() << QString::fromLatin1("created %1 message box %2: '%3', %4").arg(messageTypeHash
- .value(messageType),identifier, title, text);
+ qDebug().nospace() << "Created " << messageTypeHash.value(messageType).toUtf8().constData()
+ << " message box " << identifier << ": " << title << ", " << text;
if (qobject_cast<QApplication*> (qApp) == 0)
return defaultButton;
diff --git a/src/libs/installer/metadatajob.cpp b/src/libs/installer/metadatajob.cpp
index 77a04104c..5186df409 100644
--- a/src/libs/installer/metadatajob.cpp
+++ b/src/libs/installer/metadatajob.cpp
@@ -45,13 +45,13 @@
namespace QInstaller {
MetadataJob::MetadataJob(QObject *parent)
- : KDJob(parent)
+ : Job(parent)
, m_core(0)
{
setCapabilities(Cancelable);
- connect(&m_xmlTask, SIGNAL(finished()), this, SLOT(xmlTaskFinished()));
- connect(&m_metadataTask, SIGNAL(finished()), this, SLOT(metadataTaskFinished()));
- connect(&m_metadataTask, SIGNAL(progressValueChanged(int)), this, SLOT(progressChanged(int)));
+ connect(&m_xmlTask, &QFutureWatcherBase::finished, this, &MetadataJob::xmlTaskFinished);
+ connect(&m_metadataTask, &QFutureWatcherBase::finished, this, &MetadataJob::metadataTaskFinished);
+ connect(&m_metadataTask, &QFutureWatcherBase::progressValueChanged, this, &MetadataJob::progressChanged);
}
MetadataJob::~MetadataJob()
@@ -71,13 +71,13 @@ void MetadataJob::doStart()
{
reset();
if (!m_core) {
- emitFinishedWithError(KDJob::Canceled, tr("Missing package manager core engine."));
+ emitFinishedWithError(Job::Canceled, tr("Missing package manager core engine."));
return; // We can't do anything here without core, so avoid tons of !m_core checks.
}
emit infoMessage(this, tr("Preparing meta information download..."));
const bool onlineInstaller = m_core->isInstaller() && !m_core->isOfflineOnly();
- if (onlineInstaller || (m_core->isUpdater() || m_core->isPackageManager())) {
+ if (onlineInstaller || m_core->isMaintainer()) {
QList<FileTaskItem> items;
const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance();
foreach (const Repository &repo, m_core->settings().repositories()) {
@@ -87,8 +87,8 @@ void MetadataJob::doStart()
authenticator.setPassword(repo.password());
QString url = repo.url().toString() + QLatin1String("/Updates.xml?");
- if (!m_core->value(QLatin1String("UrlQueryString")).isEmpty())
- url += m_core->value(QLatin1String("UrlQueryString")) + QLatin1Char('&');
+ if (!m_core->value(scUrlQueryString).isEmpty())
+ url += m_core->value(scUrlQueryString) + QLatin1Char('&');
// also append a random string to avoid proxy caches
FileTaskItem item(url.append(QString::number(qrand() * qrand())));
@@ -108,7 +108,7 @@ void MetadataJob::doStart()
void MetadataJob::doCancel()
{
reset();
- emitFinishedWithError(KDJob::Canceled, tr("Meta data download canceled."));
+ emitFinishedWithError(Job::Canceled, tr("Meta data download canceled."));
}
void MetadataJob::xmlTaskFinished()
@@ -121,7 +121,7 @@ void MetadataJob::xmlTaskFinished()
if (e.type() == AuthenticationRequiredException::Type::Proxy) {
const QNetworkProxy proxy = e.proxy();
ProxyCredentialsDialog proxyCredentials(proxy);
- qDebug() << e.message();
+ qDebug().noquote() << e.message();
if (proxyCredentials.exec() == QDialog::Accepted) {
qDebug() << "Retrying with new credentials ...";
@@ -136,7 +136,7 @@ void MetadataJob::xmlTaskFinished()
emitFinishedWithError(QInstaller::DownloadError, tr("Missing proxy credentials."));
}
} else if (e.type() == AuthenticationRequiredException::Type::Server) {
- qDebug() << e.message();
+ qDebug().noquote() << e.message();
ServerAuthenticationDialog dlg(e.message(), e.taskItem());
if (dlg.exec() == QDialog::Accepted) {
Repository original = e.taskItem().value(TaskRole::UserRole)
@@ -157,7 +157,7 @@ void MetadataJob::xmlTaskFinished()
if (s.updateDefaultRepositories(update) == Settings::UpdatesApplied
|| s.updateUserRepositories(update) == Settings::UpdatesApplied) {
- if (m_core->isUpdater() || m_core->isPackageManager())
+ if (m_core->isMaintainer())
m_core->writeMaintenanceConfigFiles();
}
}
@@ -178,7 +178,7 @@ void MetadataJob::xmlTaskFinished()
emitFinishedWithError(QInstaller::DownloadError, tr("Unknown exception during download."));
}
- if (error() != KDJob::NoError)
+ if (error() != Job::NoError)
return;
if (status == XmlDownloadSuccess) {
@@ -211,7 +211,7 @@ void MetadataJob::unzipTaskFinished()
emitFinishedWithError(QInstaller::DownloadError, tr("Unknown exception during extracting."));
}
- if (error() != KDJob::NoError)
+ if (error() != Job::NoError)
return;
delete m_unzipTasks.value(watcher);
@@ -243,7 +243,7 @@ void MetadataJob::metadataTaskFinished()
QFutureWatcher<void> *watcher = new QFutureWatcher<void>();
m_unzipTasks.insert(watcher, qobject_cast<QObject*> (task));
- connect(watcher, SIGNAL(finished()), this, SLOT(unzipTaskFinished()));
+ connect(watcher, &QFutureWatcherBase::finished, this, &MetadataJob::unzipTaskFinished);
watcher->setFuture(QtConcurrent::run(&UnzipArchiveTask::doTask, task));
}
} else {
@@ -269,7 +269,7 @@ void MetadataJob::reset()
m_packages.clear();
m_metadata.clear();
- setError(KDJob::NoError);
+ setError(Job::NoError);
setErrorString(QString());
setCapabilities(Cancelable);
@@ -290,13 +290,13 @@ void MetadataJob::reset()
MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &results)
{
foreach (const FileTaskResult &result, results) {
- if (error() != KDJob::NoError)
+ if (error() != Job::NoError)
return XmlDownloadFailure;
Metadata metadata;
QTemporaryDir tmp(QDir::tempPath() + QLatin1String("/remoterepo-XXXXXX"));
if (!tmp.isValid()) {
- qDebug() << "Could not create unique temporary directory.";
+ qDebug() << "Cannot create unique temporary directory.";
return XmlDownloadFailure;
}
@@ -306,20 +306,20 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
QFile file(result.target());
if (!file.rename(metadata.directory + QLatin1String("/Updates.xml"))) {
- qDebug() << "Could not rename target to Updates.xml. Error:" << file.errorString();
+ qDebug() << "Cannot rename target to Updates.xml:" << file.errorString();
return XmlDownloadFailure;
}
if (!file.open(QIODevice::ReadOnly)) {
- qDebug() << "Could not open Updates.xml for reading. Error:" << file.errorString();
+ qDebug() << "Cannot open Updates.xml for reading:" << file.errorString();
return XmlDownloadFailure;
}
QString error;
QDomDocument doc;
if (!doc.setContent(&file, &error)) {
- qDebug() << QString::fromLatin1("Could not fetch a valid version of Updates.xml from "
- "repository: %1. Error: %2").arg(metadata.repository.displayname(), error);
+ qDebug().nospace() << "Cannot fetch a valid version of Updates.xml from repository "
+ << metadata.repository.displayname() << ": " << error;
return XmlDownloadFailure;
}
file.close();
@@ -343,7 +343,7 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
for (int j = 0; j < c2.count(); ++j) {
if (c2.at(j).toElement().tagName() == scName)
packageName = c2.at(j).toElement().text();
- else if (c2.at(j).toElement().tagName() == scRemoteVersion)
+ else if (c2.at(j).toElement().tagName() == scVersion)
packageVersion = (online ? c2.at(j).toElement().text() : QString());
else if ((c2.at(j).toElement().tagName() == QLatin1String("SHA1")) && testCheckSum)
packageHash = c2.at(j).toElement().text();
@@ -404,12 +404,12 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
if (ProductKeyCheck::instance()->isValidRepository(newRepository)) {
// store the new repository and the one old it replaces
repositoryUpdates.insertMulti(action, qMakePair(newRepository, oldRepository));
- qDebug() << "Replace repository:" << oldRepository.displayname() << "with:"
+ qDebug() << "Replace repository" << oldRepository.displayname() << "with"
<< newRepository.displayname();
}
} else {
qDebug() << "Invalid additional repositories action set in Updates.xml fetched "
- "from:" << metadata.repository.displayname() << "Line:" << el.lineNumber();
+ "from" << metadata.repository.displayname() << "line:" << el.lineNumber();
}
}
}
@@ -437,7 +437,7 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
return XmlDownloadRetry;
}
} else if (s.updateDefaultRepositories(repositoryUpdates) == Settings::UpdatesApplied) {
- if (m_core->isUpdater() || m_core->isPackageManager())
+ if (m_core->isMaintainer())
m_core->writeMaintenanceConfigFiles();
QFile::remove(result.target());
return XmlDownloadRetry;
diff --git a/src/libs/installer/metadatajob.h b/src/libs/installer/metadatajob.h
index 4350d0182..10fffe172 100644
--- a/src/libs/installer/metadatajob.h
+++ b/src/libs/installer/metadatajob.h
@@ -36,7 +36,7 @@
#include "downloadfiletask.h"
#include "fileutils.h"
-#include "kdjob.h"
+#include "job.h"
#include "repository.h"
#include <QFutureWatcher>
@@ -51,7 +51,7 @@ struct Metadata
Repository repository;
};
-class INSTALLER_EXPORT MetadataJob : public KDJob
+class INSTALLER_EXPORT MetadataJob : public Job
{
Q_OBJECT
Q_DISABLE_COPY(MetadataJob)
diff --git a/src/libs/installer/metadatajob_p.h b/src/libs/installer/metadatajob_p.h
index 549571820..a07c7a80f 100644
--- a/src/libs/installer/metadatajob_p.h
+++ b/src/libs/installer/metadatajob_p.h
@@ -34,9 +34,13 @@
#ifndef METADATAJOB_P_H
#define METADATAJOB_P_H
+#include "lib7z_extract.h"
#include "lib7z_facade.h"
#include "metadatajob.h"
+#include <QDir>
+#include <QFile>
+
namespace QInstaller{
class UnzipArchiveException : public QException
@@ -82,14 +86,14 @@ public:
Lib7z::extractArchive(&archive, m_targetDir);
} catch (const Lib7z::SevenZipException& e) {
fi.reportException(UnzipArchiveException(MetadataJob::tr("Error while extracting "
- "'%1': %2").arg(m_archive, e.message())));
+ "archive \"%1\": %2").arg(QDir::toNativeSeparators(m_archive), e.message())));
} catch (...) {
fi.reportException(UnzipArchiveException(MetadataJob::tr("Unknown exception "
- "caught while extracting %1.").arg(m_archive)));
+ "caught while extracting archive \"%1\".").arg(QDir::toNativeSeparators(m_archive))));
}
} else {
- fi.reportException(UnzipArchiveException(MetadataJob::tr("Could not open %1 for "
- "reading. Error: %2").arg(m_archive, archive.errorString())));
+ fi.reportException(UnzipArchiveException(MetadataJob::tr("Cannot open file \"%1\" for "
+ "reading: %2").arg(QDir::toNativeSeparators(m_archive), archive.errorString())));
}
fi.reportFinished();
diff --git a/src/libs/installer/minimumprogressoperation.cpp b/src/libs/installer/minimumprogressoperation.cpp
index 2929135af..a5f1fc881 100644
--- a/src/libs/installer/minimumprogressoperation.cpp
+++ b/src/libs/installer/minimumprogressoperation.cpp
@@ -35,7 +35,8 @@
using namespace QInstaller;
-MinimumProgressOperation::MinimumProgressOperation()
+MinimumProgressOperation::MinimumProgressOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
// This shouldn't be callable by script, but we need a name for the binary format
setName(QLatin1String("MinimumProgress"));
@@ -61,9 +62,3 @@ bool MinimumProgressOperation::testOperation()
{
return true;
}
-
-Operation *MinimumProgressOperation::clone() const
-{
- return new MinimumProgressOperation();
-}
-
diff --git a/src/libs/installer/minimumprogressoperation.h b/src/libs/installer/minimumprogressoperation.h
index 796ac02aa..4b4e4def9 100644
--- a/src/libs/installer/minimumprogressoperation.h
+++ b/src/libs/installer/minimumprogressoperation.h
@@ -45,13 +45,12 @@ class MinimumProgressOperation : public QObject, public Operation
Q_OBJECT
public:
- MinimumProgressOperation();
+ explicit MinimumProgressOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
signals:
void progressChanged(double progress);
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 81fd29472..2b7ec4536 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -60,12 +60,14 @@
#include <QtCore/QMutex>
#include <QtCore/QSettings>
#include <QtCore/QTemporaryFile>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
#include <QDesktopServices>
#include <QFileDialog>
-#include "kdsysinfo.h"
-#include "kdupdaterupdateoperationfactory.h"
+#include "sysinfo.h"
+#include "updateoperationfactory.h"
#ifdef Q_OS_WIN
# include "qt_windows.h"
@@ -427,7 +429,7 @@ void PackageManagerCore::writeMaintenanceTool()
gainAdminRights();
gainedAdminRights = true;
}
- d->m_updaterApplication.packagesInfo()->writeToDisk();
+ d->m_localPackageHub->writeToDisk();
if (gainedAdminRights)
dropAdminRights();
d->m_needToWriteMaintenanceTool = false;
@@ -638,11 +640,11 @@ int PackageManagerCore::downloadNeededArchives(double partProgressSize)
DownloadArchivesJob archivesJob(this);
archivesJob.setAutoDelete(false);
archivesJob.setArchivesToDownload(archivesToDownload);
- connect(this, SIGNAL(installationInterrupted()), &archivesJob, SLOT(cancel()));
- connect(&archivesJob, SIGNAL(outputTextChanged(QString)), ProgressCoordinator::instance(),
- SLOT(emitLabelAndDetailTextChanged(QString)));
- connect(&archivesJob, SIGNAL(downloadStatusChanged(QString)), ProgressCoordinator::instance(),
- SIGNAL(downloadStatusChanged(QString)));
+ connect(this, &PackageManagerCore::installationInterrupted, &archivesJob, &Job::cancel);
+ connect(&archivesJob, &DownloadArchivesJob::outputTextChanged,
+ ProgressCoordinator::instance(), &ProgressCoordinator::emitLabelAndDetailTextChanged);
+ connect(&archivesJob, &DownloadArchivesJob::downloadStatusChanged,
+ ProgressCoordinator::instance(), &ProgressCoordinator::downloadStatusChanged);
ProgressCoordinator::instance()->registerPartProgress(&archivesJob,
SIGNAL(progressChanged(double)), partProgressSize);
@@ -650,13 +652,13 @@ int PackageManagerCore::downloadNeededArchives(double partProgressSize)
archivesJob.start();
archivesJob.waitForFinished();
- if (archivesJob.error() == KDJob::Canceled)
+ if (archivesJob.error() == Job::Canceled)
interrupt();
- else if (archivesJob.error() != KDJob::NoError)
+ else if (archivesJob.error() != Job::NoError)
throw Error(archivesJob.errorString());
if (d->statusCanceledOrFailed())
- throw Error(tr("Installation canceled by user"));
+ throw Error(tr("Installation canceled by user."));
ProgressCoordinator::instance()->emitDownloadStatus(tr("All downloads finished."));
@@ -705,7 +707,6 @@ void PackageManagerCore::rollBackInstallation()
}
}
- KDUpdater::PackagesInfo &packages = *d->m_updaterApplication.packagesInfo();
while (!d->m_performedOperationsCurrentSession.isEmpty()) {
try {
Operation *const operation = d->m_performedOperationsCurrentSession.takeLast();
@@ -732,14 +733,14 @@ void PackageManagerCore::rollBackInstallation()
component = d->componentsToReplace().value(componentName).second;
if (component) {
component->setUninstalled();
- packages.removePackage(component->name());
+ d->m_localPackageHub->removePackage(component->name());
}
}
- packages.writeToDisk();
+ d->m_localPackageHub->writeToDisk();
if (isInstaller()) {
- if (packages.packageInfoCount() == 0) {
- QFile file(packages.fileName());
+ if (d->m_localPackageHub->packageInfoCount() == 0) {
+ QFile file(d->m_localPackageHub->fileName());
file.remove();
}
}
@@ -749,7 +750,7 @@ void PackageManagerCore::rollBackInstallation()
} catch (const Error &e) {
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
QLatin1String("ElevationError"), tr("Authentication Error"), tr("Some components "
- "could not be removed completely because admin rights could not be acquired: %1.")
+ "could not be removed completely because administrative rights could not be acquired: %1.")
.arg(e.message()));
} catch (...) {
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(), QLatin1String("unknown"),
@@ -785,6 +786,32 @@ bool PackageManagerCore::fileExists(const QString &filePath) const
return QFileInfo(filePath).exists();
}
+/*!
+ Returns the contents of the file \a filePath using the encoding specified
+ by \a codecName. The file is read in the text mode, that is, end-of-line
+ terminators are translated to the local encoding.
+
+ \note If the file does not exist or an error occurs while reading the file, an
+ empty string is returned.
+
+ \sa {installer::readFile}{installer.readFile}
+
+ */
+QString PackageManagerCore::readFile(const QString &filePath, const QString &codecName) const
+{
+ QFile f(filePath);
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
+ return QString();
+
+ QTextCodec *codec = QTextCodec::codecForName(qPrintable(codecName));
+ if (!codec)
+ return QString();
+
+ QTextStream stream(&f);
+ stream.setCodec(codec);
+ return stream.readAll();
+}
+
// -- QInstaller
/*!
@@ -867,7 +894,7 @@ PackageManagerCore::~PackageManagerCore()
delete d;
RemoteClient::instance().setActive(false);
- RemoteClient::instance().shutdown();
+ RemoteClient::instance().destroy();
QMutexLocker _(globalVirtualComponentsFontMutex());
delete sVirtualComponentsFont;
@@ -966,7 +993,7 @@ bool PackageManagerCore::fetchLocalPackagesTree()
d->setStatus(Running);
if (!isPackageManager()) {
- d->setStatus(Failure, tr("Application not running in Package Manager mode!"));
+ d->setStatus(Failure, tr("Application not running in Package Manager mode."));
return false;
}
@@ -988,7 +1015,7 @@ bool PackageManagerCore::fetchLocalPackagesTree()
component->loadDataFromPackage(installedPackages.value(key));
const QString &name = component->name();
if (components.contains(name)) {
- qCritical("Could not register component! Component with identifier %s already registered.",
+ qCritical("Cannot register component! Component with identifier %s already registered.",
qPrintable(name));
continue;
}
@@ -1025,8 +1052,18 @@ void PackageManagerCore::networkSettingsChanged()
d->m_repoFetched = false;
d->m_updateSourcesAdded = false;
- if (d->isUpdater() || d->isPackageManager())
+ if (isMaintainer() ) {
+ bool gainedAdminRights = false;
+ QTemporaryFile tempAdminFile(d->targetDir() + QStringLiteral("/XXXXXX"));
+ if (!tempAdminFile.open() || !tempAdminFile.isWritable()) {
+ gainAdminRights();
+ gainedAdminRights = true;
+ }
d->writeMaintenanceConfigFiles();
+ if (gainedAdminRights)
+ dropAdminRights();
+ }
+
KDUpdater::FileDownloaderFactory::instance().setProxyFactory(proxyFactory());
emit coreNetworkSettingsChanged();
@@ -1074,7 +1111,7 @@ bool PackageManagerCore::fetchRemotePackagesTree()
d->setStatus(Running);
if (isUninstaller()) {
- d->setStatus(Failure, tr("Application running in Uninstaller mode!"));
+ d->setStatus(Failure, tr("Application running in Uninstaller mode."));
return false;
}
@@ -1110,7 +1147,7 @@ bool PackageManagerCore::fetchRemotePackagesTree()
}
const LocalPackage localPackage = installedPackages.value(name);
- const QString updateVersion = update->data(scRemoteVersion).toString();
+ const QString updateVersion = update->data(scVersion).toString();
if (KDUpdater::compareVersion(updateVersion, localPackage.version) <= 0)
break; // remote version equals or is less than the installed maintenance tool
@@ -1617,8 +1654,8 @@ ComponentModel *PackageManagerCore::defaultComponentModel() const
d->m_defaultModel = componentModel(const_cast<PackageManagerCore*> (this),
QLatin1String("AllComponentsModel"));
}
- connect(this, SIGNAL(finishAllComponentsReset(QList<QInstaller::Component*>)), d->m_defaultModel,
- SLOT(setRootComponents(QList<QInstaller::Component*>)));
+ connect(this, &PackageManagerCore::finishAllComponentsReset, d->m_defaultModel,
+ &ComponentModel::setRootComponents);
return d->m_defaultModel;
}
@@ -1632,8 +1669,8 @@ ComponentModel *PackageManagerCore::updaterComponentModel() const
d->m_updaterModel = componentModel(const_cast<PackageManagerCore*> (this),
QLatin1String("UpdaterComponentsModel"));
}
- connect(this, SIGNAL(finishUpdaterComponentsReset(QList<QInstaller::Component*>)), d->m_updaterModel,
- SLOT(setRootComponents(QList<QInstaller::Component*>)));
+ connect(this, &PackageManagerCore::finishUpdaterComponentsReset, d->m_updaterModel,
+ &ComponentModel::setRootComponents);
return d->m_updaterModel;
}
@@ -1701,20 +1738,21 @@ bool PackageManagerCore::killProcess(const QString &absoluteFilePath) const
processPath = QDir::cleanPath(processPath.replace(QLatin1Char('\\'), QLatin1Char('/')));
if (processPath == normalizedPath) {
- qDebug() << QString::fromLatin1("try to kill process: %1(%2)").arg(process.name).arg(process.id);
+ qDebug().nospace() << "try to kill process " << process.name << " (" << process.id << ")";
//to keep the ui responsible use QtConcurrent::run
QFutureWatcher<bool> futureWatcher;
const QFuture<bool> future = QtConcurrent::run(KDUpdater::killProcess, process, 30000);
QEventLoop loop;
- loop.connect(&futureWatcher, SIGNAL(finished()), SLOT(quit()), Qt::QueuedConnection);
+ connect(&futureWatcher, &QFutureWatcher<bool>::finished,
+ &loop, &QEventLoop::quit, Qt::QueuedConnection);
futureWatcher.setFuture(future);
if (!future.isFinished())
loop.exec();
- qDebug() << QString::fromLatin1("\"%1\" killed!").arg(process.name);
+ qDebug() << process.name << "killed!";
return future.result();
}
}
@@ -1865,14 +1903,7 @@ QString PackageManagerCore::environmentVariable(const QString &name) const
*/
bool PackageManagerCore::operationExists(const QString &name)
{
- static QSet<QString> existingOperations;
- if (existingOperations.contains(name))
- return true;
- QScopedPointer<Operation> op(KDUpdater::UpdateOperationFactory::instance().create(name));
- if (!op.data())
- return false;
- existingOperations.insert(name);
- return true;
+ return KDUpdater::UpdateOperationFactory::instance().containsProduct(name);
}
/*!
@@ -1884,7 +1915,7 @@ bool PackageManagerCore::operationExists(const QString &name)
*/
bool PackageManagerCore::performOperation(const QString &name, const QStringList &arguments)
{
- QScopedPointer<Operation> op(KDUpdater::UpdateOperationFactory::instance().create(name));
+ QScopedPointer<Operation> op(KDUpdater::UpdateOperationFactory::instance().create(name, this));
if (!op.data())
return false;
@@ -2261,6 +2292,14 @@ bool PackageManagerCore::isPackageManager() const
}
/*!
+ Returns \c true if it is a package manager or an updater.
+*/
+bool PackageManagerCore::isMaintainer() const
+{
+ return isPackageManager() || isUpdater();
+}
+
+/*!
Runs the installer. Returns \c true on success, \c false otherwise.
\sa {installer::runInstaller}{installer.runInstaller}
@@ -2309,7 +2348,7 @@ bool PackageManagerCore::run()
return d->runInstaller();
else if (isUninstaller())
return d->runUninstaller();
- else if (isPackageManager() || isUpdater())
+ else if (isMaintainer())
return d->runPackageUpdater();
return false;
}
@@ -2328,7 +2367,7 @@ bool PackageManagerCore::updateComponentData(struct Data &data, Component *compo
// check if we already added the component to the available components list
const QString name = data.package->data(scName).toString();
if (data.components->contains(name)) {
- qCritical("Could not register component! Component with identifier %s already registered.",
+ qCritical("Cannot register component! Component with identifier %s already registered.",
qPrintable(name));
return false;
}
@@ -2529,7 +2568,7 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
continue; // Update for not installed package found, skip it.
const LocalPackage &localPackage = locals.value(name);
- const QString updateVersion = update->data(scRemoteVersion).toString();
+ const QString updateVersion = update->data(scVersion).toString();
if (KDUpdater::compareVersion(updateVersion, localPackage.version) <= 0)
continue;
@@ -2650,7 +2689,7 @@ void PackageManagerCore::updateDisplayVersions(const QString &displayKey)
}
visited.clear();
const QString displayVersionRemote = findDisplayVersion(key, componentsHash,
- scRemoteVersion, visited);
+ scVersion, visited);
if (displayVersionRemote.isEmpty())
componentsHash.value(key)->setValue(displayKey, tr("invalid"));
else
@@ -2698,3 +2737,13 @@ ComponentModel *PackageManagerCore::componentModel(PackageManagerCore *core, con
return model;
}
+
+QStringList PackageManagerCore::filesForDelayedDeletion() const
+{
+ return d->m_filesForDelayedDeletion;
+}
+
+void PackageManagerCore::addFilesForDelayedDeletion(const QStringList &files)
+{
+ d->m_filesForDelayedDeletion.append(files);
+}
diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h
index c9fe6e102..f00f33e72 100644
--- a/src/libs/installer/packagemanagercore.h
+++ b/src/libs/installer/packagemanagercore.h
@@ -189,6 +189,7 @@ public:
Q_INVOKABLE bool isFileExtensionRegistered(const QString &extension) const;
Q_INVOKABLE bool fileExists(const QString &filePath) const;
+ Q_INVOKABLE QString readFile(const QString &filePath, const QString &codecName) const;
public:
ScriptEngine *componentScriptEngine() const;
@@ -229,6 +230,8 @@ public:
Q_INVOKABLE void setPackageManager();
Q_INVOKABLE bool isPackageManager() const;
+ bool isMaintainer() const;
+
bool isVerbose() const;
void setVerbose(bool on);
@@ -259,6 +262,9 @@ public:
void setNeedsHardRestart(bool needsHardRestart = true);
bool finishedWithSuccess() const;
+ QStringList filesForDelayedDeletion() const;
+ void addFilesForDelayedDeletion(const QStringList &files);
+
public Q_SLOTS:
bool runInstaller();
bool runUninstaller();
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 18f72e03d..642d7f5ae 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -54,13 +54,13 @@
#include "componentchecker.h"
#include "globals.h"
-#include "kdselfrestarter.h"
-#include "kdupdaterfiledownloaderfactory.h"
-#include "kdupdaterupdatesourcesinfo.h"
-#include "kdupdaterupdateoperationfactory.h"
+#include "selfrestarter.h"
+#include "filedownloaderfactory.h"
+#include "updateoperationfactory.h"
#include <productkeycheck.h>
+#include <QSettings>
#include <QtConcurrentRun>
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
@@ -97,9 +97,9 @@ public:
{
if (!m_operation)
return;
- qDebug() << QString::fromLatin1("%1 %2 operation: %3").arg(state, m_operation->value(
+ qDebug().noquote() << QString::fromLatin1("%1 %2 operation: %3").arg(state, m_operation->value(
QLatin1String("component")).toString(), m_operation->name());
- qDebug() << QString::fromLatin1("\t- arguments: %1").arg(m_operation->arguments()
+ qDebug().noquote() << QString::fromLatin1("\t- arguments: %1").arg(m_operation->arguments()
.join(QLatin1String(", ")));
}
~OperationTracer() {
@@ -176,7 +176,7 @@ static void deferredRename(const QString &oldName, const QString &newName, bool
#else
QFile::remove(newName);
QFile::rename(oldName, newName);
- KDSelfRestarter::setRestartOnQuit(restart);
+ SelfRestarter::setRestartOnQuit(restart);
#endif
}
@@ -185,7 +185,7 @@ static void deferredRename(const QString &oldName, const QString &newName, bool
PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core)
: m_updateFinder(0)
- , m_updaterApplication(new DummyConfigurationInterface)
+ , m_localPackageHub(std::make_shared<LocalPackageHub>())
, m_core(core)
, m_updates(false)
, m_repoFetched(false)
@@ -206,7 +206,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core)
PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, qint64 magicInstallerMaker,
const QList<OperationBlob> &performedOperations)
: m_updateFinder(0)
- , m_updaterApplication(new DummyConfigurationInterface)
+ , m_localPackageHub(std::make_shared<LocalPackageHub>())
, m_status(PackageManagerCore::Unfinished)
, m_needsHardRestart(false)
, m_testChecksum(false)
@@ -232,24 +232,27 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, q
{
foreach (const OperationBlob &operation, performedOperations) {
QScopedPointer<QInstaller::Operation> op(KDUpdater::UpdateOperationFactory::instance()
- .create(operation.name));
+ .create(operation.name, core));
if (op.isNull()) {
- qWarning() << QString::fromLatin1("Failed to load unknown operation %1")
- .arg(operation.name);
+ qWarning() << "Failed to load unknown operation" << operation.name;
continue;
}
if (!op->fromXml(operation.xml)) {
- qWarning() << "Failed to load XML for operation:" << operation.name;
+ qWarning() << "Failed to load XML for operation" << operation.name;
continue;
}
m_performedOperationsOld.append(op.take());
}
- connect(this, SIGNAL(installationStarted()), m_core, SIGNAL(installationStarted()));
- connect(this, SIGNAL(installationFinished()), m_core, SIGNAL(installationFinished()));
- connect(this, SIGNAL(uninstallationStarted()), m_core, SIGNAL(uninstallationStarted()));
- connect(this, SIGNAL(uninstallationFinished()), m_core, SIGNAL(uninstallationFinished()));
+ connect(this, &PackageManagerCorePrivate::installationStarted,
+ m_core, &PackageManagerCore::installationStarted);
+ connect(this, &PackageManagerCorePrivate::installationFinished,
+ m_core, &PackageManagerCore::installationFinished);
+ connect(this, &PackageManagerCorePrivate::uninstallationStarted,
+ m_core, &PackageManagerCore::uninstallationStarted);
+ connect(this, &PackageManagerCorePrivate::uninstallationFinished,
+ m_core, &PackageManagerCore::uninstallationFinished);
}
PackageManagerCorePrivate::~PackageManagerCorePrivate()
@@ -311,7 +314,8 @@ bool PackageManagerCorePrivate::performOperationThreaded(Operation *operation, O
const QFuture<bool> future = QtConcurrent::run(runOperation, operation, type);
QEventLoop loop;
- loop.connect(&futureWatcher, SIGNAL(finished()), SLOT(quit()), Qt::QueuedConnection);
+ QObject::connect(&futureWatcher, &decltype(futureWatcher)::finished, &loop, &QEventLoop::quit,
+ Qt::QueuedConnection);
futureWatcher.setFuture(future);
if (!future.isFinished())
@@ -343,7 +347,7 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
return false;
// append all components to their respective parents
QHash<QString, Component*>::const_iterator it;
- for (it = components.begin(); it != components.end(); ++it) {
+ for (it = components.constBegin(); it != components.constEnd(); ++it) {
QString id = it.key();
QInstaller::Component *component = it.value();
while (!id.isEmpty() && component->parentComponent() == 0) {
@@ -395,7 +399,7 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
foreach (QInstaller::Component *component, components) {
const QStringList warnings = ComponentChecker::checkComponent(component);
foreach (const QString &warning, warnings)
- qCWarning(lcComponentChecker) << warning;
+ qCWarning(lcComponentChecker).noquote() << warning;
}
} catch (const Error &error) {
clearAllComponentLists();
@@ -413,7 +417,7 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
void PackageManagerCorePrivate::cleanUpComponentEnvironment()
{
// clean up registered (downloaded) data
- if (m_core->isUpdater() || m_core->isPackageManager())
+ if (m_core->isMaintainer())
BinaryFormatEngineHandler::instance()->clear();
// there could be still some references to already deleted components,
@@ -548,45 +552,37 @@ void PackageManagerCorePrivate::initialize(const QHash<QString, QString> &params
readMaintenanceConfigFiles(QCoreApplication::applicationDirPath());
#endif
}
+ processFilesForDelayedDeletion();
+ m_data.setDynamicPredefinedVariables();
+
+ disconnect(this, &PackageManagerCorePrivate::installationStarted,
+ ProgressCoordinator::instance(), &ProgressCoordinator::reset);
+ connect(this, &PackageManagerCorePrivate::installationStarted,
+ ProgressCoordinator::instance(), &ProgressCoordinator::reset);
+ disconnect(this, &PackageManagerCorePrivate::uninstallationStarted,
+ ProgressCoordinator::instance(), &ProgressCoordinator::reset);
+ connect(this, &PackageManagerCorePrivate::uninstallationStarted,
+ ProgressCoordinator::instance(), &ProgressCoordinator::reset);
- foreach (Operation *currentOperation, m_performedOperationsOld)
- currentOperation->setValue(QLatin1String("installer"), QVariant::fromValue(m_core));
-
- disconnect(this, SIGNAL(installationStarted()), ProgressCoordinator::instance(), SLOT(reset()));
- connect(this, SIGNAL(installationStarted()), ProgressCoordinator::instance(), SLOT(reset()));
- disconnect(this, SIGNAL(uninstallationStarted()), ProgressCoordinator::instance(), SLOT(reset()));
- connect(this, SIGNAL(uninstallationStarted()), ProgressCoordinator::instance(), SLOT(reset()));
-
- m_updaterApplication.updateSourcesInfo()->setFileName(QString());
- KDUpdater::PackagesInfo &packagesInfo = *m_updaterApplication.packagesInfo();
- packagesInfo.setFileName(componentsXmlPath());
+ if (!isInstaller())
+ m_localPackageHub->setFileName(componentsXmlPath());
- // Note: force overwriting the application name and version in case we run as installer. Both will be
- // set to wrong initial values if we install into an already existing installation. This can happen
- // if the components.xml path has not been changed, but name or version of the new installer.
- if (isInstaller() || packagesInfo.applicationName().isEmpty()) {
+ if (isInstaller() || m_localPackageHub->applicationName().isEmpty()) {
// TODO: this seems to be wrong, we should ask for ProductName defaulting to applicationName...
- packagesInfo.setApplicationName(m_data.settings().applicationName());
+ m_localPackageHub->setApplicationName(m_data.settings().applicationName());
}
- if (isInstaller() || packagesInfo.applicationVersion().isEmpty()) {
- packagesInfo.setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
- }
+ if (isInstaller() || m_localPackageHub->applicationVersion().isEmpty())
+ m_localPackageHub->setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
- if (isInstaller()) {
- // TODO: this seems to be wrong, we should ask for ProductName defaulting to applicationName...
- m_updaterApplication.addUpdateSource(m_data.settings().applicationName(),
- m_data.settings().applicationName(), QString(), QUrl(QLatin1String("resource://metadata/")), 0);
- m_updaterApplication.updateSourcesInfo()->setModified(false);
- }
+ if (isInstaller())
+ m_packageSources.insert(PackageSource(QUrl(QLatin1String("resource://metadata/")), 0));
m_metadataJob.disconnect();
m_metadataJob.setAutoDelete(false);
m_metadataJob.setPackageManagerCore(m_core);
- connect(&m_metadataJob, SIGNAL(infoMessage(KDJob*, QString)), this,
- SLOT(infoMessage(KDJob*, QString)));
- connect(&m_metadataJob, SIGNAL(progress(KDJob *, quint64, quint64)), this,
- SLOT(infoProgress(KDJob *, quint64, quint64)));
+ connect(&m_metadataJob, &Job::infoMessage, this, &PackageManagerCorePrivate::infoMessage);
+ connect(&m_metadataJob, &Job::progress, this, &PackageManagerCorePrivate::infoProgress);
KDUpdater::FileDownloaderFactory::instance().setProxyFactory(m_core->proxyFactory());
}
@@ -656,7 +652,7 @@ QByteArray PackageManagerCorePrivate::replaceVariables(const QByteArray &ba) con
*/
Operation *PackageManagerCorePrivate::createOwnedOperation(const QString &type)
{
- m_ownedOperations.append(KDUpdater::UpdateOperationFactory::instance().create(type));
+ m_ownedOperations.append(KDUpdater::UpdateOperationFactory::instance().create(type, m_core));
return m_ownedOperations.last();
}
@@ -737,24 +733,30 @@ void PackageManagerCorePrivate::writeMaintenanceConfigFiles()
// write current state (variables) to the maintenance tool ini file
const QString iniPath = targetDir() + QLatin1Char('/') + m_data.settings().maintenanceToolIniFile();
- QVariantHash variables;
+ QVariantHash variables; // Do not change to QVariantMap! Breaks existing .ini files,
+ // cause the variant types do not match while restoring the variables from the file.
QSettingsWrapper cfg(iniPath, QSettingsWrapper::IniFormat);
foreach (const QString &key, m_data.keys()) {
- if (key != scRunProgramDescription && key != scRunProgram && key != scRunProgramArguments)
- variables.insert(key, m_data.value(key));
+ if (key == scRunProgramDescription || key == scRunProgram || key == scRunProgramArguments)
+ continue;
+ QVariant value = m_data.value(key);
+ if (value.canConvert(QVariant::String))
+ value = replacePath(value.toString(), targetDir(), QLatin1String(scRelocatable));
+ variables.insert(key, value);
}
cfg.setValue(QLatin1String("Variables"), variables);
- QVariantList repos;
+ QVariantList repos; // Do not change either!
foreach (const Repository &repo, m_data.settings().defaultRepositories())
repos.append(QVariant().fromValue(repo));
cfg.setValue(QLatin1String("DefaultRepositories"), repos);
- cfg.sync();
+ cfg.setValue(QLatin1String("FilesForDelayedDeletion"), m_filesForDelayedDeletion);
+ cfg.sync();
if (cfg.status() != QSettingsWrapper::NoError) {
const QString reason = cfg.status() == QSettingsWrapper::AccessError ? tr("Access error")
: tr("Format error");
- throw Error(tr("Could not write installer configuration to %1: %2").arg(iniPath, reason));
+ throw Error(tr("Cannot write installer configuration to %1: %2").arg(iniPath, reason));
}
QFile file(targetDir() + QLatin1Char('/') + QLatin1String("network.xml"));
@@ -799,17 +801,22 @@ void PackageManagerCorePrivate::readMaintenanceConfigFiles(const QString &target
{
QSettingsWrapper cfg(targetDir + QLatin1Char('/') + m_data.settings().maintenanceToolIniFile(),
QSettingsWrapper::IniFormat);
- const QVariantHash vars = cfg.value(QLatin1String("Variables")).toHash();
- for (QHash<QString, QVariant>::ConstIterator it = vars.constBegin(); it != vars.constEnd(); ++it)
- m_data.setValue(it.key(), it.value().toString());
-
+ const QVariantHash v = cfg.value(QLatin1String("Variables")).toHash(); // Do not change to
+ // QVariantMap! Breaks reading from existing .ini files, cause the variant types do not match.
+ for (QVariantHash::const_iterator it = v.constBegin(); it != v.constEnd(); ++it) {
+ m_data.setValue(it.key(), replacePath(it.value().toString(), QLatin1String(scRelocatable),
+ targetDir));
+ }
QSet<Repository> repos;
- const QVariantList variants = cfg.value(QLatin1String("DefaultRepositories")).toList();
+ const QVariantList variants = cfg.value(QLatin1String("DefaultRepositories"))
+ .toList(); // Do not change either!
foreach (const QVariant &variant, variants)
repos.insert(variant.value<Repository>());
if (!repos.isEmpty())
m_data.settings().setDefaultRepositories(repos);
+ m_filesForDelayedDeletion = cfg.value(QLatin1String("FilesForDelayedDeletion")).toStringList();
+
QFile file(targetDir + QLatin1String("/network.xml"));
if (!file.open(QIODevice::ReadOnly))
return;
@@ -1008,13 +1015,13 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q
{
QFile dummy(resourcePath.filePath(QLatin1String("installer.dat")));
if (dummy.exists() && !dummy.remove()) {
- throw Error(tr("Could not remove data file '%1': %2").arg(dummy.fileName(),
+ throw Error(tr("Cannot remove data file \"%1\": %2").arg(dummy.fileName(),
dummy.errorString()));
}
}
if (!dataOut.rename(resourcePath.filePath(QLatin1String("installer.dat")))) {
- throw Error(tr("Could not write maintenance tool data to %1: %2").arg(out.fileName(),
+ throw Error(tr("Cannot write maintenance tool data to %1: %2").arg(out.fileName(),
out.errorString()));
}
dataOut.setAutoRemove(false);
@@ -1033,13 +1040,13 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q
{
QFile dummy(maintenanceToolRenamedName);
if (dummy.exists() && !dummy.remove()) {
- throw Error(tr("Could not remove data file '%1': %2").arg(dummy.fileName(),
+ throw Error(tr("Cannot remove data file \"%1\": %2").arg(dummy.fileName(),
dummy.errorString()));
}
}
if (!out.copy(maintenanceToolRenamedName)) {
- throw Error(tr("Could not write maintenance tool to %1: %2").arg(maintenanceToolRenamedName,
+ throw Error(tr("Cannot write maintenance tool to \"%1\": %2").arg(maintenanceToolRenamedName,
out.errorString()));
}
@@ -1071,8 +1078,7 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinaryData(QFileDevice *outp
file.remove(); // clear all possible leftovers
m_core->setValue(QString::fromLatin1("DefaultResourceReplacement"), QString());
} else {
- qWarning() << QString::fromLatin1("Could not replace default resource with '%1'.")
- .arg(newDefaultResource);
+ qWarning() << "Cannot replace default resource with" << QDir::toNativeSeparators(newDefaultResource);
}
}
@@ -1085,9 +1091,6 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinaryData(QFileDevice *outp
const qint64 operationsStart = output->pos();
QInstaller::appendInt64(output, performedOperations.count());
foreach (Operation *operation, performedOperations) {
- // the installer can't be put into XML, remove it first
- operation->clearValue(QLatin1String("installer"));
-
QInstaller::appendString(output, operation->name());
QInstaller::appendString(output, operation->toXml().toString());
@@ -1263,17 +1266,17 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
if (!replacementBinary.remove()) {
// Is there anything more sensible we can do with this error? I think not. It's not serious
// enough for throwing / aborting the process.
- qDebug() << QString::fromLatin1("Could not remove installer base binary '%1' after updating "
- "the maintenance tool: %2").arg(installerBaseBinary, replacementBinary.errorString());
+ qDebug() << "Cannot remove installer base binary" << installerBaseBinary
+ << "after updating the maintenance tool:" << replacementBinary.errorString();
} else {
- qDebug() << QString::fromLatin1("Removed installer base binary '%1' after updating the "
- "maintenance tool.").arg(installerBaseBinary);
+ qDebug() << "Removed installer base binary" << installerBaseBinary
+ << "after updating the maintenance tool.";
}
m_installerBaseBinaryUnreplaced.clear();
} else if (!installerBaseBinary.isEmpty() && !QFileInfo(installerBaseBinary).exists()) {
- qWarning() << QString::fromLatin1("The current maintenance tool could not be "
- "updated. '%1' does not exist. Please fix the 'setInstallerBaseBinary(<temp_installer_base_"
- "binary_path>)' call in your script.").arg(installerBaseBinary);
+ qWarning() << "The current maintenance tool could not be updated." << installerBaseBinary
+ << "does not exist. Please fix the \"setInstallerBaseBinary(<temp_installer_base_"
+ "binary_path>)\" call in your script.";
}
QFile input;
@@ -1283,9 +1286,9 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
try {
if (isInstaller()) {
if (QFile::exists(dataFile)) {
- qWarning() << QString::fromLatin1("Found binary data file '%1' but "
+ qWarning() << "Found binary data file" << dataFile << "but "
"deliberately not used. Running as installer requires to read the "
- "resources from the application binary.").arg(dataFile);
+ "resources from the application binary.";
}
throw Error();
}
@@ -1334,12 +1337,12 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
QFile dummy(dataFile + QLatin1String(".new"));
if (dummy.exists() && !dummy.remove()) {
- throw Error(tr("Could not remove data file '%1': %2").arg(dummy.fileName(),
+ throw Error(tr("Cannot remove data file \"%1\": %2").arg(dummy.fileName(),
dummy.errorString()));
}
if (!file.rename(dataFile + QLatin1String(".new"))) {
- throw Error(tr("Could not write maintenance tool binary data to %1: %2")
+ throw Error(tr("Cannot write maintenance tool binary data to %1: %2")
.arg(file.fileName(), file.errorString()));
}
file.setAutoRemove(false);
@@ -1399,7 +1402,7 @@ QString PackageManagerCorePrivate::registerPath()
}
QString path = QLatin1String("HKEY_CURRENT_USER");
- if (m_data.value(QLatin1String("AllUsers"), scFalse).toString() == scTrue)
+ if (m_data.value(scAllUsers, scFalse).toString() == scTrue)
path = QLatin1String("HKEY_LOCAL_MACHINE");
return path + QLatin1String("\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\")
@@ -1491,14 +1494,13 @@ bool PackageManagerCorePrivate::runInstaller()
componentsInstallPartProgressSize = double(1);
// Force an update on the components xml as the install dir might have changed.
- KDUpdater::PackagesInfo &info = *m_updaterApplication.packagesInfo();
- info.setFileName(componentsXmlPath());
+ m_localPackageHub->setFileName(componentsXmlPath());
// Clear the packages as we might install into an already existing installation folder.
- info.clearPackageInfoList();
+ m_localPackageHub->clearPackageInfos();
// also update the application name, might be set from a script as well
- info.setApplicationName(m_data.value(QLatin1String("ProductName"),
+ m_localPackageHub->setApplicationName(m_data.value(QLatin1String("ProductName"),
m_data.settings().applicationName()).toString());
- info.setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
+ m_localPackageHub->setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
const int progressOperationCount = countProgressOperations(componentsToInstall)
// add one more operation as we support progress
@@ -1526,7 +1528,6 @@ bool PackageManagerCorePrivate::runInstaller()
binaryFile = resourcePath.filePath(QLatin1String("installer.dat"));
#endif
createRepo->setValue(QLatin1String("uninstall-only"), true);
- createRepo->setValue(QLatin1String("installer"), QVariant::fromValue(m_core));
createRepo->setArguments(QStringList() << binaryFile << target
+ QLatin1String("/repository"));
@@ -1867,7 +1868,7 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr
bool ignoreError = false;
bool ok = performOperationThreaded(operation);
while (!ok && !ignoreError && m_core->status() != PackageManagerCore::Canceled) {
- qDebug() << QString::fromLatin1("Operation '%1' with arguments: '%2' failed: %3")
+ qDebug() << QString::fromLatin1("Operation \"%1\" with arguments \"%2\" failed: %3")
.arg(operation->name(), operation->arguments().join(QLatin1String("; ")),
operation->errorString());
const QMessageBox::StandardButton button =
@@ -1905,7 +1906,7 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr
if (!component->stopProcessForUpdateRequests().isEmpty()) {
Operation *stopProcessForUpdatesOp = KDUpdater::UpdateOperationFactory::instance()
- .create(QLatin1String("FakeStopProcessForUpdate"));
+ .create(QLatin1String("FakeStopProcessForUpdate"), m_core);
const QStringList arguments(component->stopProcessForUpdateRequests().join(QLatin1String(",")));
stopProcessForUpdatesOp->setArguments(arguments);
addPerformed(stopProcessForUpdatesOp);
@@ -1913,12 +1914,18 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr
}
// now mark the component as installed
- KDUpdater::PackagesInfo &packages = *m_updaterApplication.packagesInfo();
- packages.installPackage(component->name(), component->value(scVersion), component->value(scDisplayName),
- component->value(scDescription), component->dependencies(), component->forcedInstallation(),
- component->isVirtual(), component->value(scUncompressedSize).toULongLong(),
- component->value(scInheritVersion));
- packages.writeToDisk();
+ m_localPackageHub->addPackage(component->name(),
+ component->value(scVersion),
+ component->value(scDisplayName),
+ component->value(scDescription),
+ component->dependencies(),
+ component->autoDependencies(),
+ component->forcedInstallation(),
+ component->isVirtual(),
+ component->value(scUncompressedSize).toULongLong(),
+ component->value(scInheritVersion),
+ component->isCheckable());
+ m_localPackageHub->writeToDisk();
component->setInstalled();
component->markAsPerformedInstallation();
@@ -2039,7 +2046,6 @@ void PackageManagerCorePrivate::unregisterMaintenanceTool()
void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOperations, double progressSize,
bool adminRightsGained, bool deleteOperation)
{
- KDUpdater::PackagesInfo &packages = *m_updaterApplication.packagesInfo();
try {
foreach (Operation *undoOperation, undoOperations) {
if (statusCanceledOrFailed())
@@ -2075,7 +2081,7 @@ void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOpera
component = componentsToReplace().value(componentName).second;
if (component) {
component->setUninstalled();
- packages.removePackage(component->name());
+ m_localPackageHub->removePackage(component->name());
}
}
@@ -2086,13 +2092,13 @@ void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOpera
delete undoOperation;
}
} catch (const Error &error) {
- packages.writeToDisk();
+ m_localPackageHub->writeToDisk();
throw Error(error.message());
} catch (...) {
- packages.writeToDisk();
+ m_localPackageHub->writeToDisk();
throw Error(tr("Unknown error"));
}
- packages.writeToDisk();
+ m_localPackageHub->writeToDisk();
}
PackagesList PackageManagerCorePrivate::remotePackages()
@@ -2103,12 +2109,14 @@ PackagesList PackageManagerCorePrivate::remotePackages()
m_updates = false;
delete m_updateFinder;
- m_updateFinder = new KDUpdater::UpdateFinder(&m_updaterApplication);
+ m_updateFinder = new KDUpdater::UpdateFinder;
m_updateFinder->setAutoDelete(false);
+ m_updateFinder->setPackageSources(m_packageSources);
+ m_updateFinder->setLocalPackageHub(m_localPackageHub);
m_updateFinder->run();
if (m_updateFinder->updates().isEmpty()) {
- setStatus(PackageManagerCore::Failure, tr("Could not retrieve remote tree: %1.")
+ setStatus(PackageManagerCore::Failure, tr("Cannot retrieve remote tree %1.")
.arg(m_updateFinder->errorString()));
return PackagesList();
}
@@ -2124,27 +2132,32 @@ PackagesList PackageManagerCorePrivate::remotePackages()
*/
LocalPackagesHash PackageManagerCorePrivate::localInstalledPackages()
{
+ if (isInstaller())
+ return LocalPackagesHash();
+
LocalPackagesHash installedPackages;
+ if (m_localPackageHub->error() != LocalPackageHub::NoError) {
+ if (m_localPackageHub->fileName().isEmpty())
+ m_localPackageHub->setFileName(componentsXmlPath());
+ else
+ m_localPackageHub->refresh();
- if (!isInstaller()) {
- KDUpdater::PackagesInfo &packagesInfo = *m_updaterApplication.packagesInfo();
- if (!packagesInfo.isValid()) {
- packagesInfo.setFileName(componentsXmlPath());
- if (packagesInfo.applicationName().isEmpty())
- packagesInfo.setApplicationName(m_data.settings().applicationName());
- if (packagesInfo.applicationVersion().isEmpty())
- packagesInfo.setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
- }
+ if (m_localPackageHub->applicationName().isEmpty())
+ m_localPackageHub->setApplicationName(m_data.settings().applicationName());
+ if (m_localPackageHub->applicationVersion().isEmpty())
+ m_localPackageHub->setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
+ }
- if (packagesInfo.error() != KDUpdater::PackagesInfo::NoError)
- setStatus(PackageManagerCore::Failure, tr("Failure to read packages from: %1.").arg(componentsXmlPath()));
+ if (m_localPackageHub->error() != LocalPackageHub::NoError) {
+ setStatus(PackageManagerCore::Failure, tr("Failure to read packages from %1.")
+ .arg(componentsXmlPath()));
+ }
- foreach (const LocalPackage &package, packagesInfo.packageInfos()) {
- if (statusCanceledOrFailed())
- break;
- installedPackages.insert(package.name, package);
- }
- }
+ foreach (const LocalPackage &package, m_localPackageHub->packageInfos()) {
+ if (statusCanceledOrFailed())
+ break;
+ installedPackages.insert(package.name, package);
+ }
return installedPackages;
}
@@ -2162,12 +2175,12 @@ bool PackageManagerCorePrivate::fetchMetaInformationFromRepositories()
m_metadataJob.start();
m_metadataJob.waitForFinished();
} catch (Error &error) {
- setStatus(PackageManagerCore::Failure, tr("Could not retrieve meta information: %1")
+ setStatus(PackageManagerCore::Failure, tr("Cannot retrieve meta information: %1")
.arg(error.message()));
return m_repoFetched;
}
- if (m_metadataJob.error() != KDJob::NoError) {
+ if (m_metadataJob.error() != Job::NoError) {
switch (m_metadataJob.error()) {
case QInstaller::UserIgnoreError:
break; // we can simply ignore this error, the user knows about it
@@ -2192,19 +2205,13 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe
return m_updateSourcesAdded;
}
- // forces an refresh / clear on all update sources
- m_updaterApplication.updateSourcesInfo()->refresh();
- if (isInstaller()) {
- m_updaterApplication.addUpdateSource(m_data.settings().applicationName(),
- m_data.settings().applicationName(), QString(),
- QUrl(QLatin1String("resource://metadata/")), 0);
- m_updaterApplication.updateSourcesInfo()->setModified(false);
- }
+ m_packageSources.clear();
+ if (isInstaller())
+ m_packageSources.insert(PackageSource(QUrl(QLatin1String("resource://metadata/")), 0));
m_updates = false;
m_updateSourcesAdded = false;
- const QString &appName = m_data.settings().applicationName();
foreach (const Metadata &data, metadata) {
if (statusCanceledOrFailed())
return false;
@@ -2219,7 +2226,7 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe
QInstaller::openForRead(&updatesFile);
} catch(const Error &e) {
qDebug() << "Error opening Updates.xml:" << e.message();
- setStatus(PackageManagerCore::Failure, tr("Could not add temporary update source information."));
+ setStatus(PackageManagerCore::Failure, tr("Cannot add temporary update source information."));
return false;
}
@@ -2228,9 +2235,9 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe
QString error;
QDomDocument doc;
if (!doc.setContent(&updatesFile, &error, &line, &column)) {
- qDebug() << QString::fromLatin1("Parse error in file %4: %1 at line %2 col %3").arg(error,
- QString::number(line), QString::number(column), updatesFile.fileName());
- setStatus(PackageManagerCore::Failure, tr("Could not add temporary update source information."));
+ qDebug().nospace() << "Parse error in file" << updatesFile.fileName()
+ << ": " << error << " at line " << line << " col " << column;
+ setStatus(PackageManagerCore::Failure, tr("Cannot add temporary update source information."));
return false;
}
@@ -2238,14 +2245,12 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe
if (!checksum.isNull())
m_core->setTestChecksum(checksum.toElement().text().toLower() == scTrue);
}
- m_updaterApplication.addUpdateSource(appName, appName, QString(),
- QUrl::fromLocalFile(data.directory), 1);
+ m_packageSources.insert(PackageSource(QUrl::fromLocalFile(data.directory), 1));
ProductKeyCheck::instance()->addPackagesFromXml(data.directory + QLatin1String("/Updates.xml"));
}
- m_updaterApplication.updateSourcesInfo()->setModified(false);
- if (m_updaterApplication.updateSourcesInfo()->updateSourceInfoCount() == 0) {
- setStatus(PackageManagerCore::Failure, tr("Could not find any update source information."));
+ if (m_packageSources.count() == 0) {
+ setStatus(PackageManagerCore::Failure, tr("Cannot find any update source information."));
return false;
}
@@ -2297,25 +2302,20 @@ OperationList PackageManagerCorePrivate::sortOperationsBasedOnComponentDependenc
const QString componentName = operation->value(QLatin1String("component")).toString();
if (componentName.isEmpty())
sortedOperations.append(operation);
- else {
- OperationList componentOperationList = componentOperationHash.value(componentName);
- componentOperationList.append(operation);
- componentOperationHash.insert(operation->value(QLatin1String("component")).toString(),
- componentOperationList);
- }
+ else
+ componentOperationHash[componentName].append(operation);
}
- const QString empty;
const QRegExp dash(QLatin1String("-.*"));
Graph<QString> componentGraph; // create the complete component graph
foreach (const Component* node, m_core->components(PackageManagerCore::ComponentType::All)) {
componentGraph.addNode(node->name());
- componentGraph.addEdges(node->name(), node->dependencies().replaceInStrings(dash, empty));
+ componentGraph.addEdges(node->name(), node->dependencies().replaceInStrings(dash, QString()));
}
const QStringList resolvedComponents = componentGraph.sort();
if (componentGraph.hasCycle()) {
- throw Error(tr("Dependency cycle between components detected: '%1' and '%2'.")
+ throw Error(tr("Dependency cycle between components \"%1\" and \"%2\" detected.")
.arg(componentGraph.cycle().first, componentGraph.cycle().second));
}
foreach (const QString &componentName, resolvedComponents)
@@ -2331,4 +2331,20 @@ void PackageManagerCorePrivate::handleMethodInvocationRequest(const QString &inv
QMetaObject::invokeMethod(obj, qPrintable(invokableMethodName));
}
+void PackageManagerCorePrivate::processFilesForDelayedDeletion()
+{
+ if (m_filesForDelayedDeletion.isEmpty())
+ return;
+
+ const QStringList filesForDelayedDeletion = std::move(m_filesForDelayedDeletion);
+ foreach (const QString &i, filesForDelayedDeletion) {
+ QFile file(i); //TODO: this should happen asnyc and report errors, I guess
+ if (file.exists() && !file.remove()) {
+ qWarning("Cannot delete file %s: %s", qPrintable(i),
+ qPrintable(file.errorString()));
+ m_filesForDelayedDeletion << i; // try again next time
+ }
+ }
+}
+
} // namespace QInstaller
diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h
index ca2c43b9a..d78bd3e69 100644
--- a/src/libs/installer/packagemanagercore_p.h
+++ b/src/libs/installer/packagemanagercore_p.h
@@ -38,15 +38,15 @@
#include "packagemanagercore.h"
#include "packagemanagercoredata.h"
#include "packagemanagerproxyfactory.h"
+#include "packagesource.h"
#include "qinstallerglobal.h"
-#include "kdsysinfo.h"
-#include "kdupdaterapplication.h"
-#include "kdupdaterupdatefinder.h"
+#include "sysinfo.h"
+#include "updatefinder.h"
#include <QObject>
-class KDJob;
+class Job;
QT_FORWARD_DECLARE_CLASS(QFile)
QT_FORWARD_DECLARE_CLASS(QFileDevice)
@@ -65,27 +65,6 @@ class InstallerCalculator;
class UninstallerCalculator;
class RemoteFileEngineHandler;
-/*
- The default configuration interface implementation does call QSettings to save files for later deletion,
- though according to QSettings there should nothing be written if QSettings is not setup properly (which
- we do not in our case). Still, caused by a broken QSettings implementation at least on Linux we write an
- empty config file which resulted in QTIFW-196. To workaround the issue we now use this empty dummy class.
-*/
-class DummyConfigurationInterface : public KDUpdater::ConfigurationInterface
-{
-public:
- QVariant value(const QString &key) const
- {
- Q_UNUSED(key)
- return QVariant();
- }
- void setValue(const QString &key, const QVariant &value)
- {
- if (value.isNull())
- qDebug() << "DummyConfigurationInterface called with key:" << key << "and value:" << value;
- }
-};
-
class PackageManagerCorePrivate : public QObject
{
Q_OBJECT
@@ -196,7 +175,9 @@ signals:
public:
UpdateFinder *m_updateFinder;
- Application m_updaterApplication;
+ QSet<PackageSource> m_packageSources;
+ std::shared_ptr<LocalPackageHub> m_localPackageHub;
+ QStringList m_filesForDelayedDeletion;
int m_status;
QString m_error;
@@ -224,10 +205,10 @@ public:
bool m_dependsOnLocalInstallerBinary;
private slots:
- void infoMessage(KDJob *, const QString &message) {
+ void infoMessage(Job *, const QString &message) {
emit m_core->metaJobInfoMessage(message);
}
- void infoProgress(KDJob *, quint64 progress, quint64) {
+ void infoProgress(Job *, quint64 progress, quint64) {
emit m_core->metaJobProgress(progress);
}
@@ -249,6 +230,7 @@ private:
LocalPackagesHash localInstalledPackages();
bool fetchMetaInformationFromRepositories();
bool addUpdateResourcesFromRepositories(bool parseChecksum);
+ void processFilesForDelayedDeletion();
private:
PackageManagerCore *m_core;
diff --git a/src/libs/installer/packagemanagercoredata.cpp b/src/libs/installer/packagemanagercoredata.cpp
index 2241e4bcc..671717d0b 100644
--- a/src/libs/installer/packagemanagercoredata.cpp
+++ b/src/libs/installer/packagemanagercoredata.cpp
@@ -51,27 +51,14 @@ namespace QInstaller
PackageManagerCoreData::PackageManagerCoreData(const QHash<QString, QString> &variables)
{
m_variables = variables;
+ setDynamicPredefinedVariables();
// Set some common variables that may used e.g. as placeholder in some of the settings variables or
// in a script or...
- m_variables.insert(QLatin1String("rootDir"), QDir::rootPath());
- m_variables.insert(QLatin1String("homeDir"), QDir::homePath());
- m_variables.insert(QLatin1String("RootDir"), QDir::rootPath());
- m_variables.insert(QLatin1String("HomeDir"), QDir::homePath());
m_variables.insert(scTargetConfigurationFile, QLatin1String("components.xml"));
m_variables.insert(QLatin1String("InstallerDirPath"), QCoreApplication::applicationDirPath());
m_variables.insert(QLatin1String("InstallerFilePath"), QCoreApplication::applicationFilePath());
- QString dir = QLatin1String("/opt");
-#ifdef Q_OS_WIN
- TCHAR buffer[MAX_PATH + 1] = { 0 };
- SHGetFolderPath(0, CSIDL_PROGRAM_FILES, 0, 0, buffer);
- dir = QString::fromWCharArray(buffer);
-#elif defined (Q_OS_OSX)
- dir = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).value(0);
-#endif
- m_variables.insert(QLatin1String("ApplicationsDir"), dir);
-
#ifdef Q_OS_WIN
m_variables.insert(QLatin1String("os"), QLatin1String("win"));
#elif defined(Q_OS_OSX)
@@ -82,26 +69,6 @@ PackageManagerCoreData::PackageManagerCoreData(const QHash<QString, QString> &va
// TODO: add more platforms as needed...
#endif
-#ifdef Q_OS_WIN
- QSettingsWrapper user(QLatin1String("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\"
- "CurrentVersion\\Explorer\\User Shell Folders"), QSettingsWrapper::NativeFormat);
- QSettingsWrapper system(QLatin1String("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\"
- "CurrentVersion\\Explorer\\Shell Folders"), QSettingsWrapper::NativeFormat);
-
- const QString programs = user.value(QLatin1String("Programs"), QString()).toString();
- const QString allPrograms = system.value(QLatin1String("Common Programs"), QString()).toString();
-
- QString desktop;
- if (m_variables.value(QLatin1String("AllUsers")) == scTrue) {
- desktop = system.value(QLatin1String("Desktop")).toString();
- } else {
- desktop = user.value(QLatin1String("Desktop")).toString();
- }
- m_variables.insert(QLatin1String("DesktopDir"), replaceWindowsEnvironmentVariables(desktop));
- m_variables.insert(QLatin1String("UserStartMenuProgramsPath"), replaceWindowsEnvironmentVariables(programs));
- m_variables.insert(QLatin1String("AllUsersStartMenuProgramsPath"), replaceWindowsEnvironmentVariables(allPrograms));
-#endif
-
m_settings = Settings::fromFileAndPrefix(QLatin1String(":/metadata/installer-config/config.xml"),
QLatin1String(":/metadata/installer-config/"), Settings::RelaxedParseMode);
@@ -131,12 +98,57 @@ void PackageManagerCoreData::clear()
m_settings = Settings();
}
+/*!
+ Set some common variables that may be used e.g. as placeholder in some of the settings
+ variables or in a script or...
+*/
+void PackageManagerCoreData::setDynamicPredefinedVariables()
+{
+ m_variables.insert(QLatin1String("rootDir"), QDir::rootPath());
+ m_variables.insert(QLatin1String("homeDir"), QDir::homePath());
+ m_variables.insert(QLatin1String("RootDir"), QDir::rootPath());
+ m_variables.insert(QLatin1String("HomeDir"), QDir::homePath());
+
+ QString dir = QLatin1String("/opt");
+#ifdef Q_OS_WIN
+ TCHAR buffer[MAX_PATH + 1] = { 0 };
+ SHGetFolderPath(0, CSIDL_PROGRAM_FILES, 0, 0, buffer);
+ dir = QString::fromWCharArray(buffer);
+#elif defined (Q_OS_OSX)
+ dir = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).value(0);
+#endif
+ m_variables.insert(QLatin1String("ApplicationsDir"), dir);
+
+#ifdef Q_OS_WIN
+ QSettingsWrapper user(QLatin1String("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\"
+ "CurrentVersion\\Explorer\\User Shell Folders"), QSettingsWrapper::NativeFormat);
+ QSettingsWrapper system(QLatin1String("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\"
+ "CurrentVersion\\Explorer\\Shell Folders"), QSettingsWrapper::NativeFormat);
+
+ const QString programs = user.value(QLatin1String("Programs"), QString()).toString();
+ const QString allPrograms = system.value(QLatin1String("Common Programs"), QString())
+ .toString();
+
+ QString desktop;
+ if (m_variables.value(QLatin1String("AllUsers")) == scTrue) {
+ desktop = system.value(QLatin1String("Desktop")).toString();
+ } else {
+ desktop = user.value(QLatin1String("Desktop")).toString();
+ }
+ m_variables.insert(QLatin1String("DesktopDir"), replaceWindowsEnvironmentVariables(desktop));
+ m_variables.insert(QLatin1String("UserStartMenuProgramsPath"),
+ replaceWindowsEnvironmentVariables(programs));
+ m_variables.insert(QLatin1String("AllUsersStartMenuProgramsPath"),
+ replaceWindowsEnvironmentVariables(allPrograms));
+#endif
+}
+
Settings &PackageManagerCoreData::settings() const
{
return m_settings;
}
-QList<QString> PackageManagerCoreData::keys() const
+QStringList PackageManagerCoreData::keys() const
{
return m_variables.keys();
}
diff --git a/src/libs/installer/packagemanagercoredata.h b/src/libs/installer/packagemanagercoredata.h
index e83bf921a..f0a15748b 100644
--- a/src/libs/installer/packagemanagercoredata.h
+++ b/src/libs/installer/packagemanagercoredata.h
@@ -45,9 +45,10 @@ public:
explicit PackageManagerCoreData(const QHash<QString, QString> &variables);
void clear();
+ void setDynamicPredefinedVariables();
Settings &settings() const;
- QList<QString> keys() const;
+ QStringList keys() const;
bool contains(const QString &key) const;
bool setValue(const QString &key, const QString &normalizedValue);
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index 9aab80de0..34e1471ae 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -45,7 +45,7 @@
#include "scriptengine.h"
#include "productkeycheck.h"
-#include "kdsysinfo.h"
+#include "sysinfo.h"
#include <QApplication>
@@ -110,7 +110,6 @@ public:
setLayout(new QVBoxLayout);
layout()->addWidget(widget);
layout()->setContentsMargins(0, 0, 0, 0);
- layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));
addPageAndProperties(packageManagerCore()->controlScriptEngine());
addPageAndProperties(packageManagerCore()->componentScriptEngine());
@@ -207,6 +206,7 @@ public:
, m_modified(false)
, m_autoSwitchPage(true)
, m_showSettingsButton(false)
+ , m_silent(false)
{
m_wizardButtonTypes.insert(QWizard::BackButton, QLatin1String("QWizard::BackButton"));
m_wizardButtonTypes.insert(QWizard::NextButton, QLatin1String("QWizard::NextButton"));
@@ -230,6 +230,7 @@ public:
bool m_modified;
bool m_autoSwitchPage;
bool m_showSettingsButton;
+ bool m_silent;
QHash<int, QWizardPage*> m_defaultPages;
QHash<int, QString> m_defaultButtonText;
@@ -315,48 +316,65 @@ PackageManagerGui::PackageManagerGui(PackageManagerCore *core, QWidget *parent)
if (!m_core->settings().wizardStyle().isEmpty())
setWizardStyle(getStyle(m_core->settings().wizardStyle()));
+ // set custom stylesheet
+ const QString styleSheetFile = m_core->settings().styleSheet();
+ if (!styleSheetFile.isEmpty()
+ && QFileInfo::exists(styleSheetFile)) {
+ QFile sheet(styleSheetFile);
+ if (sheet.open(QIODevice::ReadOnly))
+ setStyleSheet(QString::fromLatin1(sheet.readAll()));
+ else
+ qWarning() << "The specified style sheet file can not be opened.";
+ } else {
+ qWarning() << "A style sheet file is specified, but it does not exist.";
+ }
+
setOption(QWizard::NoBackButtonOnStartPage);
setOption(QWizard::NoBackButtonOnLastPage);
- connect(this, SIGNAL(rejected()), m_core, SLOT(setCanceled()));
- connect(this, SIGNAL(interrupted()), m_core, SLOT(interrupt()));
+ connect(this, &QDialog::rejected, m_core, &PackageManagerCore::setCanceled);
+ connect(this, &PackageManagerGui::interrupted, m_core, &PackageManagerCore::interrupt);
// both queued to show the finished page once everything is done
- connect(m_core, SIGNAL(installationFinished()), this, SLOT(showFinishedPage()),
+ connect(m_core, &PackageManagerCore::installationFinished,
+ this, &PackageManagerGui::showFinishedPage,
Qt::QueuedConnection);
- connect(m_core, SIGNAL(uninstallationFinished()), this, SLOT(showFinishedPage()),
+ connect(m_core, &PackageManagerCore::uninstallationFinished,
+ this, &PackageManagerGui::showFinishedPage,
Qt::QueuedConnection);
- connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(currentPageChanged(int)));
- connect(this, SIGNAL(currentIdChanged(int)), m_core, SIGNAL(currentPageChanged(int)));
- connect(button(QWizard::FinishButton), SIGNAL(clicked()), this, SIGNAL(finishButtonClicked()));
- connect(button(QWizard::FinishButton), SIGNAL(clicked()), m_core, SIGNAL(finishButtonClicked()));
+ connect(this, &QWizard::currentIdChanged, this, &PackageManagerGui::currentPageChanged);
+ connect(this, &QWizard::currentIdChanged, m_core, &PackageManagerCore::currentPageChanged);
+ connect(button(QWizard::FinishButton), &QAbstractButton::clicked,
+ this, &PackageManagerGui::finishButtonClicked);
+ connect(button(QWizard::FinishButton), &QAbstractButton::clicked,
+ m_core, &PackageManagerCore::finishButtonClicked);
// make sure the QUiLoader's retranslateUi is executed first, then the script
- connect(this, SIGNAL(languageChanged()), m_core, SLOT(languageChanged()), Qt::QueuedConnection);
- connect(this, SIGNAL(languageChanged()), this, SLOT(onLanguageChanged()), Qt::QueuedConnection);
+ connect(this, &PackageManagerGui::languageChanged,
+ m_core, &PackageManagerCore::languageChanged, Qt::QueuedConnection);
+ connect(this, &PackageManagerGui::languageChanged,
+ this, &PackageManagerGui::onLanguageChanged, Qt::QueuedConnection);
connect(m_core,
- SIGNAL(wizardPageInsertionRequested(QWidget*,QInstaller::PackageManagerCore::WizardPage)),
- this, SLOT(wizardPageInsertionRequested(QWidget*,QInstaller::PackageManagerCore::WizardPage)));
- connect(m_core, SIGNAL(wizardPageRemovalRequested(QWidget*)), this,
- SLOT(wizardPageRemovalRequested(QWidget*)));
- connect(m_core,
- SIGNAL(wizardWidgetInsertionRequested(QWidget*,QInstaller::PackageManagerCore::WizardPage)),
- this, SLOT(wizardWidgetInsertionRequested(QWidget*,QInstaller::PackageManagerCore::WizardPage)));
- connect(m_core, SIGNAL(wizardWidgetRemovalRequested(QWidget*)), this,
- SLOT(wizardWidgetRemovalRequested(QWidget*)));
- connect(m_core, SIGNAL(wizardPageVisibilityChangeRequested(bool,int)), this,
- SLOT(wizardPageVisibilityChangeRequested(bool,int)), Qt::QueuedConnection);
+ &PackageManagerCore::wizardPageInsertionRequested,
+ this, &PackageManagerGui::wizardPageInsertionRequested);
+ connect(m_core, &PackageManagerCore::wizardPageRemovalRequested,
+ this, &PackageManagerGui::wizardPageRemovalRequested);
+ connect(m_core, &PackageManagerCore::wizardWidgetInsertionRequested,
+ this, &PackageManagerGui::wizardWidgetInsertionRequested);
+ connect(m_core, &PackageManagerCore::wizardWidgetRemovalRequested,
+ this, &PackageManagerGui::wizardWidgetRemovalRequested);
+ connect(m_core, &PackageManagerCore::wizardPageVisibilityChangeRequested,
+ this, &PackageManagerGui::wizardPageVisibilityChangeRequested, Qt::QueuedConnection);
- connect(m_core,
- SIGNAL(setValidatorForCustomPageRequested(QInstaller::Component*,QString,QString)), this,
- SLOT(setValidatorForCustomPageRequested(QInstaller::Component*,QString,QString)));
+ connect(m_core, &PackageManagerCore::setValidatorForCustomPageRequested,
+ this, &PackageManagerGui::setValidatorForCustomPageRequested);
- connect(m_core, SIGNAL(setAutomatedPageSwitchEnabled(bool)), this,
- SLOT(setAutomatedPageSwitchEnabled(bool)));
+ connect(m_core, &PackageManagerCore::setAutomatedPageSwitchEnabled,
+ this, &PackageManagerGui::setAutomatedPageSwitchEnabled);
- connect(this, SIGNAL(customButtonClicked(int)), this, SLOT(customButtonClicked(int)));
+ connect(this, &QWizard::customButtonClicked, this, &PackageManagerGui::customButtonClicked);
for (int i = QWizard::BackButton; i < QWizard::CustomButton1; ++i)
d->m_defaultButtonText.insert(i, buttonText(QWizard::WizardButton(i)));
@@ -400,6 +418,23 @@ QWizard::WizardStyle PackageManagerGui::getStyle(const QString &name)
}
/*!
+ Hides the GUI when \a silent is \c true.
+*/
+void PackageManagerGui::setSilent(bool silent)
+{
+ d->m_silent = silent;
+ setVisible(!silent);
+}
+
+/*!
+ Returns the current silent state.
+*/
+bool PackageManagerGui::isSilent() const
+{
+ return d->m_silent;
+}
+
+/*!
Enables automatic page switching when \a request is \c true.
*/
void PackageManagerGui::setAutomatedPageSwitchEnabled(bool request)
@@ -450,7 +485,7 @@ void PackageManagerGui::clickButton(int wb, int delay)
wb = QWizard::CancelButton;
if (QAbstractButton *b = button(static_cast<QWizard::WizardButton>(wb)))
- QTimer::singleShot(delay, b, SLOT(click()));
+ QTimer::singleShot(delay, b, &QAbstractButton::click);
else
qWarning() << "Button with type: " << d->buttonType(wb) << "not found!";
}
@@ -743,13 +778,13 @@ void PackageManagerGui::cancelButtonClicked()
question = tr("Do you want to quit the installer application?");
if (m_core->isUninstaller())
question = tr("Do you want to quit the uninstaller application?");
- if (m_core->isUpdater() || m_core->isPackageManager())
+ if (m_core->isMaintainer())
question = tr("Do you want to quit the maintenance application?");
}
const QMessageBox::StandardButton button =
MessageBoxHandler::question(MessageBoxHandler::currentBestSuitParent(),
- QLatin1String("cancelInstallation"), tr("Question"), question,
+ QLatin1String("cancelInstallation"), tr("%1 Question").arg(m_core->value(scTitle)), question,
QMessageBox::Yes | QMessageBox::No);
if (button == QMessageBox::Yes) {
@@ -1154,7 +1189,7 @@ int PackageManagerPage::nextId() const
core->calculateComponentsToInstall();
foreach (Component* component, core->orderedComponentsToInstall()) {
- if ((core->isPackageManager() || core->isUpdater()) && component->isInstalled())
+ if (core->isMaintainer() && component->isInstalled())
continue; // package manager or updater, hide as long as the component is installed
// The component is about to be installed and provides a license, so the page needs to
@@ -1215,20 +1250,22 @@ IntroductionPage::IntroductionPage(PackageManagerCore *core)
m_packageManager->setObjectName(QLatin1String("PackageManagerRadioButton"));
boxLayout->addWidget(m_packageManager);
m_packageManager->setChecked(core->isPackageManager());
- connect(m_packageManager, SIGNAL(toggled(bool)), this, SLOT(setPackageManager(bool)));
+ connect(m_packageManager, &QAbstractButton::toggled, this, &IntroductionPage::setPackageManager);
m_updateComponents = new QRadioButton(tr("Update components"), this);
m_updateComponents->setObjectName(QLatin1String("UpdaterRadioButton"));
boxLayout->addWidget(m_updateComponents);
m_updateComponents->setChecked(core->isUpdater());
- connect(m_updateComponents, SIGNAL(toggled(bool)), this, SLOT(setUpdater(bool)));
+ connect(m_updateComponents, &QAbstractButton::toggled, this, &IntroductionPage::setUpdater);
m_removeAllComponents = new QRadioButton(tr("Remove all components"), this);
m_removeAllComponents->setObjectName(QLatin1String("UninstallerRadioButton"));
boxLayout->addWidget(m_removeAllComponents);
m_removeAllComponents->setChecked(core->isUninstaller());
- connect(m_removeAllComponents, SIGNAL(toggled(bool)), this, SLOT(setUninstaller(bool)));
- connect(m_removeAllComponents, SIGNAL(toggled(bool)), core, SLOT(setCompleteUninstallation(bool)));
+ connect(m_removeAllComponents, &QAbstractButton::toggled,
+ this, &IntroductionPage::setUninstaller);
+ connect(m_removeAllComponents, &QAbstractButton::toggled,
+ core, &PackageManagerCore::setCompleteUninstallation);
boxLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding));
@@ -1256,16 +1293,18 @@ IntroductionPage::IntroductionPage(PackageManagerCore *core)
core->setCompleteUninstallation(core->isUninstaller());
- connect(core, SIGNAL(metaJobProgress(int)), this, SLOT(onProgressChanged(int)));
- connect(core, SIGNAL(metaJobInfoMessage(QString)), this, SLOT(setMessage(QString)));
- connect(core, SIGNAL(coreNetworkSettingsChanged()), this, SLOT(onCoreNetworkSettingsChanged()));
+ connect(core, &PackageManagerCore::metaJobProgress, this, &IntroductionPage::onProgressChanged);
+ connect(core, &PackageManagerCore::metaJobInfoMessage, this, &IntroductionPage::setMessage);
+ connect(core, &PackageManagerCore::coreNetworkSettingsChanged,
+ this, &IntroductionPage::onCoreNetworkSettingsChanged);
m_updateComponents->setEnabled(ProductKeyCheck::instance()->hasValidKey());
#ifdef Q_OS_WIN
if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) {
m_taskButton = new QWinTaskbarButton(this);
- connect(core, SIGNAL(metaJobProgress(int)), m_taskButton->progress(), SLOT(setValue(int)));
+ connect(core, &PackageManagerCore::metaJobProgress,
+ m_taskButton->progress(), &QWinTaskbarProgress::setValue);
} else {
m_taskButton = 0;
}
@@ -1281,7 +1320,7 @@ int IntroductionPage::nextId() const
if (packageManagerCore()->isUninstaller())
return PackageManagerCore::ReadyForInstallation;
- if (packageManagerCore()->isUpdater() || packageManagerCore()->isPackageManager())
+ if (packageManagerCore()->isMaintainer())
return PackageManagerCore::ComponentSelection;
return PackageManagerPage::nextId();
@@ -1306,8 +1345,7 @@ bool IntroductionPage::validatePage()
}
gui()->setSettingsButtonEnabled(false);
- const bool maintenance = core->isUpdater() || core->isPackageManager();
- if (maintenance) {
+ if (core->isMaintainer()) {
showAll();
setMaintenanceToolsEnabled(false);
} else {
@@ -1368,7 +1406,7 @@ bool IntroductionPage::validatePage()
setComplete(true);
}
- if (maintenance) {
+ if (core->isMaintainer()) {
showMaintenanceTools();
setMaintenanceToolsEnabled(true);
} else {
@@ -1550,7 +1588,7 @@ void IntroductionPage::entering()
m_progressBar->setValue(0);
m_progressBar->setRange(0, 0);
PackageManagerCore *core = packageManagerCore();
- if (core->isUninstaller() || core->isUpdater() || core->isPackageManager()) {
+ if (core->isUninstaller() || core->isMaintainer()) {
showMaintenanceTools();
setMaintenanceToolsEnabled(true);
}
@@ -1641,8 +1679,8 @@ LicenseAgreementPage::LicenseAgreementPage(PackageManagerCore *core)
m_licenseListWidget = new QListWidget(this);
m_licenseListWidget->setObjectName(QLatin1String("LicenseListWidget"));
m_licenseListWidget->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
- connect(m_licenseListWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
- this, SLOT(currentItemChanged(QListWidgetItem*)));
+ connect(m_licenseListWidget, &QListWidget::currentItemChanged,
+ this, &LicenseAgreementPage::currentItemChanged);
m_textBrowser = new QTextBrowser(this);
m_textBrowser->setReadOnly(true);
@@ -1650,7 +1688,7 @@ LicenseAgreementPage::LicenseAgreementPage(PackageManagerCore *core)
m_textBrowser->setOpenExternalLinks(true);
m_textBrowser->setObjectName(QLatin1String("LicenseTextBrowser"));
m_textBrowser->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
- connect(m_textBrowser, SIGNAL(anchorClicked(QUrl)), this, SLOT(openLicenseUrl(QUrl)));
+ connect(m_textBrowser, &QTextBrowser::anchorClicked, this, &LicenseAgreementPage::openLicenseUrl);
QHBoxLayout *licenseBoxLayout = new QHBoxLayout();
licenseBoxLayout->addWidget(m_licenseListWidget);
@@ -1689,8 +1727,8 @@ LicenseAgreementPage::LicenseAgreementPage(PackageManagerCore *core)
gridLayout->addWidget(m_rejectLabel, 1, 1);
layout->addLayout(gridLayout);
- connect(m_acceptRadioButton, SIGNAL(toggled(bool)), this, SIGNAL(completeChanged()));
- connect(m_rejectRadioButton, SIGNAL(toggled(bool)), this, SIGNAL(completeChanged()));
+ connect(m_acceptRadioButton, &QAbstractButton::toggled, this, &QWizardPage::completeChanged);
+ connect(m_rejectRadioButton, &QAbstractButton::toggled, this, &QWizardPage::completeChanged);
m_rejectRadioButton->setChecked(true);
}
@@ -1817,7 +1855,8 @@ public:
layout->addLayout(hlayout, 1);
m_checkDefault = new QPushButton;
- connect(m_checkDefault, SIGNAL(clicked()), this, SLOT(selectDefault()));
+ connect(m_checkDefault, &QAbstractButton::clicked,
+ this, &ComponentSelectionPage::Private::selectDefault);
if (m_core->isInstaller()) {
m_checkDefault->setObjectName(QLatin1String("SelectDefaultComponentsButton"));
m_checkDefault->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+A",
@@ -1835,7 +1874,8 @@ public:
m_checkAll = new QPushButton;
hlayout->addWidget(m_checkAll);
- connect(m_checkAll, SIGNAL(clicked()), this, SLOT(selectAll()));
+ connect(m_checkAll, &QAbstractButton::clicked,
+ this, &ComponentSelectionPage::Private::selectAll);
m_checkAll->setObjectName(QLatin1String("SelectAllComponentsButton"));
m_checkAll->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+S",
"select all components")));
@@ -1843,7 +1883,8 @@ public:
m_uncheckAll = new QPushButton;
hlayout->addWidget(m_uncheckAll);
- connect(m_uncheckAll, SIGNAL(clicked()), this, SLOT(deselectAll()));
+ connect(m_uncheckAll, &QAbstractButton::clicked,
+ this, &ComponentSelectionPage::Private::deselectAll);
m_uncheckAll->setObjectName(QLatin1String("DeselectAllComponentsButton"));
m_uncheckAll->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+D",
"deselect all components")));
@@ -1858,15 +1899,15 @@ public:
{
m_checkDefault->setVisible(m_core->isInstaller() || m_core->isPackageManager());
if (m_treeView->selectionModel()) {
- disconnect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(currentSelectedChanged(QModelIndex)));
+ disconnect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged,
+ this, &ComponentSelectionPage::Private::currentSelectedChanged);
}
m_currentModel = m_core->isUpdater() ? m_updaterModel : m_allModel;
m_treeView->setModel(m_currentModel);
m_treeView->setExpanded(m_currentModel->index(0, 0), true);
- const bool installActionColumnVisible = false;
+ const bool installActionColumnVisible = m_core->settings().installActionColumnVisible();
if (!installActionColumnVisible)
m_treeView->hideColumn(ComponentModelHelper::ActionColumn);
@@ -1900,8 +1941,8 @@ public:
hasChildren = m_currentModel->hasChildren(m_currentModel->index(row, 0));
m_treeView->setRootIsDecorated(hasChildren);
- connect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(currentSelectedChanged(QModelIndex)));
+ connect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged,
+ this, &ComponentSelectionPage::Private::currentSelectedChanged);
m_treeView->setCurrentIndex(m_currentModel->index(0, 0));
}
@@ -2148,19 +2189,24 @@ TargetDirectoryPage::TargetDirectoryPage(PackageManagerCore *core)
QLabel *msgLabel = new QLabel(this);
msgLabel->setWordWrap(true);
msgLabel->setObjectName(QLatin1String("MessageLabel"));
- msgLabel->setText(tr("Please specify the folder where %1 will be installed.").arg(productName()));
+ msgLabel->setText(tr("Please specify the directory where %1 will be installed.").arg(productName()));
layout->addWidget(msgLabel);
QHBoxLayout *hlayout = new QHBoxLayout;
+ m_textChangeTimer.setSingleShot(true);
+ m_textChangeTimer.setInterval(200);
+ connect(&m_textChangeTimer, &QTimer::timeout, this, &QWizardPage::completeChanged);
+
m_lineEdit = new QLineEdit(this);
m_lineEdit->setObjectName(QLatin1String("TargetDirectoryLineEdit"));
- connect(m_lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(completeChanged()));
+ connect(m_lineEdit, &QLineEdit::textChanged,
+ &m_textChangeTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
hlayout->addWidget(m_lineEdit);
QPushButton *browseButton = new QPushButton(this);
browseButton->setObjectName(QLatin1String("BrowseDirectoryButton"));
- connect(browseButton, SIGNAL(clicked()), this, SLOT(dirRequested()));
+ connect(browseButton, &QAbstractButton::clicked, this, &TargetDirectoryPage::dirRequested);
browseButton->setShortcut(QKeySequence(tr("Alt+R", "browse file system to choose a file")));
browseButton->setText(tr("B&rowse..."));
hlayout->addWidget(browseButton);
@@ -2231,6 +2277,11 @@ void TargetDirectoryPage::initializePage()
*/
bool TargetDirectoryPage::validatePage()
{
+ m_textChangeTimer.stop();
+
+ if (!isComplete())
+ return false;
+
if (!isVisible())
return true;
@@ -2256,14 +2307,14 @@ bool TargetDirectoryPage::validatePage()
QFileInfo fi2(targetDir + QDir::separator() + fileName);
if (fi2.exists()) {
- return failWithError(QLatin1String("TargetDirectoryInUse"), tr("The folder you selected already "
+ return failWithError(QLatin1String("TargetDirectoryInUse"), tr("The directory you selected already "
"exists and contains an installation. Choose a different target for installation."));
}
return askQuestion(QLatin1String("OverwriteTargetDirectory"),
- tr("You have selected an existing, non-empty folder for installation.\nNote that it will be "
+ tr("You have selected an existing, non-empty directory for installation.\nNote that it will be "
"completely wiped on uninstallation of this application.\nIt is not advisable to install into "
- "this folder as installation might fail.\nDo you want to continue?"));
+ "this directory as installation might fail.\nDo you want to continue?"));
} else if (fi.isFile() || fi.isSymLink()) {
return failWithError(QLatin1String("WrongTargetDirectory"), tr("You have selected an existing file "
"or symlink, please choose a different target for installation."));
@@ -2318,7 +2369,7 @@ bool TargetDirectoryPage::isComplete() const
QString TargetDirectoryPage::targetDirWarning() const
{
if (targetDir().isEmpty())
- return tr("The installation path cannot be empty, please specify a valid folder.");
+ return tr("The installation path cannot be empty, please specify a valid directory.");
QDir target(targetDir());
if (target.isRelative())
@@ -2381,7 +2432,7 @@ QString TargetDirectoryPage::targetDirWarning() const
}
if (nativeTargetDir.endsWith(QLatin1Char('.')))
- return tr("The installation path must not end with '.', please specify a valid folder.");
+ return tr("The installation path must not end with '.', please specify a valid directory.");
QString ambiguousChars = QLatin1String("[\"~<>|?*!@#$%^&:,; ]"
"|(\\\\CON)(\\\\|$)|(\\\\PRN)(\\\\|$)|(\\\\AUX)(\\\\|$)|(\\\\NUL)(\\\\|$)|(\\\\COM\\d)(\\\\|$)|(\\\\LPT\\d)(\\\\|$)");
@@ -2396,8 +2447,8 @@ QString TargetDirectoryPage::targetDirWarning() const
// check if there are not allowed characters in the target path
QRegularExpressionMatch match = ambCharRegEx.match(nativeTargetDir);
if (match.hasMatch()) {
- return tr("The installation path must not contain '%1', "
- "please specify a valid folder.").arg(match.captured(0));
+ return tr("The installation path must not contain \"%1\", "
+ "please specify a valid directory.").arg(match.captured(0));
}
return QString();
@@ -2442,7 +2493,7 @@ StartMenuDirectoryPage::StartMenuDirectoryPage(PackageManagerCore *core)
setObjectName(QLatin1String("StartMenuDirectoryPage"));
setColoredTitle(tr("Start Menu shortcuts"));
setColoredSubTitle(tr("Select the Start Menu in which you would like to create the program's "
- "shortcuts. You can also enter a name to create a new folder."));
+ "shortcuts. You can also enter a name to create a new directory."));
m_lineEdit = new QLineEdit(this);
m_lineEdit->setText(core->value(scStartMenuDir, productName()));
@@ -2450,7 +2501,7 @@ StartMenuDirectoryPage::StartMenuDirectoryPage(PackageManagerCore *core)
startMenuPath = core->value(QLatin1String("UserStartMenuProgramsPath"));
QStringList dirs = QDir(startMenuPath).entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
- if (core->value(QLatin1String("AllUsers")) == scTrue) {
+ if (core->value(scAllUsers, scFalse) == scTrue) {
startMenuPath = core->value(QLatin1String("AllUsersStartMenuProgramsPath"));
dirs += QDir(startMenuPath).entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
}
@@ -2466,8 +2517,8 @@ StartMenuDirectoryPage::StartMenuDirectoryPage(PackageManagerCore *core)
setLayout(layout);
- connect(m_listWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this,
- SLOT(currentItemChanged(QListWidgetItem*)));
+ connect(m_listWidget, &QListWidget::currentItemChanged, this,
+ &StartMenuDirectoryPage::currentItemChanged);
}
/*!
@@ -2573,7 +2624,7 @@ void ReadyForInstallationPage::entering()
.absolutePath())));
setComplete(true);
return;
- } else if (packageManagerCore()->isPackageManager() || packageManagerCore()->isUpdater()) {
+ } else if (packageManagerCore()->isMaintainer()) {
setButtonText(QWizard::CommitButton, tr("U&pdate"));
setColoredTitle(tr("Ready to Update Packages"));
m_msgLabel->setText(tr("Setup is now ready to begin updating your installation."));
@@ -2599,19 +2650,19 @@ void ReadyForInstallationPage::entering()
// at the moment there is no better way to check this
if (targetVolume.size() == 0 && installVolumeAvailableSize == 0) {
- qDebug() << QString::fromLatin1("Could not determine available space on device. Volume "
- "descriptor: %1, Mount path: %2. Continue silently.").arg(targetVolume
- .volumeDescriptor(), targetVolume.mountPath());
+ qDebug().nospace() << "Cannot determine available space on device. "
+ "Volume descriptor: " << targetVolume.volumeDescriptor()
+ << ", Mount path: " << targetVolume.mountPath() << ". Continue silently.";
return; // TODO: Shouldn't this also disable the "Next" button?
}
const bool tempOnSameVolume = (targetVolume == tempVolume);
if (tempOnSameVolume) {
- qDebug() << "Tmp and install folder are on the same volume. Volume mount point:"
+ qDebug() << "Tmp and install directories are on the same volume. Volume mount point:"
<< targetVolume.mountPath() << "Free space available:"
<< humanReadableSize(installVolumeAvailableSize);
} else {
- qDebug() << "Tmp is on a different volume than the install folder. Tmp volume mount point:"
+ qDebug() << "Tmp is on a different volume than the installation directory. Tmp volume mount point:"
<< tempVolume.mountPath() << "Free space available:"
<< humanReadableSize(tempVolumeAvailableSize) << "Install volume mount point:"
<< targetVolume.mountPath() << "Free space available:"
@@ -2643,7 +2694,7 @@ void ReadyForInstallationPage::entering()
if (tempOnSameVolume && (installVolumeAvailableSize <= (required + tempRequired))) {
m_msgLabel->setText(tr("Not enough disk space to store temporary files and the "
- "installation! Available space: %1, at least required %2.")
+ "installation. %1 are available, while %2 are at least required.")
.arg(humanReadableSize(installVolumeAvailableSize),
humanReadableSize(required + tempRequired)));
setComplete(false);
@@ -2651,16 +2702,16 @@ void ReadyForInstallationPage::entering()
}
if (installVolumeAvailableSize < required) {
- m_msgLabel->setText(tr("Not enough disk space to store all selected components! Available "
- "space: %1, at least required: %2.").arg(humanReadableSize(installVolumeAvailableSize),
+ m_msgLabel->setText(tr("Not enough disk space to store all selected components! %1 are available "
+ "while %2 are at least required.").arg(humanReadableSize(installVolumeAvailableSize),
humanReadableSize(required)));
setComplete(false);
return;
}
if (tempVolumeAvailableSize < tempRequired) {
- m_msgLabel->setText(tr("Not enough disk space to store temporary files! Available space: "
- "%1, at least required: %2.").arg(humanReadableSize(tempVolumeAvailableSize),
+ m_msgLabel->setText(tr("Not enough disk space to store temporary files! %1 are available "
+ "while %2 are at least required.").arg(humanReadableSize(tempVolumeAvailableSize),
humanReadableSize(tempRequired)));
setComplete(false);
return;
@@ -2774,22 +2825,27 @@ PerformInstallationPage::PerformInstallationPage(PackageManagerCore *core)
m_performInstallationForm->setupUi(this);
- connect(ProgressCoordinator::instance(), SIGNAL(detailTextChanged(QString)),
- m_performInstallationForm, SLOT(appendProgressDetails(QString)));
- connect(ProgressCoordinator::instance(), SIGNAL(detailTextResetNeeded()),
- m_performInstallationForm, SLOT(clearDetailsBrowser()));
- connect(m_performInstallationForm, SIGNAL(showDetailsChanged()), this,
- SLOT(toggleDetailsWereChanged()));
+ connect(ProgressCoordinator::instance(), &ProgressCoordinator::detailTextChanged,
+ m_performInstallationForm, &PerformInstallationForm::appendProgressDetails);
+ connect(ProgressCoordinator::instance(), &ProgressCoordinator::detailTextResetNeeded,
+ m_performInstallationForm, &PerformInstallationForm::clearDetailsBrowser);
+ connect(m_performInstallationForm, &PerformInstallationForm::showDetailsChanged,
+ this, &PerformInstallationPage::toggleDetailsWereChanged);
- connect(core, SIGNAL(installationStarted()), this, SLOT(installationStarted()));
- connect(core, SIGNAL(installationFinished()), this, SLOT(installationFinished()));
+ connect(core, &PackageManagerCore::installationStarted,
+ this, &PerformInstallationPage::installationStarted);
+ connect(core, &PackageManagerCore::installationFinished,
+ this, &PerformInstallationPage::installationFinished);
- connect(core, SIGNAL(uninstallationStarted()), this, SLOT(uninstallationStarted()));
- connect(core, SIGNAL(uninstallationFinished()), this, SLOT(uninstallationFinished()));
+ connect(core, &PackageManagerCore::uninstallationStarted,
+ this, &PerformInstallationPage::uninstallationStarted);
+ connect(core, &PackageManagerCore::uninstallationFinished,
+ this, &PerformInstallationPage::uninstallationFinished);
- connect(core, SIGNAL(titleMessageChanged(QString)), this, SLOT(setTitleMessage(QString)));
- connect(this, SIGNAL(setAutomatedPageSwitchEnabled(bool)), core,
- SIGNAL(setAutomatedPageSwitchEnabled(bool)));
+ connect(core, &PackageManagerCore::titleMessageChanged,
+ this, &PerformInstallationPage::setTitleMessage);
+ connect(this, &PerformInstallationPage::setAutomatedPageSwitchEnabled,
+ core, &PackageManagerCore::setAutomatedPageSwitchEnabled);
m_performInstallationForm->setDetailsWidgetVisible(true);
@@ -2828,7 +2884,7 @@ void PerformInstallationPage::entering()
setColoredTitle(tr("Uninstalling %1").arg(productName()));
QTimer::singleShot(30, packageManagerCore(), SLOT(runUninstaller()));
- } else if (packageManagerCore()->isPackageManager() || packageManagerCore()->isUpdater()) {
+ } else if (packageManagerCore()->isMaintainer()) {
setButtonText(QWizard::CommitButton, tr("&Update"));
setColoredTitle(tr("Updating components of %1").arg(productName()));
@@ -2954,11 +3010,11 @@ FinishedPage::FinishedPage(PackageManagerCore *core)
void FinishedPage::entering()
{
if (m_commitButton) {
- disconnect(m_commitButton, SIGNAL(clicked()), this, SLOT(handleFinishClicked()));
+ disconnect(m_commitButton, &QAbstractButton::clicked, this, &FinishedPage::handleFinishClicked);
m_commitButton = 0;
}
- if (packageManagerCore()->isUpdater() || packageManagerCore()->isPackageManager()) {
+ if (packageManagerCore()->isMaintainer()) {
#ifdef Q_OS_OSX
gui()->setOption(QWizard::NoCancelButton, false);
#endif
@@ -2967,13 +3023,13 @@ void FinishedPage::entering()
cancel->setEnabled(true);
cancel->setVisible(true);
// we don't use the usual FinishButton so we need to connect the misused CancelButton
- connect(cancel, SIGNAL(clicked()), gui(), SIGNAL(finishButtonClicked()));
- connect(cancel, SIGNAL(clicked()), packageManagerCore(), SIGNAL(finishButtonClicked()));
+ connect(cancel, &QAbstractButton::clicked, gui(), &PackageManagerGui::finishButtonClicked);
+ connect(cancel, &QAbstractButton::clicked, packageManagerCore(), &PackageManagerCore::finishButtonClicked);
// for the moment we don't want the rejected signal connected
- disconnect(gui(), SIGNAL(rejected()), packageManagerCore(), SLOT(setCanceled()));
+ disconnect(gui(), &QDialog::rejected, packageManagerCore(), &PackageManagerCore::setCanceled);
- connect(gui()->button(QWizard::CommitButton), SIGNAL(clicked()), this,
- SLOT(cleanupChangedConnects()));
+ connect(gui()->button(QWizard::CommitButton), &QAbstractButton::clicked,
+ this, &FinishedPage::cleanupChangedConnects);
}
setButtonText(QWizard::CommitButton, tr("Restart"));
setButtonText(QWizard::CancelButton, gui()->defaultButtonText(QWizard::FinishButton));
@@ -2992,8 +3048,8 @@ void FinishedPage::entering()
gui()->updateButtonLayout();
if (m_commitButton) {
- disconnect(m_commitButton, SIGNAL(clicked()), this, SLOT(handleFinishClicked()));
- connect(m_commitButton, SIGNAL(clicked()), this, SLOT(handleFinishClicked()));
+ disconnect(m_commitButton, &QAbstractButton::clicked, this, &FinishedPage::handleFinishClicked);
+ connect(m_commitButton, &QAbstractButton::clicked, this, &FinishedPage::handleFinishClicked);
}
if (packageManagerCore()->status() == PackageManagerCore::Success) {
@@ -3060,12 +3116,12 @@ void FinishedPage::cleanupChangedConnects()
{
if (QAbstractButton *cancel = gui()->button(QWizard::CancelButton)) {
// remove the workaround connect from entering page
- disconnect(cancel, SIGNAL(clicked()), gui(), SIGNAL(finishButtonClicked()));
- disconnect(cancel, SIGNAL(clicked()), packageManagerCore(), SIGNAL(finishButtonClicked()));
- connect(gui(), SIGNAL(rejected()), packageManagerCore(), SLOT(setCanceled()));
+ disconnect(cancel, &QAbstractButton::clicked, gui(), &PackageManagerGui::finishButtonClicked);
+ disconnect(cancel, &QAbstractButton::clicked, packageManagerCore(), &PackageManagerCore::finishButtonClicked);
+ connect(gui(), &QDialog::rejected, packageManagerCore(), &PackageManagerCore::setCanceled);
- disconnect(gui()->button(QWizard::CommitButton), SIGNAL(clicked()), this,
- SLOT(cleanupChangedConnects()));
+ disconnect(gui()->button(QWizard::CommitButton), &QAbstractButton::clicked,
+ this, &FinishedPage::cleanupChangedConnects);
}
}
diff --git a/src/libs/installer/packagemanagergui.h b/src/libs/installer/packagemanagergui.h
index f56dbb645..8faa75263 100644
--- a/src/libs/installer/packagemanagergui.h
+++ b/src/libs/installer/packagemanagergui.h
@@ -38,6 +38,7 @@
#include <QtCore/QEvent>
#include <QtCore/QMetaType>
+#include <QtCore/QTimer>
#include <QWizard>
#include <QWizardPage>
@@ -92,6 +93,9 @@ public:
void updateButtonLayout();
static QWizard::WizardStyle getStyle(const QString &name);
+ void setSilent(bool silent);
+ bool isSilent() const;
+
Q_SIGNALS:
void interrupted();
void languageChanged();
@@ -352,6 +356,7 @@ private:
private:
QLineEdit *m_lineEdit;
QLabel *m_warningLabel;
+ QTimer m_textChangeTimer;
};
diff --git a/src/libs/installer/packagemanagerpagefactory.cpp b/src/libs/installer/packagemanagerpagefactory.cpp
index a046284a3..7106864c0 100644
--- a/src/libs/installer/packagemanagerpagefactory.cpp
+++ b/src/libs/installer/packagemanagerpagefactory.cpp
@@ -41,9 +41,4 @@ PackageManagerPageFactory &PackageManagerPageFactory::instance()
return factory;
}
-PackageManagerPage *PackageManagerPageFactory::create(int id, PackageManagerCore *core) const
-{
- return KDGenericFactory<PackageManagerPage, int, PackageManagerCore*>::createWithArg(id, core);
-}
-
}
diff --git a/src/libs/installer/packagemanagerpagefactory.h b/src/libs/installer/packagemanagerpagefactory.h
index 6ac37732b..57056c375 100644
--- a/src/libs/installer/packagemanagerpagefactory.h
+++ b/src/libs/installer/packagemanagerpagefactory.h
@@ -34,16 +34,16 @@
#ifndef PACKAGEMANAGERPAGEFACTORY_H
#define PACKAGEMANAGERPAGEFACTORY_H
-#include <kdgenericfactory.h>
-#include <packagemanagergui.h>
+#include "genericfactory.h"
+#include "qinstallerglobal.h"
namespace QInstaller {
class PackageManagerCore;
class PackageManagerPage;
-class INSTALLER_EXPORT PackageManagerPageFactory : public KDGenericFactory<PackageManagerPage,
- int, QInstaller::PackageManagerCore*>
+class INSTALLER_EXPORT PackageManagerPageFactory : public GenericFactory<PackageManagerPage, int,
+ PackageManagerCore*>
{
Q_DISABLE_COPY(PackageManagerPageFactory)
@@ -51,12 +51,11 @@ public:
static PackageManagerPageFactory &instance();
template<typename T> void registerPackageManagerPage(int id)
{
- registerProductWithArg<T>(id);
+ registerProduct<T>(id);
}
- PackageManagerPage *create(int id, QInstaller::PackageManagerCore *core) const;
private:
- PackageManagerPageFactory() {}
+ PackageManagerPageFactory() = default;
};
} // namespace QInstaller
diff --git a/src/libs/installer/packagemanagerproxyfactory.cpp b/src/libs/installer/packagemanagerproxyfactory.cpp
index 56ca0b851..df9c3b443 100644
--- a/src/libs/installer/packagemanagerproxyfactory.cpp
+++ b/src/libs/installer/packagemanagerproxyfactory.cpp
@@ -120,7 +120,7 @@ void PackageManagerProxyFactory::setProxyCredentials(const QNetworkProxy &proxy,
auto p = std::find_if(m_proxyCredentials.begin(), m_proxyCredentials.end(),
FindProxyCredential(proxy.hostName(), proxy.port()));
- if (p == m_proxyCredentials.constEnd()) {
+ if (p == m_proxyCredentials.end()) {
ProxyCredential proxyCredential;
proxyCredential.host = proxy.hostName();
proxyCredential.port = proxy.port();
diff --git a/src/libs/installer/packagemanagerproxyfactory.h b/src/libs/installer/packagemanagerproxyfactory.h
index 765debfca..a2ba09103 100644
--- a/src/libs/installer/packagemanagerproxyfactory.h
+++ b/src/libs/installer/packagemanagerproxyfactory.h
@@ -34,7 +34,7 @@
#ifndef PACKAGEMANAGERPROXYFACTORY_H
#define PACKAGEMANAGERPROXYFACTORY_H
-#include "kdupdaterfiledownloaderfactory.h"
+#include "filedownloaderfactory.h"
namespace QInstaller {
diff --git a/src/libs/installer/packagesource.cpp b/src/libs/installer/packagesource.cpp
new file mode 100644
index 000000000..f60c5c8e1
--- /dev/null
+++ b/src/libs/installer/packagesource.cpp
@@ -0,0 +1,91 @@
+/**************************************************************************
+**
+** 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 "packagesource.h"
+
+namespace QInstaller {
+
+/*!
+ \inmodule QtInstallerFramework
+ \class QInstaller::PackageSource
+ \brief The PackageSource class specifies a single package source.
+
+ An package source represents a link to an repository that contains packages applicable by
+ the installer or package maintenance application. This structure describes a single package
+ source in terms of url and priority. While different repositories can host the same packages,
+ packages coming from a higher priority source take precedence over lower priority packages
+ during applicable package computation.
+*/
+
+/*!
+ \fn PackageSource::PackageSource()
+
+ Constructs an empty package source info object. The object's priority is set to -1. The url is
+ initialized using a \l{default-constructed value}.
+*/
+
+/*!
+ \fn PackageSource::PackageSource(const QUrl &u, int p)
+
+ Constructs an package source info object. The object's url is set to \a u, while the priority
+ is set to \a p.
+*/
+
+/*!
+ \variable PackageSource::url
+ \brief The URL of the package source.
+*/
+
+/*!
+ \variable PackageSource::priority
+ \brief The priority of the package source.
+*/
+
+/*!
+ Returns the hash value for the \a key, using \a seed to seed the calculation.
+*/
+uint qHash(const PackageSource &key, uint seed)
+{
+ return qHash(key.url, seed) ^ key.priority;
+}
+
+/*!
+ Returns \c true if \a lhs and \a rhs are equal; otherwise returns \c false.
+*/
+bool operator==(const PackageSource &lhs, const PackageSource &rhs)
+{
+ return lhs.url == rhs.url && lhs.priority == rhs.priority;
+}
+
+} // namespace QInstaller
diff --git a/src/libs/installer/packagesource.h b/src/libs/installer/packagesource.h
new file mode 100644
index 000000000..6bc565c15
--- /dev/null
+++ b/src/libs/installer/packagesource.h
@@ -0,0 +1,63 @@
+/**************************************************************************
+**
+** 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$
+**
+**************************************************************************/
+
+#ifndef PACKAGESOURCE_H
+#define PACKAGESOURCE_H
+
+#include "installer_global.h"
+
+#include <QUrl>
+
+namespace QInstaller {
+
+struct INSTALLER_EXPORT PackageSource
+{
+ PackageSource()
+ : priority(-1)
+ {}
+ PackageSource(const QUrl &u, int p)
+ : url(u)
+ , priority(p)
+ {}
+
+ QUrl url;
+ int priority;
+};
+
+INSTALLER_EXPORT uint qHash(const PackageSource &key, uint seed);
+INSTALLER_EXPORT bool operator==(const PackageSource &lhs, const PackageSource &rhs);
+
+} // namespace QInstaller
+
+#endif // PACKAGESOURCE_H
diff --git a/src/libs/installer/performinstallationform.cpp b/src/libs/installer/performinstallationform.cpp
index d9a99e71c..dbf059c94 100644
--- a/src/libs/installer/performinstallationform.cpp
+++ b/src/libs/installer/performinstallationform.cpp
@@ -122,13 +122,13 @@ void PerformInstallationForm::setupUi(QWidget *widget)
m_downloadStatus->setObjectName(QLatin1String("DownloadStatus"));
m_downloadStatus->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
topLayout->addWidget(m_downloadStatus);
- connect(ProgressCoordinator::instance(), SIGNAL(downloadStatusChanged(QString)), this,
- SLOT(onDownloadStatusChanged(QString)));
+ connect(ProgressCoordinator::instance(), &ProgressCoordinator::downloadStatusChanged, this,
+ &PerformInstallationForm::onDownloadStatusChanged);
m_detailsButton = new QPushButton(tr("&Show Details"), widget);
m_detailsButton->setObjectName(QLatin1String("DetailsButton"));
m_detailsButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
- connect(m_detailsButton, SIGNAL(clicked()), this, SLOT(toggleDetails()));
+ connect(m_detailsButton, &QAbstractButton::clicked, this, &PerformInstallationForm::toggleDetails);
topLayout->addWidget(m_detailsButton);
QVBoxLayout *bottomLayout = new QVBoxLayout();
@@ -147,7 +147,8 @@ void PerformInstallationForm::setupUi(QWidget *widget)
baseLayout->addLayout(bottomLayout);
m_updateTimer = new QTimer(widget);
- connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updateProgress())); //updateProgress includes label
+ connect(m_updateTimer, &QTimer::timeout,
+ this, &PerformInstallationForm::updateProgress); //updateProgress includes label
m_updateTimer->setInterval(30);
m_progressBar->setRange(0, 100);
@@ -181,7 +182,7 @@ void PerformInstallationForm::updateProgress()
m_progressBar->setValue(progressPercentage);
#ifdef Q_OS_WIN
if (m_taskButton) {
- if (!m_taskButton->window())
+ if (!m_taskButton->window() && QApplication::activeWindow())
m_taskButton->setWindow(QApplication::activeWindow()->windowHandle());
m_taskButton->progress()->setValue(progressPercentage);
}
diff --git a/src/libs/installer/progresscoordinator.cpp b/src/libs/installer/progresscoordinator.cpp
index b2552126d..7dfffed59 100644
--- a/src/libs/installer/progresscoordinator.cpp
+++ b/src/libs/installer/progresscoordinator.cpp
@@ -106,7 +106,7 @@ void ProgressCoordinator::registerPartProgress(QObject *sender, const char *sign
void ProgressCoordinator::partProgressChanged(double fraction)
{
if (fraction < 0 || fraction > 1) {
- qWarning() << "The fraction is outside from possible value:" << QString::number(fraction);
+ qWarning() << "The fraction is outside from possible value:" << fraction;
return;
}
diff --git a/src/libs/installer/proxycredentialsdialog.h b/src/libs/installer/proxycredentialsdialog.h
index f4935c53d..046d246f5 100644
--- a/src/libs/installer/proxycredentialsdialog.h
+++ b/src/libs/installer/proxycredentialsdialog.h
@@ -35,7 +35,7 @@
#include <QDialog>
-class QNetworkProxy;
+QT_FORWARD_DECLARE_CLASS(QNetworkProxy)
namespace QInstaller {
diff --git a/src/libs/installer/qinstallerglobal.h b/src/libs/installer/qinstallerglobal.h
index af3866d01..d6b08de7b 100644
--- a/src/libs/installer/qinstallerglobal.h
+++ b/src/libs/installer/qinstallerglobal.h
@@ -36,9 +36,9 @@
#include <installer_global.h>
-#include <kdupdaterupdate.h>
-#include <kdupdaterupdateoperation.h>
-#include <kdupdaterpackagesinfo.h>
+#include "update.h"
+#include "updateoperation.h"
+#include "localpackagehub.h"
namespace QInstaller {
@@ -60,8 +60,7 @@ typedef QList<QInstaller::Operation*> OperationList;
typedef KDUpdater::Update Package;
typedef QList<QInstaller::Package*> PackagesList;
-typedef KDUpdater::PackageInfo LocalPackage;
-typedef QHash<QString, LocalPackage> LocalPackagesHash;
+typedef QHash<QString, KDUpdater::LocalPackage> LocalPackagesHash;
} // namespace QInstaller
diff --git a/src/libs/installer/qprocesswrapper.cpp b/src/libs/installer/qprocesswrapper.cpp
index 40291719e..ca9abdea3 100644
--- a/src/libs/installer/qprocesswrapper.cpp
+++ b/src/libs/installer/qprocesswrapper.cpp
@@ -48,20 +48,17 @@ QProcessWrapper::QProcessWrapper(QObject *parent)
qRegisterMetaType<QProcess::ProcessState>();
m_timer.start(250);
- connect(&m_timer, SIGNAL(timeout()), this, SLOT(processSignals()));
- connect(&process, SIGNAL(bytesWritten(qint64)), SIGNAL(bytesWritten(qint64)));
- connect(&process, SIGNAL(aboutToClose()), SIGNAL(aboutToClose()));
- connect(&process, SIGNAL(readChannelFinished()), SIGNAL(readChannelFinished()));
+ connect(&m_timer, &QTimer::timeout, this, &QProcessWrapper::processSignals);
+ connect(&process, &QIODevice::bytesWritten, this, &QProcessWrapper::bytesWritten);
+ connect(&process, &QIODevice::aboutToClose, this, &QProcessWrapper::aboutToClose);
+ connect(&process, &QIODevice::readChannelFinished, this, &QProcessWrapper::readChannelFinished);
connect(&process, SIGNAL(error(QProcess::ProcessError)), SIGNAL(error(QProcess::ProcessError)));
- connect(&process, SIGNAL(readyReadStandardOutput()), SIGNAL(readyReadStandardOutput()));
- connect(&process, SIGNAL(readyReadStandardError()), SIGNAL(readyReadStandardError()));
- connect(&process, SIGNAL(finished(int)), SIGNAL(finished(int)));
- connect(&process, SIGNAL(finished(int,QProcess::ExitStatus)),
- SIGNAL(finished(int,QProcess::ExitStatus)));
- connect(&process, SIGNAL(readyRead()), SIGNAL(readyRead()));
- connect(&process, SIGNAL(started()), SIGNAL(started()));
- connect(&process, SIGNAL(stateChanged(QProcess::ProcessState)),
- SIGNAL(stateChanged(QProcess::ProcessState)));
+ connect(&process, &QProcess::readyReadStandardOutput, this, &QProcessWrapper::readyReadStandardOutput);
+ connect(&process, &QProcess::readyReadStandardError, this, &QProcessWrapper::readyReadStandardError);
+ connect(&process, SIGNAL(finished(int,QProcess::ExitStatus)), SIGNAL(finished(int,QProcess::ExitStatus)));
+ connect(&process, &QIODevice::readyRead, this, &QProcessWrapper::readyRead);
+ connect(&process, &QProcess::started, this, &QProcessWrapper::started);
+ connect(&process, &QProcess::stateChanged, this, &QProcessWrapper::stateChanged);
}
QProcessWrapper::~QProcessWrapper()
@@ -102,7 +99,6 @@ void QProcessWrapper::processSignals()
emit stateChanged(static_cast<QProcess::ProcessState> (receivedSignals.takeFirst()
.toInt()));
} else if (name == QLatin1String(Protocol::QProcessSignalFinished)) {
- emit finished(receivedSignals.first().toInt());
emit finished(receivedSignals.takeFirst().toInt(),
static_cast<QProcess::ExitStatus> (receivedSignals.takeFirst().toInt()));
}
diff --git a/src/libs/installer/qprocesswrapper.h b/src/libs/installer/qprocesswrapper.h
index c80281ff8..7277b33ce 100644
--- a/src/libs/installer/qprocesswrapper.h
+++ b/src/libs/installer/qprocesswrapper.h
@@ -122,7 +122,6 @@ Q_SIGNALS:
void error(QProcess::ProcessError);
void readyReadStandardOutput();
void readyReadStandardError();
- void finished(int exitCode);
void finished(int exitCode, QProcess::ExitStatus exitStatus);
void readyRead();
void started();
diff --git a/src/libs/installer/qtpatch.cpp b/src/libs/installer/qtpatch.cpp
index 28c514fc4..17abe8a7b 100644
--- a/src/libs/installer/qtpatch.cpp
+++ b/src/libs/installer/qtpatch.cpp
@@ -90,8 +90,8 @@ QHash<QString, QByteArray> QtPatch::qmakeValues(const QString &qmakePath, QByteA
if (process.exitStatus() == QProcess::CrashExit) {
qWarning() << qmake.absoluteFilePath() << args
<< "crashed with exit code" << process.exitCode()
- << "standard output: " << output
- << "error output: " << process.readAllStandardError();
+ << "standard output:" << output
+ << "error output:" << process.readAllStandardError();
return qmakeValueHash;
}
qmakeValueHash = readQmakeOutput(output);
@@ -125,7 +125,7 @@ bool QtPatch::patchBinaryFile(const QString &fileName,
openFileForPatching(&file);
if (!file.isOpen()) {
qDebug() << "qpatch: warning: file" << qPrintable(fileName) << "cannot open.";
- qDebug() << qPrintable(file.errorString());
+ qDebug().noquote() << file.errorString();
return false;
}
@@ -173,8 +173,7 @@ bool QtPatch::patchTextFile(const QString &fileName,
QFile file(fileName);
if (!file.open(QFile::ReadOnly)) {
- qDebug() << QString::fromLatin1("qpatch: warning: Open the file '%1' stopped: %2").arg(
- fileName, file.errorString());
+ qDebug() << "Cannot open file" << fileName << "for patching:" << file.errorString();
return false;
}
@@ -188,7 +187,7 @@ bool QtPatch::patchTextFile(const QString &fileName,
}
if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
- qDebug() << QString::fromLatin1("qpatch: error: file '%1' not writable").arg(fileName);
+ qDebug() << "File" << fileName << "not writable.";
return false;
}
@@ -208,7 +207,6 @@ bool QtPatch::openFileForPatching(QFile *file)
}
return file->openMode() == QFile::ReadWrite;
}
- qDebug() << QString::fromLatin1("qpatch: error: File '%1 is open, so it cannot be opened again.").arg(
- file->fileName());
+ qDebug() << "File" << file->fileName() << "is open, so it cannot be opened again.";
return false;
}
diff --git a/src/libs/installer/registerfiletypeoperation.cpp b/src/libs/installer/registerfiletypeoperation.cpp
index 936bbeb25..89d1934c3 100644
--- a/src/libs/installer/registerfiletypeoperation.cpp
+++ b/src/libs/installer/registerfiletypeoperation.cpp
@@ -33,6 +33,7 @@
#include "registerfiletypeoperation.h"
+#include "constants.h"
#include "packagemanagercore.h"
#include "qsettingswrapper.h"
@@ -78,7 +79,8 @@ static QVariantHash readHive(QSettingsWrapper *const settings, const QString &hi
// -- RegisterFileTypeOperation
-RegisterFileTypeOperation::RegisterFileTypeOperation()
+RegisterFileTypeOperation::RegisterFileTypeOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("RegisterFileType"));
}
@@ -93,16 +95,12 @@ bool RegisterFileTypeOperation::performOperation()
QStringList args = arguments();
QString progId = takeProgIdArgument(args);
- if (args.count() < 2 || args.count() > 5) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("2 to 5"), QLatin1String("")));
+ if (!checkArgumentCount(2, 5, tr("<extension> <command> [description [contentType [icon]]]")))
return false;
- }
bool allUsers = false;
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
- if (core && core->value(QLatin1String("AllUsers")) == QLatin1String("true"))
+ PackageManagerCore *const core = packageManager();
+ if (core && core->value(scAllUsers) == scTrue)
allUsers = true;
QSettingsWrapper settings(QLatin1String(allUsers ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER")
@@ -165,8 +163,8 @@ bool RegisterFileTypeOperation::undoOperation()
}
bool allUsers = false;
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
- if (core && core->value(QLatin1String("AllUsers")) == QLatin1String("true"))
+ PackageManagerCore *const core = packageManager();
+ if (core && core->value(scAllUsers) == scTrue)
allUsers = true;
QSettingsWrapper settings(QLatin1String(allUsers ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER")
@@ -220,8 +218,3 @@ bool RegisterFileTypeOperation::testOperation()
{
return true;
}
-
-Operation *RegisterFileTypeOperation::clone() const
-{
- return new RegisterFileTypeOperation();
-}
diff --git a/src/libs/installer/registerfiletypeoperation.h b/src/libs/installer/registerfiletypeoperation.h
index e595b8262..0c50ab02b 100644
--- a/src/libs/installer/registerfiletypeoperation.h
+++ b/src/libs/installer/registerfiletypeoperation.h
@@ -43,13 +43,12 @@ class INSTALLER_EXPORT RegisterFileTypeOperation : public QObject, public Operat
Q_OBJECT
public:
- RegisterFileTypeOperation();
+ explicit RegisterFileTypeOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
}
diff --git a/src/libs/installer/remoteclient.cpp b/src/libs/installer/remoteclient.cpp
index 8a9d4cdc8..59a236635 100644
--- a/src/libs/installer/remoteclient.cpp
+++ b/src/libs/installer/remoteclient.cpp
@@ -36,6 +36,8 @@
namespace QInstaller {
+RemoteClient *RemoteClient::s_instance = 0;
+
RemoteClient::RemoteClient()
: d_ptr(new RemoteClientPrivate(this))
{
@@ -47,8 +49,9 @@ RemoteClient::~RemoteClient()
RemoteClient &RemoteClient::instance()
{
- static RemoteClient instance;
- return instance;
+ if (!s_instance)
+ s_instance = new RemoteClient;
+ return *s_instance;
}
QString RemoteClient::socketName() const
@@ -81,6 +84,12 @@ void RemoteClient::shutdown()
d_ptr.reset(new RemoteClientPrivate(this));
}
+void RemoteClient::destroy()
+{
+ delete s_instance;
+ s_instance = 0;
+}
+
bool RemoteClient::isActive() const
{
Q_D(const RemoteClient);
diff --git a/src/libs/installer/remoteclient.h b/src/libs/installer/remoteclient.h
index 75cdd12c0..278132ba8 100644
--- a/src/libs/installer/remoteclient.h
+++ b/src/libs/installer/remoteclient.h
@@ -54,6 +54,7 @@ public:
Protocol::StartAs startAs);
void shutdown();
+ void destroy();
QString socketName() const;
QString authorizationKey() const;
@@ -66,6 +67,7 @@ private:
~RemoteClient();
private:
+ static RemoteClient *s_instance;
QScopedPointer<RemoteClientPrivate> d_ptr;
};
diff --git a/src/libs/installer/remoteclient_p.h b/src/libs/installer/remoteclient_p.h
index 0edfdab41..e88d0579d 100644
--- a/src/libs/installer/remoteclient_p.h
+++ b/src/libs/installer/remoteclient_p.h
@@ -131,11 +131,11 @@ public:
const QMessageBox::Button res =
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
QLatin1String("AuthorizationError"),
- QCoreApplication::translate("RemoteClient", "Could not get authorization."),
- QCoreApplication::translate("RemoteClient", "Could not get authorization that "
+ QCoreApplication::translate("RemoteClient", "Cannot get authorization."),
+ QCoreApplication::translate("RemoteClient", "Cannot get authorization that "
"is needed for continuing the installation.\n Either abort the "
- "installation or use the fallback solution by running\n\n%1\n\nas root "
- "and then clicking OK.").arg(fallback),
+ "installation or use the fallback solution by running\n\n%1\n\nas a user "
+ "with the appropriate rights and then clicking OK.").arg(fallback),
QMessageBox::Abort | QMessageBox::Ok, QMessageBox::Ok);
if (res == QMessageBox::Ok)
diff --git a/src/libs/installer/remoteobject.h b/src/libs/installer/remoteobject.h
index a09bede67..72c20eaa4 100644
--- a/src/libs/installer/remoteobject.h
+++ b/src/libs/installer/remoteobject.h
@@ -96,7 +96,7 @@ public:
QByteArray data;
while (!receivePacket(m_socket, &command, &data)) {
if (!m_socket->waitForReadyRead(-1)) {
- throw Error(tr("Could not read all data after sending command: %1. "
+ throw Error(tr("Cannot read all data after sending command: %1. "
"Bytes expected: %2, Bytes received: %3. Error: %4").arg(name).arg(0)
.arg(m_socket->bytesAvailable()).arg(m_socket->errorString()));
}
diff --git a/src/libs/installer/remoteserver.cpp b/src/libs/installer/remoteserver.cpp
index 3ecc90f02..dfb622bbf 100644
--- a/src/libs/installer/remoteserver.cpp
+++ b/src/libs/installer/remoteserver.cpp
@@ -80,13 +80,13 @@ void RemoteServer::start()
d->m_localServer = new LocalServer(d->m_socketName, d->m_key);
d->m_localServer->moveToThread(&d->m_thread);
- connect(&d->m_thread, SIGNAL(finished()), d->m_localServer, SLOT(deleteLater()));
- connect(d->m_localServer, SIGNAL(newIncomingConnection()), this, SLOT(restartWatchdog()));
- connect(d->m_localServer, SIGNAL(shutdownRequested()), this, SLOT(deleteLater()));
+ connect(&d->m_thread, &QThread::finished, d->m_localServer, &QObject::deleteLater);
+ connect(d->m_localServer, &LocalServer::newIncomingConnection, this, &RemoteServer::restartWatchdog);
+ connect(d->m_localServer, &LocalServer::shutdownRequested, this, &QObject::deleteLater);
d->m_thread.start();
if (d->m_mode == Protocol::Mode::Production) {
- connect(d->m_watchdog.data(), SIGNAL(timeout()), this, SLOT(deleteLater()));
+ connect(d->m_watchdog.data(), &QTimer::timeout, this, &QObject::deleteLater);
d->m_watchdog->start();
}
}
diff --git a/src/libs/installer/remoteserver_p.h b/src/libs/installer/remoteserver_p.h
index b069e1331..bbd83e117 100644
--- a/src/libs/installer/remoteserver_p.h
+++ b/src/libs/installer/remoteserver_p.h
@@ -84,9 +84,9 @@ private:
if (m_shutdown)
return;
- QThread *const thread = new RemoteServerConnection(socketDescriptor, m_key, this);
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- connect(thread, SIGNAL(shutdownRequested()), this, SLOT(shutdown()));
+ RemoteServerConnection *thread = new RemoteServerConnection(socketDescriptor, m_key, this);
+ connect(thread, &QThread::finished, thread, &QObject::deleteLater);
+ connect(thread, &RemoteServerConnection::shutdownRequested, this, &LocalServer::shutdown);
thread->start();
emit newIncomingConnection();
}
diff --git a/src/libs/installer/remoteserverconnection_p.h b/src/libs/installer/remoteserverconnection_p.h
index 00eaf1a9e..0c94c5f5d 100644
--- a/src/libs/installer/remoteserverconnection_p.h
+++ b/src/libs/installer/remoteserverconnection_p.h
@@ -51,19 +51,21 @@ private:
explicit QProcessSignalReceiver(QProcess *process)
: QObject(process)
{
- connect(process, SIGNAL(bytesWritten(qint64)), SLOT(onBytesWritten(qint64)));
- connect(process, SIGNAL(aboutToClose()), SLOT(onAboutToClose()));
- connect(process, SIGNAL(readChannelFinished()), SLOT(onReadChannelFinished()));
+ connect(process, &QIODevice::bytesWritten, this, &QProcessSignalReceiver::onBytesWritten);
+ connect(process, &QIODevice::aboutToClose, this, &QProcessSignalReceiver::onAboutToClose);
+ connect(process, &QIODevice::readChannelFinished, this, &QProcessSignalReceiver::onReadChannelFinished);
connect(process, SIGNAL(error(QProcess::ProcessError)),
SLOT(onError(QProcess::ProcessError)));
- connect(process, SIGNAL(readyReadStandardOutput()), SLOT(onReadyReadStandardOutput()));
- connect(process, SIGNAL(readyReadStandardError()), SLOT(onReadyReadStandardError()));
- connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
- SLOT(onFinished(int, QProcess::ExitStatus)));
- connect(process, SIGNAL(readyRead()), SLOT(onReadyRead()));
- connect(process, SIGNAL(started()), SLOT(onStarted()));
- connect(process, SIGNAL(stateChanged(QProcess::ProcessState)),
- SLOT(onStateChanged(QProcess::ProcessState)));
+ connect(process, &QProcess::readyReadStandardOutput,
+ this, &QProcessSignalReceiver::onReadyReadStandardOutput);
+ connect(process, &QProcess::readyReadStandardError,
+ this, &QProcessSignalReceiver::onReadyReadStandardError);
+ connect(process, SIGNAL(finished(int,QProcess::ExitStatus)),
+ SLOT(onFinished(int,QProcess::ExitStatus)));
+ connect(process, &QIODevice::readyRead, this, &QProcessSignalReceiver::onReadyRead);
+ connect(process, &QProcess::started, this, &QProcessSignalReceiver::onStarted);
+ connect(process, &QProcess::stateChanged,
+ this, &QProcessSignalReceiver::onStateChanged);
}
private Q_SLOTS:
diff --git a/src/libs/installer/replaceoperation.cpp b/src/libs/installer/replaceoperation.cpp
index a3f470d5d..55d501278 100644
--- a/src/libs/installer/replaceoperation.cpp
+++ b/src/libs/installer/replaceoperation.cpp
@@ -39,7 +39,8 @@
using namespace QInstaller;
-ReplaceOperation::ReplaceOperation()
+ReplaceOperation::ReplaceOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Replace"));
}
@@ -50,18 +51,14 @@ void ReplaceOperation::backup()
bool ReplaceOperation::performOperation()
{
- const QStringList args = arguments();
-
// Arguments:
// 1. filename
// 2. Source-String
// 3. Replace-String
- if (args.count() != 3) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 3"), QLatin1String("")));
+ if (!checkArgumentCount(3))
return false;
- }
+
+ const QStringList args = arguments();
const QString fileName = args.at(0);
const QString before = args.at(1);
const QString after = args.at(2);
@@ -69,7 +66,8 @@ bool ReplaceOperation::performOperation()
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to open %1 for reading").arg(fileName));
+ setErrorString(tr("Cannot open file \"%1\" for reading: %2").arg(
+ QDir::toNativeSeparators(fileName), file.errorString()));
return false;
}
@@ -79,7 +77,8 @@ bool ReplaceOperation::performOperation()
if (!file.open(QIODevice::WriteOnly)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to open %1 for writing").arg(fileName));
+ setErrorString(tr("Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(fileName), file.errorString()));
return false;
}
@@ -100,8 +99,3 @@ bool ReplaceOperation::testOperation()
{
return true;
}
-
-Operation *ReplaceOperation::clone() const
-{
- return new ReplaceOperation();
-}
diff --git a/src/libs/installer/replaceoperation.h b/src/libs/installer/replaceoperation.h
index 881e81b89..3cae90d04 100644
--- a/src/libs/installer/replaceoperation.h
+++ b/src/libs/installer/replaceoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT ReplaceOperation : public Operation
{
public:
- ReplaceOperation();
+ explicit ReplaceOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
} // namespace QInstaller
diff --git a/src/libs/installer/repository.cpp b/src/libs/installer/repository.cpp
index 49d5fd16a..9a501fdfe 100644
--- a/src/libs/installer/repository.cpp
+++ b/src/libs/installer/repository.cpp
@@ -32,7 +32,7 @@
**************************************************************************/
#include "repository.h"
-#include "kdupdaterfiledownloaderfactory.h"
+#include "filedownloaderfactory.h"
#include <QDataStream>
#include <QFileInfo>
diff --git a/src/libs/installer/resources/install.png b/src/libs/installer/resources/install.png
new file mode 100644
index 000000000..8e3309c9f
--- /dev/null
+++ b/src/libs/installer/resources/install.png
Binary files differ
diff --git a/src/libs/installer/resources/installer.qrc b/src/libs/installer/resources/installer.qrc
index 77bf00f65..48a7c65bd 100644
--- a/src/libs/installer/resources/installer.qrc
+++ b/src/libs/installer/resources/installer.qrc
@@ -3,5 +3,9 @@
<file>installer.png</file>
<file>installer.ico</file>
<file>installer.icns</file>
+ <file>install.png</file>
+ <file>uninstall.png</file>
+ <file>keepinstalled.png</file>
+ <file>keepuninstalled.png</file>
</qresource>
</RCC>
diff --git a/src/libs/installer/resources/keepinstalled.png b/src/libs/installer/resources/keepinstalled.png
new file mode 100644
index 000000000..7f8489e28
--- /dev/null
+++ b/src/libs/installer/resources/keepinstalled.png
Binary files differ
diff --git a/src/libs/installer/resources/keepuninstalled.png b/src/libs/installer/resources/keepuninstalled.png
new file mode 100644
index 000000000..2753092cc
--- /dev/null
+++ b/src/libs/installer/resources/keepuninstalled.png
Binary files differ
diff --git a/src/libs/installer/resources/uninstall.png b/src/libs/installer/resources/uninstall.png
new file mode 100644
index 000000000..5646770da
--- /dev/null
+++ b/src/libs/installer/resources/uninstall.png
Binary files differ
diff --git a/src/libs/installer/scriptengine.cpp b/src/libs/installer/scriptengine.cpp
index 0560e7e90..adf841bde 100644
--- a/src/libs/installer/scriptengine.cpp
+++ b/src/libs/installer/scriptengine.cpp
@@ -203,6 +203,15 @@ QList<QJSValue> GuiProxy::findChildren(QObject *parent, const QString &objectNam
return children;
}
+/*!
+ Hides the GUI when \a silent is \c true.
+*/
+void GuiProxy::setSilent(bool silent)
+{
+ if (m_gui)
+ m_gui->setSilent(silent);
+}
+
void GuiProxy::cancelButtonClicked()
{
if (m_gui)
@@ -265,7 +274,7 @@ ScriptEngine::ScriptEngine(PackageManagerCore *core) :
setGuiQObject(core->guiObject());
QQmlEngine::setObjectOwnership(core, QQmlEngine::CppOwnership);
global.setProperty(QLatin1String("installer"), m_engine.newQObject(core));
- connect(core, SIGNAL(guiObjectChanged(QObject*)), this, SLOT(setGuiQObject(QObject*)));
+ connect(core, &PackageManagerCore::guiObjectChanged, this, &ScriptEngine::setGuiQObject);
} else {
global.setProperty(QLatin1String("installer"), m_engine.newQObject(new QObject));
}
@@ -371,7 +380,7 @@ QJSValue ScriptEngine::loadInContext(const QString &context, const QString &file
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
- throw Error(tr("Could not open the requested script file at %1: %2.")
+ throw Error(tr("Cannot open script file at %1: %2")
.arg(fileName, file.errorString()));
}
@@ -389,9 +398,10 @@ QJSValue ScriptEngine::loadInContext(const QString &context, const QString &file
QJSValue scriptContext = evaluate(scriptContent, fileName);
scriptContext.setProperty(QLatin1String("Uuid"), QUuid::createUuid().toString());
if (scriptContext.isError()) {
- throw Error(tr("Exception while loading the component script '%1'. (%2)").arg(
- QFileInfo(file).absoluteFilePath(), scriptContext.toString().isEmpty() ?
- QString::fromLatin1("Unknown error.") : scriptContext.toString()));
+ throw Error(tr("Exception while loading the component script \"%1\": %2").arg(
+ QDir::toNativeSeparators(QFileInfo(file).absoluteFilePath()),
+ scriptContext.toString().isEmpty() ?
+ tr("Unknown error.") : scriptContext.toString()));
}
return scriptContext;
}
diff --git a/src/libs/installer/scriptengine_p.h b/src/libs/installer/scriptengine_p.h
index 1a1dac0e3..b15478680 100644
--- a/src/libs/installer/scriptengine_p.h
+++ b/src/libs/installer/scriptengine_p.h
@@ -54,7 +54,7 @@ public:
ConsoleProxy() {}
public slots :
- void log(const QString &log) { qDebug() << log; }
+ void log(const QString &log) { qDebug().noquote() << log; }
};
class InstallerProxy : public QObject
@@ -158,6 +158,8 @@ public:
Q_INVOKABLE QJSValue findChild(QObject *parent, const QString &objectName);
Q_INVOKABLE QList<QJSValue> findChildren(QObject *parent, const QString &objectName);
+ Q_INVOKABLE void setSilent(bool silent);
+
signals:
void interrupted();
void languageChanged();
diff --git a/src/libs/installer/selfrestartoperation.cpp b/src/libs/installer/selfrestartoperation.cpp
index 54b970074..df1fec2c4 100644
--- a/src/libs/installer/selfrestartoperation.cpp
+++ b/src/libs/installer/selfrestartoperation.cpp
@@ -34,30 +34,31 @@
#include "selfrestartoperation.h"
#include "packagemanagercore.h"
-#include <kdselfrestarter.h>
+#include "selfrestarter.h"
using namespace QInstaller;
-SelfRestartOperation::SelfRestartOperation()
+SelfRestartOperation::SelfRestartOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("SelfRestart"));
}
void SelfRestartOperation::backup()
{
- setValue(QLatin1String("PreviousSelfRestart"), KDSelfRestarter::restartOnQuit());
+ setValue(QLatin1String("PreviousSelfRestart"), SelfRestarter::restartOnQuit());
}
bool SelfRestartOperation::performOperation()
{
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ PackageManagerCore *const core = packageManager();
if (!core) {
setError(UserDefinedError);
- setErrorString(tr("Installer object needed in '%1' operation is empty.").arg(name()));
+ setErrorString(tr("Installer object needed in operation %1 is empty.").arg(name()));
return false;
}
- if (!core->isUpdater() && !core->isPackageManager()) {
+ if (!core->isMaintainer()) {
setError(UserDefinedError);
setErrorString(tr("Self Restart: Only valid within updater or packagemanager mode."));
return false;
@@ -68,13 +69,13 @@ bool SelfRestartOperation::performOperation()
setErrorString(tr("Self Restart: Invalid arguments"));
return false;
}
- KDSelfRestarter::setRestartOnQuit(true);
- return KDSelfRestarter::restartOnQuit();
+ SelfRestarter::setRestartOnQuit(true);
+ return SelfRestarter::restartOnQuit();
}
bool SelfRestartOperation::undoOperation()
{
- KDSelfRestarter::setRestartOnQuit(value(QLatin1String("PreviousSelfRestart")).toBool());
+ SelfRestarter::setRestartOnQuit(value(QLatin1String("PreviousSelfRestart")).toBool());
return true;
}
@@ -82,8 +83,3 @@ bool SelfRestartOperation::testOperation()
{
return true;
}
-
-Operation *SelfRestartOperation::clone() const
-{
- return new SelfRestartOperation();
-}
diff --git a/src/libs/installer/selfrestartoperation.h b/src/libs/installer/selfrestartoperation.h
index aed08aead..b4a4fa78d 100644
--- a/src/libs/installer/selfrestartoperation.h
+++ b/src/libs/installer/selfrestartoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT SelfRestartOperation : public Operation
{
public:
- SelfRestartOperation();
+ explicit SelfRestartOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
}
diff --git a/src/libs/installer/settings.cpp b/src/libs/installer/settings.cpp
index 7093a88a5..5389573fa 100644
--- a/src/libs/installer/settings.cpp
+++ b/src/libs/installer/settings.cpp
@@ -61,6 +61,7 @@ static const QLatin1String scRemoteRepositories("RemoteRepositories");
static const QLatin1String scDependsOnLocalInstallerBinary("DependsOnLocalInstallerBinary");
static const QLatin1String scTranslations("Translations");
static const QLatin1String scCreateLocalRepository("CreateLocalRepository");
+static const QLatin1String scInstallActionColumnVisible("InstallActionColumnVisible");
static const QLatin1String scFtpProxy("FtpProxy");
static const QLatin1String scHttpProxy("HttpProxy");
@@ -84,9 +85,10 @@ static void raiseError(QXmlStreamReader &reader, const QString &error, Settings:
} else {
QFile *xmlFile = qobject_cast<QFile*>(reader.device());
if (xmlFile) {
- qWarning() << QString::fromLatin1("Ignoring following settings reader error in %1, line %2, "
- "column %3: %4").arg(xmlFile->fileName()).arg(reader.lineNumber()).arg(reader.columnNumber())
- .arg(error);
+ qWarning().noquote().nospace()
+ << "Ignoring following settings reader error in " << xmlFile->fileName()
+ << ", line " << reader.lineNumber() << ", column " << reader.columnNumber()
+ << ": " << error;
} else {
qWarning("Ignoring following settings reader error: %s", qPrintable(error));
}
@@ -102,7 +104,7 @@ static QStringList readArgumentAttributes(QXmlStreamReader &reader, Settings::Pa
switch (token) {
case QXmlStreamReader::StartElement: {
if (!reader.attributes().isEmpty()) {
- raiseError(reader, QString::fromLatin1("Unexpected attribute for element '%1'.")
+ raiseError(reader, QString::fromLatin1("Unexpected attribute for element \"%1\".")
.arg(reader.name().toString()), parseMode);
return arguments;
} else {
@@ -110,7 +112,7 @@ static QStringList readArgumentAttributes(QXmlStreamReader &reader, Settings::Pa
(lc) ? arguments.append(reader.readElementText().toLower()) :
arguments.append(reader.readElementText());
} else {
- raiseError(reader, QString::fromLatin1("Unexpected element '%1'.").arg(reader.name()
+ raiseError(reader, QString::fromLatin1("Unexpected element \"%1\".").arg(reader.name()
.toString()), parseMode);
return arguments;
}
@@ -152,23 +154,23 @@ static QSet<Repository> readRepositories(QXmlStreamReader &reader, bool isDefaul
} else if (reader.name() == QLatin1String("Enabled")) {
repo.setEnabled(bool(reader.readElementText().toInt()));
} else {
- raiseError(reader, QString::fromLatin1("Unexpected element '%1'.").arg(reader.name()
+ raiseError(reader, QString::fromLatin1("Unexpected element \"%1\".").arg(reader.name()
.toString()), parseMode);
}
if (!reader.attributes().isEmpty()) {
- raiseError(reader, QString::fromLatin1("Unexpected attribute for element '%1'.")
+ raiseError(reader, QString::fromLatin1("Unexpected attribute for element \"%1\".")
.arg(reader.name().toString()), parseMode);
}
}
set.insert(repo);
} else {
- raiseError(reader, QString::fromLatin1("Unexpected element '%1'.").arg(reader.name().toString()),
+ raiseError(reader, QString::fromLatin1("Unexpected element \"%1\".").arg(reader.name().toString()),
parseMode);
}
if (!reader.attributes().isEmpty()) {
- raiseError(reader, QString::fromLatin1("Unexpected attribute for element '%1'.").arg(reader
+ raiseError(reader, QString::fromLatin1("Unexpected attribute for element \"%1\".").arg(reader
.name().toString()), parseMode);
}
}
@@ -235,12 +237,12 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix,
file.setFileName(overrideConfig.fileName());
if (!file.open(QIODevice::ReadOnly))
- throw Error(tr("Could not open settings file %1 for reading: %2").arg(path, file.errorString()));
+ throw Error(tr("Cannot open settings file %1 for reading: %2").arg(path, file.errorString()));
QXmlStreamReader reader(&file);
if (reader.readNextStartElement()) {
if (reader.name() != QLatin1String("Installer")) {
- reader.raiseError(QString::fromLatin1("Unexpected element '%1' as root element.").arg(reader
+ reader.raiseError(QString::fromLatin1("Unexpected element \"%1\" as root element.").arg(reader
.name().toString()));
}
}
@@ -252,26 +254,26 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix,
<< scStartMenuDir << scMaintenanceToolName << scMaintenanceToolIniFile << scRemoveTargetDir
<< scRunProgram << scRunProgramArguments << scRunProgramDescription
<< scDependsOnLocalInstallerBinary
- << scAllowSpaceInPath << scAllowNonAsciiCharacters << scWizardStyle << scTitleColor
+ << scAllowSpaceInPath << scAllowNonAsciiCharacters << scWizardStyle << scStyleSheet << scTitleColor
<< scWizardDefaultWidth << scWizardDefaultHeight
<< scRepositorySettingsPageVisible << scTargetConfigurationFile
- << scRemoteRepositories << scTranslations << QLatin1String(scControlScript)
- << scCreateLocalRepository;
+ << scRemoteRepositories << scTranslations << scUrlQueryString << QLatin1String(scControlScript)
+ << scCreateLocalRepository << scInstallActionColumnVisible;
Settings s;
s.d->m_data.insert(scPrefix, prefix);
while (reader.readNextStartElement()) {
const QString name = reader.name().toString();
if (!elementList.contains(name))
- raiseError(reader, QString::fromLatin1("Unexpected element '%1'.").arg(name), parseMode);
+ raiseError(reader, QString::fromLatin1("Unexpected element \"%1\".").arg(name), parseMode);
if (!reader.attributes().isEmpty()) {
- raiseError(reader, QString::fromLatin1("Unexpected attribute for element '%1'.").arg(name),
+ raiseError(reader, QString::fromLatin1("Unexpected attribute for element \"%1\".").arg(name),
parseMode);
}
if (s.d->m_data.contains(name))
- reader.raiseError(QString::fromLatin1("Element '%1' has been defined before.").arg(name));
+ reader.raiseError(QString::fromLatin1("Element \"%1\" has been defined before.").arg(name));
if (name == scTranslations) {
s.setTranslations(readArgumentAttributes(reader, parseMode, QLatin1String("Translation"), true));
@@ -323,6 +325,8 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix,
s.d->m_data.insert(scRepositorySettingsPageVisible, true);
if (!s.d->m_data.contains(scCreateLocalRepository))
s.d->m_data.insert(scCreateLocalRepository, false);
+ if (!s.d->m_data.contains(scInstallActionColumnVisible))
+ s.d->m_data.insert(scInstallActionColumnVisible, false);
return s;
}
@@ -377,6 +381,11 @@ QString Settings::wizardStyle() const
return d->m_data.value(scWizardStyle).toString();
}
+QString Settings::styleSheet() const
+{
+ return d->absolutePathFromKey(scStyleSheet);
+}
+
QString Settings::titleColor() const
{
return d->m_data.value(scTitleColor).toString();
@@ -477,6 +486,11 @@ bool Settings::createLocalRepository() const
return d->m_data.value(scCreateLocalRepository).toBool();
}
+bool Settings::installActionColumnVisible() const
+{
+ return d->m_data.value(scInstallActionColumnVisible, false).toBool();
+}
+
bool Settings::allowSpaceInPath() const
{
return d->m_data.value(scAllowSpaceInPath, true).toBool();
diff --git a/src/libs/installer/settings.h b/src/libs/installer/settings.h
index 2d7a894c3..9171ff6ae 100644
--- a/src/libs/installer/settings.h
+++ b/src/libs/installer/settings.h
@@ -88,6 +88,7 @@ public:
QString installerWindowIcon() const;
QString systemIconSuffix() const;
QString wizardStyle() const;
+ QString styleSheet() const;
QString titleColor() const;
int wizardDefaultWidth() const;
int wizardDefaultHeight() const;
@@ -111,6 +112,7 @@ public:
QString configurationFileName() const;
bool createLocalRepository() const;
+ bool installActionColumnVisible() const;
bool dependsOnLocalInstallerBinary() const;
bool hasReplacementRepos() const;
diff --git a/src/libs/installer/settingsoperation.cpp b/src/libs/installer/settingsoperation.cpp
index c7e15c423..1692cab91 100644
--- a/src/libs/installer/settingsoperation.cpp
+++ b/src/libs/installer/settingsoperation.cpp
@@ -32,7 +32,7 @@
**************************************************************************/
#include "settingsoperation.h"
#include "packagemanagercore.h"
-#include "kdupdaterupdateoperations.h"
+#include "updateoperations.h"
#include "qsettingswrapper.h"
#include <QDir>
@@ -40,7 +40,8 @@
using namespace QInstaller;
-SettingsOperation::SettingsOperation()
+SettingsOperation::SettingsOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Settings"));
}
@@ -68,7 +69,7 @@ bool SettingsOperation::checkArguments()
if (!missingArguments.isEmpty()) {
setError(InvalidArguments);
- setErrorString(tr("Missing argument(s) '%1' calling '%2' with arguments '%3'.").arg(
+ setErrorString(tr("Missing argument(s) \"%1\" calling %2 with arguments \"%3\".").arg(
missingArguments.join(QLatin1String("; ")), name(), arguments().join(QLatin1String("; "))));
return false;
}
@@ -78,7 +79,7 @@ bool SettingsOperation::checkArguments()
if (!possibleMethodValues.contains(method)) {
setError(InvalidArguments);
- setErrorString(tr("Current method argument calling '%1' with arguments '%2' is not "
+ setErrorString(tr("Current method argument calling \"%1\" with arguments \"%2\" is not "
"supported. Please use set, remove, add_array_value or remove_array_value.").arg(name(),
arguments().join(QLatin1String("; "))));
return false;
@@ -182,14 +183,14 @@ bool SettingsOperation::undoOperation()
if (cleanUp) {
QFile settingsFile(path);
if (!settingsFile.remove())
- qWarning() << settingsFile.errorString();
+ qWarning().noquote() << settingsFile.errorString();
if (!value(QLatin1String("createddir")).toString().isEmpty()) {
KDUpdater::MkdirOperation mkDirOperation;
mkDirOperation.setArguments(QStringList() << QFileInfo(path).absolutePath());
mkDirOperation.setValue(QLatin1String("createddir"), value(QLatin1String("createddir")));
if (!mkDirOperation.undoOperation()) {
- qWarning() << mkDirOperation.errorString();
+ qWarning().noquote() << mkDirOperation.errorString();
}
}
}
@@ -200,9 +201,3 @@ bool SettingsOperation::testOperation()
{
return true;
}
-
-Operation *SettingsOperation::clone() const
-{
- return new SettingsOperation();
-}
-
diff --git a/src/libs/installer/settingsoperation.h b/src/libs/installer/settingsoperation.h
index 7a1e9d5fa..83249635b 100644
--- a/src/libs/installer/settingsoperation.h
+++ b/src/libs/installer/settingsoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT SettingsOperation : public Operation
{
public:
- SettingsOperation();
+ explicit SettingsOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
private:
bool checkArguments();
diff --git a/src/libs/installer/simplemovefileoperation.cpp b/src/libs/installer/simplemovefileoperation.cpp
index 7e5cac8bb..6d904fa2a 100644
--- a/src/libs/installer/simplemovefileoperation.cpp
+++ b/src/libs/installer/simplemovefileoperation.cpp
@@ -33,11 +33,13 @@
#include "simplemovefileoperation.h"
+#include <QDir>
#include <QtCore/QFileInfo>
namespace QInstaller {
-SimpleMoveFileOperation::SimpleMoveFileOperation()
+SimpleMoveFileOperation::SimpleMoveFileOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("SimpleMoveFile"));
}
@@ -48,21 +50,17 @@ void SimpleMoveFileOperation::backup()
bool SimpleMoveFileOperation::performOperation()
{
- const QStringList args = arguments();
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 2"), QLatin1String("")));
+ if (!checkArgumentCount(2))
return false;
- }
+ const QStringList args = arguments();
const QString source = args.at(0);
const QString target = args.at(1);
if (source.isEmpty() || target.isEmpty()) {
setError(UserDefinedError);
- setErrorString(tr("None of the arguments can be empty: source '%1', target '%2'.")
- .arg(source, target));
+ setErrorString(tr("None of the arguments can be empty: source \"%1\", target \"%2\".")
+ .arg(QDir::toNativeSeparators(source), QDir::toNativeSeparators(target)));
return false;
}
@@ -72,8 +70,8 @@ bool SimpleMoveFileOperation::performOperation()
if (file.exists()) {
if (!file.remove()) {
setError(UserDefinedError);
- setErrorString(tr("Cannot move source '%1' to target '%2', because target exists and is "
- "not removable.").arg(source, target));
+ setErrorString(tr("Cannot move file from \"%1\" to \"%2\", because the target path exists and is "
+ "not removable.").arg(QDir::toNativeSeparators(source), QDir::toNativeSeparators(target)));
return false;
}
}
@@ -81,12 +79,14 @@ bool SimpleMoveFileOperation::performOperation()
file.setFileName(source);
if (!file.rename(target)) {
setError(UserDefinedError);
- setErrorString(tr("Cannot move source '%1' to target '%2': %3").arg(source, target,
- file.errorString()));
+ setErrorString(tr("Cannot move file \"%1\" to \"%2\": %3").arg(
+ QDir::toNativeSeparators(source), QDir::toNativeSeparators(target),
+ file.errorString()));
return false;
}
- emit outputTextChanged(tr("Move '%1' to '%2'.").arg(source, target));
+ emit outputTextChanged(tr("Moving file \"%1\" to \"%2\".").arg(QDir::toNativeSeparators(source),
+ QDir::toNativeSeparators(target)));
return true;
}
@@ -96,7 +96,8 @@ bool SimpleMoveFileOperation::undoOperation()
const QString target = arguments().at(1);
QFile(target).rename(source);
- emit outputTextChanged(tr("Move '%1' to '%2'.").arg(target, source));
+ emit outputTextChanged(tr("Moving file \"%1\" to \"%2\".").arg(QDir::toNativeSeparators(target),
+ QDir::toNativeSeparators(source)));
return true;
}
@@ -106,9 +107,4 @@ bool SimpleMoveFileOperation::testOperation()
return true;
}
-Operation *SimpleMoveFileOperation::clone() const
-{
- return new SimpleMoveFileOperation();
-}
-
} // namespace QInstaller
diff --git a/src/libs/installer/simplemovefileoperation.h b/src/libs/installer/simplemovefileoperation.h
index 3d6c1c58d..64338a016 100644
--- a/src/libs/installer/simplemovefileoperation.h
+++ b/src/libs/installer/simplemovefileoperation.h
@@ -45,13 +45,12 @@ class INSTALLER_EXPORT SimpleMoveFileOperation : public QObject, public Operatio
Q_OBJECT
public:
- SimpleMoveFileOperation();
+ explicit SimpleMoveFileOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
Q_SIGNALS:
void outputTextChanged(const QString &progress);
diff --git a/src/libs/installer/sysinfo_win.cpp b/src/libs/installer/sysinfo_win.cpp
index ec14ead4f..57ab67e1c 100644
--- a/src/libs/installer/sysinfo_win.cpp
+++ b/src/libs/installer/sysinfo_win.cpp
@@ -31,7 +31,7 @@
**
**************************************************************************/
-#include "kdsysinfo.h"
+#include "sysinfo.h"
#include "link.h"
#ifdef Q_CC_MINGW
diff --git a/src/libs/installer/testrepository.cpp b/src/libs/installer/testrepository.cpp
index 37067b10f..6767d9aaa 100644
--- a/src/libs/installer/testrepository.cpp
+++ b/src/libs/installer/testrepository.cpp
@@ -32,26 +32,29 @@
**************************************************************************/
#include "testrepository.h"
-#include <kdupdaterfiledownloader.h>
-#include <kdupdaterfiledownloaderfactory.h>
+#include "packagemanagercore.h"
+#include "packagemanagerproxyfactory.h"
+#include "proxycredentialsdialog.h"
+#include "serverauthenticationdialog.h"
-#include <QtCore/QFile>
+#include <QFile>
-using namespace QInstaller;
+namespace QInstaller {
-TestRepository::TestRepository(QObject *parent)
- : KDJob(parent)
- , m_downloader(0)
+TestRepository::TestRepository(PackageManagerCore *parent)
+ : Job(parent)
+ , m_core(parent)
{
- setTimeout(10000);
setAutoDelete(false);
setCapabilities(Cancelable);
+
+ connect(&m_timer, &QTimer::timeout, this, &TestRepository::onTimeout);
+ connect(&m_xmlTask, &QFutureWatcherBase::finished, this, &TestRepository::downloadCompleted);
}
TestRepository::~TestRepository()
{
- if (m_downloader)
- m_downloader->deleteLater();
+ reset();
}
Repository TestRepository::repository() const
@@ -61,100 +64,125 @@ Repository TestRepository::repository() const
void TestRepository::setRepository(const Repository &repository)
{
- cancel();
-
- setError(NoError);
- setErrorString(QString());
+ reset();
m_repository = repository;
}
void TestRepository::doStart()
{
- if (m_downloader)
- m_downloader->deleteLater();
+ reset();
+ if (!m_core) {
+ emitFinishedWithError(Job::Canceled, tr("Missing package manager core engine."));
+ return; // We can't do anything here without core, so avoid tons of !m_core checks.
+ }
const QUrl url = m_repository.url();
if (url.isEmpty()) {
- emitFinishedWithError(InvalidUrl, tr("Empty repository URL."));
- return;
- }
-
- m_downloader = KDUpdater::FileDownloaderFactory::instance().create(url.scheme(), this);
- if (!m_downloader) {
- emitFinishedWithError(InvalidUrl, tr("URL scheme not supported: %1 (%2).")
- .arg(url.scheme(), url.toString()));
+ emitFinishedWithError(QInstaller::InvalidUrl, tr("Empty repository URL."));
return;
}
QAuthenticator auth;
auth.setUser(m_repository.username());
auth.setPassword(m_repository.password());
- m_downloader->setAuthenticator(auth);
-
- connect(m_downloader, SIGNAL(downloadCompleted()), this, SLOT(downloadCompleted()));
- connect(m_downloader, SIGNAL(downloadAborted(QString)), this, SLOT(downloadAborted(QString)),
- Qt::QueuedConnection);
- connect(m_downloader, SIGNAL(authenticatorChanged(QAuthenticator)), this,
- SLOT(onAuthenticatorChanged(QAuthenticator)));
- m_downloader->setAutoRemoveDownloadedFile(true);
- m_downloader->setUrl(QUrl(url.toString() + QString::fromLatin1("/Updates.xml")));
+ FileTaskItem item(m_repository.url().toString() + QLatin1String("/Updates.xml?") +
+ QString::number(qrand() * qrand()));
+ item.insert(TaskRole::Authenticator, QVariant::fromValue(auth));
- m_downloader->download();
+ m_timer.start(10000);
+ DownloadFileTask *const xmlTask = new DownloadFileTask(item);
+ if (m_core)
+ xmlTask->setProxyFactory(m_core->proxyFactory());
+ m_xmlTask.setFuture(QtConcurrent::run(&DownloadFileTask::doTask, xmlTask));
}
void TestRepository::doCancel()
{
- if (m_downloader) {
- QString errorString = m_downloader->errorString();
- if (errorString.isEmpty())
- errorString = tr("Got a timeout while testing: '%1'").arg(m_repository.displayname());
- // at the moment the download sends downloadCompleted() if we cancel it, so just
- disconnect(m_downloader, 0, this, 0);
- m_downloader->cancelDownload();
- emitFinishedWithError(KDJob::Canceled, errorString);
- }
+ reset();
+ emitFinishedWithError(Job::Canceled, tr("Download canceled."));
+}
+
+void TestRepository::onTimeout()
+{
+ reset();
+ emitFinishedWithError(Job::Canceled, tr("Timeout while testing repository \"%1\".")
+ .arg(m_repository.displayname()));
}
void TestRepository::downloadCompleted()
{
- QString errorMsg;
- int error = DownloadError;
+ if (error() != Job::NoError)
+ return;
+
+ try {
+ m_xmlTask.waitForFinished();
- if (m_downloader->isDownloaded()) {
- QFile file(m_downloader->downloadedFileName());
- if (file.exists() && file.open(QIODevice::ReadOnly)) {
+ m_timer.stop();
+ QFile file(m_xmlTask.future().results().value(0).target());
+ if (file.open(QIODevice::ReadOnly)) {
QDomDocument doc;
QString errorMsg;
if (!doc.setContent(&file, &errorMsg)) {
- error = InvalidUpdatesXml;
- errorMsg = tr("Could not parse Updates.xml! Error: %1.").arg(errorMsg);
+ emitFinishedWithError(QInstaller::InvalidUpdatesXml,
+ tr("Cannot parse Updates.xml: %1").arg(errorMsg));
} else {
- error = NoError;
+ emitFinishedWithError(Job::NoError, QString(/*Success*/)); // OPK
}
} else {
- errorMsg = tr("Updates.xml could not be opened for reading!");
+ emitFinishedWithError(QInstaller::DownloadError,
+ tr("Cannot open Updates.xml for reading: %1").arg(file.errorString()));
}
- } else {
- errorMsg = tr("Updates.xml could not be found on server!");
+ } catch (const AuthenticationRequiredException &e) {
+ m_timer.stop();
+ if (e.type() == AuthenticationRequiredException::Type::Server) {
+ ServerAuthenticationDialog dlg(e.message(), e.taskItem());
+ if (dlg.exec() == QDialog::Accepted) {
+ m_repository.setUsername(dlg.user());
+ m_repository.setPassword(dlg.password());
+ }
+ QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection);
+ return;
+ } else if (e.type() == AuthenticationRequiredException::Type::Proxy) {
+ const QNetworkProxy proxy = e.proxy();
+ ProxyCredentialsDialog proxyCredentials(proxy);
+ if (proxyCredentials.exec() == QDialog::Accepted) {
+ PackageManagerProxyFactory *factory = m_core->proxyFactory();
+ factory->setProxyCredentials(proxy, proxyCredentials.userName(),
+ proxyCredentials.password());
+ m_core->setProxyFactory(factory);
+ }
+ QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection);
+ return;
+ } else {
+ emitFinishedWithError(QInstaller::DownloadError, tr("Authentication failed."));
+ }
+ } catch (const TaskException &e) {
+ m_timer.stop();
+ emitFinishedWithError(QInstaller::DownloadError, e.message());
+ } catch (const QUnhandledException &e) {
+ m_timer.stop();
+ emitFinishedWithError(QInstaller::DownloadError, QLatin1String(e.what()));
+ } catch (...) {
+ m_timer.stop();
+ emitFinishedWithError(QInstaller::DownloadError,
+ tr("Unknown error while testing repository \"%1\".").arg(m_repository.displayname()));
}
+}
- if (error > NoError)
- emitFinishedWithError(error, errorMsg);
- else
- emitFinished();
- m_downloader->deleteLater();
- m_downloader = 0;
-}
+// -- private
-void TestRepository::downloadAborted(const QString &reason)
+void TestRepository::reset()
{
- emitFinishedWithError(DownloadError, reason);
-}
+ m_timer.stop();
+ setError(NoError);
+ setErrorString(QString());
-void TestRepository::onAuthenticatorChanged(const QAuthenticator &authenticator)
-{
- m_repository.setUsername(authenticator.user());
- m_repository.setPassword(authenticator.password());
+ try {
+ if (m_xmlTask.isRunning())
+ m_xmlTask.cancel();
+ } catch (...) {}
}
+
+} // namespace QInstaller
diff --git a/src/libs/installer/testrepository.h b/src/libs/installer/testrepository.h
index 4e387b15d..55e492803 100644
--- a/src/libs/installer/testrepository.h
+++ b/src/libs/installer/testrepository.h
@@ -33,55 +33,47 @@
#ifndef TESTREPOSITORY_H
#define TESTREPOSITORY_H
-#include "qinstallerglobal.h"
+#include "downloadfiletask.h"
+#include "job.h"
+#include "repository.h"
-#include <repository.h>
-#include <settings.h>
-
-#include <kdjob.h>
-
-QT_BEGIN_NAMESPACE
-class QAuthenticator;
-class QLocale;
-class QVariant;
-QT_END_NAMESPACE
-
-namespace KDUpdater {
- class FileDownloader;
-}
+#include <QFutureWatcher>
+#include <QTimer>
namespace QInstaller {
- class PackageManagerCore;
-}
-namespace QInstaller {
+class PackageManagerCore;
-class INSTALLER_EXPORT TestRepository : public KDJob
+class INSTALLER_EXPORT TestRepository : public Job
{
Q_OBJECT
+ Q_DISABLE_COPY(TestRepository)
public:
-
- explicit TestRepository(QObject *parent = 0);
+ explicit TestRepository(PackageManagerCore *parent = 0);
~TestRepository();
- QInstaller::Repository repository() const;
- void setRepository(const QInstaller::Repository &repository);
+ Repository repository() const;
+ void setRepository(const Repository &repository);
-private:
+private slots:
void doStart();
void doCancel();
-private Q_SLOTS:
+ void onTimeout();
void downloadCompleted();
- void downloadAborted(const QString &reason);
- void onAuthenticatorChanged(const QAuthenticator &authenticator);
private:
- QInstaller::Repository m_repository;
- KDUpdater::FileDownloader *m_downloader;
+ void reset();
+
+private:
+ PackageManagerCore *m_core;
+
+ QTimer m_timer;
+ Repository m_repository;
+ QFutureWatcher<FileTaskResult> m_xmlTask;
};
-} //namespace QInstaller
+} // namespace QInstaller
#endif // TESTREPOSITORY_H
diff --git a/src/libs/installer/unziptask.cpp b/src/libs/installer/unziptask.cpp
index 5c00e78a2..7e05dc1c6 100644
--- a/src/libs/installer/unziptask.cpp
+++ b/src/libs/installer/unziptask.cpp
@@ -30,7 +30,9 @@
** $QT_END_LICENSE$
**
**************************************************************************/
+
#include "unziptask.h"
+#include "lib7z_facade.h"
#ifdef Q_OS_UNIX
# include "StdAfx.h"
@@ -39,21 +41,15 @@
// TODO: include once we switch from lib7z_fascade.h
//#include "Common/MyInitGuid.h"
-#include "7zip/IPassword.h"
+#include "7zip/Archive/IArchive.h"
#include "7zip/Common/FileStreams.h"
#include "7zip/UI/Common/OpenArchive.h"
#include "Windows/FileDir.h"
#include "Windows/PropVariant.h"
-#include "7zCrc.h"
-
#include <QDir>
-void registerArc7z();
-void registerCodecLZMA();
-void registerCodecLZMA2();
-
namespace QInstaller {
class ArchiveExtractCallback : public IArchiveExtractCallback, public CMyUnknownImp
@@ -104,11 +100,11 @@ public:
return E_FAIL;
bool isDir = false;
- if (IsArchiveItemFolder(m_arc.Archive, m_currentIndex, isDir) != S_OK)
+ if (Archive_IsItem_Folder(m_arc.Archive, m_currentIndex, isDir) != S_OK)
return E_FAIL;
bool isEncrypted = false;
- if (GetArchiveItemBoolProp(m_arc.Archive, m_currentIndex, kpidEncrypted, isEncrypted) != S_OK)
+ if (Archive_GetItemBoolProp(m_arc.Archive, m_currentIndex, kpidEncrypted, isEncrypted) != S_OK)
return E_FAIL;
if (isDir || isEncrypted)
@@ -154,7 +150,7 @@ public:
default: // fall through and bail
case NArchive::NExtract::NOperationResult::kCRCError:
case NArchive::NExtract::NOperationResult::kDataError:
- case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
m_outFileStream->Close();
m_outFileStreamComPtr.Release();
return E_FAIL;
@@ -162,7 +158,7 @@ public:
UInt32 attributes;
if (GetAttributes(&attributes))
- NWindows::NFile::NDirectory::MySetFileAttributes((wchar_t*)(m_currentTarget.utf16()), attributes);
+ NWindows::NFile::NDir::SetFileAttrib((wchar_t*)(m_currentTarget.utf16()), attributes);
FILETIME accessTime, creationTime, modificationTime;
const bool writeAccessTime = GetTime(kpidATime, &accessTime);
@@ -239,13 +235,7 @@ UnzipTask::UnzipTask(const QString &source, const QString &target)
: m_source(source)
, m_target(target)
{
- {
- CrcGenerateTable();
-
- registerArc7z();
- registerCodecLZMA();
- registerCodecLZMA2();
- }
+ Lib7z::initSevenZ();
}
void UnzipTask::doTask(QFutureInterface<QString> &fi)
@@ -256,19 +246,29 @@ void UnzipTask::doTask(QFutureInterface<QString> &fi)
if (codecs.Load() != S_OK)
return;
- CIntVector formatIndices;
- if (!codecs.FindFormatForArchiveType(L"", formatIndices))
- return;
- CInFileStream *fileStream = new CInFileStream;
+ COpenOptions op;
+ op.codecs = &codecs;
+
+ CObjectVector<COpenType> types;
+ op.types = &types; // Empty, because we use a stream.
+
+ CIntVector excluded;
+ op.excludedFormats = &excluded;
+
+ const CMyComPtr<CInFileStream> fileStream = new CInFileStream;
fileStream->Open((wchar_t*) (m_source.utf16()));
+ op.stream = fileStream; // CMyComPtr is needed, otherwise it crashes in OpenStream().
+
+ CObjectVector<CProperty> properties;
+ op.props = &properties;
CArchiveLink archiveLink;
- if (archiveLink.Open2(&codecs, formatIndices, false, fileStream, UString(), 0) != S_OK)
+ if (archiveLink.Open2(op, nullptr) != S_OK)
return;
UINT32 count = 0;
- for (int i = 0; i < archiveLink.Arcs.Size(); ++i) {
+ for (unsigned i = 0; i < archiveLink.Arcs.Size(); ++i) {
const CArc& arc = archiveLink.Arcs[i];
UInt32 numItems = 0;
if (arc.Archive->GetNumberOfItems(&numItems) != S_OK)
@@ -277,7 +277,7 @@ void UnzipTask::doTask(QFutureInterface<QString> &fi)
}
fi.setExpectedResultCount(count);
- for (int i = 0; i < archiveLink.Arcs.Size(); ++i) {
+ for (unsigned i = 0; i < archiveLink.Arcs.Size(); ++i) {
if (fi.isCanceled())
break;
if (fi.isPaused())
diff --git a/src/libs/kdtools/environment.h b/src/libs/kdtools/environment.h
index a17d0a4a0..748063959 100644
--- a/src/libs/kdtools/environment.h
+++ b/src/libs/kdtools/environment.h
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#ifndef LIBINSTALLER_ENVIRONMENT_H
-#define LIBINSTALLER_ENVIRONMENT_H
+#ifndef ENVIRONMENT_H
+#define ENVIRONMENT_H
#include "kdtoolsglobal.h"
@@ -69,4 +69,4 @@ private:
} // namespace KDUpdater
-#endif
+#endif // ENVIRONMENT_H
diff --git a/src/libs/kdtools/kdupdaterfiledownloader.cpp b/src/libs/kdtools/filedownloader.cpp
index 4027dda8a..508cc395d 100644
--- a/src/libs/kdtools/kdupdaterfiledownloader.cpp
+++ b/src/libs/kdtools/filedownloader.cpp
@@ -31,13 +31,14 @@
**
****************************************************************************/
-#include "kdupdaterfiledownloader_p.h"
-#include "kdupdaterfiledownloaderfactory.h"
+#include "filedownloader_p.h"
+#include "filedownloaderfactory.h"
#include "ui_authenticationdialog.h"
-#include <fileutils.h>
+#include "fileutils.h"
#include <QDialog>
+#include <QDir>
#include <QFile>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkProxyFactory>
@@ -695,8 +696,8 @@ void KDUpdater::LocalFileDownloader::doDownload()
d->source = new QFile(localFile, this);
if (!d->source->open(QFile::ReadOnly)) {
onError();
- setDownloadAborted(tr("Cannot open source file '%1' for reading.").arg(QFileInfo(localFile)
- .fileName()));
+ setDownloadAborted(tr("Cannot open file \"%1\" for reading: %2").arg(QFileInfo(localFile)
+ .fileName(), d->source->errorString()));
return;
}
@@ -711,8 +712,8 @@ void KDUpdater::LocalFileDownloader::doDownload()
if (!d->destination->isOpen()) {
onError();
- setDownloadAborted(tr("Cannot open destination file '%1' for writing.")
- .arg(QFileInfo(d->destination->fileName()).fileName()));
+ setDownloadAborted(tr("Cannot open file \"%1\" for writing: %2")
+ .arg(QFileInfo(d->destination->fileName()).fileName(), d->destination->errorString()));
return;
}
@@ -784,8 +785,9 @@ void KDUpdater::LocalFileDownloader::timerEvent(QTimerEvent *event)
killTimer(d->timerId);
d->timerId = -1;
onError();
- setDownloadAborted(tr("Writing to %1 failed: %2").arg(d->destination->fileName(),
- d->destination->errorString()));
+ setDownloadAborted(tr("Writing to file \"%1\" failed: %2").arg(
+ QDir::toNativeSeparators(d->destination->fileName()),
+ d->destination->errorString()));
return;
}
toWrite -= numWritten;
@@ -974,7 +976,7 @@ void KDUpdater::ResourceFileDownloader::timerEvent(QTimerEvent *event)
onError();
killTimer(d->timerId);
emit downloadProgress(1);
- setDownloadAborted(tr("Could not read resource file \"%1\". Reason:").arg(downloadedFileName(),
+ setDownloadAborted(tr("Cannot read resource file \"%1\": %2").arg(downloadedFileName(),
d->destFile.errorString()));
return;
}
@@ -1058,7 +1060,7 @@ struct KDUpdater::HttpDownloader::Private
void shutDown()
{
- disconnect(http, SIGNAL(finished()), q, SLOT(httpReqFinished()));
+ disconnect(http, &QNetworkReply::finished, q, &HttpDownloader::httpReqFinished);
http->deleteLater();
http = 0;
destination->close();
@@ -1076,11 +1078,11 @@ KDUpdater::HttpDownloader::HttpDownloader(QObject *parent)
, d(new Private(this))
{
#ifndef QT_NO_SSL
- connect(&d->manager, SIGNAL(sslErrors(QNetworkReply*, QList<QSslError>)),
- this, SLOT(onSslErrors(QNetworkReply*, QList<QSslError>)));
+ connect(&d->manager, &QNetworkAccessManager::sslErrors,
+ this, &HttpDownloader::onSslErrors);
#endif
- connect(&d->manager, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this,
- SLOT(onAuthenticationRequired(QNetworkReply*, QAuthenticator*)));
+ connect(&d->manager, &QNetworkAccessManager::authenticationRequired,
+ this, &HttpDownloader::onAuthenticationRequired);
}
/*!
@@ -1162,7 +1164,7 @@ void KDUpdater::HttpDownloader::httpReadyRead()
const QString error = d->destination->errorString();
const QString fileName = d->destination->fileName();
d->shutDown();
- setDownloadAborted(tr("Cannot download %1: Writing to file '%2' failed: %3")
+ setDownloadAborted(tr("Cannot download %1. Writing to file \"%2\" failed: %3")
.arg(url().toString(), fileName, error));
return;
}
@@ -1292,12 +1294,12 @@ void KDUpdater::HttpDownloader::startDownload(const QUrl &url)
d->manager.setProxyFactory(proxyFactory());
d->http = d->manager.get(QNetworkRequest(url));
- connect(d->http, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));
- connect(d->http, SIGNAL(downloadProgress(qint64, qint64)), this,
- SLOT(httpReadProgress(qint64, qint64)));
- connect(d->http, SIGNAL(finished()), this, SLOT(httpReqFinished()));
- connect(d->http, SIGNAL(error(QNetworkReply::NetworkError)), this,
- SLOT(httpError(QNetworkReply::NetworkError)));
+ connect(d->http, &QIODevice::readyRead, this, &HttpDownloader::httpReadyRead);
+ connect(d->http, &QNetworkReply::downloadProgress,
+ this, &HttpDownloader::httpReadProgress);
+ connect(d->http, &QNetworkReply::finished, this, &HttpDownloader::httpReqFinished);
+ void (QNetworkReply::*errorSignal)(QNetworkReply::NetworkError) = &QNetworkReply::error;
+ connect(d->http, errorSignal, this, &HttpDownloader::httpError);
if (d->destFileName.isEmpty()) {
QTemporaryFile *file = new QTemporaryFile(this);
@@ -1312,7 +1314,7 @@ void KDUpdater::HttpDownloader::startDownload(const QUrl &url)
const QString error = d->destination->errorString();
const QString fileName = d->destination->fileName();
d->shutDown();
- setDownloadAborted(tr("Cannot download %1: Could not create %2: %3").arg(
+ setDownloadAborted(tr("Cannot download %1. Cannot create file \"%2\": %3").arg(
url.toString(), fileName, error));
}
}
diff --git a/src/libs/kdtools/kdupdaterfiledownloader.h b/src/libs/kdtools/filedownloader.h
index 989d46c30..4d19bad24 100644
--- a/src/libs/kdtools/kdupdaterfiledownloader.h
+++ b/src/libs/kdtools/filedownloader.h
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_FILE_DOWNLOADER_H
-#define KD_UPDATER_FILE_DOWNLOADER_H
+#ifndef FILEDOWNLOADER_H
+#define FILEDOWNLOADER_H
#include "kdtoolsglobal.h"
@@ -109,10 +109,6 @@ Q_SIGNALS:
void downloadStatus(const QString &status);
void downloadProgress(qint64 bytesReceived, qint64 bytesToReceive);
void authenticatorChanged(const QAuthenticator &authenticator);
-
-#ifndef Q_MOC_RUN
-private:
-#endif
void downloadCompleted();
void downloadAborted(const QString &errorMessage);
@@ -147,4 +143,4 @@ private:
} // namespace KDUpdater
-#endif // KD_UPDATER_FILE_DOWNLOADER_H
+#endif // FILEDOWNLOADER_H
diff --git a/src/libs/kdtools/kdupdaterfiledownloader_p.h b/src/libs/kdtools/filedownloader_p.h
index 0b1016bee..f81ff53c9 100644
--- a/src/libs/kdtools/kdupdaterfiledownloader_p.h
+++ b/src/libs/kdtools/filedownloader_p.h
@@ -31,10 +31,10 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_FILE_DOWNLOADER_P_H
-#define KD_UPDATER_FILE_DOWNLOADER_P_H
+#ifndef FILEDOWNLOADER_P_H
+#define FILEDOWNLOADER_P_H
-#include "kdupdaterfiledownloader.h"
+#include "filedownloader.h"
#include <QtNetwork/QNetworkReply>
@@ -146,4 +146,4 @@ private:
} // namespace KDUpdater
-#endif // KD_UPDATER_FILE_DOWNLOADER_P_H
+#endif // FILEDOWNLOADER_P_H
diff --git a/src/libs/kdtools/kdupdaterfiledownloaderfactory.cpp b/src/libs/kdtools/filedownloaderfactory.cpp
index 1a7b9fb47..cebedcc30 100644
--- a/src/libs/kdtools/kdupdaterfiledownloaderfactory.cpp
+++ b/src/libs/kdtools/filedownloaderfactory.cpp
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#include "kdupdaterfiledownloaderfactory.h"
-#include "kdupdaterfiledownloader_p.h"
+#include "filedownloaderfactory.h"
+#include "filedownloader_p.h"
#include <QtNetwork/QSslSocket>
@@ -73,7 +73,7 @@ FileDownloaderFactory::FileDownloaderFactory()
if (QSslSocket::supportsSsl())
registerFileDownloader<HttpDownloader>(QLatin1String("https"));
else
- qWarning() << "Could not register file downloader for https protocol: QSslSocket::supportsSsl() returns false";
+ qWarning() << "Cannot register file downloader for https protocol: QSslSocket::supportsSsl() returns false";
#endif
d->m_followRedirects = false;
@@ -154,10 +154,9 @@ bool FileDownloaderFactory::isSupportedScheme(const QString &scheme)
*/
FileDownloader *FileDownloaderFactory::create(const QString &scheme, QObject *parent) const
{
- FileDownloader *downloader = KDGenericFactory<FileDownloader>::create(scheme);
+ FileDownloader *downloader =
+ GenericFactory<FileDownloader, QString, QObject*>::create(scheme, parent);
if (downloader != 0) {
- downloader->setParent(parent);
- downloader->setScheme(scheme);
downloader->setFollowRedirects(d->m_followRedirects);
downloader->setIgnoreSslErrors(d->m_ignoreSslErrors);
if (d->m_factory)
diff --git a/src/libs/kdtools/kdupdaterfiledownloaderfactory.h b/src/libs/kdtools/filedownloaderfactory.h
index c0ec8893b..fbb2b5d48 100644
--- a/src/libs/kdtools/kdupdaterfiledownloaderfactory.h
+++ b/src/libs/kdtools/filedownloaderfactory.h
@@ -31,11 +31,11 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_FILE_DOWNLOADER_FACTORY_H
-#define KD_UPDATER_FILE_DOWNLOADER_FACTORY_H
+#ifndef FILEDOWNLOADERFACTORY_H
+#define FILEDOWNLOADERFACTORY_H
-#include "kdupdater.h"
-#include <kdgenericfactory.h>
+#include "genericfactory.h"
+#include "updater.h"
#include <QtCore/QStringList>
#include <QtCore/QUrl>
@@ -57,7 +57,8 @@ public:
virtual FileDownloaderProxyFactory *clone() const = 0;
};
-class KDTOOLS_EXPORT FileDownloaderFactory : public KDGenericFactory<FileDownloader>
+class KDTOOLS_EXPORT FileDownloaderFactory : public GenericFactory<FileDownloader, QString,
+ QObject*>
{
Q_DISABLE_COPY(FileDownloaderFactory)
struct FileDownloaderFactoryData {
@@ -102,4 +103,4 @@ private:
} // namespace KDUpdater
-#endif // KD_UPDATER_FILE_DOWNLOADER_FACTORY_H
+#endif // FILEDOWNLOADERFACTORY_H
diff --git a/src/libs/kdtools/genericfactory.cpp b/src/libs/kdtools/genericfactory.cpp
new file mode 100644
index 000000000..e29a8da4a
--- /dev/null
+++ b/src/libs/kdtools/genericfactory.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
+** 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 "genericfactory.h"
+
+/*!
+ \inmodule kdupdater
+ \namespace KDUpdater
+ \brief The KDUpdater classes provide functions to automatically detect
+ updates to applications, to retrieve them from external repositories, and to
+ install them.
+
+ KDUpdater classes are a fork of KDAB's general
+ \l{http://docs.kdab.com/kdtools/2.2.2/group__kdupdater.html}{KDUpdater module}.
+*/
+
+/*!
+ \inmodule kdupdater
+ \class GenericFactory
+ \brief The GenericFactory class implements a template-based generic factory.
+
+ GenericFactory is an implementation of the factory pattern. It can be used to produce
+ instances of different classes having a common superclass \c BASE. The user of the factory
+ registers those producible classes in the factory by using the identifier \c IDENTIFIER. That
+ identifier can then be used to produce as many instances of the registered product as the
+ user wants.
+
+ One factory instance is able to produce instances of different types of DERIVED classes only
+ when the constructor of DERIVED or the registered generator function have a common signature
+ for all DERIVED classes. This signature is described by the declaration order of ARGUMENTS. It
+ is referred to as SIGNATURE in the following paragraphs.
+
+ If a class derived from BASE does not contain a SIGNATURE matching the registered one for the
+ constructor or the generator function, it is not possible to create instances of it using one
+ instance of GenericFactory subclass. In that case, more than one GenericFactory subclass
+ and instance are needed.
+
+ It is possible to register a subclass of BASE inside an instance of GenericFactory subclass
+ using the registerProduct() function. At least one of the following conditions needs to be met:
+
+ \list
+ \li A global or static function with SIGNATURE exists.
+ \li The DERIVED class has a constructor with SIGNATURE.
+ \li The DERIVED class has a static function with SIGNATURE.
+ \endlist
+
+ To get a new instance of DERIVED, one needs to call the create() function. The value of
+ IDENTIFIER determines the product's subclass registered in the factory, while the values
+ of SIGNATURE are the actual arguments passed to the class constructor or the registered
+ generator function.
+*/
+
+/*!
+ \fn GenericFactory::GenericFactory()
+
+ Creates the generic factory.
+*/
+
+/*!
+ \fn GenericFactory::~GenericFactory()
+
+ Destroys the generic factory.
+*/
+
+/*!
+ \typedef GenericFactory::FactoryFunction
+
+ This typedef defines a factory function producing an object of type BASE.
+*/
+
+/*!
+ \fn void GenericFactory::registerProduct(const IDENTIFIER &id)
+
+ Registers a type DERIVED, identified by \a id in the factory. Any type with the same id gets
+ unregistered.
+*/
+
+/*!
+ \overload
+ \fn void GenericFactory::registerProduct(const IDENTIFIER &id, FactoryFunction func)
+
+ Registers a function \a func that can create the type DERIVED, identified by \a id in the
+ factory. Any type with the same id gets unregistered.
+*/
+
+/*!
+ \fn bool GenericFactory::containsProduct(const IDENTIFIER &id) const
+
+ Returns \c true if the factory contains a type with the \a id; otherwise returns false.
+*/
+
+/*!
+ \fn BASE *GenericFactory::create(const IDENTIFIER &id, ARGUMENTS... args) const
+
+ Creates and returns the type identified by \a id, but automatically upcasted to BASE. Ownership
+ of the type is transferred to the caller.
+*/
diff --git a/src/libs/kdtools/genericfactory.h b/src/libs/kdtools/genericfactory.h
new file mode 100644
index 000000000..8588ada5e
--- /dev/null
+++ b/src/libs/kdtools/genericfactory.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
+** 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$
+**
+****************************************************************************/
+
+#ifndef GENERICFACTORY_H
+#define GENERICFACTORY_H
+
+#include "kdtoolsglobal.h"
+
+#include <QtCore/QHash>
+
+template <typename BASE, typename IDENTIFIER = QString, typename... ARGUMENTS>
+class GenericFactory
+{
+public:
+ virtual ~GenericFactory() {}
+
+ typedef BASE *(*FactoryFunction)(ARGUMENTS...);
+
+ template <typename DERIVED>
+ void registerProduct(const IDENTIFIER &id)
+ {
+ m_hash.insert(id, &GenericFactory::create<DERIVED>);
+ }
+
+ void registerProduct(const IDENTIFIER &id, FactoryFunction func)
+ {
+ m_hash.insert(id, func);
+ }
+
+ bool containsProduct(const IDENTIFIER &id) const
+ {
+ return m_hash.contains(id);
+ }
+
+ BASE *create(const IDENTIFIER &id, ARGUMENTS... args) const
+ {
+ const auto it = m_hash.constFind(id);
+ if (it == m_hash.constEnd())
+ return 0;
+ return (*it)(std::forward<ARGUMENTS>(args)...);
+ }
+
+protected:
+ GenericFactory() = default;
+
+private:
+ template <typename DERIVED>
+ static BASE *create(ARGUMENTS... args)
+ {
+ return new DERIVED(std::forward<ARGUMENTS>(args)...);
+ }
+
+ GenericFactory(const GenericFactory &) = delete;
+ GenericFactory &operator=(const GenericFactory &) = delete;
+
+private:
+ QHash<IDENTIFIER, FactoryFunction> m_hash;
+};
+
+#endif // GENERICFACTORY_H
diff --git a/src/libs/kdtools/kdjob.cpp b/src/libs/kdtools/job.cpp
index 5fbad7956..7d8036079 100644
--- a/src/libs/kdtools/kdjob.cpp
+++ b/src/libs/kdtools/job.cpp
@@ -31,30 +31,30 @@
**
****************************************************************************/
-#include "kdjob.h"
+#include "job.h"
-#include <QtCore/QDebug>
-#include <QtCore/QEventLoop>
-#include <QtCore/QTimer>
+#include <QDebug>
+#include <QEventLoop>
+#include <QTimer>
-// -- KDJob::Private
+// -- Job::Private
-class KDJob::Private
+class Job::Private
{
- KDJob *const q;
+ Job *const q;
public:
- explicit Private(KDJob *qq)
+ explicit Private(Job *qq)
: q(qq)
- , error(KDJob::NoError)
- , caps(KDJob::NoCapabilities)
+ , error(Job::NoError)
+ , caps(Job::NoCapabilities)
, autoDelete(true)
, totalAmount(100)
, processedAmount(0)
, m_timeout(-1)
{
- connect(&m_timer, SIGNAL(timeout()), q, SLOT(cancel()));
+ connect(&m_timer, &QTimer::timeout, q, &Job::cancel);
}
~Private()
@@ -83,7 +83,7 @@ public:
int error;
QString errorString;
- KDJob::Capabilities caps;
+ Job::Capabilities caps;
bool autoDelete;
quint64 totalAmount;
quint64 processedAmount;
@@ -92,93 +92,93 @@ public:
};
-// -- KDJob
+// -- Job
-KDJob::KDJob(QObject *parent)
+Job::Job(QObject *parent)
: QObject(parent),
d(new Private(this))
{
- connect(this, SIGNAL(finished(KDJob*)), this, SLOT(onFinished()));
+ connect(this, &Job::finished, this, &Job::onFinished);
}
-KDJob::~KDJob()
+Job::~Job()
{
delete d;
}
-bool KDJob::autoDelete() const
+bool Job::autoDelete() const
{
return d->autoDelete;
}
-void KDJob::setAutoDelete(bool autoDelete)
+void Job::setAutoDelete(bool autoDelete)
{
d->autoDelete = autoDelete;
}
-int KDJob::error() const
+int Job::error() const
{
return d->error;
}
-QString KDJob::errorString() const
+QString Job::errorString() const
{
return d->errorString;
}
-void KDJob::emitFinished()
+void Job::emitFinished()
{
emit finished(this);
}
-void KDJob::emitFinishedWithError(int error, const QString &errorString)
+void Job::emitFinishedWithError(int error, const QString &errorString)
{
d->error = error;
d->errorString = errorString;
emitFinished();
}
-void KDJob::setError(int error)
+void Job::setError(int error)
{
d->error = error;
}
-void KDJob::setErrorString(const QString &errorString)
+void Job::setErrorString(const QString &errorString)
{
d->errorString = errorString;
}
-void KDJob::waitForStarted()
+void Job::waitForStarted()
{
- d->waitForSignal(SIGNAL(started(KDJob*)));
+ d->waitForSignal(SIGNAL(started(Job*)));
}
-void KDJob::waitForFinished()
+void Job::waitForFinished()
{
- d->waitForSignal(SIGNAL(finished(KDJob*)));
+ d->waitForSignal(SIGNAL(finished(Job*)));
}
-KDJob::Capabilities KDJob::capabilities() const
+Job::Capabilities Job::capabilities() const
{
return d->caps;
}
-bool KDJob::hasCapability(Capability c) const
+bool Job::hasCapability(Capability c) const
{
return d->caps.testFlag(c);
}
-void KDJob::setCapabilities(Capabilities c)
+void Job::setCapabilities(Capabilities c)
{
d->caps = c;
}
-void KDJob::start()
+void Job::start()
{
QMetaObject::invokeMethod(this, "delayedStart", Qt::QueuedConnection);
}
-void KDJob::cancel()
+void Job::cancel()
{
if (d->caps & Cancelable) {
doCancel();
@@ -192,17 +192,17 @@ void KDJob::cancel()
}
}
-quint64 KDJob::totalAmount() const
+quint64 Job::totalAmount() const
{
return d->totalAmount;
}
-quint64 KDJob::processedAmount() const
+quint64 Job::processedAmount() const
{
return d->processedAmount;
}
-void KDJob::setTotalAmount(quint64 amount)
+void Job::setTotalAmount(quint64 amount)
{
if (d->totalAmount == amount)
return;
@@ -214,22 +214,22 @@ void KDJob::setTotalAmount(quint64 amount)
Returns the timeout in milliseconds before the job's cancel slot gets triggered. A return value
of -1 means there is currently no timeout used for the job.
*/
-int KDJob::timeout() const
+int Job::timeout() const
{
return d->m_timeout;
}
/*!
Sets the timeout in \a milliseconds before the job's cancel slot gets triggered. \note Only jobs
- that have the \c KDJob::Cancelable capability can be canceled by a timeout. A value of -1 will
+ that have the \c Job::Cancelable capability can be canceled by a timeout. A value of -1 will
stop the timeout mechanism.
*/
-void KDJob::setTimeout(int milliseconds)
+void Job::setTimeout(int milliseconds)
{
d->m_timeout = milliseconds;
}
-void KDJob::setProcessedAmount(quint64 amount)
+void Job::setProcessedAmount(quint64 amount)
{
if (d->processedAmount == amount)
return;
@@ -237,11 +237,11 @@ void KDJob::setProcessedAmount(quint64 amount)
emit progress(this, d->processedAmount, d->totalAmount);
}
-void KDJob::onFinished()
+void Job::onFinished()
{
d->m_timer.stop();
if (d->autoDelete)
deleteLater();
}
-#include "moc_kdjob.cpp"
+#include "moc_job.cpp"
diff --git a/src/libs/kdtools/kdjob.h b/src/libs/kdtools/job.h
index 78786c778..5df1b4bd4 100644
--- a/src/libs/kdtools/kdjob.h
+++ b/src/libs/kdtools/job.h
@@ -31,14 +31,14 @@
**
****************************************************************************/
-#ifndef KDTOOLS_KDJOB_H
-#define KDTOOLS_KDJOB_H
+#ifndef JOB_H
+#define JOB_H
#include "kdtoolsglobal.h"
#include <QtCore/QObject>
-class KDTOOLS_EXPORT KDJob : public QObject
+class KDTOOLS_EXPORT Job : public QObject
{
Q_OBJECT
class Private;
@@ -47,8 +47,8 @@ class KDTOOLS_EXPORT KDJob : public QObject
Q_PROPERTY(bool autoDelete READ autoDelete WRITE setAutoDelete)
public:
- explicit KDJob(QObject *parent = 0);
- ~KDJob();
+ explicit Job(QObject *parent = 0);
+ ~Job();
enum Error {
NoError = 0,
@@ -86,11 +86,11 @@ public Q_SLOTS:
void cancel();
Q_SIGNALS:
- void started(KDJob *job);
- void finished(KDJob *job);
+ void started(Job *job);
+ void finished(Job *job);
- void infoMessage(KDJob *job, const QString &message);
- void progress(KDJob *job, quint64 processed, quint64 total);
+ void infoMessage(Job *job, const QString &message);
+ void progress(Job *job, quint64 processed, quint64 total);
protected:
virtual void doStart() = 0;
@@ -115,6 +115,6 @@ private:
Q_PRIVATE_SLOT(d, void delayedStart())
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(KDJob::Capabilities)
+Q_DECLARE_OPERATORS_FOR_FLAGS(Job::Capabilities)
-#endif // KDTOOLS_KDJOB_H
+#endif // JOB_H
diff --git a/src/libs/kdtools/kdgenericfactory.cpp b/src/libs/kdtools/kdgenericfactory.cpp
deleted file mode 100644
index 8bb13391c..000000000
--- a/src/libs/kdtools/kdgenericfactory.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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://www.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 "kdgenericfactory.h"
-
-/*!
- \inmodule kdupdater
- \class KDGenericFactory
- \brief The KDGenericFactory class implements a template-based generic factory.
-
- KDGenericFactory is an implementation of the factory pattern. It can be used to produce
- instances of different classes having a common superclass \c T_Product. The user of the
- factory registers those producible classes in the factory by using an identifier
- \c T_Identifier. That identifier can then be used to produce as many instances of the
- registered product as the user wants.
-
- The advanced user can even choose the type of the class the factory is using to store its
- FactoryFunctions by passing a \c T_Map template parameter. It defaults to QHash.
-
- KDGenericFactory expects the storage container to be a template class accepting \c T_Identifier
- and \c FactoryFunction as parameters. Additionally it needs to provide:
-
- \table
- \header
- \li Method
- \li Description
- \row
- \li \c {const_iterator}
- \li A type that provides a random-access iterator that can read a const element and
- when dereferenced has type \c {const &FactoryFunction}.
- \row
- \li \c {insert(T_Identifier, FactoryFunction)}
- \li A function that inserts a new item with \c T_Identifier as key and \c FactoryFunction
- as value. If there is already an item with \c T_Identifier as key, that item's value
- must be replaced with \c FactoryFunction.
- \row
- \li \c {find(T_Identifier)}
- \li A function returning an iterator pointing to the item with the key \c T_Identifier.
-
- \row
- \li \c {end()}
- \li A function returning an iterator pointing to the imaginary item after the last item.
-
- \row
- \li \c {size()}
- \li A function returning the number of items.
- \row
- \li \c {remove(T_Identifier)}
- \li A function removing all items that have the key \c T_Identifier.
- \row
- \li \c {keys()}
- \li A function returning a list of all the keys \c T_Identifier in an arbitrary order.
- \endtable
-
- The only two class templates that currently match this concept are QHash and QMap. QMultiHash
- and QMultiMap do not work, because they violate the requirement on insert() above and std::map
- and std::unordered_map do not match, because they do not have keys() and, because a dereferenced
- iterator has type \c {std::pair<const T_Identifier, FactoryFunction>} instead of just
- \c FactoryFunction.
-
- The following example shows how the general use case of KDGenericFactory looks like:
-
- \code
-
- class Fruit
- {
- };
-
- class Apple : public Fruit
- {
- };
-
- class Pear : public Fruit
- {
- };
-
- int main()
- {
- // creates a common fruit "factory"
- KDGenericFactory< Fruit > fruitPlantation;
- // registers the product "Apple"
- fruitPlantation.registerProduct< Apple >( "Apple" );
- // registers the product "Pear"
- fruitPlantation.registerProduct< Pear >( "Pear" );
-
- // lets create some stuff - here comes our tasty apple:
- Fruit* myApple = fruitPlantation.create( "Apple" );
-
- // and a pear, please:
- Fruit* myPear = fruitPlantation.create( "Pear" );
-
- // ohh - that doesn't work, returns a null pointer:
- Fruit* myCherry = fruitPlantation.create( "Cherry" );
- }
- \endcode
-*/
-
-/*!
- \fn KDGenericFactory::~KDGenericFactory()
-
- Destroys the generic factory.
-*/
-
-/*!
- \typedef KDGenericFactory::FactoryFunction
-
- This typedef defines a factory function producing an object of type T_Product.
-*/
-
-/*!
- \typedef KDGenericFactory::FactoryFunctionWithArg
-
- This typedef defines a factory function producing an object of type T_Product
- with the arguments specified by \a arg.
-*/
-
-/*!
- \fn KDGenericFactory::registerProduct( const T_Identifier& name )
-
- Registers a product of the type T, identified by \a name in the factory.
- Any type with the same name gets unregistered.
-
- If a product was registered via this method, it will be created using its
- default constructor.
-*/
-
-/*!
- \fn KDGenericFactory::registerProductWithArg(const T_Identifier &name)
-
- Registers a product of the type T, identified by \a name, with arguments.
- Any type with the same name gets unregistered.
-
- If a product was registered via this method, it will be created using its
- default constructor.
-*/
-
-/*!
- \fn KDGenericFactory::create( const T_Identifier& name ) const
-
- Creates and returns a product of the type T identified by \a name.
- Ownership of the product is transferred to the caller.
-*/
-
-/*!
- \fn KDGenericFactory::createWithArg(const T_Identifier &name, const T_Argument &arg) const
-
- Creates and returns a product of the type T identified by \a name with the
- arguments specified by \a arg.
- Ownership of the product is transferred to the caller.
-*/
diff --git a/src/libs/kdtools/kdgenericfactory.h b/src/libs/kdtools/kdgenericfactory.h
deleted file mode 100644
index d1a3e2954..000000000
--- a/src/libs/kdtools/kdgenericfactory.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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://www.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$
-**
-****************************************************************************/
-
-#ifndef KDTOOLS__KDGENERICFACTORY_H
-#define KDTOOLS__KDGENERICFACTORY_H
-
-#include <kdtoolsglobal.h>
-
-#include <QtCore/QHash>
-
-template <typename T_Product, typename T_Identifier = QString, typename T_Argument = QString>
-class KDGenericFactory
-{
-public:
- virtual ~KDGenericFactory() {}
-
- typedef T_Product *(*FactoryFunction)();
- typedef T_Product *(*FactoryFunctionWithArg)(const T_Argument &arg);
-
- template <typename T>
- void registerProduct(const T_Identifier &name)
- {
-#ifdef Q_CC_MSVC
- FactoryFunction function = &KDGenericFactory::create<T>;
-#else // compile fix for old gcc
- FactoryFunction function = &create<T>;
-#endif
- map.insert(name, function);
- }
-
- T_Product *create(const T_Identifier &name) const
- {
- const typename QHash<T_Identifier, FactoryFunction>::const_iterator it = map.find(name);
- if (it == map.end())
- return 0;
- return (*it)();
- }
-
- template <typename T>
- void registerProductWithArg(const T_Identifier &name)
- {
-#ifdef Q_CC_MSVC
- FactoryFunctionWithArg function = &KDGenericFactory::create<T>;
-#else // compile fix for old gcc
- FactoryFunctionWithArg function = &create<T>;
-#endif
- map2.insert(name, function);
- }
-
- T_Product *createWithArg(const T_Identifier &name, const T_Argument &arg) const
- {
- const typename QHash<T_Identifier, FactoryFunctionWithArg>::const_iterator it = map2.find(name);
- if (it == map2.end())
- return 0;
- return (*it)(arg);
- }
-
-private:
- template <typename T>
- static T_Product *create()
- {
- return new T;
- }
-
- template <typename T>
- static T_Product *create(const T_Argument &arg)
- {
- return new T(arg);
- }
-
- QHash<T_Identifier, FactoryFunction> map;
- QHash<T_Identifier, FactoryFunctionWithArg> map2;
-};
-
-#endif
diff --git a/src/libs/kdtools/kdsysinfo_win.cpp b/src/libs/kdtools/kdsysinfo_win.cpp
index 2bd1a32d4..ea209ed95 100644
--- a/src/libs/kdtools/kdsysinfo_win.cpp
+++ b/src/libs/kdtools/kdsysinfo_win.cpp
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#include "kdsysinfo.h"
+#include "sysinfo.h"
#include <QLibrary>
#include <QStringList>
diff --git a/src/libs/kdtools/kdtools.pri b/src/libs/kdtools/kdtools.pri
index 520426096..eaa391e0f 100644
--- a/src/libs/kdtools/kdtools.pri
+++ b/src/libs/kdtools/kdtools.pri
@@ -5,53 +5,54 @@ DEFINES += BUILD_SHARED_KDTOOLS
FORMS += $$PWD/authenticationdialog.ui
HEADERS += $$PWD/kdtoolsglobal.h \
- $$PWD/kdjob.h \
- $$PWD/kdgenericfactory.h \
- $$PWD/kdselfrestarter.h \
- $$PWD/kdrunoncechecker.h \
- $$PWD/kdlockfile.h \
- $$PWD/kdsysinfo.h
-
-SOURCES += $$PWD/kdjob.cpp \
- $$PWD/kdselfrestarter.cpp \
- $$PWD/kdrunoncechecker.cpp \
- $$PWD/kdlockfile.cpp \
- $$PWD/kdsysinfo.cpp
-
-
-HEADERS += $$PWD/kdupdater.h \
- $$PWD/kdupdaterapplication.h \
- $$PWD/kdupdaterfiledownloader.h \
- $$PWD/kdupdaterfiledownloader_p.h \
- $$PWD/kdupdaterfiledownloaderfactory.h \
- $$PWD/kdupdaterpackagesinfo.h \
- $$PWD/kdupdaterupdate.h \
- $$PWD/kdupdaterupdateoperation.h \
- $$PWD/kdupdaterupdateoperationfactory.h \
- $$PWD/kdupdaterupdateoperations.h \
- $$PWD/kdupdaterupdatesourcesinfo.h \
- $$PWD/kdupdatertask.h \
- $$PWD/kdupdaterupdatefinder.h \
- $$PWD/kdupdaterupdatesinfo_p.h \
+ $$PWD/job.h \
+ $$PWD/genericfactory.h \
+ $$PWD/selfrestarter.h \
+ $$PWD/runoncechecker.h \
+ $$PWD/lockfile.h \
+ $$PWD/sysinfo.h
+
+SOURCES += $$PWD/job.cpp \
+ $$PWD/selfrestarter.cpp \
+ $$PWD/runoncechecker.cpp \
+ $$PWD/lockfile.cpp \
+ $$PWD/sysinfo.cpp
+
+
+HEADERS += $$PWD/updater.h \
+ $$PWD/filedownloader.h \
+ $$PWD/filedownloader_p.h \
+ $$PWD/filedownloaderfactory.h \
+ $$PWD/localpackagehub.h \
+ $$PWD/update.h \
+ $$PWD/updateoperation.h \
+ $$PWD/updateoperationfactory.h \
+ $$PWD/updateoperations.h \
+ $$PWD/task.h \
+ $$PWD/updatefinder.h \
+ $$PWD/updatesinfo_p.h \
$$PWD/environment.h \
- $$PWD/kdupdaterupdatesinfodata_p.h
-
-SOURCES += $$PWD/kdupdaterapplication.cpp \
- $$PWD/kdupdaterfiledownloader.cpp \
- $$PWD/kdupdaterfiledownloaderfactory.cpp \
- $$PWD/kdupdaterpackagesinfo.cpp \
- $$PWD/kdupdaterupdate.cpp \
- $$PWD/kdupdaterupdateoperation.cpp \
- $$PWD/kdupdaterupdateoperationfactory.cpp \
- $$PWD/kdupdaterupdateoperations.cpp \
- $$PWD/kdupdaterupdatesourcesinfo.cpp \
- $$PWD/kdupdatertask.cpp \
- $$PWD/kdupdaterupdatefinder.cpp \
- $$PWD/kdupdaterupdatesinfo.cpp \
+ $$PWD/updatesinfodata_p.h
+
+SOURCES += $$PWD/filedownloader.cpp \
+ $$PWD/filedownloaderfactory.cpp \
+ $$PWD/localpackagehub.cpp \
+ $$PWD/update.cpp \
+ $$PWD/updateoperation.cpp \
+ $$PWD/updateoperationfactory.cpp \
+ $$PWD/updateoperations.cpp \
+ $$PWD/task.cpp \
+ $$PWD/updatefinder.cpp \
+ $$PWD/updatesinfo.cpp \
$$PWD/environment.cpp
-unix:SOURCES += $$PWD/kdlockfile_unix.cpp
-win32:SOURCES += $$PWD/kdlockfile_win.cpp
-win32:SOURCES += $$PWD/kdsysinfo_win.cpp
-macx:SOURCES += $$PWD/kdsysinfo_mac.cpp
-unix:!macx:SOURCES += $$PWD/kdsysinfo_x11.cpp
+win32 {
+ SOURCES += $$PWD/lockfile_win.cpp \
+ $$PWD/kdsysinfo_win.cpp
+}
+
+unix {
+ SOURCES += $$PWD/lockfile_unix.cpp
+ osx: SOURCES += $$PWD/sysinfo_mac.cpp
+ else: SOURCES += $$PWD/sysinfo_x11.cpp
+}
diff --git a/src/libs/kdtools/kdtoolsglobal.h b/src/libs/kdtools/kdtoolsglobal.h
index 6cf288828..731df4a21 100644
--- a/src/libs/kdtools/kdtoolsglobal.h
+++ b/src/libs/kdtools/kdtoolsglobal.h
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#ifndef KDTOOLS_KDTOOLSGLOBAL_H
-#define KDTOOLS_KDTOOLSGLOBAL_H
+#ifndef KDTOOLSGLOBAL_H
+#define KDTOOLSGLOBAL_H
#include <QtCore/QtGlobal>
@@ -46,5 +46,5 @@
# define KDTOOLS_EXPORT
#endif // KDTOOLS_SHARED
-#endif // KDTOOLS_KDTOOLSGLOBAL_H
+#endif // KDTOOLSGLOBAL_H
diff --git a/src/libs/kdtools/kdupdaterapplication.cpp b/src/libs/kdtools/kdupdaterapplication.cpp
deleted file mode 100644
index ec534fafb..000000000
--- a/src/libs/kdtools/kdupdaterapplication.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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://www.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 "kdupdaterapplication.h"
-#include "kdupdaterpackagesinfo.h"
-#include "kdupdaterupdatesourcesinfo.h"
-
-#include <QCoreApplication>
-#include <QDebug>
-#include <QDir>
-
-using namespace KDUpdater;
-
-/*!
- \inmodule kdupdater
- \namespace KDUpdater
- \brief The KDUpdater classes provide functions to automatically detect
- updates to applications, to retrieve them from external repositories, and to
- install them.
-
- KDUpdater classes are a fork of KDAB's general
- \l{http://docs.kdab.com/kdtools/2.2.2/group__kdupdater.html}{KDUpdater module}.
-*/
-
-/*!
- \class KDUpdater::ConfigurationInterface
- \inmodule kdupdater
- \brief The ConfigurationInterface class provides an interface for configuring
- an application.
-*/
-
-/*!
- \fn KDUpdater::ConfigurationInterface::~ConfigurationInterface()
- Destroys the configuration interface.
-*/
-
-/*!
- \fn KDUpdater::ConfigurationInterface::value(const QString &key) const
- Returns the value of the key \a key.
-*/
-
-/*!
- \fn KDUpdater::ConfigurationInterface::setValue(const QString &key, const QVariant &value)
- Sets the value \a value for the key \a key.
-*/
-
-/*!
- \class KDUpdater::Application
- \inmodule kdupdater
- \brief The Application class represents an application that can be updated.
-
- A KDUpdater application is an application that interacts with one or more update servers and
- downloads or installs updates. This class helps in describing an application in terms of:
- \list
- \li Application Directory
- \li Installation information XML file name and its corresponding
- KDUpdater::PackagesInfo object
- \li Update sources XML file name and its corresponding KDUpdater::UpdateSourcesInfo object
- \endlist
-
- User can also retrieve some information from this class:
- \list
- \li Application name
- \li Application version
- \endlist
-*/
-
-struct Application::ApplicationData
-{
- explicit ApplicationData(ConfigurationInterface *config) :
- packagesInfo(0),
- updateSourcesInfo(0),
- configurationInterface(config ? config : new ConfigurationInterface)
- {
- const QStringList oldFiles = configurationInterface->value(QLatin1String("FilesForDelayedDeletion")).toStringList();
- Q_FOREACH(const QString &i, oldFiles) { //TODO this should happen asnyc and report errors, I guess
- QFile f(i);
- if (f.exists() && !f.remove()) {
- qWarning("Could not delete file %s: %s", qPrintable(i), qPrintable(f.errorString()));
- filesForDelayedDeletion << i; // try again next time
- }
- }
- configurationInterface->setValue(QLatin1String("FilesForDelayedDeletion"), filesForDelayedDeletion);
- }
-
- ~ApplicationData()
- {
- delete packagesInfo;
- delete updateSourcesInfo;
- delete configurationInterface;
- }
-
- static Application *instance;
-
- QString applicationDirectory;
- PackagesInfo *packagesInfo;
- UpdateSourcesInfo *updateSourcesInfo;
- QStringList filesForDelayedDeletion;
- ConfigurationInterface *configurationInterface;
-};
-
-Application *Application::ApplicationData::instance = 0;
-
-/*!
- Constructs an application with the parent \a p and configuration class \a config.
-*/
-Application::Application(ConfigurationInterface* config, QObject* p) : QObject(p)
-{
- d = new Application::ApplicationData( config );
- d->packagesInfo = new PackagesInfo(this);
- d->updateSourcesInfo = new UpdateSourcesInfo(this);
-
- setApplicationDirectory( QCoreApplication::applicationDirPath() );
-
- ApplicationData::instance = this;
-}
-
-/*!
- Destroys the application.
-*/
-Application::~Application()
-{
- if (this == ApplicationData::instance)
- ApplicationData::instance = 0;
- delete d;
-}
-
-/*!
- Returns a previously created application instance.
-*/
-Application *Application::instance()
-{
- return ApplicationData::instance;
-}
-
-/*!
- Sets the application directory path directory to \a dir. The installation information and
- update sources XML files found in the new application directory will be used.
-*/
-void Application::setApplicationDirectory(const QString &dir)
-{
- if (d->applicationDirectory == dir)
- return;
-
- QDir dirObj(dir);
-
- // FIXME: Perhaps we should check whether dir exists on the local file system or not
- d->applicationDirectory = dirObj.absolutePath();
- setPackagesXMLFileName(QString::fromLatin1("%1/Packages.xml").arg(dir));
- setUpdateSourcesXMLFileName(QString::fromLatin1("%1/UpdateSources.xml").arg(dir));
-}
-
-/*!
- Returns the path to the application directory.
-*/
-QString Application::applicationDirectory() const
-{
- return d->applicationDirectory;
-}
-
-/*!
- Returns the application name. By default, QCoreApplication::applicationName() is returned.
-*/
-QString Application::applicationName() const
-{
- if (d->packagesInfo->isValid())
- return d->packagesInfo->applicationName();
-
- return QCoreApplication::applicationName();
-}
-
-/*!
- Returns the application version.
-*/
-QString Application::applicationVersion() const
-{
- if (d->packagesInfo->isValid())
- return d->packagesInfo->applicationVersion();
-
- return QString();
-}
-
-/*!
- Adds the \a name, \a title, \a description, \a url, and \a priority of the
- update source to this class.
-
- \sa KDUpdater::UpdateSourceInfo
- \sa KDUpdater::UpdateSourcesInfo
-*/
-void Application::addUpdateSource(const QString &name, const QString &title,
- const QString &description, const QUrl &url, int priority)
-{
- UpdateSourceInfo info;
- info.name = name;
- info.title = title;
- info.description = description;
- info.url = url;
- info.priority = priority;
- d->updateSourcesInfo->addUpdateSourceInfo(info);
-}
-
-
-/*!
- Sets the file name of the installation information XML file for this application to \a fileName.
- By default, this is assumed to be Packages.xml in the application directory.
-
- \sa KDUpdater::PackagesInfo::setFileName()
-*/
-void Application::setPackagesXMLFileName(const QString &fileName)
-{
- d->packagesInfo->setFileName(fileName);
-}
-
-/*!
- Returns the installation information XML file name.
-*/
-QString Application::packagesXMLFileName() const
-{
- return d->packagesInfo->fileName();
-}
-
-/*!
- Returns the KDUpdater::PackagesInfo object associated with this application.
-*/
-PackagesInfo* Application::packagesInfo() const
-{
- return d->packagesInfo;
-}
-
-/*!
- Sets \a fileName as the file name of the update sources XML file for this
- application. By default, this is assumed to be UpdateSources.xml in the
- application directory.
-
- \sa KDUpdater::UpdateSourcesInfo::setFileName()
-*/
-void Application::setUpdateSourcesXMLFileName(const QString &fileName)
-{
- d->updateSourcesInfo->setFileName(fileName);
-}
-
-/*!
- Returns the update sources XML file name.
-*/
-QString Application::updateSourcesXMLFileName() const
-{
- return d->updateSourcesInfo->fileName();
-}
-
-/*!
- Returns the KDUpdater::UpdateSourcesInfo object associated with this application.
-*/
-UpdateSourcesInfo* Application::updateSourcesInfo() const
-{
- return d->updateSourcesInfo;
-}
-
-/*!
- Prints the error code \a errorCode and error message specified by \a error.
-*/
-void Application::printError(int errorCode, const QString &error)
-{
- qDebug() << errorCode << error;
-}
-
-/*!
- Returns a list of files that are scheduled for delayed deletion.
-*/
-QStringList Application::filesForDelayedDeletion() const
-{
- return d->filesForDelayedDeletion;
-}
-
-/*!
- Schedules \a files for delayed deletion.
-*/
-void Application::addFilesForDelayedDeletion(const QStringList &files)
-{
- d->filesForDelayedDeletion << files;
- d->configurationInterface->setValue(QLatin1String("FilesForDelayedDeletion"), d->filesForDelayedDeletion);
-}
diff --git a/src/libs/kdtools/kdupdaterapplication.h b/src/libs/kdtools/kdupdaterapplication.h
deleted file mode 100644
index 8726bc8b3..000000000
--- a/src/libs/kdtools/kdupdaterapplication.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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://www.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$
-**
-****************************************************************************/
-
-#ifndef KD_UPDATER_APPLICATION_H
-#define KD_UPDATER_APPLICATION_H
-
-#include "kdtoolsglobal.h"
-
-#include <QSettings>
-
-namespace KDUpdater {
-
-class PackagesInfo;
-class UpdateSourcesInfo;
-
-class ConfigurationInterface
-{
-public:
- virtual ~ConfigurationInterface() {}
- virtual QVariant value(const QString &key) const
- {
- QSettings settings;
- settings.beginGroup(QLatin1String("KDUpdater"));
- return settings.value(key);
- }
-
- virtual void setValue(const QString &key, const QVariant &value)
- {
- QSettings settings;
- settings.beginGroup(QLatin1String("KDUpdater"));
- settings.setValue(key, value);
- }
-};
-
-class KDTOOLS_EXPORT Application : public QObject
-{
- Q_OBJECT
-
-public:
- explicit Application(ConfigurationInterface *config = 0, QObject *parent = 0);
- ~Application();
-
- static Application *instance();
-
- void setApplicationDirectory(const QString &dir);
- QString applicationDirectory() const;
-
- QString applicationName() const;
- QString applicationVersion() const;
-
- void setPackagesXMLFileName(const QString &fileName);
- QString packagesXMLFileName() const;
- PackagesInfo *packagesInfo() const;
-
- void addUpdateSource(const QString &name, const QString &title,
- const QString &description, const QUrl &url, int priority = -1);
-
- void setUpdateSourcesXMLFileName(const QString &fileName);
- QString updateSourcesXMLFileName() const;
- UpdateSourcesInfo *updateSourcesInfo() const;
-
- QStringList filesForDelayedDeletion() const;
- void addFilesForDelayedDeletion(const QStringList &files);
-
-public Q_SLOTS:
- void printError(int errorCode, const QString &error);
-
-private:
- struct ApplicationData;
- ApplicationData *d;
-};
-
-} // namespace KDUpdater
-
-#endif // KD_UPDATER_APPLICATION_H
diff --git a/src/libs/kdtools/kdupdaterupdatesourcesinfo.cpp b/src/libs/kdtools/kdupdaterupdatesourcesinfo.cpp
deleted file mode 100644
index a434654db..000000000
--- a/src/libs/kdtools/kdupdaterupdatesourcesinfo.cpp
+++ /dev/null
@@ -1,480 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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://www.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 "kdupdaterupdatesourcesinfo.h"
-
-#include <QtXml/QDomElement>
-#include <QtXml/QDomDocument>
-#include <QtXml/QDomText>
-#include <QtXml/QDomCDATASection>
-#include <QFileInfo>
-#include <QFile>
-#include <QTextStream>
-
-using namespace KDUpdater;
-
-/*!
- \inmodule kdupdater
- \class KDUpdater::UpdateSourcesInfo
- \brief The UpdateSourcesInfo class provides access to information about the update sources set
- for the application.
-
- An update source is a repository that contains updates applicable for the application.
- Applications can download updates from the update source and install them locally.
-
- Each application can have one or more update sources from which it can download updates.
- Information about update source is stored in a file called UpdateSources.xml. This class helps
- access and modify the UpdateSources.xml file.
-
- The complete file name of the UpdateSources.xml file can be specified via the setFileName()
- method. The class then parses the XML file and makes available information contained in
- that XML file through an easy to use API. You can:
-
- \list
- \li Get update sources information via the updateSourceInfoCount() and updateSourceInfo()
- methods.
- \li Add or remove update source information via the addUpdateSourceInfo() and
- removeUpdateSourceInfo() methods.
- \endlist
-
- The class emits appropriate signals to inform listeners about changes in the update application.
-*/
-
-/*!
- \fn KDUpdater::operator==(const UpdateSourceInfo &lhs, const UpdateSourceInfo &rhs)
-
- Returns \c true if \a lhs and \a rhs are equal; otherwise returns \c false.
-*/
-
-/*!
- \fn KDUpdater::operator!=(const UpdateSourceInfo &lhs, const UpdateSourceInfo &rhs)
-
- Returns \c true if \a lhs and \a rhs are different; otherwise returns \c false.
-*/
-
-/*!
- \enum UpdateSourcesInfo::Error
- Error codes related to retrieving update sources.
-
- \value NoError No error occurred.
- \value NotYetReadError The update source information was not parsed yet from the
- XML file.
- \value CouldNotReadSourceFileError The specified update source file could not be read
- (does not exist or is not readable).
- \value InvalidXmlError The source file contains invalid XML.
- \value InvalidContentError The source file contains valid XML, but does not match the
- expected format for source descriptions.
- \value CouldNotSaveChangesError Changes made to the object could not be saved back to the
- source file.
-*/
-
-/*!
- \fn void UpdateSourcesInfo::reset()
-
- This signal is emitted whenever the contents of this UpdateSourcesInfo are refreshed, usually
- from within the refresh() slot.
-*/
-
-/*!
- \fn void UpdateSourcesInfo::updateSourceInfoAdded(const UpdateSourceInfo &info)
-
- This signal is emitted when \c UpdateSourceInfo \a info is added.
-*/
-
-/*!
- \fn void UpdateSourcesInfo::updateSourceInfoRemoved(const UpdateSourceInfo &info)
-
- This signal is emitted when \c UpdateSourceInfo \a info is removed.
-*/
-
-struct UpdateSourceInfoPriorityHigherThan
-{
- bool operator()(const UpdateSourceInfo &lhs, const UpdateSourceInfo &rhs) const
- {
- return lhs.priority > rhs.priority;
- }
-};
-
-
-struct UpdateSourcesInfo::UpdateSourcesInfoData
-{
- UpdateSourcesInfoData()
- : modified(false)
- , error(UpdateSourcesInfo::NotYetReadError)
- {}
-
- bool modified;
- UpdateSourcesInfo::Error error;
-
- QString fileName;
- QString errorMessage;
- QList<UpdateSourceInfo> updateSourceInfoList;
-
- void addUpdateSourceFrom(const QDomElement &element);
- void addChildElement(QDomDocument &doc, QDomElement &parentE, const QString &tagName,
- const QString &text, bool htmlText = false);
- void setInvalidContentError(const QString &detail);
- void clearError();
- void saveChanges();
-};
-
-void UpdateSourcesInfo::UpdateSourcesInfoData::setInvalidContentError(const QString &detail)
-{
- error = UpdateSourcesInfo::InvalidContentError;
- errorMessage = tr("%1 contains invalid content: %2").arg(fileName, detail);
-}
-
-void UpdateSourcesInfo::UpdateSourcesInfoData::clearError()
-{
- error = UpdateSourcesInfo::NoError;
- errorMessage.clear();
-}
-
-/*!
- \internal
-*/
-UpdateSourcesInfo::UpdateSourcesInfo(QObject *parent)
- : QObject(parent)
- , d(new UpdateSourcesInfo::UpdateSourcesInfoData)
-{
-}
-
-/*!
- \internal
-*/
-UpdateSourcesInfo::~UpdateSourcesInfo()
-{
- d->saveChanges();
-}
-
-/*!
- Returns \c true if UpdateSourcesInfo is valid; otherwise returns \c false.
- You can use the errorString() method to receive a descriptive error message.
-*/
-bool UpdateSourcesInfo::isValid() const
-{
- return d->error == NoError;
-}
-
-/*!
- Returns a human-readable description of the last error that occurred.
-*/
-QString UpdateSourcesInfo::errorString() const
-{
- return d->errorMessage;
-}
-
-/*!
- Returns the error that was found during the processing of the update sources XML file. If no
- error was found, returns NoError.
-*/
-UpdateSourcesInfo::Error UpdateSourcesInfo::error() const
-{
- return d->error;
-}
-
-/*!
- Returns the modified state of this object. The modified state defines if there where
- modifications done to the update-sources that need to be written to the updates XML file
- that will restore the update-sources on the next run.
-*/
-bool UpdateSourcesInfo::isModified() const
-{
- return d->modified;
-}
-
-/*!
- Sets the modified state of the object to \a modified.
-*/
-void UpdateSourcesInfo::setModified(bool modified)
-{
- d->modified = modified;
-}
-
-/*!
- Sets the complete file name of the update sources XML file to \a fileName. The function also
- issues a call to refresh() to reload update sources from the XML file.
-
- \sa KDUpdater::Application::setUpdateSourcesXMLFileName()
-*/
-void UpdateSourcesInfo::setFileName(const QString &fileName)
-{
- if (d->fileName == fileName)
- return;
-
- d->fileName = fileName;
- refresh(); // load new file
-}
-
-/*!
- Returns the name of the update sources XML file that this class refers to.
-*/
-QString UpdateSourcesInfo::fileName() const
-{
- return d->fileName;
-}
-
-/*!
- Returns the number of update source info structures contained in this class.
-*/
-int UpdateSourcesInfo::updateSourceInfoCount() const
-{
- return d->updateSourceInfoList.count();
-}
-
-/*!
- Returns the update source info structure at \a index. If an invalid index is passed, the
- function returns a \l{default-constructed value}.
-*/
-UpdateSourceInfo UpdateSourcesInfo::updateSourceInfo(int index) const
-{
- if (index < 0 || index >= d->updateSourceInfoList.count())
- return UpdateSourceInfo();
-
- return d->updateSourceInfoList[index];
-}
-
-/*!
- Adds the given update source info \a info to this class. Upon successful addition, the class
- emits an updateSourceInfoAdded() signal.
-*/
-void UpdateSourcesInfo::addUpdateSourceInfo(const UpdateSourceInfo &info)
-{
- if (d->updateSourceInfoList.contains(info))
- return;
- d->updateSourceInfoList.push_back(info);
- std::sort(d->updateSourceInfoList.begin(), d->updateSourceInfoList.end(), UpdateSourceInfoPriorityHigherThan());
- emit updateSourceInfoAdded(info);
- d->modified = true;
-}
-
-/*!
- Removes the given update source info \a info from this class. Upon successful removal, the class
- emits an updateSourceInfoRemoved() signal.
-*/
-void UpdateSourcesInfo::removeUpdateSourceInfo(const UpdateSourceInfo &info)
-{
- if (!d->updateSourceInfoList.contains(info))
- return;
- d->updateSourceInfoList.removeAll(info);
- emit updateSourceInfoRemoved(info);
- d->modified = true;
-}
-
-/*!
- Reloads the update source information from update sources XML file.
-*/
-void UpdateSourcesInfo::refresh()
-{
- d->saveChanges(); // save changes done in the previous file
- d->updateSourceInfoList.clear();
-
- QFile file(d->fileName);
-
- // if the file does not exist then we just skip the reading
- if (!file.exists()) {
- d->clearError();
- emit reset();
- return;
- }
-
- // Open the XML file
- if (!file.open(QFile::ReadOnly)) {
- d->errorMessage = tr("Could not read \"%1\"").arg(d->fileName);
- d->error = CouldNotReadSourceFileError;
- emit reset();
- return;
- }
-
- QDomDocument doc;
- QString parseErrorMessage;
- int parseErrorLine, parseErrorColumn;
- if (!doc.setContent(&file, &parseErrorMessage, &parseErrorLine, &parseErrorColumn)) {
- d->error = InvalidXmlError;
- d->errorMessage = tr("XML Parse error in %1 at %2, %3: %4").arg(d->fileName,
- QString::number(parseErrorLine), QString::number(parseErrorColumn), parseErrorMessage);
- emit reset();
- return;
- }
-
- // Now parse the XML file.
- const QDomElement rootE = doc.documentElement();
- if (rootE.tagName() != QLatin1String("UpdateSources")) {
- d->setInvalidContentError(tr("Root element %1 unexpected, should be \"UpdateSources\"").arg(rootE.tagName()));
- emit reset();
- return;
- }
-
- const QDomNodeList childNodes = rootE.childNodes();
- for (int i = 0; i < childNodes.count(); i++) {
- QDomElement childNodeE = childNodes.item(i).toElement();
- if ((!childNodeE.isNull()) && (childNodeE.tagName() == QLatin1String("UpdateSource")))
- d->addUpdateSourceFrom(childNodeE);
- }
-
- d->clearError();
- emit reset();
-}
-
-void UpdateSourcesInfo::UpdateSourcesInfoData::saveChanges()
-{
- if (!modified || fileName.isEmpty())
- return;
-
- const bool hadSaveError = (error == UpdateSourcesInfo::CouldNotSaveChangesError);
-
- QDomDocument doc;
- QDomElement rootE = doc.createElement(QLatin1String("UpdateSources"));
- doc.appendChild(rootE);
-
- foreach (const UpdateSourceInfo &info, updateSourceInfoList) {
- QDomElement infoE = doc.createElement(QLatin1String("UpdateSource"));
- rootE.appendChild(infoE);
- addChildElement(doc, infoE, QLatin1String("Name"), info.name);
- addChildElement(doc, infoE, QLatin1String("Title"), info.title);
- addChildElement(doc, infoE, QLatin1String("Description"), info.description,
- (info.description.length() && info.description.at(0) == QLatin1Char('<')));
- addChildElement(doc, infoE, QLatin1String("Url"), info.url.toString());
- }
-
- QFile file(fileName);
- if (!file.open(QFile::WriteOnly)) {
- error = UpdateSourcesInfo::CouldNotSaveChangesError;
- errorMessage = tr("Could not save changes to \"%1\": %2").arg(fileName, file.errorString());
- return;
- }
-
- QTextStream stream(&file);
- doc.save(stream, 2);
- stream.flush();
- file.close();
-
- if (file.error() != QFile::NoError) {
- error = UpdateSourcesInfo::CouldNotSaveChangesError;
- errorMessage = tr("Could not save changes to \"%1\": %2").arg(fileName, file.errorString());
- return;
- }
-
- //if there was a write error before, clear the error, as the write was successful now
- if (hadSaveError)
- clearError();
-
- modified = false;
-}
-
-void UpdateSourcesInfo::UpdateSourcesInfoData::addUpdateSourceFrom(const QDomElement &element)
-{
- if (element.tagName() != QLatin1String("UpdateSource"))
- return;
-
- const QDomNodeList childNodes = element.childNodes();
- if (!childNodes.count())
- return;
-
- UpdateSourceInfo info;
- for (int i = 0; i < childNodes.count(); ++i) {
- const QDomElement childNodeE = childNodes.item(i).toElement();
- if (childNodeE.isNull())
- continue;
-
- if (childNodeE.tagName() == QLatin1String("Name"))
- info.name = childNodeE.text();
- else if (childNodeE.tagName() == QLatin1String("Title"))
- info.title = childNodeE.text();
- else if (childNodeE.tagName() == QLatin1String("Description"))
- info.description = childNodeE.text();
- else if (childNodeE.tagName() == QLatin1String("Url"))
- info.url = childNodeE.text();
- }
- this->updateSourceInfoList.append(info);
-}
-
-void UpdateSourcesInfo::UpdateSourcesInfoData::addChildElement(QDomDocument &doc, QDomElement &parentE,
- const QString &tagName, const QString &text, bool htmlText)
-{
- QDomElement childE = doc.createElement(tagName);
- parentE.appendChild(childE);
- childE.appendChild(htmlText ? doc.createCDATASection(text) : doc.createTextNode(text));
-}
-
-/*!
- \inmodule kdupdater
- \class KDUpdater::UpdateSourceInfo
- \brief The UpdateSourceInfo class specifies a single update source.
-
- An update source is a repository that contains updates applicable for the application.
- This structure describes a single update source in terms of name, title, description,
- url, and priority.
-*/
-
-/*!
- \fn UpdateSourceInfo::UpdateSourceInfo()
-
- Constructs an empty update source info object. The object's priority is set to -1. All other
- class members are initialized using a \l{default-constructed value}.
-*/
-
-/*!
- \variable UpdateSourceInfo::name
- \brief The name of the update source.
-*/
-
-/*!
- \variable UpdateSourceInfo::title
- \brief The title of the update source.
-*/
-
-/*!
- \variable UpdateSourceInfo::description
- \brief The description of the update source.
-*/
-
-/*!
- \variable UpdateSourceInfo::url
- \brief The URL of the update source.
-*/
-
-/*!
- \variable UpdateSourceInfo::priority
- \brief The priority of the update source.
-*/
-
-namespace KDUpdater {
-
-bool operator== (const UpdateSourceInfo &lhs, const UpdateSourceInfo &rhs)
-{
- return lhs.name == rhs.name && lhs.title == rhs.title && lhs.description == rhs.description
- && lhs.url == rhs.url;
-}
-
-} // namespace KDUpdater
diff --git a/src/libs/kdtools/kdupdaterupdatesourcesinfo.h b/src/libs/kdtools/kdupdaterupdatesourcesinfo.h
deleted file mode 100644
index c01805f2c..000000000
--- a/src/libs/kdtools/kdupdaterupdatesourcesinfo.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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://www.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$
-**
-****************************************************************************/
-
-#ifndef KD_UPDATER_UPDATE_SOURCES_INFO_H
-#define KD_UPDATER_UPDATE_SOURCES_INFO_H
-
-#include "kdtoolsglobal.h"
-
-#include <QObject>
-#include <QVariant>
-#include <QUrl>
-
-namespace KDUpdater {
-
-struct KDTOOLS_EXPORT UpdateSourceInfo
-{
- UpdateSourceInfo() : priority(-1) { }
-
- QString name;
- QString title;
- QString description;
- QUrl url;
- int priority;
-};
-
-KDTOOLS_EXPORT bool operator==(const UpdateSourceInfo &lhs, const UpdateSourceInfo &rhs);
-
-inline bool operator!=(const UpdateSourceInfo &lhs, const UpdateSourceInfo &rhs)
-{
- return !operator==(lhs, rhs);
-}
-
-class KDTOOLS_EXPORT UpdateSourcesInfo : public QObject
-{
- Q_OBJECT
-
-public:
- ~UpdateSourcesInfo();
-
- enum Error
- {
- NoError = 0,
- NotYetReadError,
- CouldNotReadSourceFileError,
- InvalidXmlError,
- InvalidContentError,
- CouldNotSaveChangesError
- };
-
- bool isValid() const;
- QString errorString() const;
- Error error() const;
-
- bool isModified() const;
- void setModified(bool modified);
-
- void setFileName(const QString &fileName);
- QString fileName() const;
-
- int updateSourceInfoCount() const;
- UpdateSourceInfo updateSourceInfo(int index) const;
-
- void addUpdateSourceInfo(const UpdateSourceInfo &info);
- void removeUpdateSourceInfo(const UpdateSourceInfo &info);
-
-protected:
- friend class Application;
- explicit UpdateSourcesInfo(QObject *parent = 0);
-
-public Q_SLOTS:
- void refresh();
-
-Q_SIGNALS:
- void reset();
- void updateSourceInfoAdded(const UpdateSourceInfo &info);
- void updateSourceInfoRemoved(const UpdateSourceInfo &info);
-
-private:
- struct UpdateSourcesInfoData;
- QScopedPointer<UpdateSourcesInfoData> d;
-};
-
-} // namespace KDUpdater
-
-Q_DECLARE_METATYPE(KDUpdater::UpdateSourceInfo)
-
-#endif // KD_UPDATER_UPDATE_SOURCES_INFO_H
diff --git a/src/libs/kdtools/kdupdaterpackagesinfo.cpp b/src/libs/kdtools/localpackagehub.cpp
index c880b1d53..dc5ea32c7 100644
--- a/src/libs/kdtools/kdupdaterpackagesinfo.cpp
+++ b/src/libs/kdtools/localpackagehub.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
+** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -31,20 +32,21 @@
**
****************************************************************************/
-#include "kdupdaterpackagesinfo.h"
+#include "localpackagehub.h"
#include "globals.h"
+#include "constants.h"
+#include <QDomDocument>
+#include <QDomElement>
#include <QFileInfo>
-#include <QtXml/QDomDocument>
-#include <QtXml/QDomElement>
-#include <QVector>
using namespace KDUpdater;
+using namespace QInstaller;
/*!
\inmodule kdupdater
- \class KDUpdater::PackagesInfo
- \brief The PackagesInfo class provides access to information about packages installed on the
+ \class KDUpdater::LocalPackageHub
+ \brief The LocalPackageHub class provides access to information about packages installed on the
application side.
This class parses the \e {installation information} XML file specified via the setFileName()
@@ -55,14 +57,10 @@ using namespace KDUpdater;
\li Get information about the number of packages installed and their meta-data via the
packageInfoCount() and packageInfo() methods.
\endlist
-
- Instances of this class cannot be created. Each instance of KDUpdater::Application has one
- instance of this class associated with it. You can fetch a pointer to an instance of this class
- for an application via the KDUpdater::Application::packagesInfo() method.
*/
/*!
- \enum PackagesInfo::Error
+ \enum LocalPackageHub::Error
Error codes related to retrieving information about installed packages:
\value NoError No error occurred.
@@ -76,64 +74,71 @@ using namespace KDUpdater;
descriptions.
*/
-struct PackagesInfo::PackagesInfoData
+struct LocalPackageHub::PackagesInfoData
{
PackagesInfoData() :
- error(PackagesInfo::NotYetReadError),
+ error(LocalPackageHub::NotYetReadError),
modified(false)
{}
QString errorMessage;
- PackagesInfo::Error error;
+ LocalPackageHub::Error error;
QString fileName;
QString applicationName;
QString applicationVersion;
bool modified;
- QVector<PackageInfo> packageInfoList;
+ QMap<QString, LocalPackage> m_packageInfoMap;
void addPackageFrom(const QDomElement &packageE);
void setInvalidContentError(const QString &detail);
};
-void PackagesInfo::PackagesInfoData::setInvalidContentError(const QString &detail)
+void LocalPackageHub::PackagesInfoData::setInvalidContentError(const QString &detail)
{
- error = PackagesInfo::InvalidContentError;
+ error = LocalPackageHub::InvalidContentError;
errorMessage = tr("%1 contains invalid content: %2").arg(fileName, detail);
}
/*!
- \internal
+ Constructs a local package hub. To fully setup the class you have to call setFileName().
+
+ \sa setFileName
*/
-PackagesInfo::PackagesInfo(QObject *parent)
- : QObject(parent),
- d(new PackagesInfoData())
+LocalPackageHub::LocalPackageHub()
+ : d(new PackagesInfoData())
{
}
/*!
- \internal
+ Destructor
*/
-PackagesInfo::~PackagesInfo()
+LocalPackageHub::~LocalPackageHub()
{
writeToDisk();
delete d;
}
/*!
- Returns \c true if PackagesInfo is valid; otherwise returns \c false. You
+ Returns \c true if LocalPackageHub is valid; otherwise returns \c false. You
can use the errorString() method to receive a descriptive error message.
*/
-bool PackagesInfo::isValid() const
+bool LocalPackageHub::isValid() const
+{
+ return d->error <= NotYetReadError;
+}
+
+/*!
+ Returns a list of all local installed packages.
+*/
+QStringList LocalPackageHub::packageNames() const
{
- if (!d->fileName.isEmpty())
- return d->error <= NotYetReadError;
- return d->error == NoError;
+ return d->m_packageInfoMap.keys();
}
/*!
Returns a human-readable description of the last error that occurred.
*/
-QString PackagesInfo::errorString() const
+QString LocalPackageHub::errorString() const
{
return d->errorMessage;
}
@@ -142,7 +147,7 @@ QString PackagesInfo::errorString() const
Returns the error that was found during the processing of the installation information XML file.
If no error was found, returns NoError.
*/
-PackagesInfo::Error PackagesInfo::error() const
+LocalPackageHub::Error LocalPackageHub::error() const
{
return d->error;
}
@@ -150,10 +155,8 @@ PackagesInfo::Error PackagesInfo::error() const
/*!
Sets the complete file name of the installation information XML file to \a fileName. The function
also issues a call to refresh() to reload installation information from the XML file.
-
- \sa KDUpdater::Application::setPackagesXMLFileName()
*/
-void PackagesInfo::setFileName(const QString &fileName)
+void LocalPackageHub::setFileName(const QString &fileName)
{
if (d->fileName == fileName)
return;
@@ -165,7 +168,7 @@ void PackagesInfo::setFileName(const QString &fileName)
/*!
Returns the name of the installation information XML file that this class refers to.
*/
-QString PackagesInfo::fileName() const
+QString LocalPackageHub::fileName() const
{
return d->fileName;
}
@@ -174,7 +177,7 @@ QString PackagesInfo::fileName() const
Sets the application name to \a name. By default, this is the name specified in the
\c <ApplicationName> element of the installation information XML file.
*/
-void PackagesInfo::setApplicationName(const QString &name)
+void LocalPackageHub::setApplicationName(const QString &name)
{
d->applicationName = name;
}
@@ -182,7 +185,7 @@ void PackagesInfo::setApplicationName(const QString &name)
/*!
Returns the application name.
*/
-QString PackagesInfo::applicationName() const
+QString LocalPackageHub::applicationName() const
{
return d->applicationName;
}
@@ -191,7 +194,7 @@ QString PackagesInfo::applicationName() const
Sets the application version to \a version. By default, this is the version specified in the
\c <ApplicationVersion> element of the installation information XML file.
*/
-void PackagesInfo::setApplicationVersion(const QString &version)
+void LocalPackageHub::setApplicationVersion(const QString &version)
{
d->applicationVersion = version;
}
@@ -199,51 +202,34 @@ void PackagesInfo::setApplicationVersion(const QString &version)
/*!
Returns the application version.
*/
-QString PackagesInfo::applicationVersion() const
+QString LocalPackageHub::applicationVersion() const
{
return d->applicationVersion;
}
/*!
- Returns the number of KDUpdater::PackageInfo objects contained in this class.
+ Returns the number of KDUpdater::LocalPackage objects contained in this class.
*/
-int PackagesInfo::packageInfoCount() const
+int LocalPackageHub::packageInfoCount() const
{
- return d->packageInfoList.count();
+ return d->m_packageInfoMap.count();
}
/*!
- Returns the package info structure at \a index. If an invalid index is passed, the
+ Returns the package info structure whose name is \a pkgName. If no such package was found, this
function returns a \l{default-constructed value}.
*/
-PackageInfo PackagesInfo::packageInfo(int index) const
-{
- if (index < 0 || index >= d->packageInfoList.count())
- return PackageInfo();
-
- return d->packageInfoList.at(index);
-}
-
-/*!
- Returns the index of the package whose name is \a pkgName. If no such package was found, this
- function returns -1.
-*/
-int PackagesInfo::findPackageInfo(const QString &pkgName) const
+LocalPackage LocalPackageHub::packageInfo(const QString &pkgName) const
{
- for (int i = 0; i < d->packageInfoList.count(); i++) {
- if (d->packageInfoList[i].name == pkgName)
- return i;
- }
-
- return -1;
+ return d->m_packageInfoMap.value(pkgName);
}
/*!
Returns all package info structures.
*/
-QVector<PackageInfo> PackagesInfo::packageInfos() const
+QList<LocalPackage> LocalPackageHub::packageInfos() const
{
- return d->packageInfoList;
+ return d->m_packageInfoMap.values();
}
/*!
@@ -251,12 +237,12 @@ QVector<PackageInfo> PackagesInfo::packageInfos() const
and applicationVersion() are lost after this function returns. The function emits a reset()
signal after completion.
*/
-void PackagesInfo::refresh()
+void LocalPackageHub::refresh()
{
// First clear internal variables
d->applicationName.clear();
d->applicationVersion.clear();
- d->packageInfoList.clear();
+ d->m_packageInfoMap.clear();
d->modified = false;
QFile file(d->fileName);
@@ -265,15 +251,13 @@ void PackagesInfo::refresh()
if (!file.exists()) {
d->error = NotYetReadError;
d->errorMessage = tr("The file %1 does not exist.").arg(d->fileName);
- emit reset();
return;
}
// Open Packages.xml
if (!file.open(QFile::ReadOnly)) {
d->error = CouldNotReadPackageFileError;
- d->errorMessage = tr("Could not open %1.").arg(d->fileName);
- emit reset();
+ d->errorMessage = tr("Cannot open %1.").arg(d->fileName);
return;
}
@@ -289,7 +273,6 @@ void PackagesInfo::refresh()
QString::number(parseErrorLine),
QString::number(parseErrorColumn),
parseErrorMessage);
- emit reset();
return;
}
file.close();
@@ -297,8 +280,8 @@ void PackagesInfo::refresh()
// Now populate information from the XML file.
QDomElement rootE = doc.documentElement();
if (rootE.tagName() != QLatin1String("Packages")) {
- d->setInvalidContentError(tr("Root element %1 unexpected, should be 'Packages'.").arg(rootE.tagName()));
- emit reset();
+ d->setInvalidContentError(tr("Root element %1 unexpected, should be 'Packages'.")
+ .arg(rootE.tagName()));
return;
}
@@ -319,74 +302,65 @@ void PackagesInfo::refresh()
d->error = NoError;
d->errorMessage.clear();
- emit reset();
}
/*!
Marks the package specified by \a name as installed. Sets the values of
- \a version, \a title, \a description, \a dependencies, \a forcedInstallation,
- \a virtualComp, \a uncompressedSize, and \a inheritVersionFrom for the
- package.
-
- Returns \c true if the installation information was modified.
-
-*/
-bool PackagesInfo::installPackage(const QString &name, const QString &version,
- const QString &title, const QString &description,
- const QStringList &dependencies, bool forcedInstallation,
- bool virtualComp, quint64 uncompressedSize,
- const QString &inheritVersionFrom)
+ \a version,
+ \a title,
+ \a description,
+ \a dependencies,
+ \a autoDependencies,
+ \a forcedInstallation,
+ \a virtualComp,
+ \a uncompressedSize,
+ \a inheritVersionFrom,
+ and \a checkable for the package.
+*/
+void LocalPackageHub::addPackage(const QString &name,
+ const QString &version,
+ const QString &title,
+ const QString &description,
+ const QStringList &dependencies,
+ const QStringList &autoDependencies,
+ bool forcedInstallation,
+ bool virtualComp,
+ quint64 uncompressedSize,
+ const QString &inheritVersionFrom,
+ bool checkable)
{
- if (findPackageInfo(name) != -1)
- return updatePackage(name, version, QDate::currentDate());
-
- PackageInfo info;
- info.name = name;
- info.version = version;
- info.inheritVersionFrom = inheritVersionFrom;
- info.installDate = QDate::currentDate();
- info.title = title;
- info.description = description;
- info.dependencies = dependencies;
- info.forcedInstallation = forcedInstallation;
- info.virtualComp = virtualComp;
- info.uncompressedSize = uncompressedSize;
- d->packageInfoList.push_back(info);
- d->modified = true;
- return true;
-}
-
-/*!
- Updates the package specified by \a name and sets its version to \a version
- and the last update date to \a date.
-
- Returns \c false if the package is not found.
-*/
-bool PackagesInfo::updatePackage(const QString &name, const QString &version, const QDate &date)
-{
- int index = findPackageInfo(name);
-
- if (index == -1)
- return false;
-
- d->packageInfoList[index].version = version;
- d->packageInfoList[index].lastUpdateDate = date;
+ // TODO: This somewhat unexpected, remove?
+ if (d->m_packageInfoMap.contains(name)) {
+ // TODO: What about the other fields, update?
+ d->m_packageInfoMap[name].version = version;
+ d->m_packageInfoMap[name].lastUpdateDate = QDate::currentDate();
+ } else {
+ LocalPackage info;
+ info.name = name;
+ info.version = version;
+ info.inheritVersionFrom = inheritVersionFrom;
+ info.installDate = QDate::currentDate();
+ info.title = title;
+ info.description = description;
+ info.dependencies = dependencies;
+ info.autoDependencies = autoDependencies;
+ info.forcedInstallation = forcedInstallation;
+ info.virtualComp = virtualComp;
+ info.uncompressedSize = uncompressedSize;
+ info.checkable = checkable;
+ d->m_packageInfoMap.insert(name, info);
+ }
d->modified = true;
- return true;
}
/*!
- Removes the package specified by \a name.
-
- Returns \c false if the package is not found.
+ Removes the package specified by \a name. Returns \c false if the package is not found.
*/
-bool PackagesInfo::removePackage(const QString &name)
+bool LocalPackageHub::removePackage(const QString &name)
{
- const int index = findPackageInfo(name);
- if (index == -1)
+ if (d->m_packageInfoMap.remove(name) <= 0)
return false;
- d->packageInfoList.remove(index);
d->modified = true;
return true;
}
@@ -409,9 +383,9 @@ static void addTextChildHelper(QDomNode *node,
/*!
Writes the installation information file to disk.
*/
-void PackagesInfo::writeToDisk()
+void LocalPackageHub::writeToDisk()
{
- if (d->modified && (!d->packageInfoList.isEmpty() || QFile::exists(d->fileName))) {
+ if (d->modified && (!d->m_packageInfoMap.isEmpty() || QFile::exists(d->fileName))) {
QDomDocument doc;
QDomElement root = doc.createElement(QLatin1String("Packages")) ;
doc.appendChild(root);
@@ -419,11 +393,10 @@ void PackagesInfo::writeToDisk()
addTextChildHelper(&root, QLatin1String("ApplicationName"), d->applicationName);
addTextChildHelper(&root, QLatin1String("ApplicationVersion"), d->applicationVersion);
- Q_FOREACH (const PackageInfo &info, d->packageInfoList) {
+ Q_FOREACH (const LocalPackage &info, d->m_packageInfoMap) {
QDomElement package = doc.createElement(QLatin1String("Package"));
addTextChildHelper(&package, QLatin1String("Name"), info.name);
- addTextChildHelper(&package, QLatin1String("Pixmap"), info.pixmap);
addTextChildHelper(&package, QLatin1String("Title"), info.title);
addTextChildHelper(&package, QLatin1String("Description"), info.description);
if (info.inheritVersionFrom.isEmpty())
@@ -431,20 +404,23 @@ void PackagesInfo::writeToDisk()
else
addTextChildHelper(&package, QLatin1String("Version"), info.version,
QLatin1String("inheritVersionFrom"), info.inheritVersionFrom);
- addTextChildHelper(&package, QLatin1String("LastUpdateDate"), info.lastUpdateDate.toString(Qt::ISODate));
- addTextChildHelper(&package, QLatin1String("InstallDate"), info.installDate.toString(Qt::ISODate));
- addTextChildHelper(&package, QLatin1String("Size"), QString::number(info.uncompressedSize));
- QString assembledDependencies = QLatin1String("");
- Q_FOREACH (const QString & val, info.dependencies) {
- assembledDependencies += val + QLatin1String(",");
- }
- if (info.dependencies.count() > 0)
- assembledDependencies.chop(1);
- addTextChildHelper(&package, QLatin1String("Dependencies"), assembledDependencies);
+ addTextChildHelper(&package, QLatin1String("LastUpdateDate"), info.lastUpdateDate
+ .toString(Qt::ISODate));
+ addTextChildHelper(&package, QLatin1String("InstallDate"), info.installDate
+ .toString(Qt::ISODate));
+ addTextChildHelper(&package, QLatin1String("Size"),
+ QString::number(info.uncompressedSize));
+
+ if (info.dependencies.count())
+ addTextChildHelper(&package, scDependencies, info.dependencies.join(QLatin1String(",")));
+ if (info.autoDependencies.count())
+ addTextChildHelper(&package, scAutoDependOn, info.autoDependencies.join(QLatin1String(",")));
if (info.forcedInstallation)
addTextChildHelper(&package, QLatin1String("ForcedInstallation"), QLatin1String("true"));
if (info.virtualComp)
addTextChildHelper(&package, QLatin1String("Virtual"), QLatin1String("true"));
+ if (info.checkable)
+ addTextChildHelper(&package, QLatin1String("Checkable"), QLatin1String("true"));
root.appendChild(package);
}
@@ -460,7 +436,7 @@ void PackagesInfo::writeToDisk()
}
}
-void PackagesInfo::PackagesInfoData::addPackageFrom(const QDomElement &packageE)
+void LocalPackageHub::PackagesInfoData::addPackageFrom(const QDomElement &packageE)
{
if (packageE.isNull())
return;
@@ -469,9 +445,10 @@ void PackagesInfo::PackagesInfoData::addPackageFrom(const QDomElement &packageE)
if (childNodes.count() == 0)
return;
- PackageInfo info;
+ LocalPackage info;
info.forcedInstallation = false;
info.virtualComp = false;
+ info.checkable = false;
for (int i = 0; i < childNodes.count(); i++) {
QDomNode childNode = childNodes.item(i);
QDomElement childNodeE = childNode.toElement();
@@ -480,8 +457,6 @@ void PackagesInfo::PackagesInfoData::addPackageFrom(const QDomElement &packageE)
if (childNodeE.tagName() == QLatin1String("Name"))
info.name = childNodeE.text();
- else if (childNodeE.tagName() == QLatin1String("Pixmap"))
- info.pixmap = childNodeE.text();
else if (childNodeE.tagName() == QLatin1String("Title"))
info.title = childNodeE.text();
else if (childNodeE.tagName() == QLatin1String("Description"))
@@ -497,38 +472,34 @@ void PackagesInfo::PackagesInfoData::addPackageFrom(const QDomElement &packageE)
else if (childNodeE.tagName() == QLatin1String("Dependencies")) {
info.dependencies = childNodeE.text().split(QInstaller::commaRegExp(),
QString::SkipEmptyParts);
+ } else if (childNodeE.tagName() == QLatin1String("AutoDependOn")) {
+ info.autoDependencies = childNodeE.text().split(QInstaller::commaRegExp(),
+ QString::SkipEmptyParts);
} else if (childNodeE.tagName() == QLatin1String("ForcedInstallation"))
info.forcedInstallation = childNodeE.text().toLower() == QLatin1String( "true" ) ? true : false;
else if (childNodeE.tagName() == QLatin1String("LastUpdateDate"))
info.lastUpdateDate = QDate::fromString(childNodeE.text(), Qt::ISODate);
else if (childNodeE.tagName() == QLatin1String("InstallDate"))
info.installDate = QDate::fromString(childNodeE.text(), Qt::ISODate);
+ else if (childNodeE.tagName() == QLatin1String("Checkable"))
+ info.checkable = childNodeE.text().toLower() == QLatin1String("true") ? true : false;
}
-
- this->packageInfoList.append(info);
+ m_packageInfoMap.insert(info.name, info);
}
/*!
Clears the installed package list.
*/
-void PackagesInfo::clearPackageInfoList()
+void LocalPackageHub::clearPackageInfos()
{
- d->packageInfoList.clear();
+ d->m_packageInfoMap.clear();
d->modified = true;
- emit reset();
}
/*!
- \fn void KDUpdater::PackagesInfo::reset()
-
- This signal is emitted whenever the contents of this class are refreshed, usually from within
- the refresh() slot.
-*/
-
-/*!
\inmodule kdupdater
- \class KDUpdater::PackageInfo
- \brief The PackageInfo class describes a single installed package in the application.
+ \class KDUpdater::LocalPackage
+ \brief The LocalPackage class describes a single installed package in the application.
This class contains information about a single installed package in the application. The
information contained in this class corresponds to the information described by the <Package>
@@ -536,30 +507,30 @@ void PackagesInfo::clearPackageInfoList()
*/
/*!
- \variable PackageInfo::name
+ \variable LocalPackage::name
\brief The name of the package.
*/
/*!
- \variable PackageInfo::pixmap
+ \variable LocalPackage::pixmap
*/
/*!
- \variable PackageInfo::title
+ \variable LocalPackage::title
*/
/*!
- \variable PackageInfo::description
+ \variable LocalPackage::description
*/
/*!
- \variable PackageInfo::version
+ \variable LocalPackage::version
*/
/*!
- \variable PackageInfo::lastUpdateDate
+ \variable LocalPackage::lastUpdateDate
*/
/*!
- \variable PackageInfo::installDate
+ \variable LocalPackage::installDate
*/
diff --git a/src/libs/kdtools/kdupdaterpackagesinfo.h b/src/libs/kdtools/localpackagehub.h
index c53053434..9ddf2548d 100644
--- a/src/libs/kdtools/kdupdaterpackagesinfo.h
+++ b/src/libs/kdtools/localpackagehub.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
+** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -31,42 +32,42 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_PACKAGES_INFO_H
-#define KD_UPDATER_PACKAGES_INFO_H
+#ifndef LOCALPACKAGEHUB_H
+#define LOCALPACKAGEHUB_H
-#include "kdupdater.h"
+#include "updater.h"
-#include <QObject>
+#include <QCoreApplication>
#include <QDate>
-#include <QString>
#include <QStringList>
-#include <QVariant>
namespace KDUpdater {
-struct KDTOOLS_EXPORT PackageInfo
+struct KDTOOLS_EXPORT LocalPackage
{
QString name;
- QString pixmap;
QString title;
QString description;
QString version;
QString inheritVersionFrom;
QStringList dependencies;
- QStringList translations;
+ QStringList autoDependencies;
QDate lastUpdateDate;
QDate installDate;
bool forcedInstallation;
bool virtualComp;
quint64 uncompressedSize;
+ bool checkable;
};
-class KDTOOLS_EXPORT PackagesInfo : public QObject
+class KDTOOLS_EXPORT LocalPackageHub
{
- Q_OBJECT
+ Q_DISABLE_COPY(LocalPackageHub)
+ Q_DECLARE_TR_FUNCTIONS(LocalPackageHub)
public:
- ~PackagesInfo();
+ LocalPackageHub();
+ ~LocalPackageHub();
enum Error
{
@@ -78,42 +79,41 @@ public:
};
bool isValid() const;
- QString errorString() const;
+ QStringList packageNames() const;
+
Error error() const;
- void clearPackageInfoList();
+ QString errorString() const;
- void setFileName(const QString &fileName);
QString fileName() const;
+ void setFileName(const QString &fileName);
- void setApplicationName(const QString &name);
QString applicationName() const;
+ void setApplicationName(const QString &name);
- void setApplicationVersion(const QString &version);
QString applicationVersion() const;
+ void setApplicationVersion(const QString &version);
+ void clearPackageInfos();
int packageInfoCount() const;
- PackageInfo packageInfo(int index) const;
- int findPackageInfo(const QString &pkgName) const;
- QVector<KDUpdater::PackageInfo> packageInfos() const;
- void writeToDisk();
-
- bool installPackage(const QString &pkgName, const QString &version, const QString &title = QString(),
- const QString &description = QString(), const QStringList &dependencies = QStringList(),
- bool forcedInstallation = false, bool virtualComp = false, quint64 uncompressedSize = 0,
- const QString &inheritVersionFrom = QString());
- bool updatePackage(const QString &pkgName, const QString &version, const QDate &date);
+ QList<LocalPackage> packageInfos() const;
+ LocalPackage packageInfo(const QString &pkgName) const;
+
+ void addPackage(const QString &pkgName,
+ const QString &version, // mandatory
+ const QString &title,
+ const QString &description,
+ const QStringList &dependencies,
+ const QStringList &autoDependencies,
+ bool forcedInstallation,
+ bool virtualComp,
+ quint64 uncompressedSize,
+ const QString &inheritVersionFrom,
+ bool checkable);
bool removePackage(const QString &pkgName);
-public Q_SLOTS:
void refresh();
-
-Q_SIGNALS:
- void reset();
-
-protected:
- friend class Application;
- explicit PackagesInfo(QObject *parent = 0);
+ void writeToDisk();
private:
struct PackagesInfoData;
@@ -122,4 +122,4 @@ private:
} // KDUpdater
-#endif // KD_UPDATER_PACKAGES_INFO_H
+#endif // LOCALPACKAGEHUB_H
diff --git a/src/libs/kdtools/kdlockfile.cpp b/src/libs/kdtools/lockfile.cpp
index 476b034f9..a40e68fbe 100644
--- a/src/libs/kdtools/kdlockfile.cpp
+++ b/src/libs/kdtools/lockfile.cpp
@@ -32,30 +32,34 @@
**
****************************************************************************/
-#include "kdlockfile.h"
-#include "kdlockfile_p.h"
+#include "lockfile.h"
+#include "lockfile_p.h"
-KDLockFile::KDLockFile(const QString &name)
+namespace KDUpdater {
+
+LockFile::LockFile(const QString &name)
: d(new Private(name))
{
}
-KDLockFile::~KDLockFile()
+LockFile::~LockFile()
{
delete d;
}
-bool KDLockFile::lock()
+bool LockFile::lock()
{
return d->lock();
}
-QString KDLockFile::errorString() const
+QString LockFile::errorString() const
{
return d->errorString;
}
-bool KDLockFile::unlock()
+bool LockFile::unlock()
{
return d->unlock();
}
+
+} // namespace KDUpdater
diff --git a/src/libs/kdtools/kdlockfile.h b/src/libs/kdtools/lockfile.h
index 2d98c3f6d..13b28dac3 100644
--- a/src/libs/kdtools/kdlockfile.h
+++ b/src/libs/kdtools/lockfile.h
@@ -32,18 +32,20 @@
**
****************************************************************************/
-#ifndef KDLOCKFILE_H
-#define KDLOCKFILE_H
+#ifndef LOCKFILE_H
+#define LOCKFILE_H
-#include <kdtoolsglobal.h>
+#include "kdtoolsglobal.h"
-class KDTOOLS_EXPORT KDLockFile
+namespace KDUpdater {
+
+class KDTOOLS_EXPORT LockFile
{
- Q_DISABLE_COPY(KDLockFile)
+ Q_DISABLE_COPY(LockFile)
public:
- explicit KDLockFile(const QString &name);
- ~KDLockFile();
+ explicit LockFile(const QString &name);
+ ~LockFile();
QString errorString() const;
@@ -55,4 +57,6 @@ private:
Private *d;
};
-#endif // KDLOCKFILE_H
+} // namespace KDUpdater
+
+#endif // LOCKFILE_H
diff --git a/src/libs/kdtools/kdlockfile_p.h b/src/libs/kdtools/lockfile_p.h
index 51258c4ad..b8636aaad 100644
--- a/src/libs/kdtools/kdlockfile_p.h
+++ b/src/libs/kdtools/lockfile_p.h
@@ -32,10 +32,10 @@
**
****************************************************************************/
-#ifndef KDLOCKFILE_P_H
-#define KDLOCKFILE_P_H
+#ifndef LOCKFILE_P_H
+#define LOCKFILE_P_H
-#include "kdlockfile.h"
+#include "lockfile.h"
#include <QString>
@@ -43,7 +43,9 @@
# include <qt_windows.h>
#endif
-class KDLockFile::Private
+namespace KDUpdater {
+
+class LockFile::Private
{
public:
explicit Private(const QString& name)
@@ -67,4 +69,6 @@ private:
bool locked;
};
-#endif // KDLOCKFILE_P_H
+} // namespace KDUpdater
+
+#endif // LOCKFILE_P_H
diff --git a/src/libs/kdtools/kdlockfile_unix.cpp b/src/libs/kdtools/lockfile_unix.cpp
index 152fa5383..a024a842f 100644
--- a/src/libs/kdtools/kdlockfile_unix.cpp
+++ b/src/libs/kdtools/lockfile_unix.cpp
@@ -32,15 +32,18 @@
**
****************************************************************************/
-#include "kdlockfile_p.h"
+#include "lockfile_p.h"
#include <QCoreApplication>
+#include <QDir>
#include <cerrno>
#include <sys/file.h>
#include <unistd.h>
-bool KDLockFile::Private::lock()
+namespace KDUpdater {
+
+bool LockFile::Private::lock()
{
if (locked)
return true;
@@ -49,8 +52,8 @@ bool KDLockFile::Private::lock()
errno = 0;
handle = open(filename.toLatin1().constData(), O_CREAT | O_RDWR | O_NONBLOCK, 0600);
if (handle == -1) {
- errorString = QCoreApplication::translate("KDLockFile", "Could not create lock file '%1': "
- "%2").arg(filename, QString::fromLocal8Bit(strerror(errno)));
+ errorString = QCoreApplication::translate("LockFile", "Cannot create lock file \"%1\": "
+ "%2").arg(QDir::toNativeSeparators(filename), QString::fromLocal8Bit(strerror(errno)));
return false;
}
const QString pid = QString::number(qApp->applicationPid());
@@ -60,8 +63,8 @@ bool KDLockFile::Private::lock()
while (written < data.size()) {
const qint64 n = write(handle, data.constData() + written, data.size() - written);
if (n < 0) {
- errorString = QCoreApplication::translate("KDLockFile", "Could not write PID to lock "
- "file '%1': %2").arg(filename, QString::fromLocal8Bit(strerror(errno)));
+ errorString = QCoreApplication::translate("LockFile", "Cannot write PID to lock "
+ "file \"%1\": %2").arg(QDir::toNativeSeparators(filename), QString::fromLocal8Bit(strerror(errno)));
return false;
}
written += n;
@@ -69,13 +72,13 @@ bool KDLockFile::Private::lock()
errno = 0;
locked = flock(handle, LOCK_NB | LOCK_EX) != -1;
if (!locked) {
- errorString = QCoreApplication::translate("KDLockFile", "Could not obtain the lock for "
- "file '%1': %2").arg(filename, QString::fromLocal8Bit(strerror(errno)));
+ errorString = QCoreApplication::translate("LockFile", "Cannot obtain the lock for "
+ "file \"%1\": %2").arg(QDir::toNativeSeparators(filename), QString::fromLocal8Bit(strerror(errno)));
}
return locked;
}
-bool KDLockFile::Private::unlock()
+bool LockFile::Private::unlock()
{
errorString.clear();
if (!locked)
@@ -84,10 +87,12 @@ bool KDLockFile::Private::unlock()
errno = 0;
locked = flock(handle, LOCK_UN | LOCK_NB) == -1;
if (locked) {
- errorString = QCoreApplication::translate("KDLockFile", "Could not release the lock for "
- "file '%1': %2").arg(filename, QString::fromLocal8Bit(strerror(errno)));
+ errorString = QCoreApplication::translate("LockFile", "Cannot release the lock for "
+ "file \"%1\": %2").arg(QDir::toNativeSeparators(filename), QString::fromLocal8Bit(strerror(errno)));
} else {
unlink(filename.toLatin1());
}
return !locked;
}
+
+} // namespace KDUpdater
diff --git a/src/libs/kdtools/kdlockfile_win.cpp b/src/libs/kdtools/lockfile_win.cpp
index f1914f06a..84c3cc9c9 100644
--- a/src/libs/kdtools/kdlockfile_win.cpp
+++ b/src/libs/kdtools/lockfile_win.cpp
@@ -32,15 +32,18 @@
**
****************************************************************************/
-#include "kdlockfile.h"
-#include "kdlockfile_p.h"
+#include "lockfile.h"
+#include "lockfile_p.h"
-#include <utils.h>
+#include "utils.h"
#include <QCoreApplication>
+#include <QDir>
#include <QFileInfo>
-bool KDLockFile::Private::lock()
+namespace KDUpdater {
+
+bool LockFile::Private::lock()
{
if (locked)
return locked;
@@ -51,41 +54,43 @@ bool KDLockFile::Private::lock()
FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
if (handle == INVALID_HANDLE_VALUE) {
- errorString = QCoreApplication::translate("KDLockFile", "Could not create lock file '%1': "
- "%2").arg(filename, QInstaller::windowsErrorString(GetLastError()));
+ errorString = QCoreApplication::translate("LockFile", "Cannot create lock file \"%1\": "
+ "%2").arg(QDir::toNativeSeparators(filename), QInstaller::windowsErrorString(GetLastError()));
return false;
}
DWORD bytesWritten;
const QByteArray pid = QString::number(QCoreApplication::applicationPid()).toLatin1();
if (!WriteFile(handle, pid.data(), pid.size(), &bytesWritten, NULL)) {
- errorString = QCoreApplication::translate("KDLockFile", "Could not write PID to lock file "
- "'%1': %2").arg(filename, QInstaller::windowsErrorString(GetLastError()));
+ errorString = QCoreApplication::translate("LockFile", "Cannot write PID to lock file "
+ "\"%1\": %2").arg(QDir::toNativeSeparators(filename), QInstaller::windowsErrorString(GetLastError()));
return false;
}
FlushFileBuffers(handle);
- if (!LockFile(handle, 0, 0, QFileInfo(filename).size(), 0)) {
- errorString = QCoreApplication::translate("KDLockFile", "Could not obtain the lock for "
- "file '%1': %2").arg(filename, QInstaller::windowsErrorString(GetLastError()));
+ if (!::LockFile(handle, 0, 0, QFileInfo(filename).size(), 0)) {
+ errorString = QCoreApplication::translate("LockFile", "Cannot obtain the lock for "
+ "file \"%1\": %2").arg(QDir::toNativeSeparators(filename), QInstaller::windowsErrorString(GetLastError()));
} else {
locked = true;
}
return locked;
}
-bool KDLockFile::Private::unlock()
+bool LockFile::Private::unlock()
{
errorString.clear();
if (!locked)
return true;
if (!UnlockFile(handle, 0, 0, QFileInfo(filename).size(), 0)) {
- errorString = QCoreApplication::translate("KDLockFile", "Could not release the lock for "
- "file '%1': %2").arg(filename, QInstaller::windowsErrorString(GetLastError()));
+ errorString = QCoreApplication::translate("LockFile", "Cannot release the lock for "
+ "file \"%1\": %2").arg(QDir::toNativeSeparators(filename), QInstaller::windowsErrorString(GetLastError()));
} else {
locked = false;
CloseHandle(handle);
}
return !locked;
}
+
+} // namespace KDUpdater
diff --git a/src/libs/kdtools/kdrunoncechecker.cpp b/src/libs/kdtools/runoncechecker.cpp
index bc71e86c2..21b17ed81 100644
--- a/src/libs/kdtools/kdrunoncechecker.cpp
+++ b/src/libs/kdtools/runoncechecker.cpp
@@ -32,9 +32,9 @@
**
****************************************************************************/
-#include "kdrunoncechecker.h"
-#include "kdlockfile.h"
-#include "kdsysinfo.h"
+#include "runoncechecker.h"
+#include "lockfile.h"
+#include "sysinfo.h"
#include <QCoreApplication>
#include <QDebug>
@@ -46,15 +46,15 @@
using namespace KDUpdater;
-KDRunOnceChecker::KDRunOnceChecker(const QString &filename)
+RunOnceChecker::RunOnceChecker(const QString &filename)
: m_lockfile(filename)
{
}
-KDRunOnceChecker::~KDRunOnceChecker()
+RunOnceChecker::~RunOnceChecker()
{
if (!m_lockfile.unlock())
- qWarning() << m_lockfile.errorString().toUtf8().constData();
+ qWarning().noquote() << m_lockfile.errorString();
}
class ProcessnameEquals
@@ -90,7 +90,7 @@ private:
QString m_name;
};
-bool KDRunOnceChecker::isRunning(KDRunOnceChecker::ConditionFlags flags)
+bool RunOnceChecker::isRunning(RunOnceChecker::ConditionFlags flags)
{
if (flags.testFlag(ConditionFlag::ProcessList)) {
const QList<ProcessInfo> allProcesses = runningProcesses();
@@ -102,7 +102,7 @@ bool KDRunOnceChecker::isRunning(KDRunOnceChecker::ConditionFlags flags)
if (flags.testFlag(ConditionFlag::Lockfile)) {
const bool locked = m_lockfile.lock();
if (!locked)
- qWarning() << m_lockfile.errorString().toUtf8().constData();
+ qWarning().noquote() << m_lockfile.errorString();
return !locked;
}
return false;
diff --git a/src/libs/kdtools/kdrunoncechecker.h b/src/libs/kdtools/runoncechecker.h
index b357d7723..45ed1e50e 100644
--- a/src/libs/kdtools/kdrunoncechecker.h
+++ b/src/libs/kdtools/runoncechecker.h
@@ -32,16 +32,16 @@
**
****************************************************************************/
-#ifndef KDTOOLS_RUNONCECHECKER_H
-#define KDTOOLS_RUNONCECHECKER_H
+#ifndef RUNONCECHECKER_H
+#define RUNONCECHECKER_H
-#include "kdlockfile.h"
+#include "lockfile.h"
#include <QString>
-class KDTOOLS_EXPORT KDRunOnceChecker
+class KDTOOLS_EXPORT RunOnceChecker
{
- Q_DISABLE_COPY(KDRunOnceChecker)
+ Q_DISABLE_COPY(RunOnceChecker)
public:
enum struct ConditionFlag {
@@ -50,13 +50,13 @@ public:
};
Q_DECLARE_FLAGS(ConditionFlags, ConditionFlag)
- explicit KDRunOnceChecker(const QString &filename = QString());
- ~KDRunOnceChecker();
+ explicit RunOnceChecker(const QString &filename = QString());
+ ~RunOnceChecker();
- bool isRunning(KDRunOnceChecker::ConditionFlags flags);
+ bool isRunning(RunOnceChecker::ConditionFlags flags);
private:
- KDLockFile m_lockfile;
+ KDUpdater::LockFile m_lockfile;
};
-#endif // KDTOOLS_RUNONCECHECKER_H
+#endif // RUNONCECHECKER_H
diff --git a/src/libs/kdtools/kdselfrestarter.cpp b/src/libs/kdtools/selfrestarter.cpp
index 934bbf627..6f990cf90 100644
--- a/src/libs/kdtools/kdselfrestarter.cpp
+++ b/src/libs/kdtools/selfrestarter.cpp
@@ -31,13 +31,13 @@
**
****************************************************************************/
-#include "kdselfrestarter.h"
+#include "selfrestarter.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QProcess>
-class KDSelfRestarter::Private
+class SelfRestarter::Private
{
public:
Private(int argc, char *argv[])
@@ -66,33 +66,33 @@ public:
QStringList args;
bool restartOnQuit;
QString workingPath;
- static KDSelfRestarter *instance;
+ static SelfRestarter *instance;
};
-KDSelfRestarter *KDSelfRestarter::Private::instance = 0;
+SelfRestarter *SelfRestarter::Private::instance = 0;
-KDSelfRestarter::KDSelfRestarter(int argc, char *argv[])
+SelfRestarter::SelfRestarter(int argc, char *argv[])
: d(new Private(argc, argv))
{
- Q_ASSERT_X(!Private::instance, Q_FUNC_INFO, "Cannot create more than one KDSelfRestarter instance");
+ Q_ASSERT_X(!Private::instance, Q_FUNC_INFO, "Cannot create more than one SelfRestarter instance");
Private::instance = this;
}
-KDSelfRestarter::~KDSelfRestarter()
+SelfRestarter::~SelfRestarter()
{
- Q_ASSERT_X(Private::instance == this, Q_FUNC_INFO, "Cannot create more than one KDSelfRestarter instance");
+ Q_ASSERT_X(Private::instance == this, Q_FUNC_INFO, "Cannot create more than one SelfRestarter instance");
delete d;
Private::instance = 0;
}
-void KDSelfRestarter::setRestartOnQuit(bool restart)
+void SelfRestarter::setRestartOnQuit(bool restart)
{
- Q_ASSERT_X(Private::instance, Q_FUNC_INFO, "KDSelfRestarter instance must be created in main()");
+ Q_ASSERT_X(Private::instance, Q_FUNC_INFO, "SelfRestarter instance must be created in main()");
if (Private::instance)
Private::instance->d->restartOnQuit = restart;
}
-bool KDSelfRestarter::restartOnQuit()
+bool SelfRestarter::restartOnQuit()
{
return Private::instance ? Private::instance->d->restartOnQuit : false;
}
diff --git a/src/libs/kdtools/kdselfrestarter.h b/src/libs/kdtools/selfrestarter.h
index a095c728a..8d62b0345 100644
--- a/src/libs/kdtools/kdselfrestarter.h
+++ b/src/libs/kdtools/selfrestarter.h
@@ -31,24 +31,24 @@
**
****************************************************************************/
-#ifndef KDTOOLS_KDSELFRESTARTER_H
-#define KDTOOLS_KDSELFRESTARTER_H
+#ifndef SELFRESTARTER_H
+#define SELFRESTARTER_H
#include "kdtoolsglobal.h"
-class KDTOOLS_EXPORT KDSelfRestarter
+class KDTOOLS_EXPORT SelfRestarter
{
public:
- KDSelfRestarter(int argc, char *argv[]);
- ~KDSelfRestarter();
+ SelfRestarter(int argc, char *argv[]);
+ ~SelfRestarter();
static bool restartOnQuit();
static void setRestartOnQuit(bool restart);
private:
- Q_DISABLE_COPY(KDSelfRestarter)
+ Q_DISABLE_COPY(SelfRestarter)
class Private;
Private *d;
};
-#endif // KDTOOLS_KDSELFRESTARTER_H
+#endif // SELFRESTARTER_H
diff --git a/src/libs/kdtools/kdsysinfo.cpp b/src/libs/kdtools/sysinfo.cpp
index 6a2a96ea5..fafa2900e 100644
--- a/src/libs/kdtools/kdsysinfo.cpp
+++ b/src/libs/kdtools/sysinfo.cpp
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#include "kdsysinfo.h"
+#include "sysinfo.h"
#include <QtCore/QDebug>
#include <QtCore/QDir>
diff --git a/src/libs/kdtools/kdsysinfo.h b/src/libs/kdtools/sysinfo.h
index 276e98e3c..021f26cfd 100644
--- a/src/libs/kdtools/kdsysinfo.h
+++ b/src/libs/kdtools/sysinfo.h
@@ -31,10 +31,10 @@
**
****************************************************************************/
-#ifndef KDSYSINFO_H
-#define KDSYSINFO_H
+#ifndef SYSINFO_H
+#define SYSINFO_H
-#include <kdtoolsglobal.h>
+#include "kdtoolsglobal.h"
#include <QtCore/QString>
@@ -93,4 +93,4 @@ QT_END_NAMESPACE
QDebug operator<<(QDebug dbg, KDUpdater::VolumeInfo volume);
QDebug operator<<(QDebug dbg, KDUpdater::ProcessInfo process);
-#endif // KDSYSINFO_H
+#endif // SYSINFO_H
diff --git a/src/libs/kdtools/kdsysinfo_mac.cpp b/src/libs/kdtools/sysinfo_mac.cpp
index 23b3646fe..f1e3d1786 100644
--- a/src/libs/kdtools/kdsysinfo_mac.cpp
+++ b/src/libs/kdtools/sysinfo_mac.cpp
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#include "kdsysinfo.h"
+#include "sysinfo.h"
#include <Carbon/Carbon.h>
diff --git a/src/libs/kdtools/kdsysinfo_x11.cpp b/src/libs/kdtools/sysinfo_x11.cpp
index e47734c7c..6fddf895f 100644
--- a/src/libs/kdtools/kdsysinfo_x11.cpp
+++ b/src/libs/kdtools/sysinfo_x11.cpp
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#include "kdsysinfo.h"
+#include "sysinfo.h"
#include <sys/utsname.h>
#include <sys/statvfs.h>
@@ -75,7 +75,7 @@ QList<VolumeInfo> mountedVolumes()
QFile f(QLatin1String("/etc/mtab"));
if (!f.open(QIODevice::ReadOnly)) {
- qCritical("%s: Could not open %s: %s", Q_FUNC_INFO, qPrintable(f.fileName()), qPrintable(f.errorString()));
+ qCritical("%s: Cannot open %s: %s", Q_FUNC_INFO, qPrintable(f.fileName()), qPrintable(f.errorString()));
return result; //better error-handling?
}
diff --git a/src/libs/kdtools/kdupdatertask.cpp b/src/libs/kdtools/task.cpp
index 38b33da0a..14b774ea9 100644
--- a/src/libs/kdtools/kdupdatertask.cpp
+++ b/src/libs/kdtools/task.cpp
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#include "kdupdatertask.h"
+#include "task.h"
using namespace KDUpdater;
diff --git a/src/libs/kdtools/kdupdatertask.h b/src/libs/kdtools/task.h
index 51c1458f1..fc528cd66 100644
--- a/src/libs/kdtools/kdupdatertask.h
+++ b/src/libs/kdtools/task.h
@@ -31,10 +31,10 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_TASK_H
-#define KD_UPDATER_TASK_H
+#ifndef TASK_H
+#define TASK_H
-#include "kdupdater.h"
+#include "updater.h"
#include <QObject>
@@ -116,4 +116,4 @@ private:
} // namespace KDUpdater
-#endif // KD_UPDATER_TASK_H
+#endif // TASK_H
diff --git a/src/libs/kdtools/kdupdaterupdate.cpp b/src/libs/kdtools/update.cpp
index 79c5beb94..93e8e91b1 100644
--- a/src/libs/kdtools/kdupdaterupdate.cpp
+++ b/src/libs/kdtools/update.cpp
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#include "kdupdaterupdate.h"
+#include "update.h"
using namespace KDUpdater;
@@ -51,10 +51,9 @@ using namespace KDUpdater;
/*!
\internal
*/
-Update::Update(int priority, const QUrl &sourceInfoUrl, const QHash<QString, QVariant> &data)
- : m_priority(priority)
- , m_sourceInfoUrl(sourceInfoUrl)
- , m_data(data)
+Update::Update(const QInstaller::PackageSource &packageSource, const UpdateInfo &updateInfo)
+ : m_packageSource(packageSource)
+ , m_updateInfo(updateInfo)
{
}
@@ -64,22 +63,5 @@ Update::Update(int priority, const QUrl &sourceInfoUrl, const QHash<QString, QVa
*/
QVariant Update::data(const QString &name, const QVariant &defaultValue) const
{
- return m_data.value(name, defaultValue);
-}
-
-/*!
- Returns the priority of the update.
-*/
-int Update::priority() const
-{
- return m_priority;
-}
-
-/*!
- Returns the URL of the update source. An update source is a repository that
- contains an update for the application.
-*/
-QUrl Update::sourceInfoUrl() const
-{
- return m_sourceInfoUrl;
+ return m_updateInfo.data.value(name, defaultValue);
}
diff --git a/src/libs/kdtools/kdupdaterupdate.h b/src/libs/kdtools/update.h
index 10e46ad08..dfc52dfa1 100644
--- a/src/libs/kdtools/kdupdaterupdate.h
+++ b/src/libs/kdtools/update.h
@@ -31,11 +31,11 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_UPDATE_H
-#define KD_UPDATER_UPDATE_H
+#ifndef UPDATE_H
+#define UPDATE_H
-#include <QHash>
-#include <QUrl>
+#include "packagesource.h"
+#include "updatesinfo_p.h"
#include <QVariant>
namespace KDUpdater {
@@ -45,19 +45,17 @@ class Update
public:
QVariant data(const QString &name, const QVariant &defaultValue = QVariant()) const;
- int priority() const;
- QUrl sourceInfoUrl() const;
+ QInstaller::PackageSource packageSource() const {return m_packageSource; }
private:
friend class UpdateFinder;
- Update(int p, const QUrl &sourceInfoUrl, const QHash<QString, QVariant> &data);
+ Update(const QInstaller::PackageSource &packageSource, const UpdateInfo &updateInfo);
private:
- int m_priority;
- QUrl m_sourceInfoUrl;
- QHash<QString, QVariant> m_data;
+ QInstaller::PackageSource m_packageSource;
+ UpdateInfo m_updateInfo;
};
} // namespace KDUpdater
-#endif // KD_UPDATER_UPDATE_H
+#endif // UPDATE_H
diff --git a/src/libs/kdtools/kdupdaterupdatefinder.cpp b/src/libs/kdtools/updatefinder.cpp
index a4bfa209c..25e587b17 100644
--- a/src/libs/kdtools/kdupdaterupdatefinder.cpp
+++ b/src/libs/kdtools/updatefinder.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
+** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -31,14 +32,12 @@
**
****************************************************************************/
-#include "kdupdaterupdatefinder.h"
-#include "kdupdaterapplication.h"
-#include "kdupdaterupdatesourcesinfo.h"
-#include "kdupdaterpackagesinfo.h"
-#include "kdupdaterupdate.h"
-#include "kdupdaterfiledownloader.h"
-#include "kdupdaterfiledownloaderfactory.h"
-#include "kdupdaterupdatesinfo_p.h"
+#include "updatefinder.h"
+#include "update.h"
+#include "filedownloader.h"
+#include "filedownloaderfactory.h"
+#include "updatesinfo_p.h"
+#include "localpackagehub.h"
#include "fileutils.h"
#include "globals.h"
@@ -47,16 +46,17 @@
#include <QFileInfo>
using namespace KDUpdater;
+using namespace QInstaller;
/*!
\inmodule kdupdater
\class KDUpdater::UpdateFinder
- \brief The UpdaterFinder class finds updates applicable for a KDUpdater::Application.
+ \brief The UpdaterFinder class finds updates applicable for installed packages.
The KDUpdater::UpdateFinder class helps in searching for updates and installing them on the
application. The class basically processes the application's KDUpdater::PackagesInfo and the
- UpdateXMLs it aggregates from all the update sources described in KDUpdater::UpdateSourcesInfo
- and populates a list of KDUpdater::Update objects.
+ UpdateXMLs it aggregates from all the update sources and populates a list of KDUpdater::Update
+ objects.
*/
//
@@ -73,7 +73,6 @@ public:
Private(UpdateFinder *qq)
: q(qq)
- , application(0)
, downloadCompleteCount(0)
, m_downloadsToComplete(0)
{}
@@ -86,14 +85,13 @@ public:
struct Data {
Data()
: downloader(0) {}
- Data(const UpdateSourceInfo &i, FileDownloader *d = 0)
+ Data(const PackageSource &i, FileDownloader *d = 0)
: info(i), downloader(d) {}
- UpdateSourceInfo info;
+ PackageSource info;
FileDownloader *downloader;
};
UpdateFinder *q;
- Application *application;
QHash<QString, Update *> updates;
// Temporary structure that notes down information about updates.
@@ -109,9 +107,12 @@ public:
bool computeApplicableUpdates();
QList<UpdateInfo> applicableUpdates(UpdatesInfo *updatesInfo);
- void createUpdateObjects(const UpdateSourceInfo &sourceInfo, const QList<UpdateInfo> &updateInfoList);
- Resolution checkPriorityAndVersion(const UpdateSourceInfo &sourceInfo, const QVariantHash &data) const;
+ void createUpdateObjects(const PackageSource &source, const QList<UpdateInfo> &updateInfoList);
+ Resolution checkPriorityAndVersion(const PackageSource &source, const QVariantHash &data) const;
void slotDownloadDone();
+
+ QSet<PackageSource> packageSources;
+ std::weak_ptr<LocalPackageHub> m_localPackageHub;
};
@@ -151,7 +152,7 @@ void UpdateFinder::Private::clear()
This method computes the updates that can be applied on the application by
studying the application's KDUpdater::PackagesInfo object and the UpdateXML files
- from each of the update sources described in KDUpdater::UpdateSourcesInfo.
+ from each of the update sources described in QInstaller::PackageSource.
This function can take a long time to complete. The following signals are emitted
during the execution of this function
@@ -159,7 +160,7 @@ void UpdateFinder::Private::clear()
The function creates KDUpdater::Update objects on the stack. All KDUpdater::Update objects
are made children of the application associated with this finder.
- The update sources are fetched from the KDUpdater::UpdateSourcesInfo object associated with
+ The update sources are fetched from the QInstaller::PackageSource object associated with
the application. Package information is extracted from the KDUpdater::PackagesInfo object
associated with the application.
@@ -176,24 +177,20 @@ void UpdateFinder::Private::computeUpdates()
cancel = false;
// First do some quick sanity checks on the packages info
- PackagesInfo *packages = application->packagesInfo();
+ std::shared_ptr<LocalPackageHub> packages = m_localPackageHub.lock();
if (!packages) {
- q->reportError(tr("Could not access the package information of this application."));
+ q->reportError(tr("Cannot access the package information of this application."));
return;
}
+
if (!packages->isValid()) {
q->reportError(packages->errorString());
return;
}
- // Now do some quick sanity checks on the update sources info
- UpdateSourcesInfo *sources = application->updateSourcesInfo();
- if (!sources) {
- q->reportError(tr("Could not access the update sources information of this application."));
- return;
- }
- if (!sources->isValid()) {
- q->reportError(sources->errorString());
+ // Now do some quick sanity checks on the package sources.
+ if (packageSources.count() <= 0) {
+ q->reportError(tr("No package sources set for this application."));
return;
}
@@ -246,18 +243,9 @@ void UpdateFinder::Private::cancelComputeUpdates()
*/
bool UpdateFinder::Private::downloadUpdateXMLFiles()
{
- if (!application)
- return false;
-
- UpdateSourcesInfo *updateSources = application->updateSourcesInfo();
- if (!updateSources )
- return false;
-
// create UpdatesInfo for each update source
- for (int i = 0; i < updateSources->updateSourceInfoCount(); i++) {
- const UpdateSourceInfo info = updateSources->updateSourceInfo(i);
+ foreach (const PackageSource &info, packageSources) {
const QUrl url = QString::fromLatin1("%1/Updates.xml").arg(info.url.toString());
-
if (url.scheme() != QLatin1String("resource") && url.scheme() != QLatin1String("file")) {
// create FileDownloader (except for local files and resources)
FileDownloader *downloader = FileDownloaderFactory::instance().create(url.scheme(), q);
@@ -305,8 +293,8 @@ bool UpdateFinder::Private::downloadUpdateXMLFiles()
const Data data = m_updatesInfoList.value(updatesInfo);
if (data.downloader) {
if (!data.downloader->isDownloaded()) {
- q->reportError(tr("Could not download update source %1 from ('%2')").arg(data.info
- .name, data.info.url.toString()));
+ q->reportError(tr("Cannot download package source %1 from \"%2\".").arg(data
+ .downloader->url().fileName(), data.info.url.toString()));
} else {
updatesInfo->setFileName(data.downloader->downloadedFileName());
}
@@ -351,7 +339,7 @@ bool UpdateFinder::Private::computeApplicableUpdates()
if (cancel)
return false;
- const UpdateSourceInfo updateSource = m_updatesInfoList.value(updatesInfo).info;
+ const PackageSource updateSource = m_updatesInfoList.value(updatesInfo).info;
// Create Update objects for updates that have a valid
// UpdateFile
@@ -375,7 +363,7 @@ QList<UpdateInfo> UpdateFinder::Private::applicableUpdates(UpdatesInfo *updatesI
if (!updatesInfo || updatesInfo->updateInfoCount() == 0)
return dummy;
- PackagesInfo *packages = this->application->packagesInfo();
+ std::shared_ptr<LocalPackageHub> packages = m_localPackageHub.lock();
if (!packages)
return dummy;
@@ -390,17 +378,19 @@ QList<UpdateInfo> UpdateFinder::Private::applicableUpdates(UpdatesInfo *updatesI
// Catch hold of app names contained updatesInfo->applicationName()
// If the application appName isn't one of the app names, then the updates are not applicable.
const QStringList apps = appName.split(QInstaller::commaRegExp(), QString::SkipEmptyParts);
- if (apps.indexOf(this->application->applicationName()) < 0)
+ if (apps.indexOf([&packages] { return packages->isValid() ? packages->applicationName()
+ : QCoreApplication::applicationName(); } ()) < 0) {
return dummy;
+ }
}
return updatesInfo->updatesInfo();
}
-void UpdateFinder::Private::createUpdateObjects(const UpdateSourceInfo &sourceInfo,
+void UpdateFinder::Private::createUpdateObjects(const PackageSource &source,
const QList<UpdateInfo> &updateInfoList)
{
foreach (const UpdateInfo &info, updateInfoList) {
- const Resolution value = checkPriorityAndVersion(sourceInfo, info.data);
+ const Resolution value = checkPriorityAndVersion(source, info.data);
if (value == Resolution::KeepExisting)
continue;
@@ -409,7 +399,7 @@ void UpdateFinder::Private::createUpdateObjects(const UpdateSourceInfo &sourceIn
delete updates.take(name);
// Create and register the update
- updates.insert(name, new Update(sourceInfo.priority, sourceInfo.url, info.data));
+ updates.insert(name, new Update(source, info));
}
}
@@ -419,7 +409,7 @@ void UpdateFinder::Private::createUpdateObjects(const UpdateSourceInfo &sourceIn
priority, use the new new package, otherwise keep the already existing package.
*/
UpdateFinder::Private::Resolution UpdateFinder::Private::checkPriorityAndVersion(
- const UpdateSourceInfo &sourceInfo, const QVariantHash &newPackage) const
+ const PackageSource &source, const QVariantHash &newPackage) const
{
const QString name = newPackage.value(QLatin1String("Name")).toString();
if (Update *existingPackage = updates.value(name)) {
@@ -430,23 +420,23 @@ UpdateFinder::Private::Resolution UpdateFinder::Private::checkPriorityAndVersion
if (match > 0) {
// new package has higher version, use
- qDebug() << QString::fromLatin1("Remove Package 'Name: %1, Version: %2, Source: %3' "
- "found a package with higher version 'Name: %4, Version: %5, Source: %6'")
- .arg(name, existingPackage->data(QLatin1String("Version")).toString(),
- QFileInfo(existingPackage->sourceInfoUrl().toLocalFile()).fileName(),
- name, newPackage.value(QLatin1String("Version")).toString(),
- QFileInfo(sourceInfo.url.toLocalFile()).fileName());
+ qDebug().nospace() << "Remove Package 'Name: " << name << ", Version: "
+ << existingPackage->data(QLatin1String("Version")).toString()
+ << ", Source: " << QFileInfo(existingPackage->packageSource().url.toLocalFile()).fileName()
+ << "' found a package with higher version 'Name: "
+ << name << ", Version: " << newPackage.value(QLatin1String("Version")).toString()
+ << ", Source: " << QFileInfo(source.url.toLocalFile()).fileName() << "'";
return Resolution::RemoveExisting;
}
- if ((match == 0) && (sourceInfo.priority > existingPackage->priority())) {
+ if ((match == 0) && (source.priority > existingPackage->packageSource().priority)) {
// new package version equals but priority is higher, use
- qDebug() << QString::fromLatin1("Remove Package 'Name: %1, Priority: %2, Source: %3' "
- "found a package with higher priority 'Name: %4, Priority: %5, Source: %6'")
- .arg(name, QString::number(existingPackage->priority()),
- QFileInfo(existingPackage->sourceInfoUrl().toLocalFile()).fileName(),
- name, QString::number(sourceInfo.priority),
- QFileInfo(sourceInfo.url.toLocalFile()).fileName());
+ qDebug().nospace() << "Remove Package 'Name: " << name << ", Priority: "
+ << existingPackage->packageSource().priority
+ << ", Source: " << QFileInfo(existingPackage->packageSource().url.toLocalFile()).fileName()
+ << "' found a package with higher priority 'Name: "
+ << name << ", Priority: " << source.priority
+ << ", Source: " << QFileInfo(source.url.toLocalFile()).fileName() << "'";
return Resolution::RemoveExisting;
}
return Resolution::KeepExisting; // otherwise keep existing
@@ -459,14 +449,12 @@ UpdateFinder::Private::Resolution UpdateFinder::Private::checkPriorityAndVersion
//
/*!
- Constructs an update finder for the KDUpdater::Application specified by
- \a application.
+ Constructs an update finder.
*/
-UpdateFinder::UpdateFinder(Application *application)
- : Task(QLatin1String("UpdateFinder"), Stoppable, application),
+UpdateFinder::UpdateFinder()
+ : Task(QLatin1String("UpdateFinder"), Stoppable),
d(new Private(this))
{
- d->application = application;
}
/*!
@@ -478,14 +466,26 @@ UpdateFinder::~UpdateFinder()
}
/*!
- Returns a list of KDUpdater::Update objects. The update objects returned in this list
- are made children of the KDUpdater::Application object associated with this class.
+ Returns a list of KDUpdater::Update objects.
*/
QList<Update *> UpdateFinder::updates() const
{
return d->updates.values();
}
+void UpdateFinder::setLocalPackageHub(std::weak_ptr<LocalPackageHub> hub)
+{
+ d->m_localPackageHub = std::move(hub);
+}
+
+/*!
+ Sets the package sources information to use when searching for applicable packages.
+*/
+void UpdateFinder::setPackageSources(const QSet<PackageSource> &sources)
+{
+ d->packageSources = sources;
+}
+
/*!
\internal
@@ -636,4 +636,4 @@ int KDUpdater::compareVersion(const QString &v1, const QString &v2)
return 0;
}
-#include "moc_kdupdaterupdatefinder.cpp"
+#include "moc_updatefinder.cpp"
diff --git a/src/libs/kdtools/kdupdaterupdatefinder.h b/src/libs/kdtools/updatefinder.h
index ce7fae093..1fbebdd9a 100644
--- a/src/libs/kdtools/kdupdaterupdatefinder.h
+++ b/src/libs/kdtools/updatefinder.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
+** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -31,14 +32,17 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_UPDATE_FINDER_H
-#define KD_UPDATER_UPDATE_FINDER_H
+#ifndef UPDATEFINDER_H
+#define UPDATEFINDER_H
-#include "kdupdatertask.h"
+#include "task.h"
+#include "packagesource.h"
+
+#include <memory>
namespace KDUpdater {
-class Application;
+class LocalPackageHub;
class Update;
class KDTOOLS_EXPORT UpdateFinder : public Task
@@ -47,11 +51,14 @@ class KDTOOLS_EXPORT UpdateFinder : public Task
class Private;
public:
- explicit UpdateFinder(Application *application);
+ UpdateFinder();
~UpdateFinder();
QList<Update *> updates() const;
+ void setLocalPackageHub(std::weak_ptr<LocalPackageHub> hub);
+ void setPackageSources(const QSet<QInstaller::PackageSource> &sources);
+
private:
void doRun();
bool doStop();
@@ -65,4 +72,4 @@ private:
} // namespace KDUpdater
-#endif // KD_UPDATER_UPDATE_FINDER_H
+#endif // UPDATEFINDER_H
diff --git a/src/libs/kdtools/kdupdaterupdateoperation.cpp b/src/libs/kdtools/updateoperation.cpp
index 70c4e7a07..965871fda 100644
--- a/src/libs/kdtools/kdupdaterupdateoperation.cpp
+++ b/src/libs/kdtools/updateoperation.cpp
@@ -31,9 +31,11 @@
**
****************************************************************************/
-#include "kdupdaterupdateoperation.h"
+#include "updateoperation.h"
-#include "kdupdaterapplication.h"
+#include "constants.h"
+#include "fileutils.h"
+#include "packagemanagercore.h"
#include <QDataStream>
#include <QDebug>
@@ -88,17 +90,21 @@ static QString backupFileName(const QString &templateName)
/*!
\internal
*/
-UpdateOperation::UpdateOperation()
+UpdateOperation::UpdateOperation(QInstaller::PackageManagerCore *core)
: m_error(0)
-{}
+ , m_core(core)
+{
+ // Store the value for compatibility reasons.
+ m_values[QLatin1String("installer")] = QVariant::fromValue(core);
+}
/*!
\internal
*/
UpdateOperation::~UpdateOperation()
{
- if (Application *app = Application::instance())
- app->addFilesForDelayedDeletion(filesForDelayedDeletion());
+ if (auto *core = packageManager())
+ core->addFilesForDelayedDeletion(filesForDelayedDeletion());
}
/*!
@@ -180,6 +186,42 @@ QStringList UpdateOperation::arguments() const
return m_arguments;
}
+bool UpdateOperation::checkArgumentCount(int minArgCount, int maxArgCount,
+ const QString &argDescription)
+{
+ const int argCount = arguments().count();
+ if (argCount < minArgCount || argCount > maxArgCount) {
+ setError(InvalidArguments);
+ QString countRange;
+ if (minArgCount == maxArgCount)
+ countRange = tr("exactly %1").arg(minArgCount);
+ else if (maxArgCount == INT_MAX)
+ countRange = tr("at least %1").arg(minArgCount);
+ else if (minArgCount == 0)
+ countRange = tr("not more than %1").arg(maxArgCount);
+ else if (minArgCount == maxArgCount - 1)
+ countRange = tr("%1 or %2").arg(minArgCount).arg(maxArgCount);
+ else
+ countRange = tr("%1 to %2").arg(minArgCount).arg(maxArgCount);
+
+ if (argDescription.isEmpty())
+ setErrorString(tr("Invalid arguments in %1: %n arguments given, "
+ "%2 arguments expected.", 0, argCount)
+ .arg(name(), countRange));
+ else
+ setErrorString(tr("Invalid arguments in %1: %n arguments given, "
+ "%2 arguments expected in the form: %3.", 0, argCount)
+ .arg(name(), countRange, argDescription));
+ return false;
+ }
+ return true;
+}
+
+bool UpdateOperation::checkArgumentCount(int argCount)
+{
+ return checkArgumentCount(argCount, argCount);
+}
+
struct StartsWith
{
StartsWith(const QString &searchTerm)
@@ -211,9 +253,9 @@ QString UpdateOperation::argumentKeyValue(const QString &key, const QString &def
it = std::find_if(++it, tArguments.end(), StartsWith(keySeparater));
if (it != tArguments.end()) {
- qWarning() << QString::fromLatin1("There are multiple keys in the arguments calling"
- " '%1'. Only the first found '%2' is used: '%3'").arg(name(), key, arguments().join(
- QLatin1String("; ")));
+ qWarning().nospace() << "There are multiple keys in the arguments calling " << name() << ". "
+ << "Only the first found " << key << " is used: "
+ << arguments().join(QLatin1String("; "));
}
return value;
}
@@ -276,6 +318,14 @@ QStringList UpdateOperation::filesForDelayedDeletion() const
}
/*!
+ Returns the package manager core this operation belongs to.
+*/
+QInstaller::PackageManagerCore *UpdateOperation::packageManager() const
+{
+ return m_core;
+}
+
+/*!
Registers a list of \a files to be deleted later once the application was restarted and the
file or files are not used anymore.
*/
@@ -302,7 +352,8 @@ bool UpdateOperation::deleteFileNowOrLater(const QString &file, QString *errorSt
QFile f(file);
if (!f.rename(backup)) {
if (errorString)
- *errorString = tr("Renaming %1 into %2 failed with %3.").arg(file, backup, f.errorString());
+ *errorString = tr("Renaming file \"%1\" to \"%2\" failed: %3").arg(
+ QDir::toNativeSeparators(file), QDir::toNativeSeparators(backup), f.errorString());
return false;
}
registerForDelayedDeletion(QStringList(backup));
@@ -340,12 +391,6 @@ bool UpdateOperation::deleteFileNowOrLater(const QString &file, QString *errorSt
*/
/*!
- \fn virtual bool KDUpdater::UpdateOperation::clone() const = 0;
-
- Subclasses must implement this function to clone the current operation.
-*/
-
-/*!
Saves operation arguments and values as an XML document and returns the
document. You can override this method to store your
own extra-data. Extra-data can be any data that you need to store to perform or undo the
@@ -357,10 +402,13 @@ QDomDocument UpdateOperation::toXml() const
QDomDocument doc;
QDomElement root = doc.createElement(QLatin1String("operation"));
doc.appendChild(root);
+
QDomElement args = doc.createElement(QLatin1String("arguments"));
+ const QString target = m_core ? m_core->value(QInstaller::scTargetDir) : QString();
Q_FOREACH (const QString &s, arguments()) {
QDomElement arg = doc.createElement(QLatin1String("argument"));
- arg.appendChild(doc.createTextNode(s));
+ arg.appendChild(doc.createTextNode(QInstaller::replacePath(s, target,
+ QLatin1String(QInstaller::scRelocatable))));
args.appendChild(arg);
}
root.appendChild(args);
@@ -369,18 +417,31 @@ QDomDocument UpdateOperation::toXml() const
// append all values set with setValue
QDomElement values = doc.createElement(QLatin1String("values"));
- for (QVariantMap::const_iterator it = m_values.begin(); it != m_values.end(); ++it) {
+ for (QVariantMap::const_iterator it = m_values.constBegin(); it != m_values.constEnd(); ++it) {
+ // the installer can't be put into XML, ignore
+ if (it.key() == QLatin1String("installer"))
+ continue;
+
QDomElement value = doc.createElement(QLatin1String("value"));
- const QVariant& variant = it.value();
+ QVariant variant = it.value();
value.setAttribute(QLatin1String("name"), it.key());
- value.setAttribute(QLatin1String("type"), QLatin1String( QVariant::typeToName( variant.type())));
+ value.setAttribute(QLatin1String("type"), QLatin1String(variant.typeName()));
if (variant.type() != QVariant::List && variant.type() != QVariant::StringList
&& variant.canConvert(QVariant::String)) {
- // it can convert to string? great!
- value.appendChild( doc.createTextNode(variant.toString()));
+ // it can convert to string? great!
+ value.appendChild(doc.createTextNode(QInstaller::replacePath(variant.toString(),
+ target, QLatin1String(QInstaller::scRelocatable))));
} else {
// no? then we have to go the hard way...
+ if (variant.type() == QVariant::StringList) {
+ QStringList list = variant.toStringList();
+ for (int i = 0; i < list.count(); ++i) {
+ list[i] = QInstaller::replacePath(list.at(i), target,
+ QLatin1String(QInstaller::scRelocatable));
+ }
+ variant = QVariant::fromValue(list);
+ }
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
stream << variant;
@@ -394,18 +455,23 @@ QDomDocument UpdateOperation::toXml() const
/*!
Restores operation arguments and values from the XML document \a doc. Returns \c true on
- success, otherwise \c false.
+ success, otherwise \c false. \note: Clears all previously set values and arguments.
*/
bool UpdateOperation::fromXml(const QDomDocument &doc)
{
+ QString target = QCoreApplication::applicationDirPath();
+ QInstaller::isInBundle(target, &target); // Does not change target on non OSX platforms.
+
QStringList args;
const QDomElement root = doc.documentElement();
const QDomElement argsElem = root.firstChildElement(QLatin1String("arguments"));
Q_ASSERT(! argsElem.isNull());
for (QDomNode n = argsElem.firstChild(); ! n.isNull(); n = n.nextSibling()) {
const QDomElement e = n.toElement();
- if (!e.isNull() && e.tagName() == QLatin1String("argument"))
- args << e.text();
+ if (!e.isNull() && e.tagName() == QLatin1String("argument")) {
+ args << QInstaller::replacePath(e.text(), QLatin1String(QInstaller::scRelocatable),
+ target);
+ }
}
setArguments(args);
@@ -425,6 +491,14 @@ bool UpdateOperation::fromXml(const QDomDocument &doc)
if (t == QVariant::List || t == QVariant::StringList || !var.convert(t)) {
QDataStream stream(QByteArray::fromBase64( value.toLatin1()));
stream >> var;
+ if (t == QVariant::StringList) {
+ QStringList list = var.toStringList();
+ for (int i = 0; i < list.count(); ++i) {
+ list[i] = QInstaller::replacePath(list.at(i),
+ QLatin1String(QInstaller::scRelocatable), target);
+ }
+ var = QVariant::fromValue(list);
+ }
}
m_values[name] = var;
diff --git a/src/libs/kdtools/kdupdaterupdateoperation.h b/src/libs/kdtools/updateoperation.h
index 76fca727d..2216cf8f7 100644
--- a/src/libs/kdtools/kdupdaterupdateoperation.h
+++ b/src/libs/kdtools/updateoperation.h
@@ -31,16 +31,20 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_UPDATE_OPERATION_H
-#define KD_UPDATER_UPDATE_OPERATION_H
+#ifndef UPDATEOPERATION_H
+#define UPDATEOPERATION_H
-#include "kdupdater.h"
+#include "updater.h"
#include <QCoreApplication>
#include <QStringList>
#include <QVariant>
#include <QtXml/QDomDocument>
+namespace QInstaller {
+class PackageManagerCore;
+}
+
namespace KDUpdater {
class KDTOOLS_EXPORT UpdateOperation
@@ -54,7 +58,7 @@ public:
UserDefinedError = 128
};
- UpdateOperation();
+ explicit UpdateOperation(QInstaller::PackageManagerCore *core);
virtual ~UpdateOperation();
QString name() const;
@@ -73,11 +77,12 @@ public:
int error() const;
QStringList filesForDelayedDeletion() const;
+ QInstaller::PackageManagerCore *packageManager() const;
+
virtual void backup() = 0;
virtual bool performOperation() = 0;
virtual bool undoOperation() = 0;
virtual bool testOperation() = 0;
- virtual UpdateOperation *clone() const = 0;
virtual QDomDocument toXml() const;
virtual bool fromXml(const QString &xml);
@@ -89,6 +94,8 @@ protected:
void setError(int error, const QString &errorString = QString());
void registerForDelayedDeletion(const QStringList &files);
bool deleteFileNowOrLater(const QString &file, QString *errorString = 0);
+ bool checkArgumentCount(int minArgCount, int maxArgCount, const QString &argDescription = QString());
+ bool checkArgumentCount(int argCount);
private:
QString m_name;
@@ -97,8 +104,9 @@ private:
int m_error;
QVariantMap m_values;
QStringList m_delayedDeletionFiles;
+ QInstaller::PackageManagerCore *m_core;
};
} // namespace KDUpdater
-#endif // KD_UPDATER_UPDATE_OPERATION_H
+#endif // UPDATEOPERATION_H
diff --git a/src/libs/kdtools/kdupdaterupdateoperationfactory.cpp b/src/libs/kdtools/updateoperationfactory.cpp
index 161acbfd4..1df17d532 100644
--- a/src/libs/kdtools/kdupdaterupdateoperationfactory.cpp
+++ b/src/libs/kdtools/updateoperationfactory.cpp
@@ -31,10 +31,10 @@
**
****************************************************************************/
-#include "kdupdaterupdateoperationfactory.h"
-#include "kdupdaterupdateoperations.h"
+#include "updateoperationfactory.h"
-#include <QHash>
+#include "packagemanagercore.h"
+#include "updateoperations.h"
using namespace KDUpdater;
@@ -62,10 +62,13 @@ using namespace KDUpdater;
*/
/*!
+ \obsolete
\fn void KDUpdater::UpdateOperationFactory::registerUpdateOperation(const QString &name)
Registers a new update operation with the factory based on \a name. When create() is called
with that \a name, the update operation is constructed using its default constructor.
+
+ Deprecated. Use registerProduct() instead.
*/
/*!
diff --git a/src/libs/kdtools/kdupdaterupdateoperationfactory.h b/src/libs/kdtools/updateoperationfactory.h
index e60442277..5e81900fa 100644
--- a/src/libs/kdtools/kdupdaterupdateoperationfactory.h
+++ b/src/libs/kdtools/updateoperationfactory.h
@@ -31,18 +31,23 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_UPDATE_OPERATION_FACTORY_H
-#define KD_UPDATER_UPDATE_OPERATION_FACTORY_H
+#ifndef UPDATEOPERATIONFACTORY_H
+#define UPDATEOPERATIONFACTORY_H
-#include <kdgenericfactory.h>
+#include "genericfactory.h"
-#include "kdupdater.h"
+#include "updater.h"
+
+namespace QInstaller {
+class PackageManagerCore;
+}
namespace KDUpdater {
class UpdateOperation;
-class KDTOOLS_EXPORT UpdateOperationFactory : public KDGenericFactory<UpdateOperation>
+class KDTOOLS_EXPORT UpdateOperationFactory : public GenericFactory<UpdateOperation, QString,
+ QInstaller::PackageManagerCore*>
{
Q_DISABLE_COPY(UpdateOperationFactory)
@@ -55,10 +60,10 @@ public:
registerProduct<T>(name);
}
-protected:
+private:
UpdateOperationFactory();
};
} // namespace KDUpdater
-#endif // KD_UPDATER_UPDATE_OPERATION_FACTORY_H
+#endif // UPDATEOPERATIONFACTORY_H
diff --git a/src/libs/kdtools/kdupdaterupdateoperations.cpp b/src/libs/kdtools/updateoperations.cpp
index ed215e9b9..aeeaffe7b 100644
--- a/src/libs/kdtools/kdupdaterupdateoperations.cpp
+++ b/src/libs/kdtools/updateoperations.cpp
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#include "kdupdaterupdateoperations.h"
+#include "updateoperations.h"
#include "errors.h"
#include "fileutils.h"
@@ -98,7 +98,8 @@ static QString backupFileName(const QString &templateName)
// KDUpdater::CopyOperation
////////////////////////////////////////////////////////////////////////////
-CopyOperation::CopyOperation()
+CopyOperation::CopyOperation(QInstaller::PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Copy"));
}
@@ -138,18 +139,15 @@ void CopyOperation::backup()
// race condition: The backup file could get created by another process right now. But this is the same
// in QFile::copy...
if (!QFile::rename(destination, value(QLatin1String("backupOfExistingDestination")).toString()))
- setError(UserDefinedError, tr("Could not backup file %1.").arg(destination));
+ setError(UserDefinedError, tr("Cannot backup file \"%1\".").arg(QDir::toNativeSeparators(destination)));
}
bool CopyOperation::performOperation()
{
// We need two args to complete the copy operation. First arg provides the complete file name of source
// Second arg provides the complete file name of dest
- if (arguments().count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments: %1 arguments given, 2 expected.").arg(arguments().count()));
+ if (!checkArgumentCount(2))
return false;
- }
QString source = sourcePath();
QString destination = destinationPath();
@@ -157,7 +155,7 @@ bool CopyOperation::performOperation()
QFile sourceFile(source);
if (!sourceFile.exists()) {
setError(UserDefinedError);
- setErrorString(tr("Could not copy a non-existent file: %1").arg(source));
+ setErrorString(tr("Cannot copy a non-existent file: %1").arg(QDir::toNativeSeparators(source)));
return false;
}
// If destination file exists, we cannot use QFile::copy() because it does not overwrite an existing
@@ -166,7 +164,8 @@ bool CopyOperation::performOperation()
if (destinationFile.exists()) {
if (!destinationFile.remove()) {
setError(UserDefinedError);
- setErrorString(tr("Could not remove destination file %1: %2").arg(destination, destinationFile.errorString()));
+ setErrorString(tr("Cannot remove file \"%1\": %2").arg(
+ QDir::toNativeSeparators(destination), destinationFile.errorString()));
return false;
}
}
@@ -174,7 +173,9 @@ bool CopyOperation::performOperation()
const bool copied = sourceFile.copy(destination);
if (!copied) {
setError(UserDefinedError);
- setErrorString(tr("Could not copy %1 to %2: %3").arg(source, destination, sourceFile.errorString()));
+ setErrorString(tr("Cannot copy file \"%1\" to \"%2\": %3").arg(
+ QDir::toNativeSeparators(source), QDir::toNativeSeparators(destination),
+ sourceFile.errorString()));
}
return copied;
}
@@ -191,7 +192,8 @@ bool CopyOperation::undoOperation()
QFile destFile(destination);
// first remove the dest
if (destFile.exists() && !destFile.remove()) {
- setError(UserDefinedError, tr("Could not delete file %1: %2").arg(destination, destFile.errorString()));
+ setError(UserDefinedError, tr("Cannot delete file \"%1\": %2").arg(
+ QDir::toNativeSeparators(destination), destFile.errorString()));
return false;
}
@@ -204,7 +206,8 @@ bool CopyOperation::undoOperation()
// otherwise we have to copy the backup back:
const bool success = backupFile.rename(destination);
if (!success)
- setError(UserDefinedError, tr("Could not restore backup file into %1: %2").arg(destination, backupFile.errorString()));
+ setError(UserDefinedError, tr("Cannot restore backup file into \"%1\": %2").arg(
+ QDir::toNativeSeparators(destination), backupFile.errorString()));
return success;
}
@@ -232,17 +235,13 @@ bool CopyOperation::testOperation()
return true;
}
-CopyOperation *CopyOperation::clone() const
-{
- return new CopyOperation();
-}
-
////////////////////////////////////////////////////////////////////////////
// KDUpdater::MoveOperation
////////////////////////////////////////////////////////////////////////////
-MoveOperation::MoveOperation()
+MoveOperation::MoveOperation(QInstaller::PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Move"));
}
@@ -265,37 +264,36 @@ void MoveOperation::backup()
// race condition: The backup file could get created by another process right now. But this is the same
// in QFile::copy...
if (!QFile::rename(dest, value(QLatin1String("backupOfExistingDestination")).toString()))
- setError(UserDefinedError, tr("Could not backup file %1.").arg(dest));
+ setError(UserDefinedError, tr("Cannot backup file \"%1\".").arg(QDir::toNativeSeparators(dest)));
}
bool MoveOperation::performOperation()
{
// We need two args to complete the copy operation. // First arg provides the complete file name of
// source, second arg provides the complete file name of dest
- const QStringList args = this->arguments();
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments: %1 arguments given, 2 expected.").arg(args.count()));
+ if (!checkArgumentCount(2))
return false;
- }
- const QString dest = args.last();
+ const QStringList args = arguments();
+ const QString dest = args.at(1);
// If destination file exists, then we cannot use QFile::copy() because it does not overwrite an existing
// file. So we remove the destination file.
if (QFile::exists(dest)) {
QFile file(dest);
if (!file.remove(dest)) {
setError(UserDefinedError);
- setErrorString(tr("Could not remove destination file %1: %2").arg(dest, file.errorString()));
+ setErrorString(tr("Cannot remove file \"%1\": %2").arg(
+ QDir::toNativeSeparators(dest), file.errorString()));
return false;
}
}
// Copy source to destination.
- QFile file(args.first());
+ QFile file(args.at(0));
if (!file.copy(dest)) {
setError(UserDefinedError);
- setErrorString(tr("Could not copy %1 to %2: %3").arg(file.fileName(), dest, file.errorString()));
+ setErrorString(tr("Cannot copy file \"%1\" to \"%2\": %3").arg(QDir::toNativeSeparators(file.fileName()),
+ QDir::toNativeSeparators(dest), file.errorString()));
return false;
}
return deleteFileNowOrLater(file.fileName());
@@ -308,13 +306,14 @@ bool MoveOperation::undoOperation()
// first: copy back the destination to source
QFile destF(dest);
if (!destF.copy(args.first())) {
- setError(UserDefinedError, tr("Cannot copy %1 to %2: %3").arg(dest, args.first(), destF.errorString()));
+ setError(UserDefinedError, tr("Cannot copy file \"%1\" to \"%2\": %3").arg(
+ QDir::toNativeSeparators(dest), QDir::toNativeSeparators(args.first()), destF.errorString()));
return false;
}
// second: delete the move destination
if (!deleteFileNowOrLater(dest)) {
- setError(UserDefinedError, tr("Cannot remove file %1."));
+ setError(UserDefinedError, tr("Cannot remove file \"%1\".").arg(QDir::toNativeSeparators(dest)));
return false;
}
@@ -327,7 +326,8 @@ bool MoveOperation::undoOperation()
QFile backupF(value(QLatin1String("backupOfExistingDestination")).toString());
const bool success = backupF.rename(dest);
if (!success)
- setError(UserDefinedError, tr("Cannot restore backup file for %1: %2").arg(dest, backupF.errorString()));
+ setError(UserDefinedError, tr("Cannot restore backup file for \"%1\": %2").arg(
+ QDir::toNativeSeparators(dest), backupF.errorString()));
return success;
}
@@ -338,17 +338,13 @@ bool MoveOperation::testOperation()
return true;
}
-MoveOperation *MoveOperation::clone() const
-{
- return new MoveOperation;
-}
-
////////////////////////////////////////////////////////////////////////////
// KDUpdater::DeleteOperation
////////////////////////////////////////////////////////////////////////////
-DeleteOperation::DeleteOperation()
+DeleteOperation::DeleteOperation(QInstaller::PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Delete"));
}
@@ -365,19 +361,17 @@ void DeleteOperation::backup()
QFile file(fileName);
if (!file.copy(value(QLatin1String("backupOfExistingFile")).toString()))
- setError(UserDefinedError, tr("Cannot create backup of %1: %2").arg(fileName, file.errorString()));
+ setError(UserDefinedError, tr("Cannot create backup of file \"%1\": %2").arg(
+ QDir::toNativeSeparators(fileName), file.errorString()));
}
bool DeleteOperation::performOperation()
{
// Requires only one parameter. That is the name of the file to remove.
- const QStringList args = this->arguments();
- if (args.count() != 1) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments: %1 arguments given, 1 expected.").arg(args.count()));
+ if (!checkArgumentCount(1))
return false;
- }
- return deleteFileNowOrLater(args.first());
+
+ return deleteFileNowOrLater(arguments().at(0));
}
bool DeleteOperation::undoOperation()
@@ -389,7 +383,8 @@ bool DeleteOperation::undoOperation()
QFile backupF(value(QLatin1String("backupOfExistingFile")).toString());
const bool success = backupF.copy(fileName) && deleteFileNowOrLater(backupF.fileName());
if (!success)
- setError(UserDefinedError, tr("Cannot restore backup file for %1: %2").arg(fileName, backupF.errorString()));
+ setError(UserDefinedError, tr("Cannot restore backup file for \"%1\": %2").arg(
+ QDir::toNativeSeparators(fileName), backupF.errorString()));
return success;
}
@@ -399,11 +394,6 @@ bool DeleteOperation::testOperation()
return true;
}
-DeleteOperation *DeleteOperation::clone() const
-{
- return new DeleteOperation;
-}
-
/*!
\reimp
*/
@@ -426,7 +416,8 @@ QDomDocument DeleteOperation::toXml() const
// KDUpdater::MkdirOperation
////////////////////////////////////////////////////////////////////////////
-MkdirOperation::MkdirOperation()
+MkdirOperation::MkdirOperation(QInstaller::PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Mkdir"));
}
@@ -458,18 +449,15 @@ void MkdirOperation::backup()
bool MkdirOperation::performOperation()
{
// Requires only one parameter. That is the path which should be created
- QStringList args = this->arguments();
- if (args.count() != 1) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments: %1 arguments given, 1 expected.").arg(args.count()));
+ if (!checkArgumentCount(1))
return false;
- }
- const QString dirName = args.first();
+ const QString dirName = arguments().at(0);
const bool created = QDir::root().mkpath(dirName);
if (!created) {
setError(UserDefinedError);
- setErrorString(tr("Could not create folder %1: Unknown error.").arg(dirName));
+ setErrorString(tr("Cannot create directory \"%1\": %2").arg(
+ QDir::toNativeSeparators(dirName), tr("Unknown error.")));
}
return created;
}
@@ -501,9 +489,11 @@ bool MkdirOperation::undoOperation()
if (!result) {
if (errorString.isEmpty())
- setError(UserDefinedError, tr("Cannot remove directory %1: %2").arg(createdDir.path(), errorString));
+ setError(UserDefinedError, tr("Cannot remove directory \"%1\": %2").arg(
+ QDir::toNativeSeparators(createdDir.path()), errorString));
else
- setError(UserDefinedError, tr("Cannot remove directory %1: %2").arg(createdDir.path(), errnoToQString(errno)));
+ setError(UserDefinedError, tr("Cannot remove directory \"%1\": %2").arg(
+ QDir::toNativeSeparators(createdDir.path()), errnoToQString(errno)));
}
return result;
}
@@ -514,16 +504,13 @@ bool KDUpdater::MkdirOperation::testOperation()
return true;
}
-MkdirOperation *MkdirOperation::clone() const
-{
- return new MkdirOperation;
-}
////////////////////////////////////////////////////////////////////////////
// KDUpdater::RmdirOperation
////////////////////////////////////////////////////////////////////////////
-RmdirOperation::RmdirOperation()
+RmdirOperation::RmdirOperation(QInstaller::PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Rmdir"));
setValue(QLatin1String("removed"), false);
@@ -537,26 +524,25 @@ void RmdirOperation::backup()
bool RmdirOperation::performOperation()
{
// Requires only one parameter. That is the name of the file to remove.
- const QStringList args = this->arguments();
- if (args.count() != 1) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments: %1 arguments given, 1 expected.").arg(args.count()));
+ if (!checkArgumentCount(1))
return false;
- }
- QDir dir(args.first());
+ const QString firstArg = arguments().at(0);
+ QDir dir(firstArg);
if (!dir.exists()) {
setError(UserDefinedError);
- setErrorString(tr("Could not remove folder %1: The folder does not exist.").arg(args.first()));
+ setErrorString(tr("Cannot remove directory \"%1\": %2").arg(
+ QDir::toNativeSeparators(firstArg), tr("The directory does not exist.")));
return false;
}
errno = 0;
- const bool removed = dir.rmdir(args.first());
+ const bool removed = dir.rmdir(firstArg);
setValue(QLatin1String("removed"), removed);
if (!removed) {
setError(UserDefinedError);
- setErrorString(tr("Could not remove folder %1: %2").arg(args.first(), errnoToQString(errno)));
+ setErrorString(tr("Cannot remove directory \"%1\": %2").arg(
+ QDir::toNativeSeparators(firstArg), errnoToQString(errno)));
}
return removed;
}
@@ -570,7 +556,8 @@ bool RmdirOperation::undoOperation()
const QFileInfo fi(arguments().first());
const bool success = fi.dir().mkdir(fi.fileName());
if( !success)
- setError(UserDefinedError, tr("Cannot recreate directory %1: %2").arg(fi.fileName(), errnoToQString(errno)));
+ setError(UserDefinedError, tr("Cannot recreate directory \"%1\": %2").arg(
+ QDir::toNativeSeparators(fi.fileName()), errnoToQString(errno)));
return success;
}
@@ -581,17 +568,13 @@ bool RmdirOperation::testOperation()
return true;
}
-RmdirOperation *RmdirOperation::clone() const
-{
- return new RmdirOperation;
-}
-
////////////////////////////////////////////////////////////////////////////
// KDUpdater::AppendFileOperation
////////////////////////////////////////////////////////////////////////////
-AppendFileOperation::AppendFileOperation()
+AppendFileOperation::AppendFileOperation(QInstaller::PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("AppendFile"));
}
@@ -606,7 +589,8 @@ void AppendFileOperation::backup()
setValue(QLatin1String("backupOfFile"), backupFileName(filename));
if (!file.copy(value(QLatin1String("backupOfFile")).toString())) {
- setError(UserDefinedError, tr("Cannot backup file %1: %2").arg(filename, file.errorString()));
+ setError(UserDefinedError, tr("Cannot backup file \"%1\": %2").arg(
+ QDir::toNativeSeparators(filename), file.errorString()));
clearValue(QLatin1String("backupOfFile"));
}
}
@@ -615,15 +599,11 @@ bool AppendFileOperation::performOperation()
{
// This operation takes two arguments. First argument is the name of the file into which a text has to be
// appended. Second argument is the text to append.
- const QStringList args = this->arguments();
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 2"), QLatin1String("")));
+ if (!checkArgumentCount(2))
return false;
- }
- const QString fName = args.first();
+ const QStringList args = this->arguments();
+ const QString fName = args.at(0);
QFile file(fName);
if (!file.open(QFile::Append)) {
// first we rename the file, then we copy it to the real target and open the copy - the renamed original is then marked for deletion
@@ -645,14 +625,15 @@ bool AppendFileOperation::performOperation()
if (error) {
setError(UserDefinedError);
- setErrorString(tr("Could not open file '%1' for writing: %2").arg(file.fileName(), file.errorString()));
+ setErrorString(tr("Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(file.fileName()), file.errorString()));
return false;
}
deleteFileNowOrLater(newName);
}
QTextStream ts(&file);
- ts << args.last();
+ ts << args.at(1);
file.close();
return true;
@@ -664,13 +645,15 @@ bool AppendFileOperation::undoOperation()
const QString filename = arguments().first();
const QString backupOfFile = value(QLatin1String("backupOfFile")).toString();
if (!backupOfFile.isEmpty() && !QFile::exists(backupOfFile)) {
- setError(UserDefinedError, tr("Cannot find backup file for %1.").arg(filename));
+ setError(UserDefinedError, tr("Cannot find backup file for \"%1\".").arg(
+ QDir::toNativeSeparators(filename)));
return false;
}
const bool removed = deleteFileNowOrLater(filename);
if (!removed) {
- setError(UserDefinedError, tr("Could not restore backup file for %1.").arg(filename));
+ setError(UserDefinedError, tr("Cannot restore backup file for \"%1\".").arg(
+ QDir::toNativeSeparators(filename)));
return false;
}
@@ -681,7 +664,8 @@ bool AppendFileOperation::undoOperation()
QFile backupFile(backupOfFile);
const bool success = backupFile.rename(filename);
if (!success)
- setError(UserDefinedError, tr("Could not restore backup file for %1: %2").arg(filename, backupFile.errorString()));
+ setError(UserDefinedError, tr("Cannot restore backup file for \"%1\": %2").arg(
+ QDir::toNativeSeparators(filename), backupFile.errorString()));
return success;
}
@@ -691,17 +675,13 @@ bool AppendFileOperation::testOperation()
return true;
}
-AppendFileOperation *AppendFileOperation::clone() const
-{
- return new AppendFileOperation;
-}
-
////////////////////////////////////////////////////////////////////////////
// KDUpdater::PrependFileOperation
////////////////////////////////////////////////////////////////////////////
-PrependFileOperation::PrependFileOperation()
+PrependFileOperation::PrependFileOperation(QInstaller::PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("PrependFile"));
}
@@ -716,7 +696,8 @@ void PrependFileOperation::backup()
setValue(QLatin1String("backupOfFile"), backupFileName(filename));
if (!file.copy(value(QLatin1String("backupOfFile")).toString())) {
- setError(UserDefinedError, tr("Cannot backup file %1: %2").arg(filename, file.errorString()));
+ setError(UserDefinedError, tr("Cannot backup file \"%1\": %2").arg(
+ QDir::toNativeSeparators(filename), file.errorString()));
clearValue(QLatin1String("backupOfFile"));
}
}
@@ -726,19 +707,17 @@ bool PrependFileOperation::performOperation()
// This operation takes two arguments. First argument is the name
// of the file into which a text has to be appended. Second argument
// is the text to append.
- const QStringList args = this->arguments();
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments: %1 arguments given, 2 expected.").arg(args.count()));
+ if (!checkArgumentCount(2))
return false;
- }
- const QString fName = args.first();
+ const QStringList args = this->arguments();
+ const QString fName = args.at(0);
// Load the file first.
QFile file(fName);
if (!file.open(QFile::ReadOnly)) {
setError(UserDefinedError);
- setErrorString(tr("Could not open file %1 for reading: %2").arg(file.fileName(), file.errorString()));
+ setErrorString(tr("Cannot open file \"%1\" for reading: %2").arg(
+ QDir::toNativeSeparators(file.fileName()), file.errorString()));
return false;
}
@@ -747,7 +726,7 @@ bool PrependFileOperation::performOperation()
file.close();
// Prepend text to the file text
- fContents = args.last() + fContents;
+ fContents = args.at(1) + fContents;
// Now re-open the file in write only mode.
if (!file.open(QFile::WriteOnly)) {
@@ -756,7 +735,8 @@ bool PrependFileOperation::performOperation()
if (!QFile::rename(fName, newName) && QFile::copy(newName, fName) && file.open(QFile::WriteOnly)) {
QFile::rename(newName, fName);
setError(UserDefinedError);
- setErrorString(tr("Could not open file %1 for writing: %2").arg(file.fileName(), file.errorString()));
+ setErrorString(tr("Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(file.fileName()), file.errorString()));
return false;
}
deleteFileNowOrLater(newName);
@@ -774,12 +754,14 @@ bool PrependFileOperation::undoOperation()
const QString filename = arguments().first();
const QString backupOfFile = value(QLatin1String("backupOfFile")).toString();
if (!backupOfFile.isEmpty() && !QFile::exists(backupOfFile)) {
- setError(UserDefinedError, tr("Cannot find backup file for %1.").arg(filename));
+ setError(UserDefinedError,
+ tr("Cannot find backup file for \"%1\".").arg(QDir::toNativeSeparators(filename)));
return false;
}
if (!deleteFileNowOrLater(filename)) {
- setError(UserDefinedError, tr("Cannot restore backup file for %1.").arg(filename));
+ setError(UserDefinedError,
+ tr("Cannot restore backup file for \"%1\".").arg(QDir::toNativeSeparators(filename)));
return false;
}
@@ -790,7 +772,8 @@ bool PrependFileOperation::undoOperation()
QFile backupF(backupOfFile);
const bool success = backupF.rename(filename);
if (!success)
- setError(UserDefinedError, tr("Cannot restore backup file for %1: %2").arg(filename, backupF.errorString()));
+ setError(UserDefinedError, tr("Cannot restore backup file for \"%1\": %2").arg(
+ QDir::toNativeSeparators(filename), backupF.errorString()));
return success;
}
@@ -800,8 +783,3 @@ bool PrependFileOperation::testOperation()
// TODO
return true;
}
-
-PrependFileOperation *PrependFileOperation::clone() const
-{
- return new PrependFileOperation;
-}
diff --git a/src/libs/kdtools/kdupdaterupdateoperations.h b/src/libs/kdtools/updateoperations.h
index fec24c8c9..1c6c6ea97 100644
--- a/src/libs/kdtools/kdupdaterupdateoperations.h
+++ b/src/libs/kdtools/updateoperations.h
@@ -31,24 +31,23 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_UPDATE_OPERATIONS_H
-#define KD_UPDATER_UPDATE_OPERATIONS_H
+#ifndef UPDATEOPERATIONS_H
+#define UPDATEOPERATIONS_H
-#include "kdupdaterupdateoperation.h"
+#include "updateoperation.h"
namespace KDUpdater {
class KDTOOLS_EXPORT CopyOperation : public UpdateOperation
{
public:
- CopyOperation();
+ explicit CopyOperation(QInstaller::PackageManagerCore *core = 0);
~CopyOperation();
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- CopyOperation *clone() const;
QDomDocument toXml() const;
private:
@@ -59,27 +58,25 @@ private:
class KDTOOLS_EXPORT MoveOperation : public UpdateOperation
{
public:
- MoveOperation();
+ explicit MoveOperation(QInstaller::PackageManagerCore *core = 0);
~MoveOperation();
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- MoveOperation *clone() const;
};
class KDTOOLS_EXPORT DeleteOperation : public UpdateOperation
{
public:
- DeleteOperation();
+ explicit DeleteOperation(QInstaller::PackageManagerCore *core = 0);
~DeleteOperation();
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- DeleteOperation *clone() const;
QDomDocument toXml() const;
};
@@ -87,51 +84,47 @@ public:
class KDTOOLS_EXPORT MkdirOperation : public UpdateOperation
{
public:
- MkdirOperation();
+ explicit MkdirOperation(QInstaller::PackageManagerCore *core = 0);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- MkdirOperation *clone() const;
};
class KDTOOLS_EXPORT RmdirOperation : public UpdateOperation
{
public:
- RmdirOperation();
+ RmdirOperation(QInstaller::PackageManagerCore *core = 0);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- RmdirOperation *clone() const;
};
class KDTOOLS_EXPORT AppendFileOperation : public UpdateOperation
{
public:
- AppendFileOperation();
+ explicit AppendFileOperation(QInstaller::PackageManagerCore *core = 0);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- AppendFileOperation *clone() const;
};
class KDTOOLS_EXPORT PrependFileOperation : public UpdateOperation
{
public:
- PrependFileOperation();
+ explicit PrependFileOperation(QInstaller::PackageManagerCore *core = 0);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- PrependFileOperation *clone() const;
};
} // namespace KDUpdater
-#endif // KD_UPDATER_UPDATE_OPERATIONS_H
+#endif // UPDATEOPERATIONS_H
diff --git a/src/libs/kdtools/kdupdater.h b/src/libs/kdtools/updater.h
index c38bf7de2..89ce0acb4 100644
--- a/src/libs/kdtools/kdupdater.h
+++ b/src/libs/kdtools/updater.h
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_H
-#define KD_UPDATER_H
+#ifndef UPDATER_H
+#define UPDATER_H
#include "kdtoolsglobal.h"
@@ -50,4 +50,4 @@ namespace KDUpdater
KDTOOLS_EXPORT int compareVersion(const QString &v1, const QString &v2);
}
-#endif
+#endif // UPDATER_H
diff --git a/src/libs/kdtools/kdupdaterupdatesinfo.cpp b/src/libs/kdtools/updatesinfo.cpp
index 7c80e135a..414ba28a7 100644
--- a/src/libs/kdtools/kdupdaterupdatesinfo.cpp
+++ b/src/libs/kdtools/updatesinfo.cpp
@@ -31,9 +31,10 @@
**
****************************************************************************/
-#include "kdupdaterupdatesinfo_p.h"
+#include "updatesinfo_p.h"
#include "utils.h"
+#include <QDomDocument>
#include <QFile>
#include <QLocale>
#include <QPair>
@@ -62,7 +63,7 @@ void UpdatesInfoData::parseFile(const QString &updateXmlFile)
QFile file(updateXmlFile);
if (!file.open(QFile::ReadOnly)) {
error = UpdatesInfo::CouldNotReadUpdateInfoFileError;
- errorMessage = tr("Could not read \"%1\"").arg(updateXmlFile);
+ errorMessage = tr("Cannot read \"%1\"").arg(updateXmlFile);
return;
}
@@ -143,6 +144,8 @@ bool UpdatesInfoData::parsePackageUpdateElement(const QDomElement &updateE)
info.data.insert(QLatin1String("inheritVersionFrom"),
childE.attribute(QLatin1String("inheritVersionFrom")));
info.data[childE.tagName()] = childE.text();
+ } else if (childE.tagName() == QLatin1String("DisplayName")) {
+ processLocalizedTag(childE, info.data);
} else if (childE.tagName() == QLatin1String("Description")) {
if (!childE.hasAttribute(QLatin1String("xml:lang")))
info.data[QLatin1String("Description")] = childE.text();
@@ -183,6 +186,17 @@ bool UpdatesInfoData::parsePackageUpdateElement(const QDomElement &updateE)
return true;
}
+void UpdatesInfoData::processLocalizedTag(const QDomElement &childE, QHash<QString, QVariant> &info) const
+{
+ QString languageAttribute = childE.attribute(QLatin1String("xml:lang")).toLower();
+ if (!info.contains(childE.tagName()) && (languageAttribute.isEmpty()))
+ info[childE.tagName()] = childE.text();
+
+ // overwrite default if we have a language specific description
+ if (QLocale().name().startsWith(languageAttribute, Qt::CaseInsensitive))
+ info[childE.tagName()] = childE.text();
+}
+
//
// UpdatesInfo
diff --git a/src/libs/kdtools/kdupdaterupdatesinfo_p.h b/src/libs/kdtools/updatesinfo_p.h
index eb841417f..cb98b5a54 100644
--- a/src/libs/kdtools/kdupdaterupdatesinfo_p.h
+++ b/src/libs/kdtools/updatesinfo_p.h
@@ -31,11 +31,11 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_UPDATE_INFO_H
-#define KD_UPDATER_UPDATE_INFO_H
+#ifndef UPDATESINFO_P_H
+#define UPDATESINFO_P_H
-#include "kdupdater.h"
-#include "kdupdaterupdatesinfodata_p.h"
+#include "updater.h"
+#include "updatesinfodata_p.h"
#include <QHash>
#include <QSharedData>
@@ -87,4 +87,4 @@ private:
} // namespace KDUpdater
-#endif // KD_UPDATER_UPDATE_INFO_H
+#endif // UPDATESINFO_P_H
diff --git a/src/libs/kdtools/kdupdaterupdatesinfodata_p.h b/src/libs/kdtools/updatesinfodata_p.h
index be1cc217e..eeac18130 100644
--- a/src/libs/kdtools/kdupdaterupdatesinfodata_p.h
+++ b/src/libs/kdtools/updatesinfodata_p.h
@@ -31,13 +31,14 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_UPDATE_INFO_DATA_H
-#define KD_UPDATER_UPDATE_INFO_DATA_H
+#ifndef UPDATESINFODATA_P_H
+#define UPDATESINFODATA_P_H
#include <QCoreApplication>
-#include <QDomElement>
#include <QSharedData>
+QT_FORWARD_DECLARE_CLASS(QDomElement)
+
namespace KDUpdater {
struct UpdateInfo;
@@ -61,8 +62,11 @@ public:
bool parsePackageUpdateElement(const QDomElement &updateE);
void setInvalidContentError(const QString &detail);
+
+private:
+ void processLocalizedTag(const QDomElement &childE, QHash<QString, QVariant> &info) const;
};
} // namespace KDUpdater
-#endif // KD_UPDATER_UPDATE_INFO_DATA_H
+#endif // UPDATESINFODATA_P_H
diff --git a/src/libs/libs.pro b/src/libs/libs.pro
index 2189c02e7..3982bc8a1 100644
--- a/src/libs/libs.pro
+++ b/src/libs/libs.pro
@@ -1,3 +1,3 @@
-CONFIG += ordered
TEMPLATE = subdirs
SUBDIRS += 7zip installer
+installer.depends = 7zip
diff --git a/src/sdk/installerbase.cpp b/src/sdk/installerbase.cpp
index 82a08411b..66503b334 100644
--- a/src/sdk/installerbase.cpp
+++ b/src/sdk/installerbase.cpp
@@ -41,7 +41,7 @@
#include <copydirectoryoperation.h>
#include <errors.h>
#include <init.h>
-#include <kdupdaterupdateoperations.h>
+#include <updateoperations.h>
#include <messageboxhandler.h>
#include <packagemanagercore.h>
#include <packagemanagerproxyfactory.h>
@@ -52,8 +52,8 @@
#include <utils.h>
#include <globals.h>
-#include <kdrunoncechecker.h>
-#include <kdupdaterfiledownloaderfactory.h>
+#include <runoncechecker.h>
+#include <filedownloaderfactory.h>
#include <QDirIterator>
#include <QTemporaryFile>
@@ -75,13 +75,13 @@ InstallerBase::~InstallerBase()
int InstallerBase::run()
{
- KDRunOnceChecker runCheck(qApp->applicationDirPath() + QLatin1String("/lockmyApp1234865.lock"));
- if (runCheck.isRunning(KDRunOnceChecker::ConditionFlag::Lockfile)) {
+ RunOnceChecker runCheck(qApp->applicationDirPath() + QLatin1String("/lockmyApp1234865.lock"));
+ if (runCheck.isRunning(RunOnceChecker::ConditionFlag::Lockfile)) {
// It is possible to install an application and thus the maintenance tool into a
// directory that requires elevated permission to create a lock file. Since this
// cannot be done without requesting credentials from the user, we silently ignore
// the fact that we could not create the lock file and check the running processes.
- if (runCheck.isRunning(KDRunOnceChecker::ConditionFlag::ProcessList)) {
+ if (runCheck.isRunning(RunOnceChecker::ConditionFlag::ProcessList)) {
QInstaller::MessageBoxHandler::information(0, QLatin1String("AlreadyRunning"),
QString::fromLatin1("Waiting for %1").arg(qAppName()),
QString::fromLatin1("Another %1 instance is already running. Wait "
@@ -128,7 +128,7 @@ int InstallerBase::run()
qCDebug(QInstaller::lcTranslations) << "Language:" << QLocale().uiLanguages()
.value(0, QLatin1String("No UI language set")).toUtf8().constData();
- qDebug() << "Arguments: " << arguments().join(QLatin1String(", ")).toUtf8().constData();
+ qDebug().noquote() << "Arguments:" << arguments().join(QLatin1String(", "));
SDKApp::registerMetaResources(manager.collectionByName("QResources"));
if (parser.isSet(QLatin1String(CommandLineOptions::StartClient))) {
@@ -314,6 +314,6 @@ QStringList InstallerBase::repositories(const QString &list) const
{
const QStringList items = list.split(QLatin1Char(','), QString::SkipEmptyParts);
foreach (const QString &item, items)
- qDebug() << "Adding custom repository:" << item.toUtf8().constData();
+ qDebug().noquote() << "Adding custom repository:" << item;
return items;
}
diff --git a/src/sdk/installerbase.qrc b/src/sdk/installerbase.qrc
index 3358e87c3..5fabefc35 100644
--- a/src/sdk/installerbase.qrc
+++ b/src/sdk/installerbase.qrc
@@ -2,6 +2,7 @@
<qresource prefix="/">
<file>translations/de.qm</file>
<file>translations/en.qm</file>
+ <file>translations/es.qm</file>
<file>translations/fr.qm</file>
<file>translations/it.qm</file>
<file>translations/ja.qm</file>
@@ -15,5 +16,6 @@
<file alias="translations/qt_ru.qm">translations/qtbase_ru.qm</file>
<file>translations/qt_zh_CN.qm</file>
<file alias="translations/qt_it.qm">translations/qtbase_it.qm</file>
+ <file>translations/qt_es.qm</file>
</qresource>
</RCC>
diff --git a/src/sdk/installerbasecommons.cpp b/src/sdk/installerbasecommons.cpp
index 717eb2039..8ba769ece 100644
--- a/src/sdk/installerbasecommons.cpp
+++ b/src/sdk/installerbasecommons.cpp
@@ -36,6 +36,7 @@
#include <scriptengine.h>
#include <packagemanagerpagefactory.h>
#include <productkeycheck.h>
+#include <settings.h>
using namespace QInstaller;
@@ -86,17 +87,24 @@ MaintenanceGui::MaintenanceGui(PackageManagerCore *core)
}
IntroductionPage *intro = new IntroductionPage(core);
- connect(intro, SIGNAL(packageManagerCoreTypeChanged()), this, SLOT(updateRestartPage()));
+ connect(intro, &IntroductionPage::packageManagerCoreTypeChanged,
+ this, &MaintenanceGui::updateRestartPage);
+
+ if (!core->isOfflineOnly() || validRepositoriesAvailable()) {
+ setPage(PackageManagerCore::Introduction, intro);
+ setPage(PackageManagerCore::ComponentSelection, new ComponentSelectionPage(core));
+ setPage(PackageManagerCore::LicenseCheck, new LicenseAgreementPage(core));
+ } else {
+ core->setUninstaller();
+ core->setCompleteUninstallation(true);
+ }
- setPage(PackageManagerCore::Introduction, intro);
- setPage(PackageManagerCore::ComponentSelection, new ComponentSelectionPage(core));
- setPage(PackageManagerCore::LicenseCheck, new LicenseAgreementPage(core));
setPage(PackageManagerCore::ReadyForInstallation, new ReadyForInstallationPage(core));
setPage(PackageManagerCore::PerformInstallation, new PerformInstallationPage(core));
setPage(PackageManagerCore::InstallationFinished, new FinishedPage(core));
RestartPage *p = new RestartPage(core);
- connect(p, SIGNAL(restart()), this, SIGNAL(gotRestarted()));
+ connect(p, &RestartPage::restart, this, &PackageManagerGui::gotRestarted);
setPage(PackageManagerCore::InstallationFinished + 1, p);
if (core->isUninstaller())
@@ -114,3 +122,13 @@ void MaintenanceGui::updateRestartPage()
wizardPageVisibilityChangeRequested((packageManagerCore()->isUninstaller() ? false : true),
PackageManagerCore::InstallationFinished + 1);
}
+
+bool MaintenanceGui::validRepositoriesAvailable() const
+{
+ foreach (const Repository &repo, packageManagerCore()->settings().repositories()) {
+ if (repo.isEnabled() && repo.isValid()) {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/sdk/installerbasecommons.h b/src/sdk/installerbasecommons.h
index c8fb707ec..7352459d1 100644
--- a/src/sdk/installerbasecommons.h
+++ b/src/sdk/installerbasecommons.h
@@ -61,6 +61,9 @@ public:
private Q_SLOTS:
void updateRestartPage();
+
+private:
+ bool validRepositoriesAvailable() const;
};
#endif // INSTALLERBASECOMMONS_H
diff --git a/src/sdk/main.cpp b/src/sdk/main.cpp
index f8e055b7b..414003c1d 100644
--- a/src/sdk/main.cpp
+++ b/src/sdk/main.cpp
@@ -39,7 +39,7 @@
#include "updatechecker.h"
#include <errors.h>
-#include <kdselfrestarter.h>
+#include <selfrestarter.h>
#include <remoteserver.h>
#include <utils.h>
@@ -56,9 +56,9 @@
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
-#define VERSION "IFW Version: \"" QUOTE(IFW_VERSION_STR) "\""
-#define BUILDDATE "Build date: " QUOTE(__DATE__)
-#define SHA "Installer Framework SHA1: \"" QUOTE(_GIT_SHA1_) "\""
+#define VERSION "IFW Version: " QUOTE(IFW_VERSION_STR) ", built with Qt " QT_VERSION_STR "."
+#define BUILDDATE "Build date: " __DATE__
+#define SHA "Installer Framework SHA1: " QUOTE(_GIT_SHA1_)
static const char PLACEHOLDER[32] = "MY_InstallerCreateDateTime_MY";
int main(int argc, char *argv[])
@@ -157,7 +157,7 @@ int main(int argc, char *argv[])
#endif
QInstaller::RemoteServer *server = new QInstaller::RemoteServer;
- QObject::connect(server, SIGNAL(destroyed()), &app, SLOT(quit()));
+ QObject::connect(server, &QInstaller::RemoteServer::destroyed, &app, &decltype(app)::quit);
server->init(socketName, key, (production ? QInstaller::Protocol::Mode::Production
: QInstaller::Protocol::Mode::Debug));
@@ -200,7 +200,7 @@ int main(int argc, char *argv[])
if (QInstaller::isVerbose())
std::cout << VERSION << std::endl << BUILDDATE << std::endl << SHA << std::endl;
- const KDSelfRestarter restarter(argc, argv);
+ const SelfRestarter restarter(argc, argv);
return InstallerBase(argc, argv).run();
} catch (const QInstaller::Error &e) {
diff --git a/src/sdk/sdk.pro b/src/sdk/sdk.pro
index 8e78b121a..76bd4c5e2 100644
--- a/src/sdk/sdk.pro
+++ b/src/sdk/sdk.pro
@@ -22,8 +22,8 @@ CONFIG(static, static|shared) {
DESTDIR = $$IFW_APP_PATH
exists($$LRELEASE) {
- QT_LANGUAGES = qtbase_de qt_fr qtbase_ja qt_pl qtbase_ru qt_zh_CN qtbase_it
- IB_LANGUAGES = de en fr ja pl ru zh_cn it
+ QT_LANGUAGES = qtbase_de qt_es qt_fr qtbase_it qtbase_ja qt_pl qtbase_ru qt_zh_CN
+ IB_LANGUAGES = de en es fr it ja pl ru zh_cn
defineReplace(prependAll) {
for(a,$$1):result += $$2$${a}$$3
return($$result)
diff --git a/src/sdk/settingsdialog.cpp b/src/sdk/settingsdialog.cpp
index 2bfa754e9..20ac9c340 100644
--- a/src/sdk/settingsdialog.cpp
+++ b/src/sdk/settingsdialog.cpp
@@ -36,6 +36,7 @@
#include <packagemanagercore.h>
#include <productkeycheck.h>
+#include <testrepository.h>
#include <QtCore/QFile>
@@ -226,13 +227,18 @@ SettingsDialog::SettingsDialog(PackageManagerCore *core, QWidget *parent)
m_ui->m_httpProxy->setText(httpProxy.hostName());
m_ui->m_httpProxyPort->setValue(httpProxy.port());
- connect(m_ui->m_addRepository, SIGNAL(clicked()), this, SLOT(addRepository()));
- connect(m_ui->m_showPasswords, SIGNAL(clicked()), this, SLOT(updatePasswords()));
- connect(m_ui->m_removeRepository, SIGNAL(clicked()), this, SLOT(removeRepository()));
- connect(m_ui->m_useTmpRepositories, SIGNAL(clicked(bool)), this, SLOT(useTmpRepositoriesOnly(bool)));
- connect(m_ui->m_repositoriesView, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
- this, SLOT(currentRepositoryChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
- connect(m_ui->m_testRepository, SIGNAL(clicked()), this, SLOT(testRepository()));
+ connect(m_ui->m_addRepository, &QAbstractButton::clicked,
+ this, &SettingsDialog::addRepository);
+ connect(m_ui->m_showPasswords, &QAbstractButton::clicked,
+ this, &SettingsDialog::updatePasswords);
+ connect(m_ui->m_removeRepository, &QAbstractButton::clicked,
+ this, &SettingsDialog::removeRepository);
+ connect(m_ui->m_useTmpRepositories, &QAbstractButton::clicked,
+ this, &SettingsDialog::useTmpRepositoriesOnly);
+ connect(m_ui->m_repositoriesView, &QTreeWidget::currentItemChanged,
+ this, &SettingsDialog::currentRepositoryChanged);
+ connect(m_ui->m_testRepository, &QAbstractButton::clicked,
+ this, &SettingsDialog::testRepository);
useTmpRepositoriesOnly(settings.hasReplacementRepos());
m_ui->m_useTmpRepositories->setChecked(settings.hasReplacementRepos());
@@ -324,25 +330,36 @@ void SettingsDialog::testRepository()
m_ui->tabWidget->setEnabled(false);
m_ui->buttonBox->setEnabled(false);
- m_testRepository.setRepository(current->repository());
- m_testRepository.start();
- m_testRepository.waitForFinished();
- current->setRepository(m_testRepository.repository());
-
- if (m_testRepository.error() > KDJob::NoError) {
- QMessageBox msgBox(this);
- msgBox.setIcon(QMessageBox::Question);
- msgBox.setWindowModality(Qt::WindowModal);
- msgBox.setDetailedText(m_testRepository.errorString());
- msgBox.setText(tr("There was an error testing this repository."));
- msgBox.setInformativeText(tr("Do you want to disable the tested repository?"));
-
- msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
- msgBox.setDefaultButton(QMessageBox::Yes);
-
- if (msgBox.exec() == QMessageBox::Yes)
- current->setData(1, Qt::CheckStateRole, Qt::Unchecked);
+ TestRepository testJob(m_core);
+ testJob.setRepository(current->repository());
+ testJob.start();
+ testJob.waitForFinished();
+ current->setRepository(testJob.repository());
+
+ QMessageBox msgBox(this);
+ msgBox.setIcon(QMessageBox::Question);
+ msgBox.setWindowModality(Qt::WindowModal);
+ msgBox.setDetailedText(testJob.errorString());
+
+ const bool isError = (testJob.error() > Job::NoError);
+ const bool isEnabled = current->data(1, Qt::CheckStateRole).toBool();
+
+ msgBox.setText(isError
+ ? tr("An error occurred while testing this repository.")
+ : tr("The repository was tested successfully."));
+
+ const bool showQuestion = (isError == isEnabled);
+ msgBox.setStandardButtons(showQuestion ? QMessageBox::Yes | QMessageBox::No
+ : QMessageBox::Close);
+ msgBox.setDefaultButton(showQuestion ? QMessageBox::Yes : QMessageBox::Close);
+ if (showQuestion) {
+ msgBox.setInformativeText(isEnabled
+ ? tr("Do you want to disable the repository?")
+ : tr("Do you want to enable the repository?")
+ );
}
+ if (msgBox.exec() == QMessageBox::Yes)
+ current->setData(1, Qt::CheckStateRole, (!isEnabled) ? Qt::Checked : Qt::Unchecked);
m_ui->tabWidget->setEnabled(true);
m_ui->buttonBox->setEnabled(true);
diff --git a/src/sdk/settingsdialog.h b/src/sdk/settingsdialog.h
index 0264d08f9..c65ed1aa7 100644
--- a/src/sdk/settingsdialog.h
+++ b/src/sdk/settingsdialog.h
@@ -35,7 +35,6 @@
#include <repository.h>
#include <settings.h>
-#include <testrepository.h>
#include <QDialog>
#include <QStyledItemDelegate>
@@ -134,7 +133,6 @@ private:
QInstaller::PackageManagerCore *m_core;
bool m_showPasswords;
- QInstaller::TestRepository m_testRepository;
QList<QTreeWidgetItem*> m_rootItems;
};
diff --git a/src/sdk/tabcontroller.cpp b/src/sdk/tabcontroller.cpp
index 7fd3f8dd6..a9f283202 100644
--- a/src/sdk/tabcontroller.cpp
+++ b/src/sdk/tabcontroller.cpp
@@ -94,7 +94,7 @@ TabController::~TabController()
void TabController::setGui(QInstaller::PackageManagerGui *gui)
{
d->m_gui = gui;
- connect(d->m_gui, SIGNAL(gotRestarted()), this, SLOT(restartWizard()));
+ connect(d->m_gui, &PackageManagerGui::gotRestarted, this, &TabController::restartWizard);
}
void TabController::setControlScript(const QString &script)
@@ -124,8 +124,9 @@ int TabController::init()
qDebug() << "Using control script:" << d->m_controlScript;
}
- connect(d->m_gui, SIGNAL(currentIdChanged(int)), this, SLOT(onCurrentIdChanged(int)));
- connect(d->m_gui, SIGNAL(settingsButtonClicked()), this, SLOT(onSettingsButtonClicked()));
+ connect(d->m_gui, &QWizard::currentIdChanged, this, &TabController::onCurrentIdChanged);
+ connect(d->m_gui, &PackageManagerGui::settingsButtonClicked,
+ this, &TabController::onSettingsButtonClicked);
}
IntroductionPage *page =
@@ -137,7 +138,7 @@ int TabController::init()
}
d->m_gui->restart();
- d->m_gui->show();
+ d->m_gui->setVisible(!d->m_gui->isSilent());
onCurrentIdChanged(d->m_gui->currentId());
return PackageManagerCore::Success;
@@ -168,14 +169,14 @@ void TabController::restartWizard()
d->m_core->writeMaintenanceTool();
// restart and switch back to intro page
- QTimer::singleShot(0, this, SLOT(init()));
+ QTimer::singleShot(0, this, &TabController::init);
}
void TabController::onSettingsButtonClicked()
{
SettingsDialog dialog(d->m_core);
- connect (&dialog, SIGNAL(networkSettingsChanged(QInstaller::Settings)), this,
- SLOT(onNetworkSettingsChanged(QInstaller::Settings)));
+ connect(&dialog, &SettingsDialog::networkSettingsChanged,
+ this, &TabController::onNetworkSettingsChanged);
dialog.exec();
if (d->m_networkSettingsChanged) {
diff --git a/src/sdk/translations/de.ts b/src/sdk/translations/de.ts
index 20d510564..32cc79e40 100644
--- a/src/sdk/translations/de.ts
+++ b/src/sdk/translations/de.ts
@@ -15,26 +15,26 @@
<context>
<name>BinaryContent</name>
<message>
- <source>Could not seek to %1 to read the operation data.</source>
+ <source>Cannot seek to %1 to read the operation data.</source>
<translation>Konnte nicht bis zur Anweisungsliste an Position %1 springen.</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection block.</source>
+ <source>Cannot seek to %1 to read the resource collection block.</source>
<translation>Konnte nicht bis zur Resourcensammlung an Position %1 suchen.</translation>
</message>
<message>
- <source>Could not open meta resource. Error: %1</source>
+ <source>Cannot open meta resource. Error: %1</source>
<translation>Konnte Metainformationen nicht öffnen. Fehlermeldung: %1</translation>
</message>
</context>
<context>
<name>BinaryLayout</name>
<message>
- <source>Could not seek to %1 to read the embedded meta data count.</source>
+ <source>Cannot seek to %1 to read the embedded meta data count.</source>
<translation>Konnte nicht bis %1 suchen, um die eingebettete Metadatenanzahl zu lesen.</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection segment.</source>
+ <source>Cannot seek to %1 to read the resource collection segment.</source>
<translation>Konnte nicht bis %1 suchen, um die Resourcensammlung zu lesen.</translation>
</message>
<message>
@@ -72,34 +72,34 @@
<translation>Pfad %1 existiert, aber ist kein Ordner.</translation>
</message>
<message>
- <source>Could not create folder: %1</source>
+ <source>Cannot create folder: %1</source>
<translation>Konnte Ordner %1 nicht anlegen.</translation>
</message>
</context>
<context>
<name>ExtractCallbackImpl</name>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>Konnte Pfad des Archivs %1 nicht feststellen.</translation>
</message>
<message>
- <source>Could not remove already existing symlink. %1</source>
+ <source>Cannot remove already existing symlink. %1</source>
<translation>Konnte existierende Verknüpfung (Symlink) %1 nicht entfernen.</translation>
</message>
<message>
- <source>Could not open file: %1 (%2)</source>
+ <source>Cannot open file: %1 (%2)</source>
<translation>Konnte Datei %1 nicht öffnen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not create symlink at &apos;%1&apos;. Another one is already existing.</source>
+ <source>Cannot create symlink at &apos;%1&apos;. Another one is already existing.</source>
<translation>Konnte Verknüpfung (Symlink) &apos;%1&apos; nicht erstellen. Es existiert bereits eine an dieser Stelle.</translation>
</message>
<message>
- <source>Could not read symlink target from file &apos;%1&apos;.</source>
+ <source>Cannot read symlink target from file &apos;%1&apos;.</source>
<translation>Konnte Ziel der Verknüpfung (Symlink) &apos;%1&apos; nicht lesen.</translation>
</message>
<message>
- <source>Could not create symlink at %1. %2</source>
+ <source>Cannot create symlink at %1. %2</source>
<translation>Konnte keine Dateisystemverknüpfung (Symlink) %1 anlegen. Fehlermeldung: %2</translation>
</message>
</context>
@@ -131,28 +131,28 @@
</message>
</context>
<context>
- <name>KDJob</name>
+ <name>Job</name>
<message>
<source>Canceled</source>
<translation>Abgebrochen</translation>
</message>
</context>
<context>
- <name>KDLockFile</name>
+ <name>LockFile</name>
<message>
- <source>Could not create lock file &apos;%1&apos;: %2</source>
+ <source>Cannot create lock file &apos;%1&apos;: %2</source>
<translation>Konnte keine Sperrdatei %1 anlegen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not write PID to lock file &apos;%1&apos;: %2</source>
+ <source>Cannot write PID to lock file &apos;%1&apos;: %2</source>
<translation>Konnte PID nicht in die Sperrdatei %1 schreiben. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not obtain the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot obtain the lock for file &apos;%1&apos;: %2</source>
<translation>Konnte Sperre für Datei &apos;%1&apos; nicht anlegen: &apos;%2&apos;</translation>
</message>
<message>
- <source>Could not release the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot release the lock for file &apos;%1&apos;: %2</source>
<translation>Konnte Sperre für Datei &apos;%1&apos; nicht aufheben: &apos;%2&apos;</translation>
</message>
</context>
@@ -171,7 +171,7 @@
<translation>genau 2</translation>
</message>
<message>
- <source>Could not open file &apos;%1&apos; for writing: %2</source>
+ <source>Cannot open file &apos;%1&apos; for writing: %2</source>
<translation>Konnte Datei &apos;%1&apos; nicht zum Schreiben öffnen. Fehlermeldung: %2</translation>
</message>
<message>
@@ -179,11 +179,11 @@
<translation>Konnte Sicherungsdatei für %1 nicht finden.</translation>
</message>
<message>
- <source>Could not restore backup file for %1.</source>
+ <source>Cannot restore backup file for %1.</source>
<translation>Konnte Datei %1 nicht wiederherstellen.</translation>
</message>
<message>
- <source>Could not restore backup file for %1: %2</source>
+ <source>Cannot restore backup file for %1: %2</source>
<translation>Konnte Datei %1 nicht wiederherstellen. Fehlermeldung: %2</translation>
</message>
</context>
@@ -194,27 +194,27 @@
<translation>Ungültige Argumente: %1 Argumente erhalten, 2 erwartet.</translation>
</message>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>Konnte Datei %1 nicht sichern.</translation>
</message>
<message>
- <source>Could not copy a non-existent file: %1</source>
+ <source>Cannot copy a non-existent file: %1</source>
<translation>Konnte nicht existierende Datei nicht kopieren: %1</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>Konnte Zieldatei %1 nicht entfernen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>Konnte Datei %1 nicht nach %2 kopieren. Fehlermeldung: %3</translation>
</message>
<message>
- <source>Could not delete file %1: %2</source>
+ <source>Cannot delete file %1: %2</source>
<translation>Konnte Datei %1 nicht löschen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not restore backup file into %1: %2</source>
+ <source>Cannot restore backup file into %1: %2</source>
<translation>Konnte Datei %1 nicht wiederherstellen. Fehlermeldung: %2</translation>
</message>
</context>
@@ -303,7 +303,7 @@
<translation>Konnte %1 nicht herunterladen. Schreiben in Datei &apos;%2&apos; fehlgeschlagen. Fehlermeldung: %3</translation>
</message>
<message>
- <source>Cannot download %1: Could not create %2: %3</source>
+ <source>Cannot download %1: Cannot create %2: %3</source>
<translation>Konnte %1 nicht herunterladen. Erstellen der Datei %2 fehlgeschlagen. Fehlermeldung: %3</translation>
</message>
<message>
@@ -357,7 +357,7 @@
<translation>Ungültige Argumente: %1 Argumente erhalten, 1 erwartet.</translation>
</message>
<message>
- <source>Could not create folder %1: Unknown error.</source>
+ <source>Cannot create folder %1: Unknown error.</source>
<translation>Konnte Ordner %1 nicht anlegen. Unbekannter Fehler.</translation>
</message>
<message>
@@ -368,7 +368,7 @@
<context>
<name>KDUpdater::MoveOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>Konnte Datei %1 nicht sichern.</translation>
</message>
<message>
@@ -376,11 +376,11 @@
<translation>Ungültige Argumente: %1 Argumente erhalten, 2 erwartet.</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>Konnte Zieldatei %1 nicht entfernen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>Konnte Datei %1 nicht nach %2 kopieren. Fehlermeldung: %3</translation>
</message>
<message>
@@ -407,7 +407,7 @@
<translation>Datei %1 existiert nicht.</translation>
</message>
<message>
- <source>Could not open %1.</source>
+ <source>Cannot open %1.</source>
<translation>Konnte Datei %1 nicht öffnen.</translation>
</message>
<message>
@@ -430,11 +430,11 @@
<translation>Ungültige Argumente: %1 Argumente erhalten, 2 erwartet.</translation>
</message>
<message>
- <source>Could not open file %1 for reading: %2</source>
+ <source>Cannot open file %1 for reading: %2</source>
<translation>Konnte Datei %1 nicht zum Lesen öffnen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not open file %1 for writing: %2</source>
+ <source>Cannot open file %1 for writing: %2</source>
<translation>Konnte Datei %1 nicht zum Schreiben öffnen. Fehlermeldung: %2</translation>
</message>
<message>
@@ -453,7 +453,7 @@
<context>
<name>KDUpdater::ResourceFileDownloader</name>
<message>
- <source>Could not read resource file &quot;%1&quot;. Reason:</source>
+ <source>Cannot read resource file &quot;%1&quot;. Reason:</source>
<translation>Konnte Ressourcendatei %1 nicht zum Lesen öffnen. Grund:</translation>
</message>
</context>
@@ -464,11 +464,11 @@
<translation>Ungültige Argumente: %1 Argumente erhalten, 1 erwartet.</translation>
</message>
<message>
- <source>Could not remove folder %1: The folder does not exist.</source>
+ <source>Cannot remove folder %1: The folder does not exist.</source>
<translation>Konnte Ordner %1 nicht entfernen. Der Ordner existiert nicht.</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>Konnte Ordner %1 nicht löschen. Fehlermeldung: %2</translation>
</message>
<message>
@@ -510,11 +510,11 @@
<context>
<name>KDUpdater::UpdateFinder</name>
<message>
- <source>Could not access the package information of this application.</source>
+ <source>Cannot access the package information of this application.</source>
<translation>Konnte nicht auf die Paketinformationen dieser Anwendung zugreifen.</translation>
</message>
<message>
- <source>Could not access the update sources information of this application.</source>
+ <source>Cannot access the update sources information of this application.</source>
<translation>Konnte nicht auf die Aktualisierungsinformationen dieser Anwendung zugreifen.</translation>
</message>
<message numerus="yes">
@@ -529,7 +529,7 @@
<translation>Lade Updates.xml von der Aktualisierungsquelle herunter.</translation>
</message>
<message>
- <source>Could not download update source %1 from (&apos;%2&apos;)</source>
+ <source>Cannot download update source %1 from (&apos;%2&apos;)</source>
<translation>Konnte Aktualisierungen nicht von %1 (&apos;%2&apos;) herunterladen.</translation>
</message>
<message>
@@ -552,7 +552,7 @@
<translation>Datei %1 enthält ungültige Inhalte: %2</translation>
</message>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>Konnte Datei &quot;%1&quot; nicht lesen.</translation>
</message>
<message>
@@ -564,14 +564,14 @@
<translation>Unerwartetes Wurzelelement %1, erwartet wird &quot;UpdateSources&quot;.</translation>
</message>
<message>
- <source>Could not save changes to &quot;%1&quot;: %2</source>
+ <source>Cannot save changes to &quot;%1&quot;: %2</source>
<translation>Konnte Änderungen nicht in Datei %1 speichern. Fehlermeldung: %2</translation>
</message>
</context>
<context>
<name>KDUpdater::UpdatesInfoData</name>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>Konnte Datei &quot;%1&quot; nicht lesen.</translation>
</message>
<message>
@@ -610,11 +610,11 @@
<context>
<name>Lib7z</name>
<message>
- <source>Could not retrieve number of items in archive</source>
+ <source>Cannot retrieve number of items in archive</source>
<translation>Konnte Anzahl Dateien im Archiv nicht feststellen.</translation>
</message>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>Konnte Pfad des Archivs %1 nicht feststellen.</translation>
</message>
<message>
@@ -634,15 +634,15 @@
<translation>Fehler: %1</translation>
</message>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>Konnte Codecs nicht laden.</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>Konnte Standardformat nicht finden.</translation>
</message>
<message>
- <source>Could not create archive %1. %2</source>
+ <source>Cannot create archive %1. %2</source>
<translation>Konnte kein Archiv %1 anlegen. Fehlermeldung: %2</translation>
</message>
<message>
@@ -654,14 +654,14 @@
<translation>Itemindex %1 ausserhalb der Grenzen [0, %2].</translation>
</message>
<message>
- <source>Could not create output file for writing: %1</source>
+ <source>Cannot create output file for writing: %1</source>
<translation>Konnte Ausgabedatei nicht zum Schreiben öffnen. Fehlermeldung: %1</translation>
</message>
</context>
<context>
<name>Lib7z::ExtractItemJob</name>
<message>
- <source>Could not list archive: QIODevice not set or already destroyed.</source>
+ <source>Cannot list archive: QIODevice not set or already destroyed.</source>
<translation>Kann Archiv nicht anzeigen: QIODevice ist nicht gesetzt oder bereits zerstört.</translation>
</message>
<message>
@@ -680,7 +680,7 @@
<context>
<name>Lib7z::ListArchiveJob</name>
<message>
- <source>Could not list archive: QIODevice already destroyed.</source>
+ <source>Cannot list archive: QIODevice already destroyed.</source>
<translation>Kann Archiv nicht anzeigen: QIODevice ist bereits zerstört.</translation>
</message>
<message>
@@ -695,15 +695,15 @@
<context>
<name>OpenArchiveInfo</name>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>Konnte Codecs nicht laden.</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>Konnte Standardformat nicht finden.</translation>
</message>
<message>
- <source>Could not open archive</source>
+ <source>Cannot open archive</source>
<translation>Konnte Archiv nicht öffnen.</translation>
</message>
<message>
@@ -757,35 +757,35 @@
<translation>YiB</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>Konnte Datei %1 nicht löschen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>Konnte Ordner %1 nicht löschen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not create folder %1</source>
+ <source>Cannot create folder %1</source>
<translation>Konnte Ordner %1 nicht anlegen.</translation>
</message>
<message>
- <source>Could not copy file from %1 to %2: %3</source>
+ <source>Cannot copy file from %1 to %2: %3</source>
<translation>Konnte Datei %1 nicht nach %2 kopieren. Fehlermeldung: %3</translation>
</message>
<message>
- <source>Could not move file from %1 to %2: %3</source>
+ <source>Cannot move file from %1 to %2: %3</source>
<translation>Konnte Datei %1 nicht nach %2 verschieben. Fehlermeldung: %3</translation>
</message>
<message>
- <source>Could not create folder %1: %2</source>
+ <source>Cannot create folder %1: %2</source>
<translation>Konnte Ordner %1 nicht anlegen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not open temporary file: %1</source>
+ <source>Cannot open temporary file: %1</source>
<translation>Konnte temporäre Datei nicht öffnen. Fehlermeldung: %1</translation>
</message>
<message>
- <source>Could not open temporary file for template %1: %2</source>
+ <source>Cannot open temporary file for template %1: %2</source>
<translation>Konnte keine temporäre Datei für die Vorlage %1 öffnen. Fehlermeldung: %2</translation>
</message>
<message>
@@ -813,11 +813,11 @@
<translation>Das Schreiben ist nach %1 Bytes fehlgeschlagen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not create temporary file</source>
+ <source>Cannot create temporary file</source>
<translation>Konnte temporäre Datei nicht anlegen.</translation>
</message>
<message>
- <source>Could not retrieve property %1 for item %2</source>
+ <source>Cannot retrieve property %1 for item %2</source>
<translation>Konnte Eigenschaft %1 von %2 nicht erhalten.</translation>
</message>
<message>
@@ -825,11 +825,11 @@
<translation>Eigenschaft %1 von %2 ist nicht vom Typ VT_FILETIME, sondern vom Typ %3.</translation>
</message>
<message>
- <source>Could not convert file time to local time</source>
+ <source>Cannot convert file time to local time</source>
<translation>Konnte die Dateizeit nicht in die lokale Zeit umwandeln.</translation>
</message>
<message>
- <source>Could not convert local file time to system time</source>
+ <source>Cannot convert local file time to system time</source>
<translation>Konnte die lokale Dateizeit nicht in die Systemzeit umwandeln.</translation>
</message>
<message>
@@ -852,19 +852,19 @@
<translation>Komponenten können im Updater Modus keine Kinder haben.</translation>
</message>
<message>
- <source>Could not open the requested translation file &apos;%1&apos;.</source>
+ <source>Cannot open the requested translation file &apos;%1&apos;.</source>
<translation>Konnte angeforderte Übersetzungsdatei %1 nicht öffnen.</translation>
</message>
<message>
- <source>Could not open the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>Konnte angeforderte UI-Datei &apos;%1&apos; nicht öffnen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not load the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot load the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>Konnte angeforderte UI-Datei &apos;%1&apos; nicht laden. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not open the requested license file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested license file &apos;%1&apos;. Error: %2</source>
<translation>Konnte angeforderte Lizenzdatei &apos;%1&apos; nicht öffnen. Fehlermeldung: %2</translation>
</message>
<message>
@@ -1040,7 +1040,7 @@
<translation>Ungültige Argumentein %0: Ordner %1 und %2 ungültig.</translation>
</message>
<message>
- <source>Could not create %0</source>
+ <source>Cannot create %0</source>
<translation>Konnte Ordner &quot;%1&quot; nicht anlegen.</translation>
</message>
<message>
@@ -1048,11 +1048,11 @@
<translation>Konnte Datei %1 nicht überschreiben</translation>
</message>
<message>
- <source>Could not copy %0 to %1, error was: %3</source>
+ <source>Cannot copy %0 to %1, error was: %3</source>
<translation>Konnte %0 nicht nach %1 kopieren. Fehlermeldung: %3</translation>
</message>
<message>
- <source>Could not remove %0</source>
+ <source>Cannot remove %0</source>
<translation>Konnte Datei %0 nicht löschen.</translation>
</message>
</context>
@@ -1063,11 +1063,11 @@
<translation>Ungültige Anzahl task items.</translation>
</message>
<message>
- <source>Could not open source &apos;%1&apos; for read. Error: %2.</source>
+ <source>Cannot open source &apos;%1&apos; for read. Error: %2.</source>
<translation>Konnte Quelle &apos;%1&apos; nicht zum Lesen öffnen. Fehlermeldung: %2.</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<translation>Konnte Ziel &apos;%1&apos; nicht zum Schreiben öffnen. Fehlermeldung: %2.</translation>
</message>
<message>
@@ -1078,7 +1078,7 @@
<context>
<name>QInstaller::CreateDesktopEntryOperation</name>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>Konnte Datei %1 nicht sichern. Fehlermeldung: %2</translation>
</message>
<message>
@@ -1094,7 +1094,7 @@
<translation>Konnte Datei %1 nicht überschreiben.</translation>
</message>
<message>
- <source>Could not write Desktop Entry at %1</source>
+ <source>Cannot write Desktop Entry at %1</source>
<translation>Konnte keinen Eintrag %1 auf dem Arbeitsplatz anlegen.</translation>
</message>
</context>
@@ -1109,26 +1109,26 @@
<translation>genau 2</translation>
</message>
<message>
- <source>Could not create link from %1 to %2.</source>
+ <source>Cannot create link from %1 to %2.</source>
<translation>Konnte keinen Link von %1 nach %2 erstellen.</translation>
</message>
<message>
- <source>Could not remove link from %1 to %2.</source>
+ <source>Cannot remove link from %1 to %2.</source>
<translation>Konnte Link von %1 nach %2 nicht entfernen.</translation>
</message>
</context>
<context>
<name>QInstaller::CreateLocalRepositoryOperation</name>
<message>
- <source>Could not set file permissions %1!</source>
+ <source>Cannot set file permissions %1!</source>
<translation>Konnte Dateirechte auf Datei %1 nicht setzen!</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>Konnte Datei %1 nicht löschen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not move file %1 to %2. Error: %3</source>
+ <source>Cannot move file %1 to %2. Error: %3</source>
<translation>Konnte Datei %1 nicht nach %2 verschieben. Fehlermeldung: %3</translation>
</message>
<message>
@@ -1144,19 +1144,19 @@
<translation>Installer muss eine offline Version sein: %1.</translation>
</message>
<message>
- <source>Could not open file: %1</source>
+ <source>Cannot open file: %1</source>
<translation>Konnte Datei %1 nicht öffnen.</translation>
</message>
<message>
- <source>Could not read: %1. Error: %2</source>
+ <source>Cannot read: %1. Error: %2</source>
<translation>Konnte Datei %1 nicht lesen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not open file: %1. Error: %2</source>
+ <source>Cannot open file: %1. Error: %2</source>
<translation>Konnte Datei %1 nicht öffnen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not create target dir: %1.</source>
+ <source>Cannot create target dir: %1.</source>
<translation>Konnte Zielordner %1. nicht anlegen.</translation>
</message>
<message>
@@ -1168,7 +1168,7 @@
<translation>Entferne Datei %0</translation>
</message>
<message>
- <source>Could not remove %0.</source>
+ <source>Cannot remove %0.</source>
<translation>Konnte Datei %0. nicht löschen.</translation>
</message>
<message>
@@ -1191,7 +1191,7 @@
<translation> (optional: &apos;workingDirectory=...&apos;, &apos;iconPath=...&apos;, &apos;iconId=...&apos;)</translation>
</message>
<message>
- <source>Could not create folder %1: %2.</source>
+ <source>Cannot create folder %1: %2.</source>
<translation>Konnte Ordner %1 nicht anlegen. Fehlermeldung: %2</translation>
</message>
<message>
@@ -1199,7 +1199,7 @@
<translation>Konnte Datei %1 nicht überschreiben. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not create link %1: %2</source>
+ <source>Cannot create link %1: %2</source>
<translation>Konnte Verweis %1 nicht anlegen. Fehlermeldung: %2</translation>
</message>
</context>
@@ -1222,15 +1222,15 @@
<translation>Prüfsumme ungültig beim Herunterladen. Dies ist ein kurzzeitiger Fehler, bitte erneut versuchen.</translation>
</message>
<message>
- <source>Could not verify Hash</source>
+ <source>Cannot verify Hash</source>
<translation>Prüfsumme konnte nicht geprüft werden.</translation>
</message>
<message>
- <source>Could not download archive: %1 : %2</source>
+ <source>Cannot download archive: %1 : %2</source>
<translation>Konnte Archiv %1 nicht herunterladen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not fetch archives: %1
+ <source>Cannot fetch archives: %1
Error while loading %2</source>
<translation>Konnte Archiv nicht laden. Fehler: %1
Fehler beim Laden von %2</translation>
@@ -1244,7 +1244,7 @@ Fehler beim Laden von %2</translation>
<translation>Schema &quot;%1&quot; nicht unterstützt in &quot;%2&quot;.</translation>
</message>
<message>
- <source>Could not find component for: %1.</source>
+ <source>Cannot find component for: %1.</source>
<translation>Konnte keine Komponente für Datei %1 finden.</translation>
</message>
</context>
@@ -1292,7 +1292,7 @@ Fehler beim Laden von %2</translation>
<translation>Zieldatei &apos;%1&apos; existiert bereits aber ist keine Datei.</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<extracomment>%2 is a sentence describing the error</extracomment>
<translation>Konnte Ziel &apos;%1&apos; nicht zum Schreiben öffnen. Fehler: %2.</translation>
</message>
@@ -1308,11 +1308,11 @@ Fehler beim Laden von %2</translation>
<translation>mindestens 1</translation>
</message>
<message>
- <source>Execution failed: Could not start detached: &quot;%1&quot;</source>
+ <source>Execution failed: Cannot start detached: &quot;%1&quot;</source>
<translation>Ausführung fehlgeschlagen: Konnte %1 nicht detached starten.</translation>
</message>
<message>
- <source>Execution failed: Could not start: &quot;%1&quot;(%2)</source>
+ <source>Execution failed: Cannot start: &quot;%1&quot;(%2)</source>
<translation>Ausführung fehlgeschlagen: Konnte &apos;%1&apos; nicht starten. Fehlermeldung: %2</translation>
</message>
<message>
@@ -1349,7 +1349,7 @@ Fehler beim Laden von %2</translation>
<context>
<name>QInstaller::ExtractArchiveOperation::Runnable</name>
<message>
- <source>Could not open %1 for reading: %2.</source>
+ <source>Cannot open %1 for reading: %2.</source>
<translation>Konnte Datei %1 nicht zum Lesen öffnen. Fehlermeldung: %2</translation>
</message>
<message>
@@ -1368,7 +1368,7 @@ Fehler beim Laden von %2</translation>
<translation>Unpassende Anzahl Argumente: Genau eins wird verlangt</translation>
</message>
<message>
- <source>Could not get package manager core.</source>
+ <source>Cannot get package manager core.</source>
<translation>Konnte PackageManagerCore nicht erhalten.</translation>
</message>
<message>
@@ -1496,7 +1496,7 @@ Fehler beim Laden von %2</translation>
<translation>Ungültiges Argument: Quellordner darf nicht leer sein.</translation>
</message>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>Konnte Datei %1 nicht sichern. Fehlermeldung: %2</translation>
</message>
<message>
@@ -1508,7 +1508,7 @@ Fehler beim Laden von %2</translation>
<translation>Konnte Datei nicht nach %1 kopieren. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not create folder at %1: %2</source>
+ <source>Cannot create folder at %1: %2</source>
<translation>Konnte Ordner %1 nicht anlegen. Fehlermeldung: %2</translation>
</message>
</context>
@@ -1687,7 +1687,7 @@ Fehler beim Laden von %2</translation>
<translation>Beim Auspacken von %1 trat eine unbekannte Ausnahmebedingung auf.</translation>
</message>
<message>
- <source>Could not open %1 for reading. Error: %2</source>
+ <source>Cannot open %1 for reading. Error: %2</source>
<translation>Konnte Datei %1 nicht zum Lesen öffnen. Fehlermeldung: %2</translation>
</message>
</context>
@@ -1775,7 +1775,7 @@ Lade Pakete herunter...</translation>
<translation>Formatfehler</translation>
</message>
<message>
- <source>Could not write installer configuration to %1: %2</source>
+ <source>Cannot write installer configuration to %1: %2</source>
<translation>Konnte Einstellungen des Installers nicht nach %1 schreiben. Fehlermeldung: %2</translation>
</message>
<message>
@@ -1859,19 +1859,19 @@ Aktualisierung abgebrochen!</translation>
<translation>Verwaltungswerkzeug ist kein Bundle</translation>
</message>
<message>
- <source>Could not write maintenance tool data to %1: %2</source>
+ <source>Cannot write maintenance tool data to %1: %2</source>
<translation>Konnte Daten des Verwaltungswerkzeugs nicht nach %1 schreiben. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not remove data file &apos;%1&apos;: %2</source>
+ <source>Cannot remove data file &apos;%1&apos;: %2</source>
<translation>Konnte Datei %1 nicht löschen. Fehlermeldung: %2</translation>
</message>
<message>
- <source>Could not write maintenance tool to %1: %2</source>
+ <source>Cannot write maintenance tool to %1: %2</source>
<translation>Konnte Verwaltungswerkzeug nicht nach %1 schreiben: %2</translation>
</message>
<message>
- <source>Could not write maintenance tool binary data to %1: %2</source>
+ <source>Cannot write maintenance tool binary data to %1: %2</source>
<translation>Konnte Binäre Datei des Verwaltungswerkzeugs nicht nach %1 schreiben: %2</translation>
</message>
<message>
@@ -1921,7 +1921,7 @@ Installiere Komponente %1</translation>
<translation>Unbekannter Fehler</translation>
</message>
<message>
- <source>Could not retrieve remote tree: %1.</source>
+ <source>Cannot retrieve remote tree: %1.</source>
<translation>Kann entfernten Baum nicht empfangen: %1</translation>
</message>
<message>
@@ -1929,15 +1929,15 @@ Installiere Komponente %1</translation>
<translation>Fehler beim Lesen der Pakete von %1</translation>
</message>
<message>
- <source>Could not retrieve meta information: %1</source>
+ <source>Cannot retrieve meta information: %1</source>
<translation>Konnte die Metainformationen nicht empfangen: %1</translation>
</message>
<message>
- <source>Could not add temporary update source information.</source>
+ <source>Cannot add temporary update source information.</source>
<translation>Konnte Informationen zu temporären Aktualisierungsquellen nicht hinzufügen.</translation>
</message>
<message>
- <source>Could not find any update source information.</source>
+ <source>Cannot find any update source information.</source>
<translation>Konnte keine Informationen zu Aktualisierungsquellen finden.</translation>
</message>
<message>
@@ -2152,14 +2152,14 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
<context>
<name>QInstaller::RemoteObject</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>Konnte nicht alle Daten nach dem Senden des Kommandos &apos;%1&apos; lesen. Bytes erwartet: %2, Bytes erhalten: %3. Fehler: %4</translation>
</message>
</context>
<context>
<name>QInstaller::RemoteServerConnection</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>Konnte nicht alle Daten nach dem Senden des Kommandos &apos;%1&apos; lesen. Bytes erwartet: %2, Bytes erhalten: %3. Fehler: %4</translation>
</message>
</context>
@@ -2185,7 +2185,7 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
<context>
<name>QInstaller::Resource</name>
<message>
- <source>Could not open Resource &apos;%1&apos; read-only.</source>
+ <source>Cannot open Resource &apos;%1&apos; read-only.</source>
<translation>Konnte Ressourcendatei &apos;%1&apos; nicht zum Nur-Lesen öffnen.</translation>
</message>
<message>
@@ -2207,7 +2207,7 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
<context>
<name>QInstaller::ScriptEngine</name>
<message>
- <source>Could not open the requested script file at %1: %2.</source>
+ <source>Cannot open the requested script file at %1: %2.</source>
<translation>Konnte angeforderte Skriptdatei &apos;%1&apos; nicht öffnen. Fehlermeldung: %2</translation>
</message>
<message>
@@ -2404,7 +2404,7 @@ Möchten Sie trotzdem fortsetzen?</translation>
<translation>Erhielt Timeout beim Testen von: &apos;%1&apos;</translation>
</message>
<message>
- <source>Could not parse Updates.xml! Error: %1.</source>
+ <source>Cannot parse Updates.xml! Error: %1.</source>
<translation>Ungültiges Format der Updates.xml. Fehlermeldung: %1.</translation>
</message>
<message>
@@ -2434,11 +2434,11 @@ Möchten Sie trotzdem fortsetzen?</translation>
<context>
<name>RemoteClient</name>
<message>
- <source>Could not get authorization.</source>
+ <source>Cannot get authorization.</source>
<translation>Konnte Autorisierung nicht erhalten.</translation>
</message>
<message>
- <source>Could not get authorization that is needed for continuing the installation.
+ <source>Cannot get authorization that is needed for continuing the installation.
Either abort the installation or use the fallback solution by running
%1
@@ -2453,14 +2453,14 @@ als root aufrufen und dann &quot;Ok&quot; auswählen. </translation>
<context>
<name>ResourceCollectionManager</name>
<message>
- <source>Could not open resource %1: %2</source>
+ <source>Cannot open resource %1: %2</source>
<translation>Konnte Ressource %1 nicht öffnen: %2</translation>
</message>
</context>
<context>
<name>Settings</name>
<message>
- <source>Could not open settings file %1 for reading: %2</source>
+ <source>Cannot open settings file %1 for reading: %2</source>
<translation>Konnte Einstellungsdatei %1 nicht zum Lesen öffnen. Fehlermeldung: %2</translation>
</message>
</context>
@@ -2590,7 +2590,7 @@ als root aufrufen und dann &quot;Ok&quot; auswählen. </translation>
<translation>Registrierungspfad %1 ist nicht beschreibbar</translation>
</message>
<message>
- <source>Could not write to registry path %1</source>
+ <source>Cannot write to registry path %1</source>
<translation>Konnte nicht in Registrierungspfad %1 schreiben</translation>
</message>
<message>
diff --git a/src/sdk/translations/en.ts b/src/sdk/translations/en.ts
index e14431ab0..c559cb93e 100644
--- a/src/sdk/translations/en.ts
+++ b/src/sdk/translations/en.ts
@@ -4,7 +4,7 @@
<context>
<name>Component</name>
<message>
- <source>Could not open archive %1: %2</source>
+ <source>Cannot open archive %1: %2</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -67,7 +67,7 @@
</message>
</context>
<context>
- <name>KDJob</name>
+ <name>Job</name>
<message>
<source>Canceled</source>
<translation type="unfinished"></translation>
@@ -84,7 +84,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not backup existing file %1: %2</source>
+ <source>Cannot backup existing file %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -103,7 +103,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open file %1 for writing: %2</source>
+ <source>Cannot open file %1 for writing: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -111,18 +111,18 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not restore backup file for %1.</source>
+ <source>Cannot restore backup file for %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not restore backup file for %1: %2</source>
+ <source>Cannot restore backup file for %1: %2</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>KDUpdater::CopyOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -130,19 +130,19 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not delete file %1: %2</source>
+ <source>Cannot delete file %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not restore backup file into %1: %2</source>
+ <source>Cannot restore backup file into %1: %2</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -239,7 +239,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot download %1: Could not create %2: %3</source>
+ <source>Cannot download %1: Cannot create %2: %3</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -273,7 +273,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create folder %1: Unknown error.</source>
+ <source>Cannot create folder %1: Unknown error.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -284,7 +284,7 @@
<context>
<name>KDUpdater::MoveOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -292,11 +292,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -323,7 +323,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open %1.</source>
+ <source>Cannot open %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -346,11 +346,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open file %1 for reading: %2</source>
+ <source>Cannot open file %1 for reading: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open file %1 for writing: %2</source>
+ <source>Cannot open file %1 for writing: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -369,7 +369,7 @@
<context>
<name>KDUpdater::ResourceFileDownloader</name>
<message>
- <source>Could not read resource file &quot;%1&quot;. Reason:</source>
+ <source>Cannot read resource file &quot;%1&quot;. Reason:</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -380,11 +380,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not remove folder %1: The folder does not exist.</source>
+ <source>Cannot remove folder %1: The folder does not exist.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -426,11 +426,11 @@
<context>
<name>KDUpdater::UpdateFinder</name>
<message>
- <source>Could not access the package information of this application.</source>
+ <source>Cannot access the package information of this application.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not access the update sources information of this application.</source>
+ <source>Cannot access the update sources information of this application.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -442,7 +442,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not download updates from %1 (&apos;%2&apos;)</source>
+ <source>Cannot download updates from %1 (&apos;%2&apos;)</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -465,7 +465,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -477,14 +477,14 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not save changes to &quot;%1&quot;: %2</source>
+ <source>Cannot save changes to &quot;%1&quot;: %2</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>KDUpdater::UpdatesInfoData</name>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -523,14 +523,14 @@
<context>
<name>Lib7z::ExtractItemJob</name>
<message>
- <source>Could not list archive: QIODevice not set or already destroyed.</source>
+ <source>Cannot list archive: QIODevice not set or already destroyed.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Lib7z::ListArchiveJob</name>
<message>
- <source>Could not list archive: QIODevice already destroyed.</source>
+ <source>Cannot list archive: QIODevice already destroyed.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -560,15 +560,15 @@
<context>
<name>QInstaller::Component</name>
<message>
- <source>Could not open the requested translation file &apos;%1&apos;.</source>
+ <source>Cannot open the requested translation file &apos;%1&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested UI file &apos;%1&apos;. Error: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not load the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot load the requested UI file &apos;%1&apos;. Error: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -576,7 +576,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open the requested license file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested license file &apos;%1&apos;. Error: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -732,7 +732,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create %0</source>
+ <source>Cannot create %0</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -740,11 +740,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not copy %0 to %1, error was: %3</source>
+ <source>Cannot copy %0 to %1, error was: %3</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not remove %0</source>
+ <source>Cannot remove %0</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -763,7 +763,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not write Desktop Entry at %1</source>
+ <source>Cannot write Desktop Entry at %1</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -781,11 +781,11 @@
<context>
<name>QInstaller::CreateLocalRepositoryOperation</name>
<message>
- <source>Could not set file permissions %1!</source>
+ <source>Cannot set file permissions %1!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not move file %1 to %2. Error: %3</source>
+ <source>Cannot move file %1 to %2. Error: %3</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -801,19 +801,19 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open file: %1</source>
+ <source>Cannot open file: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not read: %1. Error: %2</source>
+ <source>Cannot read: %1. Error: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open file: %1. Error: %2</source>
+ <source>Cannot open file: %1. Error: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create target dir: %1.</source>
+ <source>Cannot create target dir: %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -825,7 +825,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not remove %0.</source>
+ <source>Cannot remove %0.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -848,11 +848,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create folder %1: %2.</source>
+ <source>Cannot create folder %1: %2.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create link %1: %2</source>
+ <source>Cannot create link %1: %2</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -875,15 +875,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not verify Hash</source>
+ <source>Cannot verify Hash</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not download archive: %1 : %2</source>
+ <source>Cannot download archive: %1 : %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not fetch archives: %1
+ <source>Cannot fetch archives: %1
Error while loading %2</source>
<translation type="unfinished"></translation>
</message>
@@ -900,7 +900,7 @@ Error while loading %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not find component for: %1.</source>
+ <source>Cannot find component for: %1.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -915,11 +915,11 @@ Error while loading %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Execution failed: Could not start detached: &quot;%1&quot;</source>
+ <source>Execution failed: Cannot start detached: &quot;%1&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Execution failed: Could not start: &quot;%1&quot;(%2)</source>
+ <source>Execution failed: Cannot start: &quot;%1&quot;(%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -956,7 +956,7 @@ Error while loading %2</source>
<context>
<name>QInstaller::ExtractArchiveOperation::Runnable</name>
<message>
- <source>Could not open %1 for reading: %2.</source>
+ <source>Cannot open %1 for reading: %2.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1014,15 +1014,15 @@ Error while loading %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not move Updates.xml to target location. Error: %1</source>
+ <source>Cannot move Updates.xml to target location. Error: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open Updates.xml for reading. Error: %1</source>
+ <source>Cannot open Updates.xml for reading. Error: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not fetch a valid version of Updates.xml from repository: %1. Error: %2</source>
+ <source>Cannot fetch a valid version of Updates.xml from repository: %1. Error: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1042,7 +1042,7 @@ Error while loading %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not fetch Updates.xml from repository: %1. Error: %2</source>
+ <source>Cannot fetch Updates.xml from repository: %1. Error: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1050,7 +1050,7 @@ Error while loading %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open meta info archive: %1. Error: %2</source>
+ <source>Cannot open meta info archive: %1. Error: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1062,7 +1062,7 @@ Error while loading %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not download meta information for component: %1. Error: %2</source>
+ <source>Cannot download meta information for component: %1. Error: %2</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1077,7 +1077,7 @@ Error while loading %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open %1 for reading. Error: %2</source>
+ <source>Cannot open %1 for reading. Error: %2</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1311,7 +1311,7 @@ Downloading packages...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not write installer configuration to %1: %2</source>
+ <source>Cannot write installer configuration to %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1337,11 +1337,11 @@ Downloading packages...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not write uninstaller data to %1: %2</source>
+ <source>Cannot write uninstaller data to %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not write uninstaller to %1: %2</source>
+ <source>Cannot write uninstaller to %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1349,7 +1349,7 @@ Downloading packages...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not write uninstaller binary data to %1: %2</source>
+ <source>Cannot write uninstaller binary data to %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1446,7 +1446,7 @@ Installing component %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not retrieve remote tree: %1.</source>
+ <source>Cannot retrieve remote tree: %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1454,15 +1454,15 @@ Installing component %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not retrieve meta information: %1</source>
+ <source>Cannot retrieve meta information: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not add temporary update source information.</source>
+ <source>Cannot add temporary update source information.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not find any update source information.</source>
+ <source>Cannot find any update source information.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1579,7 +1579,7 @@ Please copy the installer to a local drive</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not find the needed QmakeOutputInstallerKey(%1) value on the installer object. The ConsumeOutput operation on the valid qmake needs to be called first.</source>
+ <source>Cannot find the needed QmakeOutputInstallerKey(%1) value on the installer object. The ConsumeOutput operation on the valid qmake needs to be called first.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1808,7 +1808,7 @@ Sometimes it helps to restart the installer with a switched off antivirus softwa
<context>
<name>QInstaller::ScriptEngine</name>
<message>
- <source>Could not open the requested script file at %1: %2.</source>
+ <source>Cannot open the requested script file at %1: %2.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1816,7 +1816,7 @@ Sometimes it helps to restart the installer with a switched off antivirus softwa
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not load the component script inside a script context: &apos;%1&apos;</source>
+ <source>Cannot load the component script inside a script context: &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2044,15 +2044,15 @@ needs to be less than 255 characters.</source>
<context>
<name>QInstallerCreator::Archive</name>
<message>
- <source>Could not create %1: %2</source>
+ <source>Cannot create %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open archive file %1 for reading.</source>
+ <source>Cannot open archive file %1 for reading.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create archive from %1: Not a file.</source>
+ <source>Cannot create archive from %1: Not a file.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2067,7 +2067,7 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not seek to %1 in file %2: %3</source>
+ <source>Cannot seek to %1 in file %2: %3</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2083,35 +2083,35 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not seek to in-binary resource. (offset: %1, length: %2)</source>
+ <source>Cannot seek to in-binary resource. (offset: %1, length: %2)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not register in-binary resource.</source>
+ <source>Cannot register in-binary resource.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open binary %1: %2</source>
+ <source>Cannot open binary %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not seek to binary layout section.</source>
+ <source>Cannot seek to binary layout section.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not seek to metadata index.</source>
+ <source>Cannot seek to metadata index.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not seek to operation list.</source>
+ <source>Cannot seek to operation list.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not seek to component index information.</source>
+ <source>Cannot seek to component index information.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not seek to component index.</source>
+ <source>Cannot seek to component index.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2131,55 +2131,55 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create folder %1</source>
+ <source>Cannot create folder %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not copy file from %1 to %2: %3</source>
+ <source>Cannot copy file from %1 to %2: %3</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not move file from %1 to %2: %3</source>
+ <source>Cannot move file from %1 to %2: %3</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create folder %1: %2</source>
+ <source>Cannot create folder %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open temporary file: %1</source>
+ <source>Cannot open temporary file: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open temporary file for template %1: %2</source>
+ <source>Cannot open temporary file for template %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create temporary folder for template %1: %2</source>
+ <source>Cannot create temporary folder for template %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create lock file %1: %2</source>
+ <source>Cannot create lock file %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not write PID to lock file %1: %2</source>
+ <source>Cannot write PID to lock file %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not lock lock file %1: %2</source>
+ <source>Cannot lock lock file %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not unlock lock file %1: %2</source>
+ <source>Cannot unlock lock file %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2187,15 +2187,15 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create folder: %1</source>
+ <source>Cannot create folder: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create temporary file</source>
+ <source>Cannot create temporary file</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not retrieve property %1 for item %2</source>
+ <source>Cannot retrieve property %1 for item %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2203,11 +2203,11 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not convert file time to local time</source>
+ <source>Cannot convert file time to local time</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not convert local file time to system time</source>
+ <source>Cannot convert local file time to system time</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2215,15 +2215,15 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open archive</source>
+ <source>Cannot open archive</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2231,11 +2231,11 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not retrieve number of items in archive</source>
+ <source>Cannot retrieve number of items in archive</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2247,23 +2247,23 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not remove already existing symlink. %1</source>
+ <source>Cannot remove already existing symlink. %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open file: %1 (%2)</source>
+ <source>Cannot open file: %1 (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create symlink at &apos;%1&apos;. Another one is already existing.</source>
+ <source>Cannot create symlink at &apos;%1&apos;. Another one is already existing.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not read symlink target from file &apos;%1&apos;.</source>
+ <source>Cannot read symlink target from file &apos;%1&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create symlink at %1. %2</source>
+ <source>Cannot create symlink at %1. %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2279,7 +2279,7 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create archive %1. %2</source>
+ <source>Cannot create archive %1. %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2295,7 +2295,7 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create output file for writing: %1</source>
+ <source>Cannot create output file for writing: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2311,15 +2311,15 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not backup file %1</source>
+ <source>Cannot backup file %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not delete file %1</source>
+ <source>Cannot delete file %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not restore backup file into %1</source>
+ <source>Cannot restore backup file into %1</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2331,7 +2331,7 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not write to registry path %1</source>
+ <source>Cannot write to registry path %1</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2339,7 +2339,7 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2347,7 +2347,7 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create folder at %1: %2</source>
+ <source>Cannot create folder at %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2379,11 +2379,11 @@ needs to be less than 255 characters.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not create link from %1 to %2.</source>
+ <source>Cannot create link from %1 to %2.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not remove link from %1 to %2.</source>
+ <source>Cannot remove link from %1 to %2.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2418,7 +2418,7 @@ as root and then clicking ok.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not get package manager core.</source>
+ <source>Cannot get package manager core.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2433,7 +2433,7 @@ as root and then clicking ok.</source>
<context>
<name>Settings</name>
<message>
- <source>Could not open settings file %1 for reading: %2</source>
+ <source>Cannot open settings file %1 for reading: %2</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2638,7 +2638,7 @@ Do you want to continue?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not parse Updates.xml! Error: %1.</source>
+ <source>Cannot parse Updates.xml! Error: %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
diff --git a/src/sdk/translations/es.ts b/src/sdk/translations/es.ts
new file mode 100644
index 000000000..1ce64b86e
--- /dev/null
+++ b/src/sdk/translations/es.ts
@@ -0,0 +1,2688 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="es_ES">
+<context>
+ <name>Component</name>
+ <message>
+ <source>Cannot open archive %1: %2</source>
+ <translation>No se puede abrir el archivo %1: %2</translation>
+ </message>
+</context>
+<context>
+ <name>Dialog</name>
+ <message>
+ <source>Http authentication required</source>
+ <translation>Autenticación Http requerida</translation>
+ </message>
+ <message>
+ <source>You need to supply a Username and Password to access this site.</source>
+ <translation>Tienes que suministrar un nombre de usuario y contraseña para poder acceder a este sitio.</translation>
+ </message>
+ <message>
+ <source>Username:</source>
+ <translation>Nombre de usuario:</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>Contraseña:</translation>
+ </message>
+ <message>
+ <source>%1 at %2</source>
+ <translation>%1 en %2</translation>
+ </message>
+</context>
+<context>
+ <name>IntroductionPageImpl</name>
+ <message>
+ <source>Package manager</source>
+ <translation>Gestor de paquetes</translation>
+ </message>
+ <message>
+ <source>Update components</source>
+ <translation>Actualizar componentes</translation>
+ </message>
+ <message>
+ <source>Remove all components</source>
+ <translation>Quitar todos los componentes</translation>
+ </message>
+ <message>
+ <source>Retrieving information from remote installation sources...</source>
+ <translation>Recuperando información de fuentes de instalación remotas...</translation>
+ </message>
+ <message>
+ <source>At least one valid and enabled repository required for this action to succeed.</source>
+ <translation>Necesitas tener al menos un repositorio habilitado para que esta acción se realice con éxito.</translation>
+ </message>
+ <message>
+ <source>No updates available.</source>
+ <translation>No hay actualizaciones disponibles.</translation>
+ </message>
+ <message>
+ <source> Only local package management available.</source>
+ <translation>Sólo está disponible la gestión de paquetes de forma local.</translation>
+ </message>
+ <message>
+ <source>Quit</source>
+ <translation>Salir</translation>
+ </message>
+</context>
+<context>
+ <name>Job</name>
+ <message>
+ <source>Canceled</source>
+ <translation>Cancelado</translation>
+ </message>
+</context>
+<context>
+ <name>KDSaveFile</name>
+ <message>
+ <source>Append mode not supported.</source>
+ <translation>Modo añadir no admitido.</translation>
+ </message>
+ <message>
+ <source>Read-only access not supported.</source>
+ <translation>Acceso de sólo lectura no admitido.</translation>
+ </message>
+ <message>
+ <source>Cannot backup existing file %1: %2</source>
+ <translation>No se puede hacer una copia de seguridad del archivo existente %1: %2</translation>
+ </message>
+ <message>
+ <source>TODO</source>
+ <translation>Tareas</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::AppendFileOperation</name>
+ <message>
+ <source>Cannot backup file %1: %2</source>
+ <translation>No se puede hacer una copia de seguridad del archivo %1: %2</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 2 expected.</source>
+ <translation>Argumentos no válidos: %1 argumentos dados, 2 esperados.</translation>
+ </message>
+ <message>
+ <source>Cannot open file %1 for writing: %2</source>
+ <translation>No se puede abrir el archivo %1 en modo escritura: %2</translation>
+ </message>
+ <message>
+ <source>Cannot find backup file for %1.</source>
+ <translation>No se puede localizar la copia de seguridad de %1.</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for %1.</source>
+ <translation>No se puede restaurar la copia de seguridad de %1.</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for %1: %2</source>
+ <translation>No se puede restaurar la copia de seguridad del archivo %1: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::CopyOperation</name>
+ <message>
+ <source>Cannot backup file %1.</source>
+ <translation>No se puede hacer una copia de seguridad del archivo %1.</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 2 expected.</source>
+ <translation>Argumentos no válidos: %1 argumentos dados, 2 esperados.</translation>
+ </message>
+ <message>
+ <source>Cannot remove destination file %1: %2</source>
+ <translation>No se puede eliminar el archivo de destino %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot copy %1 to %2: %3</source>
+ <translation>No se puede copiar %1 a %2: %3</translation>
+ </message>
+ <message>
+ <source>Cannot delete file %1: %2</source>
+ <translation>No se puede eliminar el archivo %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file into %1: %2</source>
+ <translation>No se puede restaurar la copia de seguridad del archivo como %1: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::DeleteOperation</name>
+ <message>
+ <source>Cannot create backup of %1: %2</source>
+ <translation>No se puede hacer una copia de seguridad de %1: %2</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 1 expected.</source>
+ <translation>Argumentos no válidos: %1 argumentos dados, 2 esperados.</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for %1: %2</source>
+ <translation>No se puede restaurar la copia de seguridad del archivo %1: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::FileDownloader</name>
+ <message>
+ <source>Download canceled.</source>
+ <translation>Descarga cancelada.</translation>
+ </message>
+ <message>
+ <source>Cryptographic hashes do not match.</source>
+ <translation>Los hashes criptográficos no coinciden.</translation>
+ </message>
+ <message>
+ <source>Download finished.</source>
+ <translation>Descarga.finalizada.</translation>
+ </message>
+ <message>
+ <source> of </source>
+ <translation> de </translation>
+ </message>
+ <message>
+ <source> downloaded.</source>
+ <translation> descargado.</translation>
+ </message>
+ <message>
+ <source>/sec</source>
+ <translation>/seg</translation>
+ </message>
+ <message>
+ <source> day</source>
+ <translation> día</translation>
+ </message>
+ <message>
+ <source> days</source>
+ <translation> días</translation>
+ </message>
+ <message>
+ <source> hour</source>
+ <translation> hora</translation>
+ </message>
+ <message>
+ <source> hours</source>
+ <translation> horas</translation>
+ </message>
+ <message>
+ <source> minute</source>
+ <translation> minuto</translation>
+ </message>
+ <message>
+ <source> minutes</source>
+ <translation> minutos</translation>
+ </message>
+ <message>
+ <source> second</source>
+ <translation> segundo</translation>
+ </message>
+ <message>
+ <source> seconds</source>
+ <translation> segundos</translation>
+ </message>
+ <message>
+ <source> - </source>
+ <translation> - </translation>
+ </message>
+ <message>
+ <source> remaining.</source>
+ <translation> resstante.</translation>
+ </message>
+ <message>
+ <source> - unknown time remaining.</source>
+ <translation> - tiempo restante desconocido.</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::HttpDownloader</name>
+ <message>
+ <source>Cannot download %1: Writing to file &apos;%2&apos; failed: %3</source>
+ <translation>No se puede descargar %1: ha fallado la escritura del archivo &apos;%2&apos;: %3</translation>
+ </message>
+ <message>
+ <source>Cannot download %1: Cannot create %2: %3</source>
+ <translation>No se puede descargar %1: No se puede crear %2: %3</translation>
+ </message>
+ <message>
+ <source>%1 at %2</source>
+ <translation>%1 en %2</translation>
+ </message>
+ <message>
+ <source>Authentication request canceled.</source>
+ <translation>Petición de autenticación cancelada.</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::LocalFileDownloader</name>
+ <message>
+ <source>Cannot open source file &apos;%1&apos; for reading.</source>
+ <translation>No se puede abrir el archivo de origen &apos;%1&apos; en modo lectura.</translation>
+ </message>
+ <message>
+ <source>Cannot open destination file &apos;%1&apos; for writing.</source>
+ <translation>No se puede abrir el archivo de destino &apos;%1&apos; en modo escritura.</translation>
+ </message>
+ <message>
+ <source>Writing to %1 failed: %2</source>
+ <translation>La escritura en %1 ha fallado: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::MkdirOperation</name>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 1 expected.</source>
+ <translation>Argumentos no válidos: %1 argumentos dados, 2 esperados.</translation>
+ </message>
+ <message>
+ <source>Cannot create folder %1: Unknown error.</source>
+ <translation>No se puede crear la carpeta %1: error desconocido.</translation>
+ </message>
+ <message>
+ <source>Cannot remove directory %1: %2</source>
+ <translation>No se puede eliminar el directorio %1: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::MoveOperation</name>
+ <message>
+ <source>Cannot backup file %1.</source>
+ <translation>No se puede hacer una copia de seguridad del archivo %1.</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 2 expected.</source>
+ <translation>Argumentos no válidos: %1 argumentos dados, 2 esperados.</translation>
+ </message>
+ <message>
+ <source>Cannot remove destination file %1: %2</source>
+ <translation>No se puede eliminar el archivo de destino %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot copy %1 to %2: %3</source>
+ <translation>No se puede copiar %1 a %2: %3</translation>
+ </message>
+ <message>
+ <source>Cannot remove file %1.</source>
+ <translation>No se puede eliminar el archivo %1.</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for %1: %2</source>
+ <translation>No se puede restaurar la copia de seguridad del archivo %1: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::PackagesInfo</name>
+ <message>
+ <source>%1 contains invalid content: %2</source>
+ <translation>%1 tiene contenido no válido: %2</translation>
+ </message>
+ <message>
+ <source>The file %1 does not exist.</source>
+ <translation>El archivo %1 no existe.</translation>
+ </message>
+ <message>
+ <source>Cannot open %1.</source>
+ <translation>No se puede abrir el archivo %1.</translation>
+ </message>
+ <message>
+ <source>Parse error in %1 at %2, %3: %4</source>
+ <translation>Error al analizar en %1 en %2, %3: %4</translation>
+ </message>
+ <message>
+ <source>Root element %1 unexpected, should be &apos;Packages&apos;.</source>
+ <translation>Elemento raíz %1 no esperado, debería ser &apos;Packages&apos;.</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::PrependFileOperation</name>
+ <message>
+ <source>Cannot backup file %1: %2</source>
+ <translation>No se puede hacer una copia de seguridad del archivo %1: %2</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 2 expected.</source>
+ <translation>Argumentos no válidos: %1 argumentos dados, 2 esperados.</translation>
+ </message>
+ <message>
+ <source>Cannot open file %1 for reading: %2</source>
+ <translation>No se puede abrir el archivo %1 en modo lectura: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file %1 for writing: %2</source>
+ <translation>No se puede abrir el archivo %1 en modo escritura: %2</translation>
+ </message>
+ <message>
+ <source>Cannot find backup file for %1.</source>
+ <translation>No se puede localizar la copia de seguridad de %1.</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for %1.</source>
+ <translation>No se puede restaurar la copia de seguridad de %1.</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for %1: %2</source>
+ <translation>No se puede restaurar la copia de seguridad del archivo %1: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::ResourceFileDownloader</name>
+ <message>
+ <source>Cannot read resource file &quot;%1&quot;. Reason:</source>
+ <translation>No se puede leer el archivo de recursos &quot;%1&quot;. Motivo:</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::RmdirOperation</name>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 1 expected.</source>
+ <translation>Argumentos no válidos: %1 argumentos dados, 1 esperado.</translation>
+ </message>
+ <message>
+ <source>Cannot remove folder %1: The folder does not exist.</source>
+ <translation>No se puede eliminar la carpeta %1: la carpeta no existe.</translation>
+ </message>
+ <message>
+ <source>Cannot remove folder %1: %2</source>
+ <translation>No se puede eliminar la carpeta %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot recreate directory %1: %2</source>
+ <translation>No se puede recrear el directorio %1: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::Task</name>
+ <message>
+ <source>%1 started</source>
+ <translation>%1 empezada</translation>
+ </message>
+ <message>
+ <source>%1 cannot be stopped</source>
+ <translation>No se puede parar %1</translation>
+ </message>
+ <message>
+ <source>Cannot stop task %1</source>
+ <translation>No se puede parar la tarea %1</translation>
+ </message>
+ <message>
+ <source>%1 cannot be paused</source>
+ <translation>No se puede pausar %1</translation>
+ </message>
+ <message>
+ <source>Cannot pause task %1</source>
+ <translation>No se puede pausar la tarea %1</translation>
+ </message>
+ <message>
+ <source>Cannot resume task %1</source>
+ <translation>No se puede reanudar la tarea %1</translation>
+ </message>
+ <message>
+ <source>%1 done</source>
+ <translation>%1 hecha</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::UpdateFinder</name>
+ <message>
+ <source>Cannot access the package information of this application.</source>
+ <translation>No se puede acceder a la información del paquete de esta aplicación.</translation>
+ </message>
+ <message>
+ <source>Cannot access the update sources information of this application.</source>
+ <translation>No se puede acceder a la información de las fuentes de actualizaciones.</translation>
+ </message>
+ <message>
+ <source>%1 updates found.</source>
+ <translation>Hay %1 actualizaciones.</translation>
+ </message>
+ <message>
+ <source>Downloading Updates.xml from update sources.</source>
+ <translation>Descargando Updates.xml de las fuentes de actualizaciones.</translation>
+ </message>
+ <message>
+ <source>Cannot download updates from %1 (&apos;%2&apos;)</source>
+ <translation>No se pueden descargar las actualizaciones de %1 (&apos;%2&apos;)</translation>
+ </message>
+ <message>
+ <source>Updates.xml file(s) downloaded from update sources.</source>
+ <translation>Archivo(s) Updates.xml descargados de las fuentes de actualizaciones.</translation>
+ </message>
+ <message>
+ <source>Computing applicable updates.</source>
+ <translation>Comprobando qué actualizaciones son necesarias.</translation>
+ </message>
+ <message>
+ <source>Application updates computed.</source>
+ <translation>Actualizaciones de la aplicación comprobadas.</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::UpdateSourcesInfo</name>
+ <message>
+ <source>%1 contains invalid content: %2</source>
+ <translation>%1 tiene contenido no válido: %2</translation>
+ </message>
+ <message>
+ <source>Cannot read &quot;%1&quot;</source>
+ <translation>No se puede leer &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <source>XML Parse error in %1 at %2, %3: %4</source>
+ <translation>Error al analizar XML en %1 en %2, %3: %4</translation>
+ </message>
+ <message>
+ <source>Root element %1 unexpected, should be &quot;UpdateSources&quot;</source>
+ <translation>Elemento raíz %1 no esperado, debería ser &apos;UpdateSources&apos;</translation>
+ </message>
+ <message>
+ <source>Cannot save changes to &quot;%1&quot;: %2</source>
+ <translation>No se pueden guardar los cambios en &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::UpdatesInfoData</name>
+ <message>
+ <source>Cannot read &quot;%1&quot;</source>
+ <translation>No se puede leer &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <source>Parse error in %1 at %2, %3: %4</source>
+ <translation>Error al analizar en %1 en %2, %3: %4</translation>
+ </message>
+ <message>
+ <source>Updates.xml contains invalid content: %1</source>
+ <translation>Updates.xml tiene contenido no válido: %1</translation>
+ </message>
+ <message>
+ <source>Root element %1 unexpected, should be &quot;Updates&quot;.</source>
+ <translation>Elemento raíz %1 no esperado, debería ser &quot;Updates&quot;.</translation>
+ </message>
+ <message>
+ <source>ApplicationName element is missing.</source>
+ <translation>Falta el elemento ApplicationName.</translation>
+ </message>
+ <message>
+ <source>ApplicationVersion element is missing.</source>
+ <translation>Falta el elemento ApplicationVersion.</translation>
+ </message>
+ <message>
+ <source>PackageUpdate element without Name</source>
+ <translation>Elemento PackageUpdate sin &quot;Name&quot;</translation>
+ </message>
+ <message>
+ <source>PackageUpdate element without Version</source>
+ <translation>Elemento PackageUpdate sin &quot;Version&quot;</translation>
+ </message>
+ <message>
+ <source>PackageUpdate element without ReleaseDate</source>
+ <translation>Elemento PackageUpdate sin &quot;ReleaseDate&quot;</translation>
+ </message>
+</context>
+<context>
+ <name>Lib7z::ExtractItemJob</name>
+ <message>
+ <source>Cannot list archive: QIODevice not set or already destroyed.</source>
+ <translation>No se puede listar el archivo: QIODevice no está establecido o ya está destruido.</translation>
+ </message>
+</context>
+<context>
+ <name>Lib7z::ListArchiveJob</name>
+ <message>
+ <source>Cannot list archive: QIODevice already destroyed.</source>
+ <translation>No se puede listar el archivo: QIODevice ya está destruido.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::AddQtCreatorArrayValueOperation</name>
+ <message>
+ <source>exactly 4</source>
+ <translation>exactamente 4</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source> (group, arrayname, key, value)</source>
+ <translation> (group, arrayname, key, value)</translation>
+ </message>
+ <message>
+ <source>Needed installer object in %1 operation is empty.</source>
+ <translation>Se necesita el objeto del instalador en %1 la operación está vacía.</translation>
+ </message>
+ <message>
+ <source>There is no value set for %1 on the installer object.</source>
+ <translation>No se ha asignado un valor a %1 en el objeto del instalador.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::Component</name>
+ <message>
+ <source>Cannot open the requested translation file &apos;%1&apos;.</source>
+ <translation>No se puede abrir el archivo de traducción %1&apos; solicitado.</translation>
+ </message>
+ <message>
+ <source>Cannot open the requested UI file &apos;%1&apos;. Error: %2</source>
+ <translation>No se puede abrir el archivo de UI &apos;%1&apos; solicitado. Error: %2</translation>
+ </message>
+ <message>
+ <source>Cannot load the requested UI file &apos;%1&apos;. Error: %2</source>
+ <translation>No se puede cargar el archivo de UI &apos;%1&apos; solicitado. Error: %2</translation>
+ </message>
+ <message>
+ <source>An error has occurred while reading the UI file.</source>
+ <translation>Se ha producido un error al leer el archivo del UI.</translation>
+ </message>
+ <message>
+ <source>Cannot open the requested license file &apos;%1&apos;. Error: %2</source>
+ <translation>No se puede abrir el archivo de licencia %1&apos; solicitado. Error: %2</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>Error: Operation %1 does not exist</source>
+ <translation>Error: la operación %1 no existe</translation>
+ </message>
+ <message>
+ <source>Can&apos;t resolve isAutoDependOn in %1</source>
+ <translation>No se puede resolver isAutoDependOn en %1</translation>
+ </message>
+ <message>
+ <source>Can&apos;t resolve isDefault in %1</source>
+ <translation>No se puede resolver isDefault en %1</translation>
+ </message>
+ <message>
+ <source>Update Info: </source>
+ <translation>Información de actualización:</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ComponentModel</name>
+ <message>
+ <source>Component Name</source>
+ <translation>Nombre del componente</translation>
+ </message>
+ <message>
+ <source>Installed Version</source>
+ <translation>Versión instalada</translation>
+ </message>
+ <message>
+ <source>New Version</source>
+ <translation>Nueva versión</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation>Tamaño</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ComponentSelectionPage</name>
+ <message>
+ <source>Alt+A</source>
+ <comment>select default components</comment>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Def&amp;ault</source>
+ <translation>P&amp;redeterminado</translation>
+ </message>
+ <message>
+ <source>Alt+R</source>
+ <comment>reset to already installed components</comment>
+ <translation>Alt+R</translation>
+ </message>
+ <message>
+ <source>&amp;Reset</source>
+ <translation>&amp;Restablecer</translation>
+ </message>
+ <message>
+ <source>Alt+S</source>
+ <comment>select all components</comment>
+ <translation>Alt+S</translation>
+ </message>
+ <message>
+ <source>&amp;Select All</source>
+ <translation>&amp;Seleccionar todo</translation>
+ </message>
+ <message>
+ <source>Alt+D</source>
+ <comment>deselect all components</comment>
+ <translation>Alt+D</translation>
+ </message>
+ <message>
+ <source>&amp;Deselect All</source>
+ <translation>&amp;Deseleccionar todo</translation>
+ </message>
+ <message>
+ <source>This component will occupy approximately %1 on your hard disk drive.</source>
+ <translation>Este componente ocupará aproximadamente %1 de tu disco duro.</translation>
+ </message>
+ <message>
+ <source>Select Components</source>
+ <translation>Seleccionar componentes</translation>
+ </message>
+ <message>
+ <source>Please select the components you want to update.</source>
+ <translation>Por favor, selecciona los componentes que quieres actualizar.</translation>
+ </message>
+ <message>
+ <source>Please select the components you want to install.</source>
+ <translation>Por favor, selecciona los componentes que quieres instalar.</translation>
+ </message>
+ <message>
+ <source>Please select the components you want to uninstall.</source>
+ <translation>Por favor, selecciona los componentes que quieres desinstalar.</translation>
+ </message>
+ <message>
+ <source>Select the components to install. Deselect installed components to uninstall them.</source>
+ <translation>Selecciona los componentes para instalarlos. Deselecciona los componentes instalados para desinstalarlos.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ConsumeOutputOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>at least 2</source>
+ <translation>por lo menos 2</translation>
+ </message>
+ <message>
+ <source>Needed installer object in %1 operation is empty.</source>
+ <translation>Se necesita el objeto del instalador en %1 la operación está vacía.</translation>
+ </message>
+ <message>
+ <source>Can not save the output of %1 to an empty installer key value.</source>
+ <translation>No se puede guardar la salida de %1 en un valor vacío de la clave del instalador.</translation>
+ </message>
+ <message>
+ <source>File &apos;%1&apos; does not exist or is not an executable binary.</source>
+ <translation>El archivo &apos;%1&apos; no existe o no es un binario ejecutable.</translation>
+ </message>
+ <message>
+ <source>Running &apos;%1&apos; resulted in a crash.</source>
+ <translation>&apos;%1&apos; se ha cerrado de forma inesperada.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CopyDirectoryOperation</name>
+ <message>
+ <source>2 or 3</source>
+ <translation>2 ó 3</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source> (&lt;source&gt; &lt;target&gt; [forceOverwrite])</source>
+ <translation> (&lt;source&gt; &lt;target&gt; [forceOverwrite])</translation>
+ </message>
+ <message>
+ <source>Invalid argument in %0: Third argument needs to be forceOverwrite, if specified</source>
+ <translation>Argumento no válido en %0: si el tercer argumento está definido, tiene que ser forceOverwrite</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: Directories are invalid: %1 %2</source>
+ <translation>Argumentos no válidos en %0: directorios no válidos: %1 %2</translation>
+ </message>
+ <message>
+ <source>Cannot create %0</source>
+ <translation>No se puede crear %0</translation>
+ </message>
+ <message>
+ <source>Failed to overwrite %1</source>
+ <translation>Fallo al sobrescribir %1</translation>
+ </message>
+ <message>
+ <source>Cannot copy %0 to %1, error was: %3</source>
+ <translation>No se puede copiar %0 a %1, error: %3</translation>
+ </message>
+ <message>
+ <source>Cannot remove %0</source>
+ <translation>No se puede eliminar %0</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CreateDesktopEntryOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>exactamente 2</translation>
+ </message>
+ <message>
+ <source>Failed to overwrite %1</source>
+ <translation>Fallo al sobrescribir %1</translation>
+ </message>
+ <message>
+ <source>Cannot write Desktop Entry at %1</source>
+ <translation>No se puede escribir la entrada de escritorio en %1</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CreateLinkOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>exactamente 2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CreateLocalRepositoryOperation</name>
+ <message>
+ <source>Cannot set file permissions %1!</source>
+ <translation>¡No se pueden dar los permisos %1!</translation>
+ </message>
+ <message>
+ <source>Cannot move file %1 to %2. Error: %3</source>
+ <translation>No se puede mover el archivo %1 a %2. Error: %3</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>exactamente 2</translation>
+ </message>
+ <message>
+ <source>Installer needs to be an offline version: %1.</source>
+ <translation>El instalador tiene que ser la versión sin conexión: %1.</translation>
+ </message>
+ <message>
+ <source>Cannot open file: %1</source>
+ <translation>No se puede abrir el archivo: %1</translation>
+ </message>
+ <message>
+ <source>Cannot read: %1. Error: %2</source>
+ <translation>No se puede leer: %1. Error: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file: %1. Error: %2</source>
+ <translation>No se puede leer el archivo %1. Error: %2</translation>
+ </message>
+ <message>
+ <source>Cannot create target dir: %1.</source>
+ <translation>No se puede crear el directorio de destino: %1.</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught: %1.</source>
+ <translation>Excepción desconocida capturada: %1.</translation>
+ </message>
+ <message>
+ <source>Removing file: %0</source>
+ <translation>Eliminando archivo: %0</translation>
+ </message>
+ <message>
+ <source>Cannot remove %0.</source>
+ <translation>No se puede eliminar %0.</translation>
+ </message>
+ <message>
+ <source>Cannot remove directory %1: %2</source>
+ <translation>No se puede eliminar el directorio %1: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CreateShortcutOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>2 or 3</source>
+ <translation>2 ó 3</translation>
+ </message>
+ <message>
+ <source> (optional: &apos;workingDirectory=...&apos;)</source>
+ <translation> (opcional: &apos;workingDirectory=...&apos;)</translation>
+ </message>
+ <message>
+ <source>Cannot create folder %1: %2.</source>
+ <translation>No se puede crear la carpeta %1: %2.</translation>
+ </message>
+ <message>
+ <source>Cannot create link %1: %2</source>
+ <translation>No se puede crear el enlace %1: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::DownloadArchivesJob</name>
+ <message>
+ <source>Canceled</source>
+ <translation>Cancelado</translation>
+ </message>
+ <message>
+ <source>Downloading hash signature failed.</source>
+ <translation>La descarga de la firma del hash ha fallado.</translation>
+ </message>
+ <message>
+ <source>Download Error</source>
+ <translation>Error de descarga</translation>
+ </message>
+ <message>
+ <source>Hash verification while downloading failed. This is a temporary error, please retry.</source>
+ <translation>La verificación del hash ha fallado al descargar. Es un error temporal,por favor inténtalo de nuevo.</translation>
+ </message>
+ <message>
+ <source>Cannot verify Hash</source>
+ <translation>No se puede verificar el hash</translation>
+ </message>
+ <message>
+ <source>Cannot download archive: %1 : %2</source>
+ <translation>No se puede descargar el archivo %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot fetch archives: %1
+Error while loading %2</source>
+ <translation>No se pueden traer los archivos: %1
+Error al cargar %2</translation>
+ </message>
+ <message>
+ <source>Downloading archive hash for component: %1</source>
+ <translation>Descargando el hash del archivo para el componente: %1</translation>
+ </message>
+ <message>
+ <source>Downloading archive for component: %1</source>
+ <translation>Descargando archivo para el componente: %1</translation>
+ </message>
+ <message>
+ <source>Scheme not supported: %1 (%2)</source>
+ <translation>Esquema no admitido: %1 (%2)</translation>
+ </message>
+ <message>
+ <source>Cannot find component for: %1.</source>
+ <translation>No se puede localizar el componente para: %1.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ElevatedExecuteOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>at least 1</source>
+ <translation>por lo menos 1</translation>
+ </message>
+ <message>
+ <source>Execution failed: Cannot start detached: &quot;%1&quot;</source>
+ <translation>La ejecución ha fallado: no se puede iniciar separada: &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <source>Execution failed: Cannot start: &quot;%1&quot;(%2)</source>
+ <translation>La ejecución ha fallado: no se puede iniciar: &quot;%1&quot;(%2)</translation>
+ </message>
+ <message>
+ <source>Execution failed(Crash): &quot;%1&quot;</source>
+ <translation>La ejecución ha fallado (cuelgue): &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <source>Execution failed(Unexpected exit code: %1): &quot;%2&quot;</source>
+ <translation>La ejecución ha fallado (código de salida inesperado: %1): &quot;%2&quot;</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::EnvironmentVariableOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>2 or 3</source>
+ <translation>2 ó 3</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ExtractArchiveOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>exactamente 2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ExtractArchiveOperation::Runnable</name>
+ <message>
+ <source>Cannot open %1 for reading: %2.</source>
+ <translation>No se puede abrir el archivo %1 en modo lectura: %2.</translation>
+ </message>
+ <message>
+ <source>Error while extracting &apos;%1&apos;: %2</source>
+ <translation>Error al extraer &apos;%1&apos;: %2</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught while extracting %1.</source>
+ <translation>Excepción desconocida capturada al extraer %1.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::FinishedPage</name>
+ <message>
+ <source>Completing the %1 Wizard</source>
+ <translation>Completando el asistente de %1</translation>
+ </message>
+ <message>
+ <source>Click Done to exit the %1 Wizard.</source>
+ <translation>Haz clic en hecho para salir del asistente de %1.</translation>
+ </message>
+ <message>
+ <source>Click Finish to exit the %1 Wizard.</source>
+ <translation>Haz clic en terminar para salir del asistente de %1.</translation>
+ </message>
+ <message>
+ <source>Restart</source>
+ <translation>Reiniciar</translation>
+ </message>
+ <message>
+ <source>Run %1 now.</source>
+ <translation>Ejecutar %1 ahora.</translation>
+ </message>
+ <message>
+ <source>The %1 Wizard failed.</source>
+ <translation>El asistente de %1 ha fallado.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::GetRepositoryMetaInfoJob</name>
+ <message>
+ <source>Empty repository URL.</source>
+ <translation>URL del repositorio vacía.</translation>
+ </message>
+ <message>
+ <source>Retrieving component meta information...</source>
+ <translation>Recuperando metadatos del componente...</translation>
+ </message>
+ <message>
+ <source>Invalid repository URL: %1</source>
+ <translation>URL del repositorio no válida: %1</translation>
+ </message>
+ <message>
+ <source>URL scheme not supported: %1 (%2)</source>
+ <translation>Esquema de URL no admitido: %1 (%2)</translation>
+ </message>
+ <message>
+ <source>Cannot move Updates.xml to target location. Error: %1</source>
+ <translation>No se puede mover Updates.xml a la ubicación de destino. Error: %1</translation>
+ </message>
+ <message>
+ <source>Cannot open Updates.xml for reading. Error: %1</source>
+ <translation>No se puede abrir Updates.xml en modo lectura. Error: %1</translation>
+ </message>
+ <message>
+ <source>Cannot fetch a valid version of Updates.xml from repository: %1. Error: %2</source>
+ <translation>No se puede traer una versión válida de Updates.xml del repositorio: %1. Error: %2</translation>
+ </message>
+ <message>
+ <source>Download Error</source>
+ <translation>Error de descarga</translation>
+ </message>
+ <message>
+ <source>Parsing component meta information...</source>
+ <translation>Analizando los metadatos del componente...</translation>
+ </message>
+ <message>
+ <source>Repository updates received.</source>
+ <translation>Actualizaciones del repositorio obtenidas.</translation>
+ </message>
+ <message>
+ <source>Finished updating component meta information.</source>
+ <translation>Actualización de los metadatos del componente finalizada.</translation>
+ </message>
+ <message>
+ <source>Cannot fetch Updates.xml from repository: %1. Error: %2</source>
+ <translation>No se puede traer Updates.xml del repositorio: %1. Error: %2</translation>
+ </message>
+ <message>
+ <source>Retrieving component information from remote repository...</source>
+ <translation>Recuperando información del componente del repositorio remoto...</translation>
+ </message>
+ <message>
+ <source>Cannot open meta info archive: %1. Error: %2</source>
+ <translation>No se puede abrir el archivo de metadatos %1. Error: %2</translation>
+ </message>
+ <message>
+ <source>The hash of one component does not match the expected one.</source>
+ <translation>El hash de un componente no coincide con el esperado.</translation>
+ </message>
+ <message>
+ <source>Bad hash.</source>
+ <translation>Hash erróneo.</translation>
+ </message>
+ <message>
+ <source>Cannot download meta information for component: %1. Error: %2</source>
+ <translation>No se pueden descargar los metadatos del componente: %1. Error: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::GetRepositoryMetaInfoJob::ZipRunnable</name>
+ <message>
+ <source>Error while extracting &apos;%1&apos;: %2</source>
+ <translation>Error al extraer &apos;%1&apos;: %2</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught while extracting %1.</source>
+ <translation>Excepción desconocida capturada al extraer %1.</translation>
+ </message>
+ <message>
+ <source>Cannot open %1 for reading. Error: %2</source>
+ <translation>No se puede abrir %1 en modo lectura. Error: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::GlobalSettingsOperation</name>
+ <message>
+ <source>Settings are not writable</source>
+ <translation>No se puede escribir en la configuración</translation>
+ </message>
+ <message>
+ <source>Failed to write settings</source>
+ <translation>Fallo al escribir la configuración</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>3 or 4</source>
+ <translation>3 ó 4</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::InstallIconsOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>1 or 2</source>
+ <translation>1 ó 2</translation>
+ </message>
+ <message>
+ <source> (Sourcepath, [Vendorprefix])</source>
+ <translation> (Sourcepath, [Vendorprefix])</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::IntroductionPage</name>
+ <message>
+ <source>Setup - %1</source>
+ <translation>Instalación - %1</translation>
+ </message>
+ <message>
+ <source>Welcome to the %1 Setup Wizard.</source>
+ <translation>Bienvenido al asistente de instalación de %1.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::LicenseAgreementPage</name>
+ <message>
+ <source>License Agreement</source>
+ <translation>Acuerdo de licencia</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <comment>agree license</comment>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Please read the following license agreement. You must accept the terms contained in this agreement before continuing with the installation.</source>
+ <translation>Por favor, lee el siguiente acuerdo de licencia. Tienes que aceptar los términos de este acuerdo para poder continuar con la instalación.</translation>
+ </message>
+ <message>
+ <source>I accept the license.</source>
+ <translation>Acepto la licencia.</translation>
+ </message>
+ <message>
+ <source>I do not accept the license.</source>
+ <translation>No acepto la licencia.</translation>
+ </message>
+ <message>
+ <source>Please read the following license agreements. You must accept the terms contained in these agreements before continuing with the installation.</source>
+ <translation>Por favor, lee el siguiente acuerdo de licencia. Tienes que aceptar los términos de este acuerdo para poder continuar con la instalación.</translation>
+ </message>
+ <message>
+ <source>I accept the licenses.</source>
+ <translation>Acepto las licencias.</translation>
+ </message>
+ <message>
+ <source>I do not accept the licenses.</source>
+ <translation>No acepto las licencias.</translation>
+ </message>
+ <message>
+ <source>Alt+D</source>
+ <comment>do not agree license</comment>
+ <translation>Alt+D</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::LicenseOperation</name>
+ <message>
+ <source>No license files found to copy.</source>
+ <translation>No se han localizado los archivos de licencia para copiar.</translation>
+ </message>
+ <message>
+ <source>Needed installer object in %1 operation is empty.</source>
+ <translation>Se necesita el objeto del instalador en %1 la operación está vacía.</translation>
+ </message>
+ <message>
+ <source>Can not write license file: %1.</source>
+ <translation>No se puede escribir el archivo de licencia: %1.</translation>
+ </message>
+ <message>
+ <source>No license files found to delete.</source>
+ <translation>No se han localizado archivos de licencia para eliminar.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::LineReplaceOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 3</source>
+ <translation>exactamente 3</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::MacReplaceInstallNamesOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>at least 3</source>
+ <translation>por lo menos 3</translation>
+ </message>
+ <message>
+ <source>One of the given arguments is empty. Argument1=%1; Argument2=%2, Argument3=%3</source>
+ <translation>Uno de los argumentos dados está vacío. Argumento1=%1; Argumento2=%2, Argumento3=%3</translation>
+ </message>
+ <message>
+ <source>Can&apos;t invoke otool. Is Xcode installed?</source>
+ <translation>No se puede invocar otool. ¿Está Xcode instalado?</translation>
+ </message>
+ <message>
+ <source>Can&apos;t start process %0.</source>
+ <translation>No se puede iniciar el proceso %0.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PackageManagerCore</name>
+ <message>
+ <source>Error writing Uninstaller</source>
+ <translation>Error al escribir el desinstalador</translation>
+ </message>
+ <message>
+ <source>
+Downloading packages...</source>
+ <translation>
+Descargando paquetes...</translation>
+ </message>
+ <message>
+ <source>Installation canceled by user</source>
+ <translation>Instalación cancelada por el usuario</translation>
+ </message>
+ <message>
+ <source>All downloads finished.</source>
+ <translation>Todas las descargas han terminado.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>Cancelling the Installer</source>
+ <translation>Cancelando el instalador</translation>
+ </message>
+ <message>
+ <source>Authentication Error</source>
+ <translation>Error de autenticación</translation>
+ </message>
+ <message>
+ <source>Some components could not be removed completely because admin rights could not be acquired: %1.</source>
+ <translation>Algunos componentes no se han podido desinstalar completamente por falta de permisos de administrador: %1.</translation>
+ </message>
+ <message>
+ <source>Unknown error.</source>
+ <translation>Error desconocido.</translation>
+ </message>
+ <message>
+ <source>Some components could not be removed completely because an unknown error happened.</source>
+ <translation>Algunos componentes no se han podido desinstalar completamente porque se ha producido un error desconocido.</translation>
+ </message>
+ <message>
+ <source>Application not running in Package Manager mode!</source>
+ <translation>¡La aplicación no se está ejecutando en modo gestión de paquetes!</translation>
+ </message>
+ <message>
+ <source>No installed packages found.</source>
+ <translation>No se han encontrado paquetes instalados.</translation>
+ </message>
+ <message>
+ <source>Application running in Uninstaller mode!</source>
+ <translation>¡La aplicación se está ejecutando en modo desinstalador!</translation>
+ </message>
+ <message>
+ <source>invalid</source>
+ <translation>no válido</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PackageManagerCorePrivate</name>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>Component(s) added as automatic dependencies</source>
+ <translation>Componente(s) añadidos como dependencias automáticas</translation>
+ </message>
+ <message>
+ <source>Added as dependency for %1.</source>
+ <translation>Añadido como dependencia de %1.</translation>
+ </message>
+ <message>
+ <source>Component(s) that have resolved Dependencies</source>
+ <translation>Componente(s) que tienen dependencias resueltas</translation>
+ </message>
+ <message>
+ <source>Selected Component(s) without Dependencies</source>
+ <translation>Componente(s) seleccionados sin dependencias</translation>
+ </message>
+ <message>
+ <source>Access error</source>
+ <translation>Error de acceso</translation>
+ </message>
+ <message>
+ <source>Format error</source>
+ <translation>Error de formato</translation>
+ </message>
+ <message>
+ <source>Cannot write installer configuration to %1: %2</source>
+ <translation>No se puede escribir la configuración del instalador en %1: %2</translation>
+ </message>
+ <message>
+ <source>Stop Processes</source>
+ <translation>Parar procesos</translation>
+ </message>
+ <message>
+ <source>These processes should be stopped to continue:
+
+%1</source>
+ <translation>Estos procesos se tienen que parar para poder continuar:
+
+%1</translation>
+ </message>
+ <message>
+ <source>Installation canceled by user</source>
+ <translation>Instalación cancelada por el usuario</translation>
+ </message>
+ <message>
+ <source>Writing uninstaller.</source>
+ <translation>Escribiendo el desinstalador.</translation>
+ </message>
+ <message>
+ <source>Uninstaller is not a bundle</source>
+ <translation>El desinstalador no es un paquete</translation>
+ </message>
+ <message>
+ <source>Cannot write uninstaller data to %1: %2</source>
+ <translation>No se pueden escribir los datos del desinstalador en %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot write uninstaller to %1: %2</source>
+ <translation>No se pueden escribir el desinstalador en %1: %2</translation>
+ </message>
+ <message>
+ <source>Found a binary data file, but we are the installer and we should read the binary resource from our very own binary!</source>
+ <translation>Se ha localizado un archivo de datos binarios, pero ¡sólo el instalador debería leer el recurso binario desde su propio binario!</translation>
+ </message>
+ <message>
+ <source>Cannot write uninstaller binary data to %1: %2</source>
+ <translation>No se pueden escribir los datos binarios del desinstalador en %1: %2</translation>
+ </message>
+ <message>
+ <source>ProductName should be set</source>
+ <translation>Se tiene que establecer ProductName</translation>
+ </message>
+ <message>
+ <source>Variable &apos;TargetDir&apos; not set.</source>
+ <translation>Variable &apos;TargetDir&apos; sin establecer.</translation>
+ </message>
+ <message>
+ <source>Preparing the installation...</source>
+ <translation>Preparando la instalación...</translation>
+ </message>
+ <message>
+ <source>It is not possible to install from network location</source>
+ <translation>No es posible instalar desde una ubicación de red</translation>
+ </message>
+ <message>
+ <source>Creating local repository</source>
+ <translation>Creando repositorio local</translation>
+ </message>
+ <message>
+ <source>Creating Uninstaller</source>
+ <translation>Creando desinstalador</translation>
+ </message>
+ <message>
+ <source>
+Installation finished!</source>
+ <translation>
+¡Instalación terminada!</translation>
+ </message>
+ <message>
+ <source>
+Installation aborted!</source>
+ <translation>
+¡Instalación cancelada!</translation>
+ </message>
+ <message>
+ <source>It is not possible to run that operation from a network location</source>
+ <translation>No es posible ejecutar esa operación desde una ubicación de red</translation>
+ </message>
+ <message>
+ <source>Removing deselected components...</source>
+ <translation>Eliminando componentes desmarcados...</translation>
+ </message>
+ <message>
+ <source>
+Update finished!</source>
+ <translation>
+¡Actualización terminada!</translation>
+ </message>
+ <message>
+ <source>
+Update aborted!</source>
+ <translation>
+¡Actualización cancelada!</translation>
+ </message>
+ <message>
+ <source>
+Uninstallation completed successfully!</source>
+ <translation>
+¡Desinstalación completada con éxito!</translation>
+ </message>
+ <message>
+ <source>
+Uninstallation aborted!</source>
+ <translation>
+¡Instalación cancelada!</translation>
+ </message>
+ <message>
+ <source>
+Installing component %1</source>
+ <translation>
+Instalando componente %1</translation>
+ </message>
+ <message>
+ <source>Installer Error</source>
+ <translation>Error del instalador</translation>
+ </message>
+ <message>
+ <source>Error during installation process (%1):
+%2</source>
+ <translation>Error durante el proceso de instalación (%1):
+%2</translation>
+ </message>
+ <message>
+ <source>Cannot prepare uninstall</source>
+ <translation>No se puede prepara la desinstalación</translation>
+ </message>
+ <message>
+ <source>Cannot start uninstall</source>
+ <translation>No se puede iniciar la desinstalación</translation>
+ </message>
+ <message>
+ <source>Error during uninstallation process:
+%1</source>
+ <translation>Error durante el proceso de desinstalación:
+%1</translation>
+ </message>
+ <message>
+ <source>Unknown error</source>
+ <translation>Error desconocido</translation>
+ </message>
+ <message>
+ <source>Cannot retrieve remote tree: %1.</source>
+ <translation>No se puede recuperar el árbol remoto: %1.</translation>
+ </message>
+ <message>
+ <source>Failure to read packages from: %1.</source>
+ <translation>Error al leer los paquetes de: %1.</translation>
+ </message>
+ <message>
+ <source>Cannot retrieve meta information: %1</source>
+ <translation>No se pueden recuperar los metadatos: %1</translation>
+ </message>
+ <message>
+ <source>Cannot add temporary update source information.</source>
+ <translation>No se puede añadir información sobre la fuente de actualizaciones temporal.</translation>
+ </message>
+ <message>
+ <source>Cannot find any update source information.</source>
+ <translation>No se puede localizar ninguna información sobre la fuente de actualizaciones.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PackageManagerGui</name>
+ <message>
+ <source>%1 Setup</source>
+ <translation>Instalación de %1</translation>
+ </message>
+ <message>
+ <source>Maintain %1</source>
+ <translation>Mantener %1</translation>
+ </message>
+ <message>
+ <source>Question</source>
+ <translation>Pregunta</translation>
+ </message>
+ <message>
+ <source>Do you want to abort the %1 process?</source>
+ <translation>¿Quieres cancelar el proceso %1?</translation>
+ </message>
+ <message>
+ <source>uninstallation</source>
+ <translation>desinstalación</translation>
+ </message>
+ <message>
+ <source>installation</source>
+ <translation>instalación</translation>
+ </message>
+ <message>
+ <source>installer</source>
+ <translation>instalador</translation>
+ </message>
+ <message>
+ <source>uninstaller</source>
+ <translation>desinstalador</translation>
+ </message>
+ <message>
+ <source>maintenance</source>
+ <translation>mantenimiento</translation>
+ </message>
+ <message>
+ <source>Do you want to quit the %1 application?</source>
+ <translation>¿Quieres salir de la aplicación %1?</translation>
+ </message>
+ <message>
+ <source>Settings</source>
+ <translation>Configuración</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>It is not possible to install from network location.
+Please copy the installer to a local drive</source>
+ <translation>No es posible instalar desde una ubicación de red.
+Por favor, copia el instalador a un disco local</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PerformInstallationForm</name>
+ <message>
+ <source>&amp;Show Details</source>
+ <translation>&amp;Mostrar detalles</translation>
+ </message>
+ <message>
+ <source>&amp;Hide Details</source>
+ <translation>&amp;Ocultar detalles</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PerformInstallationPage</name>
+ <message>
+ <source>U&amp;ninstall</source>
+ <translation>D&amp;esinstalar</translation>
+ </message>
+ <message>
+ <source>Uninstalling %1</source>
+ <translation>Desinstalando %1</translation>
+ </message>
+ <message>
+ <source>&amp;Update</source>
+ <translation>&amp;Actualizar</translation>
+ </message>
+ <message>
+ <source>Updating components of %1</source>
+ <translation>Actualizando componentes de %1</translation>
+ </message>
+ <message>
+ <source>&amp;Install</source>
+ <translation>&amp;Instalar</translation>
+ </message>
+ <message>
+ <source>Installing %1</source>
+ <translation>Instalando %1</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::QtPatchOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 3</source>
+ <translation>exactamente 3</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
+ <translation>Se necesita el objeto del instalador en &quot;%1&quot; la operación está vacía.</translation>
+ </message>
+ <message>
+ <source>First argument should be &apos;linux&apos;, &apos;mac&apos; or &apos;windows&apos;. No other type is supported at this time.</source>
+ <translation>El primer argumento tiene que ser &apos;linux&apos;, &apos;mac&apos; o &apos;windows&apos;. Por el momento no se admiten otros tipos.</translation>
+ </message>
+ <message>
+ <source>Cannot find the needed QmakeOutputInstallerKey(%1) value on the installer object. The ConsumeOutput operation on the valid qmake needs to be called first.</source>
+ <translation>No se puede localizar el valor necesario de QmakeOutputInstallerKey(%1) en el objeto del instalador. La operación ConsumeOutput en el qmake válido se tiene que invocar antes.</translation>
+ </message>
+ <message>
+ <source>QMake from the current Qt version
+(%1)is not existing. Please file a bugreport with this dialog at https://bugreports.qt-project.org.</source>
+ <translation>No existe un QMake de la versión actual) de Qt (%1). Por favor, rellena un informe de fallos haciendo referencia a este diálogo en https://bugreports.qt-project.org.</translation>
+ </message>
+ <message>
+ <source>The output of
+%1 -query
+is not parseable. Please file a bugreport with this dialog https://bugreports.qt-project.org.
+output: &quot;%2&quot;</source>
+ <translation>La salida de
+&apos;%1 -query&apos;
+no es analizable. Por favor, rellena un informe de fallos haciendo referencia a este diálogo en https://bugreports.qt-project.org.
+salida: &quot;%2&quot;</translation>
+ </message>
+ <message>
+ <source>Qt patch error: new Qt dir(%1)
+needs to be less than 255 characters.</source>
+ <translation>Error del parche de Qt: el nuevo directorio de Qt (%1)
+tiene que ser de menos de 255 caracteres.</translation>
+ </message>
+ <message>
+ <source>Qt patch error: Can not open %1.(%2)</source>
+ <translation>Error del parche de Qt: No se puede abrir %1.(%2)</translation>
+ </message>
+ <message>
+ <source>The installer was not able to get the unpatched path from
+%1.(maybe it is broken or removed)
+It tried to patch the Qt binaries, but all other files in Qt are unpatched.
+This could result in a broken Qt version.
+Sometimes it helps to restart the installer with a switched off antivirus software.</source>
+ <translation>El instalador no ha podido obtener la ubicación no parcheada de
+%1. (tal vez sea incorrecta o se haya eliminado)
+Se ha intentado parchear los binarios de Qt, pero el resto de archivos en Qt están sin parchear.
+El resultado de ésto podría ser una versión de Qt estropeada.
+A veces ayuda reiniciar el instalador con el antivirus deshabilitado.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ReadyForInstallationPage</name>
+ <message>
+ <source>&amp;Show Details</source>
+ <translation>&amp;Mostrar detalles</translation>
+ </message>
+ <message>
+ <source>U&amp;ninstall</source>
+ <translation>D&amp;esinstalar</translation>
+ </message>
+ <message>
+ <source>Ready to Uninstall</source>
+ <translation>Preparado para la desinstalación</translation>
+ </message>
+ <message>
+ <source>Setup is now ready to begin removing %1 from your computer.&lt;br&gt;&lt;font color=&quot;red&quot;&gt;The program directory %2 will be deleted completely&lt;/font&gt;, including all content in that directory!</source>
+ <translation>El instalador está preparado para empezar a eliminar %1 de tu ordenador.&lt;br&gt;&lt;font color=&quot;red&quot;&gt;El directorio del programa %2 se va a eliminar por completo&lt;/font&gt;, ¡incluyendo todo el contenido de ese directorio!</translation>
+ </message>
+ <message>
+ <source>U&amp;pdate</source>
+ <translation>&amp;Actualizar</translation>
+ </message>
+ <message>
+ <source>Ready to Update Packages</source>
+ <translation>Preparado para actualizar paquetes</translation>
+ </message>
+ <message>
+ <source>Setup is now ready to begin updating your installation.</source>
+ <translation>El instalador está preparado para empezar a actualizar tu instalación.</translation>
+ </message>
+ <message>
+ <source>&amp;Install</source>
+ <translation>&amp;Instalar</translation>
+ </message>
+ <message>
+ <source>Ready to Install</source>
+ <translation>Preparado para la instalación</translation>
+ </message>
+ <message>
+ <source>Setup is now ready to begin installing %1 on your computer.</source>
+ <translation>El instalador está preparado para empezar a instalar %1 en tu ordenador.</translation>
+ </message>
+ <message>
+ <source>Not enough disk space to store temporary files and the installation! Available space: %1, at least required %2.</source>
+ <translation>¡No hay suficiente espacio en disco para almacenar archivos temporales y la instalación! Espacio disponible %1, se necesitan por lo menos %2.</translation>
+ </message>
+ <message>
+ <source>Not enough disk space to store all selected components! Available space: %1, at least required: %2.</source>
+ <translation>¡No hay suficiente espacio en disco para almacenar todos los componentes seleccionados! Espacio disponible %1, se necesitan por lo menos %2.</translation>
+ </message>
+ <message>
+ <source>Not enough disk space to store temporary files! Available space: %1, at least required: %2.</source>
+ <translation>¡No hay suficiente espacio en disco para almacenar archivos temporales! Espacio disponible %1, se necesitan por lo menos %2.</translation>
+ </message>
+ <message>
+ <source>The volume you selected for installation seems to have sufficient space for installation, but there will be less than 1% of the volume&apos;s space available afterwards. %1</source>
+ <translation>El volumen que has seleccionado para la instalación parece ser que tiene suficiente espacio para la instalación pero después habrá menos de 1% de espacio disponible en el volumen. %1</translation>
+ </message>
+ <message>
+ <source>The volume you selected for installation seems to have sufficient space for installation, but there will be less than 100 MB available afterwards. %1</source>
+ <translation>El volumen que has seleccionado para la instalación parece ser que tiene suficiente espacio para la instalación pero después quedarán menos de 100 MB disponibles. %1</translation>
+ </message>
+ <message>
+ <source>Can not resolve all dependencies!</source>
+ <translation>¡No se pueden resolver todas las dependencias!</translation>
+ </message>
+ <message>
+ <source>Components about to be removed.</source>
+ <translation>Componentes que se van a quitar.</translation>
+ </message>
+ <message>
+ <source>&amp;Hide Details</source>
+ <translation>&amp;Ocultar detalles</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RegisterDefaultDebuggerOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, 2 expected.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, 2 esperados.</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
+ <translation>Se necesita el objeto del instalador en &quot;%1&quot; la operación está vacía.</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>exactamente 2</translation>
+ </message>
+ <message>
+ <source>There is no value set for %1 on the installer object.</source>
+ <translation>No se ha asignado un valor a %1 en el objeto del instalador.</translation>
+ </message>
+ <message>
+ <source>Can&apos;t read from tool chains xml file(%1) correctly.</source>
+ <translation>No se puede leer correctamente el archivo xml de la cadena de herramientas (%1).</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RegisterFileTypeOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>2 to 5</source>
+ <translation>de 2 a 5</translation>
+ </message>
+ <message>
+ <source>Register File Type: Invalid arguments</source>
+ <translation>Registro de tipo de archivo: argumentos no válidos</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RegisterQtInCreatorQNXOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>at least 5</source>
+ <translation>por lo menos 5</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
+ <translation>Se necesita el objeto del instalador en &quot;%1&quot; la operación está vacía.</translation>
+ </message>
+ <message>
+ <source>There is no value set for %1 on the installer object.</source>
+ <translation>No se ha asignado un valor a %1 en el objeto del instalador.</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, minimum 4 expected.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, se esperaban al menos 4.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RegisterToolChainOperation</name>
+ <message>
+ <source>at least 4</source>
+ <translation>por lo menos 4</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &apos;%1&apos; operation is empty.</source>
+ <translation>Se necesita el objeto del instalador en &apos;%1&apos; la operación está vacía.</translation>
+ </message>
+ <message>
+ <source>There is no value set for &apos;%1&apos; on the installer object.</source>
+ <translation>No se ha asignado un valor a &apos;%1&apos; en el objeto del instalador.</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, minimum 4 expected.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, se esperaban al menos 4.</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
+ <translation>Se necesita el objeto del instalador en &quot;%1&quot; la operación está vacía.</translation>
+ </message>
+ <message>
+ <source>Can&apos;t read from tool chains xml file(%1) correctly.</source>
+ <translation>No se puede leer correctamente el archivo xml de la cadena de herramientas (%1).</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>Some arguments are not right in %1 operation.</source>
+ <translation>Algunos argumentos no son correctos en la operación %1.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ReplaceOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 3</source>
+ <translation>exactamente 3</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RestartPage</name>
+ <message>
+ <source>Completing the %1 Setup Wizard</source>
+ <translation>Completando el asistente de instalación %1</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ScriptEngine</name>
+ <message>
+ <source>Cannot open the requested script file at %1: %2.</source>
+ <translation>No se puede abrir el archivo de script %1 solicitado: %2.</translation>
+ </message>
+ <message>
+ <source>Exception while loading the component script: &apos;%1&apos;</source>
+ <translation>Excepción al cargar el script de componente: &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Cannot load the component script inside a script context: &apos;%1&apos;</source>
+ <translation>No se puede cargar el script de componente dentro de un contexto de script: &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Fatal error while evaluating a script.</source>
+ <translation>Error fatal al evaluar un script.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SelfRestartOperation</name>
+ <message>
+ <source>Installer object needed in &apos;%1&apos; operation is empty.</source>
+ <translation>Se necesita el objeto del instalador en &quot;%1&quot; la operación está vacía.</translation>
+ </message>
+ <message>
+ <source>Self Restart: Only valid within updater or packagemanager mode.</source>
+ <translation>Autoreinicio: sólo es válido en el ámbito del actualizador o del modo de gestor de paquetes.</translation>
+ </message>
+ <message>
+ <source>Self Restart: Invalid arguments</source>
+ <translation>Autoreinicio: argumentos no válidos</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SetDemosPathOnQtOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>exactamente 2</translation>
+ </message>
+ <message>
+ <source>The output of
+&apos;%1 -query&apos;
+is not parseable. Please file a bugreport with this dialog at https://bugreports.qt-project.org.
+output: %2</source>
+ <translation>La salida de
+&apos;%1 -query&apos;
+no es analizable. Por favor, rellena un informe de fallos haciendo referencia a este diálogo en https://bugreports.qt-project.org.
+salida: %2</translation>
+ </message>
+ <message>
+ <source>Qt patch error: new Qt demo path &apos;%1&apos;
+needs to be less than 255 characters.</source>
+ <translation>Error del parche de Qt: la nueva ubicación de las demos de Qt &apos;%1&apos;
+tiene que ser de menos de 255 caracteres.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SetExamplesPathOnQtOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>exactamente 2</translation>
+ </message>
+ <message>
+ <source>The output of
+&apos;%1 -query&apos;
+is not parseable. Please file a bugreport with this dialog at https://bugreports.qt-project.org.
+output: %2</source>
+ <translation>La salida de
+&apos;%1 -query&apos;
+no es analizable. Por favor, rellena un informe de fallos haciendo referencia a este diálogo en https://bugreports.qt-project.org.
+salida: %2</translation>
+ </message>
+ <message>
+ <source>Qt patch error: new Qt example path &apos;%1&apos;
+needs to be less than 255 characters.</source>
+ <translation>Error del parche de Qt: la nueva ubicación del ejemplo de Qt &apos;%1&apos;
+tiene que ser de menos de 255 caracteres.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SetImportsPathOnQtCoreOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>exactamente 2</translation>
+ </message>
+ <message>
+ <source>Qt patch error: new Qt imports path &apos;%1&apos;
+needs to be less than 255 characters.</source>
+ <translation>Error del parche de Qt: la nueva ubicación de los imports de Qt &apos;%1&apos;
+tiene que ser de menos de 255 caracteres.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SetPathOnQtCoreOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 3</source>
+ <translation>exactamente 3</translation>
+ </message>
+ <message>
+ <source>The second type/value needs to be one of: %1</source>
+ <translation>El segundo tipo/valor tiene que ser uno de: %1</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SetPluginPathOnQtCoreOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>exactamente 2</translation>
+ </message>
+ <message>
+ <source>Qt patch error: new Qt plugin path &apos;%1&apos;
+needs to be less than 255 characters.</source>
+ <translation>Error del parche de Qt: la nueva ubicación del complemento de Qt &apos;%1&apos;
+tiene que ser de menos de 255 caracteres.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SetQtCreatorValueOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 4</source>
+ <translation>exactamente 4</translation>
+ </message>
+ <message>
+ <source> (rootInstallPath, group, key, value)</source>
+ <translation> (rootInstallPath, group, key, value)</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
+ <translation>Se necesita el objeto del instalador en &quot;%1&quot; la operación está vacía.</translation>
+ </message>
+ <message>
+ <source>There is no value set for &apos;%1&apos; on the installer object.</source>
+ <translation>No se ha asignado un valor a %1 en el objeto del instalador.</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &apos;%1&apos; operation is empty.</source>
+ <translation>Se necesita el objeto del instalador en &quot;%1&quot; la operación está vacía.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SimpleMoveFileOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>Argumentos no válidos en %0: %1 argumentos dados, %2 esperados %3.</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>exactamente 2</translation>
+ </message>
+ <message>
+ <source>None of the arguments can be empty: source &apos;%1&apos;, target &apos;%2&apos;.</source>
+ <translation>Ninguno de los argumentos puede estar vacío: origen &apos;%1&apos;, destino &apos;%2&apos;.</translation>
+ </message>
+ <message>
+ <source>Can not move source &apos;%1&apos; to target &apos;%2&apos;, because target exists and is not removable.</source>
+ <translation>No se puede mover el origen &apos;%1&apos; al destino &apos;%2&apos;, porque el destino ya existe y no se puede eliminar.</translation>
+ </message>
+ <message>
+ <source>Can not move source &apos;%1&apos; to target &apos;%2&apos;: %3</source>
+ <translation>No se puede mover el origen &apos;%1&apos; al destino &apos;%2&apos;: %3</translation>
+ </message>
+ <message>
+ <source>Move &apos;%1&apos; to &apos;%2&apos;.</source>
+ <translation>Mover &apos;%1&apos; a &apos;%2&apos;.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::StartMenuDirectoryPage</name>
+ <message>
+ <source>Start Menu shortcuts</source>
+ <translation>Accesos directos del menú de inicio</translation>
+ </message>
+ <message>
+ <source>Select the Start Menu in which you would like to create the program&apos;s shortcuts. You can also enter a name to create a new folder.</source>
+ <translation>Selecciona el menú de inicio en el que te gustaría crear los accesos directos del programa. También puedes introducir un nombre para crear una carpeta nueva.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::TargetDirectoryPage</name>
+ <message>
+ <source>Installation Folder</source>
+ <translation>Carpeta de instalación</translation>
+ </message>
+ <message>
+ <source>Please specify the folder where %1 will be installed.</source>
+ <translation>Por favor, especifica la carpeta donde se instalará %1.</translation>
+ </message>
+ <message>
+ <source>Alt+R</source>
+ <comment>browse file system to choose a file</comment>
+ <translation>Alt+R</translation>
+ </message>
+ <message>
+ <source>B&amp;rowse...</source>
+ <translation>E&amp;xaminar...</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>The install directory cannot be empty, please specify a valid folder.</source>
+ <translation>El directorio de instalación no puede estar vacío, por favor especifica una carpeta válida.</translation>
+ </message>
+ <message>
+ <source>As the install directory is completely deleted on uninstall, installing in %1 is forbidden.</source>
+ <translation>Como el directorio de instalación se elimina completamente en la desinstalación, se prohibe la instalación en %1.</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Advertencia</translation>
+ </message>
+ <message>
+ <source>You have selected an existing, non-empty folder for installation. Note that it will be completely wiped on uninstallation of this application. It is not advisable to install into this folder as installation might fail. Do you want to continue?</source>
+ <translation>Has seleccionado una carpeta que ya existe y que no está vacía para la instalación. Ten en cuenta que se eliminará completamente cuando se desinstale esta aplicación. No se recomienda realizar la instalación en esta carpeta ya que puede fallar. ¿Quieres continuar?</translation>
+ </message>
+ <message>
+ <source>Select Installation Folder</source>
+ <translation>Selecciona una carpeta de instalación</translation>
+ </message>
+</context>
+<context>
+ <name>QInstallerCreator::Archive</name>
+ <message>
+ <source>Cannot create %1: %2</source>
+ <translation>No se puede crear %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open archive file %1 for reading.</source>
+ <translation>No se puede abrir el archivo %1 en modo lectura.</translation>
+ </message>
+ <message>
+ <source>Cannot create archive from %1: Not a file.</source>
+ <translation>No se puede crear el archivo de %1: no es un archivo.</translation>
+ </message>
+ <message>
+ <source>Error while packing directory at %1</source>
+ <translation>Error al empaquetar el directorio en %1</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Searched whole file, no marker found</source>
+ <translation>Búsqueda en todo el archivo terminada, marcador no encontrado</translation>
+ </message>
+ <message>
+ <source>Cannot seek to %1 in file %2: %3</source>
+ <translation>No se puede solicitar %1 en el archivo %2: %3</translation>
+ </message>
+ <message>
+ <source>No marker found, stopped after %1.</source>
+ <translation>No se ha encontrado ningún marcador, se ha parado después de %1.</translation>
+ </message>
+ <message>
+ <source>No marker found, unknown exception caught.</source>
+ <translation>No se ha encontrado ningún marcador, excepción desconocida capturada.</translation>
+ </message>
+ <message>
+ <source>Cannot create zipped file for path %1: %2</source>
+ <translation>No se puede crear el archivo comprimido para la ubicación %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot seek to in-binary resource. (offset: %1, length: %2)</source>
+ <translation>No se puede realizar una solicitud - recurso binario. (offset: %1, longitud: %2)</translation>
+ </message>
+ <message>
+ <source>Cannot register in-binary resource.</source>
+ <translation>No se puede registrar - recurso binario.</translation>
+ </message>
+ <message>
+ <source>Cannot open binary %1: %2</source>
+ <translation>No se puede abrir el binario %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot seek to binary layout section.</source>
+ <translation>No se puede solicitar la sección de la disposición del binario.</translation>
+ </message>
+ <message>
+ <source>Cannot seek to metadata index.</source>
+ <translation>No se puede solicitar el índice de los metadatos.</translation>
+ </message>
+ <message>
+ <source>Cannot seek to operation list.</source>
+ <translation>No se puede solicitar la lista de operaciones.</translation>
+ </message>
+ <message>
+ <source>Cannot seek to component index information.</source>
+ <translation>No se puede solicitar la información del índice del componente.</translation>
+ </message>
+ <message>
+ <source>Cannot seek to component index.</source>
+ <translation>No se puede solicitar el índice del componente.</translation>
+ </message>
+ <message>
+ <source>Cannot open file %1 for reading: %2</source>
+ <translation>No se puede abrir el archivo %1 en modo lectura: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file %1 for writing: %2</source>
+ <translation>No se puede abrir el archivo %1 en modo escritura: %2</translation>
+ </message>
+ <message>
+ <source>Write failed after %1 bytes: %2</source>
+ <translation>La escritura ha fallado después de %1 bytes: %2</translation>
+ </message>
+ <message>
+ <source>Read failed after %1 bytes: %2</source>
+ <translation>La lectura ha fallado después de %1 bytes: %2</translation>
+ </message>
+ <message>
+ <source>Cannot remove file %1: %2</source>
+ <translation>No se puede eliminar el archivo %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot remove folder %1: %2</source>
+ <translation>No se puede eliminar la carpeta %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot create folder %1</source>
+ <translation>No se puede crear la carpeta %1</translation>
+ </message>
+ <message>
+ <source>Cannot copy file from %1 to %2: %3</source>
+ <translation>No se puede copiar el archivo de %1 a %2: %3</translation>
+ </message>
+ <message>
+ <source>Cannot move file from %1 to %2: %3</source>
+ <translation>No se puede mover el archivo de %1 a %2: %3</translation>
+ </message>
+ <message>
+ <source>Cannot create folder %1: %2</source>
+ <translation>No se puede crear la carpeta %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open temporary file: %1</source>
+ <translation>No se puede abrir el archivo temporal: %1</translation>
+ </message>
+ <message>
+ <source>Cannot open temporary file for template %1: %2</source>
+ <translation>No se puede abrir el archivo temporal para la plantilla %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot create temporary folder for template %1: %2</source>
+ <translation>No se puede crear la carpeta temporal para la plantilla %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot create lock file %1: %2</source>
+ <translation>No se puede crear el archivo de bloqueo %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot write PID to lock file %1: %2</source>
+ <translation>No se puede escribir el PID para bloquear el archivo %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot lock lock file %1: %2</source>
+ <translation>No se puede bloquear el archivo de bloqueo %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot unlock lock file %1: %2</source>
+ <translation>No se puede desbloquear el archivo de bloqueo %1: %2</translation>
+ </message>
+ <message>
+ <source>Path exists but is not a folder: %1</source>
+ <translation>La ubicación existe pero no es una carpeta: %1</translation>
+ </message>
+ <message>
+ <source>Cannot create folder: %1</source>
+ <translation>No se puede crear la carpeta: %1</translation>
+ </message>
+ <message>
+ <source>Cannot create temporary file</source>
+ <translation>No se puede crear el archivo temporal</translation>
+ </message>
+ <message>
+ <source>Cannot retrieve property %1 for item %2</source>
+ <translation>No se puede recuperar la propiedad %1 del elemento %2</translation>
+ </message>
+ <message>
+ <source>Property %1 for item %2 not of type VT_FILETIME but %3</source>
+ <translation>La propiedad %1 del elemento %2 no es del tipo VT_FILETIME pero sí de %3</translation>
+ </message>
+ <message>
+ <source>Cannot convert file time to local time</source>
+ <translation>No se puede convertir la hora del archivo a hora local</translation>
+ </message>
+ <message>
+ <source>Cannot convert local file time to system time</source>
+ <translation>No se puede convertir la hora local del archivo a hora del sistema</translation>
+ </message>
+ <message>
+ <source>No device set for output stream</source>
+ <translation>No se ha asignado un dispositivo para el flujo de salida</translation>
+ </message>
+ <message>
+ <source>Cannot load codecs</source>
+ <translation>No se pueden cargar los códecs</translation>
+ </message>
+ <message>
+ <source>Cannot retrieve default format</source>
+ <translation>No se puede recuperar el formato predeterminado</translation>
+ </message>
+ <message>
+ <source>Cannot open archive</source>
+ <translation>No se puede abrir el archivo</translation>
+ </message>
+ <message>
+ <source>No CArc found</source>
+ <translation>No se ha localizado ningún CArc</translation>
+ </message>
+ <message>
+ <source>Cannot retrieve number of items in archive</source>
+ <translation>No se puede recuperar el número de elementos en el archivo</translation>
+ </message>
+ <message>
+ <source>Cannot retrieve path of archive item %1</source>
+ <translation>No se puede recuperar la ubicación del elemento %1 del archivo</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught (%1)</source>
+ <translation>Excepción desconocida capturada (%1)</translation>
+ </message>
+ <message>
+ <source>Failed</source>
+ <translation>Fallo</translation>
+ </message>
+ <message>
+ <source>Cannot remove already existing symlink. %1</source>
+ <translation>No se puede eliminar el enlace simbólico que ya hay. %1</translation>
+ </message>
+ <message>
+ <source>Cannot open file: %1 (%2)</source>
+ <translation>No se puede abrir el archivo: %1 (%2)</translation>
+ </message>
+ <message>
+ <source>Cannot create symlink at &apos;%1&apos;. Another one is already existing.</source>
+ <translation>No se puede crear el enlace simbólico en &apos;%1&apos;. Ya hay otro.</translation>
+ </message>
+ <message>
+ <source>Cannot read symlink target from file &apos;%1&apos;.</source>
+ <translation>No se puede leer el enlace simbólico de destino del archivo &apos;%1&apos;.</translation>
+ </message>
+ <message>
+ <source>Cannot create symlink at %1. %2</source>
+ <translation>No se puede crear el enlace simbólico en %1. %2</translation>
+ </message>
+ <message>
+ <source>internal code: %1</source>
+ <translation>código interno: %1</translation>
+ </message>
+ <message>
+ <source>not enough memory</source>
+ <translation>no hay suficiente memoria</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Error: %1</translation>
+ </message>
+ <message>
+ <source>Cannot create archive %1. %2</source>
+ <translation>No se puede crear el archivo %1. %2</translation>
+ </message>
+ <message>
+ <source>Error while extracting &apos;%1&apos;: %2</source>
+ <translation>Error al extraer &apos;%1&apos;: %2</translation>
+ </message>
+ <message>
+ <source>CArc index %1 out of bounds [0, %2]</source>
+ <translation>El índice %1 de CArc está fuera de los límites [0, %2]</translation>
+ </message>
+ <message>
+ <source>Item index %1 out of bounds [0, %2]</source>
+ <translation>El índice %1 del elemento está fuera de los límites [0, %2]</translation>
+ </message>
+ <message>
+ <source>Cannot create output file for writing: %1</source>
+ <translation>No se puede crear el archivo de salida para su escritura: %1</translation>
+ </message>
+ <message>
+ <source>Authorization required</source>
+ <translation>Autorización requerida</translation>
+ </message>
+ <message>
+ <source>Enter your password to authorize for sudo:</source>
+ <translation>Introduce tu contraseña para autorizar a sudo:</translation>
+ </message>
+ <message>
+ <source>Error acquiring admin rights</source>
+ <translation>Error al adquirir permisos de administrador</translation>
+ </message>
+ <message>
+ <source>Cannot backup file %1</source>
+ <translation>No se puede hacer una copia de seguridad del archivo %1</translation>
+ </message>
+ <message>
+ <source>Cannot delete file %1</source>
+ <translation>No se puede eliminar el archivo %1</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file into %1</source>
+ <translation>No se puede restaurar la copia de seguridad del archivo como %1</translation>
+ </message>
+ <message>
+ <source>Failed to overwrite %1: %2</source>
+ <translation>Fallo al sobrescribir %1: %2</translation>
+ </message>
+ <message>
+ <source>Registry path %1 is not writable</source>
+ <translation>No se puede escribir en la ubicación %1 del registro</translation>
+ </message>
+ <message>
+ <source>Cannot write to registry path %1</source>
+ <translation>No se puede escribir en la ubicación %1 del registro</translation>
+ </message>
+ <message>
+ <source>Invalid Argument: source folder must not be empty.</source>
+ <translation>Argumento no válido: la carpeta de origen no tiene que estar vacía.</translation>
+ </message>
+ <message>
+ <source>Cannot backup file %1: %2</source>
+ <translation>No se puede hacer una copia de seguridad del archivo %1: %2</translation>
+ </message>
+ <message>
+ <source>Failed to copy file %1: %2</source>
+ <translation>Fallo al copiar el archivo %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot create folder at %1: %2</source>
+ <translation>No se puede crear la carpeta %1: %2</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, %2 to %3 expected.</source>
+ <translation>Argumentos no válidos: %1 argumentos dados, de %2 a %3 esperados.</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, %2 expected.</source>
+ <translation>Argumentos no válidos: %1 argumentos dados, %2 esperados.</translation>
+ </message>
+ <message>
+ <source>Error while elevating access rights.</source>
+ <translation>Error al dar permisos de acceso.</translation>
+ </message>
+ <message>
+ <source>Failed to seek in file %1: %2</source>
+ <translation>Fallo al solicitar el archivo %1: %2</translation>
+ </message>
+ <message>
+ <source>Failed to open %1 for reading</source>
+ <translation>Fallo al abrir %1 en modo lectura</translation>
+ </message>
+ <message>
+ <source>Failed to open %1 for writing</source>
+ <translation>Fallo al abrir %1 en modo escritura</translation>
+ </message>
+ <message>
+ <source>Failed to seek in file %1. Reason: %2.</source>
+ <translation>Fallo al solicitar el archivo %1. Motivo: %2.</translation>
+ </message>
+ <message>
+ <source>Cannot create link from %1 to %2.</source>
+ <translation>No se puede crear el enlace de %1 a %2.</translation>
+ </message>
+ <message>
+ <source>Cannot remove link from %1 to %2.</source>
+ <translation>No se puede eliminar el enlace de %1 a %2.</translation>
+ </message>
+ <message>
+ <source>Authorization Error</source>
+ <translation>Error de autorización</translation>
+ </message>
+ <message>
+ <source>Couldn&apos;t get authorization.</source>
+ <translation>No se ha podido obtener la autorización.</translation>
+ </message>
+ <message>
+ <source>Couldn&apos;t get authorization that is needed for continuing the installation.
+Either abort the installation or use the fallback solution by running
+%1
+as root and then clicking ok.</source>
+ <translation>No se ha podido obtener la autorización necesaria para continuar con la instalación.
+Cancela la instalación o bien usa la solución alternativa ejecutando
+%1
+como root y haciendo clic en OK.</translation>
+ </message>
+ <message>
+ <source>Registering file types is only supported on Windows.</source>
+ <translation>El registro de tipos de archivo sólo está soportado en Windows.</translation>
+ </message>
+ <message>
+ <source>Failed to open &apos;%1&apos; for reading.</source>
+ <translation>Fallo al abrir &apos;%1&apos; en modo lectura.</translation>
+ </message>
+ <message>
+ <source>Failed to open &apos;%1&apos; for writing.</source>
+ <translation>Fallo al abrir %1 en modo escritura.</translation>
+ </message>
+ <message>
+ <source>Number of arguments does not match: one is required</source>
+ <translation>El número de argumentos no coincide: es necesario que haya uno</translation>
+ </message>
+ <message>
+ <source>Cannot get package manager core.</source>
+ <translation>No se puede obtener el núcleo del gestor de paquetes.</translation>
+ </message>
+ <message>
+ <source>This process should be stopped before continuing: %1</source>
+ <translation>Este proceso se tiene que parar antes de continuar: %1</translation>
+ </message>
+ <message>
+ <source>These processes should be stopped before continuing: %1</source>
+ <translation>Estos procesos se tienen que parar antes de continuar: %1</translation>
+ </message>
+</context>
+<context>
+ <name>Settings</name>
+ <message>
+ <source>Cannot open settings file %1 for reading: %2</source>
+ <translation>No se puede abrir el archivo de configuración %1 en modo lectura: %2</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsDialog</name>
+ <message>
+ <source>Settings</source>
+ <translation>Configuración</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Red</translation>
+ </message>
+ <message>
+ <source>No proxy</source>
+ <translation>Sin proxy</translation>
+ </message>
+ <message>
+ <source>System proxy settings</source>
+ <translation>Configuración del proxy del sistema</translation>
+ </message>
+ <message>
+ <source>Manual proxy configuration</source>
+ <translation>Configuración manual del proxy</translation>
+ </message>
+ <message>
+ <source>HTTP proxy:</source>
+ <translation>Proxy HTTP:</translation>
+ </message>
+ <message>
+ <source>Port:</source>
+ <translation>Puerto:</translation>
+ </message>
+ <message>
+ <source>HTTP proxy requires authentication</source>
+ <translation>El proxy HTTP requiere autenticación</translation>
+ </message>
+ <message>
+ <source>Username:</source>
+ <translation>Nombre de usuario:</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>Contraseña:</translation>
+ </message>
+ <message>
+ <source>FTP proxy:</source>
+ <translation>Proxy del FTP:</translation>
+ </message>
+ <message>
+ <source>FTP proxy requires authentication</source>
+ <translation>El proxy del FTP requiere autenticación</translation>
+ </message>
+ <message>
+ <source>Repositories</source>
+ <translation>Repositorios</translation>
+ </message>
+ <message>
+ <source>Add Username and Password for authentication if needed.</source>
+ <translation>Si es necesario, añade un nombre de usuario y contraseña para la autenticación.</translation>
+ </message>
+ <message>
+ <source>Use temporary repositories only</source>
+ <translation>Sólo usar repositorios temporales</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation>Añadir</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Eliminar</translation>
+ </message>
+ <message>
+ <source>Test</source>
+ <translation>Probar</translation>
+ </message>
+ <message>
+ <source>Show Passwords</source>
+ <translation>Mostrar contraseñas</translation>
+ </message>
+ <message>
+ <source>Check this to use repository during fetch.</source>
+ <translation>Marca esto para usar el repositorio durante la obtención.</translation>
+ </message>
+ <message>
+ <source>Add the username to authenticate on the server.</source>
+ <translation>Añade el nombre de usuario para autenticarse en el servidor.</translation>
+ </message>
+ <message>
+ <source>Add the password to authenticate on the server.</source>
+ <translation>Añade la contraseña para autenticarse en el servidor.</translation>
+ </message>
+ <message>
+ <source>The servers URL that contains a valid repository.</source>
+ <translation>La URL del servidor que contiene un repositorio válido.</translation>
+ </message>
+ <message>
+ <source>There was an error testing this repository.</source>
+ <translation>Se ha producido un error al probar este repositorio.</translation>
+ </message>
+ <message>
+ <source>Do you want to disable the tested repository?</source>
+ <translation>¿Quieres deshabilitar el repositorio probado?</translation>
+ </message>
+ <message>
+ <source>Hide Passwords</source>
+ <translation>Ocultar contraseñas</translation>
+ </message>
+ <message>
+ <source>Use</source>
+ <translation>Usar</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Nombre de usuario</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Contraseña</translation>
+ </message>
+ <message>
+ <source>Repository</source>
+ <translation>Repositorio</translation>
+ </message>
+ <message>
+ <source>Default repositories</source>
+ <translation>Repositorios predeterminados</translation>
+ </message>
+ <message>
+ <source>Temporary repositories</source>
+ <translation>Repositorios temporales</translation>
+ </message>
+ <message>
+ <source>User defined repositories</source>
+ <translation>Repositorios definidos por el usuario</translation>
+ </message>
+</context>
+<context>
+ <name>TargetDirectoryPageImpl</name>
+ <message>
+ <source>The installation path cannot be empty, please specify a valid folder.</source>
+ <translation>La ruta de instalación no puede estar vacía. Por favor ,especifica una carpeta válida.</translation>
+ </message>
+ <message>
+ <source>The installation path cannot be relative, please specify an absolute path.</source>
+ <translation>La ruta de la instalación no puede ser relativa. Por favor ,especifica una ruta absoluta.</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Advertencia</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>The path or installation directory contains non ASCII characters. This is currently not supported! Please choose a different path or installation directory.</source>
+ <translation>La ruta o el directorio de instalación contiene caracteres que no son ASCII. ¡Actualmente ésto no está soportado! Por favor, escoge una ruta o directorio de instalación diferente.</translation>
+ </message>
+ <message>
+ <source>The path you have entered is too long, please make sure to specify a valid path.</source>
+ <translation>La ruta que has introducido es demasiado larga. Por favor, asegúrate que especificas una ruta válida.</translation>
+ </message>
+ <message>
+ <source>The path you have entered is not valid, please make sure to specify a valid drive.</source>
+ <translation>La ruta que has introducido no es válida. Por favor, asegúrate que especificas un volúmen de disco válido.</translation>
+ </message>
+ <message>
+ <source>The installation path must not contain %1, please specify a valid folder.</source>
+ <translation>La ruta de la instalación no puede contener %1. Por favor ,especifica una carpeta válida.</translation>
+ </message>
+ <message>
+ <source>As the install directory is completely deleted installing in %1 is forbidden.</source>
+ <translation>Como el directorio de instalación se elimina completamente, se prohibe la instalación en %1.</translation>
+ </message>
+ <message>
+ <source>The folder you selected exists already and contains an installation.
+Do you want to overwrite it?</source>
+ <translation>La carpeta que has seleccionado ya existe y contiene una instalación.
+¿Quieres sobrescribirla?</translation>
+ </message>
+ <message>
+ <source>You have selected an existing, non-empty folder for installation.
+Note that it will be completely wiped on uninstallation of this application.
+It is not advisable to install into this folder as installation might fail.
+Do you want to continue?</source>
+ <translation>Has seleccionado una carpeta que ya existe y que no está vacía para la instalación.
+Ten en cuenta que se eliminará completamente cuando se desinstale esta aplicación.
+No se recomienda realizar la instalación en esta carpeta ya que puede fallar.
+¿Quieres continuar?</translation>
+ </message>
+ <message>
+ <source>You have selected an existing file or symlink, please choose a different target for installation.</source>
+ <translation>Has seleccionado un archivo o enlace simbólico que ya existe. Por favor, elige un destino diferente para la instalación.</translation>
+ </message>
+</context>
+<context>
+ <name>TestRepository</name>
+ <message>
+ <source>Empty repository URL.</source>
+ <translation>URL del repositorio vacía.</translation>
+ </message>
+ <message>
+ <source>URL scheme not supported: %1 (%2).</source>
+ <translation>Esquema de URL no admitido: %1 (%2).</translation>
+ </message>
+ <message>
+ <source>Cannot parse Updates.xml! Error: %1.</source>
+ <translation>¡Error al analizar Updates.xml! Error: %1.</translation>
+ </message>
+ <message>
+ <source>Updates.xml could not be opened for reading!</source>
+ <translation>¡No se puede abrir Updates.xml en modo lectura!</translation>
+ </message>
+ <message>
+ <source>Updates.xml could not be found on server!</source>
+ <translation>¡No se puede localizar Updates.xml en el servidor!</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/sdk/translations/fr.ts b/src/sdk/translations/fr.ts
index 72d27680d..c0351120f 100644
--- a/src/sdk/translations/fr.ts
+++ b/src/sdk/translations/fr.ts
@@ -15,26 +15,26 @@
<context>
<name>BinaryContent</name>
<message>
- <source>Could not seek to %1 to read the operation data.</source>
+ <source>Cannot seek to %1 to read the operation data.</source>
<translation>Impossible de rechercher dans %1 pour lire les données d&apos;exploitation.</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection block.</source>
+ <source>Cannot seek to %1 to read the resource collection block.</source>
<translation>Impossible de rechercher dans %1 pour lire l&apos;ensemble des ressources.</translation>
</message>
<message>
- <source>Could not open meta resource. Error: %1</source>
+ <source>Cannot open meta resource. Error: %1</source>
<translation>Impossible d&apos;ouvrir les métadonnées des ressources. Erreur : %1</translation>
</message>
</context>
<context>
<name>BinaryLayout</name>
<message>
- <source>Could not seek to %1 to read the embedded meta data count.</source>
+ <source>Cannot seek to %1 to read the embedded meta data count.</source>
<translation>Impossible de rechercher dans %1 pour lire le nombre de métadonnées.</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection segment.</source>
+ <source>Cannot seek to %1 to read the resource collection segment.</source>
<translation>Impossible de rechercher dans %1 pour lire le segment de l&apos;ensemble des ressources.</translation>
</message>
<message>
@@ -72,34 +72,34 @@
<translation>Le chemin existe mais n&apos;est pas un dossier : %1</translation>
</message>
<message>
- <source>Could not create folder: %1</source>
+ <source>Cannot create folder: %1</source>
<translation>Impossible de créer le dossier : %1</translation>
</message>
</context>
<context>
<name>ExtractCallbackImpl</name>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>Impossible de récupérer le chemin de l&apos;élément %1</translation>
</message>
<message>
- <source>Could not remove already existing symlink. %1</source>
+ <source>Cannot remove already existing symlink. %1</source>
<translation>Impossible de supprimer le lien symbolique existant. %1</translation>
</message>
<message>
- <source>Could not open file: %1 (%2)</source>
+ <source>Cannot open file: %1 (%2)</source>
<translation>Impossible d&apos;ouvrir le fichier %1 (%2)</translation>
</message>
<message>
- <source>Could not create symlink at &apos;%1&apos;. Another one is already existing.</source>
+ <source>Cannot create symlink at &apos;%1&apos;. Another one is already existing.</source>
<translation>Impossible de créer le lien symbolique à &apos;%1&apos;. Un autre existe déjà.</translation>
</message>
<message>
- <source>Could not read symlink target from file &apos;%1&apos;.</source>
+ <source>Cannot read symlink target from file &apos;%1&apos;.</source>
<translation>Impossible de récupérer la cible du lien symbolique du fichier &apos;%1&apos;.</translation>
</message>
<message>
- <source>Could not create symlink at %1. %2</source>
+ <source>Cannot create symlink at %1. %2</source>
<translation>Impossible de créer le lien symbolique à %1. %2</translation>
</message>
</context>
@@ -131,28 +131,28 @@
</message>
</context>
<context>
- <name>KDJob</name>
+ <name>Job</name>
<message>
<source>Canceled</source>
<translation>Annulé</translation>
</message>
</context>
<context>
- <name>KDLockFile</name>
+ <name>LockFile</name>
<message>
- <source>Could not create lock file &apos;%1&apos;: %2</source>
+ <source>Cannot create lock file &apos;%1&apos;: %2</source>
<translation>Impossible de poser un fichier de verrouillage &apos;%1&apos; : %2</translation>
</message>
<message>
- <source>Could not write PID to lock file &apos;%1&apos;: %2</source>
+ <source>Cannot write PID to lock file &apos;%1&apos;: %2</source>
<translation>Impossible d&apos;écrire le PID pour le verrou de fichier &apos;%1&apos; : &apos;%2&apos;</translation>
</message>
<message>
- <source>Could not obtain the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot obtain the lock for file &apos;%1&apos;: %2</source>
<translation>Impossible d&apos;obtenir le verrou pour le fichier &apos;%1&apos; : %2</translation>
</message>
<message>
- <source>Could not release the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot release the lock for file &apos;%1&apos;: %2</source>
<translation>Impossible de relâcher le verrou pour le fichier &apos;%1&apos; : %2</translation>
</message>
</context>
@@ -171,7 +171,7 @@
<translation>exactement 2</translation>
</message>
<message>
- <source>Could not open file &apos;%1&apos; for writing: %2</source>
+ <source>Cannot open file &apos;%1&apos; for writing: %2</source>
<translation>Impossible d&apos;ouvrir le fichier %1 en écriture : %2</translation>
</message>
<message>
@@ -179,18 +179,18 @@
<translation>Impossible de trouver la sauvegarde du fichier %1.</translation>
</message>
<message>
- <source>Could not restore backup file for %1.</source>
+ <source>Cannot restore backup file for %1.</source>
<translation>Impossible de charger la sauvegarde du fichier %1.</translation>
</message>
<message>
- <source>Could not restore backup file for %1: %2</source>
+ <source>Cannot restore backup file for %1: %2</source>
<translation>Impossible de restaurer la sauvegarde du fichier %1 : %2</translation>
</message>
</context>
<context>
<name>KDUpdater::CopyOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>Impossible de faire une sauvegarde du fichier %1.</translation>
</message>
<message>
@@ -198,23 +198,23 @@
<translation>Arguments invalides : %1 arguments fournis, 2 attendus.</translation>
</message>
<message>
- <source>Could not copy a non-existent file: %1</source>
+ <source>Cannot copy a non-existent file: %1</source>
<translation>Impossible de copier un fichier non-existant : %1</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>Impossible de supprimer le fichier de destination %1 : %2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>Impossible de copier %1 vers %2 : %3</translation>
</message>
<message>
- <source>Could not delete file %1: %2</source>
+ <source>Cannot delete file %1: %2</source>
<translation>Impossible de supprimer le fichier %1 : %2</translation>
</message>
<message>
- <source>Could not restore backup file into %1: %2</source>
+ <source>Cannot restore backup file into %1: %2</source>
<translation>Impossible de restaurer la sauvegarde du fichier vers %1 : %2</translation>
</message>
</context>
@@ -303,7 +303,7 @@
<translation>Impossible de télécharger %1 : l&apos;écriture du fichier &apos;%2&apos; à échoué : %3</translation>
</message>
<message>
- <source>Cannot download %1: Could not create %2: %3</source>
+ <source>Cannot download %1: Cannot create %2: %3</source>
<translation>Impossible de télécharger %1 : impossible de créer %2 : %3</translation>
</message>
<message>
@@ -357,7 +357,7 @@
<translation>Arguments invalides : %1 arguments fournis, 1 seul attendu.</translation>
</message>
<message>
- <source>Could not create folder %1: Unknown error.</source>
+ <source>Cannot create folder %1: Unknown error.</source>
<translation>Impossible de créer le dossier %1 : erreur indéterminée.</translation>
</message>
<message>
@@ -368,7 +368,7 @@
<context>
<name>KDUpdater::MoveOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>Impossible de sauvegarder le fichier %1.</translation>
</message>
<message>
@@ -376,11 +376,11 @@
<translation>Arguments invalides : %1 arguments fournis, 2 attendus.</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>Impossible de supprimer le fichier de destination %1 : %2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>Impossible de copier %1 vers %2 : %3</translation>
</message>
<message>
@@ -407,7 +407,7 @@
<translation>Le fichier %1 n&apos;existe pas.</translation>
</message>
<message>
- <source>Could not open %1.</source>
+ <source>Cannot open %1.</source>
<translation>Impossible d&apos;ouvrir %1.</translation>
</message>
<message>
@@ -430,11 +430,11 @@
<translation>Arguments invalides : %1 arguments fournis, 2 attendus.</translation>
</message>
<message>
- <source>Could not open file %1 for reading: %2</source>
+ <source>Cannot open file %1 for reading: %2</source>
<translation>Impossible d&apos;ouvrir le fichier %1 en lecture : %2</translation>
</message>
<message>
- <source>Could not open file %1 for writing: %2</source>
+ <source>Cannot open file %1 for writing: %2</source>
<translation>Impossible d&apos;ouvrir le fichier %1 en écriture : %2</translation>
</message>
<message>
@@ -453,7 +453,7 @@
<context>
<name>KDUpdater::ResourceFileDownloader</name>
<message>
- <source>Could not read resource file &quot;%1&quot;. Reason:</source>
+ <source>Cannot read resource file &quot;%1&quot;. Reason:</source>
<translation>Impossible de lire le fichier de ressources &quot;%1&quot;. Raison : </translation>
</message>
</context>
@@ -464,11 +464,11 @@
<translation>Arguments invalides : %1 arguments fournis, 1 seul attendu.</translation>
</message>
<message>
- <source>Could not remove folder %1: The folder does not exist.</source>
+ <source>Cannot remove folder %1: The folder does not exist.</source>
<translation>Impossible de supprimer le dossier %1 : ce dossier n&apos;existe pas.</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>Impossible de supprimer le dossier %1 : %2</translation>
</message>
<message>
@@ -510,11 +510,11 @@
<context>
<name>KDUpdater::UpdateFinder</name>
<message>
- <source>Could not access the package information of this application.</source>
+ <source>Cannot access the package information of this application.</source>
<translation>Impossible d&apos;accéder aux informations contenues dans ce paquet pour cette application.</translation>
</message>
<message>
- <source>Could not access the update sources information of this application.</source>
+ <source>Cannot access the update sources information of this application.</source>
<translation>Impossible d&apos;accéder aux informations de mise à jour pour cette application.</translation>
</message>
<message>
@@ -529,7 +529,7 @@
</translation>
</message>
<message>
- <source>Could not download update source %1 from (&apos;%2&apos;)</source>
+ <source>Cannot download update source %1 from (&apos;%2&apos;)</source>
<translation>Impossible de télécharger l&apos;emplacement des mises à jour pour %1 (&apos;%2&apos;)</translation>
</message>
<message>
@@ -552,7 +552,7 @@
<translation>%1 contient des informations invalides : %2</translation>
</message>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>Impossible de lire &quot;%1&quot;</translation>
</message>
<message>
@@ -564,14 +564,14 @@
<translation>Élément racine %1 inattendu, il devrait se trouver dans &quot;UpdateSources&quot;</translation>
</message>
<message>
- <source>Could not save changes to &quot;%1&quot;: %2</source>
+ <source>Cannot save changes to &quot;%1&quot;: %2</source>
<translation>Impossible de sauvegarder les changements dans &quot;%1&quot; : %2</translation>
</message>
</context>
<context>
<name>KDUpdater::UpdatesInfoData</name>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>Impossible de lire &quot;%1&quot;</translation>
</message>
<message>
@@ -610,11 +610,11 @@
<context>
<name>Lib7z</name>
<message>
- <source>Could not retrieve number of items in archive</source>
+ <source>Cannot retrieve number of items in archive</source>
<translation>Impossible de récupérer le nombre d&apos;éléments dans l&apos;archive</translation>
</message>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>Impossible de récupérer le chemin de l&apos;élément %1</translation>
</message>
<message>
@@ -634,15 +634,15 @@
<translation>Erreur : %1</translation>
</message>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>Impossible de charger les codecs</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>Impossible de récupérer le format par défaut</translation>
</message>
<message>
- <source>Could not create archive %1. %2</source>
+ <source>Cannot create archive %1. %2</source>
<translation>Impossible de créer l&apos;archive %1. %2</translation>
</message>
<message>
@@ -654,14 +654,14 @@
<translation>Index de l&apos;élément %1 hors limites [0, %2]</translation>
</message>
<message>
- <source>Could not create output file for writing: %1</source>
+ <source>Cannot create output file for writing: %1</source>
<translation>Impossible de créer le fichier de sortie : %1</translation>
</message>
</context>
<context>
<name>Lib7z::ExtractItemJob</name>
<message>
- <source>Could not list archive: QIODevice not set or already destroyed.</source>
+ <source>Cannot list archive: QIODevice not set or already destroyed.</source>
<translation>Impossible de lister l&apos;archive : QIODevice n&apos;est pas renseigné ou à déjà été détruit.</translation>
</message>
<message>
@@ -680,7 +680,7 @@
<context>
<name>Lib7z::ListArchiveJob</name>
<message>
- <source>Could not list archive: QIODevice already destroyed.</source>
+ <source>Cannot list archive: QIODevice already destroyed.</source>
<translation>Impossible de lister l&apos;archive : QIODevice n&apos;est pas renseigné ou à déjà été détruit.</translation>
</message>
<message>
@@ -695,15 +695,15 @@
<context>
<name>OpenArchiveInfo</name>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>Impossible de charger les codecs</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>Impossible de récupérer le format par défaut</translation>
</message>
<message>
- <source>Could not open archive</source>
+ <source>Cannot open archive</source>
<translation>Impossible d&apos;ouvrir l&apos;archive</translation>
</message>
<message>
@@ -781,43 +781,43 @@
<translation>YiB</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>Impossible de supprimer le fichier %1 : %2</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>Impossible de supprimer le dossier %1 : %2</translation>
</message>
<message>
- <source>Could not create folder %1</source>
+ <source>Cannot create folder %1</source>
<translation>Impossible de créer le dossier %1</translation>
</message>
<message>
- <source>Could not copy file from %1 to %2: %3</source>
+ <source>Cannot copy file from %1 to %2: %3</source>
<translation>Impossible de copier le fichier de %1 vers %2 : %3</translation>
</message>
<message>
- <source>Could not move file from %1 to %2: %3</source>
+ <source>Cannot move file from %1 to %2: %3</source>
<translation>Impossible de déplacer le fichier de %1 vers %2 : %3</translation>
</message>
<message>
- <source>Could not create folder %1: %2</source>
+ <source>Cannot create folder %1: %2</source>
<translation>Impossible de créer le dossier %1 : %2</translation>
</message>
<message>
- <source>Could not open temporary file: %1</source>
+ <source>Cannot open temporary file: %1</source>
<translation>Impossible d&apos;ouvrir le fichier temporaire : %1</translation>
</message>
<message>
- <source>Could not open temporary file for template %1: %2</source>
+ <source>Cannot open temporary file for template %1: %2</source>
<translation>Impossible d&apos;ouvrir le fichier temporaire pour le modèle %1 : %2</translation>
</message>
<message>
- <source>Could not create temporary file</source>
+ <source>Cannot create temporary file</source>
<translation>Impossible de créer le fichier temporaire</translation>
</message>
<message>
- <source>Could not retrieve property %1 for item %2</source>
+ <source>Cannot retrieve property %1 for item %2</source>
<translation>Impossible de récupérer la propriété %1 pour l&apos;élément %2</translation>
</message>
<message>
@@ -825,11 +825,11 @@
<translation>Propriété %1 pour l&apos;élément %2 n&apos;est pas de type VT_FILETIME mais %3</translation>
</message>
<message>
- <source>Could not convert file time to local time</source>
+ <source>Cannot convert file time to local time</source>
<translation>Impossible de convertir l&apos;heure du fichier vers l&apos;heure locale</translation>
</message>
<message>
- <source>Could not convert local file time to system time</source>
+ <source>Cannot convert local file time to system time</source>
<translation>Impossible de convertir l&apos;heure du fichier vers l&apos;heure du système</translation>
</message>
<message>
@@ -852,15 +852,15 @@
<translation>Les composants ne peuvent avoir de composants fils en mode mise-à-jour.</translation>
</message>
<message>
- <source>Could not open the requested translation file &apos;%1&apos;.</source>
+ <source>Cannot open the requested translation file &apos;%1&apos;.</source>
<translation>Impossible d&apos;ouvrir le fichier de traduction &apos;%1&apos;.</translation>
</message>
<message>
- <source>Could not open the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>Impossible d&apos;ouvir le fichier d&apos;IHM &apos;%1&apos;. Erreur : %2</translation>
</message>
<message>
- <source>Could not load the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot load the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>Impossible de charger le fichier d&apos;IHM &apos;%1&apos;. Erreur : %2</translation>
</message>
<message>
@@ -868,7 +868,7 @@
<translation>Impossible d&apos;analyser &apos;isDefault&apos; dans %1</translation>
</message>
<message>
- <source>Could not open the requested license file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested license file &apos;%1&apos;. Error: %2</source>
<translation>Impossible d&apos;ouvrir le fichier de licence &apos;%1&apos;. Erreur %2</translation>
</message>
<message>
@@ -1044,7 +1044,7 @@
<translation>Arguments invalides dans %0 : les dossier sont invalides : %1 %2</translation>
</message>
<message>
- <source>Could not create %0</source>
+ <source>Cannot create %0</source>
<translation>Impossible de créer %0</translation>
</message>
<message>
@@ -1052,11 +1052,11 @@
<translation>L&apos;écrasement de %1 à échoué</translation>
</message>
<message>
- <source>Could not copy %0 to %1, error was: %3</source>
+ <source>Cannot copy %0 to %1, error was: %3</source>
<translation>Impossible de copier %0 vers %1, l&apos;erreur rencontrée est : %3</translation>
</message>
<message>
- <source>Could not remove %0</source>
+ <source>Cannot remove %0</source>
<translation>Impossible de supprimer %0</translation>
</message>
</context>
@@ -1067,11 +1067,11 @@
<translation>Nombre incorrect d&apos;éléments de la tâche.</translation>
</message>
<message>
- <source>Could not open source &apos;%1&apos; for read. Error: %2.</source>
+ <source>Cannot open source &apos;%1&apos; for read. Error: %2.</source>
<translation>Impossible d&apos;ouvrir le fichier source &apos;%1&apos; en lecture. Erreur : %2.</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<translation>Impossible d&apos;ouvrir le fichier source &apos;%1&apos; en écriture. Erreur : %2.</translation>
</message>
<message>
@@ -1082,7 +1082,7 @@
<context>
<name>QInstaller::CreateDesktopEntryOperation</name>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>Impossible de faire une sauvegarde du fichier %1 : %2</translation>
</message>
<message>
@@ -1098,7 +1098,7 @@
<translation>L&apos;écrasement de %1 à échoué</translation>
</message>
<message>
- <source>Could not write Desktop Entry at %1</source>
+ <source>Cannot write Desktop Entry at %1</source>
<translation>Impossible d&apos;écrire un élément &apos;Desktop Entry&apos; vers %1</translation>
</message>
</context>
@@ -1113,26 +1113,26 @@
<translation>exactement 2</translation>
</message>
<message>
- <source>Could not create link from %1 to %2.</source>
+ <source>Cannot create link from %1 to %2.</source>
<translation>Impossible de créer le lien symbolique de %1 vers %2.</translation>
</message>
<message>
- <source>Could not remove link from %1 to %2.</source>
+ <source>Cannot remove link from %1 to %2.</source>
<translation>Impossible de supprimer le lien de %1 vers %2.</translation>
</message>
</context>
<context>
<name>QInstaller::CreateLocalRepositoryOperation</name>
<message>
- <source>Could not set file permissions %1!</source>
+ <source>Cannot set file permissions %1!</source>
<translation>Impossible d&apos;attribuer les autorisations du fichier %1 !</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>Impossible de supprimer le fichier %1 : %2</translation>
</message>
<message>
- <source>Could not move file %1 to %2. Error: %3</source>
+ <source>Cannot move file %1 to %2. Error: %3</source>
<translation>Impossible de déplacer le fichier %1 vers %2. Erreur : %3</translation>
</message>
<message>
@@ -1148,19 +1148,19 @@
<translation>L&apos;installeur devrait être une version hors ligne : %1.</translation>
</message>
<message>
- <source>Could not open file: %1</source>
+ <source>Cannot open file: %1</source>
<translation>Impossible d&apos;ouvrir le fichier %1</translation>
</message>
<message>
- <source>Could not read: %1. Error: %2</source>
+ <source>Cannot read: %1. Error: %2</source>
<translation>Impossible de lire : %1. Erreur : %2</translation>
</message>
<message>
- <source>Could not open file: %1. Error: %2</source>
+ <source>Cannot open file: %1. Error: %2</source>
<translation>Impossible d&apos;ouvrir le fichier %1. Erreur : %2</translation>
</message>
<message>
- <source>Could not create target dir: %1.</source>
+ <source>Cannot create target dir: %1.</source>
<translation>Impossible de créer le dossier cible : %1.</translation>
</message>
<message>
@@ -1172,7 +1172,7 @@
<translation>Suppression du fichier : %0</translation>
</message>
<message>
- <source>Could not remove %0.</source>
+ <source>Cannot remove %0.</source>
<translation>Impossible de supprimer %0.</translation>
</message>
<message>
@@ -1195,7 +1195,7 @@
<translation>(optionnel : &apos;workingDirectory=...&apos;, &apos;iconPath=...&apos;, &apos;iconId=...&apos;)</translation>
</message>
<message>
- <source>Could not create folder %1: %2.</source>
+ <source>Cannot create folder %1: %2.</source>
<translation>Impossible de créer le dossier %1 : %2.</translation>
</message>
<message>
@@ -1203,7 +1203,7 @@
<translation>L&apos;écrasement de %1 à échoué : %2</translation>
</message>
<message>
- <source>Could not create link %1: %2</source>
+ <source>Cannot create link %1: %2</source>
<translation>Impossible de créer le raccourci %1 : %2</translation>
</message>
</context>
@@ -1226,15 +1226,15 @@
<translation>La vérification de l&apos;empreinte pendant le téléchargement à échoué. C&apos;est une erreur temporaire, veuillez réessayer.</translation>
</message>
<message>
- <source>Could not verify Hash</source>
+ <source>Cannot verify Hash</source>
<translation>Impossible de vérifier l&apos;empreinte</translation>
</message>
<message>
- <source>Could not download archive: %1 : %2</source>
+ <source>Cannot download archive: %1 : %2</source>
<translation>Impossible de télécharger l&apos;archive : %1 : %2</translation>
</message>
<message>
- <source>Could not fetch archives: %1
+ <source>Cannot fetch archives: %1
Error while loading %2</source>
<translation>Impossible de charger les archives : %1
Erreur pendant le chargement %2</translation>
@@ -1248,7 +1248,7 @@ Erreur pendant le chargement %2</translation>
<translation>Schéma non supporté : %1 (%2)</translation>
</message>
<message>
- <source>Could not find component for: %1.</source>
+ <source>Cannot find component for: %1.</source>
<translation>Impossible de trouver le composant pour : %1.</translation>
</message>
</context>
@@ -1296,7 +1296,7 @@ Erreur pendant le chargement %2</translation>
<translation>Le fichier cible &apos;%1&apos; existe déjà mais il n&apos;est pas de type fichier.</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<extracomment>%2 is a sentence describing the error</extracomment>
<translation>Impossible d&apos;ouvrir le fichier cible &apos;%1&apos; en écriture. Erreur : %2.</translation>
</message>
@@ -1312,11 +1312,11 @@ Erreur pendant le chargement %2</translation>
<translation>au moins 1</translation>
</message>
<message>
- <source>Execution failed: Could not start detached: &quot;%1&quot;</source>
+ <source>Execution failed: Cannot start detached: &quot;%1&quot;</source>
<translation>L&apos;exécution à échouée : impossible de démarrer en mode arrière plan : &quot;%1&quot;</translation>
</message>
<message>
- <source>Execution failed: Could not start: &quot;%1&quot;(%2)</source>
+ <source>Execution failed: Cannot start: &quot;%1&quot;(%2)</source>
<translation>L&apos;exécution à échouée : impossible de démarrer &quot;%1&quot; (%2)</translation>
</message>
<message>
@@ -1353,7 +1353,7 @@ Erreur pendant le chargement %2</translation>
<context>
<name>QInstaller::ExtractArchiveOperation::Runnable</name>
<message>
- <source>Could not open %1 for reading: %2.</source>
+ <source>Cannot open %1 for reading: %2.</source>
<translation>Impossible d&apos;ouvrir %1 en lecture : %2.</translation>
</message>
<message>
@@ -1372,7 +1372,7 @@ Erreur pendant le chargement %2</translation>
<translation>Le nombre d&apos;arguments ne correspond pas : un seul est requis</translation>
</message>
<message>
- <source>Could not get package manager core.</source>
+ <source>Cannot get package manager core.</source>
<translation>Impossible de récupérer le noyau du gestionnaire de paquets.</translation>
</message>
<message>
@@ -1500,7 +1500,7 @@ Erreur pendant le chargement %2</translation>
<translation>Argument invalide : le dossier source ne peut être vide.</translation>
</message>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>Impossible de faire une sauvegarde du fichier %1 : %2</translation>
</message>
<message>
@@ -1512,7 +1512,7 @@ Erreur pendant le chargement %2</translation>
<translation>La copie du fichier %1 à échoué : %2</translation>
</message>
<message>
- <source>Could not create folder at %1: %2</source>
+ <source>Cannot create folder at %1: %2</source>
<translation>Impossible de créer le dossier %1 : %2</translation>
</message>
</context>
@@ -1691,7 +1691,7 @@ Erreur pendant le chargement %2</translation>
<translation>Une exception non spécifiée a été attrapée pendant l&apos;extraction de %1.</translation>
</message>
<message>
- <source>Could not open %1 for reading. Error: %2</source>
+ <source>Cannot open %1 for reading. Error: %2</source>
<translation>Impossible d&apos;ouvrir %1 en lecture : %2</translation>
</message>
</context>
@@ -1779,7 +1779,7 @@ Téléchargement des paquets...</translation>
<translation>Erreur de formatage</translation>
</message>
<message>
- <source>Could not write installer configuration to %1: %2</source>
+ <source>Cannot write installer configuration to %1: %2</source>
<translation>Impossible d&apos;écrire la configuration de l&apos;installeur vers %1 : %2</translation>
</message>
<message>
@@ -1863,19 +1863,19 @@ Mise à jour annulée !</translation>
<translation>L&apos;Outil de Maintenance n&apos;est pas un Bundle</translation>
</message>
<message>
- <source>Could not write maintenance tool data to %1: %2</source>
+ <source>Cannot write maintenance tool data to %1: %2</source>
<translation>Impossible d&apos;écrire les données de l&apos;Outil de Maintenance vers %1 : %2</translation>
</message>
<message>
- <source>Could not remove data file &apos;%1&apos;: %2</source>
+ <source>Cannot remove data file &apos;%1&apos;: %2</source>
<translation>Impossible de supprimer le fichier &apos;%1&apos; : %2</translation>
</message>
<message>
- <source>Could not write maintenance tool to %1: %2</source>
+ <source>Cannot write maintenance tool to %1: %2</source>
<translation>Impossible d&apos;écrire l&apos;Outil de Maintenance vers %1 : %2</translation>
</message>
<message>
- <source>Could not write maintenance tool binary data to %1: %2</source>
+ <source>Cannot write maintenance tool binary data to %1: %2</source>
<translation>Impossible d&apos;écrire les données de l&apos;Outil de Maintenance vers %1 : %2</translation>
</message>
<message>
@@ -1925,7 +1925,7 @@ Installation du composant %1</translation>
<translation>Erreur non déterminée</translation>
</message>
<message>
- <source>Could not retrieve remote tree: %1.</source>
+ <source>Cannot retrieve remote tree: %1.</source>
<translation>Impossible de récupérer l&apos;arborescence distante : %1.</translation>
</message>
<message>
@@ -1933,15 +1933,15 @@ Installation du composant %1</translation>
<translation>Impossible de lire les paquets à partir de : %1.</translation>
</message>
<message>
- <source>Could not retrieve meta information: %1</source>
+ <source>Cannot retrieve meta information: %1</source>
<translation>Impossible de récupérer les métadonnées : %1</translation>
</message>
<message>
- <source>Could not add temporary update source information.</source>
+ <source>Cannot add temporary update source information.</source>
<translation>Impossible d&apos;ajouter des information de source de mise à jour temporaire.</translation>
</message>
<message>
- <source>Could not find any update source information.</source>
+ <source>Cannot find any update source information.</source>
<translation>Impossible de trouver des informations de source de mise à jour.</translation>
</message>
<message>
@@ -2156,14 +2156,14 @@ Veuillez copier cet installateur sur un disque local</translation>
<context>
<name>QInstaller::RemoteObject</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>Impossible de lire les données après envoi de la commande : %1. Octets attendus : %2, reçus : %3. Erreur : %4</translation>
</message>
</context>
<context>
<name>QInstaller::RemoteServerConnection</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>Impossible de lire les données après envoi de la commande : %1. Octets attendus : %2, reçus : %3. Erreur : %4</translation>
</message>
</context>
@@ -2189,7 +2189,7 @@ Veuillez copier cet installateur sur un disque local</translation>
<context>
<name>QInstaller::Resource</name>
<message>
- <source>Could not open Resource &apos;%1&apos; read-only.</source>
+ <source>Cannot open Resource &apos;%1&apos; read-only.</source>
<translation>Le fichier de ressource &apos;%1&apos; ne peut être ouvert en lecture seule.</translation>
</message>
<message>
@@ -2211,7 +2211,7 @@ Veuillez copier cet installateur sur un disque local</translation>
<context>
<name>QInstaller::ScriptEngine</name>
<message>
- <source>Could not open the requested script file at %1: %2.</source>
+ <source>Cannot open the requested script file at %1: %2.</source>
<translation>Impossible d&apos;ouvrir le fichier de script requis à %1 : %2.</translation>
</message>
<message>
@@ -2408,7 +2408,7 @@ Il est déconseillé d&apos;installer dans ce dossier dans le cas où l&apos;ins
<translation>Délai d&apos;attente dépassé pendant le test de : &apos;%1&apos;</translation>
</message>
<message>
- <source>Could not parse Updates.xml! Error: %1.</source>
+ <source>Cannot parse Updates.xml! Error: %1.</source>
<translation>Impossible d&apos;analyser &apos;Updates.xml&apos;. Erreur : %1.</translation>
</message>
<message>
@@ -2438,11 +2438,11 @@ Il est déconseillé d&apos;installer dans ce dossier dans le cas où l&apos;ins
<context>
<name>RemoteClient</name>
<message>
- <source>Could not get authorization.</source>
+ <source>Cannot get authorization.</source>
<translation>Impossible d&apos;obtenir les autorisations nécessaires.</translation>
</message>
<message>
- <source>Could not get authorization that is needed for continuing the installation.
+ <source>Cannot get authorization that is needed for continuing the installation.
Either abort the installation or use the fallback solution by running
%1
@@ -2459,14 +2459,14 @@ en tant que root et en cliquant sur OK.</translation>
<context>
<name>ResourceCollectionManager</name>
<message>
- <source>Could not open resource %1: %2</source>
+ <source>Cannot open resource %1: %2</source>
<translation>Impossible d&apos;ouvrir la ressource %1 : %2</translation>
</message>
</context>
<context>
<name>Settings</name>
<message>
- <source>Could not open settings file %1 for reading: %2</source>
+ <source>Cannot open settings file %1 for reading: %2</source>
<translation>Impossible d&apos;ouvrir le fichier de préférences %1 en lecture : %2</translation>
</message>
</context>
@@ -2596,7 +2596,7 @@ en tant que root et en cliquant sur OK.</translation>
<translation>Le chemin du registre %1 n&apos;est pas accessible en écriture</translation>
</message>
<message>
- <source>Could not write to registry path %1</source>
+ <source>Cannot write to registry path %1</source>
<translation>Impossible d&apos;écrire dans le registre le chemin %1</translation>
</message>
<message>
diff --git a/src/sdk/translations/it.ts b/src/sdk/translations/it.ts
index 8aa0f1245..91458b78e 100644
--- a/src/sdk/translations/it.ts
+++ b/src/sdk/translations/it.ts
@@ -15,26 +15,26 @@
<context>
<name>BinaryContent</name>
<message>
- <source>Could not seek to %1 to read the operation data.</source>
+ <source>Cannot seek to %1 to read the operation data.</source>
<translation>Impossibile spostarsi alla posizione %1 per leggere i dati di funzionamento.</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection block.</source>
+ <source>Cannot seek to %1 to read the resource collection block.</source>
<translation>Impossibile spostarsi alla posizione %1 per leggere il blocco con le risorse.</translation>
</message>
<message>
- <source>Could not open meta resource. Error: %1</source>
+ <source>Cannot open meta resource. Error: %1</source>
<translation>Impossibile aprire i meta pacchetti.Errore: %1</translation>
</message>
</context>
<context>
<name>BinaryLayout</name>
<message>
- <source>Could not seek to %1 to read the embedded meta data count.</source>
+ <source>Cannot seek to %1 to read the embedded meta data count.</source>
<translation>Impossibile eseguire il seek a %1 per leggere il conteggio dei meta dati embedded.</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection segment.</source>
+ <source>Cannot seek to %1 to read the resource collection segment.</source>
<translation></translation>
</message>
<message>
@@ -72,34 +72,34 @@
<translation>Il percorso esiste ma non è una cartella: %1</translation>
</message>
<message>
- <source>Could not create folder: %1</source>
+ <source>Cannot create folder: %1</source>
<translation>Impossibile creare la cartella: %1</translation>
</message>
</context>
<context>
<name>ExtractCallbackImpl</name>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>Impossibile recuperare il path dell&apos;elemento dell&apos;archivio %1</translation>
</message>
<message>
- <source>Could not remove already existing symlink. %1</source>
+ <source>Cannot remove already existing symlink. %1</source>
<translation>Impossibile rimuovere il collegamento già esistente. %1</translation>
</message>
<message>
- <source>Could not open file: %1 (%2)</source>
+ <source>Cannot open file: %1 (%2)</source>
<translation>Impossibile aprire il file: %1 (%2)</translation>
</message>
<message>
- <source>Could not create symlink at &apos;%1&apos;. Another one is already existing.</source>
+ <source>Cannot create symlink at &apos;%1&apos;. Another one is already existing.</source>
<translation>Impossibile creare il collegamento a &apos;%1&apos;. Un altro collegamento è già esistente.</translation>
</message>
<message>
- <source>Could not read symlink target from file &apos;%1&apos;.</source>
+ <source>Cannot read symlink target from file &apos;%1&apos;.</source>
<translation>Impossibile leggere dal file %1 puntato dal collegamento.</translation>
</message>
<message>
- <source>Could not create symlink at %1. %2</source>
+ <source>Cannot create symlink at %1. %2</source>
<translation>Impossibile creare il collegamento a %1. %2</translation>
</message>
</context>
@@ -131,28 +131,28 @@
</message>
</context>
<context>
- <name>KDJob</name>
+ <name>Job</name>
<message>
<source>Canceled</source>
<translation>Annullato</translation>
</message>
</context>
<context>
- <name>KDLockFile</name>
+ <name>LockFile</name>
<message>
- <source>Could not create lock file &apos;%1&apos;: %2</source>
+ <source>Cannot create lock file &apos;%1&apos;: %2</source>
<translation>Impossibile creare il file &apos;%1&apos;: %2</translation>
</message>
<message>
- <source>Could not write PID to lock file &apos;%1&apos;: %2</source>
+ <source>Cannot write PID to lock file &apos;%1&apos;: %2</source>
<translation>Impossibile scrivere il PID nel file lockkato &apos;%1&apos;: %2</translation>
</message>
<message>
- <source>Could not obtain the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot obtain the lock for file &apos;%1&apos;: %2</source>
<translation>Impossibile ottenere il lock del file &apos;%1&apos;: %2</translation>
</message>
<message>
- <source>Could not release the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot release the lock for file &apos;%1&apos;: %2</source>
<translation>Impossibile rilasciare il lock del file &apos;%1&apos;: %2</translation>
</message>
</context>
@@ -171,7 +171,7 @@
<translation>esattamente 2</translation>
</message>
<message>
- <source>Could not open file &apos;%1&apos; for writing: %2</source>
+ <source>Cannot open file &apos;%1&apos; for writing: %2</source>
<translation>Impossibile aprire il file %1 in scrittura: %2</translation>
</message>
<message>
@@ -179,18 +179,18 @@
<translation>Impossibile trovare il file di backup per %1.</translation>
</message>
<message>
- <source>Could not restore backup file for %1.</source>
+ <source>Cannot restore backup file for %1.</source>
<translation>Impossibile ripristinare il file di backup per %1.</translation>
</message>
<message>
- <source>Could not restore backup file for %1: %2</source>
+ <source>Cannot restore backup file for %1: %2</source>
<translation>Impossibile ripristinare il file di backup per %1: %2</translation>
</message>
</context>
<context>
<name>KDUpdater::CopyOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>Impossibile eseguire il backup del file %1.</translation>
</message>
<message>
@@ -198,23 +198,23 @@
<translation>Argomenti invalidi: argomenti forniti %1, richiesti 2.</translation>
</message>
<message>
- <source>Could not copy a non-existent file: %1</source>
+ <source>Cannot copy a non-existent file: %1</source>
<translation>Impossibile copiare un file non esistente: %1</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>Impossibile rimuovere il file di destinazione %1: %2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>Impossibile copiare %1 in %2: %3</translation>
</message>
<message>
- <source>Could not delete file %1: %2</source>
+ <source>Cannot delete file %1: %2</source>
<translation>Impossibile eliminare il file %1: %2</translation>
</message>
<message>
- <source>Could not restore backup file into %1: %2</source>
+ <source>Cannot restore backup file into %1: %2</source>
<translation>Impossibile ripristinare il file di backup in %1: %2</translation>
</message>
</context>
@@ -303,7 +303,7 @@
<translation>Impossibile scaricare %1: Scrittura nel file &apos;%2&apos; fallita: %3</translation>
</message>
<message>
- <source>Cannot download %1: Could not create %2: %3</source>
+ <source>Cannot download %1: Cannot create %2: %3</source>
<translation>Impossibile scaricare %1: Impossibile creare %2: %3</translation>
</message>
<message>
@@ -357,7 +357,7 @@
<translation>Argomenti invalidi: argomenti forniti %1, richiesti 1.</translation>
</message>
<message>
- <source>Could not create folder %1: Unknown error.</source>
+ <source>Cannot create folder %1: Unknown error.</source>
<translation>Impossibile creare la cartella %1: Errore sconosciuto.</translation>
</message>
<message>
@@ -368,7 +368,7 @@
<context>
<name>KDUpdater::MoveOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>Impossibile eseguire il backup del file %1.</translation>
</message>
<message>
@@ -376,11 +376,11 @@
<translation>Argomenti invalidi: argomenti forniti %1, richiesti 2.</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>Impossibile rimuovere il file di destinazione %1: %2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>Impossibile copiare %1 in %2: %3</translation>
</message>
<message>
@@ -407,7 +407,7 @@
<translation>Il file %1 non esiste.</translation>
</message>
<message>
- <source>Could not open %1.</source>
+ <source>Cannot open %1.</source>
<translation>Impossibile aprire %1.</translation>
</message>
<message>
@@ -430,11 +430,11 @@
<translation>Argomenti invalidi: argomenti forniti %1, richiesti 2.</translation>
</message>
<message>
- <source>Could not open file %1 for reading: %2</source>
+ <source>Cannot open file %1 for reading: %2</source>
<translation>Impossibile aprire %1 in lettura: %2</translation>
</message>
<message>
- <source>Could not open file %1 for writing: %2</source>
+ <source>Cannot open file %1 for writing: %2</source>
<translation>Impossibile aprire il file %1 in scrittura: %2</translation>
</message>
<message>
@@ -453,7 +453,7 @@
<context>
<name>KDUpdater::ResourceFileDownloader</name>
<message>
- <source>Could not read resource file &quot;%1&quot;. Reason:</source>
+ <source>Cannot read resource file &quot;%1&quot;. Reason:</source>
<translation>Impossibile leggere il file di risorse &quot;%1&quot;. Motivo:</translation>
</message>
</context>
@@ -464,11 +464,11 @@
<translation>Argomenti invalidi: argomenti forniti %1, richiesti 1.</translation>
</message>
<message>
- <source>Could not remove folder %1: The folder does not exist.</source>
+ <source>Cannot remove folder %1: The folder does not exist.</source>
<translation>Impossibile rimuovere la cartella %1: La cartella non esiste.</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>Impossibile rimuovere la cartella %1: %2</translation>
</message>
<message>
@@ -510,11 +510,11 @@
<context>
<name>KDUpdater::UpdateFinder</name>
<message>
- <source>Could not access the package information of this application.</source>
+ <source>Cannot access the package information of this application.</source>
<translation>Impossibile accedere alle informazioni del pacchetto si questa applicazione.</translation>
</message>
<message>
- <source>Could not access the update sources information of this application.</source>
+ <source>Cannot access the update sources information of this application.</source>
<translation>Impossibile accedere alle informazioni degli aggiornamenti di questa applicazione.</translation>
</message>
<message>
@@ -529,7 +529,7 @@
</translation>
</message>
<message>
- <source>Could not download update source %1 from (&apos;%2&apos;)</source>
+ <source>Cannot download update source %1 from (&apos;%2&apos;)</source>
<translation>Impossibile scaricare l&apos;aggiornamento %1 da (&apos;%2&apos;)</translation>
</message>
<message>
@@ -552,7 +552,7 @@
<translation>%1 contiene dati invalidi: %2</translation>
</message>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>Impossibile leggere &quot;%1&quot;</translation>
</message>
<message>
@@ -564,14 +564,14 @@
<translation>Elemento di Root %1 inaspettato, dovrebbe essere &quot;UpdateSources&quot;</translation>
</message>
<message>
- <source>Could not save changes to &quot;%1&quot;: %2</source>
+ <source>Cannot save changes to &quot;%1&quot;: %2</source>
<translation>Impossibile salvare i cambiamenti in &quot;%1&quot;: %2</translation>
</message>
</context>
<context>
<name>KDUpdater::UpdatesInfoData</name>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>Impossibile leggere &quot;%1&quot;</translation>
</message>
<message>
@@ -610,11 +610,11 @@
<context>
<name>Lib7z</name>
<message>
- <source>Could not retrieve number of items in archive</source>
+ <source>Cannot retrieve number of items in archive</source>
<translation>Impossibile recuperare il numero di oggetti in archivio</translation>
</message>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>Impossibile recuperare il path dell&apos;oggetto in archivio %1</translation>
</message>
<message>
@@ -634,15 +634,15 @@
<translation>Errore: %1</translation>
</message>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>Impossibile caricare i codec</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>Impossibile recuperare il formato di default</translation>
</message>
<message>
- <source>Could not create archive %1. %2</source>
+ <source>Cannot create archive %1. %2</source>
<translation>Impossibile creare l&apos;archivio %1. %2</translation>
</message>
<message>
@@ -654,14 +654,14 @@
<translation>L&apos;indice dell&apos;oggetto %1 è fuori dai limiti [0, %2]</translation>
</message>
<message>
- <source>Could not create output file for writing: %1</source>
+ <source>Cannot create output file for writing: %1</source>
<translation>Impossibile creare il file di output aperto in scrittura: %1</translation>
</message>
</context>
<context>
<name>Lib7z::ExtractItemJob</name>
<message>
- <source>Could not list archive: QIODevice not set or already destroyed.</source>
+ <source>Cannot list archive: QIODevice not set or already destroyed.</source>
<translation>Impossibile accedere al contenuto dell&apos;archivio: QIODevice non configurato o già distrutto.</translation>
</message>
<message>
@@ -680,7 +680,7 @@
<context>
<name>Lib7z::ListArchiveJob</name>
<message>
- <source>Could not list archive: QIODevice already destroyed.</source>
+ <source>Cannot list archive: QIODevice already destroyed.</source>
<translation>Impossibile accedere all&apos;archivio: QIODevice già distrutto.</translation>
</message>
<message>
@@ -695,15 +695,15 @@
<context>
<name>OpenArchiveInfo</name>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>Impossibile caricare i codec</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>Impossibile recuperare il formato di default</translation>
</message>
<message>
- <source>Could not open archive</source>
+ <source>Cannot open archive</source>
<translation>Impossibile aprire l&apos;archivio</translation>
</message>
<message>
@@ -781,43 +781,43 @@
<translation></translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>Impossibile rimuovere il file %1: %2</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>Impossibile rimuovere la cartella %1: %2</translation>
</message>
<message>
- <source>Could not create folder %1</source>
+ <source>Cannot create folder %1</source>
<translation>Impossibile creare la cartella %1</translation>
</message>
<message>
- <source>Could not copy file from %1 to %2: %3</source>
+ <source>Cannot copy file from %1 to %2: %3</source>
<translation>Impossibile copiare il file da %1 a %2: %3</translation>
</message>
<message>
- <source>Could not move file from %1 to %2: %3</source>
+ <source>Cannot move file from %1 to %2: %3</source>
<translation>Impossibile muovere il file da %1 a %2: %3</translation>
</message>
<message>
- <source>Could not create folder %1: %2</source>
+ <source>Cannot create folder %1: %2</source>
<translation>Impossibile creare la cartella %1: %2</translation>
</message>
<message>
- <source>Could not open temporary file: %1</source>
+ <source>Cannot open temporary file: %1</source>
<translation>Impossibile aprire il file temporaneo: %1</translation>
</message>
<message>
- <source>Could not open temporary file for template %1: %2</source>
+ <source>Cannot open temporary file for template %1: %2</source>
<translation>Impossibile aprire il file temporaneo per template %1: %2</translation>
</message>
<message>
- <source>Could not create temporary file</source>
+ <source>Cannot create temporary file</source>
<translation>Impossibile creare il file temporaneo</translation>
</message>
<message>
- <source>Could not retrieve property %1 for item %2</source>
+ <source>Cannot retrieve property %1 for item %2</source>
<translation>Impossibile recuperare la proprietà %1 per l&apos;oggetto %2</translation>
</message>
<message>
@@ -825,11 +825,11 @@
<translation>La propietà %1 per l&apos;oggetto %2 non è di tipo VT_FILETIME ma %3</translation>
</message>
<message>
- <source>Could not convert file time to local time</source>
+ <source>Cannot convert file time to local time</source>
<translation>Impossibile convertire l&apos;orario del file in ora locale</translation>
</message>
<message>
- <source>Could not convert local file time to system time</source>
+ <source>Cannot convert local file time to system time</source>
<translation>Impossible convertire l&apos;ora del file in orario di sistema</translation>
</message>
<message>
@@ -852,15 +852,15 @@
<translation>Componenti non possono avere figli nella modalità di aggiornamento.</translation>
</message>
<message>
- <source>Could not open the requested translation file &apos;%1&apos;.</source>
+ <source>Cannot open the requested translation file &apos;%1&apos;.</source>
<translation>Impossibile aprire il file di traduzioni richiesto &apos;%1&apos;.</translation>
</message>
<message>
- <source>Could not open the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>Impossibile aprire il file UI &apos;%1&apos;. Errore: %2</translation>
</message>
<message>
- <source>Could not load the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot load the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>Impossibile caricare il file UI &apos;%1&apos;. Errore: %2</translation>
</message>
<message>
@@ -868,7 +868,7 @@
<translation>Impossibile risolvere isDefault in %1</translation>
</message>
<message>
- <source>Could not open the requested license file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested license file &apos;%1&apos;. Error: %2</source>
<translation>Impossibile aprire il file di licenza richiesto &apos;%1&apos;. Errore: %2</translation>
</message>
<message>
@@ -1040,7 +1040,7 @@
<translation>Argomenti invalidi in %0: Le cartelle sono invalide: %1 %2</translation>
</message>
<message>
- <source>Could not create %0</source>
+ <source>Cannot create %0</source>
<translation>Impossibile creare %0</translation>
</message>
<message>
@@ -1048,11 +1048,11 @@
<translation>Impossibile sovrascrivere %1</translation>
</message>
<message>
- <source>Could not copy %0 to %1, error was: %3</source>
+ <source>Cannot copy %0 to %1, error was: %3</source>
<translation>Impossibile copiare il file da %0 a %1, errore: %3</translation>
</message>
<message>
- <source>Could not remove %0</source>
+ <source>Cannot remove %0</source>
<translation>Impossibile rimuovere %0</translation>
</message>
</context>
@@ -1063,11 +1063,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open source &apos;%1&apos; for read. Error: %2.</source>
+ <source>Cannot open source &apos;%1&apos; for read. Error: %2.</source>
<translation>Impossibile aprire il file sorgente &apos;%1&apos; in lettura. Errore: %2.</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<translation>Impossibile aprire il file di destinazione &apos;%1&apos; in scrittura. Errore: %2.</translation>
</message>
<message>
@@ -1078,7 +1078,7 @@
<context>
<name>QInstaller::CreateDesktopEntryOperation</name>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>Impossibile eseguire il backup del file %1: %2</translation>
</message>
<message>
@@ -1094,7 +1094,7 @@
<translation>Impossibile sovrascrivere %1</translation>
</message>
<message>
- <source>Could not write Desktop Entry at %1</source>
+ <source>Cannot write Desktop Entry at %1</source>
<translation></translation>
</message>
</context>
@@ -1109,26 +1109,26 @@
<translation>esattamente 2</translation>
</message>
<message>
- <source>Could not create link from %1 to %2.</source>
+ <source>Cannot create link from %1 to %2.</source>
<translation>Impossibile creare il link per %1 a %2.</translation>
</message>
<message>
- <source>Could not remove link from %1 to %2.</source>
+ <source>Cannot remove link from %1 to %2.</source>
<translation>Impossibile rimuovere il link per %1 a %2.</translation>
</message>
</context>
<context>
<name>QInstaller::CreateLocalRepositoryOperation</name>
<message>
- <source>Could not set file permissions %1!</source>
+ <source>Cannot set file permissions %1!</source>
<translation>Impossibile settare i permessi del file %1!</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>Impossibile rimuovere il file %1: %2</translation>
</message>
<message>
- <source>Could not move file %1 to %2. Error: %3</source>
+ <source>Cannot move file %1 to %2. Error: %3</source>
<translation>Impossibile muovere il file da %1 a %2: Errore %3</translation>
</message>
<message>
@@ -1144,19 +1144,19 @@
<translation>Installer deve essere una versione offline: %1.</translation>
</message>
<message>
- <source>Could not open file: %1</source>
+ <source>Cannot open file: %1</source>
<translation>Impossibile aprire il file: %1</translation>
</message>
<message>
- <source>Could not read: %1. Error: %2</source>
+ <source>Cannot read: %1. Error: %2</source>
<translation>Impossibile leggere: %1. Errore: %2</translation>
</message>
<message>
- <source>Could not open file: %1. Error: %2</source>
+ <source>Cannot open file: %1. Error: %2</source>
<translation>Impossibile aprire il file: %1. Errore %2</translation>
</message>
<message>
- <source>Could not create target dir: %1.</source>
+ <source>Cannot create target dir: %1.</source>
<translation>Impossibile creare la cartella di destinazione: %1.</translation>
</message>
<message>
@@ -1168,7 +1168,7 @@
<translation>Rimozione file: %0</translation>
</message>
<message>
- <source>Could not remove %0.</source>
+ <source>Cannot remove %0.</source>
<translation>Impossibile rimuovere %0.</translation>
</message>
<message>
@@ -1191,7 +1191,7 @@
<translation> (opzionale: &apos;workingDirectory=...&apos;, &apos;iconPath=...&apos;, &apos;iconId=...&apos;)</translation>
</message>
<message>
- <source>Could not create folder %1: %2.</source>
+ <source>Cannot create folder %1: %2.</source>
<translation>Impossibile creare la cartella %1: %2.</translation>
</message>
<message>
@@ -1199,7 +1199,7 @@
<translation>Impossibile sovrascrivere %1: %2</translation>
</message>
<message>
- <source>Could not create link %1: %2</source>
+ <source>Cannot create link %1: %2</source>
<translation>Impossibile creare il link %1: %2</translation>
</message>
</context>
@@ -1222,15 +1222,15 @@
<translation>Verifica Hash durante il download fallita. Questo è un errore temporaneo, riprovare.</translation>
</message>
<message>
- <source>Could not verify Hash</source>
+ <source>Cannot verify Hash</source>
<translation>Impossibile verificare l&apos;hash</translation>
</message>
<message>
- <source>Could not download archive: %1 : %2</source>
+ <source>Cannot download archive: %1 : %2</source>
<translation>Impossibile scaricare l&apos;archivio %1. %2</translation>
</message>
<message>
- <source>Could not fetch archives: %1
+ <source>Cannot fetch archives: %1
Error while loading %2</source>
<translation>Impossibile eseguire il fetch dell&apos;archivio: %1
Errore durante lo scaricamento %2</translation>
@@ -1244,7 +1244,7 @@ Errore durante lo scaricamento %2</translation>
<translation>Schema non supportato: %1 (%2)</translation>
</message>
<message>
- <source>Could not find component for: %1.</source>
+ <source>Cannot find component for: %1.</source>
<translation>Impossibile trovare il componente per : %1.</translation>
</message>
</context>
@@ -1292,7 +1292,7 @@ Errore durante lo scaricamento %2</translation>
<translation>Il file di destinazione &apos;%1&apos; è gia esistente ma non è un file.</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<extracomment>%2 is a sentence describing the error</extracomment>
<translation>Impossibile aprire il file di destinazione &apos;%1&apos; in scrittura. Errore: %2.</translation>
</message>
@@ -1308,11 +1308,11 @@ Errore durante lo scaricamento %2</translation>
<translation>almeno 1</translation>
</message>
<message>
- <source>Execution failed: Could not start detached: &quot;%1&quot;</source>
+ <source>Execution failed: Cannot start detached: &quot;%1&quot;</source>
<translation>Esecuzione fallita:Impossibile iniziare: &quot;%1&quot;</translation>
</message>
<message>
- <source>Execution failed: Could not start: &quot;%1&quot;(%2)</source>
+ <source>Execution failed: Cannot start: &quot;%1&quot;(%2)</source>
<translation>Esecuzione fallita:Impossibile iniziare: &quot;%1&quot;(%2)</translation>
</message>
<message>
@@ -1349,7 +1349,7 @@ Errore durante lo scaricamento %2</translation>
<context>
<name>QInstaller::ExtractArchiveOperation::Runnable</name>
<message>
- <source>Could not open %1 for reading: %2.</source>
+ <source>Cannot open %1 for reading: %2.</source>
<translation>Impossibile aprire %1 in lettura: %2.</translation>
</message>
<message>
@@ -1368,7 +1368,7 @@ Errore durante lo scaricamento %2</translation>
<translation>Il numero di argomenti non corrisponde: solo uno è richiesto</translation>
</message>
<message>
- <source>Could not get package manager core.</source>
+ <source>Cannot get package manager core.</source>
<translation>Impossibile prendere il cuore del gestore pacchetti.</translation>
</message>
<message>
@@ -1496,7 +1496,7 @@ Errore durante lo scaricamento %2</translation>
<translation>Argomenti invalidi: la cartella sorgente non deve essere vuota.</translation>
</message>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>Impossibile eseguire il backup del file %1: %2</translation>
</message>
<message>
@@ -1508,7 +1508,7 @@ Errore durante lo scaricamento %2</translation>
<translation>Impossibile copiare %1: %2</translation>
</message>
<message>
- <source>Could not create folder at %1: %2</source>
+ <source>Cannot create folder at %1: %2</source>
<translation>Impossibile creare la cartella %1: %2</translation>
</message>
</context>
@@ -1685,7 +1685,7 @@ Errore durante lo scaricamento %2</translation>
<translation>Eccezzione sconosciuta durante l&apos;estrazione %1.</translation>
</message>
<message>
- <source>Could not open %1 for reading. Error: %2</source>
+ <source>Cannot open %1 for reading. Error: %2</source>
<translation>Impossibile aprire %1 in lettura. Errore: %2</translation>
</message>
</context>
@@ -1773,7 +1773,7 @@ Scaricamento pacchetti...</translation>
<translation>Errore di formato</translation>
</message>
<message>
- <source>Could not write installer configuration to %1: %2</source>
+ <source>Cannot write installer configuration to %1: %2</source>
<translation>Impossibile scrivere la configurazione dell&apos;installer in %1: %2</translation>
</message>
<message>
@@ -1856,19 +1856,19 @@ Update aborted!</source>
<translation></translation>
</message>
<message>
- <source>Could not write maintenance tool data to %1: %2</source>
+ <source>Cannot write maintenance tool data to %1: %2</source>
<translation>Impossibile scrivere i dati del tool di mantenimento in %1: %2</translation>
</message>
<message>
- <source>Could not remove data file &apos;%1&apos;: %2</source>
+ <source>Cannot remove data file &apos;%1&apos;: %2</source>
<translation>Impossibile rimuovere i dati del file &apos;%1&apos;: %2</translation>
</message>
<message>
- <source>Could not write maintenance tool to %1: %2</source>
+ <source>Cannot write maintenance tool to %1: %2</source>
<translation>Impossibile scrivere il tool di mantenimento in %1: %2</translation>
</message>
<message>
- <source>Could not write maintenance tool binary data to %1: %2</source>
+ <source>Cannot write maintenance tool binary data to %1: %2</source>
<translation>Impossibile scrivere i dati del tool di mantenimento in %1: %2</translation>
</message>
<message>
@@ -1918,7 +1918,7 @@ Installazione componenti %1</translation>
<translation>Errore sconosciuto</translation>
</message>
<message>
- <source>Could not retrieve remote tree: %1.</source>
+ <source>Cannot retrieve remote tree: %1.</source>
<translation></translation>
</message>
<message>
@@ -1926,15 +1926,15 @@ Installazione componenti %1</translation>
<translation>Fallita la lettura del pacchetto da: %1.</translation>
</message>
<message>
- <source>Could not retrieve meta information: %1</source>
+ <source>Cannot retrieve meta information: %1</source>
<translation>Impossibile recuperare i meta dati: %1</translation>
</message>
<message>
- <source>Could not add temporary update source information.</source>
+ <source>Cannot add temporary update source information.</source>
<translation></translation>
</message>
<message>
- <source>Could not find any update source information.</source>
+ <source>Cannot find any update source information.</source>
<translation>Impossibile trovare le informazioni per l&apos;aggiornamento.</translation>
</message>
<message>
@@ -2149,14 +2149,14 @@ Copiare l&apos;installer in locale</translation>
<context>
<name>QInstaller::RemoteObject</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>Impossibile leggere tutti i dati dopo l&apos;invio del comando: %1. Bytes aspettati: %2, Bytes ricevuti: %3. Errori: %4</translation>
</message>
</context>
<context>
<name>QInstaller::RemoteServerConnection</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation type="vanished">Impossibile leggere tutti i dati dopo l&apos;invio del comando: %1. Bytes aspettati: %2, Bytes ricevuti: %3. Errori: %4</translation>
</message>
</context>
@@ -2182,7 +2182,7 @@ Copiare l&apos;installer in locale</translation>
<context>
<name>QInstaller::Resource</name>
<message>
- <source>Could not open Resource &apos;%1&apos; read-only.</source>
+ <source>Cannot open Resource &apos;%1&apos; read-only.</source>
<translation>Impossibile aprire la Risorsa &apos;%1&apos; in sola lettura.</translation>
</message>
<message>
@@ -2204,7 +2204,7 @@ Copiare l&apos;installer in locale</translation>
<context>
<name>QInstaller::ScriptEngine</name>
<message>
- <source>Could not open the requested script file at %1: %2.</source>
+ <source>Cannot open the requested script file at %1: %2.</source>
<translation>Impossibile aprire lo script %1: %2.</translation>
</message>
<message>
@@ -2400,7 +2400,7 @@ Vuoi continuare?</translation>
<translation>E&apos; scaduto un timeout durante il test: &apos;%1&apos;</translation>
</message>
<message>
- <source>Could not parse Updates.xml! Error: %1.</source>
+ <source>Cannot parse Updates.xml! Error: %1.</source>
<translation>Impossibile analizzare Updates.xml! Errore: %1.</translation>
</message>
<message>
@@ -2430,11 +2430,11 @@ Vuoi continuare?</translation>
<context>
<name>RemoteClient</name>
<message>
- <source>Could not get authorization.</source>
+ <source>Cannot get authorization.</source>
<translation>Impossibile ottenere l&apos;autorizzazione.</translation>
</message>
<message>
- <source>Could not get authorization that is needed for continuing the installation.
+ <source>Cannot get authorization that is needed for continuing the installation.
Either abort the installation or use the fallback solution by running
%1
@@ -2451,14 +2451,14 @@ come root e premere ok.</translation>
<context>
<name>ResourceCollectionManager</name>
<message>
- <source>Could not open resource %1: %2</source>
+ <source>Cannot open resource %1: %2</source>
<translation>Impossibile aprire la risorsa %1: %2</translation>
</message>
</context>
<context>
<name>Settings</name>
<message>
- <source>Could not open settings file %1 for reading: %2</source>
+ <source>Cannot open settings file %1 for reading: %2</source>
<translation>Impossibile aprire il file di configurazione %1 in lettura: %2</translation>
</message>
</context>
@@ -2588,7 +2588,7 @@ come root e premere ok.</translation>
<translation>La chiave di registro %1 non può essere scritta</translation>
</message>
<message>
- <source>Could not write to registry path %1</source>
+ <source>Cannot write to registry path %1</source>
<translation>Impossibile scrivere la chiave di registro %1</translation>
</message>
<message>
diff --git a/src/sdk/translations/ja.ts b/src/sdk/translations/ja.ts
index 3f14998b6..facd4c0a7 100644
--- a/src/sdk/translations/ja.ts
+++ b/src/sdk/translations/ja.ts
@@ -25,7 +25,7 @@
</message>
</context>
<context>
- <name>KDJob</name>
+ <name>Job</name>
<message>
<source>Canceled</source>
<translation>キャンセルã—ã¾ã—ãŸ</translation>
@@ -46,7 +46,7 @@
<translation>2個</translation>
</message>
<message>
- <source>Could not open file &apos;%1&apos; for writing: %2</source>
+ <source>Cannot open file &apos;%1&apos; for writing: %2</source>
<translation>書ãè¾¼ã¿ç”¨ã«ãƒ•ã‚¡ã‚¤ãƒ« &apos;%1&apos; ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
@@ -54,18 +54,18 @@
<translation>%1 用ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。</translation>
</message>
<message>
- <source>Could not restore backup file for %1.</source>
+ <source>Cannot restore backup file for %1.</source>
<translation>%1 用ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルを復元ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <source>Could not restore backup file for %1: %2</source>
+ <source>Cannot restore backup file for %1: %2</source>
<translation>%1 用ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルを復元ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
</context>
<context>
<name>KDUpdater::CopyOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>ファイル %1 ã‚’ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
@@ -73,23 +73,23 @@
<translation>無効ãªå¼•æ•°: %1個ã®å¼•æ•°ãŒæ¸¡ã•ã‚Œã¾ã—ãŸãŒã€å¿…è¦ãªã®ã¯2個ã§ã™ã€‚</translation>
</message>
<message>
- <source>Could not copy a non-existent file: %1</source>
+ <source>Cannot copy a non-existent file: %1</source>
<translation>存在ã—ãªã„ファイルã¯ã‚³ãƒ”ーã§ãã¾ã›ã‚“: %1</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>対象ファイル %1 を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>%1 ã‚’ %2 ã«ã‚³ãƒ”ーã§ãã¾ã›ã‚“ã§ã—ãŸ: %3</translation>
</message>
<message>
- <source>Could not delete file %1: %2</source>
+ <source>Cannot delete file %1: %2</source>
<translation>ファイル %1 を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not restore backup file into %1: %2</source>
+ <source>Cannot restore backup file into %1: %2</source>
<translation>ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルを %1 ã¸å¾©å…ƒã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
</context>
@@ -174,7 +174,7 @@
<translation>%1 をダウンロードã§ãã¾ã›ã‚“: ファイル &apos;%2&apos; ã¸ã®æ›¸ãè¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ: %3</translation>
</message>
<message>
- <source>Cannot download %1: Could not create %2: %3</source>
+ <source>Cannot download %1: Cannot create %2: %3</source>
<translation>%1 をダウンロードã§ãã¾ã›ã‚“: %2 を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %3</translation>
</message>
<message>
@@ -228,7 +228,7 @@
<translation>無効ãªå¼•æ•°: %1個ã®å¼•æ•°ãŒæ¸¡ã•ã‚Œã¾ã—ãŸãŒã€å¿…è¦ãªã®ã¯1個ã§ã™ã€‚</translation>
</message>
<message>
- <source>Could not create folder %1: Unknown error.</source>
+ <source>Cannot create folder %1: Unknown error.</source>
<translation>フォルダ %1 を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: 未知ã®ã‚¨ãƒ©ãƒ¼ã§ã™ã€‚</translation>
</message>
<message>
@@ -239,7 +239,7 @@
<context>
<name>KDUpdater::MoveOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>ファイル %1 ã‚’ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
@@ -247,11 +247,11 @@
<translation>無効ãªå¼•æ•°: %1個ã®å¼•æ•°ãŒæ¸¡ã•ã‚Œã¾ã—ãŸãŒã€å¿…è¦ãªã®ã¯2個ã§ã™ã€‚</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>対象ファイル %1 を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>%1 ã‚’ %2 ã«ã‚³ãƒ”ーã§ãã¾ã›ã‚“ã§ã—ãŸ: %3</translation>
</message>
<message>
@@ -278,7 +278,7 @@
<translation>ファイル %1 ãŒå­˜åœ¨ã—ã¾ã›ã‚“。</translation>
</message>
<message>
- <source>Could not open %1.</source>
+ <source>Cannot open %1.</source>
<translation>%1 ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
@@ -301,11 +301,11 @@
<translation>無効ãªå¼•æ•°: %1個ã®å¼•æ•°ãŒæ¸¡ã•ã‚Œã¾ã—ãŸãŒã€å¿…è¦ãªã®ã¯2個ã§ã™ã€‚</translation>
</message>
<message>
- <source>Could not open file %1 for reading: %2</source>
+ <source>Cannot open file %1 for reading: %2</source>
<translation>読ã¿è¾¼ã¿ç”¨ã«ãƒ•ã‚¡ã‚¤ãƒ« %1 ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not open file %1 for writing: %2</source>
+ <source>Cannot open file %1 for writing: %2</source>
<translation>書ãè¾¼ã¿ç”¨ã«ãƒ•ã‚¡ã‚¤ãƒ« %1 ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
@@ -324,7 +324,7 @@
<context>
<name>KDUpdater::ResourceFileDownloader</name>
<message>
- <source>Could not read resource file &quot;%1&quot;. Reason:</source>
+ <source>Cannot read resource file &quot;%1&quot;. Reason:</source>
<translation>リソースファイル &quot;%1&quot; を読ã¿è¾¼ã¿ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ç†ç”±:</translation>
</message>
</context>
@@ -335,11 +335,11 @@
<translation>無効ãªå¼•æ•°: %1個ã®å¼•æ•°ãŒæ¸¡ã•ã‚Œã¾ã—ãŸãŒã€å¿…è¦ãªã®ã¯1個ã§ã™ã€‚</translation>
</message>
<message>
- <source>Could not remove folder %1: The folder does not exist.</source>
+ <source>Cannot remove folder %1: The folder does not exist.</source>
<translation>フォルダ %1 を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: フォルダãŒå­˜åœ¨ã—ã¾ã›ã‚“。</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>フォルダ %1 を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
@@ -381,11 +381,11 @@
<context>
<name>KDUpdater::UpdateFinder</name>
<message>
- <source>Could not access the package information of this application.</source>
+ <source>Cannot access the package information of this application.</source>
<translation>ã“ã®ã‚¢ãƒ—リケーションã®ãƒ‘ッケージ情報ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <source>Could not access the update sources information of this application.</source>
+ <source>Cannot access the update sources information of this application.</source>
<translation>ã“ã®ã‚¢ãƒ—リケーションã®æ›´æ–°å…ƒæƒ…å ±ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
@@ -411,7 +411,7 @@
</translation>
</message>
<message>
- <source>Could not download update source %1 from (&apos;%2&apos;)</source>
+ <source>Cannot download update source %1 from (&apos;%2&apos;)</source>
<translation>(&apos;%2&apos;) ã‹ã‚‰æ›´æ–°å…ƒ %1 をダウンロードã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
</context>
@@ -422,7 +422,7 @@
<translation>%1 ã«ç„¡åŠ¹ãªã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™: %2</translation>
</message>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>&quot;%1&quot; を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
@@ -434,14 +434,14 @@
<translation>ルートエレメント㫠%1 ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。&quot;UpdateSources&quot;を使用ã—ã¦ãã ã•ã„</translation>
</message>
<message>
- <source>Could not save changes to &quot;%1&quot;: %2</source>
+ <source>Cannot save changes to &quot;%1&quot;: %2</source>
<translation>&quot;%1&quot; ã¸ã®å¤‰æ›´ã‚’ä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
</context>
<context>
<name>KDUpdater::UpdatesInfoData</name>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>&quot;%1&quot; を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
@@ -480,7 +480,7 @@
<context>
<name>Lib7z::ExtractItemJob</name>
<message>
- <source>Could not list archive: QIODevice not set or already destroyed.</source>
+ <source>Cannot list archive: QIODevice not set or already destroyed.</source>
<translation>アーカイブã‹ã‚‰ãƒªã‚¹ãƒˆã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: QIODevice ãŒè¨­å®šã•ã‚Œã¦ã„ãªã„ã‹ã€æ—¢ã«ç ´æ£„ã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
</message>
<message>
@@ -499,7 +499,7 @@
<context>
<name>Lib7z::ListArchiveJob</name>
<message>
- <source>Could not list archive: QIODevice already destroyed.</source>
+ <source>Cannot list archive: QIODevice already destroyed.</source>
<translation>アーカイブã‹ã‚‰ãƒªã‚¹ãƒˆã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: QIODevice ãŒæ—¢ã«ç ´æ£„ã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
</message>
<message>
@@ -574,43 +574,43 @@
<translation>%1 ãƒã‚¤ãƒˆã®æ›¸ãè¾¼ã¿å¾Œã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>ファイル %1 を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>フォルダ %1 を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not create folder %1</source>
+ <source>Cannot create folder %1</source>
<translation>フォルダ %1 を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
- <source>Could not copy file from %1 to %2: %3</source>
+ <source>Cannot copy file from %1 to %2: %3</source>
<translation>ファイル %1 ã‚’ %2 ã«ã‚³ãƒ”ーã§ãã¾ã›ã‚“ã§ã—ãŸ: %3</translation>
</message>
<message>
- <source>Could not move file from %1 to %2: %3</source>
+ <source>Cannot move file from %1 to %2: %3</source>
<translation>ファイル %1 ã‚’ %2 ã¸ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ: %3</translation>
</message>
<message>
- <source>Could not create folder %1: %2</source>
+ <source>Cannot create folder %1: %2</source>
<translation>フォルダ %1 を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not open temporary file: %1</source>
+ <source>Cannot open temporary file: %1</source>
<translation>一時ファイルを開ã‘ã¾ã›ã‚“ã§ã—ãŸ: %1</translation>
</message>
<message>
- <source>Could not open temporary file for template %1: %2</source>
+ <source>Cannot open temporary file for template %1: %2</source>
<translation>テンプレート %1 用ã®ä¸€æ™‚ファイルを開ã‘ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not create temporary file</source>
+ <source>Cannot create temporary file</source>
<translation>一時ファイルを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
- <source>Could not retrieve property %1 for item %2</source>
+ <source>Cannot retrieve property %1 for item %2</source>
<translation>アイテム %2 ã‹ã‚‰ãƒ—ロパティ %1 ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
@@ -618,11 +618,11 @@
<translation>アイテム %2 ã®ãƒ—ロパティ %1 ã®åž‹ãŒ VT_FILETIME ã§ã¯ãªã %3 ã«ãªã£ã¦ã„ã¾ã™</translation>
</message>
<message>
- <source>Could not convert file time to local time</source>
+ <source>Cannot convert file time to local time</source>
<translation>ファイルã®æ™‚刻をローカルタイムã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
- <source>Could not convert local file time to system time</source>
+ <source>Cannot convert local file time to system time</source>
<translation>ローカルファイルã®æ™‚刻をシステムã®æ™‚刻ã¸å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
@@ -641,19 +641,19 @@
<context>
<name>QInstaller::Component</name>
<message>
- <source>Could not open the requested translation file &apos;%1&apos;.</source>
+ <source>Cannot open the requested translation file &apos;%1&apos;.</source>
<translation>è¦æ±‚ã•ã‚ŒãŸç¿»è¨³ãƒ•ã‚¡ã‚¤ãƒ« &apos;%1&apos; ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <source>Could not open the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>è¦æ±‚ã•ã‚ŒãŸ UI ファイル &apos;%1&apos; ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚エラー: %2</translation>
</message>
<message>
- <source>Could not load the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot load the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>è¦æ±‚ã•ã‚ŒãŸ UI ファイル &apos;%1&apos; をロードã§ãã¾ã›ã‚“ã§ã—ãŸã€‚エラー: %2</translation>
</message>
<message>
- <source>Could not open the requested license file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested license file &apos;%1&apos;. Error: %2</source>
<translation>è¦æ±‚ã•ã‚ŒãŸãƒ©ã‚¤ã‚»ãƒ³ã‚¹ãƒ•ã‚¡ã‚¤ãƒ« &apos;%1&apos; ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚エラー: %2</translation>
</message>
<message>
@@ -833,7 +833,7 @@
<translation>%0 ã«ç„¡åŠ¹ãªå¼•æ•°: ディレクトリãŒç„¡åŠ¹ã§ã™: %1 %2</translation>
</message>
<message>
- <source>Could not create %0</source>
+ <source>Cannot create %0</source>
<translation>%0 を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
@@ -841,11 +841,11 @@
<translation>%1 を上書ãã§ãã¾ã›ã‚“</translation>
</message>
<message>
- <source>Could not copy %0 to %1, error was: %3</source>
+ <source>Cannot copy %0 to %1, error was: %3</source>
<translation>%0 ã‚’ %1 ã«ã‚³ãƒ”ーã§ãã¾ã›ã‚“ã§ã—ãŸã€‚エラー: %3</translation>
</message>
<message>
- <source>Could not remove %0</source>
+ <source>Cannot remove %0</source>
<translation>%0 を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
</context>
@@ -864,11 +864,11 @@
<translation>%1 ã«ä¸Šæ›¸ãã§ãã¾ã›ã‚“</translation>
</message>
<message>
- <source>Could not write Desktop Entry at %1</source>
+ <source>Cannot write Desktop Entry at %1</source>
<translation>%1 ã¸ãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—エントリーを書ã込むã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>ファイル %1 ã‚’ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
</context>
@@ -883,22 +883,22 @@
<translation>2個</translation>
</message>
<message>
- <source>Could not create link from %1 to %2.</source>
+ <source>Cannot create link from %1 to %2.</source>
<translation>%1 ã‹ã‚‰ %2 ã¸ã®ãƒªãƒ³ã‚¯ã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <source>Could not remove link from %1 to %2.</source>
+ <source>Cannot remove link from %1 to %2.</source>
<translation>%1 ã‹ã‚‰ %2 ã¸ã®ãƒªãƒ³ã‚¯ã‚’削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
</context>
<context>
<name>QInstaller::CreateLocalRepositoryOperation</name>
<message>
- <source>Could not set file permissions %1!</source>
+ <source>Cannot set file permissions %1!</source>
<translation>ファイル %1 ã«ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™ã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ!</translation>
</message>
<message>
- <source>Could not move file %1 to %2. Error: %3</source>
+ <source>Cannot move file %1 to %2. Error: %3</source>
<translation>ファイル %1 ã‚’ %2 ã¸ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚エラー: %3</translation>
</message>
<message>
@@ -914,19 +914,19 @@
<translation>インストーラã¯ã‚ªãƒ•ãƒ©ã‚¤ãƒ³ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™: %1</translation>
</message>
<message>
- <source>Could not open file: %1</source>
+ <source>Cannot open file: %1</source>
<translation>ファイルを開ã‘ã¾ã›ã‚“ã§ã—ãŸ: %1</translation>
</message>
<message>
- <source>Could not read: %1. Error: %2</source>
+ <source>Cannot read: %1. Error: %2</source>
<translation>%1 を読ã¿è¾¼ã¿ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚エラー: %2</translation>
</message>
<message>
- <source>Could not open file: %1. Error: %2</source>
+ <source>Cannot open file: %1. Error: %2</source>
<translation>ファイル %1 ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚エラー: %2</translation>
</message>
<message>
- <source>Could not create target dir: %1.</source>
+ <source>Cannot create target dir: %1.</source>
<translation>ターゲットディレクトリを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %1</translation>
</message>
<message>
@@ -938,7 +938,7 @@
<translation>ファイルを削除ã—ã¦ã„ã¾ã™: %0</translation>
</message>
<message>
- <source>Could not remove %0.</source>
+ <source>Cannot remove %0.</source>
<translation>%0 を削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
@@ -946,7 +946,7 @@
<translation>ディレクトリ %1 を削除ã§ãã¾ã›ã‚“: %2</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>ファイル %1 を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
</context>
@@ -965,11 +965,11 @@
<translation> (オプション: &apos;workingDirectory=...&apos;, &apos;iconPath=...&apos;, &apos;iconId=...&apos;) </translation>
</message>
<message>
- <source>Could not create folder %1: %2.</source>
+ <source>Cannot create folder %1: %2.</source>
<translation>フォルダ %1 を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not create link %1: %2</source>
+ <source>Cannot create link %1: %2</source>
<translation>リンク %1 を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
@@ -996,15 +996,15 @@
<translation>ダウンロード中ã®ãƒãƒƒã‚·ãƒ¥å€¤ã®ç…§åˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã“ã‚Œã¯ä¸€æ™‚çš„ãªã‚¨ãƒ©ãƒ¼ã§ã™ã®ã§ã€å†è©¦è¡Œã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <source>Could not verify Hash</source>
+ <source>Cannot verify Hash</source>
<translation>ãƒãƒƒã‚·ãƒ¥å€¤ã®ç…§åˆãŒã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
- <source>Could not download archive: %1 : %2</source>
+ <source>Cannot download archive: %1 : %2</source>
<translation>アーカイブ %1 をダウンロードã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not fetch archives: %1
+ <source>Cannot fetch archives: %1
Error while loading %2</source>
<translation>アーカイブをå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %1
%2 ã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ</translation>
@@ -1014,7 +1014,7 @@ Error while loading %2</source>
<translation>ã“ã®ã‚¹ã‚­ãƒ¼ãƒ ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã¾ã›ã‚“: %1 (%2)</translation>
</message>
<message>
- <source>Could not find component for: %1.</source>
+ <source>Cannot find component for: %1.</source>
<translation>コンãƒãƒ¼ãƒãƒ³ãƒˆ %1 を見ã¤ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
@@ -1033,11 +1033,11 @@ Error while loading %2</source>
<translation>å°‘ãªãã¨ã‚‚1個</translation>
</message>
<message>
- <source>Execution failed: Could not start detached: &quot;%1&quot;</source>
+ <source>Execution failed: Cannot start detached: &quot;%1&quot;</source>
<translation>実行ã«å¤±æ•—ã—ã¾ã—ãŸ: &quot;%1&quot; をデタッãƒã—ã¦èµ·å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
- <source>Execution failed: Could not start: &quot;%1&quot;(%2)</source>
+ <source>Execution failed: Cannot start: &quot;%1&quot;(%2)</source>
<translation>実行ã«å¤±æ•—ã—ã¾ã—ãŸ: &quot;%1&quot; ã‚’èµ·å‹•ã§ãã¾ã›ã‚“ã§ã—㟠(%2)</translation>
</message>
<message>
@@ -1074,7 +1074,7 @@ Error while loading %2</source>
<context>
<name>QInstaller::ExtractArchiveOperation::Runnable</name>
<message>
- <source>Could not open %1 for reading: %2.</source>
+ <source>Cannot open %1 for reading: %2.</source>
<translation>読ã¿è¾¼ã¿ç”¨ã« %1 ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
@@ -1151,7 +1151,7 @@ Error while loading %2</source>
<translation>無効ãªå¼•æ•°: 空ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’ソースã«æŒ‡å®šã§ãã¾ã›ã‚“。</translation>
</message>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>ファイル %1 ã‚’ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
@@ -1163,7 +1163,7 @@ Error while loading %2</source>
<translation>ファイル %1 ã¸ã®ã‚³ãƒ”ーã«å¤±æ•—ã—ã¾ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not create folder at %1: %2</source>
+ <source>Cannot create folder at %1: %2</source>
<translation>%1 ã«ãƒ•ã‚©ãƒ«ãƒ€ã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
</context>
@@ -1373,7 +1373,7 @@ Downloading packages...</source>
<translation>フォーマットエラー</translation>
</message>
<message>
- <source>Could not write installer configuration to %1: %2</source>
+ <source>Cannot write installer configuration to %1: %2</source>
<translation>インストーラã®è¨­å®šã‚’ %1 ã«æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
@@ -1473,7 +1473,7 @@ Installing component %1</source>
<translation>未知ã®ã‚¨ãƒ©ãƒ¼</translation>
</message>
<message>
- <source>Could not retrieve remote tree: %1.</source>
+ <source>Cannot retrieve remote tree: %1.</source>
<translation>リモートã®ãƒ„リーをå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %1</translation>
</message>
<message>
@@ -1481,15 +1481,15 @@ Installing component %1</source>
<translation>å³è¨˜ã‹ã‚‰ã®ãƒ‘ッケージã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ: %1</translation>
</message>
<message>
- <source>Could not retrieve meta information: %1</source>
+ <source>Cannot retrieve meta information: %1</source>
<translation>メタ情報をå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %1</translation>
</message>
<message>
- <source>Could not add temporary update source information.</source>
+ <source>Cannot add temporary update source information.</source>
<translation>一時的ãªæ›´æ–°å…ƒæƒ…報を追加ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <source>Could not find any update source information.</source>
+ <source>Cannot find any update source information.</source>
<translation>更新元情報ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
@@ -1509,19 +1509,19 @@ Installing component %1</source>
<translation>メンテナンスツールã¯ãƒãƒ³ãƒ‰ãƒ«ã•ã‚Œã¦ã„ã¾ã›ã‚“</translation>
</message>
<message>
- <source>Could not write maintenance tool data to %1: %2</source>
+ <source>Cannot write maintenance tool data to %1: %2</source>
<translation>メンテナンスツールã®ãƒ‡ãƒ¼ã‚¿ã‚’ %1 ã«æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not remove data file &apos;%1&apos;: %2</source>
+ <source>Cannot remove data file &apos;%1&apos;: %2</source>
<translation>データファイル &apos;%1&apos; を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not write maintenance tool to %1: %2</source>
+ <source>Cannot write maintenance tool to %1: %2</source>
<translation>メンテナンスツールを %1 ã«æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not write maintenance tool binary data to %1: %2</source>
+ <source>Cannot write maintenance tool binary data to %1: %2</source>
<translation>メンテナンスツールã®ãƒã‚¤ãƒŠãƒªãƒ‡ãƒ¼ã‚¿ã‚’ %1 ã«æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
@@ -1747,7 +1747,7 @@ Please copy the installer to a local drive</source>
<context>
<name>QInstaller::ScriptEngine</name>
<message>
- <source>Could not open the requested script file at %1: %2.</source>
+ <source>Cannot open the requested script file at %1: %2.</source>
<translation>è¦æ±‚ã•ã‚ŒãŸã‚¹ã‚¯ãƒªãƒ—トファイル %1 ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
@@ -1920,7 +1920,7 @@ Do you want to continue?</source>
<translation>テスト中ã«ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆãŒç™ºç”Ÿã—ã¾ã—ãŸ: &apos;%1&apos;</translation>
</message>
<message>
- <source>Could not parse Updates.xml! Error: %1.</source>
+ <source>Cannot parse Updates.xml! Error: %1.</source>
<translation>Updates.xml を解æžã§ãã¾ã›ã‚“ã§ã—ãŸ! エラー: %1</translation>
</message>
<message>
@@ -1950,7 +1950,7 @@ Do you want to continue?</source>
<context>
<name>Settings</name>
<message>
- <source>Could not open settings file %1 for reading: %2</source>
+ <source>Cannot open settings file %1 for reading: %2</source>
<translation>読ã¿è¾¼ã¿ç”¨ã«è¨­å®šãƒ•ã‚¡ã‚¤ãƒ« %1 ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
</context>
@@ -2126,11 +2126,11 @@ Do you want to continue?</source>
<context>
<name>BinaryLayout</name>
<message>
- <source>Could not seek to %1 to read the embedded meta data count.</source>
+ <source>Cannot seek to %1 to read the embedded meta data count.</source>
<translation>埋ã‚è¾¼ã¾ã‚ŒãŸãƒ¡ã‚¿ãƒ‡ãƒ¼ã‚¿æ•°ã‚’読ã¿è¾¼ã‚€ãŸã‚ã« %1 ã«ã‚·ãƒ¼ã‚¯å‡ºæ¥ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection segment.</source>
+ <source>Cannot seek to %1 to read the resource collection segment.</source>
<translation>リソースコレクションセグメントを読ã¿è¾¼ã‚€ãŸã‚ã« %1 ã«ã‚·ãƒ¼ã‚¯å‡ºæ¥ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
@@ -2141,22 +2141,22 @@ Do you want to continue?</source>
<context>
<name>BinaryContent</name>
<message>
- <source>Could not seek to %1 to read the operation data.</source>
+ <source>Cannot seek to %1 to read the operation data.</source>
<translation>æ“作データを読ã¿è¾¼ã‚€ãŸã‚ã« %1 ã«ã‚·ãƒ¼ã‚¯å‡ºæ¥ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection block.</source>
+ <source>Cannot seek to %1 to read the resource collection block.</source>
<translation>リソースコレクションブロックを読ã¿è¾¼ã‚€ãŸã‚ã« %1 ã«ã‚·ãƒ¼ã‚¯å‡ºæ¥ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <source>Could not open meta resource. Error: %1</source>
+ <source>Cannot open meta resource. Error: %1</source>
<translation>メタリソースを開ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚エラー: %1</translation>
</message>
</context>
<context>
<name>QInstaller::Resource</name>
<message>
- <source>Could not open Resource &apos;%1&apos; read-only.</source>
+ <source>Cannot open Resource &apos;%1&apos; read-only.</source>
<translation>読ã¿è¾¼ã¿å°‚用ã§ãƒªã‚½ãƒ¼ã‚¹ %1 ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
@@ -2171,7 +2171,7 @@ Do you want to continue?</source>
<context>
<name>ResourceCollectionManager</name>
<message>
- <source>Could not open resource %1: %2</source>
+ <source>Cannot open resource %1: %2</source>
<translation>リソース %1 ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
</context>
@@ -2182,11 +2182,11 @@ Do you want to continue?</source>
<translation>タスクアイテム数ãŒç„¡åŠ¹ã§ã™ã€‚</translation>
</message>
<message>
- <source>Could not open source &apos;%1&apos; for read. Error: %2.</source>
+ <source>Cannot open source &apos;%1&apos; for read. Error: %2.</source>
<translation>読ã¿è¾¼ã¿ç”¨ã«ã‚½ãƒ¼ã‚¹ &apos;%1&apos; ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚エラー: %2。</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<translation>書ãè¾¼ã¿ç”¨ã«å¯¾è±¡ &apos;%1&apos; ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚エラー: %2</translation>
</message>
<message>
@@ -2238,7 +2238,7 @@ Do you want to continue?</source>
<translation>対象ファイル &apos;%1&apos; ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™ãŒã€ãƒ•ã‚¡ã‚¤ãƒ«ã§ã¯ã‚ã‚Šã¾ã›ã‚“。</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<extracomment>%2 is a sentence describing the error</extracomment>
<translation>対象 &apos;%1&apos; ã¯æ›¸ãè¾¼ã¿ç”¨ã«é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚エラー: %2。</translation>
</message>
@@ -2261,7 +2261,7 @@ Do you want to continue?</source>
<translation>レジストリã®ãƒ‘ス %1 ã«æ›¸ãè¾¼ã¿ã§ãã¾ã›ã‚“</translation>
</message>
<message>
- <source>Could not write to registry path %1</source>
+ <source>Cannot write to registry path %1</source>
<translation>レジストリã®ãƒ‘ス %1 ã¸æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
@@ -2276,7 +2276,7 @@ Do you want to continue?</source>
<translation>引数ã®æ•°ãŒä¸€è‡´ã—ã¾ã›ã‚“: 一ã¤ã®ã¿æŒ‡å®šã—ã¦ãã ã•ã„</translation>
</message>
<message>
- <source>Could not get package manager core.</source>
+ <source>Cannot get package manager core.</source>
<translation>パッケージマãƒãƒ¼ã‚¸ãƒ£ã®ã‚³ã‚¢ã‚’å–å¾—ã§ãã¾ã›ã‚“。</translation>
</message>
<message>
@@ -2322,7 +2322,7 @@ Do you want to continue?</source>
<translation>パスãŒå­˜åœ¨ã—ã¦ã„ã¾ã™ãŒã€ãƒ•ã‚©ãƒ«ãƒ€ã§ã¯ã‚ã‚Šã¾ã›ã‚“: %1</translation>
</message>
<message>
- <source>Could not create folder: %1</source>
+ <source>Cannot create folder: %1</source>
<translation>フォルダを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %1</translation>
</message>
</context>
@@ -2336,15 +2336,15 @@ Do you want to continue?</source>
<context>
<name>OpenArchiveInfo</name>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>コーデックをロードã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>デフォルトフォーマットをå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
- <source>Could not open archive</source>
+ <source>Cannot open archive</source>
<translation>アーカイブを開ã‘ã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
@@ -2355,11 +2355,11 @@ Do you want to continue?</source>
<context>
<name>Lib7z</name>
<message>
- <source>Could not retrieve number of items in archive</source>
+ <source>Cannot retrieve number of items in archive</source>
<translation>アーカイブ内ã®ã‚¢ã‚¤ãƒ†ãƒ æ•°ãŒå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>アーカイブアイテム %1 ã®ãƒ‘スãŒå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
@@ -2379,15 +2379,15 @@ Do you want to continue?</source>
<translation>エラー: %1</translation>
</message>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>コーデックをロードã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>デフォルトフォーマットをå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
- <source>Could not create archive %1. %2</source>
+ <source>Cannot create archive %1. %2</source>
<translation>アーカイブ %1 ãŒä½œæˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
@@ -2399,34 +2399,34 @@ Do you want to continue?</source>
<translation>アイテムã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ %1 ãŒç¯„囲外ã§ã™ [0, %2]</translation>
</message>
<message>
- <source>Could not create output file for writing: %1</source>
+ <source>Cannot create output file for writing: %1</source>
<translation>書ãè¾¼ã¿ç”¨ã«å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %1</translation>
</message>
</context>
<context>
<name>ExtractCallbackImpl</name>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>アーカイブアイテム %1 ã®ãƒ‘スãŒå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
</message>
<message>
- <source>Could not remove already existing symlink. %1</source>
+ <source>Cannot remove already existing symlink. %1</source>
<translation>ã™ã§ã«å­˜åœ¨ã™ã‚‹ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ã¯å‰Šé™¤ã§ãã¾ã›ã‚“: %1</translation>
</message>
<message>
- <source>Could not open file: %1 (%2)</source>
+ <source>Cannot open file: %1 (%2)</source>
<translation>ファイルãŒé–‹ã‘ã¾ã›ã‚“: %1 (%2)</translation>
</message>
<message>
- <source>Could not create symlink at &apos;%1&apos;. Another one is already existing.</source>
+ <source>Cannot create symlink at &apos;%1&apos;. Another one is already existing.</source>
<translation>&apos;%1&apos; ã«ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ä»–ã®ãƒªãƒ³ã‚¯ãŒã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <source>Could not read symlink target from file &apos;%1&apos;.</source>
+ <source>Cannot read symlink target from file &apos;%1&apos;.</source>
<translation>シンボリックリンクã®å‚照先ã®ãƒ•ã‚¡ã‚¤ãƒ« &apos;%1&apos; を読ã¿è¾¼ã¿ç”¨ã«é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <source>Could not create symlink at %1. %2</source>
+ <source>Cannot create symlink at %1. %2</source>
<translation>%1 ã«ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ %2</translation>
</message>
</context>
@@ -2481,7 +2481,7 @@ Do you want to continue?</source>
<translation>%1 ã®å±•é–‹ä¸­ã«æœªçŸ¥ã®ä¾‹å¤–ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <source>Could not open %1 for reading. Error: %2</source>
+ <source>Cannot open %1 for reading. Error: %2</source>
<translation>読ã¿è¾¼ã¿ç”¨ã« %1 ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚エラー: %2</translation>
</message>
</context>
@@ -2551,7 +2551,7 @@ Do you want to continue?</source>
<translation>最åˆã®å¼•æ•°ã¯ &apos;linux&apos;, &apos;mac&apos;, &apos;windows&apos; ã®ã„ãšã‚Œã‹ã‚’指定ã—ã¦ãã ã•ã„。ãれ以外ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。</translation>
</message>
<message>
- <source>Could not find the needed QmakeOutputInstallerKey(%1) value on the installer object. The ConsumeOutput operation on the valid qmake needs to be called first.</source>
+ <source>Cannot find the needed QmakeOutputInstallerKey(%1) value on the installer object. The ConsumeOutput operation on the valid qmake needs to be called first.</source>
<translation>インストーラã«å¿…è¦ãª QmakeOutputInstallerKey(%1) ã®å€¤ã‚’見ã¤ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚é©åˆ‡ãª qmake 㧠ConsumeOutput æ“作を最åˆã«å®Ÿè¡Œã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚</translation>
</message>
<message>
@@ -2595,11 +2595,11 @@ Qt ã®ãƒã‚¤ãƒŠãƒªã«ãƒ‘ッãƒã‚’é©ç”¨ã—よã†ã¨ã—ã¾ã—ãŸãŒã€Qt ã®ä»–ã
<context>
<name>RemoteClient</name>
<message>
- <source>Could not get authorization.</source>
+ <source>Cannot get authorization.</source>
<translation>èªè¨¼ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <source>Could not get authorization that is needed for continuing the installation.
+ <source>Cannot get authorization that is needed for continuing the installation.
Either abort the installation or use the fallback solution by running
%1
@@ -2614,33 +2614,33 @@ as root and then clicking OK.</source>
<context>
<name>QInstaller::RemoteObject</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>コマンドをé€ä¿¡ã—ãŸå¾Œã€ã™ã¹ã¦ã®ãƒ‡ãƒ¼ã‚¿ã‚’読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %1。想定ãƒã‚¤ãƒˆæ•°: %2 ã€å—ä¿¡ãƒã‚¤ãƒˆæ•°: %3。エラー: %4</translation>
</message>
</context>
<context>
<name>QInstaller::RemoteServerConnection</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>コマンドをé€ä¿¡ã—ãŸå¾Œã€ã™ã¹ã¦ã®ãƒ‡ãƒ¼ã‚¿ã‚’読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %1。想定ãƒã‚¤ãƒˆæ•°: %2 ã€å—ä¿¡ãƒã‚¤ãƒˆæ•°: %3。エラー: %4</translation>
</message>
</context>
<context>
- <name>KDLockFile</name>
+ <name>LockFile</name>
<message>
- <source>Could not create lock file &apos;%1&apos;: %2</source>
+ <source>Cannot create lock file &apos;%1&apos;: %2</source>
<translation>ロックファイル &apos;%1&apos; を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not write PID to lock file &apos;%1&apos;: %2</source>
+ <source>Cannot write PID to lock file &apos;%1&apos;: %2</source>
<translation>ロックファイル &apos;%1&apos; ã« PID を書ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not obtain the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot obtain the lock for file &apos;%1&apos;: %2</source>
<translation>ファイル &apos;%1&apos; をロックã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
<message>
- <source>Could not release the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot release the lock for file &apos;%1&apos;: %2</source>
<translation>ファイル &apos;%1&apos; ã®ãƒ­ãƒƒã‚¯ã‚’解除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %2</translation>
</message>
</context>
diff --git a/src/sdk/translations/pl.ts b/src/sdk/translations/pl.ts
index 46b173d28..98af6f62d 100644
--- a/src/sdk/translations/pl.ts
+++ b/src/sdk/translations/pl.ts
@@ -15,26 +15,26 @@
<context>
<name>BinaryContent</name>
<message>
- <source>Could not seek to %1 to read the operation data.</source>
+ <source>Cannot seek to %1 to read the operation data.</source>
<translation>Nie można przesunąć wskaźnika pozycji pliku do %1 w celu odczytania danych operacji.</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection block.</source>
+ <source>Cannot seek to %1 to read the resource collection block.</source>
<translation>Nie można przesunąć wskaźnika pozycji pliku do %1 w celu odczytania bloku kolekcji zasobów.</translation>
</message>
<message>
- <source>Could not open meta resource. Error: %1</source>
+ <source>Cannot open meta resource. Error: %1</source>
<translation>Nie można otworzyć metazasobów. Błąd: %1</translation>
</message>
</context>
<context>
<name>BinaryLayout</name>
<message>
- <source>Could not seek to %1 to read the embedded meta data count.</source>
+ <source>Cannot seek to %1 to read the embedded meta data count.</source>
<translation>Nie można przesunąć wskaźnika pozycji pliku do %1 w celu odczytania ilości danych wbudowanych.</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection segment.</source>
+ <source>Cannot seek to %1 to read the resource collection segment.</source>
<translation>Nie można przesunąć wskaźnika pozycji pliku do %1 w celu odczytania segmentu z kolekcją zasobów.</translation>
</message>
<message>
@@ -72,34 +72,34 @@
<translation>Isniejąca ścieżka %1 nie jest katalogiem</translation>
</message>
<message>
- <source>Could not create folder: %1</source>
+ <source>Cannot create folder: %1</source>
<translation>Nie można utworzyć katalogu: %1</translation>
</message>
</context>
<context>
<name>ExtractCallbackImpl</name>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>Nie można odczytać ścieżki elementu archiwum %1</translation>
</message>
<message>
- <source>Could not remove already existing symlink. %1</source>
+ <source>Cannot remove already existing symlink. %1</source>
<translation>Nie można usunąc istniejącego dowiązania symbolicznego %1</translation>
</message>
<message>
- <source>Could not open file: %1 (%2)</source>
+ <source>Cannot open file: %1 (%2)</source>
<translation>Nie można otworzyć pliku %1: %2</translation>
</message>
<message>
- <source>Could not create symlink at &apos;%1&apos;. Another one is already existing.</source>
+ <source>Cannot create symlink at &apos;%1&apos;. Another one is already existing.</source>
<translation>Nie można utworzyć dowiązania symbolicznego &quot;%1&quot;. Istnieje już dowiązanie do innego pliku.</translation>
</message>
<message>
- <source>Could not read symlink target from file &apos;%1&apos;.</source>
+ <source>Cannot read symlink target from file &apos;%1&apos;.</source>
<translation>Nie można odczytać docelowego pliku &quot;%1&quot; wynikającego z dowiązania.</translation>
</message>
<message>
- <source>Could not create symlink at %1. %2</source>
+ <source>Cannot create symlink at %1. %2</source>
<translation>Nie można utworzyć dowiązania symbolicznego &quot;%1&quot;: %2</translation>
</message>
</context>
@@ -131,28 +131,28 @@
</message>
</context>
<context>
- <name>KDJob</name>
+ <name>Job</name>
<message>
<source>Canceled</source>
<translation>Anulowano</translation>
</message>
</context>
<context>
- <name>KDLockFile</name>
+ <name>LockFile</name>
<message>
- <source>Could not create lock file &apos;%1&apos;: %2</source>
+ <source>Cannot create lock file &apos;%1&apos;: %2</source>
<translation>Nie można zablokować pliku &quot;%1&quot;: %2</translation>
</message>
<message>
- <source>Could not write PID to lock file &apos;%1&apos;: %2</source>
+ <source>Cannot write PID to lock file &apos;%1&apos;: %2</source>
<translation>Nie można zapisać PID w celu zablokowania pliku &quot;%1&quot;: %2</translation>
</message>
<message>
- <source>Could not obtain the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot obtain the lock for file &apos;%1&apos;: %2</source>
<translation>Nie można uzyskać wyłączności dostępu do pliku &quot;%1&quot;: %2</translation>
</message>
<message>
- <source>Could not release the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot release the lock for file &apos;%1&apos;: %2</source>
<translation>Nie można odblokować pliku &quot;%1&quot;: %2</translation>
</message>
</context>
@@ -171,7 +171,7 @@
<translation>dokładnie 2</translation>
</message>
<message>
- <source>Could not open file &apos;%1&apos; for writing: %2</source>
+ <source>Cannot open file &apos;%1&apos; for writing: %2</source>
<translation>Nie można otworzyć pliku &quot;%1&quot; do zapisu: %2</translation>
</message>
<message>
@@ -179,18 +179,18 @@
<translation>Nie można odnaleźć kopii zapasowej pliku %1.</translation>
</message>
<message>
- <source>Could not restore backup file for %1.</source>
+ <source>Cannot restore backup file for %1.</source>
<translation>Nie można przywrócić kopii zapasowej pliku %1.</translation>
</message>
<message>
- <source>Could not restore backup file for %1: %2</source>
+ <source>Cannot restore backup file for %1: %2</source>
<translation>Nie można przywrócić kopii zapasowej pliku %1: %2</translation>
</message>
</context>
<context>
<name>KDUpdater::CopyOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>Nie można utworzyć kopii zapasowej pliku %1.</translation>
</message>
<message>
@@ -198,23 +198,23 @@
<translation>Niewłaściwe argumenty: ilość przekazanych argumentów %1, oczekiwano 2.</translation>
</message>
<message>
- <source>Could not copy a non-existent file: %1</source>
+ <source>Cannot copy a non-existent file: %1</source>
<translation>Nie można skopiować nieistniejącego pliku: %1</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>Nie można usunąć pliku docelowego %1: %2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>Nie można skopiować pliku z %1 do %2: %3</translation>
</message>
<message>
- <source>Could not delete file %1: %2</source>
+ <source>Cannot delete file %1: %2</source>
<translation>Nie można usunąć pliku %1: %2</translation>
</message>
<message>
- <source>Could not restore backup file into %1: %2</source>
+ <source>Cannot restore backup file into %1: %2</source>
<translation>Nie można przywrócić kopii zapasowej pliku %1: %2</translation>
</message>
</context>
@@ -307,7 +307,7 @@
<translation>Nie można pobrać %1: błąd zapisu do %2: %3</translation>
</message>
<message>
- <source>Cannot download %1: Could not create %2: %3</source>
+ <source>Cannot download %1: Cannot create %2: %3</source>
<translation>Nie można pobrać %1: błąd tworzenia %2: %3</translation>
</message>
<message>
@@ -361,7 +361,7 @@
<translation>Niewłaściwe argumenty: ilość przekazanych argumentów %1, oczekiwano 1.</translation>
</message>
<message>
- <source>Could not create folder %1: Unknown error.</source>
+ <source>Cannot create folder %1: Unknown error.</source>
<translation>Nie można utworzyć katalogu %1: Nieznany błąd.</translation>
</message>
<message>
@@ -372,7 +372,7 @@
<context>
<name>KDUpdater::MoveOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>Nie można utworzyć kopii zapasowej pliku %1.</translation>
</message>
<message>
@@ -380,11 +380,11 @@
<translation>Niewłaściwe argumenty: ilość przekazanych argumentów %1, oczekiwano 2.</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>Nie można usunąc pliku docelowego %1: %2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>Nie można skopiować pliku z %1 do %2: %3</translation>
</message>
<message>
@@ -411,7 +411,7 @@
<translation>Plik %1 nie istnieje.</translation>
</message>
<message>
- <source>Could not open %1.</source>
+ <source>Cannot open %1.</source>
<translation>Nie można otworzyć %1.</translation>
</message>
<message>
@@ -434,11 +434,11 @@
<translation>Niewłaściwe argumenty: ilość przekazanych argumentów %1, oczekiwano 2.</translation>
</message>
<message>
- <source>Could not open file %1 for reading: %2</source>
+ <source>Cannot open file %1 for reading: %2</source>
<translation>Nie można otworzyć pliku %1 do odczytu: %2</translation>
</message>
<message>
- <source>Could not open file %1 for writing: %2</source>
+ <source>Cannot open file %1 for writing: %2</source>
<translation>Nie można otworzyć pliku %1 do zapisu: %2</translation>
</message>
<message>
@@ -457,7 +457,7 @@
<context>
<name>KDUpdater::ResourceFileDownloader</name>
<message>
- <source>Could not read resource file &quot;%1&quot;. Reason:</source>
+ <source>Cannot read resource file &quot;%1&quot;. Reason:</source>
<translation>Nie można odczytać pliku z zasobami &quot;%1&quot;. Powód:</translation>
</message>
</context>
@@ -468,11 +468,11 @@
<translation>Niewłaściwe argumenty: ilość przekazanych argumentów %1, oczekiwano 1.</translation>
</message>
<message>
- <source>Could not remove folder %1: The folder does not exist.</source>
+ <source>Cannot remove folder %1: The folder does not exist.</source>
<translation>Nie można usunąć katalogu %1: Katalog nie istnieje.</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>Nie można usunąć katalogu %1: %2</translation>
</message>
<message>
@@ -514,11 +514,11 @@
<context>
<name>KDUpdater::UpdateFinder</name>
<message>
- <source>Could not access the package information of this application.</source>
+ <source>Cannot access the package information of this application.</source>
<translation>Brak dostępu do informacji o pakiecie dla tej aplikacji.</translation>
</message>
<message>
- <source>Could not access the update sources information of this application.</source>
+ <source>Cannot access the update sources information of this application.</source>
<translation>Brak dostępu do informacji o źródłach aktualizacji dla tej aplikacji.</translation>
</message>
<message numerus="yes">
@@ -534,7 +534,7 @@
<translation>Pobieranie Updates.xml ze źródeł uaktualnień.</translation>
</message>
<message>
- <source>Could not download update source %1 from (&apos;%2&apos;)</source>
+ <source>Cannot download update source %1 from (&apos;%2&apos;)</source>
<translation>Nie można pobrać źródła uaktualnienia %1 z (&quot;%2&quot;)</translation>
</message>
<message>
@@ -557,7 +557,7 @@
<translation>Niepoprawna zawartość %1: %2</translation>
</message>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>Nie można odczytać &quot;%1&quot;</translation>
</message>
<message>
@@ -569,7 +569,7 @@
<translation>Nieoczekiwany główny element %1, oczekiwano &lt;UpdateSources&gt;</translation>
</message>
<message>
- <source>Could not save changes to &quot;%1&quot;: %2</source>
+ <source>Cannot save changes to &quot;%1&quot;: %2</source>
<translation>Nie można zachować zmian w &quot;%1&quot;: %2</translation>
</message>
</context>
@@ -580,7 +580,7 @@
<translation>Niepoprawna zawartość Updates.xml: %1</translation>
</message>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>Nie można odczytać &quot;%1&quot;</translation>
</message>
<message>
@@ -615,11 +615,11 @@
<context>
<name>Lib7z</name>
<message>
- <source>Could not retrieve number of items in archive</source>
+ <source>Cannot retrieve number of items in archive</source>
<translation>Nie można odczytać liczby elementów w archiwum</translation>
</message>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>Nie można odczytać ścieżki elementu archiwum %1</translation>
</message>
<message>
@@ -639,15 +639,15 @@
<translation>BÅ‚Ä…d: %1</translation>
</message>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>Nie można załadować kodeków</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>Nie można odczytać domyślnego formatu</translation>
</message>
<message>
- <source>Could not create archive %1. %2</source>
+ <source>Cannot create archive %1. %2</source>
<translation>Nie można utworzyć archiwum %1. %2</translation>
</message>
<message>
@@ -659,14 +659,14 @@
<translation>Indeks elementu %1 poza zakresem [0, %2]</translation>
</message>
<message>
- <source>Could not create output file for writing: %1</source>
+ <source>Cannot create output file for writing: %1</source>
<translation>Nie można otworzyć pliku wyjściowego do zapisu: %1</translation>
</message>
</context>
<context>
<name>Lib7z::ExtractItemJob</name>
<message>
- <source>Could not list archive: QIODevice not set or already destroyed.</source>
+ <source>Cannot list archive: QIODevice not set or already destroyed.</source>
<translation>Nie można uzyskać listy zawartości archiwum: nie ustawiono QIODevice lub został on już zlikwidowany.</translation>
</message>
<message>
@@ -685,7 +685,7 @@
<context>
<name>Lib7z::ListArchiveJob</name>
<message>
- <source>Could not list archive: QIODevice already destroyed.</source>
+ <source>Cannot list archive: QIODevice already destroyed.</source>
<translation>Nie można uzyskać listy zawartości archiwum: QIODevice został już zlikwidowany.</translation>
</message>
<message>
@@ -700,15 +700,15 @@
<context>
<name>OpenArchiveInfo</name>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>Nie można załadować kodeków</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>Nie można odczytać domyślnego formatu</translation>
</message>
<message>
- <source>Could not open archive</source>
+ <source>Cannot open archive</source>
<translation>Nie można otworzyć archiwum</translation>
</message>
<message>
@@ -786,43 +786,43 @@
<translation>YiB</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>Nie można usunąć pliku %1: %2</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>Nie można usunąć katalogu %1: %2</translation>
</message>
<message>
- <source>Could not create folder %1</source>
+ <source>Cannot create folder %1</source>
<translation>Nie można utworzyć katalogu %1</translation>
</message>
<message>
- <source>Could not copy file from %1 to %2: %3</source>
+ <source>Cannot copy file from %1 to %2: %3</source>
<translation>Nie można skopiować pliku z %1 do %2: %3</translation>
</message>
<message>
- <source>Could not move file from %1 to %2: %3</source>
+ <source>Cannot move file from %1 to %2: %3</source>
<translation>Nie można przenieść pliku z %1 do %2: %3</translation>
</message>
<message>
- <source>Could not create folder %1: %2</source>
+ <source>Cannot create folder %1: %2</source>
<translation>Nie można utworzyć katalogu %1: %2</translation>
</message>
<message>
- <source>Could not open temporary file: %1</source>
+ <source>Cannot open temporary file: %1</source>
<translation>Nie można otworzyć pliku tymczasowego: %1</translation>
</message>
<message>
- <source>Could not open temporary file for template %1: %2</source>
+ <source>Cannot open temporary file for template %1: %2</source>
<translation>Nie można otworzyć pliku tymczasowego dla szablonu %1: %2</translation>
</message>
<message>
- <source>Could not create temporary file</source>
+ <source>Cannot create temporary file</source>
<translation>Nie można utworzyć pliku tymczasowego</translation>
</message>
<message>
- <source>Could not retrieve property %1 for item %2</source>
+ <source>Cannot retrieve property %1 for item %2</source>
<translation>Nie można pobrać właściwości %1 z elementu %2</translation>
</message>
<message>
@@ -830,11 +830,11 @@
<translation>Właściwość %1 elementu %2 nie jest typu VT_FILETIME, tylko %3</translation>
</message>
<message>
- <source>Could not convert file time to local time</source>
+ <source>Cannot convert file time to local time</source>
<translation>Nie można skonwertować czasu zapisu pliku do czasu lokalnego</translation>
</message>
<message>
- <source>Could not convert local file time to system time</source>
+ <source>Cannot convert local file time to system time</source>
<translation>Nie można skonwertować lokalnego czasu do czasu systemowego</translation>
</message>
<message>
@@ -857,19 +857,19 @@
<translation>Komponenty nie mogą posiadać dzieci w trybie aktualizacji.</translation>
</message>
<message>
- <source>Could not open the requested translation file &apos;%1&apos;.</source>
+ <source>Cannot open the requested translation file &apos;%1&apos;.</source>
<translation>Nie można otworzyć wymaganego pliku z tłumaczeniami &quot;%1&quot;.</translation>
</message>
<message>
- <source>Could not open the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>Nie można otworzyć wymaganego pliku UI &quot;%1&quot;. Błąd: %2</translation>
</message>
<message>
- <source>Could not load the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot load the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>Nie można załadować wymaganego pliku UI &quot;%1&quot;. Błąd: %2</translation>
</message>
<message>
- <source>Could not open the requested license file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested license file &apos;%1&apos;. Error: %2</source>
<translation>Nie można otworzyć wymaganego pliku z licencją &quot;%1&quot;. Błąd: %2</translation>
</message>
<message>
@@ -1045,7 +1045,7 @@
<translation>Niewłaściwe argumenty w %0: katalogi są niewłaściwe: %1, %2</translation>
</message>
<message>
- <source>Could not create %0</source>
+ <source>Cannot create %0</source>
<translation>Nie można utworzyć %0</translation>
</message>
<message>
@@ -1053,11 +1053,11 @@
<translation>Nie można nadpisać %1</translation>
</message>
<message>
- <source>Could not copy %0 to %1, error was: %3</source>
+ <source>Cannot copy %0 to %1, error was: %3</source>
<translation>Nie można skopiować pliku z %0 do %1: %3</translation>
</message>
<message>
- <source>Could not remove %0</source>
+ <source>Cannot remove %0</source>
<translation>Nie można usunąć %0</translation>
</message>
</context>
@@ -1068,11 +1068,11 @@
<translation>Niepoprawna ilość zadań.</translation>
</message>
<message>
- <source>Could not open source &apos;%1&apos; for read. Error: %2.</source>
+ <source>Cannot open source &apos;%1&apos; for read. Error: %2.</source>
<translation>Nie można otworzyć źródła &quot;%1&quot; do odczytu. Błąd: %2.</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<translation>Nie można otworzyć &quot;%1&quot; do zapisu. Błąd: %2.</translation>
</message>
<message>
@@ -1083,7 +1083,7 @@
<context>
<name>QInstaller::CreateDesktopEntryOperation</name>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>Nie można utworzyć kopii zapasowej pliku %1: %2</translation>
</message>
<message>
@@ -1099,7 +1099,7 @@
<translation>Nie można nadpisać %1</translation>
</message>
<message>
- <source>Could not write Desktop Entry at %1</source>
+ <source>Cannot write Desktop Entry at %1</source>
<translation>Nie można zapisać Desktop Entry w %1</translation>
</message>
</context>
@@ -1114,26 +1114,26 @@
<translation>dokładnie 2</translation>
</message>
<message>
- <source>Could not create link from %1 to %2.</source>
+ <source>Cannot create link from %1 to %2.</source>
<translation>Nie można utworzyć dowiązania z %1 do %2.</translation>
</message>
<message>
- <source>Could not remove link from %1 to %2.</source>
+ <source>Cannot remove link from %1 to %2.</source>
<translation>Nie można usunąć dowiązania z %1 do %2.</translation>
</message>
</context>
<context>
<name>QInstaller::CreateLocalRepositoryOperation</name>
<message>
- <source>Could not set file permissions %1!</source>
+ <source>Cannot set file permissions %1!</source>
<translation>Nie można ustawić praw dostępu %1.</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>Nie można usunąć pliku %1: %2</translation>
</message>
<message>
- <source>Could not move file %1 to %2. Error: %3</source>
+ <source>Cannot move file %1 to %2. Error: %3</source>
<translation>Nie można przenieść pliku z %1 do %2: %3</translation>
</message>
<message>
@@ -1149,19 +1149,19 @@
<translation>Instalator musi być w wersji offline: %1.</translation>
</message>
<message>
- <source>Could not open file: %1</source>
+ <source>Cannot open file: %1</source>
<translation>Nie można otworzyć pliku %1</translation>
</message>
<message>
- <source>Could not read: %1. Error: %2</source>
+ <source>Cannot read: %1. Error: %2</source>
<translation>BÅ‚Ä…d odczytu %1: %2</translation>
</message>
<message>
- <source>Could not open file: %1. Error: %2</source>
+ <source>Cannot open file: %1. Error: %2</source>
<translation>Nie można otworzyć pliku %1: %2</translation>
</message>
<message>
- <source>Could not create target dir: %1.</source>
+ <source>Cannot create target dir: %1.</source>
<translation>Nie można utworzyć katalogu docelowego %1.</translation>
</message>
<message>
@@ -1173,7 +1173,7 @@
<translation>Usuwanie pliku %0</translation>
</message>
<message>
- <source>Could not remove %0.</source>
+ <source>Cannot remove %0.</source>
<translation>Nie można usunąć %0.</translation>
</message>
<message>
@@ -1196,7 +1196,7 @@
<translation> (opcjonalnie: &apos;workingDirectory=...&apos;, &apos;iconPath=...&apos;, &apos;iconId=...&apos;)</translation>
</message>
<message>
- <source>Could not create folder %1: %2.</source>
+ <source>Cannot create folder %1: %2.</source>
<translation>Nie można utworzyć katalogu %1: %2.</translation>
</message>
<message>
@@ -1204,7 +1204,7 @@
<translation>Nie można nadpisać %1: %2</translation>
</message>
<message>
- <source>Could not create link %1: %2</source>
+ <source>Cannot create link %1: %2</source>
<translation>Nie można utworzyć dowiązania %1: %2</translation>
</message>
</context>
@@ -1227,15 +1227,15 @@
<translation>Weryfikacja hasha podczas pobierania nie powiodła się. Jest to tymczasowy błąd, spróbuj ponownie.</translation>
</message>
<message>
- <source>Could not verify Hash</source>
+ <source>Cannot verify Hash</source>
<translation>Nie można zweryfikować hasha</translation>
</message>
<message>
- <source>Could not download archive: %1 : %2</source>
+ <source>Cannot download archive: %1 : %2</source>
<translation>Nie można pobrać archiwum %1: %2</translation>
</message>
<message>
- <source>Could not fetch archives: %1
+ <source>Cannot fetch archives: %1
Error while loading %2</source>
<translation>Nie można pobrać archiwów: %1
BÅ‚Ä…d podczas Å‚adowania %2</translation>
@@ -1249,7 +1249,7 @@ BÅ‚Ä…d podczas Å‚adowania %2</translation>
<translation>Nieobsługiwany schemat %1 (%2)</translation>
</message>
<message>
- <source>Could not find component for: %1.</source>
+ <source>Cannot find component for: %1.</source>
<translation>Brak komponentu dla %1.</translation>
</message>
</context>
@@ -1297,7 +1297,7 @@ BÅ‚Ä…d podczas Å‚adowania %2</translation>
<translation>Ścieżka docelowa &quot;%1&quot; już istnieje, lecz nie jest ona plikiem.</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<extracomment>%2 is a sentence describing the error</extracomment>
<translation>Nie można otworzyć pliku docelowego &quot;%1&quot; do zapisu. Błąd: %2.</translation>
</message>
@@ -1313,11 +1313,11 @@ BÅ‚Ä…d podczas Å‚adowania %2</translation>
<translation>przynajmniej 1</translation>
</message>
<message>
- <source>Execution failed: Could not start detached: &quot;%1&quot;</source>
+ <source>Execution failed: Cannot start detached: &quot;%1&quot;</source>
<translation>Błąd wykonywania. Nie można odrębnie uruchomić &quot;%1&quot;</translation>
</message>
<message>
- <source>Execution failed: Could not start: &quot;%1&quot;(%2)</source>
+ <source>Execution failed: Cannot start: &quot;%1&quot;(%2)</source>
<translation>Błąd wykonywania. Nie można uruchomić &quot;%1&quot;: %2</translation>
</message>
<message>
@@ -1354,7 +1354,7 @@ BÅ‚Ä…d podczas Å‚adowania %2</translation>
<context>
<name>QInstaller::ExtractArchiveOperation::Runnable</name>
<message>
- <source>Could not open %1 for reading: %2.</source>
+ <source>Cannot open %1 for reading: %2.</source>
<translation>Nie można otworzyć pliku %1 do odczytu: %2.</translation>
</message>
<message>
@@ -1373,7 +1373,7 @@ BÅ‚Ä…d podczas Å‚adowania %2</translation>
<translation>Nieoczekiwana liczba argumentów, wymagany jest tylko jeden</translation>
</message>
<message>
- <source>Could not get package manager core.</source>
+ <source>Cannot get package manager core.</source>
<translation>Brak dostępu do &quot;package manager core&quot;.</translation>
</message>
<message>
@@ -1505,7 +1505,7 @@ BÅ‚Ä…d podczas Å‚adowania %2</translation>
<translation>Niepoprawny argument: nazwa katalogu źródłowego nie może być pusta.</translation>
</message>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>Nie można utworzyć kopii zapasowej pliku %1: %2</translation>
</message>
<message>
@@ -1517,7 +1517,7 @@ BÅ‚Ä…d podczas Å‚adowania %2</translation>
<translation>Nie można nadpisać %1: %2</translation>
</message>
<message>
- <source>Could not create folder at %1: %2</source>
+ <source>Cannot create folder at %1: %2</source>
<translation>Nie można utworzyć katalogu %1: %2</translation>
</message>
</context>
@@ -1694,7 +1694,7 @@ BÅ‚Ä…d podczas Å‚adowania %2</translation>
<translation>ZÅ‚apano nieznany wyjÄ…tek podczas rozpakowywania %1.</translation>
</message>
<message>
- <source>Could not open %1 for reading. Error: %2</source>
+ <source>Cannot open %1 for reading. Error: %2</source>
<translation>Nie można otworzyć pliku %1 do odczytu: %2</translation>
</message>
</context>
@@ -1786,7 +1786,7 @@ Pobieranie pakietów...</translation>
<translation>Błędny format</translation>
</message>
<message>
- <source>Could not write installer configuration to %1: %2</source>
+ <source>Cannot write installer configuration to %1: %2</source>
<translation>Nie można zapisać konfiguracji instalatora do %1: %2</translation>
</message>
<message>
@@ -1818,19 +1818,19 @@ Pobieranie pakietów...</translation>
<translation>Narzędzie konserwacji nie jest pakietem</translation>
</message>
<message>
- <source>Could not write maintenance tool data to %1: %2</source>
+ <source>Cannot write maintenance tool data to %1: %2</source>
<translation>Nie można zapisać danych narzędzia konserwacji do %1: %2</translation>
</message>
<message>
- <source>Could not remove data file &apos;%1&apos;: %2</source>
+ <source>Cannot remove data file &apos;%1&apos;: %2</source>
<translation>Nie można usunąć pliku z danymi &quot;%1&quot;: %2</translation>
</message>
<message>
- <source>Could not write maintenance tool to %1: %2</source>
+ <source>Cannot write maintenance tool to %1: %2</source>
<translation>Nie można zapisać narzędzia konserwacji do %1: %2</translation>
</message>
<message>
- <source>Could not write maintenance tool binary data to %1: %2</source>
+ <source>Cannot write maintenance tool binary data to %1: %2</source>
<translation>Nie można zapisać binarnych danych narzędzia konserwacji do %1: %2</translation>
</message>
<message>
@@ -1928,7 +1928,7 @@ Instalacja komponentu %1</translation>
<translation>Nieznany błąd</translation>
</message>
<message>
- <source>Could not retrieve remote tree: %1.</source>
+ <source>Cannot retrieve remote tree: %1.</source>
<translation>Nie można odczytać zdalnego drzewa: %1.</translation>
</message>
<message>
@@ -1936,15 +1936,15 @@ Instalacja komponentu %1</translation>
<translation>Nie można odczytać pakietów z: %1.</translation>
</message>
<message>
- <source>Could not retrieve meta information: %1</source>
+ <source>Cannot retrieve meta information: %1</source>
<translation>Nie można odczytać metainformacji: %1</translation>
</message>
<message>
- <source>Could not add temporary update source information.</source>
+ <source>Cannot add temporary update source information.</source>
<translation>Nie można dodać tymczasowej informacji o źródłach aktualizacji.</translation>
</message>
<message>
- <source>Could not find any update source information.</source>
+ <source>Cannot find any update source information.</source>
<translation>Brak informacji o źródłach aktualizacji.</translation>
</message>
<message>
@@ -2159,14 +2159,14 @@ Skopiuj instalator na lokalny dysk.</translation>
<context>
<name>QInstaller::RemoteObject</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>Nie można odczytać wszystkich danych po wysłaniu komendy: %1. Oczekiwano %2 bajtów, otrzymano %3 bajtów. Błąd: %4</translation>
</message>
</context>
<context>
<name>QInstaller::RemoteServerConnection</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>Nie można odczytać wszystkich danych po wysłaniu komendy: %1. Oczekiwano %2 bajtów, otrzymano %3 bajtów. Błąd: %4</translation>
</message>
</context>
@@ -2192,7 +2192,7 @@ Skopiuj instalator na lokalny dysk.</translation>
<context>
<name>QInstaller::Resource</name>
<message>
- <source>Could not open Resource &apos;%1&apos; read-only.</source>
+ <source>Cannot open Resource &apos;%1&apos; read-only.</source>
<translation>Nie można otworzyć zasobu &quot;%1&quot; do odczytu.</translation>
</message>
<message>
@@ -2214,7 +2214,7 @@ Skopiuj instalator na lokalny dysk.</translation>
<context>
<name>QInstaller::ScriptEngine</name>
<message>
- <source>Could not open the requested script file at %1: %2.</source>
+ <source>Cannot open the requested script file at %1: %2.</source>
<translation>Nie można otworzyć wymaganego pliku ze skryptem &quot;%1&quot;: %2.</translation>
</message>
<message>
@@ -2411,7 +2411,7 @@ Czy kontynuować?</translation>
<translation>Przekroczono maksymalny czas oczekiwania na zakończenie testowania: &quot;%1&quot;</translation>
</message>
<message>
- <source>Could not parse Updates.xml! Error: %1.</source>
+ <source>Cannot parse Updates.xml! Error: %1.</source>
<translation>Nie można sparsować Updates.xml. Błąd: %1.</translation>
</message>
<message>
@@ -2441,11 +2441,11 @@ Czy kontynuować?</translation>
<context>
<name>RemoteClient</name>
<message>
- <source>Could not get authorization.</source>
+ <source>Cannot get authorization.</source>
<translation>Nie można uzyskać autoryzacji.</translation>
</message>
<message>
- <source>Could not get authorization that is needed for continuing the installation.
+ <source>Cannot get authorization that is needed for continuing the installation.
Either abort the installation or use the fallback solution by running
%1
@@ -2461,14 +2461,14 @@ jako administrator, po czym naciśnij OK.</translation>
<context>
<name>ResourceCollectionManager</name>
<message>
- <source>Could not open resource %1: %2</source>
+ <source>Cannot open resource %1: %2</source>
<translation>Nie można otworzyć pliku z zasobami %1: %2</translation>
</message>
</context>
<context>
<name>Settings</name>
<message>
- <source>Could not open settings file %1 for reading: %2</source>
+ <source>Cannot open settings file %1 for reading: %2</source>
<translation>Nie można otworzyć pliku z ustawieniami %1 do odczytu: %2</translation>
</message>
</context>
@@ -2598,7 +2598,7 @@ jako administrator, po czym naciśnij OK.</translation>
<translation>Ścieżka %1 rejestru jest tylko do odczytu</translation>
</message>
<message>
- <source>Could not write to registry path %1</source>
+ <source>Cannot write to registry path %1</source>
<translation>Nie można zapisać do ścieżki rejestru %1</translation>
</message>
<message>
diff --git a/src/sdk/translations/ru.ts b/src/sdk/translations/ru.ts
index 6485407d4..81ebdb00e 100644
--- a/src/sdk/translations/ru.ts
+++ b/src/sdk/translations/ru.ts
@@ -15,26 +15,26 @@
<context>
<name>BinaryContent</name>
<message>
- <source>Could not seek to %1 to read the operation data.</source>
+ <source>Cannot seek to %1 to read the operation data.</source>
<translation>Ðе удалоÑÑŒ перейти в позицию %1 Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… операций.</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection block.</source>
+ <source>Cannot seek to %1 to read the resource collection block.</source>
<translation>Ðе удалоÑÑŒ перейти в позицию %1 Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð±Ð»Ð¾ÐºÐ° набора реÑурÑов.</translation>
</message>
<message>
- <source>Could not open meta resource. Error: %1</source>
+ <source>Cannot open meta resource. Error: %1</source>
<translation>Ðе удалоÑÑŒ открыть метареÑурÑÑ‹. Ошибка: %1</translation>
</message>
</context>
<context>
<name>BinaryLayout</name>
<message>
- <source>Could not seek to %1 to read the embedded meta data count.</source>
+ <source>Cannot seek to %1 to read the embedded meta data count.</source>
<translation>Ðе удалоÑÑŒ перейти в позицию %1 Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñчётчика вÑтроенных метаданных.</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection segment.</source>
+ <source>Cannot seek to %1 to read the resource collection segment.</source>
<translation>Ðе удалоÑÑŒ перейти в позицию %1 Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñегмента набора реÑурÑов.</translation>
</message>
<message>
@@ -72,34 +72,34 @@
<translation>Путь ÑущеÑтвует, но не ÑвлÑетÑÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼: %1</translation>
</message>
<message>
- <source>Could not create folder: %1</source>
+ <source>Cannot create folder: %1</source>
<translation>Ðе удалоÑÑŒ Ñоздать каталог: %1</translation>
</message>
</context>
<context>
<name>ExtractCallbackImpl</name>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>Ðе удалоÑÑŒ определить путь файла %1 в архиве</translation>
</message>
<message>
- <source>Could not remove already existing symlink. %1</source>
+ <source>Cannot remove already existing symlink. %1</source>
<translation>Ðе удалоÑÑŒ удалить ÑущеÑтвующую Ñимвольную ÑÑылку. %1</translation>
</message>
<message>
- <source>Could not open file: %1 (%2)</source>
+ <source>Cannot open file: %1 (%2)</source>
<translation>Ðе удалоÑÑŒ открыть файл: %1 (%2)</translation>
</message>
<message>
- <source>Could not create symlink at &apos;%1&apos;. Another one is already existing.</source>
+ <source>Cannot create symlink at &apos;%1&apos;. Another one is already existing.</source>
<translation>Ðе удалоÑÑŒ Ñоздать Ñимвольную ÑÑылку «%1», потому что ÑÑылка уже ÑущеÑтвует.</translation>
</message>
<message>
- <source>Could not read symlink target from file &apos;%1&apos;.</source>
+ <source>Cannot read symlink target from file &apos;%1&apos;.</source>
<translation>Ðе удалоÑÑŒ прочитать цель Ñимвольной ÑÑылки из файла «%1».</translation>
</message>
<message>
- <source>Could not create symlink at %1. %2</source>
+ <source>Cannot create symlink at %1. %2</source>
<translation>Ðе удалоÑÑŒ Ñоздать Ñимвольную ÑÑылку %1. %2</translation>
</message>
</context>
@@ -131,28 +131,28 @@
</message>
</context>
<context>
- <name>KDJob</name>
+ <name>Job</name>
<message>
<source>Canceled</source>
<translation>Отменено</translation>
</message>
</context>
<context>
- <name>KDLockFile</name>
+ <name>LockFile</name>
<message>
- <source>Could not create lock file &apos;%1&apos;: %2</source>
+ <source>Cannot create lock file &apos;%1&apos;: %2</source>
<translation>Ðе удалоÑÑŒ Ñоздать файл блокировки «%1»: %2</translation>
</message>
<message>
- <source>Could not write PID to lock file &apos;%1&apos;: %2</source>
+ <source>Cannot write PID to lock file &apos;%1&apos;: %2</source>
<translation>Ðе удалоÑÑŒ запиÑать PID в файл блокировки «%1»: %2</translation>
</message>
<message>
- <source>Could not obtain the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot obtain the lock for file &apos;%1&apos;: %2</source>
<translation>Ðе удалоÑÑŒ заблокировать файл «%1»: %2</translation>
</message>
<message>
- <source>Could not release the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot release the lock for file &apos;%1&apos;: %2</source>
<translation>Ðе удалоÑÑŒ разблокировать файл «%1»: %2</translation>
</message>
</context>
@@ -171,7 +171,7 @@
<translation>ровно 2</translation>
</message>
<message>
- <source>Could not open file &apos;%1&apos; for writing: %2</source>
+ <source>Cannot open file &apos;%1&apos; for writing: %2</source>
<translation>Ðевозможно открыть файл «%1» на запиÑÑŒ: %2</translation>
</message>
<message>
@@ -179,18 +179,18 @@
<translation>Ðевозможно найти резервную копию %1.</translation>
</message>
<message>
- <source>Could not restore backup file for %1.</source>
+ <source>Cannot restore backup file for %1.</source>
<translation>Ðевозможно воÑÑтановить резервную копию %1.</translation>
</message>
<message>
- <source>Could not restore backup file for %1: %2</source>
+ <source>Cannot restore backup file for %1: %2</source>
<translation>Ðевозможно воÑÑтановить резервную копию %1: %2</translation>
</message>
</context>
<context>
<name>KDUpdater::CopyOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>Ðевозможно Ñоздать резервную копию файла %1.</translation>
</message>
<message>
@@ -198,23 +198,23 @@
<translation>ÐедопуÑтимое количеÑтво параметров: передано %1, требуетÑÑ 2.</translation>
</message>
<message>
- <source>Could not copy a non-existent file: %1</source>
+ <source>Cannot copy a non-existent file: %1</source>
<translation>Ðе удалоÑÑŒ Ñкопировать отÑутÑтвующий файл: %1</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>Ðевозможно удалить файл %1: %2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>Ðевозможно Ñкопировать %1 в %2: %3</translation>
</message>
<message>
- <source>Could not delete file %1: %2</source>
+ <source>Cannot delete file %1: %2</source>
<translation>Ðевозможно удалить файл %1: %2</translation>
</message>
<message>
- <source>Could not restore backup file into %1: %2</source>
+ <source>Cannot restore backup file into %1: %2</source>
<translation>Ðевозможно воÑÑтановить файл %1 из резервной копии: %2</translation>
</message>
</context>
@@ -307,7 +307,7 @@
<translation>Ðевозможно загрузить %1: Сбой запиÑи в файл «%2» - %3</translation>
</message>
<message>
- <source>Cannot download %1: Could not create %2: %3</source>
+ <source>Cannot download %1: Cannot create %2: %3</source>
<translation>Ðевозможно загрузить %1: Ðевозможно Ñоздать %2: %3</translation>
</message>
<message>
@@ -361,7 +361,7 @@
<translation>ÐедопуÑтимое количеÑтво параметров: передано %1, требуетÑÑ 1.</translation>
</message>
<message>
- <source>Could not create folder %1: Unknown error.</source>
+ <source>Cannot create folder %1: Unknown error.</source>
<translation>Ðевозможно Ñоздать каталог %1: ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°.</translation>
</message>
<message>
@@ -372,7 +372,7 @@
<context>
<name>KDUpdater::MoveOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>Ðевозможно Ñоздать резервную копию файла %1.</translation>
</message>
<message>
@@ -380,11 +380,11 @@
<translation>ÐедопуÑтимое количеÑтво параметров: передано %1, требуетÑÑ 2.</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>Ðевозможно удалить файл Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ %1: %2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>Ðевозможно Ñкопировать %1 в %2: %3</translation>
</message>
<message>
@@ -411,7 +411,7 @@
<translation>Файл %1 не ÑущеÑтвует.</translation>
</message>
<message>
- <source>Could not open %1.</source>
+ <source>Cannot open %1.</source>
<translation>Ðевозможно открыть %1.</translation>
</message>
<message>
@@ -434,11 +434,11 @@
<translation>ÐедопуÑтимое количеÑтво параметров: передано %1, требуетÑÑ 2.</translation>
</message>
<message>
- <source>Could not open file %1 for reading: %2</source>
+ <source>Cannot open file %1 for reading: %2</source>
<translation>Ðевозможно открыть файл %1 на чтение: %2</translation>
</message>
<message>
- <source>Could not open file %1 for writing: %2</source>
+ <source>Cannot open file %1 for writing: %2</source>
<translation>Ðевозможно открыть файл %1 на запиÑÑŒ: %2</translation>
</message>
<message>
@@ -457,7 +457,7 @@
<context>
<name>KDUpdater::ResourceFileDownloader</name>
<message>
- <source>Could not read resource file &quot;%1&quot;. Reason:</source>
+ <source>Cannot read resource file &quot;%1&quot;. Reason:</source>
<translation>Ðевозможно прочитать файл реÑурÑов «%1». Причина:</translation>
</message>
</context>
@@ -468,11 +468,11 @@
<translation>ÐедопуÑтимое количеÑтво параметров: передано %1, требуетÑÑ 1.</translation>
</message>
<message>
- <source>Could not remove folder %1: The folder does not exist.</source>
+ <source>Cannot remove folder %1: The folder does not exist.</source>
<translation>Ðевозможно удалить каталог %1: каталог Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем не ÑущеÑтвует.</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>Ðевозможно удалить каталог %1: %2</translation>
</message>
<message>
@@ -514,11 +514,11 @@
<context>
<name>KDUpdater::UpdateFinder</name>
<message>
- <source>Could not access the package information of this application.</source>
+ <source>Cannot access the package information of this application.</source>
<translation>Приложение не может получить доÑтуп к информации о пакетах.</translation>
</message>
<message>
- <source>Could not access the update sources information of this application.</source>
+ <source>Cannot access the update sources information of this application.</source>
<translation>Приложение не может получить доÑтуп к Ñерверам обновлений.</translation>
</message>
<message numerus="yes">
@@ -534,7 +534,7 @@
<translation>ЗагружаетÑÑ Ñ„Ð°Ð¹Ð» Updates.xml Ñ Ñервера обновлений.</translation>
</message>
<message>
- <source>Could not download update source %1 from (&apos;%2&apos;)</source>
+ <source>Cannot download update source %1 from (&apos;%2&apos;)</source>
<translation>Ðе удалоÑÑŒ загрузить иÑточник обновлений %1 Ñ («%2»)</translation>
</message>
<message>
@@ -557,7 +557,7 @@
<translation>%1 Ñодержит недопуÑтимые данные: %2</translation>
</message>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>Ðевозможно прочитать «%1»</translation>
</message>
<message>
@@ -569,7 +569,7 @@
<translation>Ðепредвиденный корневой Ñлемент %1, требуетÑÑ Â«UpdateSources»</translation>
</message>
<message>
- <source>Could not save changes to &quot;%1&quot;: %2</source>
+ <source>Cannot save changes to &quot;%1&quot;: %2</source>
<translation>Ðевозможно Ñохранить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² «%1»: %2</translation>
</message>
</context>
@@ -580,7 +580,7 @@
<translation>Файл Updates.xml Ñодержит недопуÑтимые данные: %1</translation>
</message>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>Ðевозможно прочитать «%1»</translation>
</message>
<message>
@@ -615,11 +615,11 @@
<context>
<name>Lib7z</name>
<message>
- <source>Could not retrieve number of items in archive</source>
+ <source>Cannot retrieve number of items in archive</source>
<translation>Ðе удалоÑÑŒ определить количеÑтво файлов в архиве</translation>
</message>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>Ðе удалоÑÑŒ определить путь файла %1 в архиве</translation>
</message>
<message>
@@ -639,15 +639,15 @@
<translation>Ошибка: %1</translation>
</message>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>Ðе удалоÑÑŒ загрузить кодеки</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>Ðе удалоÑÑŒ определить формат по умолчанию</translation>
</message>
<message>
- <source>Could not create archive %1. %2</source>
+ <source>Cannot create archive %1. %2</source>
<translation>Ðе удалоÑÑŒ Ñоздать архив %1. %2</translation>
</message>
<message>
@@ -659,14 +659,14 @@
<translation>Ð˜Ð½Ð´ÐµÐºÑ Ñ„Ð°Ð¹Ð»Ð° %1 вне лимитов [0, %2]</translation>
</message>
<message>
- <source>Could not create output file for writing: %1</source>
+ <source>Cannot create output file for writing: %1</source>
<translation>Ðе удалоÑÑŒ Ñоздать выходной файл Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи: %1</translation>
</message>
</context>
<context>
<name>Lib7z::ExtractItemJob</name>
<message>
- <source>Could not list archive: QIODevice not set or already destroyed.</source>
+ <source>Cannot list archive: QIODevice not set or already destroyed.</source>
<translation>Ðевозможно Ñоздать архив: QIODevice не уÑтановлен или уже разрушен.</translation>
</message>
<message>
@@ -685,7 +685,7 @@
<context>
<name>Lib7z::ListArchiveJob</name>
<message>
- <source>Could not list archive: QIODevice already destroyed.</source>
+ <source>Cannot list archive: QIODevice already destroyed.</source>
<translation>Ðевозможно Ñоздать архив: QIODevice уже разрушен.</translation>
</message>
<message>
@@ -700,15 +700,15 @@
<context>
<name>OpenArchiveInfo</name>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>Ðе удалоÑÑŒ загрузить кодеки</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>Ðе удалоÑÑŒ определить формат по умолчанию</translation>
</message>
<message>
- <source>Could not open archive</source>
+ <source>Cannot open archive</source>
<translation>Ðе удалоÑÑŒ открыть архив</translation>
</message>
<message>
@@ -762,35 +762,35 @@
<translation>ИБ</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>Ðе удалоÑÑŒ удалить файл %1: %2</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>Ðе удалоÑÑŒ удалить каталог %1: %2</translation>
</message>
<message>
- <source>Could not create folder %1</source>
+ <source>Cannot create folder %1</source>
<translation>Ðе удалоÑÑŒ Ñоздать каталог %1</translation>
</message>
<message>
- <source>Could not copy file from %1 to %2: %3</source>
+ <source>Cannot copy file from %1 to %2: %3</source>
<translation>Ðе удалоÑÑŒ Ñкопировать файл из %1 в %2: %3</translation>
</message>
<message>
- <source>Could not move file from %1 to %2: %3</source>
+ <source>Cannot move file from %1 to %2: %3</source>
<translation>Ðе удалоÑÑŒ перемеÑтить файл из %1 в %2: %3</translation>
</message>
<message>
- <source>Could not create folder %1: %2</source>
+ <source>Cannot create folder %1: %2</source>
<translation>Ðе удалоÑÑŒ Ñоздать каталог %1: %2</translation>
</message>
<message>
- <source>Could not open temporary file: %1</source>
+ <source>Cannot open temporary file: %1</source>
<translation>Ðе удалоÑÑŒ открыть временный файл %1</translation>
</message>
<message>
- <source>Could not open temporary file for template %1: %2</source>
+ <source>Cannot open temporary file for template %1: %2</source>
<translation>Ðе удалоÑÑŒ открыть временный файл Ð´Ð»Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð° %1: %2</translation>
</message>
<message>
@@ -826,11 +826,11 @@
<translation>Сбой запиÑи Ñ %1 байта: %2</translation>
</message>
<message>
- <source>Could not create temporary file</source>
+ <source>Cannot create temporary file</source>
<translation>Ðе удалоÑÑŒ Ñоздать временный файл</translation>
</message>
<message>
- <source>Could not retrieve property %1 for item %2</source>
+ <source>Cannot retrieve property %1 for item %2</source>
<translation>Ðе удалоÑÑŒ определить ÑвойÑтво %1 Ð´Ð»Ñ Ñлемента %2</translation>
</message>
<message>
@@ -838,11 +838,11 @@
<translation>СвойÑтво %1 Ñлемента %2 отноÑитÑÑ Ð½Ðµ к типу VT_FILETIME, а к %3</translation>
</message>
<message>
- <source>Could not convert file time to local time</source>
+ <source>Cannot convert file time to local time</source>
<translation>Ðе удалоÑÑŒ преобразовать Ð²Ñ€ÐµÐ¼Ñ Ñ„Ð°Ð¹Ð»Ð° в локальное времÑ</translation>
</message>
<message>
- <source>Could not convert local file time to system time</source>
+ <source>Cannot convert local file time to system time</source>
<translation>Ðе удалоÑÑŒ преобразовать Ð²Ñ€ÐµÐ¼Ñ Ñ„Ð°Ð¹Ð»Ð° в ÑиÑтемное времÑ</translation>
</message>
<message>
@@ -857,19 +857,19 @@
<translation>У компонентов не может быть потомков в режиме обновлениÑ.</translation>
</message>
<message>
- <source>Could not open the requested translation file &apos;%1&apos;.</source>
+ <source>Cannot open the requested translation file &apos;%1&apos;.</source>
<translation>Ðевозможно открыть файл перевода «%1».</translation>
</message>
<message>
- <source>Could not open the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>Ðевозможно открыть UI файл «%1». Ошибка: %2</translation>
</message>
<message>
- <source>Could not load the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot load the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>Ðевозможно загрузить UI файл «%1». Ошибка: %2</translation>
</message>
<message>
- <source>Could not open the requested license file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested license file &apos;%1&apos;. Error: %2</source>
<translation>Ðевозможно открыть файл лицензии «%1». Ошибка: %2</translation>
</message>
<message>
@@ -1049,7 +1049,7 @@
<translation>ÐедопуÑтимые параметры в %0: ÐедопуÑтимые имена папок: %1 %2</translation>
</message>
<message>
- <source>Could not create %0</source>
+ <source>Cannot create %0</source>
<translation>Ðевозможно Ñоздать %0</translation>
</message>
<message>
@@ -1057,11 +1057,11 @@
<translation>Ðе удалоÑÑŒ перезапиÑать %1</translation>
</message>
<message>
- <source>Could not copy %0 to %1, error was: %3</source>
+ <source>Cannot copy %0 to %1, error was: %3</source>
<translation>Ðевозможно Ñкопировать %0 в %1. Ошибка: %3</translation>
</message>
<message>
- <source>Could not remove %0</source>
+ <source>Cannot remove %0</source>
<translation>Ðевозможно удалить %0</translation>
</message>
</context>
@@ -1072,11 +1072,11 @@
<translation type="unfinished">Ðеверное чиÑло Ñлементов task.</translation>
</message>
<message>
- <source>Could not open source &apos;%1&apos; for read. Error: %2.</source>
+ <source>Cannot open source &apos;%1&apos; for read. Error: %2.</source>
<translation>Ðе удалоÑÑŒ открыть иÑточник «%1» Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ. Ошибка: %2.</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<translation>Ðе удалоÑÑŒ открыть «%1» Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи. Ошибка: %2.</translation>
</message>
<message>
@@ -1087,7 +1087,7 @@
<context>
<name>QInstaller::CreateDesktopEntryOperation</name>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>Ðе удалоÑÑŒ Ñоздать резервную копию файла %1: %2</translation>
</message>
<message>
@@ -1103,7 +1103,7 @@
<translation>Ðе удалоÑÑŒ перезапиÑать %1</translation>
</message>
<message>
- <source>Could not write Desktop Entry at %1</source>
+ <source>Cannot write Desktop Entry at %1</source>
<translation>Ðевозможно запиÑать Desktop Entry в %1</translation>
</message>
</context>
@@ -1118,26 +1118,26 @@
<translation>ровно 2</translation>
</message>
<message>
- <source>Could not create link from %1 to %2.</source>
+ <source>Cannot create link from %1 to %2.</source>
<translation>Ðе удалоÑÑŒ Ñоздать ÑÑылку Ñ %1 на %2.</translation>
</message>
<message>
- <source>Could not remove link from %1 to %2.</source>
+ <source>Cannot remove link from %1 to %2.</source>
<translation>Ðе удалоÑÑŒ Ñоздать ÑÑылку Ñ %1 на %2.</translation>
</message>
</context>
<context>
<name>QInstaller::CreateLocalRepositoryOperation</name>
<message>
- <source>Could not set file permissions %1!</source>
+ <source>Cannot set file permissions %1!</source>
<translation>Ðевозможно уÑтановить права доÑтупа Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° %1!</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>Ðе удалоÑÑŒ удалить файл %1: %2</translation>
</message>
<message>
- <source>Could not move file %1 to %2. Error: %3</source>
+ <source>Cannot move file %1 to %2. Error: %3</source>
<translation>Ðевозможно перемеÑтить файл %1 в %2. Ошибка: %3</translation>
</message>
<message>
@@ -1153,19 +1153,19 @@
<translation>Ðеобходима Ð¾Ñ„Ð»Ð°Ð¹Ð½Ð¾Ð²Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹ уÑтановки: %1.</translation>
</message>
<message>
- <source>Could not open file: %1</source>
+ <source>Cannot open file: %1</source>
<translation>Ðевозможно открыть файл: %1</translation>
</message>
<message>
- <source>Could not read: %1. Error: %2</source>
+ <source>Cannot read: %1. Error: %2</source>
<translation>Ðевозможно прочитать: %1. Ошибка: %2</translation>
</message>
<message>
- <source>Could not open file: %1. Error: %2</source>
+ <source>Cannot open file: %1. Error: %2</source>
<translation>Ðевозможно открыть файл: %1. Ошибка: %2</translation>
</message>
<message>
- <source>Could not create target dir: %1.</source>
+ <source>Cannot create target dir: %1.</source>
<translation>Ðевозможно Ñоздать каталог назначениÑ: %1.</translation>
</message>
<message>
@@ -1177,7 +1177,7 @@
<translation>Удаление файла: %0</translation>
</message>
<message>
- <source>Could not remove %0.</source>
+ <source>Cannot remove %0.</source>
<translation>Ðевозможно удалить %0.</translation>
</message>
<message>
@@ -1200,7 +1200,7 @@
<translation> (необÑзательно: &apos;workingDirectory=...&apos;, &apos;iconPath=...&apos;, &apos;iconId=...&apos;)</translation>
</message>
<message>
- <source>Could not create folder %1: %2.</source>
+ <source>Cannot create folder %1: %2.</source>
<translation>Ðе удалоÑÑŒ Ñоздать каталог: %1: %2.</translation>
</message>
<message>
@@ -1208,7 +1208,7 @@
<translation>Ðе удалоÑÑŒ перезапиÑать %1: %2</translation>
</message>
<message>
- <source>Could not create link %1: %2</source>
+ <source>Cannot create link %1: %2</source>
<translation>Ðе удалоÑÑŒ Ñоздать ÑÑылку %1: %2</translation>
</message>
</context>
@@ -1231,15 +1231,15 @@
<translation>Ðе удалоÑÑŒ проверить целоÑтноÑÑ‚ÑŒ хеша в процеÑÑе загрузки. ПожалуйÑта, повторите операцию.</translation>
</message>
<message>
- <source>Could not verify Hash</source>
+ <source>Cannot verify Hash</source>
<translation>Ðевозможно проверить хеш</translation>
</message>
<message>
- <source>Could not download archive: %1 : %2</source>
+ <source>Cannot download archive: %1 : %2</source>
<translation>Ðевозможно загрузить архив: %1: %2</translation>
</message>
<message>
- <source>Could not fetch archives: %1
+ <source>Cannot fetch archives: %1
Error while loading %2</source>
<translation>Ðевозможно получить архивы :%1
Ошибка в процеÑÑе загрузки %2</translation>
@@ -1253,7 +1253,7 @@ Error while loading %2</source>
<translation>Схема не поддерживаетÑÑ: %1 (%2)</translation>
</message>
<message>
- <source>Could not find component for: %1.</source>
+ <source>Cannot find component for: %1.</source>
<translation>Ðевозможно найти компонент длÑ: %1.</translation>
</message>
</context>
@@ -1301,7 +1301,7 @@ Error while loading %2</source>
<translation>«%1» уже ÑущеÑтвует, но не ÑвлÑетÑÑ Ñ„Ð°Ð¹Ð»Ð¾Ð¼.</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<extracomment>%2 is a sentence describing the error</extracomment>
<translation>Ðе удалоÑÑŒ открыть «%1» Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи. Ошибка: %2.</translation>
</message>
@@ -1317,11 +1317,11 @@ Error while loading %2</source>
<translation>по крайней мере 1</translation>
</message>
<message>
- <source>Execution failed: Could not start detached: &quot;%1&quot;</source>
+ <source>Execution failed: Cannot start detached: &quot;%1&quot;</source>
<translation>Ðе удалоÑÑŒ выполнить: невозможно запуÑтить фоновый процеÑÑ: «%1»</translation>
</message>
<message>
- <source>Execution failed: Could not start: &quot;%1&quot;(%2)</source>
+ <source>Execution failed: Cannot start: &quot;%1&quot;(%2)</source>
<translation>Ðе удалоÑÑŒ иÑполнить: невозможно запуÑтить: «%1»(%2)</translation>
</message>
<message>
@@ -1358,7 +1358,7 @@ Error while loading %2</source>
<context>
<name>QInstaller::ExtractArchiveOperation::Runnable</name>
<message>
- <source>Could not open %1 for reading: %2.</source>
+ <source>Cannot open %1 for reading: %2.</source>
<translation>Ðевозможно открыть файл %1 на чтение: %2.</translation>
</message>
<message>
@@ -1377,7 +1377,7 @@ Error while loading %2</source>
<translation>КоличеÑтво аргументов не Ñовпадает: требуетÑÑ 1</translation>
</message>
<message>
- <source>Could not get package manager core.</source>
+ <source>Cannot get package manager core.</source>
<translation>Ðевозможно получить Ñдро менеджера пакетов.</translation>
</message>
<message>
@@ -1509,7 +1509,7 @@ Error while loading %2</source>
<translation>ÐедопуÑтимый параметр: иÑходный каталог не может быть пуÑтым.</translation>
</message>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>Ðе удалоÑÑŒ Ñоздать резервную копию файла %1: %2</translation>
</message>
<message>
@@ -1521,7 +1521,7 @@ Error while loading %2</source>
<translation>Ðе удалоÑÑŒ Ñкопировать %1: %2</translation>
</message>
<message>
- <source>Could not create folder at %1: %2</source>
+ <source>Cannot create folder at %1: %2</source>
<translation>Ðе удалоÑÑŒ Ñоздать каталог в %1: %2</translation>
</message>
</context>
@@ -1698,7 +1698,7 @@ Error while loading %2</source>
<translation>Ð’ процеÑÑе Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ %1 возникло неизвеÑтное иÑключение.</translation>
</message>
<message>
- <source>Could not open %1 for reading. Error: %2</source>
+ <source>Cannot open %1 for reading. Error: %2</source>
<translation>Ðевозможно открыть файл %1 на чтение: %2</translation>
</message>
</context>
@@ -1786,7 +1786,7 @@ Downloading packages...</source>
<translation>Ошибка форматированиÑ</translation>
</message>
<message>
- <source>Could not write installer configuration to %1: %2</source>
+ <source>Cannot write installer configuration to %1: %2</source>
<translation>Ðевозможно запиÑать файл конфигурации программы уÑтановки в %1: %2</translation>
</message>
<message>
@@ -1870,19 +1870,19 @@ Update aborted!</source>
<translation>Maintenance Tool не ÑвлÑетÑÑ Ð¿Ð°ÐºÐµÑ‚Ð¾Ð¼</translation>
</message>
<message>
- <source>Could not write maintenance tool data to %1: %2</source>
+ <source>Cannot write maintenance tool data to %1: %2</source>
<translation>Ðе удалоÑÑŒ запиÑать данные Maintenance Tool в %1: %2</translation>
</message>
<message>
- <source>Could not remove data file &apos;%1&apos;: %2</source>
+ <source>Cannot remove data file &apos;%1&apos;: %2</source>
<translation>Ðе удалоÑÑŒ удалить файл данных «%1»: %2</translation>
</message>
<message>
- <source>Could not write maintenance tool to %1: %2</source>
+ <source>Cannot write maintenance tool to %1: %2</source>
<translation>Ðе удалоÑÑŒ запиÑать Maintenance Tool в %1: %2</translation>
</message>
<message>
- <source>Could not write maintenance tool binary data to %1: %2</source>
+ <source>Cannot write maintenance tool binary data to %1: %2</source>
<translation>Ðе удалоÑÑŒ запиÑать двоичные данные Maintenance Tool в %1: %2</translation>
</message>
<message>
@@ -1931,7 +1931,7 @@ Installing component %1</source>
<translation>ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°</translation>
</message>
<message>
- <source>Could not retrieve remote tree: %1.</source>
+ <source>Cannot retrieve remote tree: %1.</source>
<translation>Ðевозможно загрузить удалённую Ñтруктуру: %1.</translation>
</message>
<message>
@@ -1939,15 +1939,15 @@ Installing component %1</source>
<translation>Ðе удалоÑÑŒ прочитать пакеты из: %1.</translation>
</message>
<message>
- <source>Could not retrieve meta information: %1</source>
+ <source>Cannot retrieve meta information: %1</source>
<translation>Ðевозможно загрузить метаданные: %1</translation>
</message>
<message>
- <source>Could not add temporary update source information.</source>
+ <source>Cannot add temporary update source information.</source>
<translation>Ðевозможно добавить информацию о временном Ñервере обновлениÑ.</translation>
</message>
<message>
- <source>Could not find any update source information.</source>
+ <source>Cannot find any update source information.</source>
<translation>Ðевозможно найти информацию об иÑточниках обновлениÑ.</translation>
</message>
<message>
@@ -2161,14 +2161,14 @@ Please copy the installer to a local drive</source>
<context>
<name>QInstaller::RemoteObject</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>Ðе удалоÑÑŒ прочитать вÑе данные поÑле отправки команды: %1. ОжидалоÑÑŒ байт: %2; получено байт: %3. Ошибка: %4</translation>
</message>
</context>
<context>
<name>QInstaller::RemoteServerConnection</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>Ðе удалоÑÑŒ прочитать вÑе данные поÑле отправки команды: %1. ОжидалоÑÑŒ байт: %2; получено байт: %3. Ошибка: %4</translation>
</message>
</context>
@@ -2194,7 +2194,7 @@ Please copy the installer to a local drive</source>
<context>
<name>QInstaller::Resource</name>
<message>
- <source>Could not open Resource &apos;%1&apos; read-only.</source>
+ <source>Cannot open Resource &apos;%1&apos; read-only.</source>
<translation>Ðе удалоÑÑŒ открыть на чтение реÑÑƒÑ€Ñ Â«%1».</translation>
</message>
<message>
@@ -2216,7 +2216,7 @@ Please copy the installer to a local drive</source>
<context>
<name>QInstaller::ScriptEngine</name>
<message>
- <source>Could not open the requested script file at %1: %2.</source>
+ <source>Cannot open the requested script file at %1: %2.</source>
<translation>Ðе удалоÑÑŒ открыть файл ÑÑ†ÐµÐ½Ð°Ñ€Ð¸Ñ %1: %2.</translation>
</message>
<message>
@@ -2413,7 +2413,7 @@ Do you want to continue?</source>
<translation>Таймаут во Ð²Ñ€ÐµÐ¼Ñ Ñ‚ÐµÑта «%1»</translation>
</message>
<message>
- <source>Could not parse Updates.xml! Error: %1.</source>
+ <source>Cannot parse Updates.xml! Error: %1.</source>
<translation>Ðевозможно разобрать Updates.xml! Ошибка: %1.</translation>
</message>
<message>
@@ -2459,7 +2459,7 @@ Do you want to continue?</source>
<translation>Первым Ñлементом должен быть «linux», «mac» или «windows». Другие типы в наÑтоÑщий момент не поддерживаютÑÑ.</translation>
</message>
<message>
- <source>Could not find the needed QmakeOutputInstallerKey(%1) value on the installer object. The ConsumeOutput operation on the valid qmake needs to be called first.</source>
+ <source>Cannot find the needed QmakeOutputInstallerKey(%1) value on the installer object. The ConsumeOutput operation on the valid qmake needs to be called first.</source>
<translation>Ðе удалоÑÑŒ найти значение QmakeOutputInstallerKey(%1) в объекте уÑтановщика. Сначала должна быть выполнена Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ ConsumeOutput Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‡ÐµÐ³Ð¾ qmake&apos;а.</translation>
</message>
<message>
@@ -2503,11 +2503,11 @@ Sometimes it helps to restart the installer with a switched off antivirus softwa
<context>
<name>RemoteClient</name>
<message>
- <source>Could not get authorization.</source>
+ <source>Cannot get authorization.</source>
<translation>Ðе удалоÑÑŒ авторизоватьÑÑ.</translation>
</message>
<message>
- <source>Could not get authorization that is needed for continuing the installation.
+ <source>Cannot get authorization that is needed for continuing the installation.
Either abort the installation or use the fallback solution by running
%1
@@ -2522,14 +2522,14 @@ as root and then clicking OK.</source>
<context>
<name>ResourceCollectionManager</name>
<message>
- <source>Could not open resource %1: %2</source>
+ <source>Cannot open resource %1: %2</source>
<translation>Ðе удалоÑÑŒ открыть реÑÑƒÑ€Ñ %1: %2</translation>
</message>
</context>
<context>
<name>Settings</name>
<message>
- <source>Could not open settings file %1 for reading: %2</source>
+ <source>Cannot open settings file %1 for reading: %2</source>
<translation>Ðевозможно открыть файл наÑтроек %1 на чтение: %2</translation>
</message>
</context>
@@ -2659,7 +2659,7 @@ as root and then clicking OK.</source>
<translation>Ðевозможно запиÑать ключ %1 в рееÑÑ‚Ñ€</translation>
</message>
<message>
- <source>Could not write to registry path %1</source>
+ <source>Cannot write to registry path %1</source>
<translation>Ðе удалоÑÑŒ запиÑать ключ %1 в рееÑÑ‚Ñ€</translation>
</message>
<message>
diff --git a/src/sdk/translations/zh_cn.ts b/src/sdk/translations/zh_cn.ts
index 95c262fc6..a826448d9 100644
--- a/src/sdk/translations/zh_cn.ts
+++ b/src/sdk/translations/zh_cn.ts
@@ -15,26 +15,26 @@
<context>
<name>BinaryContent</name>
<message>
- <source>Could not seek to %1 to read the operation data.</source>
+ <source>Cannot seek to %1 to read the operation data.</source>
<translation>无法找到 %1 以读å–æ“作数æ®ã€‚</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection block.</source>
+ <source>Cannot seek to %1 to read the resource collection block.</source>
<translation>无法找到 %1 以读å–资æºé›†åˆå—。</translation>
</message>
<message>
- <source>Could not open meta resource. Error: %1</source>
+ <source>Cannot open meta resource. Error: %1</source>
<translation>无法打开元资æºã€‚错误:%1</translation>
</message>
</context>
<context>
<name>BinaryLayout</name>
<message>
- <source>Could not seek to %1 to read the embedded meta data count.</source>
+ <source>Cannot seek to %1 to read the embedded meta data count.</source>
<translation>无法找到 %1 以读å–嵌入元信æ¯æ•°æ®æ€»é‡ã€‚</translation>
</message>
<message>
- <source>Could not seek to %1 to read the resource collection segment.</source>
+ <source>Cannot seek to %1 to read the resource collection segment.</source>
<translation>无法找到 %1 以读å–资æºé›†ç‰‡æ®µã€‚</translation>
</message>
<message>
@@ -72,34 +72,34 @@
<translation>路径存在,但ä¸æ˜¯æ–‡ä»¶å¤¹ï¼š%1</translation>
</message>
<message>
- <source>Could not create folder: %1</source>
+ <source>Cannot create folder: %1</source>
<translation>无法创建文件夹:%1</translation>
</message>
</context>
<context>
<name>ExtractCallbackImpl</name>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>无法获å–存档项目 %1 的路径</translation>
</message>
<message>
- <source>Could not remove already existing symlink. %1</source>
+ <source>Cannot remove already existing symlink. %1</source>
<translation>无法删除已ç»å­˜åœ¨çš„符å·é“¾æŽ¥ã€‚%1</translation>
</message>
<message>
- <source>Could not open file: %1 (%2)</source>
+ <source>Cannot open file: %1 (%2)</source>
<translation>无法打开文件:%1 (%2)</translation>
</message>
<message>
- <source>Could not create symlink at &apos;%1&apos;. Another one is already existing.</source>
+ <source>Cannot create symlink at &apos;%1&apos;. Another one is already existing.</source>
<translation>无法在“%1â€åˆ›å»ºç¬¦å·é“¾æŽ¥ã€‚å¦ä¸€ä¸ªç¬¦å·é“¾æŽ¥å·²ç»å­˜åœ¨ã€‚</translation>
</message>
<message>
- <source>Could not read symlink target from file &apos;%1&apos;.</source>
+ <source>Cannot read symlink target from file &apos;%1&apos;.</source>
<translation>无法从文件“%1â€ä¸­è¯»å–符å·é“¾æŽ¥ç›®æ ‡ã€‚</translation>
</message>
<message>
- <source>Could not create symlink at %1. %2</source>
+ <source>Cannot create symlink at %1. %2</source>
<translation>无法在 %1 创建符å·é“¾æŽ¥ã€‚%2</translation>
</message>
</context>
@@ -131,28 +131,28 @@
</message>
</context>
<context>
- <name>KDJob</name>
+ <name>Job</name>
<message>
<source>Canceled</source>
<translation>å·²å–消</translation>
</message>
</context>
<context>
- <name>KDLockFile</name>
+ <name>LockFile</name>
<message>
- <source>Could not create lock file &apos;%1&apos;: %2</source>
+ <source>Cannot create lock file &apos;%1&apos;: %2</source>
<translation>无法创建é”文件“%1â€ï¼š%2</translation>
</message>
<message>
- <source>Could not write PID to lock file &apos;%1&apos;: %2</source>
+ <source>Cannot write PID to lock file &apos;%1&apos;: %2</source>
<translation>无法将 PID 写入é”文件“%1â€ï¼š%2</translation>
</message>
<message>
- <source>Could not obtain the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot obtain the lock for file &apos;%1&apos;: %2</source>
<translation>无法为文件“%1â€èŽ·å–é”:“%2â€</translation>
</message>
<message>
- <source>Could not release the lock for file &apos;%1&apos;: %2</source>
+ <source>Cannot release the lock for file &apos;%1&apos;: %2</source>
<translation>无法为文件“%1â€é‡Šæ”¾é”:%2</translation>
</message>
</context>
@@ -167,11 +167,11 @@
<translation>无法找到 %1 的备份文件。</translation>
</message>
<message>
- <source>Could not restore backup file for %1.</source>
+ <source>Cannot restore backup file for %1.</source>
<translation>无法æ¢å¤ %1 的备份文件。</translation>
</message>
<message>
- <source>Could not restore backup file for %1: %2</source>
+ <source>Cannot restore backup file for %1: %2</source>
<translation>无法æ¢å¤ %1 的备份文件:%2</translation>
</message>
<message>
@@ -183,14 +183,14 @@
<translation>æ°å¥½ 2 个</translation>
</message>
<message>
- <source>Could not open file &apos;%1&apos; for writing: %2</source>
+ <source>Cannot open file &apos;%1&apos; for writing: %2</source>
<translation>无法打开文件“%1â€è¿›è¡Œå†™å…¥ï¼š%2</translation>
</message>
</context>
<context>
<name>KDUpdater::CopyOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>无法备份文件 %1。</translation>
</message>
<message>
@@ -198,23 +198,23 @@
<translation>å‚数无效:已给定 %1 个å‚数,应为 2 个。</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>无法删除目标文件 %1:%2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>无法将 %1 å¤åˆ¶åˆ° %2:%3</translation>
</message>
<message>
- <source>Could not delete file %1: %2</source>
+ <source>Cannot delete file %1: %2</source>
<translation>无法删除文件 %1:%2</translation>
</message>
<message>
- <source>Could not restore backup file into %1: %2</source>
+ <source>Cannot restore backup file into %1: %2</source>
<translation>无法将备份文件æ¢å¤åˆ° %1 中:%2</translation>
</message>
<message>
- <source>Could not copy a non-existent file: %1</source>
+ <source>Cannot copy a non-existent file: %1</source>
<translation>无法å¤åˆ¶ä¸å­˜åœ¨çš„文件:%1</translation>
</message>
</context>
@@ -299,7 +299,7 @@
<translation>无法下载 %1:写入文件“%2â€å¤±è´¥ï¼š%3</translation>
</message>
<message>
- <source>Cannot download %1: Could not create %2: %3</source>
+ <source>Cannot download %1: Cannot create %2: %3</source>
<translation>无法下载 %1:无法创建 %2:%3</translation>
</message>
<message>
@@ -353,7 +353,7 @@
<translation>å‚数无效:已给定 %1 个å‚数,应为 1 个。</translation>
</message>
<message>
- <source>Could not create folder %1: Unknown error.</source>
+ <source>Cannot create folder %1: Unknown error.</source>
<translation>无法创建文件夹 %1:未知错误。</translation>
</message>
<message>
@@ -364,7 +364,7 @@
<context>
<name>KDUpdater::MoveOperation</name>
<message>
- <source>Could not backup file %1.</source>
+ <source>Cannot backup file %1.</source>
<translation>无法备份文件 %1。</translation>
</message>
<message>
@@ -372,11 +372,11 @@
<translation>å‚数无效:已给定 %1 个å‚数,应为 2 个。</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
+ <source>Cannot remove destination file %1: %2</source>
<translation>无法删除目标文件 %1:%2</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
+ <source>Cannot copy %1 to %2: %3</source>
<translation>无法将 %1 å¤åˆ¶åˆ° %2:%3</translation>
</message>
<message>
@@ -403,7 +403,7 @@
<translation>文件 %1 ä¸å­˜åœ¨ã€‚</translation>
</message>
<message>
- <source>Could not open %1.</source>
+ <source>Cannot open %1.</source>
<translation>无法打开 %1。</translation>
</message>
<message>
@@ -426,11 +426,11 @@
<translation>å‚数无效:已给定 %1 个å‚数,应为 2 个。</translation>
</message>
<message>
- <source>Could not open file %1 for reading: %2</source>
+ <source>Cannot open file %1 for reading: %2</source>
<translation>无法打开文件 %1 进行读å–:%2</translation>
</message>
<message>
- <source>Could not open file %1 for writing: %2</source>
+ <source>Cannot open file %1 for writing: %2</source>
<translation>无法打开文件 %1 进行写入:%2</translation>
</message>
<message>
@@ -449,7 +449,7 @@
<context>
<name>KDUpdater::ResourceFileDownloader</name>
<message>
- <source>Could not read resource file &quot;%1&quot;. Reason:</source>
+ <source>Cannot read resource file &quot;%1&quot;. Reason:</source>
<translation>无法读å–æºæ–‡ä»¶â€œ%1â€ã€‚原因:</translation>
</message>
</context>
@@ -460,11 +460,11 @@
<translation>å‚数无效:已给定 %1 个å‚数,应为 1 个。</translation>
</message>
<message>
- <source>Could not remove folder %1: The folder does not exist.</source>
+ <source>Cannot remove folder %1: The folder does not exist.</source>
<translation>无法删除文件夹 %1:该文件夹ä¸å­˜åœ¨ã€‚</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>无法删除文件夹 %1:%2</translation>
</message>
<message>
@@ -506,11 +506,11 @@
<context>
<name>KDUpdater::UpdateFinder</name>
<message>
- <source>Could not access the package information of this application.</source>
+ <source>Cannot access the package information of this application.</source>
<translation>无法访问此应用程åºçš„包信æ¯ã€‚</translation>
</message>
<message>
- <source>Could not access the update sources information of this application.</source>
+ <source>Cannot access the update sources information of this application.</source>
<translation>无法访问此应用程åºçš„æ›´æ–°æºä¿¡æ¯ã€‚</translation>
</message>
<message>
@@ -536,7 +536,7 @@
</translation>
</message>
<message>
- <source>Could not download update source %1 from (&apos;%2&apos;)</source>
+ <source>Cannot download update source %1 from (&apos;%2&apos;)</source>
<translation>无法从(“%2â€ï¼‰ä¸‹è½½æ›´æ–°èµ„æº %1</translation>
</message>
</context>
@@ -547,7 +547,7 @@
<translation>%1 包å«æ— æ•ˆçš„内容:%2</translation>
</message>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>无法读å–“%1â€</translation>
</message>
<message>
@@ -559,7 +559,7 @@
<translation>根元素 %1 与预期ä¸ç¬¦ï¼Œåº”为“更新æºâ€</translation>
</message>
<message>
- <source>Could not save changes to &quot;%1&quot;: %2</source>
+ <source>Cannot save changes to &quot;%1&quot;: %2</source>
<translation>无法将更改ä¿å­˜åˆ°â€œ%1â€ï¼š%2</translation>
</message>
</context>
@@ -570,7 +570,7 @@
<translation>Updates.xml 包å«æ— æ•ˆçš„内容:%1</translation>
</message>
<message>
- <source>Could not read &quot;%1&quot;</source>
+ <source>Cannot read &quot;%1&quot;</source>
<translation>无法读å–“%1â€</translation>
</message>
<message>
@@ -605,11 +605,11 @@
<context>
<name>Lib7z</name>
<message>
- <source>Could not retrieve number of items in archive</source>
+ <source>Cannot retrieve number of items in archive</source>
<translation>无法检索存档中的项目数é‡</translation>
</message>
<message>
- <source>Could not retrieve path of archive item %1</source>
+ <source>Cannot retrieve path of archive item %1</source>
<translation>无法获å–存档项目 %1 的路径</translation>
</message>
<message>
@@ -629,15 +629,15 @@
<translation>错误:%1</translation>
</message>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>无法加载解ç å™¨</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>无法检索默认格å¼</translation>
</message>
<message>
- <source>Could not create archive %1. %2</source>
+ <source>Cannot create archive %1. %2</source>
<translation>无法创建存档 %1。%2</translation>
</message>
<message>
@@ -649,14 +649,14 @@
<translation>项目索引 %1 超出 [0, %2] 的范围</translation>
</message>
<message>
- <source>Could not create output file for writing: %1</source>
+ <source>Cannot create output file for writing: %1</source>
<translation>无法创建输出文件进行写入:%1</translation>
</message>
</context>
<context>
<name>Lib7z::ExtractItemJob</name>
<message>
- <source>Could not list archive: QIODevice not set or already destroyed.</source>
+ <source>Cannot list archive: QIODevice not set or already destroyed.</source>
<translation>无法列出存档:QIODevice 尚未设置或已æŸå。</translation>
</message>
<message>
@@ -675,7 +675,7 @@
<context>
<name>Lib7z::ListArchiveJob</name>
<message>
- <source>Could not list archive: QIODevice already destroyed.</source>
+ <source>Cannot list archive: QIODevice already destroyed.</source>
<translation>无法列出存档:QIODevice å·²æŸå。</translation>
</message>
<message>
@@ -690,15 +690,15 @@
<context>
<name>OpenArchiveInfo</name>
<message>
- <source>Could not load codecs</source>
+ <source>Cannot load codecs</source>
<translation>无法加载解ç å™¨</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
+ <source>Cannot retrieve default format</source>
<translation>无法检索默认格å¼</translation>
</message>
<message>
- <source>Could not open archive</source>
+ <source>Cannot open archive</source>
<translation>无法打开存档</translation>
</message>
<message>
@@ -777,43 +777,43 @@
<translation>YB</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>无法删除文件 %1:%2</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
+ <source>Cannot remove folder %1: %2</source>
<translation>无法删除文件夹 %1:%2</translation>
</message>
<message>
- <source>Could not create folder %1</source>
+ <source>Cannot create folder %1</source>
<translation>无法创建文件夹 %1</translation>
</message>
<message>
- <source>Could not copy file from %1 to %2: %3</source>
+ <source>Cannot copy file from %1 to %2: %3</source>
<translation>无法将文件从 %1 å¤åˆ¶åˆ° %2:%3</translation>
</message>
<message>
- <source>Could not move file from %1 to %2: %3</source>
+ <source>Cannot move file from %1 to %2: %3</source>
<translation>无法将文件从 %1 移动到 %2:%3</translation>
</message>
<message>
- <source>Could not create folder %1: %2</source>
+ <source>Cannot create folder %1: %2</source>
<translation>无法创建文件夹 %1:%2</translation>
</message>
<message>
- <source>Could not open temporary file: %1</source>
+ <source>Cannot open temporary file: %1</source>
<translation>无法打开临时文件:%1</translation>
</message>
<message>
- <source>Could not open temporary file for template %1: %2</source>
+ <source>Cannot open temporary file for template %1: %2</source>
<translation>æ— æ³•æ‰“å¼€æ¨¡æ¿ %1 的临时文件:%2</translation>
</message>
<message>
- <source>Could not create temporary file</source>
+ <source>Cannot create temporary file</source>
<translation>无法创建临时文件</translation>
</message>
<message>
- <source>Could not retrieve property %1 for item %2</source>
+ <source>Cannot retrieve property %1 for item %2</source>
<translation>无法检索 %2 项目的 %1 属性</translation>
</message>
<message>
@@ -821,11 +821,11 @@
<translation>%2 项目的 %1 属性ä¸å±žäºŽ VT_FILETIME 类型,而是 %3</translation>
</message>
<message>
- <source>Could not convert file time to local time</source>
+ <source>Cannot convert file time to local time</source>
<translation>无法将文件时间转æ¢ä¸ºæœ¬åœ°æ—¶é—´</translation>
</message>
<message>
- <source>Could not convert local file time to system time</source>
+ <source>Cannot convert local file time to system time</source>
<translation>无法将本地文件时间转æ¢ä¸ºç³»ç»Ÿæ—¶é—´</translation>
</message>
<message>
@@ -860,19 +860,19 @@
<translation>在å‡çº§æ¨¡å¼ä¸‹ç»„件无法å«æœ‰å­ç»„件。</translation>
</message>
<message>
- <source>Could not open the requested translation file &apos;%1&apos;.</source>
+ <source>Cannot open the requested translation file &apos;%1&apos;.</source>
<translation>无法打开请求的翻译文件“%1â€ã€‚</translation>
</message>
<message>
- <source>Could not open the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>无法打开请求的UI文件“%1â€ã€‚错误:%2</translation>
</message>
<message>
- <source>Could not load the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot load the requested UI file &apos;%1&apos;. Error: %2</source>
<translation>无法加载请求的UI文件“%1â€ã€‚错误:%2</translation>
</message>
<message>
- <source>Could not open the requested license file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested license file &apos;%1&apos;. Error: %2</source>
<translation>无法打开请求的许å¯æ–‡ä»¶â€œ%1â€ã€‚错误:%2</translation>
</message>
<message>
@@ -1036,7 +1036,7 @@
<translation>%0 中存在无效的å‚æ•°:目录无效:%1 %2</translation>
</message>
<message>
- <source>Could not create %0</source>
+ <source>Cannot create %0</source>
<translation>无法创建 %0</translation>
</message>
<message>
@@ -1044,11 +1044,11 @@
<translation>覆盖 %1 失败</translation>
</message>
<message>
- <source>Could not copy %0 to %1, error was: %3</source>
+ <source>Cannot copy %0 to %1, error was: %3</source>
<translation>无法将 %0 å¤åˆ¶åˆ° %1,错误为:%3</translation>
</message>
<message>
- <source>Could not remove %0</source>
+ <source>Cannot remove %0</source>
<translation>无法删除 %0</translation>
</message>
</context>
@@ -1059,11 +1059,11 @@
<translation>无效的任务项总数。</translation>
</message>
<message>
- <source>Could not open source &apos;%1&apos; for read. Error: %2.</source>
+ <source>Cannot open source &apos;%1&apos; for read. Error: %2.</source>
<translation>无法打开文件“%1â€è¿›è¡Œè¯»å–。错误:%2。</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<translation>无法打开目标“%1â€è¿›è¡Œå†™å…¥ã€‚错误:%2。</translation>
</message>
<message>
@@ -1086,11 +1086,11 @@
<translation>覆盖 %1 失败</translation>
</message>
<message>
- <source>Could not write Desktop Entry at %1</source>
+ <source>Cannot write Desktop Entry at %1</source>
<translation>无法写入ä½äºŽ %1 çš„æ¡Œé¢æ¡ç›®</translation>
</message>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>无法备份文件 %1: %2</translation>
</message>
</context>
@@ -1105,22 +1105,22 @@
<translation>æ°å¥½ 2 个</translation>
</message>
<message>
- <source>Could not create link from %1 to %2.</source>
+ <source>Cannot create link from %1 to %2.</source>
<translation>无法创建从 %1 到 %2 的链接。</translation>
</message>
<message>
- <source>Could not remove link from %1 to %2.</source>
+ <source>Cannot remove link from %1 to %2.</source>
<translation>无法删除从 %1 到 %2 的链接。</translation>
</message>
</context>
<context>
<name>QInstaller::CreateLocalRepositoryOperation</name>
<message>
- <source>Could not set file permissions %1!</source>
+ <source>Cannot set file permissions %1!</source>
<translation>无法设置文件æƒé™ %1!</translation>
</message>
<message>
- <source>Could not move file %1 to %2. Error: %3</source>
+ <source>Cannot move file %1 to %2. Error: %3</source>
<translation>无法将文件 %1 移动到 %2。错误:%3</translation>
</message>
<message>
@@ -1136,19 +1136,19 @@
<translation>安装程åºå¿…须为离线版本:%1.</translation>
</message>
<message>
- <source>Could not open file: %1</source>
+ <source>Cannot open file: %1</source>
<translation>无法打开文件:%1</translation>
</message>
<message>
- <source>Could not read: %1. Error: %2</source>
+ <source>Cannot read: %1. Error: %2</source>
<translation>无法读å–:%1.错误:%2</translation>
</message>
<message>
- <source>Could not open file: %1. Error: %2</source>
+ <source>Cannot open file: %1. Error: %2</source>
<translation>无法打开文件:%1.错误:%2</translation>
</message>
<message>
- <source>Could not create target dir: %1.</source>
+ <source>Cannot create target dir: %1.</source>
<translation>无法创建目标目录:%1.</translation>
</message>
<message>
@@ -1160,7 +1160,7 @@
<translation>正在删除文件:%0</translation>
</message>
<message>
- <source>Could not remove %0.</source>
+ <source>Cannot remove %0.</source>
<translation>无法删除 %0。</translation>
</message>
<message>
@@ -1168,7 +1168,7 @@
<translation>无法删除目录 %1:%2</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
+ <source>Cannot remove file %1: %2</source>
<translation>无法删除文件 %1:%2</translation>
</message>
</context>
@@ -1183,11 +1183,11 @@
<translation>2 或 3 个</translation>
</message>
<message>
- <source>Could not create folder %1: %2.</source>
+ <source>Cannot create folder %1: %2.</source>
<translation>无法创建文件夹 %1:%2.</translation>
</message>
<message>
- <source>Could not create link %1: %2</source>
+ <source>Cannot create link %1: %2</source>
<translation>无法创建链接 %1:%2</translation>
</message>
<message>
@@ -1218,15 +1218,15 @@
<translation>下载时的散列验è¯å¤±è´¥ã€‚这是一个临时错误,请é‡è¯•ã€‚</translation>
</message>
<message>
- <source>Could not verify Hash</source>
+ <source>Cannot verify Hash</source>
<translation>无法验è¯æ•£åˆ—</translation>
</message>
<message>
- <source>Could not download archive: %1 : %2</source>
+ <source>Cannot download archive: %1 : %2</source>
<translation>无法下载存档:%1:%2</translation>
</message>
<message>
- <source>Could not fetch archives: %1
+ <source>Cannot fetch archives: %1
Error while loading %2</source>
<translation>无法æå–存档:%1
加载 %2 时出现错误</translation>
@@ -1236,7 +1236,7 @@ Error while loading %2</source>
<translation>ä¸æ”¯æŒçš„方案:%1 (%2)</translation>
</message>
<message>
- <source>Could not find component for: %1.</source>
+ <source>Cannot find component for: %1.</source>
<translation>无法下载以下项目的组件:%1.</translation>
</message>
<message>
@@ -1288,7 +1288,7 @@ Error while loading %2</source>
<translation>目标文件“%1â€å·²å­˜åœ¨ï¼Œä½†å®ƒä¸æ˜¯ä¸€ä¸ªæ–‡ä»¶ã€‚</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Cannot open target &apos;%1&apos; for write. Error: %2.</source>
<extracomment>%2 is a sentence describing the error</extracomment>
<translation>无法打开目标“%1â€ä»¥è¿›è¡Œå†™å…¥ã€‚错误:%2。</translation>
</message>
@@ -1304,7 +1304,7 @@ Error while loading %2</source>
<translation>至少 1 个</translation>
</message>
<message>
- <source>Execution failed: Could not start detached: &quot;%1&quot;</source>
+ <source>Execution failed: Cannot start detached: &quot;%1&quot;</source>
<translation>执行失败:无法开始分离:“%1â€</translation>
</message>
<message>
@@ -1316,7 +1316,7 @@ Error while loading %2</source>
<translation>执行失败(æ„外退出代ç ï¼š%1):“%2â€</translation>
</message>
<message>
- <source>Execution failed: Could not start: &quot;%1&quot;(%2)</source>
+ <source>Execution failed: Cannot start: &quot;%1&quot;(%2)</source>
<translation>执行失败:无法å¯åŠ¨ï¼šâ€œ%1â€ï¼ˆ%2)</translation>
</message>
</context>
@@ -1345,7 +1345,7 @@ Error while loading %2</source>
<context>
<name>QInstaller::ExtractArchiveOperation::Runnable</name>
<message>
- <source>Could not open %1 for reading: %2.</source>
+ <source>Cannot open %1 for reading: %2.</source>
<translation>无法打开 %1 进行读å–:%2.</translation>
</message>
<message>
@@ -1364,7 +1364,7 @@ Error while loading %2</source>
<translation>å‚æ•°æ•°é‡ä¸åŒ¹é…:需è¦ä¸€ä¸ª</translation>
</message>
<message>
- <source>Could not get package manager core.</source>
+ <source>Cannot get package manager core.</source>
<translation>无法获得包管ç†å™¨å†…核。</translation>
</message>
<message>
@@ -1488,7 +1488,7 @@ Error while loading %2</source>
<translation>å‚数无效:æºæ–‡ä»¶å¤¹ä¸å¾—为空。</translation>
</message>
<message>
- <source>Could not backup file %1: %2</source>
+ <source>Cannot backup file %1: %2</source>
<translation>无法备份文件 %1:%2</translation>
</message>
<message>
@@ -1500,7 +1500,7 @@ Error while loading %2</source>
<translation>å¤åˆ¶æ–‡ä»¶ %1 失败:%2</translation>
</message>
<message>
- <source>Could not create folder at %1: %2</source>
+ <source>Cannot create folder at %1: %2</source>
<translation>无法在 %1 创建文件夹:%2</translation>
</message>
</context>
@@ -1677,7 +1677,7 @@ Error while loading %2</source>
<translation>æå– %1 æ—¶æ•èŽ·æœªçŸ¥å¼‚常。</translation>
</message>
<message>
- <source>Could not open %1 for reading. Error: %2</source>
+ <source>Cannot open %1 for reading. Error: %2</source>
<translation>无法打开 %1 读å–。错误:%2</translation>
</message>
</context>
@@ -1765,7 +1765,7 @@ Downloading packages...</source>
<translation>æ ¼å¼é”™è¯¯</translation>
</message>
<message>
- <source>Could not write installer configuration to %1: %2</source>
+ <source>Cannot write installer configuration to %1: %2</source>
<translation>无法将安装程åºé…置写入 %1:%2</translation>
</message>
<message>
@@ -1867,7 +1867,7 @@ Installing component %1</source>
<translation>未知错误</translation>
</message>
<message>
- <source>Could not retrieve remote tree: %1.</source>
+ <source>Cannot retrieve remote tree: %1.</source>
<translation>无法检索远程树:%1.</translation>
</message>
<message>
@@ -1875,15 +1875,15 @@ Installing component %1</source>
<translation>未能从以下ä½ç½®è¯»å–包:%1.</translation>
</message>
<message>
- <source>Could not retrieve meta information: %1</source>
+ <source>Cannot retrieve meta information: %1</source>
<translation>无法检索元信æ¯ï¼š%1</translation>
</message>
<message>
- <source>Could not add temporary update source information.</source>
+ <source>Cannot add temporary update source information.</source>
<translation>无法添加临时更新æºä¿¡æ¯ã€‚</translation>
</message>
<message>
- <source>Could not find any update source information.</source>
+ <source>Cannot find any update source information.</source>
<translation>无法找到任何更新æºä¿¡æ¯ã€‚</translation>
</message>
<message>
@@ -1903,19 +1903,19 @@ Installing component %1</source>
<translation>维护工具ä¸æ˜¯æ†ç»‘套件</translation>
</message>
<message>
- <source>Could not write maintenance tool data to %1: %2</source>
+ <source>Cannot write maintenance tool data to %1: %2</source>
<translation>无法将维护工具数æ®å†™å…¥åˆ° %1:%2</translation>
</message>
<message>
- <source>Could not remove data file &apos;%1&apos;: %2</source>
+ <source>Cannot remove data file &apos;%1&apos;: %2</source>
<translation>无法删除数æ®æ–‡ä»¶â€œ%1â€ï¼š%2</translation>
</message>
<message>
- <source>Could not write maintenance tool to %1: %2</source>
+ <source>Cannot write maintenance tool to %1: %2</source>
<translation>无法将维护工具写入到 %1:%2</translation>
</message>
<message>
- <source>Could not write maintenance tool binary data to %1: %2</source>
+ <source>Cannot write maintenance tool binary data to %1: %2</source>
<translation>无法将维护工具二进制数æ®å†™å…¥ %1:%2</translation>
</message>
<message>
@@ -2142,14 +2142,14 @@ Please copy the installer to a local drive</source>
<context>
<name>QInstaller::RemoteObject</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>å‘é€å‘½ä»¤ï¼š %1 åŽæ— æ³•è¯»å–所有数æ®ã€‚ 期望: %2字节, 收到: %3字节。 错误: %4</translation>
</message>
</context>
<context>
<name>QInstaller::RemoteServerConnection</name>
<message>
- <source>Could not read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
<translation>å‘é€å‘½ä»¤ï¼š %1 åŽæ— æ³•è¯»å–所有数æ®ã€‚ 期望: %2字节, 收到: %3字节。 错误: %4</translation>
</message>
</context>
@@ -2175,7 +2175,7 @@ Please copy the installer to a local drive</source>
<context>
<name>QInstaller::Resource</name>
<message>
- <source>Could not open Resource &apos;%1&apos; read-only.</source>
+ <source>Cannot open Resource &apos;%1&apos; read-only.</source>
<translation>无法以åªè¯»æ–¹å¼æ‰“开资æºâ€œ%1â€ã€‚</translation>
</message>
<message>
@@ -2197,7 +2197,7 @@ Please copy the installer to a local drive</source>
<context>
<name>QInstaller::ScriptEngine</name>
<message>
- <source>Could not open the requested script file at %1: %2.</source>
+ <source>Cannot open the requested script file at %1: %2.</source>
<translation>无法打开ä½äºŽ %1 的请求脚本文件:%2。</translation>
</message>
<message>
@@ -2394,7 +2394,7 @@ Do you want to continue?</source>
<translation>测试:“%1â€æ—¶è¶…æ—¶</translation>
</message>
<message>
- <source>Could not parse Updates.xml! Error: %1.</source>
+ <source>Cannot parse Updates.xml! Error: %1.</source>
<translation>æ— æ³•è§£æž Updates.xml! 错误:%1。</translation>
</message>
<message>
@@ -2424,11 +2424,11 @@ Do you want to continue?</source>
<context>
<name>RemoteClient</name>
<message>
- <source>Could not get authorization.</source>
+ <source>Cannot get authorization.</source>
<translation>无法获得授æƒã€‚</translation>
</message>
<message>
- <source>Could not get authorization that is needed for continuing the installation.
+ <source>Cannot get authorization that is needed for continuing the installation.
Either abort the installation or use the fallback solution by running
%1
@@ -2443,14 +2443,14 @@ as root and then clicking OK.</source>
<context>
<name>ResourceCollectionManager</name>
<message>
- <source>Could not open resource %1: %2</source>
+ <source>Cannot open resource %1: %2</source>
<translation>æ— æ³•æ‰“å¼€èµ„æº %1:%2</translation>
</message>
</context>
<context>
<name>Settings</name>
<message>
- <source>Could not open settings file %1 for reading: %2</source>
+ <source>Cannot open settings file %1 for reading: %2</source>
<translation>无法打开设置文件 %1 进行读å–:%2</translation>
</message>
</context>
@@ -2580,7 +2580,7 @@ as root and then clicking OK.</source>
<translation>注册路径 %1 ä¸å¯å†™å…¥</translation>
</message>
<message>
- <source>Could not write to registry path %1</source>
+ <source>Cannot write to registry path %1</source>
<translation>无法写入注册路径 %1</translation>
</message>
<message>
diff --git a/src/sdk/updatechecker.cpp b/src/sdk/updatechecker.cpp
index 53c707fb1..b804096b7 100644
--- a/src/sdk/updatechecker.cpp
+++ b/src/sdk/updatechecker.cpp
@@ -37,7 +37,7 @@
#include <component.h>
#include <errors.h>
#include <init.h>
-#include <kdrunoncechecker.h>
+#include <runoncechecker.h>
#include <packagemanagercore.h>
#include <productkeycheck.h>
@@ -53,13 +53,13 @@ UpdateChecker::UpdateChecker(int &argc, char *argv[])
int UpdateChecker::check()
{
- KDRunOnceChecker runCheck(qApp->applicationDirPath() + QLatin1String("/lockmyApp15021976.lock"));
- if (runCheck.isRunning(KDRunOnceChecker::ConditionFlag::Lockfile)) {
+ RunOnceChecker runCheck(qApp->applicationDirPath() + QLatin1String("/lockmyApp15021976.lock"));
+ if (runCheck.isRunning(RunOnceChecker::ConditionFlag::Lockfile)) {
// It is possible to install an application and thus the maintenance tool into a
// directory that requires elevated permission to create a lock file. Since this
// cannot be done without requesting credentials from the user, we silently ignore
// the fact that we could not create the lock file and check the running processes.
- if (runCheck.isRunning(KDRunOnceChecker::ConditionFlag::ProcessList))
+ if (runCheck.isRunning(RunOnceChecker::ConditionFlag::ProcessList))
throw QInstaller::Error(QLatin1String("An instance is already checking for updates."));
}
@@ -107,7 +107,7 @@ int UpdateChecker::check()
foreach (QInstaller::Component *component, components) {
QDomElement update = doc.createElement(QLatin1String("update"));
update.setAttribute(QLatin1String("name"), component->value(QInstaller::scDisplayName));
- update.setAttribute(QLatin1String("version"), component->value(QInstaller::scRemoteVersion));
+ update.setAttribute(QLatin1String("version"), component->value(QInstaller::scVersion));
update.setAttribute(QLatin1String("size"), component->value(QInstaller::scUncompressedSize));
root.appendChild(update);
}
diff --git a/src/src.pro b/src/src.pro
index 8fc4f21cd..98d9facc6 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,8 +1,10 @@
-CONFIG += ordered
TEMPLATE = subdirs
SUBDIRS += libs sdk
+sdk.depends = libs
+
TRANSLATIONS += sdk/translations/de.ts \
sdk/translations/en.ts \
+ sdk/translations/es.ts \
sdk/translations/fr.ts \
sdk/translations/ja.ts \
sdk/translations/pl.ts \